@ai-setting/roy-plugin-task-show 0.8.9 → 0.8.10

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 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js CHANGED
@@ -12,6 +12,11 @@
12
12
  * v0.5.0+: SSE replaces the previous `env.notify` mechanism. URL injection
13
13
  * is no longer supported — visualization reach-out is via the SSE event
14
14
  * stream broadcast by the local HTTP service.
15
+ *
16
+ * v0.8.10+: Heap-bounded defaults (Task #2537). `pendingStartTtlMs`,
17
+ * `operationsCacheMaxEntries`, `tasksTreeCacheMaxEntries`, and
18
+ * `maxFinalizedTaskIds` keep the plugin's in-memory Maps and Sets
19
+ * bounded so a long-lived CLI session cannot OOM at 4 GiB V8 heap.
15
20
  */
16
21
  export const DEFAULT_CONFIG = {
17
22
  port: 7788,
@@ -19,6 +24,10 @@ export const DEFAULT_CONFIG = {
19
24
  autoStart: true,
20
25
  maxStoredTasks: 50,
21
26
  publicDir: "public",
27
+ operationsCacheMaxEntries: 256,
28
+ tasksTreeCacheMaxEntries: 64,
29
+ pendingStartTtlMs: 60_000,
30
+ maxFinalizedTaskIds: 4096,
22
31
  };
23
32
  /**
24
33
  * Heartbeat interval (ms) — sent as a `:keep-alive` SSE comment so reverse
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA+GH;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,EAAE;IAClB,SAAS,EAAE,QAAQ;CACpB,CAAC;AAgFF;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAsIH;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,cAAc,GAAmB;IAC5C,IAAI,EAAE,IAAI;IACV,IAAI,EAAE,SAAS;IACf,SAAS,EAAE,IAAI;IACf,cAAc,EAAE,EAAE;IAClB,SAAS,EAAE,QAAQ;IACnB,yBAAyB,EAAE,GAAG;IAC9B,wBAAwB,EAAE,EAAE;IAC5B,iBAAiB,EAAE,MAAM;IACzB,mBAAmB,EAAE,IAAI;CAC1B,CAAC;AAgFF;;;;GAIG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,KAAK,CAAC;AAE/C;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,iBAAiB,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-plugin-task-show",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
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",
@@ -20,7 +20,9 @@
20
20
  "start:demo": "bun run scripts/run-demo.ts",
21
21
  "verify": "bun run scripts/verify-service.ts",
22
22
  "verify:installed": "bun run scripts/verify-installed.ts",
23
- "verify:published": "bun run scripts/verify-published.ts"
23
+ "verify:published": "bun run scripts/verify-published.ts",
24
+ "verify:heap": "bun run scripts/verify-heap-bounded.ts",
25
+ "stress:heap": "bun --expose-gc run scripts/stress-heap.ts"
24
26
  },
25
27
  "keywords": [
26
28
  "roy-agent",
package/plugin.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@ai-setting/roy-plugin-task-show",
3
- "version": "0.8.9",
3
+ "version": "0.8.10",
4
4
  "type": "tool-plugin",
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). v0.6.11: Mermaid re-rendering is delegated to a self-contained controller (public/mermaid-renderer.js) that prevents the SVG→raw-source regression on async updates and surfaces recoverable .mermaid-error states. v0.6.12: Task lifecycle pipeline (operations timeline) server now emits data-task-id on the pipeline section; client preserves it on swap, so the page actually fetches /api/tasks/<id>/operations and renders the 7-op timeline (previously silently bailed). v0.7.0: Home page redesigned as a hierarchical task tree (driven by `roy-agent tasks tree --json`); new /api/tasks/tree endpoint with status / priority / type / root-id filters, expand/collapse UI, search, and live 30s polling. v0.8.0: per-task page Mermaid area now renders the hierarchical 'Task lifecycle + tools' view — each operation record owns a subgraph that nests its tool calls, with click callbacks (`window.__toolClick`) that scroll-into-view + highlight + auto-expand the matching row in the tool-call table below. Operation record descriptions (`description` + `processDescription`) are now always rendered inline (no `<details>` collapse) so the user sees the lifecycle state at a glance; a fallback `<details>` kicks in only for descriptions longer than 600 chars. v0.8.1: hotfix for two pre-existing bugs in v0.8.0 (browser smoke test surfaced after merge). (a) Mermaid click directives were emitted as `click t1 __toolClick(1)` (missing `call` keyword) — Mermaid 10's parser rejects this with `got 'PS'`. Fixed to `click t1 call __toolClick(1)` (the v10 grammar requires `call` to invoke a callback with arguments). (b) `buildMermaidSource` lived inside the `attachTaskPageTimeline` IIFE but was also called from a listener in the `attachToolClickBridge` IIFE — sibling IIFEs cannot see each other's locals, so the listener threw `ReferenceError: buildMermaidSource is not defined` and the Mermaid diagram silently failed to re-render after `task-show:lifecycle-ops-loaded`. Fixed by hoisting the function (and its three helpers) to script top-level so both IIFEs can see it via the script-wide closure; the function is also exposed on `window.buildMermaidSource` for tests + tooling. v0.8.3: tree-display fix (Task #2426). The home page used to look like a flat list of root tasks because `autoExpandFirstLevels(..., 2)` only opened the first 2 levels — 30/47 roots were leaf nodes and the remaining 17 collapsed to one level so grandchildren were never visible. Default expand depth is now 3 (root + child + grandchild + great-grandchild are visible on first paint), the summary line now shows per-depth count pills (root / child / grandchild / great-grandchild / level-N), each `tree-row` carries a `data-depth` attribute so CSS can paint coloured left rails per level, and the duplicated 'Live tool-call sessions (legacy view)' panel that made the page look like both a flat table AND a tree is now hidden behind `#legacy-sessions[hidden]` (kept for future debug-toggle restoration). v0.8.4: cli-eacces-compat hotfix (Task #2499). The CLI bundle `packages/cli/dist/bin/roy-agent.js` ships with `-rw-rw-r--` (no execute bit); the plugin now invokes `roy-agent` via `node <path>` from the resolved CLI path so EACCES is avoided even when the script lacks the executable bit. Resolution order: explicit `cfg.royAgentCliPath` override `$ROY_AGENT_CLI` env sibling-repo .js monorepo .js → bare `roy-agent` (PATH). v0.8.5: CLI resolution priority fix. v0.8.4's resolution order preferred sibling-repo / monorepo `.js` files over the globally-installed `roy-agent` binary, which meant stale scripts in a sibling checkout could shadow a freshly-updated global install. v0.8.5 flips the order: explicit override → `$ROY_AGENT_CLI` env → **`roy-agent` on PATH** (looked up via `which`/`where`) sibling-repo .js (dev) monorepo .js (dev) → literal `roy-agent`. The lookup is exported as a free function `resolveRoyAgentCliPath()` (plus a `findRoyAgentOnPath()` helper) so the new priority order can be unit-tested in isolation. v0.8.7: home page redesigned around a process-scoped ancestor chain. The plugin now records every `task:after.create` payload into a `TaskSessionStore`, exposes it via a new `/api/tasks/ancestor-chain?leafId=N` endpoint, and renders the home page in a fixed top-to-bottom order: (1) ancestor chain — root leaf, each link tagged with its parent_task_id and status, (2) Task lifecycle + tools — Mermaid diagram of the leaf's tool calls, (3) Task lifecycle pipeline — operations timeline placeholder, (4) a help/legend section that intentionally follows the pipeline so the pipeline is never the trailing element. When no leaf has been recorded yet, the home page falls back to the v0.8.x cross-host tasks tree so the page is never blank. v0.8.8: home page is now a task-list view (click-to-detail). The home page renders ONLY the ancestor chain; every chain item (root → leaf, leaf included) is a clickable link to /task/<id>. The Mermaid lifecycle diagram, the operations pipeline, the tool-calls table, and the raw JSON dump all live on the per-task detail page; the home page no longer loads mermaid.js or initialises the Mermaid renderer. The leaf is no longer special-cased as <strong> (it was a 'current view' marker in v0.8.7) v0.8.8 promotes it to <a href='/task/<id>'> so the leaf is reachable via click, matching the rest of the chain. v0.8.9: home page ancestor chain rewritten as a real nested <ul>/<li> tree (24px indent per level via CSS, root/parent/→ text markers removed); detail page lifecycle pipeline section moved to immediately follow the Mermaid lifecycle diagram (was after the tool-call stats and tool calls table); extractJsonEnvelope hardened to a balanced-brace scanner so trailing CLI/plugin lifecycle log lines no longer break the JSON envelope and the /api/tasks/<id>/operations endpoint stops reporting cli_failed for normal CLI runs.",
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). v0.6.11: Mermaid re-rendering is delegated to a self-contained controller (public/mermaid-renderer.js) that prevents the SVG→raw-source regression on async updates and surfaces recoverable .mermaid-error states. v0.6.12: Task lifecycle pipeline (operations timeline) server now emits data-task-id on the pipeline section; client preserves it on swap, so the page actually fetches /api/tasks/<id>/operations and renders the 7-op timeline (previously silently bailed). v0.7.0: Home page redesigned as a hierarchical task tree (driven by `roy-agent tasks tree --json`); new /api/tasks/tree endpoint with status / priority / type / root-id filters, expand/collapse UI, search, and live 30s polling. v0.8.0: per-task page Mermaid area now renders the hierarchical 'Task lifecycle + tools' view — each operation record owns a subgraph that nests its tool calls, with click callbacks (`window.__toolClick`) that scroll-into-view + highlight + auto-expand the matching row in the tool-call table below. Operation record descriptions (`description` + `processDescription`) are now always rendered inline (no `<details>` collapse) so the user sees the lifecycle state at a glance; a fallback `<details>` kicks in only for descriptions longer than 600 chars. v0.8.1: hotfix for two pre-existing bugs in v0.8.0 (browser smoke test surfaced after merge). (a) Mermaid click directives were emitted as `click t1 __toolClick(1)` (missing `call` keyword) — Mermaid 10's parser rejects this with `got 'PS'`. Fixed to `click t1 call __toolClick(1)` (the v10 grammar requires `call` to invoke a callback with arguments). (b) `buildMermaidSource` lived inside the `attachTaskPageTimeline` IIFE but was also called from a listener in the `attachToolClickBridge` IIFE — sibling IIFEs cannot see each other's locals, so the listener threw `ReferenceError: buildMermaidSource is not defined` and the Mermaid diagram silently failed to re-render after `task-show:lifecycle-ops-loaded`. Fixed by hoisting the function (and its three helpers) to script top-level so both IIFEs can see it via the script-wide closure; the function is also exposed on `window.buildMermaidSource` for tests + tooling. v0.8.3: tree-display fix (Task #2426). The home page used to look like a flat list of root tasks because `autoExpandFirstLevels(..., 2)` only opened the first 2 levels — 30/47 roots were leaf nodes and the remaining 17 collapsed to one level so grandchildren were never visible. Default expand depth is now 3 (root + child + grandchild + great-grandchild are visible on first paint), the summary line now shows per-depth count pills (root / child / grandchild / great-grandchild / level-N), each `tree-row` carries a `data-depth` attribute so CSS can paint coloured left rails per level, and the duplicated 'Live tool-call sessions (legacy view)' panel that made the page look like both a flat table AND a tree is now hidden behind `#legacy-sessions[hidden]` (kept for future debug-toggle restoration). v0.8.10: bug-fix release (Task #2537 + Task #2534). (a) Heap-bounded plugin caches: OperationsCache and TasksTreeCache now enforce a hard maxEntries cap (default 256 / 64). Oldest stale entries are evicted before inserting a new one, so long-lived roy-agent sessions (BackgroundTaskManager + MemorySessionStore) no longer leak Map entries through the plugin's per-task caches see Task #2537 for the heap-unbounded-state REDGREEN repro. (b) Mermaid CJK font-family: server.ts renderTaskPage now configures mermaid.initialize({ themeVariables: { fontFamily: '\"PingFang SC\", \"Microsoft YaHei\", \"Noto Sans CJK SC\", \"Source Han Sans CN\", \"WenQuanYi Micro Hei\", sans-serif' } }) so Chinese node labels render correctly in browsers that have at least one of those fonts installed (see Task #2534).",
6
6
  "main": "dist/index.js",
7
7
  "hooks": [
8
8
  {
package/public/style.css CHANGED
@@ -1027,48 +1027,3 @@ details summary {
1027
1027
  border: 1px solid rgba(148, 163, 184, 0.4);
1028
1028
  }
1029
1029
 
1030
-
1031
-
1032
- /* ---------- v0.8.9: nested ancestor-chain tree ----------
1033
- *
1034
- * The home page renders the ancestor chain as a real nested HTML
1035
- * tree (ul > li > ul > li …). Indent each level by 24px so the
1036
- * hierarchy is communicated visually. We reset the default
1037
- * <ul>/<li> browser margins and supply our own so the visual
1038
- * rhythm is consistent across browsers.
1039
- *
1040
- * Why 24px and not 16px/20px? It lines up with our 12px base font
1041
- * (24 = 2× base) and gives a comfortable step without making the
1042
- * leaf feel cramped on 13"-class laptop screens.
1043
- */
1044
- .chain-list {
1045
- list-style: none;
1046
- margin: 0;
1047
- padding-left: 0;
1048
- }
1049
- .chain-list .chain-list {
1050
- margin-top: 4px;
1051
- margin-bottom: 4px;
1052
- padding-left: 24px;
1053
- border-left: 1px dashed rgba(148, 163, 184, 0.25);
1054
- }
1055
- .chain-node {
1056
- list-style: none;
1057
- margin: 4px 0;
1058
- padding: 2px 0;
1059
- line-height: 1.4;
1060
- }
1061
- .chain-node > .chain-link {
1062
- display: inline-block;
1063
- padding: 2px 6px;
1064
- border-radius: 4px;
1065
- transition: background 0.15s;
1066
- }
1067
- .chain-node > .chain-link:hover {
1068
- background: rgba(56, 189, 248, 0.10);
1069
- text-decoration: none;
1070
- }
1071
- .chain-node[data-depth="0"] > .chain-link {
1072
- font-weight: 600;
1073
- color: #e6eefc;
1074
- }
@@ -1,109 +0,0 @@
1
- /**
2
- * @fileoverview TaskSessionStore — process-scoped registry of tasks
3
- * observed through the `task:after.create` hook.
4
- *
5
- * v0.8.7 introduced this store so the home page can render an
6
- * *ancestor chain* (the latest "leaf" task plus the chain of
7
- * `parent_task_id` links up to the root) instead of the full
8
- * cross-host task tree. Tracking only this-process tasks also keeps
9
- * the home page quiet until the plugin actually does work, which
10
- * makes the visualization a more accurate reflection of what the
11
- * agent is doing right now.
12
- *
13
- * Design notes:
14
- * - Pure in-memory; no I/O, no globals. The plugin owns a single
15
- * instance and disposes it via {@link TaskSessionStore.clear} when
16
- * the plugin is torn down.
17
- * - The fetcher for parent tasks is **injected** so tests can mock
18
- * the CLI call without spawning a real subprocess.
19
- * - The store is tolerant: a broken parent link, a cycle, or a
20
- * missing fetcher all degrade gracefully (the chain stops at the
21
- * first unverifiable link rather than throwing).
22
- * - `buildAncestorChain` always returns tasks in **root-first** order
23
- * (`[root, …, leaf]`) so the UI can render the chain linearly
24
- * from top to bottom without having to reverse it.
25
- */
26
- /**
27
- * Minimal task metadata shape we track. Mirrors the subset of the
28
- * CLI's `tasks get` payload we actually use.
29
- */
30
- export interface TaskMetaLike {
31
- id: number;
32
- title: string;
33
- status?: string;
34
- priority?: string;
35
- type?: string;
36
- /** Parent task id; `null` for root tasks. */
37
- parent_task_id: number | null | undefined;
38
- createdAt?: string;
39
- updatedAt?: string;
40
- tags?: string[];
41
- projectPath?: string;
42
- }
43
- /** Function used to fetch a task's metadata by id (CLI-backed). */
44
- export type TaskMetaFetcher = (id: number) => Promise<TaskMetaLike | null>;
45
- /** Options for {@link TaskSessionStore.buildAncestorChain}. */
46
- export interface BuildAncestorChainOptions {
47
- /**
48
- * Hard cap on chain length to protect against pathological trees
49
- * (cycles, broken parent links, runaway depth). Default 32.
50
- */
51
- maxDepth?: number;
52
- }
53
- /**
54
- * Process-scoped registry of tasks observed via the
55
- * `task:after.create` hook.
56
- */
57
- export declare class TaskSessionStore {
58
- /** In-memory metadata, keyed by task id. */
59
- private readonly tasks;
60
- /** Insertion order (Map preserves it). We keep a snapshot for tests. */
61
- private readonly insertionOrder;
62
- /**
63
- * Record a task. Re-recording an existing id overwrites the cached
64
- * metadata (this is the contract: the latest hook payload wins).
65
- */
66
- record(task: TaskMetaLike): void;
67
- /** Return the most recently recorded task id, or `null` if empty. */
68
- getLatestLeafId(): number | null;
69
- /** Return the cached metadata for `id`, or `null` if unknown. */
70
- getRecordedTask(id: number): TaskMetaLike | null;
71
- /** Return the recorded task ids in insertion order. */
72
- getRecordedTaskIds(): number[];
73
- /** Drop everything. Used by tests + on plugin disposal. */
74
- clear(): void;
75
- /**
76
- * Walk `parent_task_id` from `leafId` up to the root, using
77
- * `fetcher` to resolve any ancestors not already in the in-memory
78
- * cache. Returns the chain in **root-first** order
79
- * (`[root, …, leaf]`).
80
- *
81
- * Guarantees:
82
- * - Always returns at least the leaf task if the leaf is known
83
- * (from cache or via fetcher).
84
- * - Cycle-safe: a task already in the chain stops the walk.
85
- * - Depth-bounded by `options.maxDepth` (default 32).
86
- * - Never throws: a broken parent link just ends the chain early.
87
- */
88
- buildAncestorChain(leafId: number, fetcher: TaskMetaFetcher, options?: BuildAncestorChainOptions): Promise<TaskMetaLike[]>;
89
- }
90
- /**
91
- * Build a {@link TaskMetaFetcher} that shells out to the host's
92
- * `roy-agent` CLI. Intended for production use; tests should pass a
93
- * stub.
94
- *
95
- * args: [cliPath, "tasks", "get", "<id>", "--json"]
96
- * stdout: { task: { id, title, status, priority, type,
97
- * parent_task_id, createdAt, updatedAt, tags,
98
- * project_path }, ... }
99
- *
100
- * The returned fetcher:
101
- * - Spawns the CLI as a discrete arg array (no shell string).
102
- * - Enforces a 5-second wall-clock timeout.
103
- * - Locates the first `{` in stdout (the CLI prints INFO lines
104
- * before the JSON envelope).
105
- * - Returns `null` on any failure (non-zero exit, timeout, parse
106
- * error, schema mismatch).
107
- */
108
- export declare function makeCliTaskMetaFetcher(cliPath: string): TaskMetaFetcher;
109
- //# sourceMappingURL=task-session-store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-session-store.d.ts","sourceRoot":"","sources":["../src/task-session-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAWH;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,mEAAmE;AACnE,MAAM,MAAM,eAAe,GAAG,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,GAAG,IAAI,CAAC,CAAC;AAE3E,+DAA+D;AAC/D,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;;GAGG;AACH,qBAAa,gBAAgB;IAC3B,4CAA4C;IAC5C,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IACzD,wEAAwE;IACxE,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAgB;IAE/C;;;OAGG;IACH,MAAM,CAAC,IAAI,EAAE,YAAY,GAAG,IAAI;IAOhC,qEAAqE;IACrE,eAAe,IAAI,MAAM,GAAG,IAAI;IAKhC,iEAAiE;IACjE,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAIhD,uDAAuD;IACvD,kBAAkB,IAAI,MAAM,EAAE;IAI9B,2DAA2D;IAC3D,KAAK,IAAI,IAAI;IAKb;;;;;;;;;;;;OAYG;IACG,kBAAkB,CACtB,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,eAAe,EACxB,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAAC,YAAY,EAAE,CAAC;CA4B3B;AAmBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe,CAuCvE"}
@@ -1,193 +0,0 @@
1
- /**
2
- * @fileoverview TaskSessionStore — process-scoped registry of tasks
3
- * observed through the `task:after.create` hook.
4
- *
5
- * v0.8.7 introduced this store so the home page can render an
6
- * *ancestor chain* (the latest "leaf" task plus the chain of
7
- * `parent_task_id` links up to the root) instead of the full
8
- * cross-host task tree. Tracking only this-process tasks also keeps
9
- * the home page quiet until the plugin actually does work, which
10
- * makes the visualization a more accurate reflection of what the
11
- * agent is doing right now.
12
- *
13
- * Design notes:
14
- * - Pure in-memory; no I/O, no globals. The plugin owns a single
15
- * instance and disposes it via {@link TaskSessionStore.clear} when
16
- * the plugin is torn down.
17
- * - The fetcher for parent tasks is **injected** so tests can mock
18
- * the CLI call without spawning a real subprocess.
19
- * - The store is tolerant: a broken parent link, a cycle, or a
20
- * missing fetcher all degrade gracefully (the chain stops at the
21
- * first unverifiable link rather than throwing).
22
- * - `buildAncestorChain` always returns tasks in **root-first** order
23
- * (`[root, …, leaf]`) so the UI can render the chain linearly
24
- * from top to bottom without having to reverse it.
25
- */
26
- import { execFile } from "node:child_process";
27
- import { promisify } from "node:util";
28
- const execFileAsync = promisify(execFile);
29
- // ---------------------------------------------------------------------------
30
- // Store
31
- // ---------------------------------------------------------------------------
32
- /**
33
- * Process-scoped registry of tasks observed via the
34
- * `task:after.create` hook.
35
- */
36
- export class TaskSessionStore {
37
- /** In-memory metadata, keyed by task id. */
38
- tasks = new Map();
39
- /** Insertion order (Map preserves it). We keep a snapshot for tests. */
40
- insertionOrder = [];
41
- /**
42
- * Record a task. Re-recording an existing id overwrites the cached
43
- * metadata (this is the contract: the latest hook payload wins).
44
- */
45
- record(task) {
46
- if (!Number.isFinite(task.id) || task.id <= 0)
47
- return;
48
- const isNew = !this.tasks.has(task.id);
49
- this.tasks.set(task.id, { ...task });
50
- if (isNew)
51
- this.insertionOrder.push(task.id);
52
- }
53
- /** Return the most recently recorded task id, or `null` if empty. */
54
- getLatestLeafId() {
55
- if (this.insertionOrder.length === 0)
56
- return null;
57
- return this.insertionOrder[this.insertionOrder.length - 1] ?? null;
58
- }
59
- /** Return the cached metadata for `id`, or `null` if unknown. */
60
- getRecordedTask(id) {
61
- return this.tasks.get(id) ?? null;
62
- }
63
- /** Return the recorded task ids in insertion order. */
64
- getRecordedTaskIds() {
65
- return [...this.insertionOrder];
66
- }
67
- /** Drop everything. Used by tests + on plugin disposal. */
68
- clear() {
69
- this.tasks.clear();
70
- this.insertionOrder.length = 0;
71
- }
72
- /**
73
- * Walk `parent_task_id` from `leafId` up to the root, using
74
- * `fetcher` to resolve any ancestors not already in the in-memory
75
- * cache. Returns the chain in **root-first** order
76
- * (`[root, …, leaf]`).
77
- *
78
- * Guarantees:
79
- * - Always returns at least the leaf task if the leaf is known
80
- * (from cache or via fetcher).
81
- * - Cycle-safe: a task already in the chain stops the walk.
82
- * - Depth-bounded by `options.maxDepth` (default 32).
83
- * - Never throws: a broken parent link just ends the chain early.
84
- */
85
- async buildAncestorChain(leafId, fetcher, options = {}) {
86
- if (!Number.isFinite(leafId) || leafId <= 0)
87
- return [];
88
- const maxDepth = Math.max(1, options.maxDepth ?? 32);
89
- // Walk leaf → root, then reverse at the end. We collect into an
90
- // array in walk order so cycles / missing ancestors are easy to
91
- // detect.
92
- const walked = [];
93
- const seen = new Set();
94
- let currentId = leafId;
95
- for (let depth = 0; depth < maxDepth; depth++) {
96
- if (seen.has(currentId))
97
- break;
98
- seen.add(currentId);
99
- const cached = this.tasks.get(currentId);
100
- const task = cached ?? await safeFetch(fetcher, currentId);
101
- if (!task)
102
- break;
103
- walked.push(task);
104
- const parentId = task.parent_task_id;
105
- if (parentId === null || parentId === undefined)
106
- break;
107
- if (!Number.isFinite(parentId) || parentId <= 0)
108
- break;
109
- currentId = parentId;
110
- }
111
- return walked.reverse();
112
- }
113
- }
114
- /**
115
- * Run `fetcher(id)` and swallow any rejection. A failed fetch
116
- * (network / parse / CLI error) should not crash the chain walk —
117
- * we just stop at the last known task.
118
- */
119
- async function safeFetch(fetcher, id) {
120
- try {
121
- return await fetcher(id);
122
- }
123
- catch {
124
- return null;
125
- }
126
- }
127
- // ---------------------------------------------------------------------------
128
- // Default CLI-backed fetcher
129
- // ---------------------------------------------------------------------------
130
- /**
131
- * Build a {@link TaskMetaFetcher} that shells out to the host's
132
- * `roy-agent` CLI. Intended for production use; tests should pass a
133
- * stub.
134
- *
135
- * args: [cliPath, "tasks", "get", "<id>", "--json"]
136
- * stdout: { task: { id, title, status, priority, type,
137
- * parent_task_id, createdAt, updatedAt, tags,
138
- * project_path }, ... }
139
- *
140
- * The returned fetcher:
141
- * - Spawns the CLI as a discrete arg array (no shell string).
142
- * - Enforces a 5-second wall-clock timeout.
143
- * - Locates the first `{` in stdout (the CLI prints INFO lines
144
- * before the JSON envelope).
145
- * - Returns `null` on any failure (non-zero exit, timeout, parse
146
- * error, schema mismatch).
147
- */
148
- export function makeCliTaskMetaFetcher(cliPath) {
149
- return async (id) => {
150
- if (!Number.isInteger(id) || id <= 0)
151
- return null;
152
- const args = [cliPath, "tasks", "get", String(id), "--json"];
153
- let stdout = "";
154
- try {
155
- const result = await execFileAsync(cliPath, args.slice(1), {
156
- timeout: 5000,
157
- maxBuffer: 4 * 1024 * 1024,
158
- windowsHide: true,
159
- });
160
- stdout = result.stdout ?? "";
161
- }
162
- catch {
163
- return null;
164
- }
165
- const jsonStart = stdout.indexOf("{");
166
- if (jsonStart < 0)
167
- return null;
168
- const envelopeText = stdout.slice(jsonStart);
169
- let envelope;
170
- try {
171
- envelope = JSON.parse(envelopeText);
172
- }
173
- catch {
174
- return null;
175
- }
176
- const t = envelope?.task;
177
- if (!t || typeof t.id !== "number")
178
- return null;
179
- return {
180
- id: t.id,
181
- title: typeof t.title === "string" ? t.title : "",
182
- status: typeof t.status === "string" ? t.status : undefined,
183
- priority: typeof t.priority === "string" ? t.priority : undefined,
184
- type: typeof t.type === "string" ? t.type : undefined,
185
- parent_task_id: typeof t.parent_task_id === "number" ? t.parent_task_id : null,
186
- createdAt: typeof t.createdAt === "string" ? t.createdAt : undefined,
187
- updatedAt: typeof t.updatedAt === "string" ? t.updatedAt : undefined,
188
- tags: Array.isArray(t.tags) ? t.tags.filter((x) => typeof x === "string") : undefined,
189
- projectPath: typeof t.project_path === "string" ? t.project_path : undefined,
190
- };
191
- };
192
- }
193
- //# sourceMappingURL=task-session-store.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"task-session-store.js","sourceRoot":"","sources":["../src/task-session-store.ts"],"names":[],"mappings":"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"}