@ai-setting/roy-plugin-task-show 2.5.11 → 2.5.12
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/collector.d.ts +11 -0
- package/dist/collector.d.ts.map +1 -1
- package/dist/collector.js +37 -12
- package/dist/collector.js.map +1 -1
- package/dist/file-tree.d.ts +57 -1
- package/dist/file-tree.d.ts.map +1 -1
- package/dist/file-tree.js +22 -2
- package/dist/file-tree.js.map +1 -1
- package/dist/file-viewer-utils.d.ts +76 -0
- package/dist/file-viewer-utils.d.ts.map +1 -0
- package/dist/file-viewer-utils.js +215 -0
- package/dist/file-viewer-utils.js.map +1 -0
- package/dist/logger.d.ts +59 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +181 -0
- package/dist/logger.js.map +1 -0
- package/dist/mermaid-zoom-guardian.d.ts +77 -0
- package/dist/mermaid-zoom-guardian.d.ts.map +1 -0
- package/dist/mermaid-zoom-guardian.js +176 -0
- package/dist/mermaid-zoom-guardian.js.map +1 -0
- package/dist/plugin.d.ts +24 -10
- package/dist/plugin.d.ts.map +1 -1
- package/dist/plugin.js +79 -33
- package/dist/plugin.js.map +1 -1
- package/dist/server.d.ts +25 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +120 -8
- package/dist/server.js.map +1 -1
- package/dist/tool-call-detail.d.ts +18 -0
- package/dist/tool-call-detail.d.ts.map +1 -1
- package/dist/tool-call-detail.js +115 -7
- package/dist/tool-call-detail.js.map +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/public/app.js +18 -0
- package/public/mermaid-zoom-guardian.js +137 -0
- package/public/style.css +109 -0
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Plugin-internal unified logger (Task #2961).
|
|
3
|
+
*
|
|
4
|
+
* User feedback: "用 logger.info 走日志系统,不污染 stdout/stderr".
|
|
5
|
+
*
|
|
6
|
+
* The plugin is intentionally zero-runtime-dep (no `@ai-setting/roy-agent-core`,
|
|
7
|
+
* no `pino`/`winston`). To route diagnostic output through a unified logger
|
|
8
|
+
* WITHOUT polluting stdout/stderr, we ship a small, self-contained logger
|
|
9
|
+
* here that mirrors the host agent's `createLogger` semantics:
|
|
10
|
+
*
|
|
11
|
+
* - `info` / `warn` / `error` / `debug` methods on every logger instance.
|
|
12
|
+
* - Quiet-by-default mode: when `quietMode === true` (the default), all
|
|
13
|
+
* log calls go to a per-category log file under
|
|
14
|
+
* `${XDG_DATA_HOME:-~/.local/share}/roy-agent/logs/roy-plugin-task-show-<name>.log`,
|
|
15
|
+
* and DO NOT touch `console.log` / `console.warn` / `console.error`.
|
|
16
|
+
* - Console output is only enabled when an operator explicitly calls
|
|
17
|
+
* `setQuietMode(false)`. The env var `TASK_SHOW_DEBUG=1` no longer
|
|
18
|
+
* re-enables console output — it is intentionally ignored (was the
|
|
19
|
+
* previous band-aid in Task #2953).
|
|
20
|
+
* - The log file path is created on first write (mkdir -p).
|
|
21
|
+
* - Writes are synchronous append (`appendFileSync`) so the log is
|
|
22
|
+
* durable even when the process exits immediately (subprocess shutdown).
|
|
23
|
+
*
|
|
24
|
+
* Why a new file instead of inlining in `plugin.ts`? Tests pin the
|
|
25
|
+
* `createPluginLogger` symbol (RED-3 / RED-4 / RED-5) and the chat
|
|
26
|
+
* subprocess test imports it from `../src/logger.js`. Co-locating the
|
|
27
|
+
* logger means `server.ts`, `collector.ts`, and `plugin.ts` all import
|
|
28
|
+
* the same `createPluginLogger` — one sink, one set of gates.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: this logger is intentionally minimal. If the host agent ever
|
|
31
|
+
* exposes a `createPluginLogger` factory in `@ai-setting/roy-agent-core`,
|
|
32
|
+
* this file can be replaced with a thin re-export.
|
|
33
|
+
*/
|
|
34
|
+
export declare function isQuietMode(): boolean;
|
|
35
|
+
export declare function setQuietMode(enabled: boolean): void;
|
|
36
|
+
export interface PluginLogger {
|
|
37
|
+
/** Log to file unconditionally. Console only when un-quiet. */
|
|
38
|
+
info(message: string, data?: unknown): void;
|
|
39
|
+
warn(message: string, data?: unknown): void;
|
|
40
|
+
error(message: string, data?: unknown): void;
|
|
41
|
+
debug(message: string, data?: unknown): void;
|
|
42
|
+
/**
|
|
43
|
+
* Whether this logger currently routes to the console. True when
|
|
44
|
+
* quiet mode is off AND the env says console output is allowed.
|
|
45
|
+
* Tests use this to assert the default behaviour without spying on
|
|
46
|
+
* `console.*` directly.
|
|
47
|
+
*/
|
|
48
|
+
readonly consoleEnabled: boolean;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Create (or fetch from cache) a plugin logger under the given category
|
|
52
|
+
* prefix. The prefix appears in the log file name and in each formatted
|
|
53
|
+
* line so operators can grep for it.
|
|
54
|
+
*
|
|
55
|
+
* @param prefix A short identifier for the subsystem
|
|
56
|
+
* (e.g. `"plugin"`, `"server"`, `"collector"`).
|
|
57
|
+
*/
|
|
58
|
+
export declare function createPluginLogger(prefix: string): PluginLogger;
|
|
59
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAqBH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAEnD;AAgDD,MAAM,WAAW,YAAY;IAC3B,+DAA+D;IAC/D,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IAC7C;;;;;OAKG;IACH,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;CAClC;AA+CD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,YAAY,CA4C/D"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Plugin-internal unified logger (Task #2961).
|
|
3
|
+
*
|
|
4
|
+
* User feedback: "用 logger.info 走日志系统,不污染 stdout/stderr".
|
|
5
|
+
*
|
|
6
|
+
* The plugin is intentionally zero-runtime-dep (no `@ai-setting/roy-agent-core`,
|
|
7
|
+
* no `pino`/`winston`). To route diagnostic output through a unified logger
|
|
8
|
+
* WITHOUT polluting stdout/stderr, we ship a small, self-contained logger
|
|
9
|
+
* here that mirrors the host agent's `createLogger` semantics:
|
|
10
|
+
*
|
|
11
|
+
* - `info` / `warn` / `error` / `debug` methods on every logger instance.
|
|
12
|
+
* - Quiet-by-default mode: when `quietMode === true` (the default), all
|
|
13
|
+
* log calls go to a per-category log file under
|
|
14
|
+
* `${XDG_DATA_HOME:-~/.local/share}/roy-agent/logs/roy-plugin-task-show-<name>.log`,
|
|
15
|
+
* and DO NOT touch `console.log` / `console.warn` / `console.error`.
|
|
16
|
+
* - Console output is only enabled when an operator explicitly calls
|
|
17
|
+
* `setQuietMode(false)`. The env var `TASK_SHOW_DEBUG=1` no longer
|
|
18
|
+
* re-enables console output — it is intentionally ignored (was the
|
|
19
|
+
* previous band-aid in Task #2953).
|
|
20
|
+
* - The log file path is created on first write (mkdir -p).
|
|
21
|
+
* - Writes are synchronous append (`appendFileSync`) so the log is
|
|
22
|
+
* durable even when the process exits immediately (subprocess shutdown).
|
|
23
|
+
*
|
|
24
|
+
* Why a new file instead of inlining in `plugin.ts`? Tests pin the
|
|
25
|
+
* `createPluginLogger` symbol (RED-3 / RED-4 / RED-5) and the chat
|
|
26
|
+
* subprocess test imports it from `../src/logger.js`. Co-locating the
|
|
27
|
+
* logger means `server.ts`, `collector.ts`, and `plugin.ts` all import
|
|
28
|
+
* the same `createPluginLogger` — one sink, one set of gates.
|
|
29
|
+
*
|
|
30
|
+
* NOTE: this logger is intentionally minimal. If the host agent ever
|
|
31
|
+
* exposes a `createPluginLogger` factory in `@ai-setting/roy-agent-core`,
|
|
32
|
+
* this file can be replaced with a thin re-export.
|
|
33
|
+
*/
|
|
34
|
+
import * as fs from "node:fs";
|
|
35
|
+
import * as os from "node:os";
|
|
36
|
+
import * as path from "node:path";
|
|
37
|
+
// ============================================================================
|
|
38
|
+
// Module-level quiet mode (mirrors @ai-setting/roy-agent-core quietMode)
|
|
39
|
+
// ============================================================================
|
|
40
|
+
/**
|
|
41
|
+
* Quiet mode = "log to file only, do not touch console". When false, log
|
|
42
|
+
* calls also forward to the matching `console.*` method.
|
|
43
|
+
*
|
|
44
|
+
* Defaults to `true` so the plugin never pollutes the parent process's
|
|
45
|
+
* stdout / stderr unless the operator explicitly asks for it. The env
|
|
46
|
+
* var `TASK_SHOW_DEBUG=1` (legacy band-aid from Task #2953) is ignored
|
|
47
|
+
* — see `envSaysConsoleEnabled()` for the rationale.
|
|
48
|
+
*/
|
|
49
|
+
let quietMode = true;
|
|
50
|
+
export function isQuietMode() {
|
|
51
|
+
return quietMode;
|
|
52
|
+
}
|
|
53
|
+
export function setQuietMode(enabled) {
|
|
54
|
+
quietMode = enabled;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* v2.5.12 (Task #2961): the env flags are intentionally NOT consulted.
|
|
58
|
+
* The user's explicit feedback was "用 logger.info 走日志系统,不污染
|
|
59
|
+
* stdout/stderr". Honouring that means the default behaviour must NEVER
|
|
60
|
+
* touch console, regardless of legacy debug env vars. Operators who
|
|
61
|
+
* want console output for live debugging should call `setQuietMode(false)`
|
|
62
|
+
* directly — this keeps the env variable surface narrow and predictable.
|
|
63
|
+
*/
|
|
64
|
+
function envSaysConsoleEnabled() {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
// ============================================================================
|
|
68
|
+
// Log file path
|
|
69
|
+
// ============================================================================
|
|
70
|
+
/**
|
|
71
|
+
* Resolve the log directory every call so tests that flip
|
|
72
|
+
* `XDG_DATA_HOME` between cases pick up the new path. The cost is a
|
|
73
|
+
* couple of `path.join` calls per log write — negligible.
|
|
74
|
+
*/
|
|
75
|
+
function getLogDir() {
|
|
76
|
+
const xdg = process.env?.XDG_DATA_HOME;
|
|
77
|
+
const base = xdg && xdg.length > 0
|
|
78
|
+
? xdg
|
|
79
|
+
: path.join(os.homedir(), ".local", "share");
|
|
80
|
+
const dir = path.join(base, "roy-agent", "logs");
|
|
81
|
+
try {
|
|
82
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// ignore — fall through; writeToFile will no-op on error.
|
|
86
|
+
}
|
|
87
|
+
return dir;
|
|
88
|
+
}
|
|
89
|
+
function getLogFilePath(category) {
|
|
90
|
+
// Sanitize the category to avoid path traversal — keep alnum + dash/underscore.
|
|
91
|
+
const safe = category.replace(/[^a-zA-Z0-9_-]/g, "_").slice(0, 64);
|
|
92
|
+
return path.join(getLogDir(), `roy-plugin-task-show-${safe}.log`);
|
|
93
|
+
}
|
|
94
|
+
const TAG = "roy-plugin-task-show";
|
|
95
|
+
function formatLine(level, prefix, message, data) {
|
|
96
|
+
const ts = new Date().toISOString();
|
|
97
|
+
const tail = data !== undefined ? ` ${safeStringify(data)}` : "";
|
|
98
|
+
return `${ts} [${level.toUpperCase()}] [${TAG}:${prefix}] ${message}${tail}`;
|
|
99
|
+
}
|
|
100
|
+
function safeStringify(data) {
|
|
101
|
+
try {
|
|
102
|
+
const s = JSON.stringify(data);
|
|
103
|
+
return s === undefined ? String(data) : s;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return String(data);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
function writeToFile(line, category) {
|
|
110
|
+
try {
|
|
111
|
+
const file = getLogFilePath(category);
|
|
112
|
+
fs.appendFileSync(file, line + "\n", "utf-8");
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// Swallow — the plugin must never crash on log I/O.
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Compute the current console-enabled state. Called on every log
|
|
120
|
+
* call so that toggling `quietMode` at runtime takes effect immediately.
|
|
121
|
+
*/
|
|
122
|
+
function computeConsoleEnabled() {
|
|
123
|
+
return !quietMode || envSaysConsoleEnabled();
|
|
124
|
+
}
|
|
125
|
+
// ============================================================================
|
|
126
|
+
// Logger factory
|
|
127
|
+
// ============================================================================
|
|
128
|
+
const cache = new Map();
|
|
129
|
+
/**
|
|
130
|
+
* Create (or fetch from cache) a plugin logger under the given category
|
|
131
|
+
* prefix. The prefix appears in the log file name and in each formatted
|
|
132
|
+
* line so operators can grep for it.
|
|
133
|
+
*
|
|
134
|
+
* @param prefix A short identifier for the subsystem
|
|
135
|
+
* (e.g. `"plugin"`, `"server"`, `"collector"`).
|
|
136
|
+
*/
|
|
137
|
+
export function createPluginLogger(prefix) {
|
|
138
|
+
const cached = cache.get(prefix);
|
|
139
|
+
if (cached)
|
|
140
|
+
return cached;
|
|
141
|
+
const logger = {
|
|
142
|
+
get consoleEnabled() {
|
|
143
|
+
return computeConsoleEnabled();
|
|
144
|
+
},
|
|
145
|
+
info(message, data) {
|
|
146
|
+
const line = formatLine("info", prefix, message, data);
|
|
147
|
+
writeToFile(line, prefix);
|
|
148
|
+
if (computeConsoleEnabled()) {
|
|
149
|
+
// eslint-disable-next-line no-console
|
|
150
|
+
console.log(line);
|
|
151
|
+
}
|
|
152
|
+
},
|
|
153
|
+
warn(message, data) {
|
|
154
|
+
const line = formatLine("warn", prefix, message, data);
|
|
155
|
+
writeToFile(line, prefix);
|
|
156
|
+
if (computeConsoleEnabled()) {
|
|
157
|
+
// eslint-disable-next-line no-console
|
|
158
|
+
console.warn(line);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
error(message, data) {
|
|
162
|
+
const line = formatLine("error", prefix, message, data);
|
|
163
|
+
writeToFile(line, prefix);
|
|
164
|
+
if (computeConsoleEnabled()) {
|
|
165
|
+
// eslint-disable-next-line no-console
|
|
166
|
+
console.error(line);
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
debug(message, data) {
|
|
170
|
+
const line = formatLine("debug", prefix, message, data);
|
|
171
|
+
writeToFile(line, prefix);
|
|
172
|
+
if (computeConsoleEnabled()) {
|
|
173
|
+
// eslint-disable-next-line no-console
|
|
174
|
+
console.debug(line);
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
cache.set(prefix, logger);
|
|
179
|
+
return logger;
|
|
180
|
+
}
|
|
181
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Mermaid zoom-stage guardian (v2.5.12 / Task #2951).
|
|
3
|
+
*
|
|
4
|
+
* Why this module exists
|
|
5
|
+
* ----------------------
|
|
6
|
+
* The Mermaid controller (`public/mermaid-renderer.js`) wraps every
|
|
7
|
+
* freshly-rendered SVG in a `.mermaid-zoom-stage` div that carries
|
|
8
|
+
* the pan/zoom CSS transform and the pointer-drag handlers. Without
|
|
9
|
+
* that wrapper the user can neither pan nor zoom the lifecycle
|
|
10
|
+
* diagram.
|
|
11
|
+
*
|
|
12
|
+
* Mermaid's library auto-runs `mermaid.run({nodes})` once
|
|
13
|
+
* `startOnLoad: true` is set in `mermaid.initialize`. We DO set
|
|
14
|
+
* `startOnLoad: true` in the SSR template (server.ts line ~2041) so
|
|
15
|
+
* the initial paint works for hosts that don't ship our controller.
|
|
16
|
+
* The auto-runner scans the DOM for `.mermaid` elements that are not
|
|
17
|
+
* already marked `data-processed` and replaces their innerHTML with a
|
|
18
|
+
* freshly-rendered SVG.
|
|
19
|
+
*
|
|
20
|
+
* Even after our controller's `update()` has set `data-processed="true"`
|
|
21
|
+
* and wrapped the SVG, Mermaid's auto-runner fires roughly 1.5–3s
|
|
22
|
+
* later (observed via Playwright trace on 2026-08-12) and replaces
|
|
23
|
+
* the contents of the `.mermaid` element with a fresh, bare SVG. The
|
|
24
|
+
* bare SVG is not wrapped in `.mermaid-zoom-stage`, so the pan/zoom
|
|
25
|
+
* UI silently breaks for the rest of the page lifetime.
|
|
26
|
+
*
|
|
27
|
+
* What this module does
|
|
28
|
+
* ---------------------
|
|
29
|
+
* `ensureMermaidZoomStage(container)` — one-shot helper that walks
|
|
30
|
+
* the container and wraps any existing `<svg>` in a
|
|
31
|
+
* `.mermaid-zoom-stage` div. Idempotent: calling it twice keeps ONE
|
|
32
|
+
* wrapper.
|
|
33
|
+
*
|
|
34
|
+
* `MermaidZoomGuardian` — a long-lived `MutationObserver` that
|
|
35
|
+
* detects when something (Mermaid's late `mermaid.run()`, an SSE
|
|
36
|
+
* patch, etc.) replaces the SVG and re-applies the wrapper. The
|
|
37
|
+
* guardian stops observing after `stop()` is called.
|
|
38
|
+
*
|
|
39
|
+
* Both helpers are deliberately framework-free so they can be unit-
|
|
40
|
+
* tested in happy-dom / jsdom without a full browser.
|
|
41
|
+
*/
|
|
42
|
+
/**
|
|
43
|
+
* Wrap any existing SVG inside `container` in a single
|
|
44
|
+
* `.mermaid-zoom-stage` div. Idempotent.
|
|
45
|
+
*
|
|
46
|
+
* @returns the (possibly newly-created) stage element, or `null`
|
|
47
|
+
* when the container has no SVG to wrap.
|
|
48
|
+
*/
|
|
49
|
+
export declare function ensureMermaidZoomStage(container: Element): HTMLElement | null;
|
|
50
|
+
/**
|
|
51
|
+
* v2.5.12 (Task #2951): the MermaidZoomGuardian watches a container
|
|
52
|
+
* and re-wraps any replacement SVG in `.mermaid-zoom-stage`. Use
|
|
53
|
+
* this for diagrams that survive past the initial render — e.g. the
|
|
54
|
+
* lifecycle mermaid on the per-task page, where Mermaid's late
|
|
55
|
+
* `mermaid.run()` otherwise destroys the wrapper.
|
|
56
|
+
*
|
|
57
|
+
* Lifecycle:
|
|
58
|
+
* const g = new MermaidZoomGuardian(container);
|
|
59
|
+
* g.start();
|
|
60
|
+
* // ...later, when the page is torn down:
|
|
61
|
+
* g.stop();
|
|
62
|
+
*/
|
|
63
|
+
export declare class MermaidZoomGuardian {
|
|
64
|
+
private readonly container;
|
|
65
|
+
private observer;
|
|
66
|
+
private scheduled;
|
|
67
|
+
constructor(container: Element);
|
|
68
|
+
start(): void;
|
|
69
|
+
stop(): void;
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Export the constants so tests can reference them without hardcoding.
|
|
73
|
+
*/
|
|
74
|
+
export declare const MERMAID_STAGE_CLASS = "mermaid-zoom-stage";
|
|
75
|
+
export declare const MERMAID_TOOLBAR_CLASS = "mermaid-zoom-toolbar";
|
|
76
|
+
export declare const MERMAID_CONTAINER_CLASS = "mermaid";
|
|
77
|
+
//# sourceMappingURL=mermaid-zoom-guardian.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid-zoom-guardian.d.ts","sourceRoot":"","sources":["../src/mermaid-zoom-guardian.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAgBH;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,OAAO,GAAG,WAAW,GAAG,IAAI,CAsC7E;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAiC;IACjD,OAAO,CAAC,SAAS,CAAS;gBAEd,SAAS,EAAE,OAAO;IAI9B,KAAK,IAAI,IAAI;IAwCb,IAAI,IAAI,IAAI;CAOb;AAED;;GAEG;AACH,eAAO,MAAM,mBAAmB,uBAAc,CAAC;AAC/C,eAAO,MAAM,qBAAqB,yBAAgB,CAAC;AACnD,eAAO,MAAM,uBAAuB,YAAgB,CAAC"}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Mermaid zoom-stage guardian (v2.5.12 / Task #2951).
|
|
3
|
+
*
|
|
4
|
+
* Why this module exists
|
|
5
|
+
* ----------------------
|
|
6
|
+
* The Mermaid controller (`public/mermaid-renderer.js`) wraps every
|
|
7
|
+
* freshly-rendered SVG in a `.mermaid-zoom-stage` div that carries
|
|
8
|
+
* the pan/zoom CSS transform and the pointer-drag handlers. Without
|
|
9
|
+
* that wrapper the user can neither pan nor zoom the lifecycle
|
|
10
|
+
* diagram.
|
|
11
|
+
*
|
|
12
|
+
* Mermaid's library auto-runs `mermaid.run({nodes})` once
|
|
13
|
+
* `startOnLoad: true` is set in `mermaid.initialize`. We DO set
|
|
14
|
+
* `startOnLoad: true` in the SSR template (server.ts line ~2041) so
|
|
15
|
+
* the initial paint works for hosts that don't ship our controller.
|
|
16
|
+
* The auto-runner scans the DOM for `.mermaid` elements that are not
|
|
17
|
+
* already marked `data-processed` and replaces their innerHTML with a
|
|
18
|
+
* freshly-rendered SVG.
|
|
19
|
+
*
|
|
20
|
+
* Even after our controller's `update()` has set `data-processed="true"`
|
|
21
|
+
* and wrapped the SVG, Mermaid's auto-runner fires roughly 1.5–3s
|
|
22
|
+
* later (observed via Playwright trace on 2026-08-12) and replaces
|
|
23
|
+
* the contents of the `.mermaid` element with a fresh, bare SVG. The
|
|
24
|
+
* bare SVG is not wrapped in `.mermaid-zoom-stage`, so the pan/zoom
|
|
25
|
+
* UI silently breaks for the rest of the page lifetime.
|
|
26
|
+
*
|
|
27
|
+
* What this module does
|
|
28
|
+
* ---------------------
|
|
29
|
+
* `ensureMermaidZoomStage(container)` — one-shot helper that walks
|
|
30
|
+
* the container and wraps any existing `<svg>` in a
|
|
31
|
+
* `.mermaid-zoom-stage` div. Idempotent: calling it twice keeps ONE
|
|
32
|
+
* wrapper.
|
|
33
|
+
*
|
|
34
|
+
* `MermaidZoomGuardian` — a long-lived `MutationObserver` that
|
|
35
|
+
* detects when something (Mermaid's late `mermaid.run()`, an SSE
|
|
36
|
+
* patch, etc.) replaces the SVG and re-applies the wrapper. The
|
|
37
|
+
* guardian stops observing after `stop()` is called.
|
|
38
|
+
*
|
|
39
|
+
* Both helpers are deliberately framework-free so they can be unit-
|
|
40
|
+
* tested in happy-dom / jsdom without a full browser.
|
|
41
|
+
*/
|
|
42
|
+
const STAGE_CLASS = "mermaid-zoom-stage";
|
|
43
|
+
const TOOLBAR_CLASS = "mermaid-zoom-toolbar";
|
|
44
|
+
const MERMAID_CLASS = "mermaid";
|
|
45
|
+
/**
|
|
46
|
+
* Find the SVG inside a container (one level deep — direct child
|
|
47
|
+
* OR nested inside another wrapper). Returns `null` when no SVG is
|
|
48
|
+
* present. Used by both `ensureMermaidZoomStage` and the
|
|
49
|
+
* `MermaidZoomGuardian`.
|
|
50
|
+
*/
|
|
51
|
+
function findSvg(container) {
|
|
52
|
+
return container.querySelector("svg");
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Wrap any existing SVG inside `container` in a single
|
|
56
|
+
* `.mermaid-zoom-stage` div. Idempotent.
|
|
57
|
+
*
|
|
58
|
+
* @returns the (possibly newly-created) stage element, or `null`
|
|
59
|
+
* when the container has no SVG to wrap.
|
|
60
|
+
*/
|
|
61
|
+
export function ensureMermaidZoomStage(container) {
|
|
62
|
+
if (!container || typeof container.querySelector !== "function")
|
|
63
|
+
return null;
|
|
64
|
+
// Already wrapped — return the existing stage. The caller may
|
|
65
|
+
// re-run this on every SSR update without inflating the DOM.
|
|
66
|
+
const existing = container.querySelector(`.${STAGE_CLASS}`);
|
|
67
|
+
if (existing)
|
|
68
|
+
return existing;
|
|
69
|
+
const svg = findSvg(container);
|
|
70
|
+
if (!svg)
|
|
71
|
+
return null;
|
|
72
|
+
const doc = container.ownerDocument;
|
|
73
|
+
const stage = doc.createElement("div");
|
|
74
|
+
stage.className = STAGE_CLASS;
|
|
75
|
+
// Reparent the SVG into the new stage. We use a DocumentFragment
|
|
76
|
+
// so a single DOM mutation swaps the child instead of two
|
|
77
|
+
// separate insert/remove operations.
|
|
78
|
+
const fragment = doc.createDocumentFragment
|
|
79
|
+
? doc.createDocumentFragment()
|
|
80
|
+
: null;
|
|
81
|
+
if (fragment) {
|
|
82
|
+
while (container.firstChild) {
|
|
83
|
+
fragment.appendChild(container.firstChild);
|
|
84
|
+
}
|
|
85
|
+
stage.appendChild(fragment);
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
while (container.firstChild) {
|
|
89
|
+
stage.appendChild(container.firstChild);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
container.appendChild(stage);
|
|
93
|
+
// Mark the stage so the controller / CSS picks it up. Mirrors
|
|
94
|
+
// `style.css` `.mermaid-zoom-stage` rules.
|
|
95
|
+
stage.setAttribute("data-mermaid-zoom-stage", "true");
|
|
96
|
+
return stage;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* v2.5.12 (Task #2951): the MermaidZoomGuardian watches a container
|
|
100
|
+
* and re-wraps any replacement SVG in `.mermaid-zoom-stage`. Use
|
|
101
|
+
* this for diagrams that survive past the initial render — e.g. the
|
|
102
|
+
* lifecycle mermaid on the per-task page, where Mermaid's late
|
|
103
|
+
* `mermaid.run()` otherwise destroys the wrapper.
|
|
104
|
+
*
|
|
105
|
+
* Lifecycle:
|
|
106
|
+
* const g = new MermaidZoomGuardian(container);
|
|
107
|
+
* g.start();
|
|
108
|
+
* // ...later, when the page is torn down:
|
|
109
|
+
* g.stop();
|
|
110
|
+
*/
|
|
111
|
+
export class MermaidZoomGuardian {
|
|
112
|
+
container;
|
|
113
|
+
observer = null;
|
|
114
|
+
scheduled = false;
|
|
115
|
+
constructor(container) {
|
|
116
|
+
this.container = container;
|
|
117
|
+
}
|
|
118
|
+
start() {
|
|
119
|
+
if (this.observer)
|
|
120
|
+
return; // idempotent
|
|
121
|
+
// First, wrap whatever is already there.
|
|
122
|
+
ensureMermaidZoomStage(this.container);
|
|
123
|
+
const doc = this.container.ownerDocument;
|
|
124
|
+
const Observer = typeof globalThis !== "undefined" && globalThis.MutationObserver
|
|
125
|
+
? globalThis.MutationObserver
|
|
126
|
+
: doc && doc.defaultView && doc.defaultView.MutationObserver;
|
|
127
|
+
if (typeof Observer !== "function")
|
|
128
|
+
return; // jsdom-less test env: skip
|
|
129
|
+
this.observer = new Observer((mutations) => {
|
|
130
|
+
// Coalesce: when Mermaid replaces innerHTML in one tick, we
|
|
131
|
+
// get several mutations. Schedule one re-wrap on the microtask
|
|
132
|
+
// queue so all of them see the same end state.
|
|
133
|
+
if (this.scheduled)
|
|
134
|
+
return;
|
|
135
|
+
for (const m of mutations) {
|
|
136
|
+
if (m.type !== "childList")
|
|
137
|
+
continue;
|
|
138
|
+
// Only react when children were added/removed from the
|
|
139
|
+
// container itself (not from descendants of the stage).
|
|
140
|
+
if (m.target !== this.container)
|
|
141
|
+
continue;
|
|
142
|
+
if (m.addedNodes.length === 0 && m.removedNodes.length === 0)
|
|
143
|
+
continue;
|
|
144
|
+
// If the change was a new stage being added, ignore.
|
|
145
|
+
for (let i = 0; i < m.addedNodes.length; i++) {
|
|
146
|
+
const n = m.addedNodes[i];
|
|
147
|
+
if (n && n.nodeType === 1 && n.classList && n.classList.contains(STAGE_CLASS)) {
|
|
148
|
+
return; // already a stage — no work to do
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
this.scheduled = true;
|
|
152
|
+
queueMicrotask(() => {
|
|
153
|
+
this.scheduled = false;
|
|
154
|
+
ensureMermaidZoomStage(this.container);
|
|
155
|
+
});
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
});
|
|
159
|
+
if (this.observer)
|
|
160
|
+
this.observer.observe(this.container, { childList: true });
|
|
161
|
+
}
|
|
162
|
+
stop() {
|
|
163
|
+
if (this.observer) {
|
|
164
|
+
this.observer.disconnect();
|
|
165
|
+
this.observer = null;
|
|
166
|
+
}
|
|
167
|
+
this.scheduled = false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Export the constants so tests can reference them without hardcoding.
|
|
172
|
+
*/
|
|
173
|
+
export const MERMAID_STAGE_CLASS = STAGE_CLASS;
|
|
174
|
+
export const MERMAID_TOOLBAR_CLASS = TOOLBAR_CLASS;
|
|
175
|
+
export const MERMAID_CONTAINER_CLASS = MERMAID_CLASS;
|
|
176
|
+
//# sourceMappingURL=mermaid-zoom-guardian.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mermaid-zoom-guardian.js","sourceRoot":"","sources":["../src/mermaid-zoom-guardian.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
CHANGED
|
@@ -36,21 +36,35 @@ import type { PluginEnvLike, TaskShowConfig } from "./types.js";
|
|
|
36
36
|
import { ToolCallCollector } from "./collector.js";
|
|
37
37
|
import { EventBus } from "./event-bus.js";
|
|
38
38
|
/**
|
|
39
|
-
* Optional
|
|
40
|
-
* stub
|
|
41
|
-
*
|
|
39
|
+
* Optional logger-like sink for {@link printStartBanner}. Tests inject a
|
|
40
|
+
* stub with `info` (and optionally `log`) to capture calls; production
|
|
41
|
+
* callers rely on the default plugin logger.
|
|
42
|
+
*
|
|
43
|
+
* v2.5.12 (Task #2961): the default sink is the plugin unified logger,
|
|
44
|
+
* NOT `console`. The banner writes to the log file by default and only
|
|
45
|
+
* surfaces on stdout/stderr when `setQuietMode(false)` is called.
|
|
42
46
|
*/
|
|
43
47
|
export type BannerLogger = {
|
|
44
|
-
log
|
|
48
|
+
log?: (msg: string) => void;
|
|
49
|
+
info?: (msg: string) => void;
|
|
45
50
|
};
|
|
46
51
|
/**
|
|
47
|
-
* Print the "🚀 task-show running at …"
|
|
52
|
+
* Print the "🚀 task-show running at …" URL.
|
|
53
|
+
*
|
|
54
|
+
* v2.5.12 (Task #2953): was gated behind `TASK_SHOW_DEBUG=1` to keep
|
|
55
|
+
* the banner out of stdout (the chat subprocess was capturing stdout
|
|
56
|
+
* and surfacing the URL as a chat-panel banner prefix).
|
|
57
|
+
*
|
|
58
|
+
* v2.5.12 (Task #2961): the gate is removed — the URL is emitted
|
|
59
|
+
* unconditionally through the plugin unified logger (default sink),
|
|
60
|
+
* which is quiet-by-default and writes to a per-category log file
|
|
61
|
+
* under `${XDG_DATA_HOME:-~/.local/share}/roy-agent/logs/`. The
|
|
62
|
+
* banner never touches `console.log` / `console.warn` / `console.error`
|
|
63
|
+
* unless an operator explicitly calls `setQuietMode(false)`. This is
|
|
64
|
+
* the user's "走日志系统,不污染 stdout/stderr" requirement.
|
|
48
65
|
*
|
|
49
|
-
* Exported (and parameterised on a logger sink) so tests can spy on
|
|
50
|
-
* output without monkey-patching the global `console.log`.
|
|
51
|
-
* intentionally bypasses the gated `info()` logger above — we want
|
|
52
|
-
* operators to see the URL on the main-agent stdout without setting
|
|
53
|
-
* `TASK_SHOW_DEBUG=1`.
|
|
66
|
+
* Exported (and parameterised on a logger sink) so tests can spy on
|
|
67
|
+
* the output without monkey-patching the global `console.log`.
|
|
54
68
|
*/
|
|
55
69
|
export declare function printStartBanner(lanHost: string, port: number, logger?: BannerLogger): void;
|
|
56
70
|
/**
|
package/dist/plugin.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH,OAAO,KAAK,EACV,aAAa,EAIb,cAAc,EAGf,MAAM,YAAY,CAAC;AAEpB,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|