@aiti-ai/aiti-git-trace 0.0.0-stage → 0.2.11

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 (41) hide show
  1. package/AGENTS.md +28 -0
  2. package/LICENSE +21 -0
  3. package/api.ts +424 -0
  4. package/check-client.mjs +273 -0
  5. package/client/src/common.ts +179 -0
  6. package/client/src/entry.tsx +81 -0
  7. package/client/src/host-shim.ts +118 -0
  8. package/client/src/jsx-runtime.ts +2 -0
  9. package/client/src/panels.tsx +1377 -0
  10. package/client/src/trace-app.tsx +275 -0
  11. package/client/src/trace-files-row.pure.ts +88 -0
  12. package/client/src/trace-files-row.tsx +110 -0
  13. package/client/src/version-mention.ts +90 -0
  14. package/deploy-commit.mjs +52 -0
  15. package/dev-pack.mjs +246 -0
  16. package/dist/aiti-git-trace-client.mjs +4 -0
  17. package/dist/entry-C_le59dp.js +1594 -0
  18. package/dist/panels-BpC4XLni.js +1522 -0
  19. package/ext-icons-deploy.mjs +24 -0
  20. package/icon.svg +1 -0
  21. package/icons/git-branch.svg +1 -0
  22. package/icons/git-commit-horizontal.svg +1 -0
  23. package/index.ts +705 -0
  24. package/package.json +33 -4
  25. package/reconcile-deps.mjs +41 -0
  26. package/reload-instances.mjs +60 -0
  27. package/scripts/aiti-trace.mjs +117 -0
  28. package/skills/index.json +1 -0
  29. package/skills/rollback-session/SKILL.md +34 -0
  30. package/skills/trace-ops/SKILL.md +31 -0
  31. package/skills/watch-path/SKILL.md +34 -0
  32. package/test/fixtures/ops-sample.jsonl +3 -0
  33. package/tools/deploy.mjs +103 -0
  34. package/tools/trace-compact.mjs +58 -0
  35. package/trace-core.test.mjs +1120 -0
  36. package/trace-core.ts +1346 -0
  37. package/trace-files-row.test.mjs +66 -0
  38. package/tsconfig.check.json +21 -0
  39. package/version-mention.test.mjs +76 -0
  40. package/vite.config.ts +43 -0
  41. package/README.md +0 -3
