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.
Files changed (72) hide show
  1. package/README.md +5 -6
  2. package/dist/web/assets/{Analytics-Dma_j2Rq.js → Analytics-Dpje9L84.js} +1 -1
  3. package/dist/web/assets/{ConfigTemplates-C49Y1PLH.js → ConfigTemplates-Cz6kasek.js} +1 -1
  4. package/dist/web/assets/Home-BwTaYu3q.js +1 -0
  5. package/dist/web/assets/Home-Jom_ZcdY.css +1 -0
  6. package/dist/web/assets/{PluginManager-B1ECTHyY.js → PluginManager-DsN-xNXx.js} +1 -1
  7. package/dist/web/assets/ProjectList-4BCObimU.js +1 -0
  8. package/dist/web/assets/{ProjectList-B_L55-l9.css → ProjectList-D3a0oRum.css} +1 -1
  9. package/dist/web/assets/{SessionList-CH5GwwiJ.js → SessionList-D4c8FRzq.js} +1 -1
  10. package/dist/web/assets/{SkillManager-CRyVhjYQ.js → SkillManager-C-KYbXB5.js} +1 -1
  11. package/dist/web/assets/{WorkspaceManager-CO9tclVt.js → WorkspaceManager-B-BlPJHX.js} +1 -1
  12. package/dist/web/assets/index-Btfvh0GG.js +2 -0
  13. package/dist/web/assets/{index-CM26UrnJ.css → index-CLNa6DhH.css} +1 -1
  14. package/dist/web/index.html +2 -2
  15. package/package.json +2 -1
  16. package/src/commands/channels.js +8 -8
  17. package/src/commands/daemon.js +4 -4
  18. package/src/commands/doctor.js +1 -1
  19. package/src/commands/logs.js +1 -3
  20. package/src/commands/port-config.js +4 -4
  21. package/src/commands/proxy-control.js +13 -13
  22. package/src/commands/stats.js +6 -6
  23. package/src/commands/toggle-proxy.js +8 -8
  24. package/src/config/default.js +3 -3
  25. package/src/config/paths.js +46 -49
  26. package/src/index.js +4 -5
  27. package/src/server/api/commands.js +1 -1
  28. package/src/server/api/config-export.js +2 -2
  29. package/src/server/api/config-registry.js +1 -1
  30. package/src/server/api/config.js +1 -1
  31. package/src/server/api/dashboard.js +16 -16
  32. package/src/server/api/mcp.js +2 -2
  33. package/src/server/api/{pi-channels.js → omp-channels.js} +15 -15
  34. package/src/server/api/{pi-config.js → omp-config.js} +13 -13
  35. package/src/server/api/{pi-projects.js → omp-projects.js} +5 -5
  36. package/src/server/api/{pi-proxy.js → omp-proxy.js} +18 -18
  37. package/src/server/api/{pi-sessions.js → omp-sessions.js} +21 -21
  38. package/src/server/api/{pi-statistics.js → omp-statistics.js} +1 -1
  39. package/src/server/api/plugins.js +1 -1
  40. package/src/server/api/skills.js +1 -1
  41. package/src/server/api/workspaces.js +1 -1
  42. package/src/server/index.js +10 -10
  43. package/src/server/{pi-proxy-server.js → omp-proxy-server.js} +13 -13
  44. package/src/server/services/channel-balance.js +3 -3
  45. package/src/server/services/channel-scheduler.js +4 -4
  46. package/src/server/services/commands-service.js +5 -5
  47. package/src/server/services/config-export-service.js +53 -53
  48. package/src/server/services/config-registry-service.js +8 -8
  49. package/src/server/services/config-sync-manager.js +26 -26
  50. package/src/server/services/config-templates-service.js +28 -28
  51. package/src/server/services/mcp-service.js +20 -20
  52. package/src/server/services/notification-hooks.js +138 -6
  53. package/src/server/services/{pi-auth-providers.js → omp-auth-providers.js} +2 -2
  54. package/src/server/services/{pi-channels.js → omp-channels.js} +5 -5
  55. package/src/server/services/{pi-config.js → omp-config.js} +47 -65
  56. package/src/server/services/{pi-sessions.js → omp-sessions.js} +20 -20
  57. package/src/server/services/{pi-settings-manager.js → omp-settings-manager.js} +422 -18
  58. package/src/server/services/{pi-statistics-service.js → omp-statistics-service.js} +2 -2
  59. package/src/server/services/plugins-service.js +122 -122
  60. package/src/server/services/prompts-service.js +20 -20
  61. package/src/server/services/proxy-log-helper.js +1 -1
  62. package/src/server/services/proxy-runtime.js +1 -1
  63. package/src/server/services/skill-service.js +7 -7
  64. package/src/server/services/speed-test.js +29 -29
  65. package/src/server/services/ui-config.js +3 -3
  66. package/src/server/services/workspace-service.js +8 -8
  67. package/src/server/websocket-server.js +4 -4
  68. package/src/shared/platforms.js +201 -0
  69. package/dist/web/assets/Home-DGGC8H4g.js +0 -1
  70. package/dist/web/assets/Home-ewgeIhF7.css +0 -1
  71. package/dist/web/assets/ProjectList-DyiGyT-H.js +0 -1
  72. 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
