zcode-pro 0.17.2 → 0.18.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.
@@ -1,14 +1,22 @@
1
1
  // 注入脚本公共工具:与 helper 通信、DOM 构建、多语言文案。
2
2
  export const BOOT = typeof window !== 'undefined' ? (window.__ZCODEPRO__ || {}) : {};
3
3
  export const HELPER_URL = BOOT.helperUrl || 'http://127.0.0.1:47889';
4
- const TOKEN = BOOT.token || '';
4
+
5
+ // token/helperUrl 必须在每次调用时实时读 window.__ZCODEPRO__:cli.mjs 重启后 helper 换了
6
+ // 随机 token,重新注入会被 index.js 的幂等守卫跳过、页面继续用旧闭包——若在模块求值时
7
+ // 固化成常量,旧闭包会永远拿旧 token 报 unauthorized。重注入的 bootstrap 会先更新
8
+ // window.__ZCODEPRO__,实时读即可对上新一轮 token。
9
+ function liveBoot() {
10
+ return (typeof window !== 'undefined' && window.__ZCODEPRO__) || BOOT;
11
+ }
5
12
 
6
13
  export function rpc(path, options = {}) {
7
- return fetch(HELPER_URL + path, {
14
+ const boot = liveBoot();
15
+ return fetch((boot.helperUrl || HELPER_URL) + path, {
8
16
  method: options.method || 'GET',
9
17
  headers: {
10
18
  'Content-Type': 'application/json',
11
- 'X-ZCodePro-Token': TOKEN,
19
+ 'X-ZCodePro-Token': boot.token || '',
12
20
  },
13
21
  body: options.body ? JSON.stringify(options.body) : undefined,
14
22
  })
@@ -41,16 +49,24 @@ const zh = {
41
49
  agentsSave: '保存',
42
50
  agentsSaved: '全局提示词已保存',
43
51
  agentsLoadFailed: '读取全局提示词失败',
44
- proxyDesc: '为 ZCode Pro 本地助手发起的网络访问设置 HTTP 代理:插件市场的更新与安装、Headroom 本体的检查更新与升级都会走该代理。不影响 ZCode 应用本身与模型请求,保存后立即生效。',
52
+ proxyDesc: '为 ZCode Pro 本地助手发起的网络访问设置 HTTP 代理:插件市场的更新与安装、插件依赖软件的安装与升级、WebDAV 同步都可走该代理,用下方开关选择生效范围。不影响 ZCode 应用本身与模型请求,保存后立即生效。',
45
53
  proxyPlaceholder: 'http://127.0.0.1:7890',
46
54
  proxySave: '保存',
47
55
  proxySaved: '代理设置已保存',
48
56
  proxyHint: '留空保存即清除代理。',
49
57
  proxyTest: '检测',
50
58
  proxyTesting: '检测中…',
59
+ proxyTestEmpty: '请先输入代理地址',
51
60
  proxyTestFailed: '检测失败',
61
+ proxyScopePlugins: '插件市场更新',
62
+ proxyScopePluginsDesc: '插件市场的检查更新、安装与卸载(zcode CLI 的 git 操作)走代理。',
63
+ proxyScopeDeps: '插件依赖软件',
64
+ proxyScopeDepsDesc: 'headroom 与 rtk 的安装、检查更新与升级(pip 与 GitHub 下载)走代理。',
65
+ proxyScopeSync: '同步',
66
+ proxyScopeSyncDesc: 'WebDAV 上传与下载走代理。默认关闭:坚果云等国内网盘直连即可,代理停了同步会跟着失败。',
52
67
  tabSync: '同步',
53
- syncDesc: '手动把 ZCode Pro 设置与模型设置备份到 WebDAV,或在新电脑上恢复。两项各自独立成文件,可只上传或只覆盖其中一项;仅在点击按钮时传输,不做自动同步。',
68
+ tabDebug: '调试',
69
+ syncDesc: '手动把 ZCode Pro 设置与模型设置备份到 WebDAV,或在新电脑上恢复。两项各自独立成文件,可只上传或只覆盖其中一项;每次上传会额外保留一份带时间戳的历史版本,下载时任选一个版本恢复;仅在点击按钮时传输,不做自动同步。',
54
70
  syncUrlPlaceholder: 'https://dav.jianguoyun.com/dav/',
55
71
  syncDir: '上传目录',
56
72
  syncDirPlaceholder: 'zcode-pro',
@@ -58,7 +74,7 @@ const zh = {
58
74
  syncPassword: '密码',
59
75
  syncSave: '保存',
60
76
  syncSaved: '同步配置已保存',
61
- syncFormHint: '同步文件存到“上传目录”(默认 zcode-pro,可多级,自动创建)下的 zcodepro.json 与 model.json。',
77
+ syncFormHint: '同步文件存到“上传目录”(默认 zcode-pro,可多级,自动创建):zcodepro.json 与 model.json 始终是最新一版,旁边另保留带时间戳的历史版本。',
62
78
  syncRecLink: '坚果云 WebDAV',
63
79
  syncRecSuffix: ':登录与密码填“应用密码”,不是账号密码。',
64
80
  syncIncludeZcp: 'ZCode Pro 设置',
@@ -68,16 +84,44 @@ const zh = {
68
84
  syncUpload: '上传到云端',
69
85
  syncDownload: '从云端下载',
70
86
  syncUploading: '上传中…',
71
- syncDownloading: '下载中…',
72
87
  syncUploaded: '已上传到云端',
73
88
  syncDownloaded: '已从云端恢复',
74
89
  syncLastPush: '上次上传',
75
90
  syncLastPull: '上次下载',
76
91
  syncNever: '无',
77
92
  syncConfirmTitle: '从云端下载',
78
- syncConfirmDesc: '将用云端数据覆盖本机勾选的同步内容(覆盖前会在原文件旁留下 .zcodepro-backup 备份);本机的同步配置与登录凭据不受影响。模型设置恢复后建议重启 ZCode 生效。确认下载?',
79
- syncConfirmGo: '确认下载',
93
+ syncConfirmDesc: '将用所选文件覆盖本机对应的一项(覆盖前会在原文件旁留下 .zcodepro-backup 备份);本机的同步配置与登录凭据不受影响。模型设置恢复后建议重启 ZCode 生效。确认导入?',
94
+ syncConfirmGo: '确认导入',
95
+ syncPickDesc: '固定名文件始终是最新一版,带时间戳的是每次上传留下的历史版本;「导入」用所选文件覆盖本机对应的一项。',
96
+ syncVerDeleteLatestNote: '注意:这是“最新”文件,旧版 zcode-pro 的「从云端下载」依赖它,删除后旧版机器将无法下载;带时间戳的历史版本不受影响。',
80
97
  syncHint: '同步登录凭据仅保存在本机 zcodepro.json;模型设置包含自定义供应商的 API Key,只会上传到你自己的 WebDAV。',
98
+ syncTest: '测试',
99
+ syncTesting: '测试中…',
100
+ syncTestEmpty: '请先填写 URL',
101
+ syncTestFailed: '测试失败',
102
+ syncTestStepConnect: '连接',
103
+ syncTestStepDir: '目录',
104
+ syncTestStepList: '文件',
105
+ syncTestFilesFound: '云端已有 {n} 个备份文件',
106
+ syncPickTitle: '请选择一个文件',
107
+ syncPickLoading: '正在读取云端文件列表…',
108
+ syncPickEmpty: '云端还没有备份文件,请先在其他电脑上传',
109
+ syncVerImport: '导入',
110
+ syncVerImporting: '导入中…',
111
+ syncVerDelete: '删除',
112
+ syncVerSave: '保存到磁盘',
113
+ syncVerSaving: '保存中…',
114
+ syncVerLatest: '最新',
115
+ syncVerDeleteTitle: '删除云端文件',
116
+ syncVerDeleteDesc: '将删除云端的这份备份,不可恢复:',
117
+ syncVerDeleted: '已删除云端备份',
118
+ syncVerSaved: '已保存到',
119
+ devMode: '开发模式',
120
+ devModeRowDesc: '开启后出现「重载 ZCode Pro」按钮;也可给启动器设环境变量 ZCODEPRO_DEV=1 启用。此标签页仅在开发模式生效时显示。',
121
+ devModeDesc: '开发调试用:改完 zcode-pro 代码后不必重启 ZCode,点「重载 ZCode Pro」即可加载新代码。流程为自动构建(需在源码目录运行)→ 以新进程重启 ZCode Pro(本地助手与注入脚本都换新)→ 所有 ZCode 窗口自动刷新并重新注入;ZCode 本体与已打开的会话不受影响。',
122
+ devReload: '重载 ZCode Pro',
123
+ devReloading: '重载中…',
124
+ devReloadDesc: '点击后约 2-3 秒内所有 ZCode 窗口自动刷新一次并加载新脚本。',
81
125
  rowGapName: '段落间距',
82
126
  rowGapDesc: '会话中段落等文本块之间的垂直间距(回合之间、答案内部)。',
83
127
  listSpacingName: '列表上下边距',
@@ -94,6 +138,8 @@ const zh = {
94
138
  tableCellPaddingDesc: '表格单元格内的留白;左输入框为上下、右为左右。',
95
139
  lineHeightName: '回答行高',
96
140
  lineHeightDesc: '回答正文的行高(倍数)。',
141
+ thinkingLineHeightName: '思考行高',
142
+ thinkingLineHeightDesc: '「已工作/工作中」过程记录(读取/编辑/查阅/终端条目与思考内容)的行高(倍数)。',
97
143
  userLineHeightName: '提问行高',
98
144
  userLineHeightDesc: '提问内容的行高(倍数)。',
99
145
  contentWidthName: '内容宽度',
@@ -157,7 +203,7 @@ const zh = {
157
203
  featurePinnedExpand: '置顶会话保持项目折叠(实验性)',
158
204
  featurePinnedExpandDesc: '点击折叠项目的置顶会话后将其保持折叠。受限于应用机制,项目会先短暂展开再缩起。',
159
205
  featureAutoUpdatePlugins: '自动更新 zcode-plugins 插件',
160
- featureAutoUpdatePluginsDesc: '启动时自动检查并更新已装的 zcode-plugins 插件(含安装市场里新增的插件),更新在新会话生效。',
206
+ featureAutoUpdatePluginsDesc: '启动时自动检查并更新已安装的 zcode-plugins 插件(只升级不安装,卸载不会被撤销),更新在新会话生效。',
161
207
  pluginsUpdateTitle: '插件更新 · zcode-plugins',
162
208
  pluginsCheckNow: '检查并更新',
163
209
  pluginsUpdating: '正在更新插件…',
@@ -169,7 +215,7 @@ const zh = {
169
215
  pluginsAutoUpdated: 'zcode-plugins 插件已更新',
170
216
  tabVision: 'Vision',
171
217
  visionDesc: '主模型不支持图片输入时(如 glm-5.3),自动把消息里的图片交给下面的视觉模型识别,把描述带给主模型(zcode-vision 插件;/vision-* 命令编辑同一配置)。改动自动保存。',
172
- visionEnabled: '启用图片识别',
218
+ visionEnabled: '启用',
173
219
  visionForceIntercept: '主模型能看图也拦截',
174
220
  visionMode: '链模式',
175
221
  visionModeFallback: '依次尝试',
@@ -194,21 +240,21 @@ const zh = {
194
240
  visionResetChainConfirm: '将链模式与代理列表恢复为默认两级(glm-session → glm-flash),当前对代理的修改会丢失。继续?',
195
241
  visionBaseUrl: '接口地址 baseUrl',
196
242
  visionModel: '模型',
197
- visionFormat: '格式',
198
243
  visionApiKey: 'API Key',
199
244
  visionApiKeyHint: '留空自动取 GLM 订阅 key',
200
245
  visionPrompt: '识别提示词(pipeline 后续步可用 {prev} 引用上一步)',
201
246
  visionTest: '测试',
202
247
  visionTesting: '测试中…',
203
248
  visionTestFailed: '视觉代理测试失败',
204
- visionTestOutput: '测试输出',
205
249
  visionCompressKB: '压缩阈值 KB',
206
250
  visionCompressKBHint: '超过该大小的图先压缩再识别(最长边 2000、JPEG);0 = 不压缩',
207
251
  visionLoadFailed: '读取视觉代理配置失败',
208
252
  tabRtk: 'rtk',
209
253
  rtkDesc: 'rtk 插件:把常见开发命令的输出压缩 60-90% 再进入上下文(/rtk-* 命令编辑同一配置)。改动自动保存并立即生效。',
210
- rtkEnabled: '启用 rtk 压缩',
211
- rtkNotInstalled: '未安装 rtk,以下配置将在安装后生效(会话里可用 /rtk-setup 安装)',
254
+ rtkEnabled: '启用',
255
+ rtkNotInstalled: '未安装 rtk 本体;安装后以下设置生效(会话里执行 /rtk-setup 也可以)',
256
+ rtkInstallBin: '安装 rtk 本体',
257
+ rtkBinInstalled: 'rtk 本体已安装;PATH 需注销重登后对会话生效,插件钩子即时生效',
212
258
  rtkWhitelistTitle: '白名单(不压缩直接放行)',
213
259
  rtkBuiltinLabel: '内置放行(只读,随插件更新):',
214
260
  rtkWhitelistDesc: '每条 name(如 docker)或 git:name(如 git:clone)。输出极小或纯副作用的命令无需压缩,加入后不再压缩;内置的 git add/commit/push、mkdir/cp 等不可移除。删除本文件即恢复默认。',
@@ -221,12 +267,25 @@ const zh = {
221
267
  tabHeadroom: 'Headroom',
222
268
  headroomDesc: 'Headroom 插件:本地压缩代理驻留 127.0.0.1(默认 8787 端口),压缩发往模型的上下文以省 token(/hr-* 命令编辑同一配置)。压缩设备与省电切换保存后立即生效;切换设备会重启代理,正在处理的请求可能中断一次。',
223
269
  headroomBinMissing: '未找到 headroom 程序,代理无法启动;安装 headroom 后以下设置自动生效',
270
+ hrInstallBin: '安装 headroom 本体',
271
+ hrBinInstalled: 'headroom 本体已安装;重新打开会话后代理可用(SessionStart 钩子自动拉起)',
224
272
  headroomInstallTitle: '未安装 headroom 插件',
225
273
  headroomInstallDesc: '从 zcode-plugins 市场安装后即可在此管理压缩代理;建议安装后重启会话生效。',
226
274
  headroomInstall: '安装',
227
275
  headroomInstalling: '安装中…',
228
276
  headroomInstalled: '已安装 headroom 插件',
229
277
  headroomInstallRetry: '安装未生效,请重试或手动在插件市场安装',
278
+ pluginInstallCardTitle: '未安装 {name} 插件',
279
+ pluginInstallCardDesc: '从 zcode-plugins 市场安装后即可在此管理;建议安装后重启会话生效。',
280
+ pluginInstallDone: '已安装 {name} 插件',
281
+ pluginEnable: '启用',
282
+ hrStarting: '正在启动压缩代理…',
283
+ hrStarted: '压缩代理已启动',
284
+ hrStartTimeout: '代理启动超时(90 秒),请检查 ~/.zcode-headroom-proxy.log',
285
+ hrStopping: '正在停止压缩代理…',
286
+ hrRestarting: '正在重启压缩代理…',
287
+ hrStopped: '压缩代理已停止',
288
+ hrUsageNone: '当前没有走 headroom 的供应商,未切换',
230
289
  headroomLoadFailed: '读取 Headroom 配置失败',
231
290
  headroomStatusTitle: '运行状态',
232
291
  headroomStatusLoadFailed: '读取运行状态失败',
@@ -252,7 +311,7 @@ const zh = {
252
311
  headroomRestart: '重启',
253
312
  headroomStopAction: '停止',
254
313
  headroomStopTitle: '停止 Headroom 代理',
255
- headroomStopDesc: '停止后,ZCode 中指向该代理(127.0.0.1)的供应商将无法连接,直至重新启动代理。确认停止?',
314
+ headroomStopDesc: '停止后,ZCode 及其他程序中指向该代理(127.0.0.1)的请求都会失败,直至重新启动代理。headroom 是共享的,其他工具可能正在使用。确认停止?',
256
315
  headroomStoppedWarn: '代理已停止;指向 127.0.0.1 的供应商将无法连接',
257
316
  headroomBackend: '压缩设备',
258
317
  headroomBackendAuto: '自动 · 显卡优先',
@@ -270,8 +329,6 @@ const zh = {
270
329
  headroomInterval: '监视间隔',
271
330
  headroomIntervalDesc: '省电监视器轮询电源状态的间隔(10–3600 秒,默认 60);保存后从下一轮巡检起生效,无需重启。',
272
331
  headroomSecUnit: '秒',
273
- headroomVersionPlugin: '插件',
274
- headroomVersionBin: '程序',
275
332
  upgradeCheck: '检查更新',
276
333
  upgradeChecking: '检查中…',
277
334
  upgradeUpToDate: '已是最新({v})',
@@ -334,16 +391,24 @@ const en = {
334
391
  agentsSave: 'Save',
335
392
  agentsSaved: 'Global prompt saved.',
336
393
  agentsLoadFailed: 'Failed to load the global prompt',
337
- proxyDesc: 'Set an HTTP proxy for network access made by the local helper: plugin marketplace updates and installs, headroom update checks and upgrades. Does not affect the ZCode app itself or model requests. Applies immediately.',
394
+ proxyDesc: 'Set an HTTP proxy for network access made by the local helper: plugin marketplace updates and installs, plugin dependency installs and upgrades, and WebDAV sync can all use it — pick the scopes with the toggles below. Does not affect the ZCode app itself or model requests. Applies immediately.',
338
395
  proxyPlaceholder: 'http://127.0.0.1:7890',
339
396
  proxySave: 'Save',
340
397
  proxySaved: 'Proxy settings saved.',
341
398
  proxyHint: 'Save empty to clear the proxy.',
342
399
  proxyTest: 'Test',
343
400
  proxyTesting: 'Testing…',
401
+ proxyTestEmpty: 'Enter a proxy address first',
344
402
  proxyTestFailed: 'Test failed',
403
+ proxyScopePlugins: 'Plugin marketplace',
404
+ proxyScopePluginsDesc: 'Marketplace checks, installs and uninstalls (zcode CLI git operations) go through the proxy.',
405
+ proxyScopeDeps: 'Plugin dependencies',
406
+ proxyScopeDepsDesc: 'headroom and rtk installs, update checks and upgrades (pip and GitHub downloads) go through the proxy.',
407
+ proxyScopeSync: 'Sync',
408
+ proxyScopeSyncDesc: 'WebDAV upload and download go through the proxy. Off by default: domestic WebDAV providers work fine direct, and a stopped proxy breaks sync.',
345
409
  tabSync: 'Sync',
346
- syncDesc: 'Manually back up ZCode Pro settings and model settings to WebDAV, or restore them on a new computer. The two items are stored as separate files, so you can upload or overwrite either one alone; data moves only when you click, never automatically.',
410
+ tabDebug: 'Debug',
411
+ syncDesc: 'Manually back up ZCode Pro settings and model settings to WebDAV, or restore them on a new computer. The two items are stored as separate files, so you can upload or overwrite either one alone; every upload also keeps a timestamped history version and download lets you pick any of them. Data moves only when you click, never automatically.',
347
412
  syncUrlPlaceholder: 'https://dav.example.com/dav/',
348
413
  syncDir: '上传目录',
349
414
  syncDirPlaceholder: 'zcode-pro',
@@ -351,7 +416,7 @@ const en = {
351
416
  syncPassword: 'Password',
352
417
  syncSave: 'Save',
353
418
  syncSaved: 'Sync settings saved.',
354
- syncFormHint: 'Sync files go to zcodepro.json and model.json inside the folder (default zcode-pro, multi-level allowed, created automatically).',
419
+ syncFormHint: 'Sync files go inside the folder (default zcode-pro, multi-level allowed, created automatically): zcodepro.json and model.json are always the latest version; timestamped history versions are kept alongside.',
355
420
  syncRecLink: 'Jianguoyun WebDAV',
356
421
  syncRecSuffix: ' — use the app password, not your account password.',
357
422
  syncIncludeZcp: 'ZCode Pro settings',
@@ -361,16 +426,44 @@ const en = {
361
426
  syncUpload: 'Upload',
362
427
  syncDownload: 'Download',
363
428
  syncUploading: 'Uploading…',
364
- syncDownloading: 'Downloading…',
365
429
  syncUploaded: 'Uploaded to the server.',
366
430
  syncDownloaded: 'Restored from the server.',
367
431
  syncLastPush: 'Last upload',
368
432
  syncLastPull: 'Last download',
369
433
  syncNever: 'never',
370
434
  syncConfirmTitle: 'Download from the server',
371
- syncConfirmDesc: 'Cloud data will overwrite the selected sections locally (a .zcodepro-backup copy is kept next to each file); your local sync config and credentials stay untouched. Restarting ZCode is recommended after restoring model settings. Download now?',
372
- syncConfirmGo: 'Download',
435
+ syncConfirmDesc: 'The selected file will overwrite the matching local section (a .zcodepro-backup copy is kept next to each file); your local sync config and credentials stay untouched. Restarting ZCode is recommended after restoring model settings. Import now?',
436
+ syncConfirmGo: 'Import',
437
+ syncPickDesc: 'Fixed names are always the latest version; timestamped files are the history each upload leaves behind. Import overwrites the matching local section.',
438
+ syncVerDeleteLatestNote: 'Note: this is the "latest" file that older zcode-pro installs download from; deleting it breaks their download. Timestamped history versions are not affected.',
373
439
  syncHint: 'Sync credentials are stored locally in zcodepro.json only; model settings contain the API keys of custom providers and go to your own WebDAV only.',
440
+ syncTest: 'Test',
441
+ syncTesting: 'Testing…',
442
+ syncTestEmpty: 'Enter the WebDAV URL first',
443
+ syncTestFailed: 'Test failed',
444
+ syncTestStepConnect: 'Connect',
445
+ syncTestStepDir: 'Folder',
446
+ syncTestStepList: 'Files',
447
+ syncTestFilesFound: '{n} backup file(s) on the server',
448
+ syncPickTitle: 'Select a file',
449
+ syncPickLoading: 'Loading files from the server…',
450
+ syncPickEmpty: 'No backups on the server yet. Upload from a computer first.',
451
+ syncVerImport: 'Import',
452
+ syncVerImporting: 'Importing…',
453
+ syncVerDelete: 'Delete',
454
+ syncVerSave: 'Save to disk',
455
+ syncVerSaving: 'Saving…',
456
+ syncVerLatest: 'Latest',
457
+ syncVerDeleteTitle: 'Delete server file',
458
+ syncVerDeleteDesc: 'This backup will be deleted from the server and cannot be recovered: ',
459
+ syncVerDeleted: 'Backup deleted from the server.',
460
+ syncVerSaved: 'Saved to',
461
+ devMode: 'Developer mode',
462
+ devModeRowDesc: 'Shows the "Reload ZCode Pro" button; can also be enabled with the ZCODEPRO_DEV=1 environment variable. This tab is visible only while developer mode is active.',
463
+ devModeDesc: 'For development: after changing zcode-pro code, click "Reload ZCode Pro" instead of restarting ZCode. It builds automatically (when running from the source repo), restarts the ZCode Pro launcher process (fresh helper and injected script), and every ZCode window refreshes and re-injects. The ZCode app itself and all sessions stay untouched.',
464
+ devReload: 'Reload ZCode Pro',
465
+ devReloading: 'Reloading…',
466
+ devReloadDesc: 'Every ZCode window refreshes automatically within 2-3 seconds to load the new script.',
374
467
  rowGapName: 'Paragraph spacing',
375
468
  rowGapDesc: 'Vertical spacing between text blocks (turns, paragraphs inside answers).',
376
469
  listSpacingName: 'List spacing',
@@ -387,6 +480,8 @@ const en = {
387
480
  tableCellPaddingDesc: 'Padding inside table cells; left input is vertical, right is horizontal.',
388
481
  lineHeightName: 'Answer line height',
389
482
  lineHeightDesc: 'Line height of answer text (multiplier).',
483
+ thinkingLineHeightName: 'Work-log line height',
484
+ thinkingLineHeightDesc: 'Line height of the “worked for…” history panel (tool entries and reasoning, multiplier).',
390
485
  userLineHeightName: 'Question line height',
391
486
  userLineHeightDesc: 'Line height of question text (multiplier).',
392
487
  contentWidthName: 'Content width',
@@ -450,7 +545,7 @@ const en = {
450
545
  featurePinnedExpand: 'Keep projects collapsed for pinned sessions (experimental)',
451
546
  featurePinnedExpandDesc: 'Keeps the project collapsed after clicking a pinned session. Note: it briefly expands first, then collapses.',
452
547
  featureAutoUpdatePlugins: 'Auto-update zcode-plugins plugins',
453
- featureAutoUpdatePluginsDesc: 'Checks and updates installed zcode-plugins plugins on startup (including newly added ones). Updates apply to new sessions.',
548
+ featureAutoUpdatePluginsDesc: 'Checks and updates installed zcode-plugins plugins on startup (updates only — never installs; uninstalled plugins stay uninstalled). Updates apply to new sessions.',
454
549
  pluginsUpdateTitle: 'Plugin updates · zcode-plugins',
455
550
  pluginsCheckNow: 'Check & update',
456
551
  pluginsUpdating: 'Updating plugins…',
@@ -462,7 +557,7 @@ const en = {
462
557
  pluginsAutoUpdated: 'zcode-plugins updated',
463
558
  tabVision: 'Vision',
464
559
  visionDesc: 'When the main model cannot see images (e.g. glm-5.3), images in messages are recognized by the vision models below and passed to the main model as text (zcode-vision plugin; /vision-* commands edit the same file). Changes save automatically.',
465
- visionEnabled: 'Enable image recognition',
560
+ visionEnabled: 'Enable',
466
561
  visionForceIntercept: 'Intercept even if the main model sees images',
467
562
  visionMode: 'Chain mode',
468
563
  visionModeFallback: 'Fallback',
@@ -487,21 +582,21 @@ const en = {
487
582
  visionResetChainConfirm: 'Reset chain mode and the proxy list to the default 2-level chain (glm-session → glm-flash)? Current proxy edits will be lost. Continue?',
488
583
  visionBaseUrl: 'Base URL',
489
584
  visionModel: 'Model',
490
- visionFormat: 'Format',
491
585
  visionApiKey: 'API Key',
492
586
  visionApiKeyHint: 'Leave empty to reuse the GLM subscription key',
493
587
  visionPrompt: 'Recognition prompt ({prev} = previous step in pipeline)',
494
588
  visionTest: 'Test',
495
589
  visionTesting: 'Testing…',
496
590
  visionTestFailed: 'Vision proxy test failed',
497
- visionTestOutput: 'Test output',
498
591
  visionCompressKB: 'Compress threshold KB',
499
592
  visionCompressKBHint: 'Images above this size are compressed first (max edge 2000, JPEG); 0 = never',
500
593
  visionLoadFailed: 'Failed to load the vision config',
501
594
  tabRtk: 'rtk',
502
595
  rtkDesc: 'rtk plugin: compresses common dev command output by 60-90% before it reaches the context (/rtk-* commands edit the same files). Changes save automatically and apply immediately.',
503
- rtkEnabled: 'Enable rtk compression',
596
+ rtkEnabled: 'Enable',
504
597
  rtkNotInstalled: 'rtk is not installed. The settings below take effect after installation (/rtk-setup in a session).',
598
+ rtkInstallBin: 'Install rtk binary',
599
+ rtkBinInstalled: 'rtk installed; PATH takes effect for sessions after signing out and back in — the plugin hook works immediately',
505
600
  rtkWhitelistTitle: 'Whitelist (pass through without compression)',
506
601
  rtkBuiltinLabel: 'Built-in exemptions (read-only, follow plugin updates):',
507
602
  rtkWhitelistDesc: 'Each entry is name (e.g. docker) or git:name (e.g. git:clone). Commands with tiny or no output need no compression; adding them skips compression. Built-ins (git add/commit/push, mkdir/cp, …) cannot be removed. Delete the file to reset.',
@@ -514,12 +609,25 @@ const en = {
514
609
  tabHeadroom: 'Headroom',
515
610
  headroomDesc: 'Headroom plugin: a local compression proxy on 127.0.0.1 (port 8787 by default) that compresses context sent to the model to save tokens (/hr-* commands edit the same file). Device and power-save changes apply immediately; switching the device restarts the proxy, so requests in progress may be interrupted once.',
516
611
  headroomBinMissing: 'The headroom program was not found, so the proxy cannot start. The settings below take effect once it is installed.',
612
+ hrInstallBin: 'Install headroom binary',
613
+ hrBinInstalled: 'headroom installed; reopen a session and the hook will start the proxy automatically',
517
614
  headroomInstallTitle: 'headroom plugin not installed',
518
615
  headroomInstallDesc: 'Install it from the zcode-plugins marketplace to manage the compression proxy here; restarting the session afterwards is recommended.',
519
616
  headroomInstall: 'Install',
520
617
  headroomInstalling: 'Installing…',
521
618
  headroomInstalled: 'headroom plugin installed',
522
619
  headroomInstallRetry: 'Installation did not take effect; retry or install it from the marketplace manually',
620
+ pluginInstallCardTitle: '{name} plugin not installed',
621
+ pluginInstallCardDesc: 'Install it from the zcode-plugins marketplace to manage it here; restarting the session afterwards is recommended.',
622
+ pluginInstallDone: '{name} plugin installed',
623
+ pluginEnable: 'Enable',
624
+ hrStarting: 'Starting compression proxy…',
625
+ hrStarted: 'Compression proxy started',
626
+ hrStartTimeout: 'Proxy start timed out (90s); check ~/.zcode-headroom-proxy.log',
627
+ hrStopping: 'Stopping compression proxy…',
628
+ hrRestarting: 'Restarting compression proxy…',
629
+ hrStopped: 'Compression proxy stopped',
630
+ hrUsageNone: 'No providers route through headroom; nothing changed',
523
631
  headroomLoadFailed: 'Failed to load the Headroom config',
524
632
  headroomStatusTitle: 'Status',
525
633
  headroomStatusLoadFailed: 'Failed to load the status',
@@ -545,7 +653,7 @@ const en = {
545
653
  headroomRestart: 'Restart',
546
654
  headroomStopAction: 'Stop',
547
655
  headroomStopTitle: 'Stop the Headroom proxy',
548
- headroomStopDesc: 'Providers in ZCode that point at this proxy (127.0.0.1) will fail to connect until it is started again. Stop it?',
656
+ headroomStopDesc: 'Requests from ZCode and other apps pointing at this proxy (127.0.0.1) will fail until it is started again. headroom is shared — other tools may be using it. Stop it?',
549
657
  headroomStoppedWarn: 'Proxy stopped; providers pointing at 127.0.0.1 cannot connect.',
550
658
  headroomBackend: 'Compression device',
551
659
  headroomBackendAuto: 'Auto · GPU first',
@@ -563,8 +671,6 @@ const en = {
563
671
  headroomInterval: 'Watch interval',
564
672
  headroomIntervalDesc: 'Seconds between power checks (10–3600, default 60); applies from the next round, no restart needed.',
565
673
  headroomSecUnit: 's',
566
- headroomVersionPlugin: 'plugin',
567
- headroomVersionBin: 'program',
568
674
  upgradeCheck: 'Check update',
569
675
  upgradeChecking: 'Checking…',
570
676
  upgradeUpToDate: 'Up to date ({v})',
@@ -695,6 +801,8 @@ const errEn = {
695
801
  'sync-remote-invalid': 'The URL already holds a different file; use another file path',
696
802
  'sync-request': 'The WebDAV request failed',
697
803
  'sync-run': 'Sync failed',
804
+ 'sync-file-invalid': 'Invalid backup file name',
805
+ 'sync-export': 'Failed to save the backup to disk',
698
806
  };
699
807
 
700
808
  export function errText(res) {
@@ -14,7 +14,7 @@ export async function startPluginUpdateCheck() {
14
14
 
15
15
  const config = await getConfig();
16
16
  if ((config.features || {}).autoUpdatePlugins === true) {
17
- const res = await rpc('/plugins/update', { method: 'POST', body: { installMissing: true } });
17
+ const res = await rpc('/plugins/update', { method: 'POST', body: {} });
18
18
  if (res.ok) showToast(L.pluginsAutoUpdated, 'success');
19
19
  else showToast(L.pluginsUpdateFailed + ': ' + (res.error || ''), 'error');
20
20
  return;