@@ -0,0 +1,1594 @@
1
+ let It = null;
2
+ function j() {
3
+ if (It) return It;
4
+ try {
5
+ return globalThis.__aitiGitTraceHostCtx ?? null;
6
+ } catch {
7
+ return null;
8
+ }
9
+ }
10
+ function Pe(t) {
11
+ It = t;
12
+ try {
13
+ globalThis.__aitiGitTraceHostCtx = t;
14
+ } catch {
15
+ }
16
+ }
17
+ function jn(t) {
18
+ return j()?.getExtService?.(t);
19
+ }
20
+ function pt(t) {
21
+ return j()?.[t] ?? (() => {
22
+ });
23
+ }
24
+ const $n = typeof Symbol < "u" && Symbol.for ? Symbol.for("react.fragment") : 2763;
25
+ function u(...t) {
26
+ return pt("h").call(null, ...t);
27
+ }
28
+ function ee(t) {
29
+ const [e, n, a, ...s] = t;
30
+ if (n && typeof n == "object") {
31
+ const r = { ...n };
32
+ return a != null && (r.key = a), [e, r, ...s];
33
+ }
34
+ return t;
35
+ }
36
+ const b = (...t) => u(...ee(t)), $ = (...t) => {
37
+ const n = t[1]?.children;
38
+ if (Array.isArray(n))
39
+ for (const a of n)
40
+ a && typeof a == "object" && a._store && (a._store.validated = 1);
41
+ return u(...ee(t));
42
+ }, w = (t) => pt("useState")(t), v = (t, e) => pt("useEffect")(t, e), zn = (t) => pt("useRef")(t);
43
+ function ht(t) {
44
+ const e = j()?.apiUrl;
45
+ return typeof e == "function" ? e(t) : t;
46
+ }
47
+ function C(t, e) {
48
+ const n = j()?.t;
49
+ return typeof n == "function" ? n(t, e) : t;
50
+ }
51
+ function Fn(t) {
52
+ const e = j()?.appendText;
53
+ try {
54
+ typeof e == "function" && e(t);
55
+ } catch {
56
+ }
57
+ }
58
+ function Vn(t, e) {
59
+ const n = j()?.openFile;
60
+ try {
61
+ typeof n == "function" && n(t, e);
62
+ } catch {
63
+ }
64
+ }
65
+ function Ne(t) {
66
+ if (t.transform !== "none" || t.perspective !== "none" || t.filter !== "none" || /transform|perspective|filter/.test(t.willChange || "")) return !0;
67
+ const e = t.contain;
68
+ return e === "strict" || e === "content" || e === "layout" || e === "paint";
69
+ }
70
+ function He(t) {
71
+ let e = t.parentElement;
72
+ for (; e && e !== document.documentElement; ) {
73
+ try {
74
+ if (Ne(getComputedStyle(e))) {
75
+ const n = e.getBoundingClientRect();
76
+ return { x: n.left, y: n.top };
77
+ }
78
+ } catch {
79
+ }
80
+ e = e.parentElement;
81
+ }
82
+ return { x: 0, y: 0 };
83
+ }
84
+ function je(t, e, n, a, s = 8) {
85
+ const r = window.innerWidth, o = window.innerHeight;
86
+ return {
87
+ left: Math.max(s, Math.min(t, r - s - n)),
88
+ top: Math.max(s, Math.min(e, Math.max(s, o - s - a)))
89
+ };
90
+ }
91
+ const m = (t) => ({ tag: "path", attrs: { d: t } }), tt = (t, e, n, a, s = 2) => ({ tag: "rect", attrs: { x: t, y: e, width: n, height: a, rx: s } }), ne = {
92
+ /** 浮窗:圆角框 + 标题栏 + 圆点(app-window;用户 2026-09-15 定稿 C)。 */
93
+ float: [
94
+ tt(2, 4, 20, 16, 2),
95
+ m("M10 4v4"),
96
+ m("M2 8h20"),
97
+ m("M6 4v4")
98
+ ],
99
+ /** 新窗口打开:方框 + 右上外斜箭头(square-arrow-out-up-right;
100
+ * 用户 2026-09-15 拍板:B 图形用作「新窗口打开」,且仅支持的面板(文件/文件夹)显示)。 */
101
+ "new-window": [
102
+ m("M21 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h6"),
103
+ m("m21 3-9 9"),
104
+ m("M15 3h6v6")
105
+ ],
106
+ /** 左栏:方框 + 左缘粗边。 */
107
+ "panel-left": [tt(3, 3, 18, 18), m("M9 3v18")],
108
+ /** 右栏:方框 + 右缘粗边。 */
109
+ "panel-right": [tt(3, 3, 18, 18), m("M15 3v18")],
110
+ /** 底部(预留位):方框 + 下缘粗边。 */
111
+ "panel-bottom": [tt(3, 3, 18, 18), m("M3 15h18")],
112
+ "chevron-up": [m("m18 15-6-6-6 6")],
113
+ "chevron-down": [m("m6 9 6 6 6-6")],
114
+ "chevron-left": [m("m15 18-6-6 6-6")],
115
+ "chevron-right": [m("m9 18 6-6-6-6")],
116
+ "arrow-up": [m("m5 12 7-7 7 7"), m("M12 19V5")],
117
+ /** 钉住:图钉(lucide pin;⋮ 区块操作「钉住」,与 aiti-folder MiPin 同形)。 */
118
+ pin: [
119
+ { tag: "line", attrs: { x1: 12, y1: 17, x2: 12, y2: 22 } },
120
+ m("M5 17h14v-1.76a2 2 0 0 0-1.11-1.79l-1.78-.9A2 2 0 0 1 15 10.76V6h1a2 2 0 0 0 0-4H8a2 2 0 0 0 0 4h1v4.76a2 2 0 0 1-1.11 1.79l-1.78.9A2 2 0 0 0 5 15.24Z")
121
+ ],
122
+ /** 关闭:×(lucide x;⋮ 区块操作「关闭」)。 */
123
+ x: [m("M18 6 6 18"), m("m6 6 12 12")],
124
+ /** 移除本实例:垃圾桶(lucide trash;多实例区块 ⋮「移除本实例」,与 aiti-folder MiTrash 同形)。 */
125
+ trash: [
126
+ { tag: "polyline", attrs: { points: "3 6 5 6 21 6" } },
127
+ m("M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"),
128
+ { tag: "line", attrs: { x1: 10, y1: 11, x2: 10, y2: 17 } },
129
+ { tag: "line", attrs: { x1: 14, y1: 11, x2: 14, y2: 17 } }
130
+ ],
131
+ /** 移动:对角双箭头(lucide move-diagonal-2;⋮「移动」行首图标——左上 + 右下,用户 2026-09-15 指定)。 */
132
+ "move-diagonal-2": [
133
+ m("M5 11V5h6"),
134
+ m("M19 13v6h-6"),
135
+ m("M5 5l14 14")
136
+ ]
137
+ };
138
+ function $e(t) {
139
+ return t === "float" || t === "floating" ? "float" : t === "sidebar-explorer" || t.startsWith("sidebar:") ? "panel-left" : t === "bottom-panel" || t.startsWith("bottom:") ? "panel-bottom" : "panel-right";
140
+ }
141
+ const Ut = "http://www.w3.org/2000/svg";
142
+ function ze(t, e = 16) {
143
+ const n = document.createElementNS(Ut, "svg");
144
+ n.setAttribute("viewBox", "0 0 24 24"), n.setAttribute("width", String(e)), n.setAttribute("height", String(e)), n.setAttribute("fill", "none"), n.setAttribute("stroke", "currentColor"), n.setAttribute("stroke-width", "2"), n.setAttribute("stroke-linecap", "round"), n.setAttribute("stroke-linejoin", "round"), n.setAttribute("aria-hidden", "true");
145
+ for (const a of ne[t] ?? []) {
146
+ const s = document.createElementNS(Ut, a.tag);
147
+ for (const [r, o] of Object.entries(a.attrs)) s.setAttribute(r, String(o));
148
+ n.appendChild(s);
149
+ }
150
+ return n;
151
+ }
152
+ const Fe = {
153
+ viewBox: "0 0 24 24",
154
+ fill: "none",
155
+ stroke: "currentColor",
156
+ strokeWidth: 2,
157
+ strokeLinecap: "round",
158
+ strokeLinejoin: "round"
159
+ };
160
+ function at(t) {
161
+ return `sidebar:${t}`;
162
+ }
163
+ function Wt(t) {
164
+ return t === "docked:sidebar-explorer" || t.startsWith("docked:sidebar:");
165
+ }
166
+ const oe = "pi:sidebar-dock:collapsed:", Dt = "pi:sidebar-dock:collapsed-changed", Ve = "pi:sidebar-dock:move", Ge = "pi:sidebar-dock:drop";
167
+ function Zt(t) {
168
+ try {
169
+ return localStorage.getItem(oe + t) === "1";
170
+ } catch {
171
+ return !1;
172
+ }
173
+ }
174
+ function ie(t, e) {
175
+ try {
176
+ localStorage.setItem(oe + t, e ? "1" : "0");
177
+ } catch {
178
+ }
179
+ try {
180
+ window.dispatchEvent(new CustomEvent(Dt, { detail: { key: t, collapsed: e } }));
181
+ } catch {
182
+ }
183
+ }
184
+ const Jt = "piwe-float-installed", qe = 1e4;
185
+ function Ye(t) {
186
+ return t ? t.map((e) => `${e.id}|${e.title}|${e.badge ?? ""}|${e.active ? 1 : 0}|${e.done ? 1 : 0}|${e.disabled ? 1 : 0}|${e.visibility ?? "always"}`).join("§") : "";
187
+ }
188
+ function Ue(t) {
189
+ return t ? t.map((e) => e.kind === "item" ? `i:${e.id ?? e.label}:${e.label}:${e.hint ?? ""}:${e.active ? 1 : 0}:${e.alwaysRun ? 1 : 0}:${e.disabled ? 1 : 0}` : e.kind === "head" ? `h:${e.label}` : "s").join("§") : "";
190
+ }
191
+ function Ze(t) {
192
+ try {
193
+ return JSON.stringify(t);
194
+ } catch {
195
+ return `keys:${Object.keys(t).length}`;
196
+ }
197
+ }
198
+ function Je() {
199
+ const t = /* @__PURE__ */ new Map(), e = /* @__PURE__ */ new Map(), n = (r) => {
200
+ let o = t.get(r);
201
+ return o || (o = { actions: null, commands: null, state: {}, menuItems: null, pending: null, sig: { actions: "", state: "{}", menu: "" } }, t.set(r, o)), o;
202
+ }, a = (r) => {
203
+ const o = e.get(r);
204
+ if (o)
205
+ for (const c of [...o])
206
+ try {
207
+ c();
208
+ } catch {
209
+ }
210
+ }, s = (r) => {
211
+ const o = n(r), c = o.pending;
212
+ if (!c) return;
213
+ if (Date.now() - c.at > qe) {
214
+ o.pending = null;
215
+ return;
216
+ }
217
+ const l = o.commands?.[c.id];
218
+ if (typeof l == "function") {
219
+ o.pending = null;
220
+ try {
221
+ l(c.payload);
222
+ } catch {
223
+ }
224
+ }
225
+ };
226
+ return {
227
+ register(r, o) {
228
+ const c = n(r);
229
+ if ("actions" in o) {
230
+ const l = o.actions ?? null;
231
+ c.actions = l;
232
+ const f = Ye(l);
233
+ f !== c.sig.actions && (c.sig.actions = f, a(r));
234
+ }
235
+ if ("state" in o) {
236
+ const l = o.state ?? {};
237
+ c.state = l;
238
+ const f = Ze(l);
239
+ f !== c.sig.state && (c.sig.state = f, a(r));
240
+ }
241
+ if ("menuItems" in o) {
242
+ const l = o.menuItems ?? null;
243
+ c.menuItems = l;
244
+ const f = Ue(l);
245
+ f !== c.sig.menu && (c.sig.menu = f, a(r));
246
+ }
247
+ return "commands" in o && (c.commands = o.commands ?? null, s(r)), () => {
248
+ const l = t.get(r);
249
+ l && ("actions" in o && l.actions === (o.actions ?? null) && (l.actions = null, l.sig.actions = "", a(r)), "menuItems" in o && l.menuItems === (o.menuItems ?? null) && (l.menuItems = null, l.sig.menu = "", a(r)), "commands" in o && l.commands === (o.commands ?? null) && (l.commands = null), "state" in o && (l.state = {}, l.sig.state = "{}", a(r)));
250
+ };
251
+ },
252
+ request(r, o, c) {
253
+ const l = n(r), f = l.commands?.[o];
254
+ if (typeof f == "function") {
255
+ try {
256
+ f(c);
257
+ } catch {
258
+ }
259
+ return !0;
260
+ }
261
+ l.pending = { id: o, at: Date.now(), payload: c };
262
+ try {
263
+ ie(r, !1);
264
+ } catch {
265
+ }
266
+ return !1;
267
+ },
268
+ actionsOf(r) {
269
+ return t.get(r)?.actions ?? null;
270
+ },
271
+ commandsOf(r) {
272
+ return t.get(r)?.commands ?? null;
273
+ },
274
+ stateOf(r) {
275
+ return t.get(r)?.state ?? {};
276
+ },
277
+ menuItemsOf(r) {
278
+ return t.get(r)?.menuItems ?? null;
279
+ },
280
+ subscribe(r, o) {
281
+ let c = e.get(r);
282
+ return c || (c = /* @__PURE__ */ new Set(), e.set(r, c)), c.add(o), () => {
283
+ const l = e.get(r);
284
+ l && (l.delete(o), l.size === 0 && e.delete(r));
285
+ };
286
+ }
287
+ };
288
+ }
289
+ let Ct = null;
290
+ function Ke() {
291
+ return Ct || (Ct = Je()), Ct;
292
+ }
293
+ const Xe = "__piweFloat", Tt = "piwe-float-present-change", dt = (t) => `pi-web:ext-float:dockpref:v1:${t}`;
294
+ function T() {
295
+ const t = window[Xe];
296
+ return t && typeof t.present == "function" ? t : null;
297
+ }
298
+ const re = "pi-web:ext-float:localstates:v1", Bt = "pi-web:ext-float:localstates-rev:v1";
299
+ function ae() {
300
+ try {
301
+ const t = localStorage.getItem(re), e = t ? JSON.parse(t) : null;
302
+ return new Map(Object.entries(e ?? {}));
303
+ } catch {
304
+ return /* @__PURE__ */ new Map();
305
+ }
306
+ }
307
+ const H = ae();
308
+ let ut = "";
309
+ try {
310
+ ut = localStorage.getItem(Bt) ?? "";
311
+ } catch {
312
+ }
313
+ function se() {
314
+ let t = "";
315
+ try {
316
+ t = localStorage.getItem(Bt) ?? "";
317
+ } catch {
318
+ }
319
+ if (t === ut) return;
320
+ ut = t;
321
+ const e = ae();
322
+ H.clear();
323
+ for (const [n, a] of e) H.set(n, a);
324
+ }
325
+ function Qe() {
326
+ const t = String(Date.now()) + "-" + Math.random().toString(36).slice(2, 8);
327
+ try {
328
+ localStorage.setItem(re, JSON.stringify(Object.fromEntries(H))), localStorage.setItem(Bt, t);
329
+ } catch {
330
+ }
331
+ ut = t;
332
+ }
333
+ const Lt = /* @__PURE__ */ new Set(), tn = "piwe-float-present-activate";
334
+ function ce(t, e, n) {
335
+ se();
336
+ const a = H.get(t) ?? "closed";
337
+ let s = a;
338
+ if (e === "open")
339
+ if (a.startsWith("docked:")) s = a;
340
+ else {
341
+ const o = nn(t), c = ft.get(t) ?? [], l = o && o !== "float" && (c.includes(o) || Wt(`docked:${o}`)) ? o : gt.get(t) ?? c[0];
342
+ s = l ? `docked:${l}` : "floating";
343
+ }
344
+ else if (e === "float") s = "floating";
345
+ else if (e === "close") s = "closed";
346
+ else if (e.startsWith("dock:")) {
347
+ const o = e.slice(5);
348
+ try {
349
+ localStorage.setItem(dt(t), o);
350
+ } catch {
351
+ }
352
+ s = `docked:${o}`;
353
+ }
354
+ if (s === a) {
355
+ if (a.startsWith("docked:"))
356
+ try {
357
+ window.dispatchEvent(new CustomEvent(tn, { detail: { key: t, state: a, ...n?.auto ? { auto: !0 } : {} } }));
358
+ } catch {
359
+ }
360
+ return;
361
+ }
362
+ H.set(t, s), Qe();
363
+ const r = { key: t, state: s };
364
+ for (const o of Lt)
365
+ try {
366
+ o(r);
367
+ } catch {
368
+ }
369
+ try {
370
+ window.dispatchEvent(new CustomEvent(Tt, { detail: r }));
371
+ } catch {
372
+ }
373
+ }
374
+ function U(t, e, n) {
375
+ const a = T();
376
+ if (a) {
377
+ a.present(t, e, n);
378
+ return;
379
+ }
380
+ ce(t, e, n);
381
+ }
382
+ function N(t) {
383
+ const e = T();
384
+ return e ? e.presented(t) ?? "closed" : (se(), H.get(t) ?? "closed");
385
+ }
386
+ function en(t) {
387
+ const e = T();
388
+ return e ? e.onPresentChange(t) : (Lt.add(t), () => Lt.delete(t));
389
+ }
390
+ function nn(t) {
391
+ const e = T();
392
+ if (e) return e.dockPref(t) ?? null;
393
+ try {
394
+ return localStorage.getItem(dt(t));
395
+ } catch {
396
+ return null;
397
+ }
398
+ }
399
+ function on(t) {
400
+ try {
401
+ const e = document.querySelector(`[data-ext-float-dock-body="${t}"]`);
402
+ if (!e) return;
403
+ e.classList.remove("piwe-dock-flash"), e.offsetWidth, e.classList.add("piwe-dock-flash"), setTimeout(() => e.classList.remove("piwe-dock-flash"), 2e3);
404
+ } catch {
405
+ }
406
+ }
407
+ function At(t) {
408
+ N(t).startsWith("docked:") && on(t), U(t, "open");
409
+ }
410
+ if (typeof window < "u")
411
+ try {
412
+ window.addEventListener("piwe-float-present-command", ((t) => {
413
+ T() || !t.detail || !t.detail.key || !t.detail.mode || ce(t.detail.key, t.detail.mode);
414
+ }));
415
+ } catch {
416
+ }
417
+ function rn(t, e) {
418
+ U(t, `dock:${e}`);
419
+ }
420
+ function an(t) {
421
+ U(t, `dock:${at(t)}`);
422
+ }
423
+ function sn(t) {
424
+ U(t, "float");
425
+ }
426
+ function st(t) {
427
+ U(t, "close");
428
+ }
429
+ function cn(t, e) {
430
+ try {
431
+ localStorage.getItem(dt(t)) || localStorage.setItem(dt(t), e);
432
+ } catch {
433
+ }
434
+ const n = T();
435
+ if (n && typeof n.registerDefaultZone == "function")
436
+ try {
437
+ n.registerDefaultZone(t, e);
438
+ } catch {
439
+ }
440
+ gt.set(t, e);
441
+ }
442
+ let G = null, D = null, et = null;
443
+ if (typeof window < "u")
444
+ try {
445
+ window.addEventListener("piwe-float-dock-menu", ((t) => {
446
+ if (T()) return;
447
+ const e = t.detail?.key;
448
+ if (!e) return;
449
+ if (G === e || et && et.key === e && Date.now() - et.at < 350) {
450
+ D && D.remove(), D = null, G = null;
451
+ return;
452
+ }
453
+ D && D.remove();
454
+ const n = ft.get(e)?.length ? ft.get(e) : N(e).startsWith("docked:") ? [N(e).slice(7)] : [], a = gt.get(e), s = N(e), r = document.createElement("div");
455
+ r.setAttribute("data-ext-dock-menu", "1"), r.style.cssText = "position:fixed;z-index:2147483600;background:var(--bg-panel,#1a1a1a);border:1px solid var(--border,#444);border-radius:8px;padding:4px;display:flex;flex-direction:column;gap:2px;box-shadow:0 8px 24px rgba(0,0,0,0.4);min-width:190px;";
456
+ const o = t.detail?.rect;
457
+ r.style.left = Math.max(8, (o?.left ?? window.innerWidth / 2 - 70) - 60) + "px", r.style.top = (o?.bottom ?? 140) + 4 + "px";
458
+ const c = le(e, n, a, s, { onNewWindow: de(e) });
459
+ un(r, c, { label: "停靠方位", onPick: () => {
460
+ D === r && (D = null, G = null);
461
+ } }), document.body.appendChild(r), G = e, D = r;
462
+ const l = (f) => {
463
+ r.contains(f.target) || (et = { key: e, at: Date.now() }, r.remove(), D === r && (D = null, G = null), document.removeEventListener("mousedown", l, !0));
464
+ };
465
+ setTimeout(() => document.addEventListener("mousedown", l, !0), 0);
466
+ }));
467
+ } catch {
468
+ }
469
+ const Kt = {
470
+ "sidebar-explorer": "左栏 · 区块",
471
+ "right-panel": "右栏 · 面板"
472
+ };
473
+ function ln(t, e, n, a) {
474
+ const s = e.some((o) => o === "sidebar-explorer" || o.startsWith("sidebar:")), r = [];
475
+ if (s) {
476
+ const o = n === "sidebar-explorer" || !!n?.startsWith("sidebar:");
477
+ r.push({
478
+ key: "sidebar-explorer",
479
+ icon: "panel-left",
480
+ label: Kt["sidebar-explorer"],
481
+ hint: o ? "默认" : void 0,
482
+ isDefault: o,
483
+ active: Wt(a),
484
+ run: () => an(t)
485
+ });
486
+ }
487
+ for (const o of e)
488
+ o === "sidebar-explorer" || o.startsWith("sidebar:") || r.push({
489
+ key: o,
490
+ icon: $e(o),
491
+ label: Kt[o] ?? o,
492
+ hint: o === n ? "默认" : void 0,
493
+ isDefault: o === n,
494
+ active: a === `docked:${o}`,
495
+ run: () => rn(t, o)
496
+ });
497
+ return r;
498
+ }
499
+ function le(t, e, n, a, s) {
500
+ const r = s?.onNewWindow ?? de(t);
501
+ return [
502
+ ...r ? [{ key: "new-window", icon: "new-window", label: "新窗口打开", run: r }] : [],
503
+ { key: "float", icon: "float", label: "浮窗", active: a === "floating", run: () => sn(t) },
504
+ ...ln(t, e, n, a)
505
+ ];
506
+ }
507
+ const dn = /* @__PURE__ */ new Map();
508
+ function de(t) {
509
+ const e = T();
510
+ if (e && typeof e.windowOpenerOf == "function")
511
+ try {
512
+ const n = e.windowOpenerOf(t);
513
+ if (typeof n == "function") return n;
514
+ } catch {
515
+ }
516
+ return dn.get(t) ?? null;
517
+ }
518
+ function un(t, e, n) {
519
+ const a = document.createElement("div");
520
+ if (a.setAttribute("data-ext-dock-icon-row", "1"), a.style.cssText = "display:flex;align-items:center;justify-content:space-between;gap:16px;padding:5px 10px;", n?.label) {
521
+ const r = document.createElement("span");
522
+ r.setAttribute("data-ext-dock-icon-row-label", "1"), r.textContent = n.label, r.style.cssText = "font-size:12px;color:var(--text-dim,#888);flex-shrink:0;user-select:none;white-space:nowrap;", a.appendChild(r);
523
+ }
524
+ const s = document.createElement("div");
525
+ s.setAttribute("data-ext-dock-icon-group", "1"), s.style.cssText = "display:flex;gap:6px;margin-left:auto;flex-shrink:0;";
526
+ for (const r of e) {
527
+ const o = document.createElement("button");
528
+ o.type = "button";
529
+ const c = r.isDefault ? `${r.label}(默认)` : r.label;
530
+ if (o.title = c, o.setAttribute("aria-label", c), r.active === !0 || r.active === !1 ? (o.setAttribute("role", "menuitemradio"), o.setAttribute("aria-checked", r.active ? "true" : "false")) : o.setAttribute("role", "menuitem"), o.setAttribute("data-ext-dock-icon", r.key), o.style.cssText = "position:relative;width:28px;height:28px;display:inline-flex;align-items:center;justify-content:center;border:none;background:none;border-radius:6px;padding:0;font-family:inherit;cursor:pointer;color:var(--text-muted,#888);" + (r.active ? "cursor:default;background:var(--bg-selected,#2a2a2a);color:var(--accent,#2563eb);" : ""), o.appendChild(ze(r.icon, 16)), r.active || (o.addEventListener("mouseenter", () => {
531
+ o.style.background = "var(--bg-hover,#262626)", o.style.color = "var(--text,#ddd)";
532
+ }), o.addEventListener("mouseleave", () => {
533
+ o.style.background = "none", o.style.color = "var(--text-muted,#888)";
534
+ }), o.addEventListener("click", () => {
535
+ n?.onPick?.(r), r.run();
536
+ })), r.isDefault) {
537
+ const l = document.createElement("span");
538
+ l.setAttribute("data-ext-dock-icon-default", "1"), l.style.cssText = "position:absolute;top:3px;right:3px;width:4px;height:4px;border-radius:50%;background:var(--accent,#2563eb);pointer-events:none;", o.appendChild(l);
539
+ }
540
+ s.appendChild(o);
541
+ }
542
+ return a.appendChild(s), t.appendChild(a), a;
543
+ }
544
+ const ft = /* @__PURE__ */ new Map(), gt = /* @__PURE__ */ new Map();
545
+ function Xt(t, e, n) {
546
+ const a = T();
547
+ if (a && typeof a.registerZones == "function") {
548
+ try {
549
+ a.registerZones(t, e);
550
+ } catch {
551
+ }
552
+ if (n && typeof a.registerDefaultZone == "function")
553
+ try {
554
+ a.registerDefaultZone(t, n);
555
+ } catch {
556
+ }
557
+ }
558
+ ft.set(t, e.filter(Boolean)), n && gt.set(t, n);
559
+ }
560
+ function mt(t) {
561
+ const [e, n] = w(() => N(t));
562
+ return v(() => {
563
+ n(N(t));
564
+ const a = ((r) => {
565
+ r.detail?.key === t && n(r.detail.state);
566
+ });
567
+ window.addEventListener(Tt, a);
568
+ const s = en((r) => {
569
+ r.key === t && n(r.state);
570
+ });
571
+ return () => {
572
+ window.removeEventListener(Tt, a), s();
573
+ };
574
+ }, [t]), e;
575
+ }
576
+ function nt(t, e = 16) {
577
+ return u(
578
+ "svg",
579
+ { width: e, height: e, ...Fe, "aria-hidden": "true" },
580
+ ...ne[t].map((n, a) => u(n.tag, { key: a, ...n.attrs }))
581
+ );
582
+ }
583
+ function L() {
584
+ const e = T()?.dockHeader;
585
+ return e && typeof e.register == "function" ? e : Ke();
586
+ }
587
+ function Gn(t, e, n) {
588
+ return L().request(t, e, n);
589
+ }
590
+ function bt() {
591
+ const [t, e] = w(0);
592
+ return v(() => {
593
+ const n = () => e((a) => a + 1);
594
+ return window.addEventListener(Jt, n), () => window.removeEventListener(Jt, n);
595
+ }, []), t;
596
+ }
597
+ function qn(t, e) {
598
+ const n = bt();
599
+ v(() => {
600
+ if (t)
601
+ try {
602
+ L().register(t, { commands: e });
603
+ } catch {
604
+ }
605
+ }), v(() => {
606
+ if (t)
607
+ return () => {
608
+ try {
609
+ L().register(t, { commands: null });
610
+ } catch {
611
+ }
612
+ };
613
+ }, [t, n]);
614
+ }
615
+ function Yn(t, e) {
616
+ const n = bt();
617
+ v(() => {
618
+ if (t)
619
+ try {
620
+ L().register(t, { state: e });
621
+ } catch {
622
+ }
623
+ }), v(() => {
624
+ if (t)
625
+ return () => {
626
+ try {
627
+ L().register(t, { state: null });
628
+ } catch {
629
+ }
630
+ };
631
+ }, [t, n]);
632
+ }
633
+ function Un(t) {
634
+ const e = bt(), [, n] = w(0);
635
+ return v(() => t ? L().subscribe(t, () => n((s) => s + 1)) : void 0, [t, e]), t ? L().stateOf(t) : {};
636
+ }
637
+ function fn(t) {
638
+ const e = bt(), [, n] = w(0);
639
+ v(() => L().subscribe(t, () => n((r) => r + 1)), [t, e]);
640
+ const a = L();
641
+ return { actions: a.actionsOf(t), menuItems: a.menuItemsOf(t), hasCommands: !!a.commandsOf(t) };
642
+ }
643
+ function pn(t, e) {
644
+ const n = [], a = /* @__PURE__ */ new Set();
645
+ for (const s of [...t ?? [], ...e ?? []])
646
+ !s || typeof s.id != "string" || a.has(s.id) || (a.add(s.id), n.push(s));
647
+ return n;
648
+ }
649
+ function Zn(t) {
650
+ const { itemKey: e, zone: n, title: a, chrome: s = "section", zones: r, defaultZone: o, children: c } = t, l = t.kind ?? "dockable", f = t.blockKey ?? e, S = w(() => Zt(f)), E = t.collapsed ?? S[0], F = S[1];
651
+ v(() => {
652
+ if (t.collapsed !== void 0) return;
653
+ const i = () => F(Zt(f));
654
+ return window.addEventListener(Dt, i), window.addEventListener("storage", i), () => {
655
+ window.removeEventListener(Dt, i), window.removeEventListener("storage", i);
656
+ };
657
+ }, [f, t.collapsed]);
658
+ const I = (i) => {
659
+ F(i), ie(f, i), t.onToggleCollapsed?.(i);
660
+ }, A = fn(e), [y, x] = w(null), [M, we] = w(null), [jt, xe] = w(null), [ke, Se] = w(null), [wt, xt] = w(null);
661
+ v(() => {
662
+ if (!y || !M || !y.anchor) return;
663
+ const i = y.anchor.getBoundingClientRect(), p = M.getBoundingClientRect(), d = 4, k = 8;
664
+ let g = i.bottom + d;
665
+ const _ = window.innerHeight - k - g, X = i.top - d - k;
666
+ p.height > _ && X > _ && (g = i.top - d - p.height);
667
+ const V = je(i.right - p.width, g, p.width, p.height, k), R = He(M), Et = { left: V.left - R.x, top: V.top - R.y };
668
+ xt((Q) => Q && Q.left === Et.left && Q.top === Et.top ? Q : Et);
669
+ }, [y, M]), v(() => {
670
+ if (!y) return;
671
+ const i = (d) => {
672
+ const k = d.target;
673
+ k && M?.contains(k) || k && y.anchor?.contains(k) || x(null);
674
+ }, p = (d) => {
675
+ M && d.target instanceof Node && M.contains(d.target) || x(null);
676
+ };
677
+ return document.addEventListener("mousedown", i), window.addEventListener("scroll", p, !0), () => {
678
+ document.removeEventListener("mousedown", i), window.removeEventListener("scroll", p, !0);
679
+ };
680
+ }, [y, M]);
681
+ const [J, Ee] = w(null), [$t, Ce] = w(4);
682
+ v(() => {
683
+ if (!J) return;
684
+ const i = () => {
685
+ const d = J.clientWidth || 0;
686
+ if (d <= 0) return;
687
+ const g = Math.max(0, Math.min(6, Math.floor((d - 154) / 27)));
688
+ Ce((_) => _ === g ? _ : g);
689
+ };
690
+ i();
691
+ let p = null;
692
+ try {
693
+ typeof ResizeObserver == "function" && (p = new ResizeObserver(i), p.observe(J));
694
+ } catch {
695
+ }
696
+ return window.addEventListener("resize", i), () => {
697
+ try {
698
+ p && p.disconnect();
699
+ } catch {
700
+ }
701
+ window.removeEventListener("resize", i);
702
+ };
703
+ }, [J]);
704
+ const Ie = mt(e), kt = r && r.length ? r : n ? [n] : [], De = l === "dockable" && s === "section" && kt.length > 0, K = {
705
+ background: "none",
706
+ border: "none",
707
+ color: "var(--text-muted, #888)",
708
+ cursor: "pointer",
709
+ fontSize: 11,
710
+ lineHeight: 1,
711
+ padding: "2px 5px",
712
+ flexShrink: 0,
713
+ fontFamily: "inherit"
714
+ }, zt = pn(t.headerActions, A.actions).filter((i) => !E || (i.visibility ?? "always") !== "expanded"), Ft = zt.slice(0, $t), St = zt.slice($t), Te = (i) => u(
715
+ "button",
716
+ {
717
+ key: i.id,
718
+ type: "button",
719
+ title: i.title,
720
+ "aria-label": i.title,
721
+ disabled: i.disabled === !0,
722
+ style: {
723
+ ...K,
724
+ position: "relative",
725
+ color: i.done ? "var(--ok, #4ade80)" : i.active ? "var(--accent, #2563eb)" : "var(--text-muted, #888)",
726
+ opacity: i.disabled ? 0.5 : 1,
727
+ cursor: i.disabled ? "default" : "pointer"
728
+ },
729
+ onClick: (p) => {
730
+ i.disabled !== !0 && i.onClick(p);
731
+ }
732
+ },
733
+ i.icon ? u("span", { style: { display: "inline-flex", alignItems: "center", justifyContent: "center" } }, i.icon) : u("span", { style: { fontSize: 12, fontWeight: 700, lineHeight: 1 } }, "•"),
734
+ i.badge !== void 0 && i.badge !== null && i.badge !== "" ? u("span", {
735
+ style: { position: "absolute", top: -5, right: -4, fontSize: 9, lineHeight: "13px", color: "var(--text-muted, #888)", background: "var(--bg-panel, #1a1a1a)", border: "1px solid var(--border, #444)", borderRadius: 7, padding: "0 3px" }
736
+ }, String(i.badge)) : null
737
+ ), Le = () => {
738
+ const i = [];
739
+ if (St.length > 0) {
740
+ i.push({ type: "head", label: "工具" });
741
+ for (const d of St) i.push({ type: "item", label: d.title, icon: d.icon, badge: d.badge, active: d.active, alwaysRun: !0, disabled: d.disabled, run: d.onClick });
742
+ }
743
+ if (A.menuItems && A.menuItems.length > 0) {
744
+ i.length > 0 && i.push({ type: "sep" });
745
+ for (const d of A.menuItems)
746
+ d.kind === "head" ? i.push({ type: "head", label: d.label }) : d.kind === "sep" ? i.push({ type: "sep" }) : i.push({ type: "item", label: d.label, icon: d.icon, hint: d.hint, active: d.active, alwaysRun: d.alwaysRun, disabled: d.disabled, run: d.run });
747
+ }
748
+ const p = [];
749
+ if (s === "section" && p.push({ type: "icons", label: "移动", icon: nt("move-diagonal-2", 13), items: [
750
+ { key: "move-up", icon: "chevron-up", label: "上移", run: () => Qt(f, -1) },
751
+ { key: "move-down", icon: "chevron-down", label: "下移", run: () => Qt(f, 1) }
752
+ ] }), l === "reserved" && typeof t.onRemove == "function" && p.push({ type: "item", label: "移除本实例", icon: nt("trash", 13), run: () => t.onRemove() }), Array.isArray(t.extraMenuItems))
753
+ for (const d of t.extraMenuItems) p.push({ type: "item", label: d.label, icon: d.icon, hint: d.hint, active: d.active, alwaysRun: d.alwaysRun, run: d.run });
754
+ return l === "dockable" && s === "section" && p.push({ type: "item", label: "关闭", icon: nt("x", 13), run: () => t.onClose ? t.onClose() : st(e) }), p.length > 0 && (i.length > 0 && i.push({ type: "sep" }), i.push({ type: "head", label: "区块" }), i.push(...p)), i;
755
+ }, Ae = y?.kind === "position" ? [{ type: "icons", label: "停靠方位", items: le(e, kt, o, Ie, { onNewWindow: t.onNewWindow }) }] : [], Me = y?.kind === "position" ? Ae : y?.kind === "main" ? Le() : [], Oe = (i, p) => {
756
+ if (i.type === "sep") return u("div", { key: `sep-${p}`, style: { height: 1, background: "var(--border, #444)", margin: "3px 4px", opacity: 0.7, flexShrink: 0 } });
757
+ if (i.type === "head") return u("div", { key: `head-${p}`, style: { fontSize: 10, color: "var(--text-dim, #888)", fontWeight: 600, padding: "4px 10px 2px", letterSpacing: 0.3, userSelect: "none", whiteSpace: "nowrap" } }, i.label);
758
+ if (i.type === "icons") return u(
759
+ "div",
760
+ {
761
+ key: `icons-${p}`,
762
+ role: "group",
763
+ "data-ext-dock-icon-row": "1",
764
+ style: { display: "flex", alignItems: "center", justifyContent: "space-between", gap: 16, padding: "5px 10px", flexShrink: 0 }
765
+ },
766
+ i.label ? u(
767
+ "span",
768
+ {
769
+ key: "label",
770
+ "data-ext-dock-icon-row-label": "1",
771
+ // 行首图标(可选):带图标 = 动作行(正文字色,与其余 icon+text 行同款);
772
+ // 无图标 = 纯说明名(dim,位置菜单「停靠方位」标题原样)。
773
+ style: {
774
+ display: "inline-flex",
775
+ alignItems: "center",
776
+ gap: 6,
777
+ fontSize: 12,
778
+ color: i.icon ? "var(--text, #ddd)" : "var(--text-dim, #888)",
779
+ flexShrink: 0,
780
+ userSelect: "none",
781
+ whiteSpace: "nowrap"
782
+ }
783
+ },
784
+ i.icon ? u("span", { style: { display: "inline-flex", flexShrink: 0 } }, i.icon) : null,
785
+ i.label
786
+ ) : null,
787
+ u(
788
+ "div",
789
+ {
790
+ key: "group",
791
+ "data-ext-dock-icon-group": "1",
792
+ style: { display: "flex", gap: 6, marginLeft: "auto", flexShrink: 0 }
793
+ },
794
+ ...i.items.map((g, _) => {
795
+ const X = g.active === !0 || g.active === !1, V = g.isDefault ? `${g.label}(默认)` : g.label;
796
+ return u(
797
+ "button",
798
+ {
799
+ key: `icon-${_}`,
800
+ type: "button",
801
+ role: X ? "menuitemradio" : "menuitem",
802
+ ...X ? { "aria-checked": g.active ? "true" : "false" } : {},
803
+ title: V,
804
+ "aria-label": V,
805
+ "data-ext-dock-icon": g.key,
806
+ style: {
807
+ position: "relative",
808
+ width: 28,
809
+ height: 28,
810
+ display: "inline-flex",
811
+ alignItems: "center",
812
+ justifyContent: "center",
813
+ border: "none",
814
+ borderRadius: 6,
815
+ padding: 0,
816
+ fontFamily: "inherit",
817
+ cursor: g.active ? "default" : "pointer",
818
+ background: g.active ? "var(--bg-selected, #2a2a2a)" : "none",
819
+ color: g.active ? "var(--accent, #2563eb)" : "var(--text-muted, #888)"
820
+ },
821
+ onClick: () => {
822
+ g.active || (x(null), g.run());
823
+ },
824
+ onMouseEnter: (R) => {
825
+ g.active || (R.currentTarget.style.background = "var(--bg-hover, #262626)", R.currentTarget.style.color = "var(--text, #ddd)");
826
+ },
827
+ onMouseLeave: (R) => {
828
+ g.active || (R.currentTarget.style.background = "none", R.currentTarget.style.color = "var(--text-muted, #888)");
829
+ }
830
+ },
831
+ nt(g.icon, 16),
832
+ g.isDefault ? u("span", { key: "dot", "data-ext-dock-icon-default": "1", style: { position: "absolute", top: 3, right: 3, width: 4, height: 4, borderRadius: "50%", background: "var(--accent, #2563eb)", pointerEvents: "none" } }) : null
833
+ );
834
+ })
835
+ )
836
+ );
837
+ const d = i.disabled === !0, k = i.active === !0 && i.alwaysRun !== !0;
838
+ return u(
839
+ "button",
840
+ {
841
+ key: `item-${p}`,
842
+ type: "button",
843
+ role: "menuitem",
844
+ disabled: d,
845
+ style: {
846
+ background: "none",
847
+ border: "none",
848
+ cursor: d || k ? "default" : "pointer",
849
+ fontSize: 12,
850
+ padding: "6px 12px",
851
+ textAlign: "left",
852
+ borderRadius: 6,
853
+ fontFamily: "inherit",
854
+ color: i.active ? "var(--accent, #2563eb)" : "var(--text, #ddd)",
855
+ display: "flex",
856
+ alignItems: "center",
857
+ gap: 6,
858
+ opacity: d ? 0.5 : 1,
859
+ flexShrink: 0
860
+ },
861
+ onClick: () => {
862
+ x(null), k || i.run();
863
+ },
864
+ onKeyDown: (g) => {
865
+ g.key === "Escape" && x(null);
866
+ }
867
+ },
868
+ i.icon ? u("span", { style: { width: 14, display: "inline-flex", justifyContent: "center", flexShrink: 0 } }, i.icon) : null,
869
+ (i.active ? "✓ " : "") + i.label,
870
+ i.badge !== void 0 && i.badge !== null && i.badge !== "" ? u("span", { style: { marginLeft: "auto", fontSize: 10, color: "var(--text-muted, #888)", border: "1px solid var(--border, #444)", borderRadius: 6, padding: "0 4px" } }, String(i.badge)) : null,
871
+ i.hint ? u("span", { style: { marginLeft: "auto", fontSize: 10, color: "var(--text-muted, #888)", border: "1px solid var(--border, #444)", borderRadius: 4, padding: "0 4px" } }, i.hint) : null
872
+ );
873
+ }, Vt = y ? u("div", {
874
+ ref: we,
875
+ role: "menu",
876
+ style: {
877
+ position: "fixed",
878
+ zIndex: 2147483600,
879
+ background: "var(--bg-panel, #1a1a1a)",
880
+ border: "1px solid var(--border, #444)",
881
+ borderRadius: 8,
882
+ padding: 4,
883
+ display: "flex",
884
+ flexDirection: "column",
885
+ gap: 2,
886
+ boxShadow: "0 8px 24px rgba(0,0,0,0.4)",
887
+ minWidth: y?.kind === "position" ? 190 : 150,
888
+ maxWidth: "calc(100vw - 16px)",
889
+ // 长菜单滚动契约(v3):视口内可滚 + 防滚动穿透(内部滚动不触发「容器滚动即关」)
890
+ maxHeight: "min(70vh, calc(100vh - 16px))",
891
+ overflowY: "auto",
892
+ overscrollBehavior: "contain",
893
+ // 首帧离屏(布局期测量后落位,绘制前同步无闪烁)
894
+ ...wt ? { left: wt.left, top: wt.top } : { left: -99999, top: -99999 }
895
+ },
896
+ onMouseLeave: () => x(null)
897
+ }, Me.map(Oe)) : null, Gt = () => I(!E), Re = (i) => {
898
+ if (i.target && typeof i.target.closest == "function" && i.target.closest("button")) {
899
+ i.preventDefault();
900
+ return;
901
+ }
902
+ ot = f;
903
+ try {
904
+ i.dataTransfer.setData("application/x-pi-dock", f), i.dataTransfer.effectAllowed = "move";
905
+ } catch {
906
+ }
907
+ }, qt = (i) => {
908
+ try {
909
+ return [...i.dataTransfer?.types ?? []].includes("application/x-pi-dock");
910
+ } catch {
911
+ return !1;
912
+ }
913
+ }, Yt = (i, p) => {
914
+ const d = i.currentTarget;
915
+ d && (d.classList.remove("pi-dock-drop-before", "pi-dock-drop-after"), p && d.classList.add(i.clientY - d.getBoundingClientRect().top < d.getBoundingClientRect().height / 2 ? "pi-dock-drop-before" : "pi-dock-drop-after"));
916
+ }, _e = (i) => {
917
+ if (!qt(i)) return;
918
+ i.preventDefault();
919
+ const p = i.currentTarget;
920
+ p.classList.remove("pi-dock-drop-before", "pi-dock-drop-after");
921
+ let d = "";
922
+ try {
923
+ d = i.dataTransfer.getData("application/x-pi-dock") || "";
924
+ } catch {
925
+ }
926
+ if (d || (d = ot || ""), !d || d === f) return;
927
+ const k = p.getBoundingClientRect();
928
+ hn(d, f, i.clientY - k.top < k.height / 2);
929
+ }, O = { ref: Ee, style: { display: "flex", alignItems: "center", gap: 4, padding: "4px 8px", borderBottom: "1px solid var(--border, #333)", flexShrink: 0, minWidth: 0 }, onClick: (i) => {
930
+ i.target && typeof i.target.closest == "function" && i.target.closest("button") || Gt();
931
+ } };
932
+ s === "section" && (O.draggable = !0, O.title = "拖动排序", O.onDragStart = Re, O.onDragOver = (i) => {
933
+ qt(i) && ot !== f && (i.preventDefault(), i.dataTransfer.dropEffect = "move", Yt(i, !0));
934
+ }, O.onDragLeave = (i) => {
935
+ try {
936
+ if (i.relatedTarget && i.currentTarget.contains(i.relatedTarget)) return;
937
+ } catch {
938
+ }
939
+ Yt(i, !1);
940
+ }, O.onDrop = _e, O.onDragEnd = () => {
941
+ ot = null, document.querySelectorAll(".pi-dock-drop-before, .pi-dock-drop-after").forEach((i) => i.classList.remove("pi-dock-drop-before", "pi-dock-drop-after"));
942
+ });
943
+ const We = t.renderTitle ? u("span", { style: { minWidth: 0, flex: "0 1 auto", display: "inline-flex", alignItems: "center" } }, t.renderTitle()) : u("span", { style: { fontSize: 11, fontWeight: 600, color: "var(--text-muted, #999)", letterSpacing: "0.04em", textTransform: "uppercase", flex: "0 1 auto", overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", minWidth: 0 } }, a ?? ""), Be = E && A.hasCommands;
944
+ return u(
945
+ "div",
946
+ {
947
+ "data-ext-float-dock-body": e,
948
+ "data-ext-item": e,
949
+ "data-ext-dock-block": f,
950
+ // 根上带声明属性:TabBar ⇱ 菜单在 face 挂载时可直接读(注册表兜底优先)
951
+ "data-ext-float-dock": kt.join(" "),
952
+ ...o ? { "data-ext-float-dock-default": o } : {},
953
+ // 注册按钮数(e2e/调试断言用):当前头行可见 / 溢出
954
+ "data-ext-dock-actions": String(Ft.length),
955
+ "data-ext-dock-actions-overflow": String(St.length),
956
+ style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0, overflow: "hidden", position: "relative" }
957
+ },
958
+ s === "section" && u(
959
+ "div",
960
+ O,
961
+ u(
962
+ "button",
963
+ {
964
+ type: "button",
965
+ title: E ? "展开" : "折叠",
966
+ "aria-label": (a ?? "区块") + (E ? " 展开" : " 折叠"),
967
+ "aria-expanded": E ? "false" : "true",
968
+ style: { ...K, display: "flex", alignItems: "center" },
969
+ onClick: Gt
970
+ },
971
+ u(
972
+ "svg",
973
+ {
974
+ width: 9,
975
+ height: 9,
976
+ viewBox: "0 0 10 10",
977
+ fill: "none",
978
+ stroke: "currentColor",
979
+ strokeWidth: 1.8,
980
+ strokeLinecap: "round",
981
+ strokeLinejoin: "round",
982
+ style: { transform: E ? "none" : "rotate(90deg)", transition: "transform 0.15s", flexShrink: 0 }
983
+ },
984
+ u("polyline", { points: "3 2 7 5 3 8" })
985
+ )
986
+ ),
987
+ We,
988
+ typeof t.count == "number" && u("span", { style: { color: "var(--text-dim, #777)", fontWeight: 400, fontSize: 10, flexShrink: 0 } }, `(${t.count})`),
989
+ u("span", { style: { flex: 1, minWidth: 0 } }),
990
+ ...Ft.map(Te),
991
+ De ? u(
992
+ "span",
993
+ { style: { position: "relative", display: "inline-flex", flexShrink: 0 } },
994
+ u("button", {
995
+ ref: Se,
996
+ type: "button",
997
+ title: "切换停靠位置",
998
+ "aria-label": "切换停靠位置",
999
+ "aria-haspopup": "menu",
1000
+ "aria-expanded": y?.kind === "position" ? "true" : "false",
1001
+ style: { ...K, fontSize: 12 },
1002
+ onClick: () => {
1003
+ y?.kind === "position" ? x(null) : (xt(null), x({ kind: "position", anchor: ke ?? jt }));
1004
+ }
1005
+ }, "⇱"),
1006
+ y?.kind === "position" ? Vt : null
1007
+ ) : null,
1008
+ u(
1009
+ "span",
1010
+ { style: { position: "relative", display: "inline-flex", flexShrink: 0 } },
1011
+ u("button", {
1012
+ ref: xe,
1013
+ type: "button",
1014
+ title: "区块操作",
1015
+ "aria-label": "区块操作",
1016
+ "aria-haspopup": "menu",
1017
+ "aria-expanded": y?.kind === "main" ? "true" : "false",
1018
+ style: { ...K, fontSize: 12, fontWeight: 700 },
1019
+ onClick: () => {
1020
+ y?.kind === "main" ? x(null) : (xt(null), x({ kind: "main", anchor: jt }));
1021
+ },
1022
+ onKeyDown: (i) => {
1023
+ i.key === "Escape" && y?.kind === "main" && x(null);
1024
+ }
1025
+ }, "⋮"),
1026
+ y?.kind === "main" ? Vt : null
1027
+ )
1028
+ ),
1029
+ (!E || Be) && u("div", { style: { flex: E ? "0 0 0" : 1, minHeight: 0, overflow: "hidden", display: E ? "none" : "flex", flexDirection: "column" } }, c)
1030
+ );
1031
+ }
1032
+ function Qt(t, e) {
1033
+ try {
1034
+ window.dispatchEvent(new CustomEvent(Ve, { detail: { key: t, delta: e } }));
1035
+ } catch {
1036
+ }
1037
+ }
1038
+ function hn(t, e, n) {
1039
+ try {
1040
+ window.dispatchEvent(new CustomEvent(Ge, { detail: { key: t, target: e, before: n } }));
1041
+ } catch {
1042
+ }
1043
+ }
1044
+ let ot = null;
1045
+ if (typeof document < "u" && !document.getElementById("pi-dock-dnd-css"))
1046
+ try {
1047
+ const t = document.createElement("style");
1048
+ t.id = "pi-dock-dnd-css", t.textContent = "[data-ext-dock-block][draggable=true] { cursor: grab; }.pi-dock-drop-before { box-shadow: inset 0 2px 0 var(--accent, #2563eb); }.pi-dock-drop-after { box-shadow: inset 0 -2px 0 var(--accent, #2563eb); }", document.head.appendChild(t);
1049
+ } catch {
1050
+ }
1051
+ if (typeof document < "u" && !document.getElementById("piwe-dock-flash-css"))
1052
+ try {
1053
+ const t = document.createElement("style");
1054
+ t.id = "piwe-dock-flash-css", t.textContent = "@keyframes piwe-dock-flash-kf { 0%,100% { box-shadow: none; } 30% { box-shadow: inset 0 0 0 2px var(--accent, #2563eb); } }.piwe-dock-flash { animation: piwe-dock-flash-kf 2s ease; }", document.head.appendChild(t);
1055
+ } catch {
1056
+ }
1057
+ const Mt = "aiti-git-trace:timeline", Ot = "aiti-git-trace:watch", q = "aiti-git-trace-open";
1058
+ function z(t, e) {
1059
+ window.dispatchEvent(new CustomEvent(q, { detail: { kind: t, data: e } }));
1060
+ }
1061
+ function Jn(t, e) {
1062
+ const n = t === "timeline" ? Mt : t === "watch" ? Ot : "aiti-git-trace:" + t, a = mt(n), s = a !== "closed";
1063
+ return v(() => {
1064
+ const o = (c) => {
1065
+ const l = c.detail || {};
1066
+ l.kind === t ? (e && e(l.data), At(n)) : l.kind === null && (st(Mt), st(Ot));
1067
+ };
1068
+ return window.addEventListener(q, o), () => window.removeEventListener(q, o);
1069
+ }, []), [s, (o) => {
1070
+ o ? At(n) : st(n);
1071
+ }, a];
1072
+ }
1073
+ const yt = "/api/extensions/aiti-git-trace";
1074
+ async function Kn(t) {
1075
+ return (await fetch(ht(yt + t), { headers: { accept: "application/json" } })).json();
1076
+ }
1077
+ async function Xn(t, e, n = "POST") {
1078
+ return (await fetch(ht(yt + t), {
1079
+ method: n,
1080
+ headers: { "content-type": "application/json" },
1081
+ body: e === void 0 ? void 0 : JSON.stringify(e)
1082
+ })).json();
1083
+ }
1084
+ const gn = 4e3;
1085
+ function ue(t) {
1086
+ if (!t) return Promise.resolve([]);
1087
+ const e = Date.now(), n = h.opsCache;
1088
+ if (n && n.sid === t && e - n.at < gn) return Promise.resolve(n.rows);
1089
+ if (h.opsInflight && h.opsInflight.sid === t) return h.opsInflight.promise;
1090
+ const a = { accept: "application/json" };
1091
+ n && n.sid === t && n.etag && (a["if-none-match"] = n.etag);
1092
+ const s = fetch(ht(yt + "/ops?session=" + encodeURIComponent(t)), { headers: a }).then(async (o) => {
1093
+ if (o.status === 304 && h.opsCache && h.opsCache.sid === t)
1094
+ return h.opsCache.at = Date.now(), h.opsCache.rows;
1095
+ const c = await o.json().catch(() => null), l = c && c.ops || [];
1096
+ return h.opsCache = { sid: t, at: Date.now(), etag: o.headers.get("etag"), rows: l }, l;
1097
+ }).catch(() => h.opsCache && h.opsCache.sid === t ? h.opsCache.rows : []);
1098
+ h.opsInflight = { sid: t, promise: s };
1099
+ const r = () => {
1100
+ h.opsInflight && h.opsInflight.sid === t && (h.opsInflight = null);
1101
+ };
1102
+ return s.then(r, r), s;
1103
+ }
1104
+ function mn(t) {
1105
+ h.opsCache && (!t || h.opsCache.sid === t) && (h.opsCache = null);
1106
+ }
1107
+ const h = globalThis.__aitiGitTraceShared ?? (globalThis.__aitiGitTraceShared = { current: null, svc: null, svcInstalled: !1, opsCache: null, opsInflight: null });
1108
+ function Z(t) {
1109
+ const e = t?.currentSession;
1110
+ e && (e.id || e.cwd || e.name) && (h.current = { id: e.id, cwd: e.cwd, name: e.name, firstMessage: e.firstMessage });
1111
+ }
1112
+ function bn(t) {
1113
+ h.svc = t && t.phase === "active" && t.sessionId ? { id: String(t.sessionId), cwd: String(t.session?.cwd ?? "") } : null;
1114
+ }
1115
+ function yn(t) {
1116
+ if (h.svcInstalled) return;
1117
+ h.svcInstalled = !0;
1118
+ const e = () => {
1119
+ const n = t.getExtService?.("pi-web.session");
1120
+ return n?.subscribe ? (n.subscribe(bn), !0) : !1;
1121
+ };
1122
+ e() || t.onExtServiceChange?.((n, a) => {
1123
+ n === "pi-web.session" && a === "up" && e();
1124
+ });
1125
+ }
1126
+ function Y() {
1127
+ return h.svc?.id ? h.svc.id : h.current?.id ? String(h.current.id) : "";
1128
+ }
1129
+ function Qn() {
1130
+ return String(h.svc?.cwd || h.current?.cwd || "");
1131
+ }
1132
+ const to = {
1133
+ position: "fixed",
1134
+ right: 18,
1135
+ top: 64,
1136
+ zIndex: 10050,
1137
+ width: 460,
1138
+ maxWidth: "92vw",
1139
+ maxHeight: "78vh",
1140
+ overflow: "auto",
1141
+ background: "var(--bg-panel)",
1142
+ color: "var(--text)",
1143
+ border: "1px solid var(--border)",
1144
+ borderRadius: 10,
1145
+ padding: 14,
1146
+ boxShadow: "0 8px 32px rgba(0,0,0,.45)",
1147
+ fontSize: 13,
1148
+ lineHeight: 1.5
1149
+ }, Rt = {
1150
+ cursor: "pointer",
1151
+ borderRadius: 6,
1152
+ border: "1px solid var(--border)",
1153
+ background: "var(--bg-panel)",
1154
+ color: "inherit",
1155
+ padding: "3px 10px",
1156
+ fontSize: 12
1157
+ }, ct = { ...Rt, padding: "1px 7px", fontSize: 11, opacity: 0.9 }, eo = {
1158
+ borderRadius: 6,
1159
+ border: "1px solid var(--border)",
1160
+ background: "var(--bg)",
1161
+ color: "inherit",
1162
+ padding: "4px 8px",
1163
+ fontSize: 12,
1164
+ width: "100%",
1165
+ boxSizing: "border-box"
1166
+ }, no = { flex: 1, minHeight: 0, overflowY: "auto" }, oo = (t) => ({
1167
+ cursor: "pointer",
1168
+ marginLeft: 6,
1169
+ padding: "0 6px",
1170
+ borderRadius: 8,
1171
+ fontSize: 11,
1172
+ border: "1px solid",
1173
+ ...t === "cross" ? { color: "#9a6700", borderColor: "#d4a72c" } : t === "leak" ? { color: "#cf222e", borderColor: "#f1c1c1" } : { color: "var(--text-dim)", borderColor: "var(--border)" }
1174
+ });
1175
+ function io(t) {
1176
+ if (!t) return "";
1177
+ const e = new Date(t);
1178
+ return e.toDateString() === (/* @__PURE__ */ new Date()).toDateString() ? e.toTimeString().slice(0, 5) : e.toLocaleDateString();
1179
+ }
1180
+ const _t = /* @__PURE__ */ new Set();
1181
+ let it = null, fe = !1;
1182
+ function pe() {
1183
+ for (const t of [..._t])
1184
+ try {
1185
+ t();
1186
+ } catch {
1187
+ }
1188
+ }
1189
+ function Pt() {
1190
+ return it || (it = import("./panels-BpC4XLni.js").then((t) => (pe(), t)).catch((t) => {
1191
+ throw it = null, t;
1192
+ })), it;
1193
+ }
1194
+ function Nt(t) {
1195
+ return t === "timeline" ? Mt : t === "watch" ? Ot : "aiti-git-trace:" + t;
1196
+ }
1197
+ const lt = /* @__PURE__ */ new Map(), P = /* @__PURE__ */ new Map();
1198
+ function he(t, e) {
1199
+ return e ? (P.set(t, (P.get(t) ?? 0) + 1), () => {
1200
+ const n = (P.get(t) ?? 1) - 1;
1201
+ n <= 0 ? P.delete(t) : P.set(t, n);
1202
+ }) : () => {
1203
+ };
1204
+ }
1205
+ typeof window < "u" && window.addEventListener(q, (t) => {
1206
+ const e = t?.detail || {};
1207
+ if (!e.kind) return;
1208
+ const n = String(e.kind);
1209
+ (P.get(n) ?? 0) === 0 && lt.set(n, e.data), At(Nt(n)), Pt().catch(() => {
1210
+ });
1211
+ }, !0);
1212
+ function Ht(t, e) {
1213
+ const [n, a] = w(null);
1214
+ return v(() => {
1215
+ if (!t || n) return;
1216
+ let s = !0;
1217
+ return Pt().then((r) => {
1218
+ s && a(() => r[e]);
1219
+ }).catch(() => {
1220
+ }), () => {
1221
+ s = !1;
1222
+ };
1223
+ }, [t, e, n]), n;
1224
+ }
1225
+ function ge(t, e) {
1226
+ v(() => {
1227
+ if (!e || !lt.has(t)) return;
1228
+ const n = lt.get(t);
1229
+ lt.delete(t);
1230
+ try {
1231
+ window.dispatchEvent(new CustomEvent(q, { detail: { kind: t, data: n } }));
1232
+ } catch {
1233
+ }
1234
+ }, [e, t]);
1235
+ }
1236
+ function me(t, e) {
1237
+ return t === "float" ? e === "floating" : t === "right" ? e === "docked:right-panel" : Wt(e);
1238
+ }
1239
+ function be(t, e) {
1240
+ return function(a) {
1241
+ const s = mt(Nt(t)), r = me("float", s);
1242
+ v(() => he(t, r), [t, r]);
1243
+ const o = Ht(r, e);
1244
+ return ge(t, o), o ? /* @__PURE__ */ b(o, { ...a ?? {} }) : null;
1245
+ };
1246
+ }
1247
+ function vt(t, e, n) {
1248
+ return function(s) {
1249
+ const r = mt(Nt(t)), o = me(e, r);
1250
+ v(() => he(t, o), [t, o]);
1251
+ const c = Ht(o, n);
1252
+ return ge(t, c), c ? /* @__PURE__ */ b(c, { ...s ?? {} }) : null;
1253
+ };
1254
+ }
1255
+ const vn = be("watch", "WatchPanelSlot"), wn = vt("watch", "left", "WatchDockLeft"), xn = vt("watch", "right", "WatchDockRight"), kn = be("timeline", "TimelineSlot"), Sn = vt("timeline", "right", "TimelineDockRight"), En = vt("timeline", "left", "TimelineDockLeft");
1256
+ function Cn() {
1257
+ const [t, e] = w(fe);
1258
+ v(() => {
1259
+ if (t) return;
1260
+ const a = () => e(!0);
1261
+ return _t.add(a), () => {
1262
+ _t.delete(a);
1263
+ };
1264
+ }, [t]);
1265
+ const n = Ht(t, "ForkDialogSlot");
1266
+ return n ? /* @__PURE__ */ b(n, {}) : null;
1267
+ }
1268
+ async function In(t) {
1269
+ return fe = !0, pe(), (await Pt()).requestForkDialog(t);
1270
+ }
1271
+ const ye = {
1272
+ display: "flex",
1273
+ alignItems: "center",
1274
+ justifyContent: "center",
1275
+ width: 36,
1276
+ height: 36,
1277
+ padding: 0,
1278
+ background: "none",
1279
+ borderRight: "1px solid var(--border)",
1280
+ color: "var(--text-muted)",
1281
+ cursor: "pointer",
1282
+ flexShrink: 0,
1283
+ fontSize: 16,
1284
+ lineHeight: 1,
1285
+ transition: "color 0.12s"
1286
+ }, ve = { width: 16, height: 16, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": !0 };
1287
+ function Dn(t) {
1288
+ return Z(t), /* @__PURE__ */ b("button", { style: ye, title: C("gt.watch.title"), onClick: () => z("watch"), children: /* @__PURE__ */ $("svg", { ...ve, children: [
1289
+ /* @__PURE__ */ b("line", { x1: "6", x2: "6", y1: "3", y2: "15" }),
1290
+ /* @__PURE__ */ b("circle", { cx: "18", cy: "6", r: "3" }),
1291
+ /* @__PURE__ */ b("circle", { cx: "6", cy: "18", r: "3" }),
1292
+ /* @__PURE__ */ b("path", { d: "M18 9a9 9 0 0 1-9 9" })
1293
+ ] }) });
1294
+ }
1295
+ function Tn(t) {
1296
+ return Z(t), /* @__PURE__ */ b("button", { style: ye, title: C("gt.timeline.title"), onClick: () => z("timeline", { sessionId: Y() }), children: /* @__PURE__ */ $("svg", { ...ve, children: [
1297
+ /* @__PURE__ */ b("circle", { cx: "12", cy: "12", r: "10" }),
1298
+ /* @__PURE__ */ b("polyline", { points: "12 6 12 12 16 14" })
1299
+ ] }) });
1300
+ }
1301
+ function Ln(t) {
1302
+ Z(t);
1303
+ const e = t?.sessionId || Y();
1304
+ return /* @__PURE__ */ b(
1305
+ "button",
1306
+ {
1307
+ title: C("gt.timeline.title"),
1308
+ "aria-label": C("gt.timeline.title"),
1309
+ onClick: () => z("timeline", { sessionId: e }),
1310
+ style: {
1311
+ display: "flex",
1312
+ alignItems: "center",
1313
+ justifyContent: "center",
1314
+ gap: 5,
1315
+ width: 32,
1316
+ height: 32,
1317
+ padding: 0,
1318
+ background: "none",
1319
+ border: "none",
1320
+ borderRadius: 9,
1321
+ color: "var(--text-muted)",
1322
+ cursor: "pointer",
1323
+ transition: "background 0.12s, color 0.12s"
1324
+ },
1325
+ onMouseEnter: (n) => {
1326
+ n.currentTarget.style.background = "var(--bg-hover)", n.currentTarget.style.color = "var(--text)";
1327
+ },
1328
+ onMouseLeave: (n) => {
1329
+ n.currentTarget.style.background = "none", n.currentTarget.style.color = "var(--text-muted)";
1330
+ },
1331
+ children: /* @__PURE__ */ $("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": !0, children: [
1332
+ /* @__PURE__ */ b("circle", { cx: "12", cy: "12", r: "10" }),
1333
+ /* @__PURE__ */ b("polyline", { points: "12 6 12 12 16 14" })
1334
+ ] })
1335
+ }
1336
+ );
1337
+ }
1338
+ function An() {
1339
+ const [t, e] = w(null);
1340
+ return v(() => (window.__aitiGitTraceBanner = (n) => e(n || null), () => {
1341
+ try {
1342
+ delete window.__aitiGitTraceBanner;
1343
+ } catch {
1344
+ }
1345
+ }), []), t ? /* @__PURE__ */ $("div", { style: { margin: "6px 12px", padding: "6px 12px", borderRadius: 8, border: "1px solid #d4a72c", color: "#9a6700", background: "var(--bg-panel)", display: "flex", gap: 10, alignItems: "center" }, children: [
1346
+ /* @__PURE__ */ b("span", { children: String(C("gt.banner.text")).replace("{n}", String(t.count ?? "?")) }),
1347
+ /* @__PURE__ */ b("button", { style: Rt, onClick: () => z("timeline", { sessionId: t.sessionId }), children: C("gt.timeline.title") }),
1348
+ /* @__PURE__ */ b("button", { style: Rt, onClick: () => e(null), children: C("gt.common.close") })
1349
+ ] }) : null;
1350
+ }
1351
+ function Mn(t) {
1352
+ Z(t);
1353
+ const e = String(t?.entryId || ""), [n, a] = w(null);
1354
+ if (v(() => {
1355
+ if (!e) return;
1356
+ let o = !1;
1357
+ const c = Y();
1358
+ if (c)
1359
+ return ue(c).then((l) => {
1360
+ o || a(l);
1361
+ }), () => {
1362
+ o = !0;
1363
+ };
1364
+ }, [e]), !e || n === null) return null;
1365
+ const s = (o) => (o.leaks || []).length > 0 || (o.stores || []).some((c) => c.before && (c.files ? (c.files.M || 0) + (c.files.A || 0) + (c.files.D || 0) : 0) > 0), r = n.filter((o) => (o.entryId === e || o.userEntryId === e) && s(o));
1366
+ return r.length === 0 ? null : (
1367
+ // 场景 3:徽标带 entryId 打开 → 总览自动过滤到该轮
1368
+ /* @__PURE__ */ $(
1369
+ "button",
1370
+ {
1371
+ style: ct,
1372
+ title: "aiti-git-trace:" + r.length + " 个被追踪操作(点击看时间线)",
1373
+ onClick: () => z("timeline", { sessionId: Y(), entryId: e }),
1374
+ children: [
1375
+ "⎇ ",
1376
+ r.length
1377
+ ]
1378
+ }
1379
+ )
1380
+ );
1381
+ }
1382
+ function On(t) {
1383
+ return (t.leaks || []).length > 0 || (t.stores || []).some((e) => !!e.before && (e.files ? (e.files.M || 0) + (e.files.A || 0) + (e.files.D || 0) : 0) > 0);
1384
+ }
1385
+ function Rn(t, e) {
1386
+ if (!e) return "";
1387
+ if (/^([a-zA-Z]:[\\/]|\/)/.test(e) || !t) return e;
1388
+ const n = t.endsWith("/") || t.endsWith("\\") ? "" : "/";
1389
+ return t + n + e;
1390
+ }
1391
+ function _n(t, e) {
1392
+ const n = new Set((e || []).map(String).filter(Boolean));
1393
+ if (n.size === 0) return null;
1394
+ const a = /* @__PURE__ */ new Set(), s = [];
1395
+ let r = !1, o = 0;
1396
+ for (const c of t || [])
1397
+ if (n.has(String(c.entryId || "")) && On(c)) {
1398
+ o++;
1399
+ for (const l of c.stores || []) {
1400
+ l?.pathsTruncated && (r = !0);
1401
+ for (const f of l?.paths || []) {
1402
+ const S = Rn(l?.root, String(f));
1403
+ !S || a.has(S) || (a.add(S), s.push(S));
1404
+ }
1405
+ }
1406
+ }
1407
+ return s.length === 0 ? null : { absPaths: s, truncated: r, ops: o };
1408
+ }
1409
+ function Wn(t, e) {
1410
+ const n = (s) => String(s || "").replace(/\\/g, "/").replace(/\/+$/, ""), a = new Set((e || []).map(n));
1411
+ return (t || []).filter((s) => !a.has(n(s)));
1412
+ }
1413
+ const te = 8, Bn = 800, rt = /* @__PURE__ */ new Set();
1414
+ let W = null, B = null;
1415
+ function Pn(t) {
1416
+ if (rt.add(t), !W)
1417
+ try {
1418
+ W = new EventSource(ht(yt + "/events")), W.addEventListener("op", (e) => {
1419
+ let n = "";
1420
+ try {
1421
+ n = String(JSON.parse(String(e?.data || "{}"))?.sessionId || "");
1422
+ } catch {
1423
+ return;
1424
+ }
1425
+ n && (mn(n), B && clearTimeout(B), B = setTimeout(() => {
1426
+ B = null;
1427
+ for (const a of [...rt])
1428
+ try {
1429
+ a(n);
1430
+ } catch {
1431
+ }
1432
+ }, Bn));
1433
+ });
1434
+ } catch {
1435
+ W = null;
1436
+ }
1437
+ return () => {
1438
+ if (rt.delete(t), rt.size === 0) {
1439
+ if (W) {
1440
+ try {
1441
+ W.close();
1442
+ } catch {
1443
+ }
1444
+ W = null;
1445
+ }
1446
+ B && (clearTimeout(B), B = null);
1447
+ }
1448
+ };
1449
+ }
1450
+ function Nn(t) {
1451
+ Z(t);
1452
+ const e = Array.isArray(t?.assistantEntryIds) && t.assistantEntryIds.length ? t.assistantEntryIds.map(String).filter(Boolean) : t?.entryId ? [String(t.entryId)] : [], n = Array.isArray(t?.writtenFiles) ? t.writtenFiles.map(String).filter(Boolean) : [], a = String(t?.sessionId || "") || Y(), s = e.join("|"), [r, o] = w(null), [c, l] = w(!1);
1453
+ if (v(() => {
1454
+ if (!s || !a) return;
1455
+ let I = !1;
1456
+ const A = () => {
1457
+ ue(a).then((x) => {
1458
+ I || o(x);
1459
+ });
1460
+ };
1461
+ A();
1462
+ const y = Pn((x) => {
1463
+ x === a && A();
1464
+ });
1465
+ return () => {
1466
+ I = !0, y();
1467
+ };
1468
+ }, [s, a]), !s || r === null) return null;
1469
+ const f = _n(r, e);
1470
+ if (!f) return null;
1471
+ const S = Wn(f.absPaths, n);
1472
+ if (S.length === 0) return null;
1473
+ const E = c ? S : S.slice(0, te), F = S.length - E.length;
1474
+ return /* @__PURE__ */ $("div", { style: { display: "flex", flexWrap: "wrap", gap: 4, alignItems: "center", marginTop: -2 }, children: [
1475
+ /* @__PURE__ */ b(
1476
+ "span",
1477
+ {
1478
+ "aria-hidden": !0,
1479
+ title: C("gt.footer.title", { n: f.ops }),
1480
+ style: { fontSize: 11, color: "var(--text-dim)", cursor: "default" },
1481
+ children: "⎇"
1482
+ }
1483
+ ),
1484
+ E.map((I) => /* @__PURE__ */ b(
1485
+ "button",
1486
+ {
1487
+ style: { ...ct, maxWidth: 260, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" },
1488
+ title: I,
1489
+ onClick: () => z("timeline", { sessionId: a, view: "file", file: I }),
1490
+ children: I.split("/").pop() || I
1491
+ },
1492
+ I
1493
+ )),
1494
+ F > 0 && /* @__PURE__ */ b(
1495
+ "button",
1496
+ {
1497
+ style: ct,
1498
+ title: C("gt.footer.title", { n: f.ops }),
1499
+ onClick: () => l(!0),
1500
+ children: C("gt.footer.more", { n: F })
1501
+ }
1502
+ ),
1503
+ c && S.length > te && /* @__PURE__ */ b("button", { style: ct, onClick: () => l(!1), children: C("gt.footer.collapse") }),
1504
+ f.truncated && /* @__PURE__ */ b(
1505
+ "span",
1506
+ {
1507
+ title: C("gt.footer.truncated"),
1508
+ "aria-label": C("gt.footer.truncated"),
1509
+ style: { fontSize: 11, color: "var(--text-dim)", cursor: "default" },
1510
+ children: "…"
1511
+ }
1512
+ )
1513
+ ] });
1514
+ }
1515
+ function ro(t) {
1516
+ Pe(t), yn(t), cn("aiti-git-trace:timeline", "right-panel"), Xt("aiti-git-trace:timeline", ["right-panel", at("aiti-git-trace:timeline")], "right-panel"), Xt("aiti-git-trace:watch", [at("aiti-git-trace:watch"), "right-panel"], at("aiti-git-trace:watch")), t.registerItems?.("rightFileDock", [
1517
+ { id: "timeline", render: Sn, meta: { title: "时间线" } },
1518
+ { id: "watch", render: xn, meta: { title: "关注路径" } }
1519
+ ]), t.registerItems?.("sidebarExplorerDock", [
1520
+ { id: "timeline", render: En, meta: { title: "时间线", priority: 3 } },
1521
+ { id: "watch", render: wn, meta: { title: "关注路径", priority: 3 } }
1522
+ ]), t.registerItems?.("toolbar", [
1523
+ { id: "aiti-git-trace-watch", render: Dn, meta: { label: "关注路径", icon: "icons/git-branch.svg" }, feature: "trace.watchUI" },
1524
+ { id: "aiti-git-trace-timeline", render: Tn, meta: { label: "时间线", icon: "icons/git-commit-horizontal.svg" }, feature: "trace.timelineUI" }
1525
+ ]), t.registerItems?.("composerTools", [
1526
+ { id: "aiti-git-trace-timeline-entry", render: Ln, meta: { label: "时间线" } }
1527
+ ]), t.registerItems?.("dialogs", [
1528
+ { id: "aiti-git-trace-watch-dialog", render: vn },
1529
+ { id: "aiti-git-trace-timeline-dialog", render: kn },
1530
+ { id: "aiti-git-trace-fork-dialog", render: Cn }
1531
+ ]), t.registerItems?.("banners", [{ id: "aiti-git-trace-banner", render: An }]), t.registerItems?.("userMessageActions", [{ id: "aiti-git-trace-badge", render: Mn }]);
1532
+ try {
1533
+ t.registerItems?.("assistantMessageFooter", [
1534
+ { id: "aiti-git-trace-footer", render: Nn }
1535
+ ]);
1536
+ } catch {
1537
+ }
1538
+ t.registerSessionForkGate?.(async (e) => {
1539
+ try {
1540
+ const n = await In({
1541
+ sessionId: e?.sessionId || "",
1542
+ entryId: e?.entryId || "",
1543
+ // 方案 §3.3:被裁轮次集合(M 及之后全部用户消息 entryId)——优先按它精确圈定区间(含被编辑轮)
1544
+ cutUserEntryIds: Array.isArray(e?.cutUserEntryIds) ? e.cutUserEntryIds.map(String).filter(Boolean) : []
1545
+ });
1546
+ return !(n && n.action === "cancel");
1547
+ } catch {
1548
+ return !0;
1549
+ }
1550
+ });
1551
+ try {
1552
+ console.log("[aiti-git-trace] client 已挂载(关注路径/时间线/回撤对话框/横幅/徽标)");
1553
+ } catch {
1554
+ }
1555
+ return () => {
1556
+ };
1557
+ }
1558
+ export {
1559
+ at as A,
1560
+ Qn as B,
1561
+ Gn as C,
1562
+ Zn as D,
1563
+ jn as E,
1564
+ $n as F,
1565
+ ro as G,
1566
+ Mt as T,
1567
+ Ot as W,
1568
+ zn as a,
1569
+ v as b,
1570
+ $ as c,
1571
+ Rt as d,
1572
+ Fn as e,
1573
+ Xn as f,
1574
+ Y as g,
1575
+ Z as h,
1576
+ Jn as i,
1577
+ b as j,
1578
+ Wt as k,
1579
+ ht as l,
1580
+ Kn as m,
1581
+ Un as n,
1582
+ qn as o,
1583
+ Yn as p,
1584
+ io as q,
1585
+ ct as r,
1586
+ no as s,
1587
+ C as t,
1588
+ w as u,
1589
+ eo as v,
1590
+ z as w,
1591
+ oo as x,
1592
+ Vn as y,
1593
+ to as z
1594
+ };