@sanqianx/claude-ai-workbench 0.13.1 → 0.13.2-rc.2

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 CHANGED
@@ -12,6 +12,8 @@
12
12
 
13
13
  工作台是产品供应商与凭据的活动配置源。后台维护默认模型持久化,不随会话临时模型切换;解析后的凭据只交给鉴权本地服务,不进入浏览器消息。SDK 会话从当前项目登记的工作区恢复,也兼容旧登记文件。
14
14
 
15
+ MiniMax 向量模型使用独立的 `/v1/embeddings` 接口,不复用聊天的 `/anthropic` 路由。官方域名的已知接口后缀在运行期规范化为服务根地址,现有配置文件不被迁移或改写;自定义网关路径保持原样。
16
+
15
17
  Windows 上 Claude Code 探测与实际启动使用同一解析结果:失效的 `CLAUDE_CODE_EXECPATH` 不遮住有效安装,npm/CMD/PowerShell 启动脚本解析成实际文件,JavaScript 入口用当前 Node 探测版本。`/system/doctor` 返回实际启动路径、被跳过的失效路径及版本探测错误。发现和会话失败使用 `log/v2`;受外壳守护时写入外壳统一诊断,独立运行保存在工作台数据目录的 `diagnostics.jsonl`,不记录凭据或原始提示词。
16
18
 
17
19
  ## 仓库结构
@@ -59,7 +61,8 @@ npm run start:agent-terminal
59
61
  - 页面:`http://127.0.0.1:5760/agent-terminal/`
60
62
  - 数据目录:`~/.agent-terminal`(`AGENT_TERMINAL_DATA_DIR` 覆盖;端口 `AGENT_TERMINAL_PORT`)
61
63
  - 首次使用:设置 → 模型供应商 → 添加供应商(Base URL / API Key / 模型列表),然后添加本地项目文件夹即可开聊。
62
- - Agent 发现自动扫描本机:Claude Code(Agent SDK,支持 Anthropic 兼容端点如 MiniMax)、Codex(`codex exec --json`,使用自身登录)、OpenCode(`opencode run --format json`)、ZCode(已安装但暂无 headless CLI,如实标注不可用)。
64
+ - Agent 发现自动扫描本机:Claude Code(Agent SDK,支持 Anthropic 兼容端点如 MiniMax)、Codex(app-server,保留 CLI 回退)、OpenCode(serve + SSE,保留 CLI 回退)、ZCode(桌面内置 app-server)。版本探测成功不等于认证或任务执行成功,实际运行失败另写诊断日志。
65
+ - ZCode 启动只引用安装目录里已有的供应商配置,并保留显式环境变量覆盖及个人配置。不会改写桌面安装资源、生成假配置或复制凭据。
63
66
  - 零点击模型检测:填好 Base URL 与 API Key 后自动探测 `/v1/models` 并合并 models.dev 能力数据(上下文窗口、模态、推理),保存时自动填充模型列表与上下文大小。
64
67
  - 会话内模型切换:切换供应商/模型不换会话,历史跨供应商延续(Claude 保留 resume,CLI 保留线程参数)。
65
68
  - 运行时体验对齐:中断不再误报退出码错误、stderr 聚合为单个折叠、上下文用量按轮取最大值而非累计求和。
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: Claude AI Workbench API
4
- version: 0.13.1
4
+ version: 0.13.2-rc.2
5
5
  description: Versioned local API for AI Profile, credential and Claude Code session management.
6
6
  servers:
7
7
  - url: http://127.0.0.1:5760/api/claude-workbench/v1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanqianx/claude-ai-workbench",
3
- "version": "0.13.1",
3
+ "version": "0.13.2-rc.2",
4
4
  "description": "Shared Claude Code terminal and Anthropic-compatible AI profile modules for local developer tools.",
5
5
  "type": "commonjs",
6
6
  "main": "src/index.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-ai-workbench/client",
3
- "version": "0.13.1",
3
+ "version": "0.13.2-rc.2",
4
4
  "type": "commonjs",
5
5
  "main": "index.js",
6
6
  "browser": "index.js",
@@ -20,7 +20,7 @@
20
20
  "README.md"
21
21
  ],
