theclawbay 0.3.87 → 0.4.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 +3 -2
- package/dist/commands/logout.js +82 -1466
- package/dist/commands/setup.js +143 -3604
- package/dist/lib/base-command.js +7 -5
- package/dist/lib/clients/aider-cleanup.d.ts +1 -0
- package/dist/lib/clients/aider-cleanup.js +15 -0
- package/dist/lib/clients/aider.d.ts +14 -0
- package/dist/lib/clients/aider.js +57 -0
- package/dist/lib/clients/claude-cleanup.d.ts +2 -0
- package/dist/lib/clients/claude-cleanup.js +88 -0
- package/dist/lib/clients/claude.d.ts +49 -0
- package/dist/lib/clients/claude.js +400 -0
- package/dist/lib/clients/cline-cleanup.d.ts +1 -0
- package/dist/lib/clients/cline-cleanup.js +80 -0
- package/dist/lib/clients/cline.d.ts +15 -0
- package/dist/lib/clients/cline.js +73 -0
- package/dist/lib/clients/codex-cleanup.d.ts +7 -0
- package/dist/lib/clients/codex-cleanup.js +145 -0
- package/dist/lib/clients/codex.d.ts +28 -0
- package/dist/lib/clients/codex.js +176 -0
- package/dist/lib/clients/continue-cleanup.d.ts +1 -0
- package/dist/lib/clients/continue-cleanup.js +40 -0
- package/dist/lib/clients/continue.d.ts +22 -0
- package/dist/lib/clients/continue.js +81 -0
- package/dist/lib/clients/gsd-cleanup.d.ts +4 -0
- package/dist/lib/clients/gsd-cleanup.js +168 -0
- package/dist/lib/clients/gsd.d.ts +30 -0
- package/dist/lib/clients/gsd.js +136 -0
- package/dist/lib/clients/hermes-cleanup.d.ts +2 -0
- package/dist/lib/clients/hermes-cleanup.js +112 -0
- package/dist/lib/clients/hermes.d.ts +18 -0
- package/dist/lib/clients/hermes.js +145 -0
- package/dist/lib/clients/openclaw-cleanup.d.ts +1 -0
- package/dist/lib/clients/openclaw-cleanup.js +52 -0
- package/dist/lib/clients/openclaw.d.ts +34 -0
- package/dist/lib/clients/openclaw.js +100 -0
- package/dist/lib/clients/opencode-family-cleanup.d.ts +12 -0
- package/dist/lib/clients/opencode-family-cleanup.js +201 -0
- package/dist/lib/clients/opencode-family.d.ts +86 -0
- package/dist/lib/clients/opencode-family.js +433 -0
- package/dist/lib/clients/roo-cleanup.d.ts +1 -0
- package/dist/lib/clients/roo-cleanup.js +48 -0
- package/dist/lib/clients/roo.d.ts +21 -0
- package/dist/lib/clients/roo.js +91 -0
- package/dist/lib/clients/trae-cleanup.d.ts +2 -0
- package/dist/lib/clients/trae-cleanup.js +40 -0
- package/dist/lib/clients/trae.d.ts +27 -0
- package/dist/lib/clients/trae.js +118 -0
- package/dist/lib/clients/zo.d.ts +39 -0
- package/dist/lib/clients/zo.js +210 -0
- package/dist/lib/shared/backend.d.ts +31 -0
- package/dist/lib/shared/backend.js +273 -0
- package/dist/lib/shared/client-registry.d.ts +23 -0
- package/dist/lib/shared/client-registry.js +68 -0
- package/dist/lib/shared/editor-env-cleanup.d.ts +2 -0
- package/dist/lib/shared/editor-env-cleanup.js +86 -0
- package/dist/lib/shared/editor-env.d.ts +27 -0
- package/dist/lib/shared/editor-env.js +224 -0
- package/dist/lib/shared/env-persist-cleanup.d.ts +4 -0
- package/dist/lib/shared/env-persist-cleanup.js +77 -0
- package/dist/lib/shared/env-persist.d.ts +26 -0
- package/dist/lib/shared/env-persist.js +179 -0
- package/dist/lib/shared/format.d.ts +5 -0
- package/dist/lib/shared/format.js +48 -0
- package/dist/lib/shared/fsx-cleanup.d.ts +3 -0
- package/dist/lib/shared/fsx-cleanup.js +36 -0
- package/dist/lib/shared/fsx.d.ts +9 -0
- package/dist/lib/shared/fsx.js +103 -0
- package/dist/lib/shared/models.d.ts +60 -0
- package/dist/lib/shared/models.js +124 -0
- package/dist/lib/shared/platform.d.ts +16 -0
- package/dist/lib/shared/platform.js +116 -0
- package/dist/lib/shared/prompts.d.ts +29 -0
- package/dist/lib/shared/prompts.js +504 -0
- package/dist/lib/shared/providers.d.ts +3 -0
- package/dist/lib/shared/providers.js +8 -0
- package/dist/lib/shared/toml.d.ts +7 -0
- package/dist/lib/shared/toml.js +157 -0
- package/dist/lib/shared/tui.d.ts +42 -0
- package/dist/lib/shared/tui.js +173 -0
- package/dist/lib/shared/urls.d.ts +18 -0
- package/dist/lib/shared/urls.js +149 -0
- package/dist/lib/supported-models.d.ts +1 -1
- package/dist/lib/supported-models.js +1 -1
- package/package.json +1 -6
- package/theclawbay-supported-models.json +202 -5
package/dist/commands/logout.js
CHANGED
|
@@ -1,1457 +1,73 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
const
|
|
7
|
-
const node_os_1 = __importDefault(require("node:os"));
|
|
8
|
-
const node_path_1 = __importDefault(require("node:path"));
|
|
9
|
-
const node_child_process_1 = require("node:child_process");
|
|
10
|
-
const core_1 = require("@oclif/core");
|
|
11
|
-
const yaml_1 = require("yaml");
|
|
3
|
+
const format_1 = require("../lib/shared/format");
|
|
12
4
|
const base_command_1 = require("../lib/base-command");
|
|
13
|
-
const
|
|
14
|
-
const
|
|
15
|
-
const codex_model_cache_migration_1 = require("../lib/codex-model-cache-migration");
|
|
5
|
+
const tui_1 = require("../lib/shared/tui");
|
|
6
|
+
const core_1 = require("@oclif/core");
|
|
16
7
|
const config_1 = require("../lib/managed/config");
|
|
17
8
|
const errors_1 = require("../lib/managed/errors");
|
|
18
|
-
const
|
|
9
|
+
const codex_history_migration_1 = require("../lib/codex-history-migration");
|
|
10
|
+
const codex_auth_seeding_1 = require("../lib/codex-auth-seeding");
|
|
11
|
+
const codex_model_cache_migration_1 = require("../lib/codex-model-cache-migration");
|
|
12
|
+
const fsx_1 = require("../lib/shared/fsx");
|
|
19
13
|
const paths_1 = require("../lib/config/paths");
|
|
20
|
-
const
|
|
21
|
-
const
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
31
|
-
const
|
|
32
|
-
const
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
const
|
|
36
|
-
const
|
|
37
|
-
const CLAUDE_ENV_SIMPLE_MODE_NAME = "CLAUDE_CODE_SIMPLE";
|
|
38
|
-
const CLAUDE_ENV_DISABLE_NONESSENTIAL_TRAFFIC_NAME = "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC";
|
|
39
|
-
const CLAUDE_ENV_ENABLE_TELEMETRY_NAME = "CLAUDE_CODE_ENABLE_TELEMETRY";
|
|
40
|
-
const CLAUDE_CODE_EDITOR_ENV_SETTING = "claudeCode.environmentVariables";
|
|
41
|
-
const CLAUDE_CODE_EDITOR_DISABLE_LOGIN_PROMPT_SETTING = "claudeCode.disableLoginPrompt";
|
|
42
|
-
const CONTINUE_CONFIG_PATH = node_path_1.default.join(node_os_1.default.homedir(), ".continue", "config.yaml");
|
|
43
|
-
const CLINE_GLOBAL_STATE_PATH = node_path_1.default.join(node_os_1.default.homedir(), ".cline", "data", "globalState.json");
|
|
44
|
-
const CLINE_SECRETS_PATH = node_path_1.default.join(node_os_1.default.homedir(), ".cline", "data", "secrets.json");
|
|
45
|
-
const AIDER_CONFIG_PATH = node_path_1.default.join(node_os_1.default.homedir(), ".aider.conf.yml");
|
|
46
|
-
const GSD_AGENT_DIR = node_path_1.default.join(node_os_1.default.homedir(), ".gsd", "agent");
|
|
47
|
-
const GSD_MODELS_PATH = node_path_1.default.join(GSD_AGENT_DIR, "models.json");
|
|
48
|
-
const GSD_AUTH_PATH = node_path_1.default.join(GSD_AGENT_DIR, "auth.json");
|
|
49
|
-
const GSD_SETTINGS_PATH = node_path_1.default.join(GSD_AGENT_DIR, "settings.json");
|
|
50
|
-
const CLINE_RESTORE_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "cline.restore.json");
|
|
51
|
-
const GSD_RESTORE_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "gsd.restore.json");
|
|
52
|
-
const OPENCODE_RESTORE_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "opencode.restore.json");
|
|
53
|
-
const KILO_RESTORE_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "kilo.restore.json");
|
|
54
|
-
const ROO_SETTINGS_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "roo-settings.restore.json");
|
|
55
|
-
const EDITOR_TERMINAL_ENV_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "editor-terminal-env.restore.json");
|
|
56
|
-
const CLAUDE_EDITOR_SETTINGS_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "claude-editor-settings.restore.json");
|
|
57
|
-
const CLAUDE_DESKTOP_3P_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "claude-desktop-3p.restore.json");
|
|
58
|
-
const CODEX_FEATURE_FLAGS_STATE_PATH = node_path_1.default.join(paths_1.theclawbayStateDir, "codex-features.restore.json");
|
|
59
|
-
const ROO_IMPORT_FILE = node_path_1.default.join(paths_1.theclawbayConfigDir, "roo-code-settings.json");
|
|
60
|
-
const MIGRATION_STATE_FILE = node_path_1.default.join(paths_1.codexDir, "theclawbay.migration.json");
|
|
61
|
-
const HISTORY_PROVIDER_NEUTRALIZE_SOURCES = new Set([
|
|
62
|
-
OPENAI_PROVIDER_ID,
|
|
63
|
-
WAN_PROVIDER_ID,
|
|
64
|
-
DEFAULT_PROVIDER_ID,
|
|
65
|
-
]);
|
|
66
|
-
const HISTORY_PROVIDER_DB_MIGRATE_SOURCES = [DEFAULT_PROVIDER_ID, WAN_PROVIDER_ID];
|
|
67
|
-
const LEGACY_THECLAWBAY_OPENAI_PROXY_SUFFIX = "/api/codex-auth/v1/proxy/v1";
|
|
68
|
-
const CANONICAL_THECLAWBAY_OPENAI_PROXY_SUFFIX = "/v1";
|
|
69
|
-
const CANONICAL_CODEX_NATIVE_PROXY_SUFFIX = "/backend-api/codex";
|
|
70
|
-
const THECLAWBAY_CANONICAL_API_HOST = "api.theclawbay.com";
|
|
71
|
-
const THECLAWBAY_WEBSITE_HOSTS = new Set(["theclawbay.com", "www.theclawbay.com"]);
|
|
72
|
-
const SUPPORTED_MODEL_IDS = new Set((0, supported_models_1.getSupportedModelIds)());
|
|
73
|
-
const CONTINUE_MODEL_NAME = "The Claw Bay";
|
|
74
|
-
const HERMES_PROVIDER_NAME = "The Claw Bay";
|
|
75
|
-
const HERMES_KEY_ENV_NAME = "HERMES_THECLAWBAY_API_KEY";
|
|
76
|
-
const TRAE_PATCH_MARKER = "theclawbay-trae-patch";
|
|
77
|
-
const TRAE_BUNDLE_BACKUP_SUFFIX = ".theclawbay-managed-backup";
|
|
78
|
-
const MANAGED_EDITOR_TERMINAL_ENV_NAMES = [
|
|
79
|
-
ENV_KEY_NAME,
|
|
80
|
-
GEMINI_ENV_API_KEY_NAME,
|
|
81
|
-
GOOGLE_ENV_API_KEY_NAME,
|
|
82
|
-
GOOGLE_GEMINI_BASE_URL_NAME,
|
|
83
|
-
];
|
|
84
|
-
function formatSummaryList(items) {
|
|
85
|
-
return items.join(", ");
|
|
86
|
-
}
|
|
14
|
+
const env_persist_1 = require("../lib/shared/env-persist");
|
|
15
|
+
const env_persist_cleanup_1 = require("../lib/shared/env-persist-cleanup");
|
|
16
|
+
const editor_env_cleanup_1 = require("../lib/shared/editor-env-cleanup");
|
|
17
|
+
const claude_cleanup_1 = require("../lib/clients/claude-cleanup");
|
|
18
|
+
const codex_cleanup_1 = require("../lib/clients/codex-cleanup");
|
|
19
|
+
const codex_1 = require("../lib/clients/codex");
|
|
20
|
+
const providers_1 = require("../lib/shared/providers");
|
|
21
|
+
const continue_cleanup_1 = require("../lib/clients/continue-cleanup");
|
|
22
|
+
const cline_cleanup_1 = require("../lib/clients/cline-cleanup");
|
|
23
|
+
const gsd_cleanup_1 = require("../lib/clients/gsd-cleanup");
|
|
24
|
+
const openclaw_cleanup_1 = require("../lib/clients/openclaw-cleanup");
|
|
25
|
+
const opencode_family_cleanup_1 = require("../lib/clients/opencode-family-cleanup");
|
|
26
|
+
const roo_cleanup_1 = require("../lib/clients/roo-cleanup");
|
|
27
|
+
const hermes_cleanup_1 = require("../lib/clients/hermes-cleanup");
|
|
28
|
+
const trae_cleanup_1 = require("../lib/clients/trae-cleanup");
|
|
29
|
+
const aider_cleanup_1 = require("../lib/clients/aider-cleanup");
|
|
30
|
+
const claude_1 = require("../lib/clients/claude");
|
|
87
31
|
function logLogoutCompactSummary(params) {
|
|
88
|
-
if (
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
else {
|
|
92
|
-
params.log("Reverted: no local tool changes were found.");
|
|
93
|
-
}
|
|
94
|
-
if (params.sharedConfigChanged) {
|
|
95
|
-
params.log("Shared config: removed your local credential env and managed machine setup.");
|
|
96
|
-
}
|
|
97
|
-
else {
|
|
98
|
-
params.log("Shared config: nothing managed needed cleanup.");
|
|
99
|
-
}
|
|
100
|
-
for (const note of params.notes) {
|
|
101
|
-
params.log(`Note: ${note}`);
|
|
102
|
-
}
|
|
103
|
-
params.log("Restart any open terminals or editor windows to clear already-loaded environment.");
|
|
104
|
-
}
|
|
105
|
-
function removeManagedBlock(source, start, end) {
|
|
106
|
-
const markerStart = source.indexOf(start);
|
|
107
|
-
if (markerStart < 0)
|
|
108
|
-
return source;
|
|
109
|
-
const markerEnd = source.indexOf(end, markerStart);
|
|
110
|
-
if (markerEnd < 0)
|
|
111
|
-
return `${source.slice(0, markerStart).trimEnd()}\n`;
|
|
112
|
-
return `${(source.slice(0, markerStart) + source.slice(markerEnd + end.length)).trimEnd()}\n`;
|
|
113
|
-
}
|
|
114
|
-
function removeProviderTable(source, providerId) {
|
|
115
|
-
const header = `[model_providers.${providerId}]`;
|
|
116
|
-
const lines = source.split(/\r?\n/);
|
|
117
|
-
const output = [];
|
|
118
|
-
for (let i = 0; i < lines.length; i++) {
|
|
119
|
-
if ((lines[i] ?? "").trim() !== header) {
|
|
120
|
-
output.push(lines[i] ?? "");
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
i++;
|
|
124
|
-
while (i < lines.length && !/^\s*\[[^\]]+\]\s*$/.test(lines[i] ?? ""))
|
|
125
|
-
i++;
|
|
126
|
-
i--;
|
|
127
|
-
}
|
|
128
|
-
return `${output.join("\n").trimEnd()}\n`;
|
|
129
|
-
}
|
|
130
|
-
function removeTopLevelProviderSelection(source) {
|
|
131
|
-
const lines = source.split(/\r?\n/);
|
|
132
|
-
const filtered = [];
|
|
133
|
-
for (let i = 0; i < lines.length; i++) {
|
|
134
|
-
const line = lines[i] ?? "";
|
|
135
|
-
if (/^\s*\[/.test(line)) {
|
|
136
|
-
filtered.push(...lines.slice(i));
|
|
137
|
-
break;
|
|
138
|
-
}
|
|
139
|
-
if (/^\s*#/.test(line) || !line.trim()) {
|
|
140
|
-
filtered.push(line);
|
|
141
|
-
continue;
|
|
142
|
-
}
|
|
143
|
-
const match = line.match(/^\s*model_provider\s*=\s*"([^"]+)"\s*$/);
|
|
144
|
-
if (!match) {
|
|
145
|
-
filtered.push(line);
|
|
146
|
-
continue;
|
|
147
|
-
}
|
|
148
|
-
if (match[1] === DEFAULT_PROVIDER_ID || match[1] === OPENAI_PROVIDER_ID)
|
|
149
|
-
continue;
|
|
150
|
-
filtered.push(line);
|
|
151
|
-
}
|
|
152
|
-
return `${filtered.join("\n").trimEnd()}\n`;
|
|
153
|
-
}
|
|
154
|
-
function removeTopLevelKeyLineIf(source, key, shouldRemove) {
|
|
155
|
-
const lines = source.split(/\r?\n/);
|
|
156
|
-
const filtered = [];
|
|
157
|
-
let removed = false;
|
|
158
|
-
for (let i = 0; i < lines.length; i++) {
|
|
159
|
-
const line = lines[i] ?? "";
|
|
160
|
-
if (/^\s*\[/.test(line)) {
|
|
161
|
-
filtered.push(...lines.slice(i));
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
if (/^\s*#/.test(line) || !line.trim()) {
|
|
165
|
-
filtered.push(line);
|
|
166
|
-
continue;
|
|
167
|
-
}
|
|
168
|
-
const match = line.match(new RegExp(`^\\s*${key}\\s*=\\s*\"([^\"]*)\"\\s*$`));
|
|
169
|
-
if (!match) {
|
|
170
|
-
filtered.push(line);
|
|
171
|
-
continue;
|
|
172
|
-
}
|
|
173
|
-
if (shouldRemove(match[1] ?? "")) {
|
|
174
|
-
removed = true;
|
|
175
|
-
continue;
|
|
176
|
-
}
|
|
177
|
-
filtered.push(line);
|
|
178
|
-
}
|
|
179
|
-
if (!removed)
|
|
180
|
-
return source;
|
|
181
|
-
return `${filtered.join("\n").trimEnd()}\n`;
|
|
182
|
-
}
|
|
183
|
-
function setTopLevelTableKey(source, tableName, key, tomlValue) {
|
|
184
|
-
const header = `[${tableName}]`;
|
|
185
|
-
const lines = source.split(/\r?\n/);
|
|
186
|
-
let tableStart = -1;
|
|
187
|
-
for (let i = 0; i < lines.length; i++) {
|
|
188
|
-
if ((lines[i] ?? "").trim() === header) {
|
|
189
|
-
tableStart = i;
|
|
190
|
-
break;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
if (tableStart < 0) {
|
|
194
|
-
const block = `${header}\n${key} = ${tomlValue}\n`;
|
|
195
|
-
if (!source.trim())
|
|
196
|
-
return block;
|
|
197
|
-
return `${source.trimEnd()}\n\n${block}`;
|
|
198
|
-
}
|
|
199
|
-
let tableEnd = lines.length;
|
|
200
|
-
for (let i = tableStart + 1; i < lines.length; i++) {
|
|
201
|
-
if (/^\s*\[[^\]]+\]\s*$/.test(lines[i] ?? "")) {
|
|
202
|
-
tableEnd = i;
|
|
203
|
-
break;
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
for (let i = tableStart + 1; i < tableEnd; i++) {
|
|
207
|
-
const line = lines[i] ?? "";
|
|
208
|
-
if (/^\s*#/.test(line))
|
|
209
|
-
continue;
|
|
210
|
-
if (new RegExp(`^\\s*${key}\\s*=`).test(line)) {
|
|
211
|
-
lines[i] = `${key} = ${tomlValue}`;
|
|
212
|
-
return `${lines.join("\n").trimEnd()}\n`;
|
|
213
|
-
}
|
|
214
|
-
}
|
|
215
|
-
lines.splice(tableEnd, 0, `${key} = ${tomlValue}`);
|
|
216
|
-
return `${lines.join("\n").trimEnd()}\n`;
|
|
217
|
-
}
|
|
218
|
-
function removeTopLevelTableKey(source, tableName, key) {
|
|
219
|
-
const header = `[${tableName}]`;
|
|
220
|
-
const lines = source.split(/\r?\n/);
|
|
221
|
-
let tableStart = -1;
|
|
222
|
-
for (let i = 0; i < lines.length; i++) {
|
|
223
|
-
if ((lines[i] ?? "").trim() === header) {
|
|
224
|
-
tableStart = i;
|
|
225
|
-
break;
|
|
226
|
-
}
|
|
227
|
-
}
|
|
228
|
-
if (tableStart < 0)
|
|
229
|
-
return source;
|
|
230
|
-
let tableEnd = lines.length;
|
|
231
|
-
for (let i = tableStart + 1; i < lines.length; i++) {
|
|
232
|
-
if (/^\s*\[[^\]]+\]\s*$/.test(lines[i] ?? "")) {
|
|
233
|
-
tableEnd = i;
|
|
234
|
-
break;
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
let removed = false;
|
|
238
|
-
const nextLines = [...lines];
|
|
239
|
-
for (let i = tableStart + 1; i < tableEnd; i++) {
|
|
240
|
-
const line = nextLines[i] ?? "";
|
|
241
|
-
if (/^\s*#/.test(line))
|
|
242
|
-
continue;
|
|
243
|
-
if (new RegExp(`^\\s*${key}\\s*=`).test(line)) {
|
|
244
|
-
nextLines.splice(i, 1);
|
|
245
|
-
removed = true;
|
|
246
|
-
break;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
if (!removed)
|
|
250
|
-
return source;
|
|
251
|
-
return `${nextLines.join("\n").trimEnd()}\n`;
|
|
252
|
-
}
|
|
253
|
-
function isTheClawBayChatgptBaseUrl(value) {
|
|
254
|
-
const trimmed = value.trim().replace(/\/+$/g, "");
|
|
255
|
-
if (!trimmed)
|
|
256
|
-
return false;
|
|
257
|
-
try {
|
|
258
|
-
const parsed = new URL(trimmed);
|
|
259
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
260
|
-
return hostname === THECLAWBAY_CANONICAL_API_HOST || THECLAWBAY_WEBSITE_HOSTS.has(hostname);
|
|
261
|
-
}
|
|
262
|
-
catch {
|
|
263
|
-
return false;
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
async function readFileIfExists(filePath) {
|
|
267
|
-
try {
|
|
268
|
-
return await promises_1.default.readFile(filePath, "utf8");
|
|
269
|
-
}
|
|
270
|
-
catch (error) {
|
|
271
|
-
const err = error;
|
|
272
|
-
if (err.code === "ENOENT")
|
|
273
|
-
return null;
|
|
274
|
-
throw error;
|
|
275
|
-
}
|
|
276
|
-
}
|
|
277
|
-
function hermesHomeDir() {
|
|
278
|
-
const raw = process.env.HERMES_HOME?.trim();
|
|
279
|
-
if (raw)
|
|
280
|
-
return raw;
|
|
281
|
-
return node_path_1.default.join(node_os_1.default.homedir(), ".hermes");
|
|
282
|
-
}
|
|
283
|
-
function hermesConfigPath() {
|
|
284
|
-
return node_path_1.default.join(hermesHomeDir(), "config.yaml");
|
|
285
|
-
}
|
|
286
|
-
function hermesEnvPath() {
|
|
287
|
-
return node_path_1.default.join(hermesHomeDir(), ".env");
|
|
288
|
-
}
|
|
289
|
-
async function removeDotEnvValue(filePath, key) {
|
|
290
|
-
const existing = await readFileIfExists(filePath);
|
|
291
|
-
if (existing === null)
|
|
292
|
-
return false;
|
|
293
|
-
const nextLines = existing
|
|
294
|
-
.split(/\r?\n/)
|
|
295
|
-
.filter((line) => !new RegExp(`^\\s*${key}\\s*=`).test(line));
|
|
296
|
-
const next = `${nextLines.join("\n").trimEnd()}\n`;
|
|
297
|
-
const normalizedExisting = `${existing.trimEnd()}\n`;
|
|
298
|
-
if (next === normalizedExisting)
|
|
299
|
-
return false;
|
|
300
|
-
if (!next.trim()) {
|
|
301
|
-
return removeFileIfExists(filePath);
|
|
302
|
-
}
|
|
303
|
-
await promises_1.default.mkdir(node_path_1.default.dirname(filePath), { recursive: true });
|
|
304
|
-
await promises_1.default.writeFile(filePath, next, "utf8");
|
|
305
|
-
return true;
|
|
306
|
-
}
|
|
307
|
-
function localAppDataDir() {
|
|
308
|
-
if (process.env.LOCALAPPDATA?.trim())
|
|
309
|
-
return process.env.LOCALAPPDATA;
|
|
310
|
-
return node_path_1.default.join(node_os_1.default.homedir(), "AppData", "Local");
|
|
311
|
-
}
|
|
312
|
-
function traeBundlePath() {
|
|
313
|
-
if (node_os_1.default.platform() !== "win32")
|
|
314
|
-
return null;
|
|
315
|
-
return node_path_1.default.join(localAppDataDir(), "Programs", "Trae", "resources", "app", "node_modules", "@byted-icube", "ai-modules-chat", "dist", "index.js");
|
|
316
|
-
}
|
|
317
|
-
function traeBundleBackupPath(bundlePath) {
|
|
318
|
-
return `${bundlePath}${TRAE_BUNDLE_BACKUP_SUFFIX}`;
|
|
319
|
-
}
|
|
320
|
-
async function removeFileIfExists(filePath) {
|
|
321
|
-
try {
|
|
322
|
-
await promises_1.default.unlink(filePath);
|
|
323
|
-
return true;
|
|
324
|
-
}
|
|
325
|
-
catch (error) {
|
|
326
|
-
const err = error;
|
|
327
|
-
if (err.code === "ENOENT")
|
|
328
|
-
return false;
|
|
329
|
-
throw error;
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
async function writeIfChanged(filePath, next, previous) {
|
|
333
|
-
if (next === previous)
|
|
334
|
-
return false;
|
|
335
|
-
await promises_1.default.writeFile(filePath, next, "utf8");
|
|
336
|
-
return true;
|
|
337
|
-
}
|
|
338
|
-
function objectRecordOr(value, fallback) {
|
|
339
|
-
if (typeof value === "object" && value !== null && !Array.isArray(value))
|
|
340
|
-
return { ...value };
|
|
341
|
-
return fallback;
|
|
342
|
-
}
|
|
343
|
-
function isTheClawBayOpenAiCompatibleBaseUrl(value) {
|
|
344
|
-
if (typeof value !== "string")
|
|
345
|
-
return false;
|
|
346
|
-
const normalized = value.trim();
|
|
347
|
-
if (!normalized)
|
|
348
|
-
return false;
|
|
349
|
-
try {
|
|
350
|
-
const parsed = new URL(normalized);
|
|
351
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
352
|
-
const pathname = parsed.pathname.replace(/\/+$/g, "");
|
|
353
|
-
if (pathname === LEGACY_THECLAWBAY_OPENAI_PROXY_SUFFIX &&
|
|
354
|
-
(THECLAWBAY_WEBSITE_HOSTS.has(hostname) ||
|
|
355
|
-
hostname === "localhost" ||
|
|
356
|
-
hostname === "127.0.0.1" ||
|
|
357
|
-
hostname === "::1")) {
|
|
358
|
-
return true;
|
|
359
|
-
}
|
|
360
|
-
return (hostname === THECLAWBAY_CANONICAL_API_HOST &&
|
|
361
|
-
pathname === CANONICAL_THECLAWBAY_OPENAI_PROXY_SUFFIX);
|
|
362
|
-
}
|
|
363
|
-
catch {
|
|
364
|
-
return false;
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
function isTheClawBayCodexNativeBaseUrl(value) {
|
|
368
|
-
if (typeof value !== "string")
|
|
369
|
-
return false;
|
|
370
|
-
const normalized = value.trim();
|
|
371
|
-
if (!normalized)
|
|
372
|
-
return false;
|
|
373
|
-
try {
|
|
374
|
-
const parsed = new URL(normalized);
|
|
375
|
-
return (parsed.hostname.toLowerCase() === THECLAWBAY_CANONICAL_API_HOST &&
|
|
376
|
-
parsed.pathname.replace(/\/+$/g, "") === CANONICAL_CODEX_NATIVE_PROXY_SUFFIX);
|
|
377
|
-
}
|
|
378
|
-
catch {
|
|
379
|
-
return false;
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
function isTheClawBayAnthropicCompatibleBaseUrl(value) {
|
|
383
|
-
if (typeof value !== "string")
|
|
384
|
-
return false;
|
|
385
|
-
const normalized = value.trim();
|
|
386
|
-
if (!normalized)
|
|
387
|
-
return false;
|
|
388
|
-
try {
|
|
389
|
-
const parsed = new URL(normalized);
|
|
390
|
-
const hostname = parsed.hostname.toLowerCase();
|
|
391
|
-
const pathname = parsed.pathname.replace(/\/+$/g, "");
|
|
392
|
-
return hostname === THECLAWBAY_CANONICAL_API_HOST && pathname === "/anthropic/v1";
|
|
393
|
-
}
|
|
394
|
-
catch {
|
|
395
|
-
return false;
|
|
396
|
-
}
|
|
397
|
-
}
|
|
398
|
-
function uniqueStrings(values) {
|
|
399
|
-
const output = [];
|
|
400
|
-
const seen = new Set();
|
|
401
|
-
for (const value of values) {
|
|
402
|
-
const normalized = value.trim();
|
|
403
|
-
if (!normalized || seen.has(normalized))
|
|
404
|
-
continue;
|
|
405
|
-
seen.add(normalized);
|
|
406
|
-
output.push(normalized);
|
|
407
|
-
}
|
|
408
|
-
return output;
|
|
409
|
-
}
|
|
410
|
-
function xdgConfigHomeDir() {
|
|
411
|
-
const raw = process.env.XDG_CONFIG_HOME?.trim();
|
|
412
|
-
if (raw)
|
|
413
|
-
return raw;
|
|
414
|
-
return node_path_1.default.join(node_os_1.default.homedir(), ".config");
|
|
415
|
-
}
|
|
416
|
-
function configDirCandidates(appName) {
|
|
417
|
-
const home = node_os_1.default.homedir();
|
|
418
|
-
const dirs = [node_path_1.default.join(xdgConfigHomeDir(), appName)];
|
|
419
|
-
if (node_os_1.default.platform() === "darwin") {
|
|
420
|
-
dirs.push(node_path_1.default.join(home, "Library", "Application Support", appName));
|
|
421
|
-
}
|
|
422
|
-
else if (node_os_1.default.platform() === "win32") {
|
|
423
|
-
dirs.push(node_path_1.default.join(roamingAppDataDir(), appName));
|
|
424
|
-
}
|
|
425
|
-
return uniqueStrings(dirs);
|
|
426
|
-
}
|
|
427
|
-
function claudeDesktop3pConfigPath() {
|
|
428
|
-
if (node_os_1.default.platform() !== "darwin")
|
|
429
|
-
return null;
|
|
430
|
-
return node_path_1.default.join(node_os_1.default.homedir(), "Library", "Application Support", "Claude-3p", "claude_desktop_config.json");
|
|
431
|
-
}
|
|
432
|
-
function openCodeConfigCleanupTargets() {
|
|
433
|
-
const home = node_os_1.default.homedir();
|
|
434
|
-
const dirs = configDirCandidates("opencode");
|
|
435
|
-
const candidates = [];
|
|
436
|
-
for (const dir of dirs) {
|
|
437
|
-
candidates.push(node_path_1.default.join(dir, "opencode.json"));
|
|
438
|
-
candidates.push(node_path_1.default.join(dir, ".opencode.json"));
|
|
439
|
-
candidates.push(node_path_1.default.join(dir, "config.json"));
|
|
440
|
-
}
|
|
441
|
-
candidates.push(node_path_1.default.join(home, ".opencode.json"));
|
|
442
|
-
return uniqueStrings(candidates);
|
|
443
|
-
}
|
|
444
|
-
function kiloConfigCleanupTargets() {
|
|
445
|
-
const home = node_os_1.default.homedir();
|
|
446
|
-
const dirs = uniqueStrings([...configDirCandidates("kilo"), node_path_1.default.join(home, ".kilo")]);
|
|
447
|
-
const candidates = [];
|
|
448
|
-
for (const dir of dirs) {
|
|
449
|
-
candidates.push(node_path_1.default.join(dir, "opencode.json"));
|
|
450
|
-
candidates.push(node_path_1.default.join(dir, "config.json"));
|
|
451
|
-
}
|
|
452
|
-
return uniqueStrings(candidates);
|
|
453
|
-
}
|
|
454
|
-
async function readJsonObjectFile(filePath) {
|
|
455
|
-
const existingRaw = await readFileIfExists(filePath);
|
|
456
|
-
if (existingRaw === null || !existingRaw.trim())
|
|
457
|
-
return {};
|
|
458
|
-
try {
|
|
459
|
-
return objectRecordOr(JSON.parse(existingRaw), {});
|
|
460
|
-
}
|
|
461
|
-
catch {
|
|
462
|
-
return {};
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
async function writeJsonFile(filePath, value, mode) {
|
|
466
|
-
await promises_1.default.mkdir(node_path_1.default.dirname(filePath), { recursive: true });
|
|
467
|
-
await promises_1.default.writeFile(filePath, `${JSON.stringify(value, null, 2)}\n`, "utf8");
|
|
468
|
-
if (mode !== undefined)
|
|
469
|
-
await promises_1.default.chmod(filePath, mode);
|
|
470
|
-
}
|
|
471
|
-
function isManagedOpenCodeModel(value) {
|
|
472
|
-
if (typeof value !== "string")
|
|
473
|
-
return false;
|
|
474
|
-
if (!value.startsWith(`${OPENAI_PROVIDER_ID}/`))
|
|
475
|
-
return false;
|
|
476
|
-
return SUPPORTED_MODEL_IDS.has(value.slice(`${OPENAI_PROVIDER_ID}/`.length));
|
|
477
|
-
}
|
|
478
|
-
function isManagedOpenCodeProvider(value) {
|
|
479
|
-
const provider = objectRecordOr(value, {});
|
|
480
|
-
const options = objectRecordOr(provider.options, {});
|
|
481
|
-
return isTheClawBayOpenAiCompatibleBaseUrl(options.baseURL);
|
|
482
|
-
}
|
|
483
|
-
function isManagedOpenCodeAnthropicProvider(value) {
|
|
484
|
-
const provider = objectRecordOr(value, {});
|
|
485
|
-
const options = objectRecordOr(provider.options, {});
|
|
486
|
-
return isTheClawBayAnthropicCompatibleBaseUrl(options.baseURL);
|
|
487
|
-
}
|
|
488
|
-
function roamingAppDataDir() {
|
|
489
|
-
if (process.env.APPDATA?.trim())
|
|
490
|
-
return process.env.APPDATA;
|
|
491
|
-
return node_path_1.default.join(node_os_1.default.homedir(), "AppData", "Roaming");
|
|
492
|
-
}
|
|
493
|
-
function editorSettingsCandidates() {
|
|
494
|
-
const home = node_os_1.default.homedir();
|
|
495
|
-
if (node_os_1.default.platform() === "darwin") {
|
|
496
|
-
const appSupport = node_path_1.default.join(home, "Library", "Application Support");
|
|
497
|
-
return [
|
|
498
|
-
node_path_1.default.join(appSupport, "Code", "User", "settings.json"),
|
|
499
|
-
node_path_1.default.join(appSupport, "Code - Insiders", "User", "settings.json"),
|
|
500
|
-
node_path_1.default.join(appSupport, "Cursor", "User", "settings.json"),
|
|
501
|
-
node_path_1.default.join(appSupport, "Windsurf", "User", "settings.json"),
|
|
502
|
-
node_path_1.default.join(appSupport, "VSCodium", "User", "settings.json"),
|
|
503
|
-
];
|
|
504
|
-
}
|
|
505
|
-
if (node_os_1.default.platform() === "win32") {
|
|
506
|
-
const appData = roamingAppDataDir();
|
|
507
|
-
return [
|
|
508
|
-
node_path_1.default.join(appData, "Code", "User", "settings.json"),
|
|
509
|
-
node_path_1.default.join(appData, "Code - Insiders", "User", "settings.json"),
|
|
510
|
-
node_path_1.default.join(appData, "Cursor", "User", "settings.json"),
|
|
511
|
-
node_path_1.default.join(appData, "Windsurf", "User", "settings.json"),
|
|
512
|
-
node_path_1.default.join(appData, "VSCodium", "User", "settings.json"),
|
|
513
|
-
];
|
|
514
|
-
}
|
|
515
|
-
return [
|
|
516
|
-
node_path_1.default.join(home, ".config", "Code", "User", "settings.json"),
|
|
517
|
-
node_path_1.default.join(home, ".config", "Code - Insiders", "User", "settings.json"),
|
|
518
|
-
node_path_1.default.join(home, ".config", "Cursor", "User", "settings.json"),
|
|
519
|
-
node_path_1.default.join(home, ".config", "Windsurf", "User", "settings.json"),
|
|
520
|
-
node_path_1.default.join(home, ".config", "VSCodium", "User", "settings.json"),
|
|
521
|
-
];
|
|
522
|
-
}
|
|
523
|
-
async function cleanupCodexConfig() {
|
|
524
|
-
const configPath = node_path_1.default.join(paths_1.codexDir, "config.toml");
|
|
525
|
-
const existing = await readFileIfExists(configPath);
|
|
526
|
-
if (existing === null)
|
|
527
|
-
return false;
|
|
528
|
-
let next = existing;
|
|
529
|
-
next = removeManagedBlock(next, MANAGED_START, MANAGED_END);
|
|
530
|
-
next = removeProviderTable(next, DEFAULT_PROVIDER_ID);
|
|
531
|
-
next = removeTopLevelProviderSelection(next);
|
|
532
|
-
next = removeTopLevelKeyLineIf(next, "openai_base_url", isTheClawBayCodexNativeBaseUrl);
|
|
533
|
-
next = removeTopLevelKeyLineIf(next, "chatgpt_base_url", isTheClawBayChatgptBaseUrl);
|
|
534
|
-
return writeIfChanged(configPath, next, existing);
|
|
535
|
-
}
|
|
536
|
-
async function cleanupContinueConfig() {
|
|
537
|
-
const existing = await readFileIfExists(CONTINUE_CONFIG_PATH);
|
|
538
|
-
if (existing === null || !existing.trim())
|
|
539
|
-
return false;
|
|
540
|
-
try {
|
|
541
|
-
const doc = (0, yaml_1.parseDocument)(existing);
|
|
542
|
-
const root = objectRecordOr(doc.toJS(), {});
|
|
543
|
-
const models = Array.isArray(root.models) ? root.models : [];
|
|
544
|
-
const filtered = models.filter((entry) => {
|
|
545
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
546
|
-
return true;
|
|
547
|
-
const candidate = entry;
|
|
548
|
-
return !(candidate.provider === "openai" &&
|
|
549
|
-
candidate.name === CONTINUE_MODEL_NAME &&
|
|
550
|
-
isTheClawBayOpenAiCompatibleBaseUrl(candidate.apiBase));
|
|
551
|
-
});
|
|
552
|
-
if (filtered.length === models.length)
|
|
553
|
-
return false;
|
|
554
|
-
doc.set("models", filtered);
|
|
555
|
-
await promises_1.default.writeFile(CONTINUE_CONFIG_PATH, doc.toString(), "utf8");
|
|
556
|
-
return true;
|
|
557
|
-
}
|
|
558
|
-
catch {
|
|
559
|
-
return false;
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
async function cleanupClineConfig() {
|
|
563
|
-
const globalState = await readJsonObjectFile(CLINE_GLOBAL_STATE_PATH);
|
|
564
|
-
const secrets = await readJsonObjectFile(CLINE_SECRETS_PATH);
|
|
565
|
-
const snapshotRaw = await readFileIfExists(CLINE_RESTORE_STATE_PATH);
|
|
566
|
-
let changed = false;
|
|
567
|
-
if (snapshotRaw?.trim()) {
|
|
568
|
-
try {
|
|
569
|
-
const snapshot = JSON.parse(snapshotRaw);
|
|
570
|
-
for (const [key, value] of Object.entries(snapshot.globalState ?? {})) {
|
|
571
|
-
if (value === null) {
|
|
572
|
-
if (key in globalState) {
|
|
573
|
-
delete globalState[key];
|
|
574
|
-
changed = true;
|
|
575
|
-
}
|
|
576
|
-
continue;
|
|
577
|
-
}
|
|
578
|
-
if (globalState[key] !== value) {
|
|
579
|
-
globalState[key] = value;
|
|
580
|
-
changed = true;
|
|
581
|
-
}
|
|
582
|
-
}
|
|
583
|
-
for (const [key, value] of Object.entries(snapshot.secrets ?? {})) {
|
|
584
|
-
if (value === null) {
|
|
585
|
-
if (key in secrets) {
|
|
586
|
-
delete secrets[key];
|
|
587
|
-
changed = true;
|
|
588
|
-
}
|
|
589
|
-
continue;
|
|
590
|
-
}
|
|
591
|
-
if (secrets[key] !== value) {
|
|
592
|
-
secrets[key] = value;
|
|
593
|
-
changed = true;
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
}
|
|
597
|
-
catch {
|
|
598
|
-
// Fall through to best-effort cleanup below.
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
else {
|
|
602
|
-
if (globalState.planModeApiProvider === OPENAI_PROVIDER_ID) {
|
|
603
|
-
delete globalState.planModeApiProvider;
|
|
604
|
-
changed = true;
|
|
605
|
-
}
|
|
606
|
-
if (globalState.actModeApiProvider === OPENAI_PROVIDER_ID) {
|
|
607
|
-
delete globalState.actModeApiProvider;
|
|
608
|
-
changed = true;
|
|
609
|
-
}
|
|
610
|
-
if (isTheClawBayOpenAiCompatibleBaseUrl(globalState.openAiBaseUrl)) {
|
|
611
|
-
delete globalState.openAiBaseUrl;
|
|
612
|
-
changed = true;
|
|
613
|
-
}
|
|
614
|
-
for (const key of ["planModeOpenAiModelId", "actModeOpenAiModelId"]) {
|
|
615
|
-
if (typeof globalState[key] === "string") {
|
|
616
|
-
delete globalState[key];
|
|
617
|
-
changed = true;
|
|
618
|
-
}
|
|
619
|
-
}
|
|
620
|
-
if (typeof secrets.openAiApiKey === "string") {
|
|
621
|
-
delete secrets.openAiApiKey;
|
|
622
|
-
changed = true;
|
|
623
|
-
}
|
|
624
|
-
}
|
|
625
|
-
if (changed) {
|
|
626
|
-
await writeJsonFile(CLINE_GLOBAL_STATE_PATH, globalState);
|
|
627
|
-
await writeJsonFile(CLINE_SECRETS_PATH, secrets, 0o600);
|
|
628
|
-
}
|
|
629
|
-
await removeFileIfExists(CLINE_RESTORE_STATE_PATH);
|
|
630
|
-
return changed;
|
|
631
|
-
}
|
|
632
|
-
function isEmptyObject(value) {
|
|
633
|
-
return Object.keys(value).length === 0;
|
|
634
|
-
}
|
|
635
|
-
function normalizeGsdRestoreSnapshot(value) {
|
|
636
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
637
|
-
return null;
|
|
638
|
-
const obj = value;
|
|
639
|
-
return {
|
|
640
|
-
version: 1,
|
|
641
|
-
modelsExisted: obj.modelsExisted === true,
|
|
642
|
-
providerConfig: typeof obj.providerConfig === "object" && obj.providerConfig !== null && !Array.isArray(obj.providerConfig)
|
|
643
|
-
? obj.providerConfig
|
|
644
|
-
: null,
|
|
645
|
-
authExisted: obj.authExisted === true,
|
|
646
|
-
authEntry: typeof obj.authEntry === "object" && obj.authEntry !== null && !Array.isArray(obj.authEntry)
|
|
647
|
-
? obj.authEntry
|
|
648
|
-
: null,
|
|
649
|
-
settingsExisted: obj.settingsExisted === true,
|
|
650
|
-
defaultProvider: typeof obj.defaultProvider === "string" ? obj.defaultProvider : null,
|
|
651
|
-
defaultModel: typeof obj.defaultModel === "string" ? obj.defaultModel : null,
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
function normalizeGsdCredential(value) {
|
|
655
|
-
if (typeof value !== "object" || value === null || Array.isArray(value))
|
|
656
|
-
return null;
|
|
657
|
-
return { ...value };
|
|
658
|
-
}
|
|
659
|
-
async function cleanupGsdConfig() {
|
|
660
|
-
const snapshotRaw = await readFileIfExists(GSD_RESTORE_STATE_PATH);
|
|
661
|
-
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
662
|
-
return false;
|
|
663
|
-
let snapshot = null;
|
|
664
|
-
try {
|
|
665
|
-
snapshot = normalizeGsdRestoreSnapshot(JSON.parse(snapshotRaw));
|
|
666
|
-
}
|
|
667
|
-
catch {
|
|
668
|
-
snapshot = null;
|
|
669
|
-
}
|
|
670
|
-
if (!snapshot)
|
|
671
|
-
return false;
|
|
672
|
-
let changed = false;
|
|
673
|
-
const modelsRaw = await readFileIfExists(GSD_MODELS_PATH);
|
|
674
|
-
if (modelsRaw !== null) {
|
|
675
|
-
let fileChanged = false;
|
|
676
|
-
let doc = objectRecordOr({}, {});
|
|
677
|
-
try {
|
|
678
|
-
doc = modelsRaw.trim() ? objectRecordOr(JSON.parse(modelsRaw), {}) : {};
|
|
679
|
-
}
|
|
680
|
-
catch {
|
|
681
|
-
doc = {};
|
|
682
|
-
}
|
|
683
|
-
const providersRoot = objectRecordOr(doc.providers, {});
|
|
684
|
-
if (snapshot.providerConfig) {
|
|
685
|
-
const currentProvider = objectRecordOr(providersRoot[DEFAULT_PROVIDER_ID], {});
|
|
686
|
-
const nextProvider = JSON.stringify(snapshot.providerConfig);
|
|
687
|
-
if (JSON.stringify(currentProvider) !== nextProvider) {
|
|
688
|
-
providersRoot[DEFAULT_PROVIDER_ID] = snapshot.providerConfig;
|
|
689
|
-
fileChanged = true;
|
|
690
|
-
}
|
|
691
|
-
}
|
|
692
|
-
else if (DEFAULT_PROVIDER_ID in providersRoot) {
|
|
693
|
-
delete providersRoot[DEFAULT_PROVIDER_ID];
|
|
694
|
-
fileChanged = true;
|
|
695
|
-
}
|
|
696
|
-
if (isEmptyObject(providersRoot)) {
|
|
697
|
-
if ("providers" in doc)
|
|
698
|
-
fileChanged = true;
|
|
699
|
-
delete doc.providers;
|
|
700
|
-
}
|
|
701
|
-
else {
|
|
702
|
-
doc.providers = providersRoot;
|
|
703
|
-
}
|
|
704
|
-
if (!fileChanged) {
|
|
705
|
-
// Preserve the file exactly if nothing changed.
|
|
706
|
-
}
|
|
707
|
-
else if (!snapshot.modelsExisted && isEmptyObject(doc)) {
|
|
708
|
-
changed = (await removeFileIfExists(GSD_MODELS_PATH)) || changed;
|
|
709
|
-
}
|
|
710
|
-
else {
|
|
711
|
-
await writeJsonFile(GSD_MODELS_PATH, doc);
|
|
712
|
-
changed = true;
|
|
713
|
-
}
|
|
714
|
-
}
|
|
715
|
-
const authRaw = await readFileIfExists(GSD_AUTH_PATH);
|
|
716
|
-
if (authRaw !== null) {
|
|
717
|
-
let fileChanged = false;
|
|
718
|
-
let doc = objectRecordOr({}, {});
|
|
719
|
-
try {
|
|
720
|
-
doc = authRaw.trim() ? objectRecordOr(JSON.parse(authRaw), {}) : {};
|
|
721
|
-
}
|
|
722
|
-
catch {
|
|
723
|
-
doc = {};
|
|
724
|
-
}
|
|
725
|
-
if (snapshot.authEntry) {
|
|
726
|
-
const currentEntry = normalizeGsdCredential(doc[DEFAULT_PROVIDER_ID]);
|
|
727
|
-
const nextEntry = JSON.stringify(snapshot.authEntry);
|
|
728
|
-
if (JSON.stringify(currentEntry) !== nextEntry) {
|
|
729
|
-
doc[DEFAULT_PROVIDER_ID] = snapshot.authEntry;
|
|
730
|
-
fileChanged = true;
|
|
731
|
-
}
|
|
732
|
-
}
|
|
733
|
-
else if (DEFAULT_PROVIDER_ID in doc) {
|
|
734
|
-
delete doc[DEFAULT_PROVIDER_ID];
|
|
735
|
-
fileChanged = true;
|
|
736
|
-
}
|
|
737
|
-
if (!fileChanged) {
|
|
738
|
-
// Preserve the file exactly if nothing changed.
|
|
739
|
-
}
|
|
740
|
-
else if (!snapshot.authExisted && isEmptyObject(doc)) {
|
|
741
|
-
changed = (await removeFileIfExists(GSD_AUTH_PATH)) || changed;
|
|
742
|
-
}
|
|
743
|
-
else {
|
|
744
|
-
await writeJsonFile(GSD_AUTH_PATH, doc, 0o600);
|
|
745
|
-
changed = true;
|
|
746
|
-
}
|
|
747
|
-
}
|
|
748
|
-
const settingsRaw = await readFileIfExists(GSD_SETTINGS_PATH);
|
|
749
|
-
if (settingsRaw !== null) {
|
|
750
|
-
let fileChanged = false;
|
|
751
|
-
let doc = objectRecordOr({}, {});
|
|
752
|
-
try {
|
|
753
|
-
doc = settingsRaw.trim() ? objectRecordOr(JSON.parse(settingsRaw), {}) : {};
|
|
754
|
-
}
|
|
755
|
-
catch {
|
|
756
|
-
doc = {};
|
|
757
|
-
}
|
|
758
|
-
if (doc.defaultProvider === DEFAULT_PROVIDER_ID) {
|
|
759
|
-
if (snapshot.defaultProvider === null) {
|
|
760
|
-
if ("defaultProvider" in doc) {
|
|
761
|
-
delete doc.defaultProvider;
|
|
762
|
-
fileChanged = true;
|
|
763
|
-
}
|
|
764
|
-
}
|
|
765
|
-
else if (doc.defaultProvider !== snapshot.defaultProvider) {
|
|
766
|
-
doc.defaultProvider = snapshot.defaultProvider;
|
|
767
|
-
fileChanged = true;
|
|
768
|
-
}
|
|
769
|
-
if (snapshot.defaultModel === null) {
|
|
770
|
-
if ("defaultModel" in doc) {
|
|
771
|
-
delete doc.defaultModel;
|
|
772
|
-
fileChanged = true;
|
|
773
|
-
}
|
|
774
|
-
}
|
|
775
|
-
else if (doc.defaultModel !== snapshot.defaultModel) {
|
|
776
|
-
doc.defaultModel = snapshot.defaultModel;
|
|
777
|
-
fileChanged = true;
|
|
778
|
-
}
|
|
779
|
-
}
|
|
780
|
-
if (!fileChanged) {
|
|
781
|
-
// Preserve the file exactly if nothing changed.
|
|
782
|
-
}
|
|
783
|
-
else if (!snapshot.settingsExisted && isEmptyObject(doc)) {
|
|
784
|
-
changed = (await removeFileIfExists(GSD_SETTINGS_PATH)) || changed;
|
|
785
|
-
}
|
|
786
|
-
else {
|
|
787
|
-
await writeJsonFile(GSD_SETTINGS_PATH, doc);
|
|
788
|
-
changed = true;
|
|
789
|
-
}
|
|
790
|
-
}
|
|
791
|
-
await removeFileIfExists(GSD_RESTORE_STATE_PATH);
|
|
792
|
-
return changed;
|
|
793
|
-
}
|
|
794
|
-
async function cleanupRooConfig() {
|
|
795
|
-
const snapshotRaw = await readFileIfExists(ROO_SETTINGS_STATE_PATH);
|
|
796
|
-
let changed = false;
|
|
797
|
-
if (snapshotRaw?.trim()) {
|
|
798
|
-
try {
|
|
799
|
-
const entries = JSON.parse(snapshotRaw);
|
|
800
|
-
for (const entry of entries) {
|
|
801
|
-
const settings = await readJsonObjectFile(entry.settingsPath);
|
|
802
|
-
const currentValue = settings["roo-cline.autoImportSettingsPath"];
|
|
803
|
-
if (currentValue !== ROO_IMPORT_FILE)
|
|
804
|
-
continue;
|
|
805
|
-
if (entry.previousValue === null) {
|
|
806
|
-
delete settings["roo-cline.autoImportSettingsPath"];
|
|
807
|
-
}
|
|
808
|
-
else {
|
|
809
|
-
settings["roo-cline.autoImportSettingsPath"] = entry.previousValue;
|
|
810
|
-
}
|
|
811
|
-
await writeJsonFile(entry.settingsPath, settings);
|
|
812
|
-
changed = true;
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
catch {
|
|
816
|
-
// Fall back to common editor settings paths below.
|
|
817
|
-
}
|
|
818
|
-
}
|
|
819
|
-
if (!changed) {
|
|
820
|
-
for (const settingsPath of editorSettingsCandidates()) {
|
|
821
|
-
const settings = await readJsonObjectFile(settingsPath);
|
|
822
|
-
if (settings["roo-cline.autoImportSettingsPath"] !== ROO_IMPORT_FILE)
|
|
823
|
-
continue;
|
|
824
|
-
delete settings["roo-cline.autoImportSettingsPath"];
|
|
825
|
-
await writeJsonFile(settingsPath, settings);
|
|
826
|
-
changed = true;
|
|
827
|
-
}
|
|
828
|
-
}
|
|
829
|
-
const removedImport = await removeFileIfExists(ROO_IMPORT_FILE);
|
|
830
|
-
await removeFileIfExists(ROO_SETTINGS_STATE_PATH);
|
|
831
|
-
return changed || removedImport;
|
|
832
|
-
}
|
|
833
|
-
async function cleanupAiderConfig() {
|
|
834
|
-
const existing = await readFileIfExists(AIDER_CONFIG_PATH);
|
|
835
|
-
if (existing === null)
|
|
836
|
-
return false;
|
|
837
|
-
const next = removeManagedBlock(existing, AIDER_MANAGED_START, AIDER_MANAGED_END);
|
|
838
|
-
return writeIfChanged(AIDER_CONFIG_PATH, next, existing);
|
|
839
|
-
}
|
|
840
|
-
async function cleanupShellFiles() {
|
|
841
|
-
const updated = [];
|
|
842
|
-
const shellRcPaths = [".bashrc", ".zshrc", ".profile"].map((name) => node_path_1.default.join(node_os_1.default.homedir(), name));
|
|
843
|
-
for (const rcPath of shellRcPaths) {
|
|
844
|
-
const existing = await readFileIfExists(rcPath);
|
|
845
|
-
if (existing === null)
|
|
846
|
-
continue;
|
|
847
|
-
const next = removeManagedBlock(existing, SHELL_START, SHELL_END);
|
|
848
|
-
if (await writeIfChanged(rcPath, next, existing))
|
|
849
|
-
updated.push(rcPath);
|
|
850
|
-
}
|
|
851
|
-
return updated;
|
|
852
|
-
}
|
|
853
|
-
function powerShellProfilePaths() {
|
|
854
|
-
const candidates = new Set();
|
|
855
|
-
const addDocumentsProfiles = (documentsDir) => {
|
|
856
|
-
if (!documentsDir)
|
|
857
|
-
return;
|
|
858
|
-
candidates.add(node_path_1.default.join(documentsDir, "PowerShell", "Microsoft.PowerShell_profile.ps1"));
|
|
859
|
-
candidates.add(node_path_1.default.join(documentsDir, "WindowsPowerShell", "Microsoft.PowerShell_profile.ps1"));
|
|
860
|
-
};
|
|
861
|
-
if (node_os_1.default.platform() === "win32") {
|
|
862
|
-
addDocumentsProfiles(node_path_1.default.join(node_os_1.default.homedir(), "Documents"));
|
|
863
|
-
addDocumentsProfiles(resolveWindowsDocumentsDirForHost());
|
|
864
|
-
return [...candidates];
|
|
865
|
-
}
|
|
866
|
-
if (!isWslInteropRuntime())
|
|
867
|
-
return [];
|
|
868
|
-
if (!shouldManageWindowsHostProfilesFromWsl())
|
|
869
|
-
return [];
|
|
870
|
-
addDocumentsProfiles(resolveWindowsDocumentsDirForHost());
|
|
871
|
-
addDocumentsProfiles(resolveWindowsPathForHost(node_path_1.default.join(resolveWindowsHomeDirForHost() ?? "", "Documents")));
|
|
872
|
-
return [...candidates];
|
|
873
|
-
}
|
|
874
|
-
function isWslInteropRuntime() {
|
|
875
|
-
return node_os_1.default.platform() === "linux" && Boolean(process.env.WSL_DISTRO_NAME || process.env.WSL_INTEROP);
|
|
876
|
-
}
|
|
877
|
-
function shouldManageWindowsHostProfilesFromWsl() {
|
|
878
|
-
const mode = (process.env.THECLAWBAY_WINDOWS_PROFILE_MODE ?? "").trim().toLowerCase();
|
|
879
|
-
if (mode === "always")
|
|
880
|
-
return true;
|
|
881
|
-
if (mode === "never")
|
|
882
|
-
return false;
|
|
883
|
-
const home = process.env.HOME?.trim() ?? "";
|
|
884
|
-
const user = process.env.USER?.trim() ?? "";
|
|
885
|
-
if (!home || !user)
|
|
886
|
-
return true;
|
|
887
|
-
return home === node_path_1.default.posix.join("/home", user);
|
|
888
|
-
}
|
|
889
|
-
function readWindowsCommandStdout(command) {
|
|
890
|
-
const shell = node_os_1.default.platform() === "win32" ? "powershell.exe" : isWslInteropRuntime() ? "powershell.exe" : null;
|
|
891
|
-
if (!shell)
|
|
892
|
-
return null;
|
|
893
|
-
const result = (0, node_child_process_1.spawnSync)(shell, ["-NoProfile", "-Command", command], {
|
|
894
|
-
encoding: "utf8",
|
|
895
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
896
|
-
});
|
|
897
|
-
if (result.status !== 0)
|
|
898
|
-
return null;
|
|
899
|
-
const next = result.stdout.replace(/\r/g, "").trim();
|
|
900
|
-
return next ? next : null;
|
|
901
|
-
}
|
|
902
|
-
function resolveWindowsPathForHost(input) {
|
|
903
|
-
if (!input)
|
|
904
|
-
return null;
|
|
905
|
-
const trimmed = input.trim();
|
|
906
|
-
if (!trimmed)
|
|
907
|
-
return null;
|
|
908
|
-
if (node_os_1.default.platform() === "win32")
|
|
909
|
-
return trimmed;
|
|
910
|
-
const match = /^([A-Za-z]):\\(.*)$/.exec(trimmed);
|
|
911
|
-
if (!match)
|
|
912
|
-
return null;
|
|
913
|
-
const drive = match[1].toLowerCase();
|
|
914
|
-
const rest = match[2].replace(/\\/g, "/");
|
|
915
|
-
return node_path_1.default.posix.join("/mnt", drive, rest);
|
|
916
|
-
}
|
|
917
|
-
function resolveWindowsHomeDirForHost() {
|
|
918
|
-
const reported = readWindowsCommandStdout("$env:USERPROFILE");
|
|
919
|
-
if (reported)
|
|
920
|
-
return resolveWindowsPathForHost(reported);
|
|
921
|
-
if (node_os_1.default.platform() === "win32")
|
|
922
|
-
return node_os_1.default.homedir();
|
|
923
|
-
return null;
|
|
924
|
-
}
|
|
925
|
-
function resolveWindowsDocumentsDirForHost() {
|
|
926
|
-
const reported = readWindowsCommandStdout("[Environment]::GetFolderPath('MyDocuments')");
|
|
927
|
-
if (reported)
|
|
928
|
-
return resolveWindowsPathForHost(reported);
|
|
929
|
-
const home = resolveWindowsHomeDirForHost();
|
|
930
|
-
if (!home)
|
|
931
|
-
return null;
|
|
932
|
-
return node_path_1.default.join(home, "Documents");
|
|
933
|
-
}
|
|
934
|
-
async function cleanupPowerShellProfiles() {
|
|
935
|
-
const updated = [];
|
|
936
|
-
for (const profilePath of powerShellProfilePaths()) {
|
|
937
|
-
const existing = await readFileIfExists(profilePath);
|
|
938
|
-
if (existing === null)
|
|
939
|
-
continue;
|
|
940
|
-
const next = removeManagedBlock(existing, SHELL_START, SHELL_END);
|
|
941
|
-
if (await writeIfChanged(profilePath, next, existing))
|
|
942
|
-
updated.push(profilePath);
|
|
943
|
-
}
|
|
944
|
-
return updated;
|
|
945
|
-
}
|
|
946
|
-
async function cleanupVsCodeHooks() {
|
|
947
|
-
const updated = [];
|
|
948
|
-
const homes = [".vscode-server", ".vscode-server-insiders"];
|
|
949
|
-
for (const home of homes) {
|
|
950
|
-
const setupPath = node_path_1.default.join(node_os_1.default.homedir(), home, "server-env-setup");
|
|
951
|
-
const existing = await readFileIfExists(setupPath);
|
|
952
|
-
if (existing === null)
|
|
953
|
-
continue;
|
|
954
|
-
const next = removeManagedBlock(existing, SHELL_START, SHELL_END);
|
|
955
|
-
if (await writeIfChanged(setupPath, next, existing))
|
|
956
|
-
updated.push(setupPath);
|
|
957
|
-
}
|
|
958
|
-
return updated;
|
|
959
|
-
}
|
|
960
|
-
function terminalIntegratedEnvSettingsKey() {
|
|
961
|
-
if (node_os_1.default.platform() === "darwin")
|
|
962
|
-
return "terminal.integrated.env.osx";
|
|
963
|
-
if (node_os_1.default.platform() === "win32")
|
|
964
|
-
return "terminal.integrated.env.windows";
|
|
965
|
-
return "terminal.integrated.env.linux";
|
|
966
|
-
}
|
|
967
|
-
async function cleanupEditorTerminalEnvSettings() {
|
|
968
|
-
const snapshotRaw = await readFileIfExists(EDITOR_TERMINAL_ENV_STATE_PATH);
|
|
969
|
-
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
970
|
-
return [];
|
|
971
|
-
let entries = [];
|
|
972
|
-
try {
|
|
973
|
-
entries = JSON.parse(snapshotRaw);
|
|
974
|
-
}
|
|
975
|
-
catch {
|
|
976
|
-
return [];
|
|
977
|
-
}
|
|
978
|
-
const settingsKey = terminalIntegratedEnvSettingsKey();
|
|
979
|
-
const updated = [];
|
|
980
|
-
for (const entry of entries) {
|
|
981
|
-
const settings = await readJsonObjectFile(entry.settingsPath);
|
|
982
|
-
if (!entry.hadKey) {
|
|
983
|
-
if (Object.prototype.hasOwnProperty.call(settings, settingsKey)) {
|
|
984
|
-
delete settings[settingsKey];
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
else {
|
|
988
|
-
settings[settingsKey] = entry.previousValue;
|
|
989
|
-
}
|
|
990
|
-
if (entry.existed || Object.keys(settings).length > 0) {
|
|
991
|
-
const next = `${JSON.stringify(settings, null, 2)}\n`;
|
|
992
|
-
const existing = await readFileIfExists(entry.settingsPath);
|
|
993
|
-
if (existing !== next) {
|
|
994
|
-
await promises_1.default.mkdir(node_path_1.default.dirname(entry.settingsPath), { recursive: true });
|
|
995
|
-
await promises_1.default.writeFile(entry.settingsPath, next, "utf8");
|
|
996
|
-
updated.push(entry.settingsPath);
|
|
997
|
-
}
|
|
998
|
-
continue;
|
|
999
|
-
}
|
|
1000
|
-
if (await removeFileIfExists(entry.settingsPath)) {
|
|
1001
|
-
updated.push(entry.settingsPath);
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
await removeFileIfExists(EDITOR_TERMINAL_ENV_STATE_PATH);
|
|
1005
|
-
return updated;
|
|
1006
|
-
}
|
|
1007
|
-
async function cleanupClaudeEditorSettings() {
|
|
1008
|
-
const snapshotRaw = await readFileIfExists(CLAUDE_EDITOR_SETTINGS_STATE_PATH);
|
|
1009
|
-
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
1010
|
-
return [];
|
|
1011
|
-
let entries = [];
|
|
1012
|
-
try {
|
|
1013
|
-
entries = JSON.parse(snapshotRaw);
|
|
1014
|
-
}
|
|
1015
|
-
catch {
|
|
1016
|
-
return [];
|
|
1017
|
-
}
|
|
1018
|
-
const updated = [];
|
|
1019
|
-
for (const entry of entries) {
|
|
1020
|
-
const settings = await readJsonObjectFile(entry.settingsPath);
|
|
1021
|
-
if (!entry.envHadKey) {
|
|
1022
|
-
delete settings[CLAUDE_CODE_EDITOR_ENV_SETTING];
|
|
32
|
+
if (!process.stdout.isTTY) {
|
|
33
|
+
if (params.revertedTargets.length > 0) {
|
|
34
|
+
params.log(`Reverted: ${(0, format_1.formatSummaryList)(params.revertedTargets)}`);
|
|
1023
35
|
}
|
|
1024
36
|
else {
|
|
1025
|
-
|
|
37
|
+
params.log("Reverted: no local tool changes were found.");
|
|
1026
38
|
}
|
|
1027
|
-
if (
|
|
1028
|
-
|
|
39
|
+
if (params.sharedConfigChanged) {
|
|
40
|
+
params.log("Shared config: removed your local credential env and managed machine setup.");
|
|
1029
41
|
}
|
|
1030
42
|
else {
|
|
1031
|
-
|
|
1032
|
-
}
|
|
1033
|
-
if (entry.existed || Object.keys(settings).length > 0) {
|
|
1034
|
-
const next = `${JSON.stringify(settings, null, 2)}\n`;
|
|
1035
|
-
const existing = await readFileIfExists(entry.settingsPath);
|
|
1036
|
-
if (existing !== next) {
|
|
1037
|
-
await promises_1.default.mkdir(node_path_1.default.dirname(entry.settingsPath), { recursive: true });
|
|
1038
|
-
await promises_1.default.writeFile(entry.settingsPath, next, "utf8");
|
|
1039
|
-
updated.push(entry.settingsPath);
|
|
1040
|
-
}
|
|
1041
|
-
continue;
|
|
43
|
+
params.log("Shared config: nothing managed needed cleanup.");
|
|
1042
44
|
}
|
|
1043
|
-
|
|
1044
|
-
|
|
45
|
+
for (const note of params.notes) {
|
|
46
|
+
params.log(`Note: ${note}`);
|
|
1045
47
|
}
|
|
48
|
+
params.log("Restart any open terminals or editor windows to clear already-loaded environment.");
|
|
49
|
+
return;
|
|
1046
50
|
}
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
}
|
|
1050
|
-
async function cleanupClaudeDesktop3pConfig() {
|
|
1051
|
-
const snapshotRaw = await readFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
1052
|
-
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
1053
|
-
return false;
|
|
1054
|
-
let snapshot = null;
|
|
1055
|
-
try {
|
|
1056
|
-
snapshot = JSON.parse(snapshotRaw);
|
|
1057
|
-
}
|
|
1058
|
-
catch {
|
|
1059
|
-
snapshot = null;
|
|
1060
|
-
}
|
|
1061
|
-
if (!snapshot?.configPath) {
|
|
1062
|
-
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
1063
|
-
return false;
|
|
1064
|
-
}
|
|
1065
|
-
if (!snapshot.existed) {
|
|
1066
|
-
const removed = await removeFileIfExists(snapshot.configPath);
|
|
1067
|
-
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
1068
|
-
return removed;
|
|
1069
|
-
}
|
|
1070
|
-
const previousRaw = snapshot.previousRaw ?? "";
|
|
1071
|
-
await promises_1.default.mkdir(node_path_1.default.dirname(snapshot.configPath), { recursive: true });
|
|
1072
|
-
const existingRaw = await readFileIfExists(snapshot.configPath);
|
|
1073
|
-
if (existingRaw === previousRaw) {
|
|
1074
|
-
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
1075
|
-
return false;
|
|
1076
|
-
}
|
|
1077
|
-
await promises_1.default.writeFile(snapshot.configPath, previousRaw, "utf8");
|
|
1078
|
-
await removeFileIfExists(CLAUDE_DESKTOP_3P_STATE_PATH);
|
|
1079
|
-
return true;
|
|
1080
|
-
}
|
|
1081
|
-
async function cleanupCodexFeatureFlags() {
|
|
1082
|
-
const snapshotRaw = await readFileIfExists(CODEX_FEATURE_FLAGS_STATE_PATH);
|
|
1083
|
-
if (snapshotRaw === null || !snapshotRaw.trim())
|
|
1084
|
-
return false;
|
|
1085
|
-
let snapshot = null;
|
|
1086
|
-
try {
|
|
1087
|
-
snapshot = JSON.parse(snapshotRaw);
|
|
1088
|
-
}
|
|
1089
|
-
catch {
|
|
1090
|
-
snapshot = null;
|
|
1091
|
-
}
|
|
1092
|
-
if (!snapshot)
|
|
1093
|
-
return false;
|
|
1094
|
-
const configPath = node_path_1.default.join(paths_1.codexDir, "config.toml");
|
|
1095
|
-
const existing = await readFileIfExists(configPath);
|
|
1096
|
-
if (existing === null) {
|
|
1097
|
-
await removeFileIfExists(CODEX_FEATURE_FLAGS_STATE_PATH);
|
|
1098
|
-
return false;
|
|
1099
|
-
}
|
|
1100
|
-
let next = existing;
|
|
1101
|
-
if (snapshot.appsHadKey && snapshot.appsPreviousValue !== null) {
|
|
1102
|
-
next = setTopLevelTableKey(next, "features", "apps", snapshot.appsPreviousValue);
|
|
51
|
+
const lines = [];
|
|
52
|
+
if (params.revertedTargets.length > 0) {
|
|
53
|
+
lines.push((0, tui_1.statusLine)("ok", `Reverted ${(0, format_1.formatSummaryList)(params.revertedTargets)}`));
|
|
1103
54
|
}
|
|
1104
55
|
else {
|
|
1105
|
-
|
|
56
|
+
lines.push((0, tui_1.statusLine)("info", "No local tool changes were found."));
|
|
1106
57
|
}
|
|
1107
|
-
if (
|
|
1108
|
-
|
|
58
|
+
if (params.sharedConfigChanged) {
|
|
59
|
+
lines.push((0, tui_1.statusLine)("ok", "Removed your local credential env and managed machine setup."));
|
|
1109
60
|
}
|
|
1110
61
|
else {
|
|
1111
|
-
|
|
1112
|
-
}
|
|
1113
|
-
await removeFileIfExists(CODEX_FEATURE_FLAGS_STATE_PATH);
|
|
1114
|
-
return writeIfChanged(configPath, next, existing);
|
|
1115
|
-
}
|
|
1116
|
-
async function cleanupOpenClawConfig() {
|
|
1117
|
-
const configPath = node_path_1.default.join(node_os_1.default.homedir(), ".openclaw", "openclaw.json");
|
|
1118
|
-
const existingRaw = await readFileIfExists(configPath);
|
|
1119
|
-
if (existingRaw === null || !existingRaw.trim())
|
|
1120
|
-
return false;
|
|
1121
|
-
let doc;
|
|
1122
|
-
try {
|
|
1123
|
-
doc = objectRecordOr(JSON.parse(existingRaw), {});
|
|
1124
|
-
}
|
|
1125
|
-
catch {
|
|
1126
|
-
return false;
|
|
1127
|
-
}
|
|
1128
|
-
let changed = false;
|
|
1129
|
-
const modelsRoot = objectRecordOr(doc.models, {});
|
|
1130
|
-
const providersRoot = objectRecordOr(modelsRoot.providers, {});
|
|
1131
|
-
for (const id of [DEFAULT_PROVIDER_ID]) {
|
|
1132
|
-
if (id in providersRoot) {
|
|
1133
|
-
delete providersRoot[id];
|
|
1134
|
-
changed = true;
|
|
1135
|
-
}
|
|
1136
|
-
}
|
|
1137
|
-
modelsRoot.providers = providersRoot;
|
|
1138
|
-
doc.models = modelsRoot;
|
|
1139
|
-
const agentsRoot = objectRecordOr(doc.agents, {});
|
|
1140
|
-
const defaultsRoot = objectRecordOr(agentsRoot.defaults, {});
|
|
1141
|
-
const modelRoot = objectRecordOr(defaultsRoot.model, {});
|
|
1142
|
-
const primary = modelRoot.primary;
|
|
1143
|
-
if (typeof primary === "string" && primary.startsWith(`${DEFAULT_PROVIDER_ID}/`)) {
|
|
1144
|
-
delete modelRoot.primary;
|
|
1145
|
-
changed = true;
|
|
1146
|
-
}
|
|
1147
|
-
defaultsRoot.model = modelRoot;
|
|
1148
|
-
agentsRoot.defaults = defaultsRoot;
|
|
1149
|
-
doc.agents = agentsRoot;
|
|
1150
|
-
if (!changed)
|
|
1151
|
-
return false;
|
|
1152
|
-
await promises_1.default.writeFile(configPath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
|
|
1153
|
-
return true;
|
|
1154
|
-
}
|
|
1155
|
-
function normalizeOpenCodeRestoreSnapshot(snapshot, fallbackConfigPath) {
|
|
1156
|
-
if (typeof snapshot !== "object" || snapshot === null || Array.isArray(snapshot))
|
|
1157
|
-
return null;
|
|
1158
|
-
const obj = snapshot;
|
|
1159
|
-
if ((obj.version === 2 || obj.version === 3) && Array.isArray(obj.targets)) {
|
|
1160
|
-
const targets = [];
|
|
1161
|
-
for (const entry of obj.targets) {
|
|
1162
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
1163
|
-
continue;
|
|
1164
|
-
const candidate = entry;
|
|
1165
|
-
const configPath = typeof candidate.configPath === "string" ? candidate.configPath.trim() : "";
|
|
1166
|
-
if (!configPath)
|
|
1167
|
-
continue;
|
|
1168
|
-
targets.push({
|
|
1169
|
-
configPath,
|
|
1170
|
-
existed: candidate.existed === true,
|
|
1171
|
-
openAiProvider: typeof candidate.openAiProvider === "object" &&
|
|
1172
|
-
candidate.openAiProvider !== null &&
|
|
1173
|
-
!Array.isArray(candidate.openAiProvider)
|
|
1174
|
-
? candidate.openAiProvider
|
|
1175
|
-
: null,
|
|
1176
|
-
anthropicProvider: typeof candidate.anthropicProvider === "object" &&
|
|
1177
|
-
candidate.anthropicProvider !== null &&
|
|
1178
|
-
!Array.isArray(candidate.anthropicProvider)
|
|
1179
|
-
? candidate.anthropicProvider
|
|
1180
|
-
: null,
|
|
1181
|
-
model: typeof candidate.model === "string" ? candidate.model : null,
|
|
1182
|
-
schema: typeof candidate.schema === "string" ? candidate.schema : null,
|
|
1183
|
-
plugin: "plugin" in candidate
|
|
1184
|
-
? Array.isArray(candidate.plugin)
|
|
1185
|
-
? candidate.plugin
|
|
1186
|
-
: null
|
|
1187
|
-
: undefined,
|
|
1188
|
-
});
|
|
1189
|
-
}
|
|
1190
|
-
return { version: 3, targets };
|
|
1191
|
-
}
|
|
1192
|
-
const looksLikeV1 = "openAiProvider" in obj || "model" in obj || "schema" in obj;
|
|
1193
|
-
if (!looksLikeV1)
|
|
1194
|
-
return null;
|
|
1195
|
-
return {
|
|
1196
|
-
version: 3,
|
|
1197
|
-
targets: [
|
|
1198
|
-
{
|
|
1199
|
-
configPath: fallbackConfigPath,
|
|
1200
|
-
existed: true,
|
|
1201
|
-
openAiProvider: typeof obj.openAiProvider === "object" && obj.openAiProvider !== null && !Array.isArray(obj.openAiProvider)
|
|
1202
|
-
? obj.openAiProvider
|
|
1203
|
-
: null,
|
|
1204
|
-
model: typeof obj.model === "string" ? obj.model : null,
|
|
1205
|
-
schema: typeof obj.schema === "string" ? obj.schema : null,
|
|
1206
|
-
},
|
|
1207
|
-
],
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
async function readOpenCodeRestoreSnapshot(restoreStatePath, fallbackConfigPath) {
|
|
1211
|
-
const existingRaw = await readFileIfExists(restoreStatePath);
|
|
1212
|
-
if (existingRaw === null || !existingRaw.trim())
|
|
1213
|
-
return null;
|
|
1214
|
-
try {
|
|
1215
|
-
return normalizeOpenCodeRestoreSnapshot(JSON.parse(existingRaw), fallbackConfigPath);
|
|
1216
|
-
}
|
|
1217
|
-
catch {
|
|
1218
|
-
return null;
|
|
62
|
+
lines.push((0, tui_1.statusLine)("info", "Nothing managed needed cleanup."));
|
|
1219
63
|
}
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
const configPaths = uniqueStrings(params.configPaths);
|
|
1223
|
-
const fallbackConfigPath = configPaths[0] ?? node_path_1.default.join(xdgConfigHomeDir(), "opencode", "opencode.json");
|
|
1224
|
-
const snapshot = await readOpenCodeRestoreSnapshot(params.restoreStatePath, fallbackConfigPath);
|
|
1225
|
-
const snapshotTargets = snapshot?.targets ?? [];
|
|
1226
|
-
let changed = false;
|
|
1227
|
-
const restoreConfig = async (target) => {
|
|
1228
|
-
if (!target.existed) {
|
|
1229
|
-
changed = (await removeFileIfExists(target.configPath)) || changed;
|
|
1230
|
-
return;
|
|
1231
|
-
}
|
|
1232
|
-
const existingRaw = await readFileIfExists(target.configPath);
|
|
1233
|
-
if (existingRaw === null || !existingRaw.trim()) {
|
|
1234
|
-
return;
|
|
1235
|
-
}
|
|
1236
|
-
let doc;
|
|
1237
|
-
try {
|
|
1238
|
-
doc = objectRecordOr(JSON.parse(existingRaw), {});
|
|
1239
|
-
}
|
|
1240
|
-
catch {
|
|
1241
|
-
return;
|
|
1242
|
-
}
|
|
1243
|
-
const providerRoot = objectRecordOr(doc.provider, {});
|
|
1244
|
-
if (DEFAULT_PROVIDER_ID in providerRoot) {
|
|
1245
|
-
delete providerRoot[DEFAULT_PROVIDER_ID];
|
|
1246
|
-
changed = true;
|
|
1247
|
-
}
|
|
1248
|
-
if (Object.prototype.hasOwnProperty.call(target, "plugin")) {
|
|
1249
|
-
if (target.plugin === null) {
|
|
1250
|
-
if ("plugin" in doc) {
|
|
1251
|
-
delete doc.plugin;
|
|
1252
|
-
changed = true;
|
|
1253
|
-
}
|
|
1254
|
-
}
|
|
1255
|
-
else {
|
|
1256
|
-
doc.plugin = target.plugin;
|
|
1257
|
-
changed = true;
|
|
1258
|
-
}
|
|
1259
|
-
}
|
|
1260
|
-
if (target.openAiProvider) {
|
|
1261
|
-
providerRoot[OPENAI_PROVIDER_ID] = target.openAiProvider;
|
|
1262
|
-
}
|
|
1263
|
-
else if (OPENAI_PROVIDER_ID in providerRoot) {
|
|
1264
|
-
delete providerRoot[OPENAI_PROVIDER_ID];
|
|
1265
|
-
changed = true;
|
|
1266
|
-
}
|
|
1267
|
-
if (target.anthropicProvider) {
|
|
1268
|
-
providerRoot[ANTHROPIC_PROVIDER_ID] = target.anthropicProvider;
|
|
1269
|
-
changed = true;
|
|
1270
|
-
}
|
|
1271
|
-
else if (ANTHROPIC_PROVIDER_ID in providerRoot) {
|
|
1272
|
-
delete providerRoot[ANTHROPIC_PROVIDER_ID];
|
|
1273
|
-
changed = true;
|
|
1274
|
-
}
|
|
1275
|
-
doc.provider = providerRoot;
|
|
1276
|
-
if (target.model === null) {
|
|
1277
|
-
if (isManagedOpenCodeModel(doc.model) || (typeof doc.model === "string" && doc.model.startsWith(`${DEFAULT_PROVIDER_ID}/`))) {
|
|
1278
|
-
delete doc.model;
|
|
1279
|
-
changed = true;
|
|
1280
|
-
}
|
|
1281
|
-
}
|
|
1282
|
-
else {
|
|
1283
|
-
doc.model = target.model;
|
|
1284
|
-
changed = true;
|
|
1285
|
-
}
|
|
1286
|
-
if (target.schema === null) {
|
|
1287
|
-
if (typeof doc.$schema === "string") {
|
|
1288
|
-
delete doc.$schema;
|
|
1289
|
-
changed = true;
|
|
1290
|
-
}
|
|
1291
|
-
}
|
|
1292
|
-
else {
|
|
1293
|
-
doc.$schema = target.schema;
|
|
1294
|
-
changed = true;
|
|
1295
|
-
}
|
|
1296
|
-
await promises_1.default.writeFile(target.configPath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
|
|
1297
|
-
};
|
|
1298
|
-
if (snapshotTargets.length > 0) {
|
|
1299
|
-
for (const target of snapshotTargets) {
|
|
1300
|
-
await restoreConfig(target);
|
|
1301
|
-
}
|
|
1302
|
-
await removeFileIfExists(params.restoreStatePath);
|
|
1303
|
-
return changed;
|
|
1304
|
-
}
|
|
1305
|
-
for (const configPath of configPaths) {
|
|
1306
|
-
const existingRaw = await readFileIfExists(configPath);
|
|
1307
|
-
if (existingRaw === null || !existingRaw.trim())
|
|
1308
|
-
continue;
|
|
1309
|
-
let doc;
|
|
1310
|
-
try {
|
|
1311
|
-
doc = objectRecordOr(JSON.parse(existingRaw), {});
|
|
1312
|
-
}
|
|
1313
|
-
catch {
|
|
1314
|
-
continue;
|
|
1315
|
-
}
|
|
1316
|
-
let fileChanged = false;
|
|
1317
|
-
const providerRoot = objectRecordOr(doc.provider, {});
|
|
1318
|
-
if (DEFAULT_PROVIDER_ID in providerRoot) {
|
|
1319
|
-
delete providerRoot[DEFAULT_PROVIDER_ID];
|
|
1320
|
-
fileChanged = true;
|
|
1321
|
-
}
|
|
1322
|
-
const model = doc.model;
|
|
1323
|
-
if (typeof model === "string" &&
|
|
1324
|
-
(model.startsWith(`${DEFAULT_PROVIDER_ID}/`) || isManagedOpenCodeModel(model))) {
|
|
1325
|
-
delete doc.model;
|
|
1326
|
-
fileChanged = true;
|
|
1327
|
-
}
|
|
1328
|
-
if (isManagedOpenCodeProvider(providerRoot[OPENAI_PROVIDER_ID])) {
|
|
1329
|
-
delete providerRoot[OPENAI_PROVIDER_ID];
|
|
1330
|
-
fileChanged = true;
|
|
1331
|
-
}
|
|
1332
|
-
if (isManagedOpenCodeAnthropicProvider(providerRoot[ANTHROPIC_PROVIDER_ID])) {
|
|
1333
|
-
delete providerRoot[ANTHROPIC_PROVIDER_ID];
|
|
1334
|
-
fileChanged = true;
|
|
1335
|
-
}
|
|
1336
|
-
if (!fileChanged)
|
|
1337
|
-
continue;
|
|
1338
|
-
changed = true;
|
|
1339
|
-
doc.provider = providerRoot;
|
|
1340
|
-
await promises_1.default.writeFile(configPath, `${JSON.stringify(doc, null, 2)}\n`, "utf8");
|
|
1341
|
-
}
|
|
1342
|
-
await removeFileIfExists(params.restoreStatePath);
|
|
1343
|
-
return changed;
|
|
1344
|
-
}
|
|
1345
|
-
async function cleanupOpenCodeConfig() {
|
|
1346
|
-
return cleanupOpenCodeFamilyConfigs({
|
|
1347
|
-
configPaths: openCodeConfigCleanupTargets(),
|
|
1348
|
-
restoreStatePath: OPENCODE_RESTORE_STATE_PATH,
|
|
1349
|
-
});
|
|
1350
|
-
}
|
|
1351
|
-
async function cleanupKiloConfig() {
|
|
1352
|
-
return cleanupOpenCodeFamilyConfigs({
|
|
1353
|
-
configPaths: kiloConfigCleanupTargets(),
|
|
1354
|
-
restoreStatePath: KILO_RESTORE_STATE_PATH,
|
|
1355
|
-
});
|
|
1356
|
-
}
|
|
1357
|
-
async function cleanupHermesConfig() {
|
|
1358
|
-
const configPath = hermesConfigPath();
|
|
1359
|
-
const envPath = hermesEnvPath();
|
|
1360
|
-
const existingRaw = await readFileIfExists(configPath);
|
|
1361
|
-
let configChanged = false;
|
|
1362
|
-
let removedManagedProvider = false;
|
|
1363
|
-
const removedProviderBaseUrls = new Set();
|
|
1364
|
-
if (existingRaw !== null && existingRaw.trim()) {
|
|
1365
|
-
try {
|
|
1366
|
-
const existingConfig = objectRecordOr((0, yaml_1.parseDocument)(existingRaw).toJS(), {});
|
|
1367
|
-
const nextConfig = { ...existingConfig };
|
|
1368
|
-
const rawCustomProviders = Array.isArray(existingConfig.custom_providers)
|
|
1369
|
-
? existingConfig.custom_providers
|
|
1370
|
-
: [];
|
|
1371
|
-
const nextCustomProviders = rawCustomProviders.filter((entry) => {
|
|
1372
|
-
if (typeof entry !== "object" || entry === null || Array.isArray(entry))
|
|
1373
|
-
return true;
|
|
1374
|
-
const record = entry;
|
|
1375
|
-
const name = typeof record.name === "string" ? record.name.trim() : "";
|
|
1376
|
-
const providerBaseUrl = typeof record.base_url === "string" ? record.base_url.trim().replace(/\/+$/g, "") : "";
|
|
1377
|
-
const keyEnv = typeof record.key_env === "string" ? record.key_env.trim() : "";
|
|
1378
|
-
if (keyEnv === HERMES_KEY_ENV_NAME) {
|
|
1379
|
-
removedManagedProvider = true;
|
|
1380
|
-
if (providerBaseUrl)
|
|
1381
|
-
removedProviderBaseUrls.add(providerBaseUrl);
|
|
1382
|
-
return false;
|
|
1383
|
-
}
|
|
1384
|
-
if (name === HERMES_PROVIDER_NAME && isTheClawBayOpenAiCompatibleBaseUrl(providerBaseUrl)) {
|
|
1385
|
-
removedManagedProvider = true;
|
|
1386
|
-
if (providerBaseUrl)
|
|
1387
|
-
removedProviderBaseUrls.add(providerBaseUrl);
|
|
1388
|
-
return false;
|
|
1389
|
-
}
|
|
1390
|
-
return true;
|
|
1391
|
-
});
|
|
1392
|
-
if (nextCustomProviders.length !== rawCustomProviders.length) {
|
|
1393
|
-
configChanged = true;
|
|
1394
|
-
}
|
|
1395
|
-
if (nextCustomProviders.length > 0) {
|
|
1396
|
-
nextConfig.custom_providers = nextCustomProviders;
|
|
1397
|
-
}
|
|
1398
|
-
else if ("custom_providers" in nextConfig) {
|
|
1399
|
-
delete nextConfig.custom_providers;
|
|
1400
|
-
configChanged = true;
|
|
1401
|
-
}
|
|
1402
|
-
const modelConfig = objectRecordOr(existingConfig.model, {});
|
|
1403
|
-
const provider = typeof modelConfig.provider === "string" ? modelConfig.provider.trim() : "";
|
|
1404
|
-
const baseUrl = typeof modelConfig.base_url === "string" ? modelConfig.base_url.trim().replace(/\/+$/g, "") : "";
|
|
1405
|
-
const apiMode = typeof modelConfig.api_mode === "string" ? modelConfig.api_mode.trim() : "";
|
|
1406
|
-
const shouldRemoveManagedModel = provider === "custom" &&
|
|
1407
|
-
(isTheClawBayOpenAiCompatibleBaseUrl(baseUrl) ||
|
|
1408
|
-
(removedManagedProvider && apiMode === "codex_responses" && removedProviderBaseUrls.has(baseUrl)));
|
|
1409
|
-
if (shouldRemoveManagedModel) {
|
|
1410
|
-
for (const key of ["provider", "default", "base_url", "api_mode", "api_key", "context_length"]) {
|
|
1411
|
-
if (key in modelConfig) {
|
|
1412
|
-
delete modelConfig[key];
|
|
1413
|
-
configChanged = true;
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
if (Object.keys(modelConfig).length > 0) {
|
|
1417
|
-
nextConfig.model = modelConfig;
|
|
1418
|
-
}
|
|
1419
|
-
else if ("model" in nextConfig) {
|
|
1420
|
-
delete nextConfig.model;
|
|
1421
|
-
configChanged = true;
|
|
1422
|
-
}
|
|
1423
|
-
}
|
|
1424
|
-
if (configChanged) {
|
|
1425
|
-
await promises_1.default.mkdir(node_path_1.default.dirname(configPath), { recursive: true });
|
|
1426
|
-
await promises_1.default.writeFile(configPath, (0, yaml_1.stringify)(nextConfig), "utf8");
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
catch {
|
|
1430
|
-
// Leave invalid user config untouched; still remove our dedicated env key below.
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
const envChanged = await removeDotEnvValue(envPath, HERMES_KEY_ENV_NAME);
|
|
1434
|
-
return configChanged || envChanged;
|
|
1435
|
-
}
|
|
1436
|
-
async function cleanupTraeBundle() {
|
|
1437
|
-
const bundlePath = traeBundlePath();
|
|
1438
|
-
if (!bundlePath)
|
|
1439
|
-
return false;
|
|
1440
|
-
const existing = await readFileIfExists(bundlePath);
|
|
1441
|
-
if (existing === null)
|
|
1442
|
-
return false;
|
|
1443
|
-
const backupPath = traeBundleBackupPath(bundlePath);
|
|
1444
|
-
const backup = await readFileIfExists(backupPath);
|
|
1445
|
-
const isPatched = existing.includes(TRAE_PATCH_MARKER);
|
|
1446
|
-
if (isPatched && backup !== null) {
|
|
1447
|
-
await promises_1.default.writeFile(bundlePath, backup, "utf8");
|
|
1448
|
-
await removeFileIfExists(backupPath);
|
|
1449
|
-
return true;
|
|
64
|
+
for (const note of params.notes) {
|
|
65
|
+
lines.push((0, tui_1.statusLine)("info", note));
|
|
1450
66
|
}
|
|
1451
|
-
|
|
1452
|
-
|
|
67
|
+
lines.push((0, tui_1.statusLine)("warn", "Restart any open terminals or editor windows to clear already-loaded environment."));
|
|
68
|
+
for (const line of (0, tui_1.renderBox)({ title: "Logout complete", lines })) {
|
|
69
|
+
params.log(line);
|
|
1453
70
|
}
|
|
1454
|
-
return false;
|
|
1455
71
|
}
|
|
1456
72
|
class LogoutCommand extends base_command_1.BaseCommand {
|
|
1457
73
|
async run() {
|
|
@@ -1518,29 +134,29 @@ class LogoutCommand extends base_command_1.BaseCommand {
|
|
|
1518
134
|
}
|
|
1519
135
|
progress.update("Removing shared machine config");
|
|
1520
136
|
deletedManagedPaths = (await Promise.all([
|
|
1521
|
-
removeFileIfExists(paths_1.managedConfigPath),
|
|
1522
|
-
removeFileIfExists(paths_1.legacyManagedConfigPathClayBay),
|
|
1523
|
-
removeFileIfExists(paths_1.legacyManagedConfigPathCodexAuth),
|
|
137
|
+
(0, fsx_1.removeFileIfExists)(paths_1.managedConfigPath),
|
|
138
|
+
(0, fsx_1.removeFileIfExists)(paths_1.legacyManagedConfigPathClayBay),
|
|
139
|
+
(0, fsx_1.removeFileIfExists)(paths_1.legacyManagedConfigPathCodexAuth),
|
|
1524
140
|
])).filter(Boolean).length;
|
|
1525
|
-
removedEnvFile = await removeFileIfExists(ENV_FILE);
|
|
1526
|
-
updatedShellFiles = await cleanupShellFiles();
|
|
1527
|
-
updatedPowerShellProfiles = await cleanupPowerShellProfiles();
|
|
1528
|
-
updatedVsCodeHooks = await cleanupVsCodeHooks();
|
|
1529
|
-
updatedEditorTerminalSettings = await cleanupEditorTerminalEnvSettings();
|
|
1530
|
-
updatedClaudeEditorSettings = await cleanupClaudeEditorSettings();
|
|
1531
|
-
updatedClaudeDesktopConfig = await cleanupClaudeDesktop3pConfig();
|
|
141
|
+
removedEnvFile = await (0, fsx_1.removeFileIfExists)(env_persist_1.ENV_FILE);
|
|
142
|
+
updatedShellFiles = await (0, env_persist_cleanup_1.cleanupShellFiles)();
|
|
143
|
+
updatedPowerShellProfiles = await (0, env_persist_cleanup_1.cleanupPowerShellProfiles)();
|
|
144
|
+
updatedVsCodeHooks = await (0, env_persist_cleanup_1.cleanupVsCodeHooks)();
|
|
145
|
+
updatedEditorTerminalSettings = await (0, editor_env_cleanup_1.cleanupEditorTerminalEnvSettings)();
|
|
146
|
+
updatedClaudeEditorSettings = await (0, claude_cleanup_1.cleanupClaudeEditorSettings)();
|
|
147
|
+
updatedClaudeDesktopConfig = await (0, claude_cleanup_1.cleanupClaudeDesktop3pConfig)();
|
|
1532
148
|
progress.update("Reverting Codex");
|
|
1533
|
-
updatedCodexConfig = await cleanupCodexConfig();
|
|
1534
|
-
updatedCodexFeatures = await cleanupCodexFeatureFlags();
|
|
149
|
+
updatedCodexConfig = await (0, codex_cleanup_1.cleanupCodexConfig)();
|
|
150
|
+
updatedCodexFeatures = await (0, codex_cleanup_1.cleanupCodexFeatureFlags)();
|
|
1535
151
|
sessionMigration = await (0, codex_history_migration_1.migrateSessionProviders)({
|
|
1536
152
|
codexHome: paths_1.codexDir,
|
|
1537
|
-
migrationStateFile: MIGRATION_STATE_FILE,
|
|
1538
|
-
neutralizeSources: HISTORY_PROVIDER_NEUTRALIZE_SOURCES,
|
|
153
|
+
migrationStateFile: codex_1.MIGRATION_STATE_FILE,
|
|
154
|
+
neutralizeSources: codex_1.HISTORY_PROVIDER_NEUTRALIZE_SOURCES,
|
|
1539
155
|
});
|
|
1540
156
|
stateDbMigration = await (0, codex_history_migration_1.migrateStateDbProviders)({
|
|
1541
157
|
codexHome: paths_1.codexDir,
|
|
1542
|
-
targetProvider: OPENAI_PROVIDER_ID,
|
|
1543
|
-
sourceProviders: HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
|
|
158
|
+
targetProvider: providers_1.OPENAI_PROVIDER_ID,
|
|
159
|
+
sourceProviders: codex_cleanup_1.HISTORY_PROVIDER_DB_MIGRATE_SOURCES,
|
|
1544
160
|
});
|
|
1545
161
|
authSeedCleanup = await (0, codex_auth_seeding_1.cleanupSeededCodexAuth)({
|
|
1546
162
|
codexHome: paths_1.codexDir,
|
|
@@ -1549,39 +165,39 @@ class LogoutCommand extends base_command_1.BaseCommand {
|
|
|
1549
165
|
codexHome: paths_1.codexDir,
|
|
1550
166
|
});
|
|
1551
167
|
progress.update("Reverting Continue");
|
|
1552
|
-
updatedContinueConfig = await cleanupContinueConfig();
|
|
168
|
+
updatedContinueConfig = await (0, continue_cleanup_1.cleanupContinueConfig)();
|
|
1553
169
|
progress.update("Reverting Cline");
|
|
1554
|
-
updatedClineConfig = await cleanupClineConfig();
|
|
170
|
+
updatedClineConfig = await (0, cline_cleanup_1.cleanupClineConfig)();
|
|
1555
171
|
progress.update("Reverting GSD");
|
|
1556
|
-
updatedGsdConfig = await cleanupGsdConfig();
|
|
172
|
+
updatedGsdConfig = await (0, gsd_cleanup_1.cleanupGsdConfig)();
|
|
1557
173
|
progress.update("Reverting OpenClaw");
|
|
1558
|
-
updatedOpenClawConfig = await cleanupOpenClawConfig();
|
|
174
|
+
updatedOpenClawConfig = await (0, openclaw_cleanup_1.cleanupOpenClawConfig)();
|
|
1559
175
|
progress.update("Reverting OpenCode");
|
|
1560
|
-
updatedOpenCodeConfig = await cleanupOpenCodeConfig();
|
|
176
|
+
updatedOpenCodeConfig = await (0, opencode_family_cleanup_1.cleanupOpenCodeConfig)();
|
|
1561
177
|
progress.update("Reverting Kilo Code");
|
|
1562
|
-
updatedKiloConfig = await cleanupKiloConfig();
|
|
178
|
+
updatedKiloConfig = await (0, opencode_family_cleanup_1.cleanupKiloConfig)();
|
|
1563
179
|
progress.update("Reverting Roo Code");
|
|
1564
|
-
updatedRooConfig = await cleanupRooConfig();
|
|
180
|
+
updatedRooConfig = await (0, roo_cleanup_1.cleanupRooConfig)();
|
|
1565
181
|
progress.update("Reverting Hermes");
|
|
1566
|
-
updatedHermesConfig = await cleanupHermesConfig();
|
|
182
|
+
updatedHermesConfig = await (0, hermes_cleanup_1.cleanupHermesConfig)();
|
|
1567
183
|
progress.update("Reverting Trae");
|
|
1568
|
-
updatedTraeBundle = await cleanupTraeBundle();
|
|
184
|
+
updatedTraeBundle = await (0, trae_cleanup_1.cleanupTraeBundle)();
|
|
1569
185
|
progress.update("Reverting Aider");
|
|
1570
|
-
updatedAiderConfig = await cleanupAiderConfig();
|
|
186
|
+
updatedAiderConfig = await (0, aider_cleanup_1.cleanupAiderConfig)();
|
|
1571
187
|
}
|
|
1572
188
|
catch (error) {
|
|
1573
189
|
progress.fail("Logout failed");
|
|
1574
190
|
throw error;
|
|
1575
191
|
}
|
|
1576
|
-
delete process.env[ENV_KEY_NAME];
|
|
1577
|
-
delete process.env[GEMINI_ENV_API_KEY_NAME];
|
|
1578
|
-
delete process.env[GOOGLE_ENV_API_KEY_NAME];
|
|
1579
|
-
delete process.env[GOOGLE_GEMINI_BASE_URL_NAME];
|
|
1580
|
-
delete process.env[CLAUDE_ENV_API_KEY_NAME];
|
|
1581
|
-
delete process.env[CLAUDE_ENV_BASE_URL_NAME];
|
|
1582
|
-
delete process.env[CLAUDE_ENV_SIMPLE_MODE_NAME];
|
|
1583
|
-
delete process.env[CLAUDE_ENV_DISABLE_NONESSENTIAL_TRAFFIC_NAME];
|
|
1584
|
-
delete process.env[CLAUDE_ENV_ENABLE_TELEMETRY_NAME];
|
|
192
|
+
delete process.env[env_persist_1.ENV_KEY_NAME];
|
|
193
|
+
delete process.env[env_persist_1.GEMINI_ENV_API_KEY_NAME];
|
|
194
|
+
delete process.env[env_persist_1.GOOGLE_ENV_API_KEY_NAME];
|
|
195
|
+
delete process.env[env_persist_1.GOOGLE_GEMINI_BASE_URL_NAME];
|
|
196
|
+
delete process.env[env_persist_1.CLAUDE_ENV_API_KEY_NAME];
|
|
197
|
+
delete process.env[env_persist_1.CLAUDE_ENV_BASE_URL_NAME];
|
|
198
|
+
delete process.env[claude_1.CLAUDE_ENV_SIMPLE_MODE_NAME];
|
|
199
|
+
delete process.env[claude_1.CLAUDE_ENV_DISABLE_NONESSENTIAL_TRAFFIC_NAME];
|
|
200
|
+
delete process.env[claude_1.CLAUDE_ENV_ENABLE_TELEMETRY_NAME];
|
|
1585
201
|
if (!debugOutput && process.stdout.isTTY) {
|
|
1586
202
|
progress.succeed("Logout complete");
|
|
1587
203
|
}
|