@ai-setting/roy-plugin-task-show 0.6.12 → 0.8.4

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.
@@ -0,0 +1,143 @@
1
+ /**
2
+ * @fileoverview CLI adapter for `roy-agent tasks tree [--json] [--root-id N]`.
3
+ *
4
+ * Used by the Web homepage to render a hierarchical task list instead of
5
+ * the flat per-task tool-call view. Mirrors the design of
6
+ * `cli-tasks-adapter.ts` (typed errors, timeouts, byte caps, injectable
7
+ * runner) so the HTTP layer can map errors the same way.
8
+ *
9
+ * The CLI's `--json` output for `tasks tree` is:
10
+ * {
11
+ * "total": <number>, // total tasks in the filtered set
12
+ * "rootCount": <number>, // number of root nodes in the returned tree
13
+ * "tree": [ // array of root nodes (recursively nested)
14
+ * {
15
+ * "task": { id, title, status, priority, type, progress, ... },
16
+ * "children": [ /* same shape, recursively *\/ ]
17
+ * },
18
+ * ...
19
+ * ]
20
+ * }
21
+ *
22
+ * If `--root-id N` is provided, the response is a 1-element array whose
23
+ * only root is task #N, and the rest of the tree hangs below it. We
24
+ * transparently pass `--root-id` through to the CLI — callers don't have
25
+ * to filter the result themselves.
26
+ *
27
+ * Design goals (matching cli-tasks-adapter.ts):
28
+ * - Spawn the host CLI as a discrete arg array — never via shell string.
29
+ * - Enforce a wall-clock timeout and a maximum stdout size.
30
+ * - Locate the leading `{` in stdout to skip INFO/log lines the real
31
+ * CLI emits before its JSON envelope.
32
+ * - Validate the parsed envelope against a stable schema.
33
+ * - Surface typed errors so callers can map them to HTTP status codes.
34
+ *
35
+ * The adapter is intentionally narrow: it knows nothing about HTTP, the
36
+ * server, or the frontend. The `runner` is injectable so tests never
37
+ * need a real subprocess.
38
+ */
39
+ import type { TaskShowConfig } from "./types.js";
40
+ /** Subset of the CLI's `task` payload that we surface to the UI. */
41
+ export interface TaskTreeNodeTask {
42
+ id: number;
43
+ title: string;
44
+ description?: string;
45
+ status: string;
46
+ priority: string;
47
+ type: string;
48
+ progress?: number;
49
+ current_status?: string;
50
+ createdAt: string;
51
+ updatedAt: string;
52
+ tags: string[];
53
+ project_path?: string;
54
+ parent_task_id?: number;
55
+ }
56
+ /** One node in the returned tree (recursive). */
57
+ export interface TaskTreeNode {
58
+ task: TaskTreeNodeTask;
59
+ children: TaskTreeNode[];
60
+ }
61
+ /** Successful parse result. */
62
+ export interface TasksTreeEnvelope {
63
+ total: number;
64
+ rootCount: number;
65
+ tree: TaskTreeNode[];
66
+ /** When the source data was last fetched (ISO 8601). */
67
+ fetchedAt: string;
68
+ /** True if this entry is past TTL but still served. */
69
+ stale: boolean;
70
+ }
71
+ /** Filter parameters understood by the underlying CLI. */
72
+ export interface TasksTreeFilter {
73
+ status?: "todo" | "active" | "completed" | "paused" | "cancelled";
74
+ priority?: "low" | "medium" | "high";
75
+ type?: "normal" | "cycle" | "longterm";
76
+ /** Restrict the tree to one root (and its descendants). */
77
+ rootId?: number;
78
+ includeArchived?: boolean;
79
+ }
80
+ export { AdapterError, TimeoutError, ParseError, SchemaError, } from "./cli-tasks-adapter.js";
81
+ export interface AdapterRunnerResult {
82
+ stdout: string;
83
+ stderr: string;
84
+ exitCode: number;
85
+ }
86
+ export type AdapterRunner = (args: string[]) => Promise<AdapterRunnerResult>;
87
+ export interface TasksTreeAdapterOptions {
88
+ /** Absolute path to the `roy-agent` executable. */
89
+ cliPath: string;
90
+ /** Mockable subprocess runner (defaults to `defaultRunner`). */
91
+ runner?: AdapterRunner;
92
+ /** Wall-clock timeout (default 30000 ms — the tree JSON is large and the CLI runs migrations). */
93
+ timeoutMs?: number;
94
+ /** Maximum stdout bytes to keep (default 8 MiB). */
95
+ maxBytes?: number;
96
+ /** TaskShowConfig for sharing limits / defaults. */
97
+ cfg: TaskShowConfig;
98
+ }
99
+ export interface TasksTreeSource {
100
+ getTasksTree(filter: TasksTreeFilter): Promise<TasksTreeEnvelope>;
101
+ }
102
+ /**
103
+ * Default subprocess runner. We deliberately avoid `shell: true` to keep
104
+ * argv as a literal array — no shell metacharacter interpretation.
105
+ *
106
+ * Two adaptations for Bun / large outputs:
107
+ * 1. File-descriptor stdio: under Bun, piping ≥1 MB via
108
+ * `stdio: ["ignore", "pipe", "pipe"]` drops data because the
109
+ * `data` and `end` events fire before every chunk has been
110
+ * delivered. Redirecting stdout/stderr to temp files captures the
111
+ * full output reliably.
112
+ * 2. Poll-until-stable read: on Bun, the child process's `close` event
113
+ * can fire BEFORE all writes have been flushed to the file
114
+ * descriptor. We poll the file size until it stabilizes, then
115
+ * read with createReadStream (more robust than readFileSync for
116
+ * large files). This guarantees we don't return truncated output.
117
+ *
118
+ * Both adaptations are no-ops under Node.js (no observable behavior
119
+ * change), so the same code runs reliably on either runtime.
120
+ *
121
+ * Temp files are cleaned up in `finally` so a crash doesn't leak dirs.
122
+ */
123
+ export declare const defaultRunner: AdapterRunner;
124
+ /**
125
+ * Build the argv array for `roy-agent tasks tree [--status] [--priority]
126
+ * [--type] [--root-id] [--include-archived] --json`. Pure function — easy
127
+ * to unit-test.
128
+ */
129
+ export declare function buildTasksTreeArgs(cliPath: string, filter: TasksTreeFilter): string[];
130
+ /**
131
+ * Run `roy-agent tasks tree [--json] [--filter...]` and return a parsed
132
+ * envelope. Errors are typed so the HTTP layer can map them to status
133
+ * codes.
134
+ *
135
+ * Pass `runner: defaultRunner` in production. Tests pass a `fixedRunner`.
136
+ */
137
+ export declare function runTasksTree(filter: TasksTreeFilter, options: TasksTreeAdapterOptions): Promise<TasksTreeEnvelope>;
138
+ /**
139
+ * Convenience wrapper used by TasksTreeCache: a `TasksTreeSource` whose
140
+ * `getTasksTree(filter)` returns the parsed envelope or throws.
141
+ */
142
+ export declare function makeTasksTreeSource(opts: TasksTreeAdapterOptions): TasksTreeSource;
143
+ //# sourceMappingURL=cli-tasks-tree-adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-tasks-tree-adapter.d.ts","sourceRoot":"","sources":["../src/cli-tasks-tree-adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,400 @@
1
+ /**
2
+ * @fileoverview CLI adapter for `roy-agent tasks tree [--json] [--root-id N]`.
3
+ *
4
+ * Used by the Web homepage to render a hierarchical task list instead of
5
+ * the flat per-task tool-call view. Mirrors the design of
6
+ * `cli-tasks-adapter.ts` (typed errors, timeouts, byte caps, injectable
7
+ * runner) so the HTTP layer can map errors the same way.
8
+ *
9
+ * The CLI's `--json` output for `tasks tree` is:
10
+ * {
11
+ * "total": <number>, // total tasks in the filtered set
12
+ * "rootCount": <number>, // number of root nodes in the returned tree
13
+ * "tree": [ // array of root nodes (recursively nested)
14
+ * {
15
+ * "task": { id, title, status, priority, type, progress, ... },
16
+ * "children": [ /* same shape, recursively *\/ ]
17
+ * },
18
+ * ...
19
+ * ]
20
+ * }
21
+ *
22
+ * If `--root-id N` is provided, the response is a 1-element array whose
23
+ * only root is task #N, and the rest of the tree hangs below it. We
24
+ * transparently pass `--root-id` through to the CLI — callers don't have
25
+ * to filter the result themselves.
26
+ *
27
+ * Design goals (matching cli-tasks-adapter.ts):
28
+ * - Spawn the host CLI as a discrete arg array — never via shell string.
29
+ * - Enforce a wall-clock timeout and a maximum stdout size.
30
+ * - Locate the leading `{` in stdout to skip INFO/log lines the real
31
+ * CLI emits before its JSON envelope.
32
+ * - Validate the parsed envelope against a stable schema.
33
+ * - Surface typed errors so callers can map them to HTTP status codes.
34
+ *
35
+ * The adapter is intentionally narrow: it knows nothing about HTTP, the
36
+ * server, or the frontend. The `runner` is injectable so tests never
37
+ * need a real subprocess.
38
+ */
39
+ // Re-exports so the HTTP layer can use the same error classes without
40
+ // importing cli-tasks-adapter.ts directly (avoids a circular import).
41
+ export { AdapterError, TimeoutError, ParseError, SchemaError, } from "./cli-tasks-adapter.js";
42
+ import { AdapterError, TimeoutError, ParseError, SchemaError } from "./cli-tasks-adapter.js";
43
+ // ---------------------------------------------------------------------------
44
+ // Default runner — spawns the CLI as discrete args with timeout & byte cap
45
+ // ---------------------------------------------------------------------------
46
+ /**
47
+ * Default subprocess runner. We deliberately avoid `shell: true` to keep
48
+ * argv as a literal array — no shell metacharacter interpretation.
49
+ *
50
+ * Two adaptations for Bun / large outputs:
51
+ * 1. File-descriptor stdio: under Bun, piping ≥1 MB via
52
+ * `stdio: ["ignore", "pipe", "pipe"]` drops data because the
53
+ * `data` and `end` events fire before every chunk has been
54
+ * delivered. Redirecting stdout/stderr to temp files captures the
55
+ * full output reliably.
56
+ * 2. Poll-until-stable read: on Bun, the child process's `close` event
57
+ * can fire BEFORE all writes have been flushed to the file
58
+ * descriptor. We poll the file size until it stabilizes, then
59
+ * read with createReadStream (more robust than readFileSync for
60
+ * large files). This guarantees we don't return truncated output.
61
+ *
62
+ * Both adaptations are no-ops under Node.js (no observable behavior
63
+ * change), so the same code runs reliably on either runtime.
64
+ *
65
+ * Temp files are cleaned up in `finally` so a crash doesn't leak dirs.
66
+ */
67
+ export const defaultRunner = async (args) => {
68
+ const { spawn } = await import("node:child_process");
69
+ const { mkdtempSync, openSync, rmSync, statSync, createReadStream } = await import("node:fs");
70
+ const { tmpdir } = await import("node:os");
71
+ const { join } = await import("node:path");
72
+ const executable = args[0];
73
+ const argv = args.slice(1);
74
+ const dir = mkdtempSync(join(tmpdir(), "roy-task-tree-"));
75
+ const stdoutPath = join(dir, "stdout");
76
+ const stderrPath = join(dir, "stderr");
77
+ const stdoutFd = openSync(stdoutPath, "w");
78
+ const stderrFd = openSync(stderrPath, "w");
79
+ return new Promise((resolve, reject) => {
80
+ let settled = false;
81
+ const MAX_BYTES_DEFAULT = 8 * 1024 * 1024;
82
+ const child = spawn(executable, argv, {
83
+ stdio: ["ignore", stdoutFd, stderrFd],
84
+ env: process.env,
85
+ });
86
+ const timer = setTimeout(() => {
87
+ if (settled)
88
+ return;
89
+ settled = true;
90
+ try {
91
+ child.kill("SIGKILL");
92
+ }
93
+ catch {
94
+ /* ignore */
95
+ }
96
+ const err = new Error("CLI spawn timed out");
97
+ err.name = "AbortError";
98
+ reject(err);
99
+ }, 30_000);
100
+ child.on("error", (err) => {
101
+ if (settled)
102
+ return;
103
+ settled = true;
104
+ clearTimeout(timer);
105
+ reject(err);
106
+ });
107
+ child.on("close", (code) => {
108
+ if (settled)
109
+ return;
110
+ settled = true;
111
+ clearTimeout(timer);
112
+ // Poll the stdout file size until it stops growing. The Bun
113
+ // runtime can fire `close` before the child's buffered stdout
114
+ // has been fully written to the file descriptor, so we must wait
115
+ // for the writer side to flush before reading.
116
+ const waitForFlush = () => new Promise((done) => {
117
+ const deadline = Date.now() + 5000; // 5s safety net
118
+ let lastSize = -1;
119
+ let stableTicks = 0;
120
+ const tick = () => {
121
+ let curSize = 0;
122
+ try {
123
+ curSize = statSync(stdoutPath).size;
124
+ }
125
+ catch {
126
+ // file may have been removed by something — bail
127
+ done();
128
+ return;
129
+ }
130
+ if (curSize === lastSize) {
131
+ stableTicks += 1;
132
+ if (stableTicks >= 3) {
133
+ done();
134
+ return;
135
+ }
136
+ }
137
+ else {
138
+ stableTicks = 0;
139
+ lastSize = curSize;
140
+ }
141
+ if (Date.now() >= deadline) {
142
+ done();
143
+ return;
144
+ }
145
+ setTimeout(tick, 25);
146
+ };
147
+ tick();
148
+ });
149
+ waitForFlush().then(() => {
150
+ try {
151
+ const readUtf8 = (filePath) => new Promise((res, rej) => {
152
+ const chunks = [];
153
+ const stream = createReadStream(filePath);
154
+ stream.on("data", (c) => chunks.push(Buffer.isBuffer(c) ? c : Buffer.from(c)));
155
+ stream.on("end", () => res(Buffer.concat(chunks).toString("utf8")));
156
+ stream.on("error", rej);
157
+ });
158
+ Promise.all([readUtf8(stdoutPath), readUtf8(stderrPath)]).then(([stdout, stderr]) => {
159
+ if (stdout.length > MAX_BYTES_DEFAULT) {
160
+ reject(new AdapterError(`CLI stdout exceeded maxBytes=${MAX_BYTES_DEFAULT} (got ${stdout.length})`, { code: "oversize" }));
161
+ return;
162
+ }
163
+ resolve({
164
+ stdout,
165
+ stderr,
166
+ exitCode: code ?? 0,
167
+ });
168
+ }, (err) => reject(err));
169
+ }
170
+ catch (err) {
171
+ reject(err);
172
+ }
173
+ });
174
+ });
175
+ }).finally(() => {
176
+ try {
177
+ rmSync(dir, { recursive: true, force: true });
178
+ }
179
+ catch {
180
+ /* ignore — best-effort cleanup */
181
+ }
182
+ });
183
+ };
184
+ // ---------------------------------------------------------------------------
185
+ // Arg builder
186
+ // ---------------------------------------------------------------------------
187
+ /**
188
+ * Build the argv array for `roy-agent tasks tree [--status] [--priority]
189
+ * [--type] [--root-id] [--include-archived] --json`. Pure function — easy
190
+ * to unit-test.
191
+ */
192
+ export function buildTasksTreeArgs(cliPath, filter) {
193
+ const args = [cliPath, "tasks", "tree"];
194
+ if (filter.status)
195
+ args.push("--status", filter.status);
196
+ if (filter.priority)
197
+ args.push("--priority", filter.priority);
198
+ if (filter.type)
199
+ args.push("--type", filter.type);
200
+ if (typeof filter.rootId === "number" && Number.isFinite(filter.rootId) && filter.rootId > 0) {
201
+ args.push("--root-id", String(Math.trunc(filter.rootId)));
202
+ }
203
+ if (filter.includeArchived)
204
+ args.push("--include-archived");
205
+ args.push("--json");
206
+ // The CLI is noisy on stdout by default — force quiet mode so we only
207
+ // get the JSON envelope. Newer builds accept `--quiet`; older builds
208
+ // (default quiet=true) ignore it harmlessly.
209
+ args.push("--quiet");
210
+ return args;
211
+ }
212
+ // ---------------------------------------------------------------------------
213
+ // Parsing helpers
214
+ // ---------------------------------------------------------------------------
215
+ /**
216
+ * Locate the JSON envelope in stdout. The CLI emits migration / OTel
217
+ * log lines before the envelope, and some runtimes (notably Bun) have
218
+ * been observed to append unrelated output (e.g. other plugins'
219
+ * `dispose` banners) AFTER the envelope's closing brace.
220
+ *
221
+ * Strategy:
222
+ * 1. Locate the leading `{` and skip the leading log lines.
223
+ * 2. Walk forward, tracking brace depth, to find the matching `}`.
224
+ * This is robust against trailing content that isn't part of the
225
+ * envelope — anything after the balanced close brace is dropped.
226
+ * 3. Bail with a ParseError if the brace depth never returns to 0.
227
+ *
228
+ * The implementation treats `{` and `}` that appear inside JSON strings
229
+ * conservatively (a real string can contain an unescaped brace in some
230
+ * shapes, but our CLI's envelope never does). This keeps the extractor
231
+ * simple while still handling the observed trailing-noise case.
232
+ */
233
+ function extractJsonEnvelope(stdout) {
234
+ const start = stdout.indexOf("{");
235
+ if (start < 0) {
236
+ throw new ParseError("No JSON envelope found in CLI stdout (no leading `{`)");
237
+ }
238
+ let depth = 0;
239
+ let inString = false;
240
+ let escape = false;
241
+ let end = -1;
242
+ for (let i = start; i < stdout.length; i++) {
243
+ const ch = stdout[i];
244
+ if (inString) {
245
+ if (escape) {
246
+ escape = false;
247
+ }
248
+ else if (ch === "\\") {
249
+ escape = true;
250
+ }
251
+ else if (ch === '"') {
252
+ inString = false;
253
+ }
254
+ continue;
255
+ }
256
+ if (ch === '"') {
257
+ inString = true;
258
+ continue;
259
+ }
260
+ if (ch === "{") {
261
+ depth += 1;
262
+ }
263
+ else if (ch === "}") {
264
+ depth -= 1;
265
+ if (depth === 0) {
266
+ end = i;
267
+ break;
268
+ }
269
+ }
270
+ }
271
+ if (end < 0) {
272
+ throw new ParseError("Unterminated JSON envelope (brace depth never returned to 0)");
273
+ }
274
+ return stdout.slice(start, end + 1);
275
+ }
276
+ /**
277
+ * Recursively validate + normalize a tree node. Throws SchemaError on the
278
+ * first structural problem so the caller can surface a 502-style error.
279
+ */
280
+ function normalizeNode(raw, depth) {
281
+ if (depth > 16) {
282
+ // Defensive: a malicious / buggy CLI emitting 17+ levels deep would
283
+ // blow the stack on recursive normalizeNode. Bail with a clear error.
284
+ throw new SchemaError(`tree node depth > 16 (recursion guard)`);
285
+ }
286
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) {
287
+ throw new SchemaError("tree node is not an object");
288
+ }
289
+ if (!raw.task || typeof raw.task !== "object") {
290
+ throw new SchemaError("tree node missing `task` object");
291
+ }
292
+ const t = raw.task;
293
+ const task = {
294
+ id: Number(t.id),
295
+ title: String(t.title ?? ""),
296
+ description: typeof t.description === "string" ? t.description : undefined,
297
+ status: String(t.status ?? "unknown"),
298
+ priority: String(t.priority ?? "medium"),
299
+ type: String(t.type ?? "normal"),
300
+ progress: typeof t.progress === "number" ? t.progress : undefined,
301
+ current_status: typeof t.current_status === "string" ? t.current_status : undefined,
302
+ createdAt: String(t.createdAt ?? ""),
303
+ updatedAt: String(t.updatedAt ?? ""),
304
+ tags: Array.isArray(t.tags) ? t.tags.map((x) => String(x)) : [],
305
+ project_path: typeof t.project_path === "string" ? t.project_path : undefined,
306
+ parent_task_id: typeof t.parent_task_id === "number" ? t.parent_task_id : undefined,
307
+ };
308
+ if (!Number.isInteger(task.id) || task.id <= 0) {
309
+ throw new SchemaError(`tree node task.id is invalid: ${String(task.id)}`);
310
+ }
311
+ const children = Array.isArray(raw.children) ? raw.children : [];
312
+ return { task, children: children.map((c) => normalizeNode(c, depth + 1)) };
313
+ }
314
+ // ---------------------------------------------------------------------------
315
+ // Public entry point
316
+ // ---------------------------------------------------------------------------
317
+ /**
318
+ * Run `roy-agent tasks tree [--json] [--filter...]` and return a parsed
319
+ * envelope. Errors are typed so the HTTP layer can map them to status
320
+ * codes.
321
+ *
322
+ * Pass `runner: defaultRunner` in production. Tests pass a `fixedRunner`.
323
+ */
324
+ export async function runTasksTree(filter, options) {
325
+ const runner = options.runner ?? defaultRunner;
326
+ const args = buildTasksTreeArgs(options.cliPath, filter);
327
+ const timeoutMs = options.timeoutMs ?? 30_000;
328
+ const maxBytes = options.maxBytes ?? 8 * 1024 * 1024;
329
+ let raw;
330
+ try {
331
+ raw = await withTimeout(runner(args), timeoutMs);
332
+ }
333
+ catch (err) {
334
+ if (err?.name === "AbortError" || /timeout|abort/i.test(String(err?.message ?? ""))) {
335
+ throw new TimeoutError(`CLI timeout after ${timeoutMs}ms`, err);
336
+ }
337
+ if (err instanceof AdapterError)
338
+ throw err;
339
+ throw new AdapterError(`CLI runner failed: ${err?.message ?? String(err)}`, { cause: err });
340
+ }
341
+ if (raw.stdout.length > maxBytes) {
342
+ throw new AdapterError(`CLI stdout exceeded maxBytes=${maxBytes} (got ${raw.stdout.length})`, { code: "oversize" });
343
+ }
344
+ let parsed;
345
+ try {
346
+ const jsonText = extractJsonEnvelope(raw.stdout);
347
+ parsed = JSON.parse(jsonText);
348
+ }
349
+ catch (err) {
350
+ if (raw.exitCode !== 0) {
351
+ throw new AdapterError(`CLI exited with code ${raw.exitCode} and no parseable JSON envelope`, { code: "cli_failed", exitCode: raw.exitCode });
352
+ }
353
+ if (err instanceof ParseError || err instanceof SchemaError)
354
+ throw err;
355
+ throw new ParseError("Failed to parse CLI JSON envelope", err);
356
+ }
357
+ if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
358
+ throw new SchemaError("envelope root is not an object");
359
+ }
360
+ if (!Array.isArray(parsed.tree)) {
361
+ throw new SchemaError("envelope missing `tree` array");
362
+ }
363
+ const tree = parsed.tree.map((n) => normalizeNode(n, 0));
364
+ const total = Number(parsed.total ?? tree.length);
365
+ const rootCount = Number(parsed.rootCount ?? tree.length);
366
+ return {
367
+ total,
368
+ rootCount,
369
+ tree,
370
+ fetchedAt: new Date().toISOString(),
371
+ stale: false,
372
+ };
373
+ }
374
+ /** Wrap a promise with a wall-clock timeout. */
375
+ function withTimeout(p, ms) {
376
+ let timer;
377
+ const timeout = new Promise((_, reject) => {
378
+ timer = setTimeout(() => {
379
+ const err = new Error(`timed out after ${ms}ms`);
380
+ err.name = "AbortError";
381
+ reject(err);
382
+ }, ms);
383
+ });
384
+ return Promise.race([p, timeout]).finally(() => {
385
+ if (timer)
386
+ clearTimeout(timer);
387
+ });
388
+ }
389
+ /**
390
+ * Convenience wrapper used by TasksTreeCache: a `TasksTreeSource` whose
391
+ * `getTasksTree(filter)` returns the parsed envelope or throws.
392
+ */
393
+ export function makeTasksTreeSource(opts) {
394
+ return {
395
+ async getTasksTree(filter) {
396
+ return runTasksTree(filter, opts);
397
+ },
398
+ };
399
+ }
400
+ //# sourceMappingURL=cli-tasks-tree-adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli-tasks-tree-adapter.js","sourceRoot":"","sources":["../src/cli-tasks-tree-adapter.ts"],"names":[],"mappings":"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"}
package/dist/plugin.d.ts CHANGED
@@ -145,6 +145,8 @@ export declare class TaskShowPlugin implements TaskShowPluginInterface {
145
145
  private readonly eventBus;
146
146
  /** v0.7.0+: cache for parsed task operations envelopes. */
147
147
  private readonly operationsCache;
148
+ /** v0.8.0+: cache for parsed task tree envelopes (used by /api/tasks/tree). */
149
+ private readonly tasksTreeCache;
148
150
  private env;
149
151
  private disposed;
150
152
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
package/dist/plugin.js CHANGED
@@ -40,6 +40,8 @@ import { buildVisualizationUrl } from "./url-injector.js";
40
40
  import { getLanHostname } from "./lan-host.js";
41
41
  import { OperationsCache } from "./operations-cache.js";
42
42
  import { defaultRunner as defaultCliRunner, makeTaskOperationsSource, } from "./cli-tasks-adapter.js";
43
+ import { defaultRunner as defaultTreeCliRunner, makeTasksTreeSource, } from "./cli-tasks-tree-adapter.js";
44
+ import { TasksTreeCache } from "./tasks-tree-cache.js";
43
45
  import * as fs from "node:fs";
44
46
  import * as path from "node:path";
45
47
  import { fileURLToPath } from "node:url";
@@ -189,6 +191,8 @@ export class TaskShowPlugin {
189
191
  eventBus;
190
192
  /** v0.7.0+: cache for parsed task operations envelopes. */
191
193
  operationsCache;
194
+ /** v0.8.0+: cache for parsed task tree envelopes (used by /api/tasks/tree). */
195
+ tasksTreeCache;
192
196
  env = null;
193
197
  disposed = false;
194
198
  /**
@@ -233,6 +237,25 @@ export class TaskShowPlugin {
233
237
  source,
234
238
  ttlMs: this.cfg.operationsCacheTtlMs,
235
239
  });
240
+ // v0.8.0+: separate cache for `tasks tree` envelopes. The same
241
+ // CLI binary is reused, but the response shape is different and the
242
+ // filter combinations deserve their own cache namespace. The tree
243
+ // runner uses temp-file stdio (see cli-tasks-tree-adapter.ts) so the
244
+ // larger output (~2.5 MB) is delivered reliably under Bun.
245
+ const treeSource = makeTasksTreeSource({
246
+ cliPath,
247
+ runner: defaultTreeCliRunner,
248
+ // Tree output is ~2.5 MiB — override the cfg.cliMaxBytes default
249
+ // (1 MiB) which is too small. 8 MiB leaves headroom for future
250
+ // task growth without bumping the limit again.
251
+ timeoutMs: this.cfg.cliTimeoutMs ?? 30_000,
252
+ maxBytes: 8 * 1024 * 1024,
253
+ cfg: this.cfg,
254
+ });
255
+ this.tasksTreeCache = new TasksTreeCache({
256
+ source: treeSource,
257
+ ttlMs: this.cfg.operationsCacheTtlMs,
258
+ });
236
259
  this.server = new TaskShowServer({
237
260
  cfg: this.cfg,
238
261
  collector: this.collector,
@@ -243,6 +266,7 @@ export class TaskShowPlugin {
243
266
  metaUrl: typeof import.meta !== "undefined" ? import.meta.url : undefined,
244
267
  logger: { info, warn, error },
245
268
  operationsCache: this.operationsCache,
269
+ tasksTreeCache: this.tasksTreeCache,
246
270
  });
247
271
  }
248
272
  /**