22
22
  "dependencies": {
23
- "@claude-ai-workbench/contracts": "0.13.1"
23
+ "@claude-ai-workbench/contracts": "0.13.2-rc.2"
24
24
  },
25
25
  "engines": {
26
26
  "node": ">=18"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-ai-workbench/contracts",
3
- "version": "0.13.1",
3
+ "version": "0.13.2-rc.2",
4
4
  "type": "commonjs",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-ai-workbench/core",
3
- "version": "0.13.1",
3
+ "version": "0.13.2-rc.2",
4
4
  "type": "commonjs",
5
5
  "main": "index.js",
6
6
  "browser": "index.js",
@@ -20,7 +20,7 @@
20
20
  "README.md"
21
21
  ],
22
22
  "dependencies": {
23
- "@claude-ai-workbench/contracts": "0.13.1"
23
+ "@claude-ai-workbench/contracts": "0.13.2-rc.2"
24
24
  },
25
25
  "engines": {
26
26
  "node": ">=18"
@@ -82,6 +82,20 @@ function safeReaddir(dir) {
82
82
  try { return fs.readdirSync(dir); } catch { return []; }
83
83
  }
84
84
 
85
+ function providerRuntimeEnvironment(cliPath, { env = process.env, homedir = os.homedir(), existsSync = safeExists } = {}) {
86
+ const output = {};
87
+ if (!env.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE?.trim()) {
88
+ // Desktop bundles keep config beside glm, not inside it. Recent native
89
+ // CLIs otherwise resolve a development-tree fallback outside the install.
90
+ const dir = path.dirname(path.resolve(cliPath));
91
+ const bundled = [path.join(dir, 'provider/zcode-builtin.json'), path.resolve(dir, '../config/provider/zcode-builtin.json')].find(existsSync);
92
+ if (!bundled) return output;
93
+ output.ZCODE_BUILTIN_PROVIDER_CONFIG_FILE = bundled;
94
+ }
95
+ if (!env.ZCODE_PERSONAL_PROVIDER_CONFIG_FILE?.trim()) output.ZCODE_PERSONAL_PROVIDER_CONFIG_FILE = path.join(env.ZCODE_DATA_BASE_DIR?.trim() || homedir, '.zcode/v2/provider_config.json');
96
+ return output;
97
+ }
98
+
85
99
  // Discovery chain for the bundled zcode CLI:
86
100
  // 1. ZCODE_CLI_PATH env override (the .cjs itself or the install root);
87
101
  // 2. common Windows install roots (%LOCALAPPDATA%\Programs, Program Files,
@@ -653,6 +667,7 @@ function createAppServerZCodeDriver(options, cli) {
653
667
  // runtime with the app-server stdio subcommand.
654
668
  command: options.nodePath || process.execPath,
655
669
  args: [cli.path, 'app-server', '--stdio'],
670
+ env: providerRuntimeEnvironment(cli.path, { env: options.env || process.env }),
656
671
  spawn: options.appServerSpawn,
657
672
  onEvent: handleNotification,
658
673
  onServerRequest: handleServerRequest,
@@ -1160,6 +1175,7 @@ module.exports = {
1160
1175
  createZCodeDriver,
1161
1176
  discoverZCodeCli,
1162
1177
  probeZCodeVersion,
1178
+ providerRuntimeEnvironment,
1163
1179
  runtimeModelForProfile: injectedRuntimeModel,
1164
1180
  toolResultText,
1165
1181
  MODE_FOR_PERMISSION,
@@ -61,6 +61,7 @@ class ProfileStore {
61
61
  const saved = this._profiles().embedding;
62
62
  if (!saved) return { configured: false, config: null };
63
63
  const { credentialRef, ...config } = saved;
64
+ config.endpoint = normalizeEmbedding(saved).endpoint;
64
65
  let configured = false;
65
66
  try { configured = Boolean(this.embeddingRuntime()); } catch {}
66
67
  return { configured, config };
@@ -95,7 +96,7 @@ class ProfileStore {
95
96
  if (!saved) throw Object.assign(new Error('向量模型未配置。'), { status: 409 });
96
97
  const secret = saved.profileId ? this.runtimeProfile(saved.profileId).apiKey : this._credentials().credentials[saved.credentialRef];
97
98
  if (!secret) throw Object.assign(new Error('向量模型凭据未配置。'), { status: 409 });
98
- return { provider: saved.provider, model: saved.model, endpoint: saved.endpoint, apiKey: secret };
99
+ return { provider: saved.provider, model: saved.model, endpoint: normalizeEmbedding(saved).endpoint, apiKey: secret };
99
100
  }
100
101
 
101
102
  importEmbedding({ migrationId, settings }) {
@@ -245,10 +246,13 @@ function normalizeEmbedding(input) {
245
246
  if (!['minimax', 'openai'].includes(input.provider)) throw Object.assign(new Error('请选择支持的向量协议。'), { status: 400 });
246
247
  const model = String(input.model || (input.provider === 'minimax' ? 'embo-01' : 'text-embedding-3-small')).trim();
247
248
  if (!model || model.length > 200 || /[\x00-\x1f]/.test(model)) throw Object.assign(new Error('无效的向量模型。'), { status: 400 });
248
- const endpoint = String(input.endpoint || '').trim();
249
+ let endpoint = String(input.endpoint || '').trim();
249
250
  if (endpoint) {
250
251
  let url; try { url = new URL(endpoint); } catch {}
251
252
  if (!url || !['http:', 'https:'].includes(url.protocol) || url.username || url.password || url.search || url.hash) throw Object.assign(new Error('向量接口地址无效。'), { status: 400 });
253
+ // MiniMax appends /v1/embeddings itself. Only official, known route
254
+ // aliases are normalized; private gateways may require their path prefix.
255
+ if (input.provider === 'minimax' && ['api.minimaxi.com', 'api.minimax.io', 'api.minimax.cn', 'api.minimax.chat'].includes(url.hostname) && /^\/(?:anthropic|v1(?:\/embeddings)?)?\/?$/.test(url.pathname)) endpoint = url.origin;
252
256
  }
253
257
  return { provider: input.provider, model, endpoint, profileId: input.profileId ? cleanId(input.profileId, 'profileId') : null };
254
258
  }
@@ -651,7 +651,7 @@ class WorkbenchService {
651
651
  }
652
652
  _runtimeFailure(sessionId, error) {
653
653
  const state = this.runner.getState(sessionId);
654
- this.diagnostics?.error('agent.runtime.failed', 'Agent 会话运行失败。', { projectId: /^project-[A-Za-z0-9._-]+$/.test(state?.projectSlug || '') ? state.projectSlug : undefined, runId: sessionId, phase: 'runtime', error, context: { agent: this.runner.agentOf?.(sessionId) || state?.agentId || 'claude-code', sessionId } });
654
+ this.diagnostics?.error('agent.runtime.failed', 'Agent 会话运行失败。', { projectId: /^project-[A-Za-z0-9._-]+$/.test(state?.projectSlug || '') ? state.projectSlug : undefined, runId: sessionId, phase: 'runtime', error, context: { agent: this.runner.agentOf?.(sessionId) || this.sessionAgents.get(sessionId) || state?.agentId || 'claude-code', sessionId } });
655
655
  }
656
656
  _audit(action, detail) {
657
657
  if (!this.auditFile) return;
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-ai-workbench/server",
3
- "version": "0.13.1",
3
+ "version": "0.13.2-rc.2",
4
4
  "type": "commonjs",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -25,7 +25,7 @@
25
25
  ],
26
26
  "dependencies": {
27
27
  "@anthropic-ai/claude-agent-sdk": "^0.2.141",
28
- "@claude-ai-workbench/contracts": "0.13.1"
28
+ "@claude-ai-workbench/contracts": "0.13.2-rc.2"
29
29
  },
30
30
  "engines": {
31
31
  "node": ">=18"
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@claude-ai-workbench/ui",
3
- "version": "0.13.1",
3
+ "version": "0.13.2-rc.2",
4
4
  "type": "commonjs",
5
5
  "main": "ai-profile-settings.js",
6
6
  "browser": "ai-profile-settings.js",
@@ -33,7 +33,7 @@
33
33
  "README.md"
34
34
  ],
35
35
  "dependencies": {
36
- "@claude-ai-workbench/core": "0.13.1"
36
+ "@claude-ai-workbench/core": "0.13.2-rc.2"
37
37
  },
38
38
  "engines": {
39
39
  "node": ">=18"