@hileeon/mcc 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (86) hide show
  1. package/README.md +226 -127
  2. package/dist/accounts/store.d.ts +1 -0
  3. package/dist/accounts/store.d.ts.map +1 -1
  4. package/dist/accounts/store.js.map +1 -1
  5. package/dist/commands/launch.d.ts +9 -0
  6. package/dist/commands/launch.d.ts.map +1 -0
  7. package/dist/commands/launch.js +158 -0
  8. package/dist/commands/launch.js.map +1 -0
  9. package/dist/commands/mcp.d.ts +9 -0
  10. package/dist/commands/mcp.d.ts.map +1 -0
  11. package/dist/commands/mcp.js +112 -0
  12. package/dist/commands/mcp.js.map +1 -0
  13. package/dist/commands/profile.d.ts +8 -0
  14. package/dist/commands/profile.d.ts.map +1 -0
  15. package/dist/commands/profile.js +125 -0
  16. package/dist/commands/profile.js.map +1 -0
  17. package/dist/core/model-router.d.ts.map +1 -1
  18. package/dist/core/model-router.js +5 -2
  19. package/dist/core/model-router.js.map +1 -1
  20. package/dist/{dashboard-server.d.ts → dashboard/server.d.ts} +1 -1
  21. package/dist/dashboard/server.d.ts.map +1 -0
  22. package/dist/{dashboard-server.js → dashboard/server.js} +169 -51
  23. package/dist/dashboard/server.js.map +1 -0
  24. package/dist/mcc.d.ts +4 -2
  25. package/dist/mcc.d.ts.map +1 -1
  26. package/dist/mcc.js +121 -408
  27. package/dist/mcc.js.map +1 -1
  28. package/dist/mcp/mcp-config.d.ts +17 -1
  29. package/dist/mcp/mcp-config.d.ts.map +1 -1
  30. package/dist/mcp/mcp-config.js +50 -17
  31. package/dist/mcp/mcp-config.js.map +1 -1
  32. package/dist/proxy/proxy-daemon.d.ts.map +1 -1
  33. package/dist/proxy/proxy-daemon.js +17 -2
  34. package/dist/proxy/proxy-daemon.js.map +1 -1
  35. package/dist/proxy/proxy-entry.js +5 -3
  36. package/dist/proxy/proxy-entry.js.map +1 -1
  37. package/dist/proxy/proxy-server.d.ts.map +1 -1
  38. package/dist/proxy/proxy-server.js +32 -6
  39. package/dist/proxy/proxy-server.js.map +1 -1
  40. package/dist/shared/config.d.ts +15 -0
  41. package/dist/shared/config.d.ts.map +1 -0
  42. package/dist/shared/config.js +79 -0
  43. package/dist/shared/config.js.map +1 -0
  44. package/dist/shared/logger.d.ts +23 -18
  45. package/dist/shared/logger.d.ts.map +1 -1
  46. package/dist/shared/logger.js +17 -178
  47. package/dist/shared/logger.js.map +1 -1
  48. package/dist/shared/provider-preset-catalog.d.ts +6 -2
  49. package/dist/shared/provider-preset-catalog.d.ts.map +1 -1
  50. package/dist/shared/provider-preset-catalog.js +47 -26
  51. package/dist/shared/provider-preset-catalog.js.map +1 -1
  52. package/dist/ui/assets/index-ClqmrjNk.js +40 -0
  53. package/dist/ui/assets/index-CwMwQ-Z4.css +1 -0
  54. package/dist/ui/index.html +21 -13
  55. package/dist/update.d.ts +31 -0
  56. package/dist/update.d.ts.map +1 -0
  57. package/dist/update.js +196 -0
  58. package/dist/update.js.map +1 -0
  59. package/lib/mcp/mcc-image-analysis-server.cjs +454 -454
  60. package/lib/mcp/mcc-websearch-server.cjs +339 -339
  61. package/lib/mcp-hooks/image-analysis-runtime.cjs +510 -510
  62. package/lib/mcp-hooks/image-analyzer-transformer.cjs +526 -526
  63. package/lib/mcp-hooks/websearch-transformer.cjs +1597 -1421
  64. package/lib/proxy/config/config-loader-facade.js +24 -24
  65. package/lib/proxy/glmt/delta-accumulator.js +362 -362
  66. package/lib/proxy/glmt/glmt-transformer.js +203 -203
  67. package/lib/proxy/glmt/index.js +40 -40
  68. package/lib/proxy/glmt/locale-enforcer.js +68 -68
  69. package/lib/proxy/glmt/pipeline/content-transformer.js +161 -161
  70. package/lib/proxy/glmt/pipeline/index.js +19 -19
  71. package/lib/proxy/glmt/pipeline/request-transformer.js +115 -115
  72. package/lib/proxy/glmt/pipeline/response-builder.js +204 -204
  73. package/lib/proxy/glmt/pipeline/stream-parser.js +233 -233
  74. package/lib/proxy/glmt/pipeline/tool-call-handler.js +77 -77
  75. package/lib/proxy/glmt/pipeline/types.js +5 -5
  76. package/lib/proxy/glmt/reasoning-enforcer.js +150 -150
  77. package/lib/proxy/glmt/sse-parser.js +101 -101
  78. package/lib/proxy/services/logging.js +13 -13
  79. package/lib/proxy/transformers/request-transformer.js +471 -471
  80. package/lib/proxy/transformers/sse-stream-transformer.js +198 -198
  81. package/lib/shared/logger.cjs +156 -138
  82. package/package.json +58 -41
  83. package/dist/dashboard-server.d.ts.map +0 -1
  84. package/dist/dashboard-server.js.map +0 -1
  85. package/dist/ui/assets/index-B16lhKZ6.js +0 -40
  86. package/dist/ui/assets/index-jEfiB6-h.css +0 -1
