huaweicloud-devkit 1.0.2-next.2 → 1.0.3-dev.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,6 @@ import { createInterface } from 'node:readline';
8
8
  import { spawnSync } from 'node:child_process';
9
9
  import { getAuthStatus, syncAuth } from './auth/service.mjs';
10
10
  import { globalCredentialsPath, readGlobalCredentials, writeGlobalCredentials, writeObsConfig } from './auth/credentials.mjs';
11
- import { proxyConfigPath, readProxyConfig, writeProxyConfig, clearProxyConfig, getProxySettings } from './proxy/proxy-config.mjs';
12
11
 
13
12
  const __dirname = dirname(fileURLToPath(import.meta.url));
14
13
  const PLUGIN_ROOT = resolve(__dirname, '..');
@@ -57,15 +56,6 @@ function workbuddySkillsDir() { return join(homedir(), '.workbuddy', 'skills');
57
56
  function workbuddyMcpConfigFile() { return join(homedir(), '.workbuddy', 'mcp.json'); }
58
57
  function workbuddyPluginsDir() { return join(homedir(), '.workbuddy', 'huaweicloud-plugins'); }
59
58
 
60
- function dshRoot() { return process.env.DSH_HOME || join(homedir(), '.dsh'); }
61
- function dshSkillsDir() { return join(dshRoot(), 'skills'); }
62
- function dshProfileDir() { return join(dshRoot(), 'profiles', 'web'); }
63
- function dshPatchFile() { return join(dshProfileDir(), 'cordis.patch.yml'); }
64
- function dshPluginsDir() { return join(dshRoot(), 'huaweicloud-plugins'); }
65
-
66
- const DSH_MCP_PATCH_START = '# HuaweiCloud DevKit DSH integration start';
67
- const DSH_MCP_PATCH_END = '# HuaweiCloud DevKit DSH integration end';
68
-
69
59
  // Detect CodeArts sandbox mode (bash_mode in permission config).
70
60
  function detectCodeartsSandbox() {
71
61
  try {
@@ -768,261 +758,6 @@ function workbuddyStatus() {
768
758
  }
769
759
  }
770
760
 
771
- function dshMcpServerPath() {
772
- return join(dshPluginsDir(), 'src', 'mcp-server.mjs').replace(/\\/g, '/');
773
- }
774
-
775
- function dshPatchBlock() {
776
- const hcloudBin = findHcloudBin();
777
- const envLines = [
778
- ' HUAWEICLOUD_AGENT_TOOLKIT_MODE: local',
779
- " HDKITSERVICE_ENDPOINT: ''",
780
- ];
781
- if (hcloudBin) {
782
- envLines.push(` HCLOUD_BIN: '${hcloudBin.replace(/\\/g, '/').replace(/'/g, "''")}'`);
783
- }
784
- return [
785
- DSH_MCP_PATCH_START,
786
- '- insert:',
787
- ' - id: mcp-huaweicloud',
788
- " name: '@deepseek-ai/dsh-mcp-client'",
789
- ' config:',
790
- ' serverName: huaweicloud',
791
- ' transport: stdio',
792
- ' command: node',
793
- ' args:',
794
- ` - '${dshMcpServerPath().replace(/'/g, "''")}'`,
795
- ' env:',
796
- ...envLines,
797
- ' failOnStartupError: false',
798
- DSH_MCP_PATCH_END,
799
- ].join('\n');
800
- }
801
-
802
- function escapeRegExp(value) {
803
- return String(value).replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
804
- }
805
-
806
- function removeManagedDshPatchBlock(content) {
807
- const pattern = new RegExp(`\\n?${escapeRegExp(DSH_MCP_PATCH_START)}[\\s\\S]*?${escapeRegExp(DSH_MCP_PATCH_END)}\\s*`, 'g');
808
- return String(content || '').replace(pattern, '\n').replace(/\n{3,}/g, '\n\n').trimEnd();
809
- }
810
-
811
- function dshPatchHasOnlyCommentsOrEmptyList(content) {
812
- const meaningful = String(content || '')
813
- .split(/\r?\n/)
814
- .map((line) => line.trim())
815
- .filter((line) => line && !line.startsWith('#'));
816
- return meaningful.length === 0 || (meaningful.length === 1 && meaningful[0] === '[]');
817
- }
818
-
819
- function ensureDshMcpPatch() {
820
- const patchFile = dshPatchFile();
821
- const existing = existsSync(patchFile) ? readFileSync(patchFile, 'utf8') : '';
822
- const cleaned = removeManagedDshPatchBlock(existing);
823
- const block = dshPatchBlock();
824
- let next;
825
- if (dshPatchHasOnlyCommentsOrEmptyList(cleaned)) {
826
- const prefix = cleaned
827
- .split(/\r?\n/)
828
- .filter((line) => line.trim() !== '[]')
829
- .join('\n')
830
- .trimEnd();
831
- next = `${prefix ? `${prefix}\n` : ''}${block}\n`;
832
- } else {
833
- next = `${cleaned}\n\n${block}\n`;
834
- }
835
- if (existing.replace(/\r\n/g, '\n') === next) {
836
- console.log(` DSH patch unchanged: ${patchFile}`);
837
- return false;
838
- }
839
- mkdirSync(dirname(patchFile), { recursive: true });
840
- writeFileSync(patchFile, next);
841
- console.log(` DSH patch updated: ${patchFile}`);
842
- return true;
843
- }
844
-
845
- function removeDshMcpPatch() {
846
- const patchFile = dshPatchFile();
847
- if (!existsSync(patchFile)) return false;
848
- const existing = readFileSync(patchFile, 'utf8');
849
- const cleaned = removeManagedDshPatchBlock(existing);
850
- if (cleaned === existing.trimEnd()) return false;
851
- const prefix = cleaned
852
- .split(/\r?\n/)
853
- .filter((line) => line.trim() !== '[]')
854
- .join('\n')
855
- .trimEnd();
856
- const next = dshPatchHasOnlyCommentsOrEmptyList(cleaned)
857
- ? `${prefix ? `${prefix}\n` : ''}[]\n`
858
- : `${cleaned}\n`;
859
- writeFileSync(patchFile, next);
860
- console.log(` DSH patch cleaned: ${patchFile}`);
861
- return true;
862
- }
863
-
864
- function dshPatchConfigured() {
865
- const patchFile = dshPatchFile();
866
- if (!existsSync(patchFile)) return false;
867
- try {
868
- const patch = readFileSync(patchFile, 'utf8');
869
- return patch.includes('id: mcp-huaweicloud')
870
- && patch.includes("@deepseek-ai/dsh-mcp-client")
871
- && patch.includes('serverName: huaweicloud');
872
- } catch {
873
- return false;
874
- }
875
- }
876
-
877
- function commandAvailable(command, args = ['--version']) {
878
- try {
879
- const r = spawnSync(command, args, { shell: false, windowsHide: true, stdio: 'pipe', timeout: 10000 });
880
- if (r.status === 0) return true;
881
- } catch {}
882
- if (process.platform === 'win32') {
883
- try {
884
- const w = spawnSync('where.exe', [command], { windowsHide: true, stdio: 'pipe', timeout: 10000 });
885
- return w.status === 0 && w.stdout.toString().trim().length > 0;
886
- } catch {}
887
- }
888
- return false;
889
- }
890
-
891
- function dshMcpClientAvailable() {
892
- const modulePath = join('node_modules', '@deepseek-ai', 'dsh-mcp-client', 'package.json');
893
- const candidates = [
894
- join(dshProfileDir(), modulePath),
895
- join(dshRoot(), 'profiles', modulePath),
896
- join(dshRoot(), modulePath),
897
- ];
898
- if (candidates.some((p) => existsSync(p))) return true;
899
- const pkgPath = join(dshProfileDir(), 'package.json');
900
- if (!existsSync(pkgPath)) return false;
901
- try {
902
- const pkg = JSON.parse(readFileSync(pkgPath, 'utf8'));
903
- return Boolean(pkg.dependencies?.['@deepseek-ai/dsh-mcp-client']
904
- || pkg.devDependencies?.['@deepseek-ai/dsh-mcp-client']);
905
- } catch {
906
- return false;
907
- }
908
- }
909
-
910
- function tryInstallDshMcpClient() {
911
- if (process.env.HUAWEICLOUD_DEVKIT_SKIP_DSH_PLUGIN_INSTALL === '1') {
912
- console.log(' DSH MCP client install skipped by environment');
913
- return false;
914
- }
915
- if (dshMcpClientAvailable()) {
916
- console.log(' DSH MCP client package detected');
917
- return true;
918
- }
919
- if (commandAvailable('dsh')) {
920
- const r = spawnSync('dsh', ['plugin', '--profile', 'web', 'add', '@deepseek-ai/dsh-mcp-client'], {
921
- env: { ...process.env, DSH_HOME: dshRoot() },
922
- windowsHide: true,
923
- stdio: 'pipe',
924
- timeout: 60000,
925
- });
926
- if (r.status === 0) {
927
- console.log(' DSH MCP client package installed via dsh');
928
- return true;
929
- }
930
- const err = `${r.stderr || ''}${r.stdout || ''}`.trim().split(/\r?\n/).slice(-2).join(' ');
931
- console.log(` \x1b[33m[WARN]\x1b[0m DSH MCP client auto-install failed${err ? `: ${err}` : ''}`);
932
- }
933
- if (commandAvailable('pnpm') && existsSync(join(dshProfileDir(), 'package.json'))) {
934
- const r = spawnSync('pnpm', ['--dir', dshProfileDir(), 'add', '@deepseek-ai/dsh-mcp-client'], {
935
- windowsHide: true,
936
- stdio: 'pipe',
937
- timeout: 60000,
938
- });
939
- if (r.status === 0) {
940
- console.log(' DSH MCP client package installed via pnpm');
941
- return true;
942
- }
943
- }
944
- console.log(' \x1b[33m[WARN]\x1b[0m DSH MCP client package not detected.');
945
- console.log(' Manual: npx @deepseek-ai/dsh plugin --profile web add @deepseek-ai/dsh-mcp-client');
946
- console.log(' If pnpm is missing, run: corepack enable pnpm');
947
- return false;
948
- }
949
-
950
- async function installDsh() {
951
- const skillsSrc = join(PLUGIN_ROOT, 'skills');
952
- const srcDir = join(PLUGIN_ROOT, 'src');
953
- const safetyDir = join(PLUGIN_ROOT, 'safety');
954
- const pluginDest = dshPluginsDir();
955
-
956
- copyDir(skillsSrc, dshSkillsDir());
957
- console.log(` Skills -> ${dshSkillsDir()}`);
958
- copyDir(srcDir, join(pluginDest, 'src'));
959
- console.log(` MCP Server -> ${join(pluginDest, 'src')}`);
960
- copyDir(safetyDir, join(pluginDest, 'safety'));
961
- console.log(` Safety Policy -> ${join(pluginDest, 'safety')}`);
962
- ensureDshMcpPatch();
963
- tryInstallDshMcpClient();
964
- mkdirSync(pluginDest, { recursive: true });
965
- writeFileSync(join(pluginDest, '.installed'), new Date().toISOString());
966
- }
967
-
968
- async function updateDsh() {
969
- const skillsSrc = join(PLUGIN_ROOT, 'skills');
970
- const srcDir = join(PLUGIN_ROOT, 'src');
971
- const safetyDir = join(PLUGIN_ROOT, 'safety');
972
- const pluginDest = dshPluginsDir();
973
-
974
- copyDir(skillsSrc, dshSkillsDir());
975
- const stale = pruneStale(dshSkillsDir(), skillsSrc);
976
- console.log(` Skills updated -> ${dshSkillsDir()}${stale > 0 ? ` (removed ${stale} stale)` : ''}`);
977
- copyDir(srcDir, join(pluginDest, 'src'));
978
- console.log(` MCP Server updated -> ${join(pluginDest, 'src')}`);
979
- copyDir(safetyDir, join(pluginDest, 'safety'));
980
- console.log(` Safety Policy updated -> ${join(pluginDest, 'safety')}`);
981
- ensureDshMcpPatch();
982
- tryInstallDshMcpClient();
983
- mkdirSync(pluginDest, { recursive: true });
984
- writeFileSync(join(pluginDest, '.installed'), new Date().toISOString());
985
- }
986
-
987
- function uninstallDsh() {
988
- const skillsDir = dshSkillsDir();
989
- let removed = 0;
990
- if (existsSync(skillsDir)) {
991
- for (const entry of readdirSync(skillsDir, { withFileTypes: true })) {
992
- if (entry.name.startsWith('huawei')) {
993
- removeIfExists(join(skillsDir, entry.name));
994
- removed++;
995
- }
996
- }
997
- if (removed > 0) console.log(` Removed ${removed} skills`);
998
- try {
999
- if (readdirSync(skillsDir).length === 0) {
1000
- rmSync(skillsDir, { recursive: true, force: true });
1001
- console.log(` Removed empty skills directory: ${skillsDir}`);
1002
- }
1003
- } catch {}
1004
- }
1005
- if (removeIfExists(dshPluginsDir())) {
1006
- console.log(' Removed MCP server and safety policy');
1007
- }
1008
- removeDshMcpPatch();
1009
- }
1010
-
1011
- function dshStatus() {
1012
- const pluginDir = dshPluginsDir();
1013
- const skillsDir = dshSkillsDir();
1014
- console.log(` MCP Server: ${existsSync(join(pluginDir, 'src', 'mcp-server.mjs')) ? '\x1b[32mInstalled\x1b[0m' : '\x1b[31mNot installed\x1b[0m'}`);
1015
- console.log(` Safety Policy: ${existsSync(join(pluginDir, 'safety', 'policy.json')) ? '\x1b[32mInstalled\x1b[0m' : '\x1b[31mNot installed\x1b[0m'}`);
1016
- let skillCount = 0;
1017
- if (existsSync(skillsDir)) {
1018
- skillCount = readdirSync(skillsDir, { withFileTypes: true })
1019
- .filter((d) => d.isDirectory() && d.name.startsWith('huawei')).length;
1020
- }
1021
- console.log(` Skills: ${skillCount > 0 ? `\x1b[32m${skillCount} installed\x1b[0m` : '\x1b[31mNot installed\x1b[0m'}`);
1022
- console.log(` DSH patch: ${dshPatchConfigured() ? '\x1b[32mConfigured\x1b[0m' : '\x1b[31mNot configured\x1b[0m'}`);
1023
- console.log(` DSH MCP client package: ${dshMcpClientAvailable() ? '\x1b[32mDetected\x1b[0m' : '\x1b[33mCheck DSH profile\x1b[0m'}`);
1024
- }
1025
-
1026
761
  function opencodeStatus() {
1027
762
  const pluginDir = opencodePluginsDir();
1028
763
  const skillsDir = opencodeSkillsDir();
@@ -1053,7 +788,6 @@ function parseTarget() {
1053
788
  if (val === 'codex-desktop') return 'codex-desktop';
1054
789
  if (val === 'codearts') return 'codearts';
1055
790
  if (val === 'workbuddy') return 'workbuddy';
1056
- if (val === 'dsh') return 'dsh';
1057
791
  if (val === 'all') return 'all';
1058
792
  return 'opencode';
1059
793
  }
@@ -1080,10 +814,6 @@ async function cmdInstall() {
1080
814
  console.log('\n[WorkBuddy]');
1081
815
  await installWorkBuddy();
1082
816
  }
1083
- if (target === 'dsh' || target === 'all') {
1084
- console.log('\n[DSH]');
1085
- await installDsh();
1086
- }
1087
817
  if (target === 'codex' || target === 'all') {
1088
818
  console.log('\n[Codex]');
1089
819
  if (!hasCodexCLI()) {
@@ -1106,13 +836,11 @@ async function cmdInstall() {
1106
836
  } else {
1107
837
  installCodex();
1108
838
  }
1109
- }
1110
- console.log(`\n\x1b[32mInstallation complete!\x1b[0m`);
839
+ } console.log(`\n\x1b[32mInstallation complete!\x1b[0m`);
1111
840
  const appName = target === 'codearts' ? 'CodeArts'
1112
841
  : target === 'codex-desktop' ? 'Codex Desktop'
1113
842
  : target === 'codex' ? 'Codex'
1114
843
  : target === 'workbuddy' ? 'WorkBuddy'
1115
- : target === 'dsh' ? 'DSH'
1116
844
  : 'OpenCode';
1117
845
  const pad = ' '.repeat(24 - appName.length);
1118
846
  console.log(`\n\x1b[1m\x1b[33m╔══════════════════════════════════════════════════════╗`);
@@ -1135,8 +863,7 @@ async function cmdInstall() {
1135
863
  console.log(` 3. 运行自检:npx huaweicloud-devkit doctor`);
1136
864
 
1137
865
  // Write install marker for doctor to detect
1138
- const markerDir = target === 'dsh' ? dshPluginsDir()
1139
- : target === 'codearts' ? codeartsPluginsDir()
866
+ const markerDir = target === 'codearts' ? codeartsPluginsDir()
1140
867
  : target === 'workbuddy' ? workbuddyPluginsDir()
1141
868
  : target === 'codex-desktop' ? codexDesktopPluginsDir()
1142
869
  : opencodePluginsDir();
@@ -1154,9 +881,6 @@ async function cmdInstall() {
1154
881
  if (target === 'workbuddy' || target === 'all') {
1155
882
  console.log('Or describe your Huawei Cloud task in WorkBuddy');
1156
883
  }
1157
- if (target === 'dsh' || target === 'all') {
1158
- console.log('Or describe your Huawei Cloud task in DSH');
1159
- }
1160
884
  }
1161
885
 
1162
886
  async function cmdUninstall() {
@@ -1176,10 +900,6 @@ async function cmdUninstall() {
1176
900
  console.log('\n[WorkBuddy]');
1177
901
  uninstallWorkBuddy();
1178
902
  }
1179
- if (target === 'dsh' || target === 'all') {
1180
- console.log('\n[DSH]');
1181
- uninstallDsh();
1182
- }
1183
903
  if (target === 'codex-desktop' || target === 'codex' || target === 'all') {
1184
904
  console.log('\n[Codex]');
1185
905
  uninstallCodexDesktop();
@@ -1224,10 +944,6 @@ async function cmdStatus() {
1224
944
  console.log('\n[WorkBuddy]');
1225
945
  workbuddyStatus();
1226
946
  }
1227
- if (target === 'dsh' || target === 'all') {
1228
- console.log('\n[DSH]');
1229
- dshStatus();
1230
- }
1231
947
  if (target === 'codex' || target === 'all') {
1232
948
  console.log('\n[Codex]');
1233
949
  if (!hasCodexCLI()) {
@@ -1255,22 +971,16 @@ async function cmdDoctor() {
1255
971
  // Node.js
1256
972
  check('Node.js >= 20', process.versions.node.split('.')[0] >= 20, 'Run: nvm install 20 && nvm use 20');
1257
973
 
1258
- // MCP server — check OpenCode, Codex Desktop, CodeArts, WorkBuddy, and DSH paths
974
+ // MCP server — check OpenCode, Codex Desktop, CodeArts, and WorkBuddy paths
1259
975
  const opencodePluginDir = opencodePluginsDir();
1260
976
  const codexPluginDir = codexDesktopPluginsDir();
1261
- const codeartsPluginDir = codeartsPluginsDir();
1262
977
  const workbuddyPluginDir = workbuddyPluginsDir();
1263
- const dshPluginDir = dshPluginsDir();
1264
978
  const mcpOk = existsSync(join(opencodePluginDir, 'src', 'mcp-server.mjs'))
1265
979
  || existsSync(join(codexPluginDir, 'src', 'mcp-server.mjs'))
1266
- || existsSync(join(codeartsPluginDir, 'src', 'mcp-server.mjs'))
1267
- || existsSync(join(workbuddyPluginDir, 'src', 'mcp-server.mjs'))
1268
- || existsSync(join(dshPluginDir, 'src', 'mcp-server.mjs'));
980
+ || existsSync(join(workbuddyPluginDir, 'src', 'mcp-server.mjs'));
1269
981
  const mcpTarget = existsSync(join(opencodePluginDir, 'src', 'mcp-server.mjs')) ? 'OpenCode'
1270
982
  : existsSync(join(codexPluginDir, 'src', 'mcp-server.mjs')) ? 'Codex Desktop'
1271
- : existsSync(join(codeartsPluginDir, 'src', 'mcp-server.mjs')) ? 'CodeArts'
1272
- : existsSync(join(workbuddyPluginDir, 'src', 'mcp-server.mjs')) ? 'WorkBuddy'
1273
- : existsSync(join(dshPluginDir, 'src', 'mcp-server.mjs')) ? 'DSH' : '';
983
+ : existsSync(join(workbuddyPluginDir, 'src', 'mcp-server.mjs')) ? 'WorkBuddy' : '';
1274
984
  check('MCP server installed', mcpOk, 'Run: npx huaweicloud-devkit install');
1275
985
 
1276
986
  if (mcpOk) {
@@ -1279,12 +989,10 @@ async function cmdDoctor() {
1279
989
 
1280
990
  const safetyOk = existsSync(join(opencodePluginDir, 'safety', 'policy.json'))
1281
991
  || existsSync(join(codexPluginDir, 'safety', 'policy.json'))
1282
- || existsSync(join(codeartsPluginDir, 'safety', 'policy.json'))
1283
- || existsSync(join(workbuddyPluginDir, 'safety', 'policy.json'))
1284
- || existsSync(join(dshPluginDir, 'safety', 'policy.json'));
992
+ || existsSync(join(workbuddyPluginDir, 'safety', 'policy.json'));
1285
993
  check('Safety policy installed', safetyOk, 'Run: npx huaweicloud-devkit install');
1286
994
 
1287
- // MCP config — check OpenCode, Codex Desktop, CodeArts, WorkBuddy, and DSH
995
+ // MCP config — check OpenCode, Codex Desktop, and WorkBuddy
1288
996
  let mcpConfigured = false;
1289
997
  let mcpCfgTarget = '';
1290
998
  const opencodeCfg = opencodeConfigFile();
@@ -1301,13 +1009,6 @@ async function cmdDoctor() {
1301
1009
  if (cfg.includes('[mcp_servers.huaweicloud-devkit]')) { mcpConfigured = true; mcpCfgTarget = 'Codex Desktop'; }
1302
1010
  } catch {}
1303
1011
  }
1304
- const codeartsCfg = codeartsMcpSettingsFile();
1305
- if (!mcpConfigured && existsSync(codeartsCfg)) {
1306
- try {
1307
- const cfg = JSON.parse(readFileSync(codeartsCfg, 'utf8'));
1308
- if (cfg.mcpServers && cfg.mcpServers['huaweicloud-devkit']) { mcpConfigured = true; mcpCfgTarget = 'CodeArts'; }
1309
- } catch {}
1310
- }
1311
1012
  const workbuddyCfg = workbuddyMcpConfigFile();
1312
1013
  if (!mcpConfigured && existsSync(workbuddyCfg)) {
1313
1014
  try {
@@ -1315,10 +1016,6 @@ async function cmdDoctor() {
1315
1016
  if (cfg.mcpServers && cfg.mcpServers['huaweicloud-devkit']) { mcpConfigured = true; mcpCfgTarget = 'WorkBuddy'; }
1316
1017
  } catch {}
1317
1018
  }
1318
- if (!mcpConfigured && dshPatchConfigured()) {
1319
- mcpConfigured = true;
1320
- mcpCfgTarget = 'DSH';
1321
- }
1322
1019
  check('MCP configured', mcpConfigured, mcpCfgTarget ? `Found in ${mcpCfgTarget} config` : 'Run: npx huaweicloud-devkit install');
1323
1020
 
1324
1021
  // hcloud CLI
@@ -1348,7 +1045,7 @@ async function cmdDoctor() {
1348
1045
  }
1349
1046
 
1350
1047
  // Skills
1351
- const skillsOptions = [opencodeSkillsDir(), codexDesktopSkillsDir(), codeartsSkillsDir(), workbuddySkillsDir(), dshSkillsDir()];
1048
+ const skillsOptions = [opencodeSkillsDir(), codexDesktopSkillsDir(), codeartsSkillsDir(), workbuddySkillsDir()];
1352
1049
  let skillCount = 0, skillsDir = '', missingSkills = [];
1353
1050
  for (const dir of skillsOptions) {
1354
1051
  if (!existsSync(dir)) continue;
@@ -1367,14 +1064,6 @@ async function cmdDoctor() {
1367
1064
  warn++;
1368
1065
  }
1369
1066
 
1370
- const proxyConfig = readProxyConfig();
1371
- const proxyEnv = process.env.HTTPS_PROXY || process.env.https_proxy || process.env.HTTP_PROXY || process.env.http_proxy;
1372
- if (proxyConfig || proxyEnv) {
1373
- const source = proxyEnv ? 'env' : 'file';
1374
- const proxyUrl = proxyEnv || proxyConfig.https_proxy || proxyConfig.http_proxy;
1375
- console.log(` \x1b[36m[INFO]\x1b[0m Proxy configured (${source}): ${proxyUrl}`);
1376
- }
1377
-
1378
1067
  console.log(`\nResults: ${pass} pass, ${warn} warn, ${fail} fail`);
1379
1068
 
1380
1069
  if (mcpConfigured && !hcloudOk) {
@@ -1393,7 +1082,6 @@ async function cmdDoctor() {
1393
1082
  { path: join(codexDesktopPluginsDir(), '.installed'), name: 'Codex Desktop' },
1394
1083
  { path: join(workbuddyPluginsDir(), '.installed'), name: 'WorkBuddy' },
1395
1084
  { path: join(codeartsPluginsDir(), '.installed'), name: 'CodeArts' },
1396
- { path: join(dshPluginsDir(), '.installed'), name: 'DSH' },
1397
1085
  ];
1398
1086
  for (const marker of installedMarkers) {
1399
1087
  if (existsSync(marker.path)) {
@@ -1475,18 +1163,6 @@ async function cmdUpdate() {
1475
1163
  return;
1476
1164
  }
1477
1165
 
1478
- if (target === 'dsh') {
1479
- if (!existsSync(join(dshPluginsDir(), 'src', 'mcp-server.mjs'))) {
1480
- console.log('\x1b[33mNot installed. Use "install" command first.\x1b[0m');
1481
- return;
1482
- }
1483
- console.log('[DSH]');
1484
- await updateDsh();
1485
- console.log(`\n\x1b[32mUpdate complete.\x1b[0m`);
1486
- console.log(`\x1b[33mRestart the DSH session for changes to take effect.\x1b[0m`);
1487
- return;
1488
- }
1489
-
1490
1166
  if (target === 'all') {
1491
1167
  let updatedAny = false;
1492
1168
  if (existsSync(join(opencodePluginsDir(), 'src', 'mcp-server.mjs'))) {
@@ -1509,11 +1185,6 @@ async function cmdUpdate() {
1509
1185
  await updateWorkBuddy();
1510
1186
  updatedAny = true;
1511
1187
  }
1512
- if (existsSync(join(dshPluginsDir(), 'src', 'mcp-server.mjs'))) {
1513
- console.log('\n[DSH]');
1514
- await updateDsh();
1515
- updatedAny = true;
1516
- }
1517
1188
  if (codexStatus()) {
1518
1189
  console.log('\n[Codex]');
1519
1190
  installCodex();
@@ -1853,93 +1524,6 @@ async function cmdAuth() {
1853
1524
  return cmdAuthStatus();
1854
1525
  }
1855
1526
 
1856
- async function cmdProxyInit() {
1857
- console.log(BANNER);
1858
- console.log('HuaweiCloud DevKit Proxy Configuration\n');
1859
- console.log('Configure HTTP/HTTPS proxy for connections to Huawei Cloud services.');
1860
- console.log('Proxy settings are saved to ~/.config/huaweicloud/proxy.json\n');
1861
-
1862
- const existing = readProxyConfig() || {};
1863
- const interactive = process.stdin.isTTY && process.stdout.isTTY;
1864
-
1865
- if (!interactive) {
1866
- console.error('\x1b[31mNon-interactive session. Set proxy via environment variables:\x1b[0m');
1867
- console.error(' HTTPS_PROXY=http://proxy:port');
1868
- console.error(' HTTP_PROXY=http://proxy:port');
1869
- console.error(' NO_PROXY=localhost,127.0.0.1');
1870
- console.error('\nOr run "npx huaweicloud-devkit proxy init" in a real terminal.');
1871
- process.exitCode = 1;
1872
- return;
1873
- }
1874
-
1875
- const httpsProxy = await readLineQuestion(`HTTPS proxy [${existing.https_proxy || 'none'}]: `);
1876
- const httpProxy = await readLineQuestion(`HTTP proxy [${existing.http_proxy || 'none'}]: `);
1877
- const noProxy = await readLineQuestion(`NO_PROXY hosts [${existing.no_proxy || 'localhost,127.0.0.1'}]: `);
1878
-
1879
- const config = {
1880
- https_proxy: httpsProxy || existing.https_proxy || '',
1881
- http_proxy: httpProxy || existing.http_proxy || '',
1882
- no_proxy: noProxy || existing.no_proxy || 'localhost,127.0.0.1',
1883
- };
1884
-
1885
- const path = writeProxyConfig(config);
1886
- console.log(`\nProxy configuration saved to ${path}`);
1887
- console.log('\nEffective settings:');
1888
- console.log(` HTTPS_PROXY: ${config.https_proxy || '(none)'}`);
1889
- console.log(` HTTP_PROXY: ${config.http_proxy || '(none)'}`);
1890
- console.log(` NO_PROXY: ${config.no_proxy || '(none)'}`);
1891
- console.log('\nEnvironment variables (HTTPS_PROXY, HTTP_PROXY, NO_PROXY) override file settings.');
1892
- }
1893
-
1894
- async function cmdProxyShow() {
1895
- console.log(BANNER);
1896
- console.log('HuaweiCloud DevKit Proxy Configuration\n');
1897
-
1898
- const config = readProxyConfig();
1899
- const configPath = proxyConfigPath();
1900
-
1901
- console.log(`Config file: ${configPath}`);
1902
- console.log(`File exists: ${config ? 'yes' : 'no'}\n`);
1903
-
1904
- if (config) {
1905
- console.log('File settings:');
1906
- console.log(` https_proxy: ${config.https_proxy || '(empty)'}`);
1907
- console.log(` http_proxy: ${config.http_proxy || '(empty)'}`);
1908
- console.log(` no_proxy: ${config.no_proxy || '(empty)'}`);
1909
- }
1910
-
1911
- console.log('\nEnvironment variables:');
1912
- console.log(` HTTPS_PROXY: ${process.env.HTTPS_PROXY || process.env.https_proxy || '(not set)'}`);
1913
- console.log(` HTTP_PROXY: ${process.env.HTTP_PROXY || process.env.http_proxy || '(not set)'}`);
1914
- console.log(` NO_PROXY: ${process.env.NO_PROXY || process.env.no_proxy || '(not set)'}`);
1915
-
1916
- const effective = getProxySettings();
1917
- console.log('\nEffective (env > file):');
1918
- if (effective) {
1919
- console.log(` https_proxy: ${effective.https_proxy || '(none)'}`);
1920
- console.log(` http_proxy: ${effective.http_proxy || '(none)'}`);
1921
- console.log(` no_proxy: ${effective.no_proxy || '(none)'}`);
1922
- } else {
1923
- console.log(' (no proxy configured)');
1924
- }
1925
- }
1926
-
1927
- async function cmdProxyClear() {
1928
- const removed = clearProxyConfig();
1929
- if (removed) {
1930
- console.log('Proxy configuration removed.');
1931
- } else {
1932
- console.log('No proxy configuration file found.');
1933
- }
1934
- }
1935
-
1936
- async function cmdProxy() {
1937
- const sub = (process.argv[3] || 'show').toLowerCase();
1938
- if (sub === 'init' || sub === 'setup') return cmdProxyInit();
1939
- if (sub === 'clear' || sub === 'remove' || sub === 'reset') return cmdProxyClear();
1940
- return cmdProxyShow();
1941
- }
1942
-
1943
1527
  async function main() {
1944
1528
  const cmd = process.argv[2] || 'help';
1945
1529
 
@@ -1973,15 +1557,12 @@ async function main() {
1973
1557
  case 'auth':
1974
1558
  await cmdAuth();
1975
1559
  break;
1976
- case 'proxy':
1977
- await cmdProxy();
1978
- break;
1979
1560
  case 'help':
1980
1561
  case '--help':
1981
1562
  case '-h':
1982
1563
  default:
1983
1564
  console.log(BANNER);
1984
- console.log('Usage: npx huaweicloud-devkit <command> [--target <opencode|codex|codearts|workbuddy|dsh|all>]\n');
1565
+ console.log('Usage: npx huaweicloud-devkit <command> [--target <opencode|codex|codearts|workbuddy|all>]\n');
1985
1566
  console.log('Commands:');
1986
1567
  console.log(' install Install skills, MCP server, safety policy');
1987
1568
  console.log(' uninstall Remove installed files');
@@ -1991,22 +1572,18 @@ async function main() {
1991
1572
  console.log(' doctor Self-check: hcloud, MCP, skills, auth');
1992
1573
  console.log(' install-hcloud Show KooCLI install commands for your OS');
1993
1574
  console.log(' auth Manage unified auth: init | sync | status');
1994
- console.log(' proxy Manage proxy config: init | show | clear');
1995
1575
  console.log(' help Show this help');
1996
1576
  console.log('\nOptions:');
1997
- console.log(' --target Target agent: opencode (default), codex, codearts, workbuddy, dsh, all');
1577
+ console.log(' --target Target agent: opencode (default), codex, codearts, workbuddy, all');
1998
1578
  console.log('\nExamples:');
1999
1579
  console.log(' npx huaweicloud-devkit install');
2000
1580
  console.log(' npx huaweicloud-devkit install --target codex');
2001
1581
  console.log(' npx huaweicloud-devkit install --target codearts');
2002
1582
  console.log(' npx huaweicloud-devkit install --target workbuddy');
2003
- console.log(' npx huaweicloud-devkit install --target dsh');
2004
1583
  console.log(' npx huaweicloud-devkit install --target all');
2005
1584
  console.log(' npx huaweicloud-devkit auth init');
2006
1585
  console.log(' npx huaweicloud-devkit auth sync --target all');
2007
1586
  console.log(' npx huaweicloud-devkit auth status --target all');
2008
- console.log(' npx huaweicloud-devkit proxy init');
2009
- console.log(' npx huaweicloud-devkit proxy show');
2010
1587
  break;
2011
1588
  }
2012
1589
  }