scalemax 0.1.51 → 0.1.52
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/dist/configure/roo-code.js +28 -16
- package/dist/detect/roo-code.d.ts +19 -0
- package/dist/detect/roo-code.js +31 -8
- package/package.json +1 -1
|
@@ -2,10 +2,10 @@ import path from 'node:path';
|
|
|
2
2
|
import fs from 'fs-extra';
|
|
3
3
|
import JSON5 from 'json5';
|
|
4
4
|
import { atomicWrite, backupFile, captureFileSnapshots, restoreFileSnapshots, snapshotRollback } from '../utils/fs.js';
|
|
5
|
-
import { clientConfigPath } from './paths.js';
|
|
6
5
|
import { anthropicModelIds, deepSeekChatModelIds, isDeepSeekChatModelId, modelIdKey, modelName, modelSupportsTools, openAiBaseUrl, openAiResponsesModelIds, preferredAnthropicModel, preferredChatCompletionsModel, preferredOpenAiResponsesModel } from './models.js';
|
|
7
6
|
import { isAnthropicModel } from '../utils/api.js';
|
|
8
7
|
import { rooRipgrepRepairNote } from '../repair/roo-ripgrep.js';
|
|
8
|
+
import { rooSettingsTargets } from '../detect/roo-code.js';
|
|
9
9
|
const id = 'roo-code';
|
|
10
10
|
const name = 'Roo Code (VS Code)';
|
|
11
11
|
const importSetting = 'roo-cline.autoImportSettingsPath';
|
|
@@ -167,23 +167,30 @@ export async function configure(ctx) {
|
|
|
167
167
|
return note ? { ...result, note } : result;
|
|
168
168
|
}
|
|
169
169
|
async function configureHandoff(ctx) {
|
|
170
|
-
const
|
|
170
|
+
const targets = await rooSettingsTargets(ctx.home, ctx.platform, ctx.env);
|
|
171
171
|
const profileFile = importPath(ctx.home);
|
|
172
|
-
const snapshots = await captureFileSnapshots([settingsFile, profileFile]);
|
|
173
|
-
const originalSettings = await fs.readFile(settingsFile, 'utf8').catch(() => '');
|
|
172
|
+
const snapshots = await captureFileSnapshots([...targets.map(target => target.settingsFile), profileFile]);
|
|
174
173
|
const originalProfile = await fs.readFile(profileFile, 'utf8').catch(() => '');
|
|
175
|
-
const
|
|
176
|
-
|
|
174
|
+
const writes = [];
|
|
175
|
+
for (const target of targets) {
|
|
176
|
+
const original = await fs.readFile(target.settingsFile, 'utf8').catch(() => '');
|
|
177
|
+
const next = JSON.stringify({ ...parseSettings(original, target.settingsFile), [importSetting]: importSettingValue }, null, 2) + '\n';
|
|
178
|
+
if (original !== next)
|
|
179
|
+
writes.push({ file: target.settingsFile, text: next });
|
|
180
|
+
}
|
|
177
181
|
const nextProfile = handoff(ctx);
|
|
178
|
-
|
|
182
|
+
const editors = targets.map(target => target.editor).join(', ');
|
|
183
|
+
if (!writes.length && originalProfile === nextProfile) {
|
|
179
184
|
await fs.chmod(profileFile, 0o600).catch(() => undefined);
|
|
180
|
-
return { id, name, changed: false, path: profileFile, message:
|
|
185
|
+
return { id, name, changed: false, path: profileFile, message: `supported Roo Code auto-import handoff is already current (${editors}); reload the editor to consume it`, tip: ROO_CODE_MODE_TIP };
|
|
181
186
|
}
|
|
182
|
-
|
|
187
|
+
for (const write of writes)
|
|
188
|
+
await backupFile(write.file, ctx.home);
|
|
183
189
|
await backupFile(profileFile, ctx.home);
|
|
184
190
|
try {
|
|
185
191
|
await atomicWrite(profileFile, nextProfile, 0o600, ctx.platform);
|
|
186
|
-
|
|
192
|
+
for (const write of writes)
|
|
193
|
+
await atomicWrite(write.file, write.text, 0o600, ctx.platform);
|
|
187
194
|
}
|
|
188
195
|
catch (error) {
|
|
189
196
|
try {
|
|
@@ -199,19 +206,23 @@ async function configureHandoff(ctx) {
|
|
|
199
206
|
name,
|
|
200
207
|
changed: true,
|
|
201
208
|
path: profileFile,
|
|
202
|
-
message:
|
|
209
|
+
message: `created a private, supported auto-import handoff for ${editors}; reload the editor so Roo Code imports the profile into SecretStorage`,
|
|
203
210
|
tip: ROO_CODE_MODE_TIP,
|
|
204
211
|
rollback: snapshotRollback(snapshots, ctx.platform),
|
|
205
212
|
};
|
|
206
213
|
}
|
|
207
214
|
export async function verify(ctx) {
|
|
208
|
-
const settingsFile = clientConfigPath(id, ctx.home, ctx.platform, ctx.env);
|
|
209
215
|
const profileFile = importPath(ctx.home);
|
|
210
|
-
|
|
216
|
+
let handoffSet = true;
|
|
217
|
+
for (const target of await rooSettingsTargets(ctx.home, ctx.platform, ctx.env)) {
|
|
218
|
+
const settings = parseSettings(await fs.readFile(target.settingsFile, 'utf8'), target.settingsFile);
|
|
219
|
+
if (settings[importSetting] !== importSettingValue)
|
|
220
|
+
handoffSet = false;
|
|
221
|
+
}
|
|
211
222
|
const profile = await fs.readJson(profileFile).catch(() => undefined);
|
|
212
223
|
const expectedProfiles = profilesFor(ctx);
|
|
213
224
|
const current = currentProfileFor(ctx, expectedProfiles);
|
|
214
|
-
if (
|
|
225
|
+
if (!handoffSet || profile?.providerProfiles?.currentApiConfigName !== current.name) {
|
|
215
226
|
throw new Error('Roo Code auto-import handoff is incomplete.');
|
|
216
227
|
}
|
|
217
228
|
if (profile?.globalSettings?.maxWorkspaceFiles !== 0) {
|
|
@@ -232,10 +243,11 @@ export async function verify(ctx) {
|
|
|
232
243
|
return { id, name, changed: false, path: profileFile, message: 'verified supported auto-import handoff (runtime activation requires a VS Code reload)' };
|
|
233
244
|
}
|
|
234
245
|
export async function remove(ctx) {
|
|
235
|
-
const settingsFile = clientConfigPath(id, ctx.home, ctx.platform, ctx.env);
|
|
236
246
|
const profileFile = importPath(ctx.home);
|
|
237
247
|
let changed = false;
|
|
238
|
-
|
|
248
|
+
for (const { settingsFile } of await rooSettingsTargets(ctx.home, ctx.platform, ctx.env)) {
|
|
249
|
+
if (!(await fs.pathExists(settingsFile)))
|
|
250
|
+
continue;
|
|
239
251
|
const text = await fs.readFile(settingsFile, 'utf8');
|
|
240
252
|
const settings = parseSettings(text, settingsFile);
|
|
241
253
|
if (settings[importSetting] === importSettingValue) {
|
|
@@ -5,6 +5,13 @@ export interface EditorExtensionRoot {
|
|
|
5
5
|
editor: string;
|
|
6
6
|
/** Path segments below the home folder. */
|
|
7
7
|
segments: readonly string[];
|
|
8
|
+
/**
|
|
9
|
+
* The editor's user-data folder name under the platform config root
|
|
10
|
+
* (%APPDATA% / ~/Library/Application Support / ~/.config), whose
|
|
11
|
+
* `User/settings.json` Roo Code reads. Absent for remote servers, which have
|
|
12
|
+
* no local settings file of their own.
|
|
13
|
+
*/
|
|
14
|
+
userDir?: string;
|
|
8
15
|
}
|
|
9
16
|
/**
|
|
10
17
|
* VS Code's own per-user extension folders. Detection stays limited to these
|
|
@@ -17,6 +24,18 @@ export declare const VSCODE_EXTENSION_ROOTS: readonly EditorExtensionRoot[];
|
|
|
17
24
|
* installed extension itself rather than writing editor settings.
|
|
18
25
|
*/
|
|
19
26
|
export declare const ALL_EDITOR_EXTENSION_ROOTS: readonly EditorExtensionRoot[];
|
|
27
|
+
export interface RooSettingsTarget {
|
|
28
|
+
editor: string;
|
|
29
|
+
/** That editor's user settings.json, which holds roo-cline.autoImportSettingsPath. */
|
|
30
|
+
settingsFile: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Every settings.json Roo Code reads its auto-import path from: VS Code's
|
|
34
|
+
* (always, as before) plus each VS Code-family editor that has Roo Code
|
|
35
|
+
* installed. A fork reads only its own settings.json, so writing VS Code's
|
|
36
|
+
* alone left Roo in Antigravity, Cursor or Windsurf unconfigured.
|
|
37
|
+
*/
|
|
38
|
+
export declare function rooSettingsTargets(home: string, platform: NodeJS.Platform, env?: NodeJS.ProcessEnv): Promise<RooSettingsTarget[]>;
|
|
20
39
|
export interface RooExtensionDir {
|
|
21
40
|
editor: string;
|
|
22
41
|
/** Absolute extension folder, e.g. ~/.vscode/extensions/rooveterinaryinc.roo-cline-3.54.0 */
|
package/dist/detect/roo-code.js
CHANGED
|
@@ -3,14 +3,15 @@ import fs from 'fs-extra';
|
|
|
3
3
|
import JSON5 from 'json5';
|
|
4
4
|
import { commandExists } from '../utils/exec.js';
|
|
5
5
|
import { clientConfigPath } from '../configure/paths.js';
|
|
6
|
+
import { configRoot } from '../utils/paths.js';
|
|
6
7
|
export const ROO_EXTENSION_PATTERN = /^rooveterinaryinc\.roo-cline-/i;
|
|
7
8
|
/**
|
|
8
9
|
* VS Code's own per-user extension folders. Detection stays limited to these
|
|
9
10
|
* because configure writes VS Code's settings.json, which forks do not read.
|
|
10
11
|
*/
|
|
11
12
|
export const VSCODE_EXTENSION_ROOTS = [
|
|
12
|
-
{ editor: 'VS Code', segments: ['.vscode', 'extensions'] },
|
|
13
|
-
{ editor: 'VS Code Insiders', segments: ['.vscode-insiders', 'extensions'] },
|
|
13
|
+
{ editor: 'VS Code', segments: ['.vscode', 'extensions'], userDir: 'Code' },
|
|
14
|
+
{ editor: 'VS Code Insiders', segments: ['.vscode-insiders', 'extensions'], userDir: 'Code - Insiders' },
|
|
14
15
|
];
|
|
15
16
|
/**
|
|
16
17
|
* Every per-user extension folder Roo Code can be installed into: VS Code,
|
|
@@ -19,14 +20,36 @@ export const VSCODE_EXTENSION_ROOTS = [
|
|
|
19
20
|
*/
|
|
20
21
|
export const ALL_EDITOR_EXTENSION_ROOTS = [
|
|
21
22
|
...VSCODE_EXTENSION_ROOTS,
|
|
22
|
-
{ editor: 'Cursor', segments: ['.cursor', 'extensions'] },
|
|
23
|
-
{ editor: 'Windsurf', segments: ['.windsurf', 'extensions'] },
|
|
24
|
-
{ editor: 'VSCodium', segments: ['.vscode-oss', 'extensions'] },
|
|
23
|
+
{ editor: 'Cursor', segments: ['.cursor', 'extensions'], userDir: 'Cursor' },
|
|
24
|
+
{ editor: 'Windsurf', segments: ['.windsurf', 'extensions'], userDir: 'Windsurf' },
|
|
25
|
+
{ editor: 'VSCodium', segments: ['.vscode-oss', 'extensions'], userDir: 'VSCodium' },
|
|
25
26
|
{ editor: 'VS Code Server', segments: ['.vscode-server', 'extensions'] },
|
|
26
27
|
{ editor: 'Cursor Server', segments: ['.cursor-server', 'extensions'] },
|
|
27
|
-
{ editor: 'Trae', segments: ['.trae', 'extensions'] },
|
|
28
|
-
{ editor: 'Kiro', segments: ['.kiro', 'extensions'] },
|
|
28
|
+
{ editor: 'Trae', segments: ['.trae', 'extensions'], userDir: 'Trae' },
|
|
29
|
+
{ editor: 'Kiro', segments: ['.kiro', 'extensions'], userDir: 'Kiro' },
|
|
30
|
+
// Google Antigravity (VS Code fork, Open VSX). Product.json on Windows,
|
|
31
|
+
// 2.5.5: dataFolderName ".antigravity-ide", user data "%APPDATA%\Antigravity IDE".
|
|
32
|
+
{ editor: 'Antigravity IDE', segments: ['.antigravity-ide', 'extensions'], userDir: 'Antigravity IDE' },
|
|
33
|
+
{ editor: 'Antigravity', segments: ['.antigravity', 'extensions'], userDir: 'Antigravity' },
|
|
29
34
|
];
|
|
35
|
+
/**
|
|
36
|
+
* Every settings.json Roo Code reads its auto-import path from: VS Code's
|
|
37
|
+
* (always, as before) plus each VS Code-family editor that has Roo Code
|
|
38
|
+
* installed. A fork reads only its own settings.json, so writing VS Code's
|
|
39
|
+
* alone left Roo in Antigravity, Cursor or Windsurf unconfigured.
|
|
40
|
+
*/
|
|
41
|
+
export async function rooSettingsTargets(home, platform, env = process.env) {
|
|
42
|
+
const targets = [{ editor: 'VS Code', settingsFile: clientConfigPath('roo-code', home, platform, env) }];
|
|
43
|
+
const root = configRoot(home, platform, env);
|
|
44
|
+
const forks = ALL_EDITOR_EXTENSION_ROOTS.filter(entry => entry.userDir && entry.editor !== 'VS Code');
|
|
45
|
+
for (const hit of await findRooExtensionDirs(home, forks)) {
|
|
46
|
+
const fork = forks.find(entry => entry.editor === hit.editor);
|
|
47
|
+
const settingsFile = path.join(root, fork.userDir, 'User', 'settings.json');
|
|
48
|
+
if (!targets.some(target => target.settingsFile === settingsFile))
|
|
49
|
+
targets.push({ editor: hit.editor, settingsFile });
|
|
50
|
+
}
|
|
51
|
+
return targets;
|
|
52
|
+
}
|
|
30
53
|
/** Roo Code extension folders under the given roots; missing roots are skipped. */
|
|
31
54
|
export async function findRooExtensionDirs(home, roots = VSCODE_EXTENSION_ROOTS) {
|
|
32
55
|
const hits = [];
|
|
@@ -42,7 +65,7 @@ export async function findRooExtensionDirs(home, roots = VSCODE_EXTENSION_ROOTS)
|
|
|
42
65
|
return hits;
|
|
43
66
|
}
|
|
44
67
|
export async function detect(ctx) {
|
|
45
|
-
const paths = (await findRooExtensionDirs(ctx.home)).map(hit => hit.dir);
|
|
68
|
+
const paths = (await findRooExtensionDirs(ctx.home, ALL_EDITOR_EXTENSION_ROOTS.filter(entry => entry.userDir))).map(hit => hit.dir);
|
|
46
69
|
const executable = await commandExists('code', ctx.env);
|
|
47
70
|
if (executable)
|
|
48
71
|
paths.unshift('command:code');
|