@@ -0,0 +1,112 @@
1
+ "use strict";
2
+ /**
3
+ * `mcc mcp <list|add|remove|enable|disable>` — external MCP server management.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdMcpList = cmdMcpList;
7
+ exports.cmdMcpAdd = cmdMcpAdd;
8
+ exports.cmdMcpRemove = cmdMcpRemove;
9
+ exports.cmdMcpEnable = cmdMcpEnable;
10
+ exports.cmdMcpDisable = cmdMcpDisable;
11
+ const store_1 = require("../accounts/store");
12
+ const instance_manager_1 = require("../accounts/instance-manager");
13
+ const installer_1 = require("../mcp/installer");
14
+ const registry_1 = require("../mcp/registry");
15
+ const external_registry_1 = require("../mcp/external-registry");
16
+ const instanceMgr = new instance_manager_1.MCCInstanceManager();
17
+ function getFlag(args, flag) {
18
+ const idx = args.indexOf(flag);
19
+ return idx !== -1 ? args[idx + 1] : undefined;
20
+ }
21
+ async function cmdMcpList() {
22
+ const servers = (0, registry_1.getAllServers)();
23
+ console.log('MCP Servers:');
24
+ for (const s of servers) {
25
+ const isBuiltin = 'config' in s;
26
+ const marker = isBuiltin && s.enabledByDefault ? ' (builtin, default)' : isBuiltin ? ' (builtin)' : '';
27
+ console.log(` ${s.name}${marker}`);
28
+ console.log(` ${s.displayName}: ${s.description}`);
29
+ if (!isBuiltin) {
30
+ const ext = s;
31
+ console.log(` Command: ${ext.command} ${ext.args.join(' ')}`);
32
+ }
33
+ }
34
+ }
35
+ async function cmdMcpAdd(args) {
36
+ const name = getFlag(args, '--name');
37
+ const displayName = getFlag(args, '--display-name') ?? name ?? '';
38
+ const description = getFlag(args, '--description') ?? '';
39
+ const command = getFlag(args, '--command') ?? 'uvx';
40
+ const argsStr = getFlag(args, '--args') ?? '';
41
+ const argsList = argsStr ? argsStr.split(',').map((s) => s.trim()) : [];
42
+ const providerRef = getFlag(args, '--provider-ref');
43
+ const enabledByDefault = args.includes('--enabled-by-default');
44
+ if (!name || !command) {
45
+ console.error('[!] --name and --command are required');
46
+ console.error(' Usage: mcc mcp add --name <id> --command <cmd> --args "<arg1>,<arg2>" [--display-name <name>] [--description <desc>] [--provider-ref <provider>] [--enabled-by-default]');
47
+ process.exit(1);
48
+ }
49
+ const envVars = {};
50
+ if (providerRef) {
51
+ envVars.MINIMAX_API_KEY = `\${MCC_PROVIDER_KEY:${providerRef}}`;
52
+ envVars.MINIMAX_API_HOST = 'https://api.minimaxi.com';
53
+ }
54
+ const server = {
55
+ name,
56
+ displayName,
57
+ description,
58
+ command,
59
+ args: argsList,
60
+ envVars,
61
+ enabledByDefault,
62
+ };
63
+ (0, external_registry_1.addExternalMcpServer)(server);
64
+ console.log(`[OK] External MCP added: ${name}`);
65
+ }
66
+ async function cmdMcpRemove(args) {
67
+ const name = args[0];
68
+ if (!name) {
69
+ console.error('[!] Usage: mcc mcp remove <name>');
70
+ process.exit(1);
71
+ }
72
+ const existing = (0, external_registry_1.readExternalMcpRegistry)().find((s) => s.name === name);
73
+ if (!existing) {
74
+ console.error(`[!] External MCP not found: ${name}`);
75
+ process.exit(1);
76
+ }
77
+ (0, external_registry_1.removeExternalMcpServer)(name);
78
+ console.log(`[OK] External MCP removed: ${name}`);
79
+ }
80
+ async function cmdMcpEnable(args) {
81
+ const name = args[0];
82
+ const profileName = args[1];
83
+ if (!name || !profileName) {
84
+ console.error('[!] Usage: mcc mcp enable <name> <profile>');
85
+ process.exit(1);
86
+ }
87
+ if (!(0, store_1.hasProfile)(profileName)) {
88
+ console.error(`[!] Profile not found: ${profileName}`);
89
+ process.exit(1);
90
+ }
91
+ const instancePath = instanceMgr.getInstancePath(profileName);
92
+ (0, installer_1.enableInstanceExternalMcp)(instancePath, name);
93
+ (0, installer_1.syncInstanceMcpServers)(instancePath, registry_1.BUILTIN_MCP_SERVERS.map((s) => s.name), profileName);
94
+ console.log(`[OK] External MCP '${name}' enabled for profile '${profileName}'`);
95
+ }
96
+ async function cmdMcpDisable(args) {
97
+ const name = args[0];
98
+ const profileName = args[1];
99
+ if (!name || !profileName) {
100
+ console.error('[!] Usage: mcc mcp disable <name> <profile>');
101
+ process.exit(1);
102
+ }
103
+ if (!(0, store_1.hasProfile)(profileName)) {
104
+ console.error(`[!] Profile not found: ${profileName}`);
105
+ process.exit(1);
106
+ }
107
+ const instancePath = instanceMgr.getInstancePath(profileName);
108
+ (0, installer_1.disableInstanceExternalMcp)(instancePath, name);
109
+ (0, installer_1.syncInstanceMcpServers)(instancePath, registry_1.BUILTIN_MCP_SERVERS.map((s) => s.name), profileName);
110
+ console.log(`[OK] External MCP '${name}' disabled for profile '${profileName}'`);
111
+ }
112
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * `mcc profile <add|list|remove|default>` — profile lifecycle commands.
3
+ */
4
+ export declare function cmdProfileAdd(args: string[]): Promise<void>;
5
+ export declare function cmdProfileList(): Promise<void>;
6
+ export declare function cmdProfileRemove(args: string[]): Promise<void>;
7
+ export declare function cmdProfileDefault(args: string[]): Promise<void>;
8
+ //# sourceMappingURL=profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"AAAA;;GAEG;AAsBH,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAmDjE;AAED,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAuBpD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAapE;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAarE"}
@@ -0,0 +1,125 @@
1
+ "use strict";
2
+ /**
3
+ * `mcc profile <add|list|remove|default>` — profile lifecycle commands.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.cmdProfileAdd = cmdProfileAdd;
7
+ exports.cmdProfileList = cmdProfileList;
8
+ exports.cmdProfileRemove = cmdProfileRemove;
9
+ exports.cmdProfileDefault = cmdProfileDefault;
10
+ const store_1 = require("../accounts/store");
11
+ const instance_manager_1 = require("../accounts/instance-manager");
12
+ const installer_1 = require("../mcp/installer");
13
+ const registry_1 = require("../mcp/registry");
14
+ const instanceMgr = new instance_manager_1.MCCInstanceManager();
15
+ function getFlag(args, flag) {
16
+ const idx = args.indexOf(flag);
17
+ return idx !== -1 ? args[idx + 1] : undefined;
18
+ }
19
+ async function cmdProfileAdd(args) {
20
+ const name = args[0];
21
+ if (!name) {
22
+ console.error('[!] Usage: mcc profile add <name> --base-url <url> --api-key <key> --model <model> [--display-name <label>] [--protocol anthropic|openai] [--opus-model <m>] [--sonnet-model <m>] [--haiku-model <m>]');
23
+ process.exit(1);
24
+ }
25
+ const baseUrl = getFlag(args, '--base-url');
26
+ const apiKey = getFlag(args, '--api-key');
27
+ const displayName = getFlag(args, '--display-name');
28
+ const model = getFlag(args, '--model') ?? 'claude-sonnet-4-6';
29
+ const protocol = getFlag(args, '--protocol') ?? 'anthropic';
30
+ const proxyChatCompletionsPath = getFlag(args, '--proxy-chat-completions-path');
31
+ if (!baseUrl || !apiKey) {
32
+ console.error('[!] --base-url and --api-key are required');
33
+ process.exit(1);
34
+ }
35
+ if (protocol !== 'anthropic' && protocol !== 'openai') {
36
+ console.error('[!] --protocol must be "anthropic" or "openai"');
37
+ process.exit(1);
38
+ }
39
+ const profile = {
40
+ name,
41
+ displayName: displayName?.trim() || undefined,
42
+ baseUrl,
43
+ model,
44
+ opusModel: getFlag(args, '--opus-model'),
45
+ sonnetModel: getFlag(args, '--sonnet-model'),
46
+ haikuModel: getFlag(args, '--haiku-model'),
47
+ protocol,
48
+ proxyChatCompletionsPath: proxyChatCompletionsPath || undefined,
49
+ createdAt: new Date().toISOString(),
50
+ };
51
+ (0, store_1.saveProfile)(profile, apiKey);
52
+ await instanceMgr.ensureInstance(name);
53
+ const instancePath = instanceMgr.getInstancePath(name);
54
+ (0, installer_1.syncInstanceMcpServers)(instancePath, registry_1.BUILTIN_MCP_SERVERS.map((s) => s.name), name);
55
+ console.log(`[OK] Profile created: ${name}`);
56
+ if (profile.displayName)
57
+ console.log(` Display name: ${profile.displayName}`);
58
+ console.log(` Base URL: ${baseUrl}`);
59
+ console.log(` Model: ${model}`);
60
+ console.log(` Protocol: ${protocol}`);
61
+ if (profile.opusModel)
62
+ console.log(` Opus: ${profile.opusModel}`);
63
+ if (profile.sonnetModel)
64
+ console.log(` Sonnet: ${profile.sonnetModel}`);
65
+ if (profile.haikuModel)
66
+ console.log(` Haiku: ${profile.haikuModel}`);
67
+ if (profile.proxyChatCompletionsPath)
68
+ console.log(` Proxy chat path: ${profile.proxyChatCompletionsPath}`);
69
+ }
70
+ async function cmdProfileList() {
71
+ const profiles = (0, store_1.listProfiles)();
72
+ const defaultProfile = (0, store_1.getDefaultProfile)();
73
+ if (profiles.length === 0) {
74
+ console.log('[i] No profiles. Run: mcc profile add <name> --base-url <url> --api-key <key> --model <model>');
75
+ return;
76
+ }
77
+ console.log('Profiles:');
78
+ for (const p of profiles) {
79
+ const marker = p.name === defaultProfile ? ' (default)' : '';
80
+ const label = p.displayName && p.displayName !== p.name ? ` — ${p.displayName}` : '';
81
+ console.log(` ${p.name}${marker}${label}`);
82
+ console.log(` Base URL: ${p.baseUrl}`);
83
+ console.log(` Model: ${p.model}`);
84
+ console.log(` Protocol: ${p.protocol || 'anthropic'}`);
85
+ if (p.opusModel)
86
+ console.log(` Opus: ${p.opusModel}`);
87
+ if (p.sonnetModel)
88
+ console.log(` Sonnet: ${p.sonnetModel}`);
89
+ if (p.haikuModel)
90
+ console.log(` Haiku: ${p.haikuModel}`);
91
+ if (p.proxyChatCompletionsPath)
92
+ console.log(` Proxy chat path: ${p.proxyChatCompletionsPath}`);
93
+ console.log();
94
+ }
95
+ }
96
+ async function cmdProfileRemove(args) {
97
+ const name = args[0];
98
+ if (!name) {
99
+ console.error('[!] Usage: mcc profile remove <name>');
100
+ process.exit(1);
101
+ }
102
+ if (!(0, store_1.hasProfile)(name)) {
103
+ console.error(`[!] Profile not found: ${name}`);
104
+ process.exit(1);
105
+ }
106
+ (0, store_1.deleteProfile)(name);
107
+ await instanceMgr.deleteInstance(name);
108
+ console.log(`[OK] Profile removed: ${name}`);
109
+ }
110
+ async function cmdProfileDefault(args) {
111
+ const name = args[0];
112
+ if (name) {
113
+ if (!(0, store_1.hasProfile)(name)) {
114
+ console.error(`[!] Profile not found: ${name}`);
115
+ process.exit(1);
116
+ }
117
+ (0, store_1.setDefaultProfile)(name);
118
+ console.log(`[OK] Default profile set: ${name}`);
119
+ }
120
+ else {
121
+ const defaultProf = (0, store_1.getDefaultProfile)();
122
+ console.log(defaultProf ? `Default profile: ${defaultProf}` : '[i] No default profile set');
123
+ }
124
+ }
125
+ //# sourceMappingURL=profile.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"profile.js","sourceRoot":"","sources":["../../src/commands/profile.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"model-router.d.ts","sourceRoot":"","sources":["../../src/core/model-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,WAAW,UAAU;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,4BAA4B,EAAE,MAAM,CAAC;IACrC,8BAA8B,EAAE,MAAM,CAAC;IACvC,6BAA6B,EAAE,MAAM,CAAC;IACtC,0BAA0B,EAAE,MAAM,CAAC;IACnC,iBAAiB,EAAE,GAAG,CAAC;IACvB,qBAAqB,EAAE,GAAG,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,UAAU,CAiDrG"}
1
+ {"version":3,"file":"model-router.d.ts","sourceRoot":"","sources":["../../src/core/model-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAGjD,MAAM,WAAW,UAAU;IACzB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,EAAE,MAAM,CAAC;IACxB,4BAA4B,EAAE,MAAM,CAAC;IACrC,8BAA8B,EAAE,MAAM,CAAC;IACvC,6BAA6B,EAAE,MAAM,CAAC;IACtC,0BAA0B,EAAE,MAAM,CAAC;IACnC,iBAAiB,EAAE,GAAG,CAAC;IACvB,qBAAqB,EAAE,GAAG,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,UAAU,CAoDrG"}
@@ -37,14 +37,17 @@ function buildProfileEnv(profile, apiKey, claudeConfigDir) {
37
37
  // MCP: WebSearch
38
38
  env.MCC_WEBSEARCH_ENABLED = mcpConfig.websearch.enabled ? '1' : '0';
39
39
  for (const p of wsProviders) {
40
- env[`MCC_WEBSEARCH_${p.toUpperCase()}`] = '1';
41
- // Set API key env vars for providers that need them
40
+ // Normalize provider id to a valid env-var suffix (no dashes).
41
+ const envKey = p.replace(/-/g, '_').toUpperCase();
42
+ env[`MCC_WEBSEARCH_${envKey}`] = '1';
42
43
  const providerConfig = mcpConfig.websearch.providers[p];
43
44
  if (providerConfig?.apiKey) {
44
45
  const keyEnvMap = {
45
46
  exa: 'MCC_WEBSEARCH_EXA_API_KEY',
46
47
  tavily: 'MCC_WEBSEARCH_TAVILY_API_KEY',
47
48
  brave: 'MCC_WEBSEARCH_BRAVE_API_KEY',
49
+ bocha: 'MCC_WEBSEARCH_BOCHA_API_KEY',
50
+ minimax: 'MCC_WEBSEARCH_MINIMAX_API_KEY',
48
51
  };
49
52
  if (keyEnvMap[p]) {
50
53
  env[keyEnvMap[p]] = providerConfig.apiKey;
@@ -1 +1 @@
1
- {"version":3,"file":"model-router.js","sourceRoot":"","sources":["../../src/core/model-router.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAuBH,0CAiDC;AArED,kDAAgH;AAgBhH;;;GAGG;AACH,SAAgB,eAAe,CAAC,OAAgB,EAAE,MAAc,EAAE,eAAuB;IACvF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAE5B,wCAAwC;IACxC,MAAM,SAAS,GAAG,IAAA,0BAAa,GAAE,CAAC;IAClC,MAAM,WAAW,GAAG,IAAA,yCAA4B,EAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAA,2CAA8B,EAAC,SAAS,CAAC,CAAC;IAE7D,MAAM,GAAG,GAA2B;QAClC,kBAAkB,EAAE,OAAO,CAAC,OAAO;QACnC,oBAAoB,EAAE,MAAM;QAC5B,eAAe,EAAE,KAAK;QACtB,4BAA4B,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;QACxD,8BAA8B,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK;QAC5D,6BAA6B,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;QAC1D,0BAA0B,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;QACvD,iBAAiB,EAAE,GAAG;QACtB,qBAAqB,EAAE,GAAG;QAC1B,iBAAiB,EAAE,eAAe;KACnC,CAAC;IAEF,iBAAiB;IACjB,GAAG,CAAC,qBAAqB,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACpE,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,GAAG,CAAC,iBAAiB,CAAC,CAAC,WAAW,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC;QAC9C,oDAAoD;QACpD,MAAM,cAAc,GAAG,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YAC3B,MAAM,SAAS,GAA2B;gBACxC,GAAG,EAAE,2BAA2B;gBAChC,MAAM,EAAE,8BAA8B;gBACtC,KAAK,EAAE,6BAA6B;aACrC,CAAC;YACF,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,IAAI,SAAS,CAAC,aAAa,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC;QAClD,GAAG,CAAC,0BAA0B,GAAG,GAAG,CAAC;QACrC,GAAG,CAAC,mCAAmC,GAAG,UAAU,CAAC,OAAO,CAAC;QAC7D,GAAG,CAAC,kCAAkC,GAAG,UAAU,CAAC,MAAM,CAAC;QAC3D,GAAG,CAAC,wBAAwB,GAAG,UAAU,CAAC,KAAK,CAAC;QAChD,GAAG,CAAC,yBAAyB,GAAG,UAAU,CAAC,MAAM,CAAC;IACpD,CAAC;IAED,OAAO,GAA4B,CAAC;AACtC,CAAC"}
1
+ {"version":3,"file":"model-router.js","sourceRoot":"","sources":["../../src/core/model-router.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;AAuBH,0CAoDC;AAxED,kDAAgH;AAgBhH;;;GAGG;AACH,SAAgB,eAAe,CAAC,OAAgB,EAAE,MAAc,EAAE,eAAuB;IACvF,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAE5B,wCAAwC;IACxC,MAAM,SAAS,GAAG,IAAA,0BAAa,GAAE,CAAC;IAClC,MAAM,WAAW,GAAG,IAAA,yCAA4B,EAAC,SAAS,CAAC,CAAC;IAC5D,MAAM,UAAU,GAAG,IAAA,2CAA8B,EAAC,SAAS,CAAC,CAAC;IAE7D,MAAM,GAAG,GAA2B;QAClC,kBAAkB,EAAE,OAAO,CAAC,OAAO;QACnC,oBAAoB,EAAE,MAAM;QAC5B,eAAe,EAAE,KAAK;QACtB,4BAA4B,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK;QACxD,8BAA8B,EAAE,OAAO,CAAC,WAAW,IAAI,KAAK;QAC5D,6BAA6B,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;QAC1D,0BAA0B,EAAE,OAAO,CAAC,UAAU,IAAI,KAAK;QACvD,iBAAiB,EAAE,GAAG;QACtB,qBAAqB,EAAE,GAAG;QAC1B,iBAAiB,EAAE,eAAe;KACnC,CAAC;IAEF,iBAAiB;IACjB,GAAG,CAAC,qBAAqB,GAAG,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACpE,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,+DAA+D;QAC/D,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;QAClD,GAAG,CAAC,iBAAiB,MAAM,EAAE,CAAC,GAAG,GAAG,CAAC;QACrC,MAAM,cAAc,GAAG,SAAS,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,cAAc,EAAE,MAAM,EAAE,CAAC;YAC3B,MAAM,SAAS,GAA2B;gBACxC,GAAG,EAAE,2BAA2B;gBAChC,MAAM,EAAE,8BAA8B;gBACtC,KAAK,EAAE,6BAA6B;gBACpC,KAAK,EAAE,6BAA6B;gBACpC,OAAO,EAAE,+BAA+B;aACzC,CAAC;YACF,IAAI,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjB,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC;YAC5C,CAAC;QACH,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,IAAI,SAAS,CAAC,aAAa,CAAC,OAAO,IAAI,UAAU,EAAE,CAAC;QAClD,GAAG,CAAC,0BAA0B,GAAG,GAAG,CAAC;QACrC,GAAG,CAAC,mCAAmC,GAAG,UAAU,CAAC,OAAO,CAAC;QAC7D,GAAG,CAAC,kCAAkC,GAAG,UAAU,CAAC,MAAM,CAAC;QAC3D,GAAG,CAAC,wBAAwB,GAAG,UAAU,CAAC,KAAK,CAAC;QAChD,GAAG,CAAC,yBAAyB,GAAG,UAAU,CAAC,MAAM,CAAC;IACpD,CAAC;IAED,OAAO,GAA4B,CAAC;AACtC,CAAC"}
@@ -2,4 +2,4 @@
2
2
  * Dashboard Server - Express API + static file server
3
3
  */
