@ai-setting/roy-plugin-task-show 0.8.10 → 0.9.6
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/cli-tasks-adapter.d.ts +5 -0
- package/dist/cli-tasks-adapter.d.ts.map +1 -1
- package/dist/cli-tasks-adapter.js +9 -0
- package/dist/cli-tasks-adapter.js.map +1 -1
- package/dist/cli-tasks-tree-adapter.d.ts +5 -0
- package/dist/cli-tasks-tree-adapter.d.ts.map +1 -1
- package/dist/cli-tasks-tree-adapter.js +5 -0
- package/dist/cli-tasks-tree-adapter.js.map +1 -1
- package/dist/plugin.d.ts +8 -0
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +99 -0
- package/dist/plugin.js.map +1 -1
- package/dist/server.d.ts +15 -2
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +46 -10
- package/dist/server.js.map +1 -1
- package/dist/task-detail-mermaid.d.ts +9 -0
- package/dist/task-detail-mermaid.d.ts.map +1 -1
- package/dist/task-detail-mermaid.js +43 -3
- package/dist/task-detail-mermaid.js.map +1 -1
- package/dist/task-metadata.d.ts +21 -0
- package/dist/task-metadata.d.ts.map +1 -0
- package/dist/task-metadata.js +50 -0
- package/dist/task-metadata.js.map +1 -0
- package/dist/task-session-store.d.ts +70 -0
- package/dist/task-session-store.d.ts.map +1 -0
- package/dist/task-session-store.js +177 -0
- package/dist/task-session-store.js.map +1 -0
- package/dist/tracing/decorator.d.ts +48 -0
- package/dist/tracing/decorator.d.ts.map +1 -0
- package/dist/tracing/decorator.js +310 -0
- package/dist/tracing/decorator.js.map +1 -0
- package/package.json +1 -1
- package/plugin.json +2 -2
- package/public/app.js +45 -1
- package/public/index.html +3 -0
- package/public/session-forest.js +97 -0
- package/public/style.css +64 -0
- package/public/task-operations.js +7 -0
package/public/app.js
CHANGED
|
@@ -247,7 +247,7 @@ function buildMermaidSource(session, operations) {
|
|
|
247
247
|
// Top-level helpers used by buildMermaidSource. Kept here so both
|
|
248
248
|
// IIFEs can call them via the script-wide closure.
|
|
249
249
|
function toolLabel(t) {
|
|
250
|
-
const head =
|
|
250
|
+
const head = encodeMermaidLabelTextClient(`${t.sequence}. ${t.toolName}${t.hasAttachment ? " \ud83d\udcce" : ""}`);
|
|
251
251
|
return `${head}<br/><small>${t.success ? "ok" : "FAIL"} \u00b7 ${t.durationMs}ms</small>`;
|
|
252
252
|
}
|
|
253
253
|
|
|
@@ -263,6 +263,35 @@ function escapeMermaid(s) {
|
|
|
263
263
|
return String(s).replace(/[<>"#]/g, "").replace(/[^A-Za-z0-9_.\-]/g, "_");
|
|
264
264
|
}
|
|
265
265
|
|
|
266
|
+
/**
|
|
267
|
+
* v0.9.0 client-side mirror of `encodeMermaidLabelText` from
|
|
268
|
+
* `src/task-detail-mermaid.ts`. MUST stay byte-for-byte identical
|
|
269
|
+
* to the server implementation; the parity test in
|
|
270
|
+
* `test/mermaid-cjk-encoding-client.test.ts` enforces this.
|
|
271
|
+
*/
|
|
272
|
+
function encodeMermaidLabelTextClient(s) {
|
|
273
|
+
var cleaned = String(s == null ? "" : s)
|
|
274
|
+
.replace(/["\r\n\t]+/g, " ")
|
|
275
|
+
.replace(/\s+/g, " ")
|
|
276
|
+
.trim();
|
|
277
|
+
var out = "";
|
|
278
|
+
for (var i = 0; i < cleaned.length; i++) {
|
|
279
|
+
var ch = cleaned[i];
|
|
280
|
+
var code = ch.codePointAt ? ch.codePointAt(0) : (ch.charCodeAt ? ch.charCodeAt(0) : undefined);
|
|
281
|
+
if (code === undefined) continue;
|
|
282
|
+
if (code < 0x80) { out += ch; continue; }
|
|
283
|
+
if (code <= 0xFFFF) {
|
|
284
|
+
out += "\\u" + code.toString(16).padStart(4, "0");
|
|
285
|
+
} else {
|
|
286
|
+
var v = code - 0x10000;
|
|
287
|
+
var hi = 0xD800 + (v >> 10);
|
|
288
|
+
var lo = 0xDC00 + (v & 0x3FF);
|
|
289
|
+
out += "\\u" + hi.toString(16).padStart(4, "0") + "\\u" + lo.toString(16).padStart(4, "0");
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
return out;
|
|
293
|
+
}
|
|
294
|
+
|
|
266
295
|
// ---------------------------------------------------------------------------
|
|
267
296
|
// v0.8.2 (fix/mermaid-readable-labels) — human-readable Mermaid
|
|
268
297
|
// phase labels. This block mirrors `src/task-detail-mermaid.ts` so
|
|
@@ -481,6 +510,21 @@ function getPhaseLabel(op) {
|
|
|
481
510
|
if (typeof window !== "undefined") {
|
|
482
511
|
window.buildMermaidSource = buildMermaidSource;
|
|
483
512
|
window.getPhaseLabel = getPhaseLabel;
|
|
513
|
+
window.encodeMermaidLabelTextClient = encodeMermaidLabelTextClient;
|
|
514
|
+
window.toolLabelClient = function (t) { return toolLabel(t); };
|
|
515
|
+
// v0.9.0 invariant: when invoked with a server encoder, the client
|
|
516
|
+
// encoder must produce byte-for-byte identical output. Drift is
|
|
517
|
+
// surfaced as a hard throw so SSR HTML and dynamic re-render stay
|
|
518
|
+
// in sync.
|
|
519
|
+
window.__cjkParityCheck = function (serverEncode) {
|
|
520
|
+
var cases = ["Phase 3: Plan", "\u4efb\u52a1\u7ba1\u7406", "Phase 1: \u4efb\u52a1\u7ba1\u7406"];
|
|
521
|
+
for (var i = 0; i < cases.length; i++) {
|
|
522
|
+
if (encodeMermaidLabelTextClient(cases[i]) !== serverEncode(cases[i])) {
|
|
523
|
+
throw new Error("CJK parity broken: " + JSON.stringify(cases[i]));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
return true;
|
|
527
|
+
};
|
|
484
528
|
}
|
|
485
529
|
/**
|
|
486
530
|
* v0.8.0+ Mermaid ↔ tool-table bridge.
|
package/public/index.html
CHANGED
|
@@ -80,6 +80,9 @@
|
|
|
80
80
|
</section>
|
|
81
81
|
|
|
82
82
|
<script src="/static/app.js"></script>
|
|
83
|
+
<script src="/static/mermaid-renderer.js"></script>
|
|
83
84
|
<script src="/static/tasks-tree.js"></script>
|
|
85
|
+
<script src="/static/task-operations.js"></script>
|
|
86
|
+
<script src="/static/session-forest.js"></script>
|
|
84
87
|
</body>
|
|
85
88
|
</html>
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Client-side controller for the v0.9.0 session-scoped forest.
|
|
3
|
+
*
|
|
4
|
+
* - Wires each `[data-toggle="<id>"]` button to its matching
|
|
5
|
+
* `details[data-details="<id>"]` block (the "显示全部栏位" toggle).
|
|
6
|
+
* - Lazy-loads `/api/tasks/<id>/operations` into each
|
|
7
|
+
* `ul.session-operations[data-task-operations="<id>"]` placeholder,
|
|
8
|
+
* reusing `renderPipelineHtml` from `task-operations.js`.
|
|
9
|
+
*
|
|
10
|
+
* Vanilla JS, no framework dependency. Bootstraps on DOMContentLoaded.
|
|
11
|
+
*/
|
|
12
|
+
(function () {
|
|
13
|
+
"use strict";
|
|
14
|
+
|
|
15
|
+
function esc(s) {
|
|
16
|
+
return String(s == null ? "" : s)
|
|
17
|
+
.replace(/&/g, "&")
|
|
18
|
+
.replace(/</g, "<")
|
|
19
|
+
.replace(/>/g, ">")
|
|
20
|
+
.replace(/"/g, """)
|
|
21
|
+
.replace(/'/g, "'");
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function wireToggle(button) {
|
|
25
|
+
var id = button.getAttribute("data-toggle");
|
|
26
|
+
if (!id) return;
|
|
27
|
+
var target = document.querySelector('[data-details="' + cssEscape(id) + '"]');
|
|
28
|
+
if (!target) return;
|
|
29
|
+
button.addEventListener("click", function () {
|
|
30
|
+
target.open = !target.open;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function cssEscape(s) {
|
|
35
|
+
if (window.CSS && typeof window.CSS.escape === "function") {
|
|
36
|
+
return window.CSS.escape(s);
|
|
37
|
+
}
|
|
38
|
+
return String(s).replace(/[^a-zA-Z0-9_-]/g, function (c) {
|
|
39
|
+
return "\\" + c;
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function loadOperationsFor(placeholder) {
|
|
44
|
+
var id = placeholder.getAttribute("data-task-operations");
|
|
45
|
+
if (!id) return;
|
|
46
|
+
placeholder.innerHTML = '<p class="empty">Loading operations…</p>';
|
|
47
|
+
fetch("/api/tasks/" + encodeURIComponent(id) + "/operations")
|
|
48
|
+
.then(function (r) {
|
|
49
|
+
if (!r.ok) throw new Error("HTTP " + r.status);
|
|
50
|
+
return r.json();
|
|
51
|
+
})
|
|
52
|
+
.then(function (envelope) {
|
|
53
|
+
if (typeof window.renderPipelineHtml === "function") {
|
|
54
|
+
placeholder.innerHTML = window.renderPipelineHtml(envelope.operations || [], envelope.stale, Number(id));
|
|
55
|
+
} else {
|
|
56
|
+
// Fallback: render a minimal list
|
|
57
|
+
var html = "<ol class=\"ops-fallback\">";
|
|
58
|
+
(envelope.operations || []).forEach(function (op) {
|
|
59
|
+
html += "<li>" + esc(op.title || op.milestoneType || "op") + "</li>";
|
|
60
|
+
});
|
|
61
|
+
html += "</ol>";
|
|
62
|
+
placeholder.innerHTML = html;
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.catch(function (err) {
|
|
66
|
+
placeholder.innerHTML = '<p class="empty error">Failed to load operations: ' + esc(err && err.message || err) + '</p>';
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function boot() {
|
|
71
|
+
var section = document.querySelector('[data-session-forest="1"]');
|
|
72
|
+
if (!section) return;
|
|
73
|
+
var buttons = section.querySelectorAll('[data-toggle]');
|
|
74
|
+
for (var i = 0; i < buttons.length; i++) wireToggle(buttons[i]);
|
|
75
|
+
var placeholders = section.querySelectorAll('[data-task-operations]');
|
|
76
|
+
for (var j = 0; j < placeholders.length; j++) loadOperationsFor(placeholders[j]);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (typeof window !== "undefined") {
|
|
80
|
+
window.__sessionForestBoot = boot;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (typeof document !== "undefined") {
|
|
84
|
+
if (document.readyState === "loading") {
|
|
85
|
+
document.addEventListener("DOMContentLoaded", boot);
|
|
86
|
+
} else {
|
|
87
|
+
boot();
|
|
88
|
+
}
|
|
89
|
+
} else if (typeof window !== "undefined" && window.document) {
|
|
90
|
+
// jsdom eval fallback: window may exist but document may not be in scope
|
|
91
|
+
if (window.document.readyState === "loading") {
|
|
92
|
+
window.document.addEventListener("DOMContentLoaded", boot);
|
|
93
|
+
} else {
|
|
94
|
+
boot();
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
})();
|
package/public/style.css
CHANGED
|
@@ -1027,3 +1027,67 @@ details summary {
|
|
|
1027
1027
|
border: 1px solid rgba(148, 163, 184, 0.4);
|
|
1028
1028
|
}
|
|
1029
1029
|
|
|
1030
|
+
/* ---------- Session forest metadata ---------- */
|
|
1031
|
+
.session-forest > ul {
|
|
1032
|
+
list-style: none;
|
|
1033
|
+
margin: 0;
|
|
1034
|
+
padding: 0;
|
|
1035
|
+
}
|
|
1036
|
+
.session-row {
|
|
1037
|
+
min-width: 0;
|
|
1038
|
+
margin: 8px 0;
|
|
1039
|
+
padding: 10px 12px;
|
|
1040
|
+
border: 1px solid var(--border);
|
|
1041
|
+
border-radius: 8px;
|
|
1042
|
+
background: rgba(24, 36, 66, 0.45);
|
|
1043
|
+
}
|
|
1044
|
+
.session-row .session-title {
|
|
1045
|
+
display: inline-block;
|
|
1046
|
+
font-weight: 600;
|
|
1047
|
+
overflow-wrap: anywhere;
|
|
1048
|
+
}
|
|
1049
|
+
.session-toggle {
|
|
1050
|
+
margin-left: 10px;
|
|
1051
|
+
}
|
|
1052
|
+
.session-details {
|
|
1053
|
+
margin-top: 8px;
|
|
1054
|
+
}
|
|
1055
|
+
.session-details dl {
|
|
1056
|
+
display: grid;
|
|
1057
|
+
grid-template-columns: minmax(10rem, 15rem) minmax(0, 1fr);
|
|
1058
|
+
gap: 6px 12px;
|
|
1059
|
+
margin: 10px 0 0;
|
|
1060
|
+
}
|
|
1061
|
+
.session-details dt {
|
|
1062
|
+
color: var(--muted);
|
|
1063
|
+
font-weight: 600;
|
|
1064
|
+
overflow-wrap: anywhere;
|
|
1065
|
+
}
|
|
1066
|
+
.session-details dd {
|
|
1067
|
+
min-width: 0;
|
|
1068
|
+
margin: 0;
|
|
1069
|
+
overflow-wrap: anywhere;
|
|
1070
|
+
}
|
|
1071
|
+
.session-details pre.metadata-json,
|
|
1072
|
+
.session-details pre.metadata-text {
|
|
1073
|
+
max-height: 24rem;
|
|
1074
|
+
margin: 0;
|
|
1075
|
+
white-space: pre-wrap;
|
|
1076
|
+
overflow: auto;
|
|
1077
|
+
overflow-wrap: anywhere;
|
|
1078
|
+
word-break: break-word;
|
|
1079
|
+
}
|
|
1080
|
+
.session-operations {
|
|
1081
|
+
list-style: none;
|
|
1082
|
+
margin: 12px 0 0;
|
|
1083
|
+
padding: 0;
|
|
1084
|
+
}
|
|
1085
|
+
@media (max-width: 700px) {
|
|
1086
|
+
.session-details dl {
|
|
1087
|
+
grid-template-columns: 1fr;
|
|
1088
|
+
gap: 2px;
|
|
1089
|
+
}
|
|
1090
|
+
.session-details dd {
|
|
1091
|
+
margin-bottom: 8px;
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
@@ -282,6 +282,13 @@
|
|
|
282
282
|
window.__pipelineController = new PipelineController(root);
|
|
283
283
|
}
|
|
284
284
|
|
|
285
|
+
// v0.9.0: expose renderPipelineHtml to the global scope so other
|
|
286
|
+
// modules (session-forest.js) can re-use the same timeline rendering
|
|
287
|
+
// for the v0.9.0 session-forest view.
|
|
288
|
+
if (typeof window !== "undefined") {
|
|
289
|
+
window.renderPipelineHtml = renderPipelineHtml;
|
|
290
|
+
}
|
|
291
|
+
|
|
285
292
|
if (document.readyState === "loading") {
|
|
286
293
|
document.addEventListener("DOMContentLoaded", boot);
|
|
287
294
|
} else {
|