zcode-pro 1.3.0 → 1.3.1
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/dist/inject.js +26 -4
- package/package.json +1 -1
- package/src/host/helper.mjs +1 -1
- package/src/inject/features/ws-running.js +43 -7
package/dist/inject.js
CHANGED
|
@@ -7024,7 +7024,7 @@
|
|
|
7024
7024
|
}
|
|
7025
7025
|
var SEC_SPIN_CLASS = "zcodepro-ws-sec-spin";
|
|
7026
7026
|
var anyActiveCache = { at: 0, value: null, busy: false };
|
|
7027
|
-
var sectionActive = { task: false, project: false };
|
|
7027
|
+
var sectionActive = { task: false, project: false, pinned: false };
|
|
7028
7028
|
var activeProjectPaths = /* @__PURE__ */ new Set();
|
|
7029
7029
|
setInterval(() => {
|
|
7030
7030
|
if (!anyActiveCache.busy && Date.now() - anyActiveCache.at >= 1e4) globalAnyActive();
|
|
@@ -7035,6 +7035,7 @@
|
|
|
7035
7035
|
anyActiveCache.busy = true;
|
|
7036
7036
|
sectionActive.task = false;
|
|
7037
7037
|
sectionActive.project = false;
|
|
7038
|
+
sectionActive.pinned = false;
|
|
7038
7039
|
activeProjectPaths = /* @__PURE__ */ new Set();
|
|
7039
7040
|
void (async () => {
|
|
7040
7041
|
let hit = null;
|
|
@@ -7102,8 +7103,29 @@
|
|
|
7102
7103
|
}
|
|
7103
7104
|
}
|
|
7104
7105
|
const taskDomRunning = !!document.querySelector('[data-task-item-key]:not(section[data-project-id] *) svg[class*="lucide-loader"]');
|
|
7105
|
-
|
|
7106
|
-
|
|
7106
|
+
const taskLive = [...byKind.task].some(live);
|
|
7107
|
+
const projLive = [...byKind.project].some(live);
|
|
7108
|
+
if (taskLive) sectionActive.task = true;
|
|
7109
|
+
if (projLive) sectionActive.project = true;
|
|
7110
|
+
if (!taskDomRunning && taskLive && document.querySelector("[data-task-item-key]:not(section[data-project-id] *)")) {
|
|
7111
|
+
sectionActive.task = false;
|
|
7112
|
+
}
|
|
7113
|
+
for (const h3 of document.querySelectorAll("h3")) {
|
|
7114
|
+
const list = h3.nextElementSibling;
|
|
7115
|
+
if (!list) continue;
|
|
7116
|
+
for (const el of list.querySelectorAll("[data-task-item-key]")) {
|
|
7117
|
+
if (el.closest("section[data-project-id]")) continue;
|
|
7118
|
+
const k = el.getAttribute("data-task-item-key") || "";
|
|
7119
|
+
const id = k.slice(k.indexOf(":sess_") + 1);
|
|
7120
|
+
const base = k.slice(0, k.lastIndexOf(":")).replace(/[\/]+$/, "");
|
|
7121
|
+
const ids = byKindByPath.get(base) || [];
|
|
7122
|
+
if (ids.map(String).includes(id) && ids.some(live)) {
|
|
7123
|
+
sectionActive.pinned = true;
|
|
7124
|
+
break;
|
|
7125
|
+
}
|
|
7126
|
+
}
|
|
7127
|
+
if (sectionActive.pinned) break;
|
|
7128
|
+
}
|
|
7107
7129
|
hit = sectionActive.task || sectionActive.project;
|
|
7108
7130
|
}
|
|
7109
7131
|
} catch {
|
|
@@ -7128,7 +7150,7 @@
|
|
|
7128
7150
|
expanded = !list || list.offsetHeight > 0;
|
|
7129
7151
|
}
|
|
7130
7152
|
if (!kind) return;
|
|
7131
|
-
const scoped = kind === "project" ? sectionActive.project : sectionActive.task;
|
|
7153
|
+
const scoped = head.tagName === "H3" ? sectionActive.pinned : kind === "project" ? sectionActive.project : sectionActive.task;
|
|
7132
7154
|
const want = !expanded && scoped;
|
|
7133
7155
|
const existing = head.querySelector(":scope > ." + SEC_SPIN_CLASS);
|
|
7134
7156
|
if (want && !existing) {
|
package/package.json
CHANGED
package/src/host/helper.mjs
CHANGED
|
@@ -17,7 +17,7 @@ import { reorderWorkspaceTasks, reorderGroupMembers } from './taskOrder.mjs';
|
|
|
17
17
|
import { webdavRequest, webdavPutWithMkcol, webdavHttpText, parseWebdavListing, findCurl } from './webdav.mjs';
|
|
18
18
|
import { resolveZcodeExecutable } from './paths.mjs';
|
|
19
19
|
|
|
20
|
-
const VERSION = '1.3.
|
|
20
|
+
const VERSION = '1.3.1';
|
|
21
21
|
|
|
22
22
|
// 全局提示词固定在用户主目录:官方加载器按 HOME/USERPROFILE 拼 .zcode/AGENTS.md,
|
|
23
23
|
// 不读 ZCODE_DATA_BASE_DIR(数据根迁走时全局指令仍在原位)。
|
|
@@ -374,8 +374,10 @@ const SEC_SPIN_CLASS = 'zcodepro-ws-sec-spin';
|
|
|
374
374
|
// 尾斜杠两种形式各查一次),任一非终态会话即“有任务在跑”。10 秒节流缓存;
|
|
375
375
|
// 接口不可用(≤3.15.x)时无缓存,分区头退回 DOM 检测
|
|
376
376
|
let anyActiveCache = { at: 0, value: null, busy: false };
|
|
377
|
-
// 活跃按分区归属:task = “任务”分区(非项目工作区),project =
|
|
378
|
-
|
|
377
|
+
// 活跃按分区归属:task = “任务”分区(非项目工作区),project = “项目”分区,
|
|
378
|
+
// pinned = “已置顶”标题(置顶区任务,需单独判定——不与 task/project 混用,
|
|
379
|
+
// 否则别的分区有活跃时已置顶头也会亮)
|
|
380
|
+
const sectionActive = { task: false, project: false, pinned: false };
|
|
379
381
|
// 权威扫描发现的有活跃任务的项目路径集合(全部 root);项目行折叠态判定用
|
|
380
382
|
let activeProjectPaths = new Set();
|
|
381
383
|
// 周期复查:缓存到期就无条件重扫(不看当前值)——只在 true 时扫会有两个缺口:
|
|
@@ -390,6 +392,7 @@ function globalAnyActive() {
|
|
|
390
392
|
anyActiveCache.busy = true;
|
|
391
393
|
sectionActive.task = false;
|
|
392
394
|
sectionActive.project = false;
|
|
395
|
+
sectionActive.pinned = false;
|
|
393
396
|
activeProjectPaths = new Set();
|
|
394
397
|
void (async () => {
|
|
395
398
|
let hit = null;
|
|
@@ -465,11 +468,42 @@ function globalAnyActive() {
|
|
|
465
468
|
if (projName) for (const p2 of projectPaths.get(projName) || []) activeProjectPaths.add(p2);
|
|
466
469
|
}
|
|
467
470
|
}
|
|
468
|
-
//
|
|
469
|
-
//
|
|
471
|
+
// 任务侧加一道 DOM 确认:非项目任务行上真有 loader 在转才亮——侧栏
|
|
472
|
+
// 显示的就是真相,syncer 报告的活跃(尤其历史残留工作区)不足为凭。
|
|
473
|
+
// 但“任务”分区折叠后行整体卸载(DOM 检测失效),此时退回只信权威扫描
|
|
474
|
+
//(否则分区折叠后头永远不亮——用户实测回归)
|
|
470
475
|
const taskDomRunning = !!document.querySelector('[data-task-item-key]:not(section[data-project-id] *) svg[class*="lucide-loader"]');
|
|
471
|
-
|
|
472
|
-
|
|
476
|
+
const taskLive = [...byKind.task].some(live);
|
|
477
|
+
const projLive = [...byKind.project].some(live);
|
|
478
|
+
// 分区头亮灯各管各的:任务头只看非项目工作区,项目头只看项目工作区。
|
|
479
|
+
// 折叠后行不在场(DOM 检测失效),只信权威扫描;DOM 确认仅在非项目
|
|
480
|
+
// 任务行在场(分区展开着)时用来否决 syncer 卡滞误报
|
|
481
|
+
if (taskLive) sectionActive.task = true;
|
|
482
|
+
if (projLive) sectionActive.project = true;
|
|
483
|
+
if (!taskDomRunning && taskLive
|
|
484
|
+
&& document.querySelector('[data-task-item-key]:not(section[data-project-id] *)')) {
|
|
485
|
+
// 非项目任务行在场但全没 loader(分区展开着)→ syncer 卡滞误报
|
|
486
|
+
sectionActive.task = false;
|
|
487
|
+
}
|
|
488
|
+
// 已置顶区单独判定:取“已置顶”标题(h3)旁边列表容器内的任务行
|
|
489
|
+
// (不在任何 data-project-id 分区里),它们的 id 有活跃才亮已置顶头
|
|
490
|
+
// ——跟 task/project 分区的活跃无关
|
|
491
|
+
for (const h3 of document.querySelectorAll('h3')) {
|
|
492
|
+
const list = h3.nextElementSibling;
|
|
493
|
+
if (!list) continue;
|
|
494
|
+
for (const el of list.querySelectorAll('[data-task-item-key]')) {
|
|
495
|
+
if (el.closest('section[data-project-id]')) continue;
|
|
496
|
+
const k = el.getAttribute('data-task-item-key') || '';
|
|
497
|
+
const id = k.slice(k.indexOf(':sess_') + 1);
|
|
498
|
+
const base = k.slice(0, k.lastIndexOf(':')).replace(/[\/]+$/, '');
|
|
499
|
+
const ids = byKindByPath.get(base) || [];
|
|
500
|
+
if (ids.map(String).includes(id) && ids.some(live)) {
|
|
501
|
+
sectionActive.pinned = true;
|
|
502
|
+
break;
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
if (sectionActive.pinned) break;
|
|
506
|
+
}
|
|
473
507
|
hit = sectionActive.task || sectionActive.project;
|
|
474
508
|
}
|
|
475
509
|
} catch { /* 查询失败保持旧值 */ }
|
|
@@ -500,7 +534,9 @@ function applySectionSpin() {
|
|
|
500
534
|
expanded = !list || list.offsetHeight > 0;
|
|
501
535
|
}
|
|
502
536
|
if (!kind) return; // 折叠后解析不到归属且无缓存:跳过(不动现有图标)
|
|
503
|
-
|
|
537
|
+
// 已置顶标题(h3)单独看 pinned scope,不复用 task 的
|
|
538
|
+
const scoped = head.tagName === 'H3' ? sectionActive.pinned
|
|
539
|
+
: kind === 'project' ? sectionActive.project : sectionActive.task;
|
|
504
540
|
// 折叠态一律只信权威扫描:DOM 检测在折叠后不可靠(容器卸载后解析会落到
|
|
505
541
|
// 别的分区,多目录项目的行匹配也套不上),且权威扫描周期覆盖刷新
|
|
506
542
|
const want = !expanded && scoped;
|