4
4
  export {};
5
- //# sourceMappingURL=dashboard-server.d.ts.map
5
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/dashboard/server.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -44,36 +44,99 @@ const cors_1 = __importDefault(require("cors"));
44
44
  const path = __importStar(require("path"));
45
45
  const fs = __importStar(require("fs"));
46
46
  const child_process_1 = require("child_process");
47
- const registry_1 = require("./mcp/registry");
48
- const mcp_config_1 = require("./mcp/mcp-config");
49
- const external_registry_1 = require("./mcp/external-registry");
50
- const installer_1 = require("./mcp/installer");
51
- const instance_manager_1 = require("./accounts/instance-manager");
47
+ const store_1 = require("../accounts/store");
48
+ const registry_1 = require("../mcp/registry");
49
+ const mcp_config_1 = require("../mcp/mcp-config");
50
+ const external_registry_1 = require("../mcp/external-registry");
51
+ const installer_1 = require("../mcp/installer");
52
+ const instance_manager_1 = require("../accounts/instance-manager");
53
+ const provider_preset_catalog_1 = require("../shared/provider-preset-catalog");
52
54
  const PORT = 3000;
53
- const DIST_DIR = path.join(__dirname, '..', 'dist', 'ui');
54
- async function importModule(modulePath, fn) {
55
- const mod = await Promise.resolve(`${modulePath}`).then(s => __importStar(require(s)));
56
- return mod[fn];
57
- }
58
- async function listProfiles() {
59
- const fn = await importModule('./accounts/store', 'listProfiles');
60
- return fn();
61
- }
62
- async function saveProfile(profile, apiKey) {
63
- const fn = await importModule('./accounts/store', 'saveProfile');
64
- return fn(profile, apiKey);
65
- }
66
- async function deleteProfile(name) {
67
- const fn = await importModule('./accounts/store', 'deleteProfile');
68
- return fn(name);
69
- }
70
- async function setDefaultProfile(name) {
71
- const fn = await importModule('./accounts/store', 'setDefaultProfile');
72
- return fn(name);
55
+ // dist/dashboard/server.js ../../dist/ui (two levels up to reach dist/)
56
+ const DIST_DIR = path.join(__dirname, '..', '..', 'dist', 'ui');
57
+ const PKG_VERSION = (() => {
58
+ try {
59
+ return require(path.join(__dirname, '..', '..', 'package.json')).version;
60
+ }
61
+ catch {
62
+ return '0.0.0';
63
+ }
64
+ })();
65
+ /**
66
+ * Hit the provider's models endpoint to verify the key and return the
67
+ * available model list. One round-trip covers both "is this key valid?"
68
+ * and "what models can I pick from?" — they share the same auth.
69
+ *
70
+ * Anthropic protocol → GET {base}/v1/models (x-api-key + anthropic-version)
71
+ * OpenAI protocol → GET {base}/models (Authorization: Bearer)
72
+ */
73
+ async function testProviderKey(baseUrl, apiKey, protocol) {
74
+ const start = Date.now();
75
+ const trimmedBase = baseUrl.trim().replace(/\/+$/, '');
76
+ const url = protocol === 'anthropic' ? `${trimmedBase}/v1/models` : `${trimmedBase}/models`;
77
+ const headers = protocol === 'anthropic'
78
+ ? { 'x-api-key': apiKey, 'anthropic-version': '2023-06-01' }
79
+ : { Authorization: `Bearer ${apiKey}` };
80
+ try {
81
+ const resp = await fetch(url, { method: 'GET', headers });
82
+ const latencyMs = Date.now() - start;
83
+ if (!resp.ok) {
84
+ let errText;
85
+ try {
86
+ errText = await resp.text();
87
+ }
88
+ catch {
89
+ errText = '';
90
+ }
91
+ return {
92
+ ok: false,
93
+ latencyMs,
94
+ models: [],
95
+ error: `HTTP ${resp.status} ${resp.statusText}${errText ? ` — ${errText.slice(0, 200)}` : ''}`,
96
+ };
97
+ }
98
+ const body = (await resp.json());
99
+ const models = extractModelIds(body);
100
+ return { ok: true, latencyMs, models };
101
+ }
102
+ catch (e) {
103
+ return {
104
+ ok: false,
105
+ latencyMs: Date.now() - start,
106
+ models: [],
107
+ error: e.message,
108
+ };
109
+ }
73
110
  }
74
- async function getDefaultProfile() {
75
- const fn = await importModule('./accounts/store', 'getDefaultProfile');
76
- return fn();
111
+ /**
112
+ * Extract model IDs from the various shapes providers return. We accept
113
+ * `data: [...]`, `models: [...]`, or a bare array; each entry can be a
114
+ * string or an object with `id` / `model` / `name`.
115
+ */
116
+ function extractModelIds(body) {
117
+ if (!body)
118
+ return [];
119
+ const raw = body;
120
+ const list = Array.isArray(body)
121
+ ? body
122
+ : Array.isArray(raw.data)
123
+ ? raw.data
124
+ : Array.isArray(raw.models)
125
+ ? raw.models
126
+ : [];
127
+ const ids = [];
128
+ for (const item of list) {
129
+ if (typeof item === 'string') {
130
+ ids.push(item);
131
+ }
132
+ else if (item && typeof item === 'object') {
133
+ const o = item;
134
+ const id = o.id ?? o.model ?? o.name;
135
+ if (typeof id === 'string')
136
+ ids.push(id);
137
+ }
138
+ }
139
+ return Array.from(new Set(ids));
77
140
  }
78
141
  function openBrowser(url) {
79
142
  const isWindows = process.platform === 'win32';
@@ -92,24 +155,35 @@ async function main() {
92
155
  app.use(express_1.default.static(DIST_DIR));
93
156
  }
94
157
  // GET /api/profiles
95
- app.get('/api/profiles', async (_req, res) => {
158
+ app.get('/api/profiles', (_req, res) => {
96
159
  try {
97
- res.json(await listProfiles());
160
+ res.json((0, store_1.listProfiles)());
98
161
  }
99
162
  catch (e) {
100
163
  res.status(500).json({ error: e.message });
101
164
  }
102
165
  });
103
166
  // POST /api/profiles
104
- app.post('/api/profiles', async (req, res) => {
167
+ app.post('/api/profiles', (req, res) => {
105
168
  try {
106
- const { name, baseUrl, apiKey, model, opusModel, sonnetModel, haikuModel, protocol, proxyChatCompletionsPath } = req.body;
169
+ const { name, displayName, baseUrl, apiKey, model, opusModel, sonnetModel, haikuModel, protocol, proxyChatCompletionsPath } = req.body;
107
170
  if (!name || !baseUrl || !apiKey || !model) {
108
171
  res.status(400).json({ error: 'Missing required fields' });
109
172
  return;
110
173
  }
111
- const profile = { name, baseUrl, model, opusModel, sonnetModel, haikuModel, protocol: protocol || 'anthropic', proxyChatCompletionsPath: proxyChatCompletionsPath || undefined, createdAt: new Date().toISOString() };
112
- await saveProfile(profile, apiKey);
174
+ const profile = {
175
+ name,
176
+ displayName: displayName?.trim() || undefined,
177
+ baseUrl,
178
+ model,
179
+ opusModel,
180
+ sonnetModel,
181
+ haikuModel,
182
+ protocol: protocol || 'anthropic',
183
+ proxyChatCompletionsPath: proxyChatCompletionsPath || undefined,
184
+ createdAt: new Date().toISOString(),
185
+ };
186
+ (0, store_1.saveProfile)(profile, apiKey);
113
187
  console.log(`[i] Profile created: ${name} (model: ${model}, protocol: ${protocol || 'anthropic'})`);
114
188
  res.json({ ok: true });
115
189
  }
@@ -118,20 +192,19 @@ async function main() {
118
192
  }
119
193
  });
120
194
  // PUT /api/profiles/:name — update profile
121
- app.put('/api/profiles/:name', async (req, res) => {
195
+ app.put('/api/profiles/:name', (req, res) => {
122
196
  try {
123
- const { baseUrl, apiKey, model, opusModel, sonnetModel, haikuModel, protocol, proxyChatCompletionsPath } = req.body;
197
+ const { displayName, baseUrl, apiKey, model, opusModel, sonnetModel, haikuModel, protocol, proxyChatCompletionsPath } = req.body;
124
198
  const profileName = req.params.name;
125
- const getProfileApiKey = await importModule('./accounts/store', 'getProfileApiKey');
126
- const existingKey = getProfileApiKey(profileName);
127
- const profiles = await listProfiles();
128
- const existing = profiles.find((p) => p.name === profileName);
199
+ const existingKey = (0, store_1.getProfileApiKey)(profileName);
200
+ const existing = (0, store_1.listProfiles)().find((p) => p.name === profileName);
129
201
  if (!existing) {
130
202
  res.status(404).json({ error: 'Profile not found' });
131
203
  return;
132
204
  }
133
205
  const updated = {
134
206
  ...existing,
207
+ displayName: displayName !== undefined ? (displayName.trim() || undefined) : existing.displayName,
135
208
  baseUrl: baseUrl ?? existing.baseUrl,
136
209
  model: model ?? existing.model,
137
210
  opusModel: opusModel !== undefined ? (opusModel || undefined) : existing.opusModel,
@@ -141,7 +214,7 @@ async function main() {
141
214
  proxyChatCompletionsPath: proxyChatCompletionsPath !== undefined ? (proxyChatCompletionsPath || undefined) : existing.proxyChatCompletionsPath,
142
215
  };
143
216
  // Only update API key if a new one is provided
144
- await saveProfile(updated, apiKey ?? existingKey ?? '');
217
+ (0, store_1.saveProfile)(updated, apiKey ?? existingKey ?? '');
145
218
  console.log(`[i] Profile updated: ${profileName} (model: ${updated.model}, protocol: ${updated.protocol || 'anthropic'})`);
146
219
  res.json({ ok: true });
147
220
  }
@@ -149,11 +222,50 @@ async function main() {
149
222
  res.status(500).json({ error: e.message });
150
223
  }
151
224
  });
225
+ // GET /api/profiles/:name/key — return stored API key (dashboard is localhost-only)
226
+ app.get('/api/profiles/:name/key', (req, res) => {
227
+ try {
228
+ const name = req.params.name;
229
+ const key = (0, store_1.getProfileApiKey)(name);
230
+ if (key === undefined) {
231
+ res.status(404).json({ error: 'Profile or key not found' });
232
+ return;
233
+ }
234
+ res.json({ apiKey: key });
235
+ }
236
+ catch (e) {
237
+ res.status(500).json({ error: e.message });
238
+ }
239
+ });
240
+ // POST /api/profiles/test — test API key + fetch model list in one shot.
241
+ // Body: { baseUrl, protocol, apiKey?, profileName? } — apiKey falls back to
242
+ // the stored key for `profileName` when omitted (used by the edit form).
243
+ app.post('/api/profiles/test', async (req, res) => {
244
+ try {
245
+ const { baseUrl, protocol, apiKey, profileName } = req.body;
246
+ if (!baseUrl || !protocol) {
247
+ res.status(400).json({ error: 'baseUrl and protocol required' });
248
+ return;
249
+ }
250
+ const effectiveKey = apiKey?.trim() ||
251
+ (profileName ? (0, store_1.getProfileApiKey)(profileName) : undefined) ||
252
+ '';
253
+ if (!effectiveKey) {
254
+ res.status(400).json({ error: 'No API key available' });
255
+ return;
256
+ }
257
+ const result = await testProviderKey(baseUrl, effectiveKey, protocol);
258
+ res.json(result);
259
+ }
260
+ catch (e) {
261
+ res.status(500).json({ error: e.message });
262
+ }
263
+ });
152
264
  // DELETE /api/profiles/:name
153
- app.delete('/api/profiles/:name', async (req, res) => {
265
+ app.delete('/api/profiles/:name', (req, res) => {
154
266
  try {
155
267
  const name = req.params.name;
156
- await deleteProfile(name);
268
+ (0, store_1.deleteProfile)(name);
157
269
  console.log(`[i] Profile deleted: ${name}`);
158
270
  res.json({ ok: true });
159
271
  }
@@ -162,25 +274,27 @@ async function main() {
162
274
  }
163
275
  });
164
276
  // PUT /api/profiles/:name/default
165
- app.put('/api/profiles/:name/default', async (req, res) => {
277
+ app.put('/api/profiles/:name/default', (req, res) => {
166
278
  try {
167
- await setDefaultProfile(req.params.name);
279
+ (0, store_1.setDefaultProfile)(req.params.name);
168
280
  res.json({ ok: true });
169
281
  }
170
282
  catch (e) {
171
283
  res.status(500).json({ error: e.message });
172
284
  }
173
285
  });
174
- // GET /api/ping - connection health check
286
+ // GET /api/ping - connection health check (UI 用,5s 轮询)
175
287
  app.get('/api/ping', (_req, res) => {
176
288
  res.json({ ok: true });
177
289
  });
290
+ // GET /api/health - 进程级探活(用于 systemd / Docker / 外部监控)
291
+ app.get('/api/health', (_req, res) => {
292
+ res.json({ status: 'ok', version: PKG_VERSION, uptime: process.uptime() });
293
+ });
178
294
  // GET /api/status
179
- app.get('/api/status', async (_req, res) => {
295
+ app.get('/api/status', (_req, res) => {
180
296
  try {
181
- const defaultProfile = await getDefaultProfile();
182
- let currentProfile = defaultProfile;
183
- res.json({ currentProfile });
297
+ res.json({ currentProfile: (0, store_1.getDefaultProfile)() });
184
298
  }
185
299
  catch (e) {
186
300
  res.status(500).json({ error: e.message });
@@ -363,6 +477,10 @@ async function main() {
363
477
  app.get('/api/mcp-config/presets', (_req, res) => {
364
478
  res.json((0, mcp_config_1.getProviderPresets)());
365
479
  });
480
+ // GET /api/profile-presets - provider templates for the Templates gallery
481
+ app.get('/api/profile-presets', (_req, res) => {
482
+ res.json(provider_preset_catalog_1.PROVIDER_PRESET_DEFINITIONS);
483
+ });
366
484
  app.get('*', (_req, res) => {
367
485
  const indexPath = path.join(DIST_DIR, 'index.html');
368
486
  if (fs.existsSync(indexPath)) {
@@ -406,4 +524,4 @@ main().catch((err) => {
406
524
  console.error(`[!] Dashboard server error: ${err.message}`);
407
525
  process.exit(1);
408
526
  });
409
- //# sourceMappingURL=dashboard-server.js.map
527
+ //# sourceMappingURL=server.js.map