zcode-pro 0.18.0 → 0.20.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.
- package/README.en.md +1 -0
- package/README.md +1 -0
- package/bin/zcode-pro.mjs +32 -9
- package/dist/inject.js +684 -130
- package/package.json +1 -1
- package/src/host/helper.mjs +613 -50
- package/src/host/main.mjs +8 -4
- package/src/host/setup.mjs +45 -42
- package/src/host/taskIndex.mjs +258 -0
- package/src/inject/core.js +67 -19
- package/src/inject/features/file-menu.js +9 -2
- package/src/inject/features/settings-dialog.js +266 -63
- package/src/inject/features/styles.js +1 -1
- package/src/inject/features/task-order.js +1 -1
- package/src/inject/features/title-gen.js +178 -0
- package/src/inject/features/title-lock.js +73 -1
- package/src/inject/features/toolbar-icons.js +38 -4
- package/src/inject/features/ws-running.js +1 -1
- package/src/inject/index.js +2 -0
- package/src/inject/provider-fields.js +71 -0
- package/src/inject/ui.js +20 -5
package/src/inject/core.js
CHANGED
|
@@ -43,6 +43,7 @@ const zh = {
|
|
|
43
43
|
tabFeatures: '功能',
|
|
44
44
|
tabStyles: '样式',
|
|
45
45
|
tabProxy: '代理',
|
|
46
|
+
tabBehavior: '行为',
|
|
46
47
|
tabAgents: '全局提示词',
|
|
47
48
|
agentsDesc: '写入 ~/.zcode/AGENTS.md,作为默认指令用于所有项目的每次会话;保存后从新会话起生效,项目内的 AGENTS.md 可补充或覆盖。内容超过 100KB 会被应用截断。',
|
|
48
49
|
agentsPlaceholder: '填写希望所有项目默认遵循的指令;清空并保存即移除全局提示词',
|
|
@@ -66,12 +67,16 @@ const zh = {
|
|
|
66
67
|
proxyScopeSyncDesc: 'WebDAV 上传与下载走代理。默认关闭:坚果云等国内网盘直连即可,代理停了同步会跟着失败。',
|
|
67
68
|
tabSync: '同步',
|
|
68
69
|
tabDebug: '调试',
|
|
69
|
-
syncDesc: '手动把 ZCode Pro 设置与模型设置备份到 WebDAV
|
|
70
|
+
syncDesc: '手动把 ZCode Pro 设置与模型设置备份到 WebDAV,或在新电脑上恢复。两项各自独立成文件,可只上传或只覆盖其中一项;每次上传会额外保留一份带时间戳的历史版本(保留多少个见“历史版本”一行,上传后自动删除超出的最旧版本),下载时任选一个版本恢复;仅在点击按钮时传输,不做自动同步。',
|
|
70
71
|
syncUrlPlaceholder: 'https://dav.jianguoyun.com/dav/',
|
|
71
72
|
syncDir: '上传目录',
|
|
72
73
|
syncDirPlaceholder: 'zcode-pro',
|
|
73
74
|
syncLogin: '登录',
|
|
74
75
|
syncPassword: '密码',
|
|
76
|
+
syncHistoryLimit: '历史版本',
|
|
77
|
+
syncHistoryLimitUnit: '个',
|
|
78
|
+
syncHistoryLimitHint: '云端最多保留最近几次上传留下的历史版本,上传成功后自动删除更早的;固定名最新版不受影响;0 = 不保留历史版本',
|
|
79
|
+
syncPruned: '已清理 {n} 个更早的历史版本',
|
|
75
80
|
syncSave: '保存',
|
|
76
81
|
syncSaved: '同步配置已保存',
|
|
77
82
|
syncFormHint: '同步文件存到“上传目录”(默认 zcode-pro,可多级,自动创建):zcodepro.json 与 model.json 始终是最新一版,旁边另保留带时间戳的历史版本。',
|
|
@@ -92,8 +97,8 @@ const zh = {
|
|
|
92
97
|
syncConfirmTitle: '从云端下载',
|
|
93
98
|
syncConfirmDesc: '将用所选文件覆盖本机对应的一项(覆盖前会在原文件旁留下 .zcodepro-backup 备份);本机的同步配置与登录凭据不受影响。模型设置恢复后建议重启 ZCode 生效。确认导入?',
|
|
94
99
|
syncConfirmGo: '确认导入',
|
|
95
|
-
syncPickDesc: '
|
|
96
|
-
syncVerDeleteLatestNote: '注意:这是“最新”文件,旧版 zcode-pro
|
|
100
|
+
syncPickDesc: '固定名文件始终是最新一版,带时间戳的是每次上传留下的历史版本;“导入”用所选文件覆盖本机对应的一项。',
|
|
101
|
+
syncVerDeleteLatestNote: '注意:这是“最新”文件,旧版 zcode-pro 的“从云端下载”依赖它,删除后旧版机器将无法下载;带时间戳的历史版本不受影响。',
|
|
97
102
|
syncHint: '同步登录凭据仅保存在本机 zcodepro.json;模型设置包含自定义供应商的 API Key,只会上传到你自己的 WebDAV。',
|
|
98
103
|
syncTest: '测试',
|
|
99
104
|
syncTesting: '测试中…',
|
|
@@ -117,8 +122,8 @@ const zh = {
|
|
|
117
122
|
syncVerDeleted: '已删除云端备份',
|
|
118
123
|
syncVerSaved: '已保存到',
|
|
119
124
|
devMode: '开发模式',
|
|
120
|
-
devModeRowDesc: '
|
|
121
|
-
devModeDesc: '开发调试用:改完 zcode-pro 代码后不必重启 ZCode
|
|
125
|
+
devModeRowDesc: '开启后出现“重载 ZCode Pro”按钮;也可给启动器设环境变量 ZCODEPRO_DEV=1 启用。此标签页仅在开发模式生效时显示。',
|
|
126
|
+
devModeDesc: '开发调试用:改完 zcode-pro 代码后不必重启 ZCode,点“重载 ZCode Pro”即可加载新代码。流程为自动构建(需在源码目录运行)→ 以新进程重启 ZCode Pro(本地助手与注入脚本都换新)→ 所有 ZCode 窗口自动刷新并重新注入;ZCode 本体与已打开的会话不受影响。',
|
|
122
127
|
devReload: '重载 ZCode Pro',
|
|
123
128
|
devReloading: '重载中…',
|
|
124
129
|
devReloadDesc: '点击后约 2-3 秒内所有 ZCode 窗口自动刷新一次并加载新脚本。',
|
|
@@ -139,7 +144,7 @@ const zh = {
|
|
|
139
144
|
lineHeightName: '回答行高',
|
|
140
145
|
lineHeightDesc: '回答正文的行高(倍数)。',
|
|
141
146
|
thinkingLineHeightName: '思考行高',
|
|
142
|
-
thinkingLineHeightDesc: '
|
|
147
|
+
thinkingLineHeightDesc: '“已工作/工作中”过程记录(读取/编辑/查阅/终端条目与思考内容)的行高(倍数)。',
|
|
143
148
|
userLineHeightName: '提问行高',
|
|
144
149
|
userLineHeightDesc: '提问内容的行高(倍数)。',
|
|
145
150
|
contentWidthName: '内容宽度',
|
|
@@ -154,6 +159,30 @@ const zh = {
|
|
|
154
159
|
featureSessionSwitchDesc: 'alt+z 在当前与上次会话间来回切换;按住 alt 再按 x/c 弹出最近会话列表前后选择,松开 alt 切换(类 alt+tab)。',
|
|
155
160
|
featureTitleLock: '重命名会话名锁定',
|
|
156
161
|
featureTitleLockDesc: '手动重命名过的会话不再被自动标题覆盖:会话有新回答后界面可能改显自动标题,重启后又变回,本功能让侧栏始终显示重命名后的名字。',
|
|
162
|
+
tabTitleGen: '任务名提示词',
|
|
163
|
+
titleGenShortDesc: '新会话开始作答时,按所选供应商与提示词生成任务名并按手动重命名保存,官方自动标题不再覆盖。',
|
|
164
|
+
titleGenEnabled: '启用',
|
|
165
|
+
titleGenProvider: '供应商',
|
|
166
|
+
titleGenProviderNone: '不跟随(自填地址)',
|
|
167
|
+
titleGenProviderSession: '跟随当前会话',
|
|
168
|
+
titleGenProviderDeleted: '(已删除)',
|
|
169
|
+
titleGenModel: '模型',
|
|
170
|
+
titleGenModelHint: '从列表选择,或直接填写模型 id',
|
|
171
|
+
titleGenModelEmpty: '(未选择)',
|
|
172
|
+
titleGenModelSessionHint: '从列表选择模型;列表第一项为跟随会话当前模型',
|
|
173
|
+
titleGenModelFollowSession: '跟随当前会话当前模型',
|
|
174
|
+
titleGenModelManualHint: '输入模型 id',
|
|
175
|
+
titleGenBaseUrl: '接口地址',
|
|
176
|
+
titleGenApiKey: 'API Key',
|
|
177
|
+
titleGenFormat: '协议',
|
|
178
|
+
titleGenPrompt: '提示词',
|
|
179
|
+
titleGenPromptPlaceholder: '留空使用内置默认提示词(点击下方按钮可查看)',
|
|
180
|
+
titleGenPromptReset: '使用默认提示词',
|
|
181
|
+
titleGenSample: '测试消息',
|
|
182
|
+
titleGenTest: '测试生成',
|
|
183
|
+
titleGenTesting: '生成中…',
|
|
184
|
+
titleGenTestOk: '生成结果:',
|
|
185
|
+
titleGenTestFailed: '生成失败',
|
|
157
186
|
featureWsRunning: '折叠项目运行提示(实验性)',
|
|
158
187
|
featureWsRunningDesc: '折叠的项目里仍有会话在运行时,项目图标旋转提示;全部结束或展开项目后恢复。期间每 60 秒在后台短暂展开该项目复核运行状态再收起,会话行不显示,仅项目位置可能有约四分之一秒的轻微高度起伏。',
|
|
159
188
|
tabPerformance: '性能',
|
|
@@ -228,10 +257,6 @@ const zh = {
|
|
|
228
257
|
visionMoveDown: '下移',
|
|
229
258
|
visionName: '名称',
|
|
230
259
|
visionUseProvider: '供应商',
|
|
231
|
-
visionUseProviderHint: '下拉选择或手动输入:session=跟随当前会话供应商,或供应商名/ID;设置后 baseUrl/API Key/格式自动取该供应商',
|
|
232
|
-
visionUseProviderNone: '不跟随(自填地址)',
|
|
233
|
-
visionUseProviderSession: '跟随当前会话(session)',
|
|
234
|
-
visionUseProviderUnknown: '未找到该供应商,识别时会报错;请从下拉选择,或输入 session',
|
|
235
260
|
visionSkipAfterFailures: '连续失败次数',
|
|
236
261
|
visionSkipAfterFailuresHint: '某代理连续失败满次数后暂时跳过它,直接试下一个;0 = 不跳过',
|
|
237
262
|
visionSkipMinutes: '跳过分钟数',
|
|
@@ -340,7 +365,6 @@ const zh = {
|
|
|
340
365
|
upgradeDone: '已更新到 {v}',
|
|
341
366
|
upgradeFinished: '升级完成',
|
|
342
367
|
upgradeCheckFailed: '检查更新失败',
|
|
343
|
-
version: '版本',
|
|
344
368
|
close: '关闭',
|
|
345
369
|
cancel: '取消',
|
|
346
370
|
pathLabel: '路径',
|
|
@@ -385,6 +409,7 @@ const en = {
|
|
|
385
409
|
tabFeatures: 'Features',
|
|
386
410
|
tabStyles: 'Styles',
|
|
387
411
|
tabProxy: 'Proxy',
|
|
412
|
+
tabBehavior: 'Behavior',
|
|
388
413
|
tabAgents: 'Global Prompt',
|
|
389
414
|
agentsDesc: 'Written to ~/.zcode/AGENTS.md and used as default instructions in every session across all projects. Takes effect for new sessions; per-project AGENTS.md can extend or override it. Content over 100 KB is truncated by the app.',
|
|
390
415
|
agentsPlaceholder: 'Instructions followed by all projects by default; save empty to remove the global prompt',
|
|
@@ -408,12 +433,16 @@ const en = {
|
|
|
408
433
|
proxyScopeSyncDesc: 'WebDAV upload and download go through the proxy. Off by default: domestic WebDAV providers work fine direct, and a stopped proxy breaks sync.',
|
|
409
434
|
tabSync: 'Sync',
|
|
410
435
|
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.',
|
|
436
|
+
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 (how many to keep is set in the "History" row; older ones are removed automatically after upload) and download lets you pick any of them. Data moves only when you click, never automatically.',
|
|
412
437
|
syncUrlPlaceholder: 'https://dav.example.com/dav/',
|
|
413
|
-
syncDir: '
|
|
438
|
+
syncDir: 'Folder',
|
|
414
439
|
syncDirPlaceholder: 'zcode-pro',
|
|
415
440
|
syncLogin: 'Login',
|
|
416
441
|
syncPassword: 'Password',
|
|
442
|
+
syncHistoryLimit: 'History',
|
|
443
|
+
syncHistoryLimitUnit: 'versions',
|
|
444
|
+
syncHistoryLimitHint: 'How many recent uploads keep their history versions on the server; older ones are removed automatically after a successful upload. The fixed-name latest file is never removed. 0 = keep no history versions.',
|
|
445
|
+
syncPruned: 'removed {n} older history versions',
|
|
417
446
|
syncSave: 'Save',
|
|
418
447
|
syncSaved: 'Sync settings saved.',
|
|
419
448
|
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.',
|
|
@@ -496,6 +525,30 @@ const en = {
|
|
|
496
525
|
featureSessionSwitchDesc: 'alt+z toggles between the current and the last session; hold alt and press x/c to move the highlight across recently used sessions, release alt to switch (like alt+tab).',
|
|
497
526
|
featureTitleLock: 'Keep renamed session titles',
|
|
498
527
|
featureTitleLockDesc: 'Sessions you renamed keep their custom title: after new replies the app may show an auto-generated title instead, which reverts after a restart; this keeps the renamed title in the sidebar.',
|
|
528
|
+
tabTitleGen: 'Task name prompt',
|
|
529
|
+
titleGenShortDesc: 'When a new session starts answering, generates the task name with the chosen provider and prompt and saves it as a manual rename the built-in title never overrides.',
|
|
530
|
+
titleGenEnabled: 'Enable',
|
|
531
|
+
titleGenProvider: 'Provider',
|
|
532
|
+
titleGenProviderNone: 'Custom endpoint (no provider)',
|
|
533
|
+
titleGenProviderSession: 'Follow current session',
|
|
534
|
+
titleGenProviderDeleted: ' (deleted)',
|
|
535
|
+
titleGenModel: 'Model',
|
|
536
|
+
titleGenModelHint: 'Pick from the list, or type a model id',
|
|
537
|
+
titleGenModelEmpty: '(not set)',
|
|
538
|
+
titleGenModelSessionHint: 'Pick from the list; the first entry follows the session model',
|
|
539
|
+
titleGenModelFollowSession: 'Follow the session model',
|
|
540
|
+
titleGenModelManualHint: 'Type a model id',
|
|
541
|
+
titleGenBaseUrl: 'Base URL',
|
|
542
|
+
titleGenApiKey: 'API Key',
|
|
543
|
+
titleGenFormat: 'Protocol',
|
|
544
|
+
titleGenPrompt: 'Prompt',
|
|
545
|
+
titleGenPromptPlaceholder: 'Leave empty for the built-in default prompt (button below shows it)',
|
|
546
|
+
titleGenPromptReset: 'Use default prompt',
|
|
547
|
+
titleGenSample: 'Test message',
|
|
548
|
+
titleGenTest: 'Test',
|
|
549
|
+
titleGenTesting: 'Generating…',
|
|
550
|
+
titleGenTestOk: 'Result: ',
|
|
551
|
+
titleGenTestFailed: 'Generation failed',
|
|
499
552
|
featureWsRunning: 'Running indicator on collapsed projects (experimental)',
|
|
500
553
|
featureWsRunningDesc: 'Spins a collapsed project\'s icon while any of its sessions is still running; stops when they all finish or the project is expanded. While spinning, the project is briefly re-expanded in the background every 60 s to re-check and then collapsed — rows stay hidden, with only a subtle quarter-second height ripple at the project.',
|
|
501
554
|
tabPerformance: 'Performance',
|
|
@@ -570,10 +623,6 @@ const en = {
|
|
|
570
623
|
visionMoveDown: 'Down',
|
|
571
624
|
visionName: 'Name',
|
|
572
625
|
visionUseProvider: 'Provider',
|
|
573
|
-
visionUseProviderHint: 'Pick from the list or type: session = follow the current session provider, or a provider name/ID; baseUrl/API key/format follow that provider',
|
|
574
|
-
visionUseProviderNone: 'Not following (enter base URL)',
|
|
575
|
-
visionUseProviderSession: 'Follow session provider (session)',
|
|
576
|
-
visionUseProviderUnknown: 'Unknown provider; recognition will fail. Pick from the list or type session',
|
|
577
626
|
visionSkipAfterFailures: 'Skip after failures',
|
|
578
627
|
visionSkipAfterFailuresHint: 'After this many consecutive failures a proxy is skipped and the next one is tried; 0 = never skip',
|
|
579
628
|
visionSkipMinutes: 'Skip minutes',
|
|
@@ -682,7 +731,6 @@ const en = {
|
|
|
682
731
|
upgradeDone: 'Updated to {v}',
|
|
683
732
|
upgradeFinished: 'Update finished',
|
|
684
733
|
upgradeCheckFailed: 'Update check failed',
|
|
685
|
-
version: 'Version',
|
|
686
734
|
close: 'Close',
|
|
687
735
|
cancel: 'Cancel',
|
|
688
736
|
pathLabel: 'Path',
|
|
@@ -855,7 +903,7 @@ export function observeRadixPopups(onPopup) {
|
|
|
855
903
|
}
|
|
856
904
|
// 兜底:直接观察 role=menu 的 content。延迟一帧再回调——Radix 偶尔分两帧渲染
|
|
857
905
|
// (先挂 menu 容器、下一帧才填菜单项),立即回调时菜单项为空,调用方找不到
|
|
858
|
-
//
|
|
906
|
+
// 参照的菜单项就永远漏注入(菜单项填入不会再产生 role=menu 节点添加事件)
|
|
859
907
|
if (node.getAttribute && node.getAttribute('role') === 'menu' && !seen.has(node)) {
|
|
860
908
|
seen.add(node);
|
|
861
909
|
requestAnimationFrame(() => {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
// 触发器/菜单的 React fiber props(OpenSplitButton 场景 target/fileLink/row.path)。
|
|
9
9
|
import { t, closeRadixMenu, itemsOf, itemText, rpc } from '../core.js';
|
|
10
10
|
import { getConfig } from '../core.js';
|
|
11
|
+
import { showToast } from '../ui.js';
|
|
11
12
|
|
|
12
13
|
const COPY_ABS_TEXTS = ['复制绝对路径', 'Copy absolute path'];
|
|
13
14
|
const NO_APPS_TEXTS = ['未找到可用 App', 'No apps found'];
|
|
@@ -126,6 +127,12 @@ export function handleFileMenu(content) {
|
|
|
126
127
|
const path = resolveTargetPath(content);
|
|
127
128
|
if (!path) return;
|
|
128
129
|
const L = t();
|
|
130
|
+
// 打开失败(路径不存在等)弹 toast 报错,不再无声无息
|
|
131
|
+
const fire = (endpoint, label) => {
|
|
132
|
+
rpc(endpoint, { method: 'POST', body: { path } })
|
|
133
|
+
.then((r) => { if (r && r.ok === false) showToast(`${label}失败:${r.error || '未知错误'}`, 'error'); })
|
|
134
|
+
.catch(() => { /* 网络异常时 helper 多半未运行,此时菜单不会注入,静默 */ });
|
|
135
|
+
};
|
|
129
136
|
// “默认应用打开”锚在编辑器列表末尾(无可用编辑器时即“未找到可用 App”禁用项)之上;
|
|
130
137
|
// 找不到该组时退而锚在“复制绝对路径”上,保持“打开方式在前、路径操作在后”的次序
|
|
131
138
|
const noApps = items.find((el) => NO_APPS_TEXTS.some((x) => itemText(el) === x))
|
|
@@ -135,13 +142,13 @@ export function handleFileMenu(content) {
|
|
|
135
142
|
marker: 'file-open-default',
|
|
136
143
|
label: L.fileOpenDefault,
|
|
137
144
|
icon: ICON_OPEN_DEFAULT,
|
|
138
|
-
onPick: () => {
|
|
145
|
+
onPick: () => { void fire('/open-path', L.fileOpenDefault); },
|
|
139
146
|
});
|
|
140
147
|
appendMenuItem(content, copyAbs, copyAbs, {
|
|
141
148
|
marker: 'file-reveal',
|
|
142
149
|
label: L.fileReveal,
|
|
143
150
|
icon: ICON_REVEAL,
|
|
144
|
-
onPick: () => {
|
|
151
|
+
onPick: () => { void fire('/reveal-path', L.fileReveal); },
|
|
145
152
|
});
|
|
146
153
|
})();
|
|
147
154
|
}
|