@ai-setting/roy-plugin-task-show 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,22 +1,21 @@
1
1
  /**
2
- * @fileoverview Mutates a ToolResult output to append a visualization URL.
2
+ * @fileoverview URL builders for the visualization page.
3
3
  *
4
- * ## ⚠️ DEPRECATED as of v0.4.0
4
+ * ## ⚠️ DEPRECATED as of v0.5.0
5
5
  *
6
- * `injectVisualizationUrl()` mutates `result.output` in-place by appending a
7
- * markdown link. v0.4.0+ plugins should call `env.notify({type:"visualization_ready", ...})`
8
- * instead see `TaskShowPlugin.emitVisualizationReady()` in `src/plugin.ts`.
6
+ * This module used to also export `injectVisualizationUrl()` /
7
+ * `appendVisualizationBanner()` for mutating tool result output. Those
8
+ * helpers were removed in v0.5.0 the plugin no longer mutates tool
9
+ * result output. Reach-out happens via the SSE event stream broadcast
10
+ * by the local HTTP service.
9
11
  *
10
- * The mutation path is kept as a fallback for callers (e.g. custom test
11
- * harnesses or older hosts) that need to mutate a result directly. It will
12
- * be removed in v2.0.
12
+ * Only the pure URL builders remain. They are still used internally by
13
+ * the plugin (to compute `visualizationUrl` on each TaskSession) and may
14
+ * be useful for tests / custom callers that want to display the URL.
13
15
  *
14
- * The mutation itself is **non-destructive** — we never alter or trim the
15
- * original content, only append after a divider so LLM agents can still
16
- * parse the response.
17
- *
18
- * @deprecated since v0.4.0 — use `env.notify` (host) or
19
- * `TaskShowPlugin.emitVisualizationReady()` (plugin) instead.
16
+ * The mutation helpers (`injectVisualizationUrl`, `appendVisualizationBanner`)
17
+ * are gone in v0.5.0. If you depend on the old mutation behavior, pin to
18
+ * `roy-plugin-task-show@0.4.x`.
20
19
  */
21
20
  import type { TaskShowConfig } from "./types.js";
22
21
  /**
@@ -29,38 +28,4 @@ export declare function buildVisualizationUrl(cfg: Pick<TaskShowConfig, "host" |
29
28
  * mention "see all recent tasks" alongside a single URL).
30
29
  */
31
30
  export declare function buildIndexUrl(cfg: Pick<TaskShowConfig, "host" | "port">): string;
32
- /**
33
- * Result of an injection attempt — we want callers (especially tests) to be
34
- * able to verify whether a result was actually modified.
35
- */
36
- export interface InjectionResult {
37
- /** True iff the output text was actually mutated. */
38
- mutated: boolean;
39
- /** The final visualization URL we appended. */
40
- url?: string;
41
- /** The full output AFTER mutation. */
42
- output?: string;
43
- }
44
- /**
45
- * Append the visualization URL to a tool result.
46
- *
47
- * - The mutation only runs when `enabled` is true.
48
- * - The hook context shape is intentionally permissive (any) because the
49
- * ToolResult shape across versions can drift slightly. We only depend on
50
- * a string `output`.
51
- *
52
- * @deprecated since v0.4.0 — use `env.notify` (host) or
53
- * `TaskShowPlugin.emitVisualizationReady()` (plugin) instead. This
54
- * function will be removed in v2.0.
55
- */
56
- export declare function injectVisualizationUrl(opts: {
57
- ctx?: any;
58
- cfg: TaskShowConfig;
59
- taskId: number;
60
- }): InjectionResult;
61
- /**
62
- * Helper for tests / non-tool callers — given a raw string output, returns a
63
- * new string with the banner appended. Does not mutate the input.
64
- */
65
- export declare function appendVisualizationBanner(output: string, cfg: Pick<TaskShowConfig, "host" | "port">, taskId: number | string, extraLines?: string[]): string;
66
31
  //# sourceMappingURL=url-injector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-injector.d.ts","sourceRoot":"","sources":["../src/url-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,EAC1C,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,GACzC,MAAM,CAGR;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,qDAAqD;IACrD,OAAO,EAAE,OAAO,CAAC;IACjB,+CAA+C;IAC/C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC3C,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,GAAG,EAAE,cAAc,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;CAChB,GAAG,eAAe,CAyBlB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,EAC1C,MAAM,EAAE,MAAM,GAAG,MAAM,EACvB,UAAU,GAAE,MAAM,EAAO,GACxB,MAAM,CAMR"}