- if (env.OMP_PROFILE !== undefined) {
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.PI_CONFIG_DIR || '');
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 getLegacyPiAgentDir() {
50
- return path.join(HOME_DIR, '.pi', 'agent');
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 runtime?.runtime === 'pi' ? getLegacyPiAgentDir(env) : getDefaultOmpAgentDir(env);
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 runPiCommand(command, args = [], env = process.env, options = {}, stdio = ['ignore', 'pipe', 'pipe']) {
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 = runPiCommand(command, ['config', 'path'], env, options);
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 getPiAgentDir(env = process.env, options = {}) {
87
- const runtime = options.runtime || resolvePiRuntime(env, options);
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(getFallbackPiAgentDir(runtime, env)));
86
+ return path.resolve(expandHome(getFallbackOmpAgentDir(runtime, env)));
95
87
  }
96
88
 
97
- function getPiPaths(env = process.env, options = {}) {
98
- const runtime = options.runtime || resolvePiRuntime(env, options);
99
- const agentDir = getPiAgentDir(env, { ...options, runtime });
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 ensurePiDir(dirPath) {
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
- ensurePiDir(path.dirname(filePath));
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
- ensurePiDir(path.dirname(filePath));
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 readPiSettings() {
165
- const paths = getPiPaths();
157
+ function readOmpSettings() {
158
+ const paths = getOmpPaths();
166
159
  return readYamlFile(paths.settings, readJsonFile(paths.settingsJsonLegacy, {}));
167
160
  }
168
161
 
169
- function writePiSettings(settings) {
170
- writeYamlFile(getPiPaths().settings, settings || {});
162
+ function writeOmpSettings(settings) {
163
+ writeYamlFile(getOmpPaths().settings, settings || {});
171
164
  }
172
165
 
173
- function getPiCommand(env = process.env) {
174
- return String(env.OMP_COMMAND || env.PI_COMMAND || DEFAULT_OMP_COMMAND).trim() || DEFAULT_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
- runPiCommand(command, ['--version'], env, options, 'ignore');
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 resolvePiRuntime(env = process.env, options = {}) {
187
- const configured = env.OMP_COMMAND || env.PI_COMMAND;
179
+ function resolveOmpRuntime(env = process.env, options = {}) {
180
+ const configured = env.OMP_COMMAND;
188
181
  if (configured) {
189
- const command = getPiCommand(env);
190
- const source = env.OMP_COMMAND ? 'OMP_COMMAND' : 'PI_COMMAND';
182
+ const command = getOmpCommand(env);
191
183
  return {
192
184
  command,
193
- runtime: command === LEGACY_PI_COMMAND ? 'pi' : 'omp',
185
+ runtime: 'omp',
194
186
  installed: commandExists(command, env, options),
195
187
  configured: true,
196
- commandSource: source
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 isPiInstalled(env = process.env, options = {}) {
230
- const runtime = options.runtime || resolvePiRuntime(env, options);
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(getPiPaths(env, { ...options, runtime }).agentDir);
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 getPiStatus(env = process.env, options = {}) {
247
- const runtime = resolvePiRuntime(env, options);
248
- const paths = getPiPaths(env, { ...options, runtime });
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: isPiInstalled(env, { ...options, runtime }),
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
- getPiAgentDir,
273
- getPiPaths,
274
- ensurePiDir,
254
+ getOmpAgentDir,
255
+ getOmpPaths,
256
+ ensureOmpDir,
275
257
  readJsonFile,
276
258
  readYamlFile,
277
259
  readTextFile,
278
260
  writeJsonFile,
279
261
  writeYamlFile,
280
- readPiSettings,
281
- writePiSettings,
282
- getPiCommand,
262
+ readOmpSettings,
263
+ writeOmpSettings,
264
+ getOmpCommand,
283
265
  getOmpProfile,
284
- resolvePiRuntime,
285
- isPiInstalled,
286
- getPiStatus
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 { getPiCommand, getPiPaths, isPiInstalled, resolvePiRuntime } = require('./pi-config');
5
+ const { getOmpCommand, getOmpPaths, isOmpInstalled, resolveOmpRuntime } = require('./omp-config');
6
6
 
7
- const PROJECT_ORDER_FILE = PATHS.piProjectOrder;
8
- const SESSION_ORDER_FILE = PATHS.piSessionOrder;
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 parsePiSessionId(filePath = '') {
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 convertPiEntry(entry = {}, index = 0) {
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(convertPiEntry).filter(Boolean);
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 || parsePiSessionId(filePath);
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: 'pi'
210
+ source: 'omp'
211
211
  };
212
212
  }
213
213
 
214
- function scanSessionFiles(rootDir = getPiPaths().sessions) {
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: 'pi'
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: 'pi',
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(convertPiEntry).filter(Boolean);
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(convertPiEntry).filter(Boolean);
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: parsePiSessionId(targetPath), filePath: targetPath };
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 `${getPiCommand()} ${args.join(' ')}`;
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 isPiCliInstalled() {
457
- if (isPiInstalled()) return true;
458
- const runtime = resolvePiRuntime();
456
+ function isOmpCliInstalled() {
457
+ if (isOmpInstalled()) return true;
458
+ const runtime = resolveOmpRuntime();
459
459
  if (runtime.installed) return true;
460
460
  try {
461
- execFileSync(getPiCommand(), ['--version'], { stdio: 'ignore', timeout: 3000 });
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
- isPiInstalled: isPiCliInstalled,
482
+ isOmpInstalled: isOmpCliInstalled,
483
483
  normalizeSession,
484
484
  parseSessionFile,
485
485
  scanSessionFiles,