1
+ {"version":3,"file":"url-injector.d.ts","sourceRoot":"","sources":["../src/url-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAEjD;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,EAC1C,MAAM,EAAE,MAAM,GAAG,MAAM,GACtB,MAAM,CAIR;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,IAAI,CAAC,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC,GACzC,MAAM,CAGR"}
@@ -1,22 +1,21 @@
1
1
  /**
2
- * @fileoverview Mutates a ToolResult output to append a visualization URL.
2
+ * @fileoverview URL builders for the visualization page.
3
3
  *
4
- * ## ⚠️ DEPRECATED as of v0.4.0
4
+ * ## ⚠️ DEPRECATED as of v0.5.0
5
5
  *
6
- * `injectVisualizationUrl()` mutates `result.output` in-place by appending a
7
- * markdown link. v0.4.0+ plugins should call `env.notify({type:"visualization_ready", ...})`
8
- * instead see `TaskShowPlugin.emitVisualizationReady()` in `src/plugin.ts`.
6
+ * This module used to also export `injectVisualizationUrl()` /
7
+ * `appendVisualizationBanner()` for mutating tool result output. Those
8
+ * helpers were removed in v0.5.0 the plugin no longer mutates tool
9
+ * result output. Reach-out happens via the SSE event stream broadcast
10
+ * by the local HTTP service.
9
11
  *
10
- * The mutation path is kept as a fallback for callers (e.g. custom test
11
- * harnesses or older hosts) that need to mutate a result directly. It will
12
- * be removed in v2.0.
12
+ * Only the pure URL builders remain. They are still used internally by
13
+ * the plugin (to compute `visualizationUrl` on each TaskSession) and may
14
+ * be useful for tests / custom callers that want to display the URL.
13
15
  *
14
- * The mutation itself is **non-destructive** — we never alter or trim the
15
- * original content, only append after a divider so LLM agents can still
16
- * parse the response.
17
- *
18
- * @deprecated since v0.4.0 — use `env.notify` (host) or
19
- * `TaskShowPlugin.emitVisualizationReady()` (plugin) instead.
16
+ * The mutation helpers (`injectVisualizationUrl`, `appendVisualizationBanner`)
17
+ * are gone in v0.5.0. If you depend on the old mutation behavior, pin to
18
+ * `roy-plugin-task-show@0.4.x`.
20
19
  */
21
20
  /**
22
21
  * Build the public URL the visualization lives at. Exposed so that unit tests
@@ -35,48 +34,4 @@ export function buildIndexUrl(cfg) {
35
34
  const host = cfg.host === "0.0.0.0" ? "localhost" : cfg.host;
36
35
  return `http://${host}:${cfg.port}/`;
37
36
  }
38
- /**
39
- * Append the visualization URL to a tool result.
40
- *
41
- * - The mutation only runs when `enabled` is true.
42
- * - The hook context shape is intentionally permissive (any) because the
43
- * ToolResult shape across versions can drift slightly. We only depend on
44
- * a string `output`.
45
- *
46
- * @deprecated since v0.4.0 — use `env.notify` (host) or
47
- * `TaskShowPlugin.emitVisualizationReady()` (plugin) instead. This
48
- * function will be removed in v2.0.
49
- */
50
- export function injectVisualizationUrl(opts) {
51
- const { ctx, cfg, taskId } = opts;
52
- if (!cfg.urlInjectEnabled)
53
- return { mutated: false };
54
- if (!ctx)
55
- return { mutated: false };
56
- const result = ctx?.result ?? ctx?.toolResult ?? null;
57
- if (!result || typeof result.output !== "string") {
58
- return { mutated: false };
59
- }
60
- const url = buildVisualizationUrl(cfg, taskId);
61
- const banner = `\n\n---\n📊 **可视化工具调用链路**: <${url}>\n` +
62
- `(浏览器访问即可查看 mermaid 流程图:每个工具调用、参数、结果摘要、耗时)`;
63
- const newOutput = result.output + banner;
64
- result.output = newOutput;
65
- // Make sure the URL is also recorded in metadata — some chat clients
66
- // prefer to render markdown from a structured field.
67
- if (typeof result.metadata === "object" && result.metadata !== null) {
68
- result.metadata.task_visualization_url = url;
69
- }
70
- return { mutated: true, url, output: newOutput };
71
- }
72
- /**
73
- * Helper for tests / non-tool callers — given a raw string output, returns a
74
- * new string with the banner appended. Does not mutate the input.
75
- */
76
- export function appendVisualizationBanner(output, cfg, taskId, extraLines = []) {
77
- const url = buildVisualizationUrl(cfg, taskId);
78
- const banner = `\n\n---\n📊 **可视化工具调用链路**: <${url}>` +
79
- (extraLines.length ? "\n" + extraLines.map((l) => `> ${l}`).join("\n") : "");
80
- return output + banner;
81
- }
82
37
  //# sourceMappingURL=url-injector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"url-injector.js","sourceRoot":"","sources":["../src/url-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAIH;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAA0C,EAC1C,MAAuB;IAEvB,qDAAqD;IACrD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC7D,OAAO,UAAU,IAAI,IAAI,GAAG,CAAC,IAAI,SAAS,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,GAA0C;IAE1C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC7D,OAAO,UAAU,IAAI,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC;AACvC,CAAC;AAeD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAItC;IACC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC;IAElC,IAAI,CAAC,GAAG,CAAC,gBAAgB;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IACrD,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAEpC,MAAM,MAAM,GAAG,GAAG,EAAE,MAAM,IAAI,GAAG,EAAE,UAAU,IAAI,IAAI,CAAC;IACtD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACjD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,MAAM,GAAG,GAAG,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,MAAM,GACV,+BAA+B,GAAG,KAAK;QACvC,2CAA2C,CAAC;IAC9C,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;IACzC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC;IAE1B,qEAAqE;IACrE,qDAAqD;IACrD,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,IAAI,EAAE,CAAC;QACnE,MAAM,CAAC,QAAoC,CAAC,sBAAsB,GAAG,GAAG,CAAC;IAC5E,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;AACnD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,MAAc,EACd,GAA0C,EAC1C,MAAuB,EACvB,aAAuB,EAAE;IAEzB,MAAM,GAAG,GAAG,qBAAqB,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;IAC/C,MAAM,MAAM,GACV,+BAA+B,GAAG,GAAG;QACrC,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/E,OAAO,MAAM,GAAG,MAAM,CAAC;AACzB,CAAC"}
1
+ {"version":3,"file":"url-injector.js","sourceRoot":"","sources":["../src/url-injector.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAIH;;;GAGG;AACH,MAAM,UAAU,qBAAqB,CACnC,GAA0C,EAC1C,MAAuB;IAEvB,qDAAqD;IACrD,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC7D,OAAO,UAAU,IAAI,IAAI,GAAG,CAAC,IAAI,SAAS,kBAAkB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC;AACjF,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAC3B,GAA0C;IAE1C,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC;IAC7D,OAAO,UAAU,IAAI,IAAI,GAAG,CAAC,IAAI,GAAG,CAAC;AACvC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-plugin-task-show",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "roy-agent plugin: visualize task solving process via tool call flow on a local web service",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/plugin.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-plugin-task-show",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "type": "tool-plugin",
5
- "description": "Visualize the tool call chain of a task on a local web service and notify via env.notify. v0.4.0+: env.notify({type:\"visualization_ready\"}) on terminal status (preferred). Subscribes to tool:before.execute (for self-managed timing), tool:after.execute, task:after.complete (preferred, 2026-07-10+) and task:after.update (legacy fallback).",
5
+ "description": "Visualize the tool call chain of a task on a local web service with real-time SSE updates. v0.5.0+: page refreshes stream over GET /api/events (Server-Sent Events). Subscribes to tool:before.execute, tool:after.execute, task:before.create, task:after.create, task:after.complete (preferred, 2026-07-10+), and task:after.update (legacy fallback).",
6
6
  "main": "dist/index.js",
7
7
  "hooks": [
8
8
  {
@@ -11,15 +11,23 @@
11
11
  },
12
12
  {
13
13
  "point": "tool:after.execute",
14
- "purpose": "Collect every tool invocation: tool name, args, result, timing, success"
14
+ "purpose": "Collect every tool invocation: tool name, args, result, timing, success. Broadcasts a `tool.recorded` SSE event so the frontend timeline + progress bar update live."
15
+ },
16
+ {
17
+ "point": "task:before.create",
18
+ "purpose": "Open a fresh TaskSession before the task runs (v0.5.0+). Mints the visualization URL and broadcasts a `task.created` SSE event so the UI can render the card immediately, even if no tool call fires."
19
+ },
20
+ {
21
+ "point": "task:after.create",
22
+ "purpose": "Mark the session ready for tracking (v0.5.0+). For hosts that emit only this hook (no `task:before.create`), the plugin opens the session here. Broadcasts a `task.created` SSE event when the session is newly minted."
15
23
  },
16
24
  {
17
25
  "point": "task:after.complete",
18
- "purpose": "PREFERRED hook point (roy-agent 2026-07-10+). When a task transitions to a terminal status (completed/failed/cancelled/timeout), finalize the session and emit a `visualization_ready` notification via `env.notify`. terminalStatus field is explicit — no status filtering required. The URL is delivered through the host's NotificationChannel pipeline (default: EventBusNotificationChannel) instead of mutating tool result output."
26
+ "purpose": "PREFERRED hook point (roy-agent 2026-07-10+). When a task transitions to a terminal status (completed/failed/cancelled), finalize the session and broadcast a `task.completed` SSE event. terminalStatus field is explicit — no status filtering required. The handler dedupes against any `task:after.update` that may also fire on the same transition."
19
27
  },
20
28
  {
21
29
  "point": "task:after.update",
22
- "purpose": "LEGACY fallback. Hosts predating the AFTER_COMPLETE hook point only expose AFTER_UPDATE; the plugin filters for terminal status internally and dedupes against any AFTER_COMPLETE that might also fire on the new code path."
30
+ "purpose": "GENERIC status update hook (v0.5.0+). Used for non-terminal transitions (running → paused → running) AND as a legacy fallback for hosts predating the AFTER_COMPLETE hook point. Broadcasts `task.updated` for non-terminal status, `task.completed` for terminal status. The internal dedup set guarantees at most one terminal broadcast per task even if both hooks fire."
23
31
  }
24
32
  ],
25
33
  "commands": [
@@ -49,17 +57,31 @@
49
57
  "default": 50,
50
58
  "description": "Maximum number of completed tasks to keep in memory (older ones are evicted)"
51
59
  },
52
- "urlInjectEnabled": {
53
- "type": "boolean",
54
- "default": false,
55
- "description": "DEPRECATED (v0.4.0+). Append a 📊 visualization URL to the last tool result when a task completes. The plugin no longer mutates tool result output by default — use env.notify instead. Set to true only for legacy hosts that pre-date NotificationChannel."
56
- },
57
60
  "publicDir": {
58
61
  "type": "string",
59
62
  "default": "public",
60
63
  "description": "Directory holding the static visualization frontend (HTML/JS/CSS)"
61
64
  }
62
65
  },
66
+ "endpoints": {
67
+ "index": "GET / — index of recent task sessions",
68
+ "taskDetail": "GET /task/:taskId — detail page (mermaid flow + tables)",
69
+ "apiSessions": "GET /api/sessions — JSON list of sessions",
70
+ "apiSessionDetail": "GET /api/sessions/:taskId — JSON detail of one session",
71
+ "apiEvents": "GET /api/events — Server-Sent Events stream (real-time push)",
72
+ "static": "GET /static/* — static frontend assets (CSS/JS)"
73
+ },
74
+ "sse": {
75
+ "events": [
76
+ "snapshot — initial state dump on connect",
77
+ "task.created — new task session opened",
78
+ "task.updated — non-terminal status change",
79
+ "task.completed — task transitioned to a terminal status",
80
+ "tool.recorded — tool call appended to a session"
81
+ ],
82
+ "heartbeatMs": 15000,
83
+ "snapshotFrame": "event: snapshot\ndata: {type:'snapshot', data:{sessions:[...]}}\n\n"
84
+ },
63
85
  "roy-agent": {
64
86
  "minVersion": "1.6.0",
65
87
  "extends": "BasePlugin",
@@ -67,4 +89,4 @@
67
89
  },
68
90
  "repository": "github:ai-setting/roy-plugin-task-visualize",
69
91
  "bugs": "https://github.com/ai-setting/roy-plugin-task-visualize/issues"
70
- }
92
+ }