md-task-viewer 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/cli.ts
4
- import path3 from "path";
4
+ import path4 from "path";
5
5
  import process from "process";
6
6
  import open from "open";
7
7
 
@@ -9,7 +9,7 @@ import open from "open";
9
9
  import Fastify from "fastify";
10
10
  import fastifyStatic from "@fastify/static";
11
11
  import chokidar from "chokidar";
12
- import path2 from "path";
12
+ import path3 from "path";
13
13
  import { fileURLToPath } from "url";
14
14
 
15
15
  // src/taskStore.ts
@@ -161,7 +161,8 @@ async function readConfig(rootDir) {
161
161
  const taskDirs = Array.isArray(parsed.taskDirs) ? parsed.taskDirs.filter((item) => typeof item === "string") : ["."];
162
162
  const ignorePaths = Array.isArray(parsed.ignorePaths) ? parsed.ignorePaths.filter((item) => typeof item === "string") : [];
163
163
  const order = Array.isArray(parsed.order) ? parsed.order.filter((item) => typeof item === "string") : [];
164
- return { version: parsed.version ?? 1, taskDirs, ignorePaths, order };
164
+ const commands = Array.isArray(parsed.commands) ? parsed.commands : void 0;
165
+ return { version: parsed.version ?? 1, taskDirs, ignorePaths, order, commands };
165
166
  } catch (error) {
166
167
  const maybeError = error;
167
168
  if (maybeError.code !== "ENOENT") {
@@ -190,11 +191,11 @@ async function saveOrder(rootDir, order) {
190
191
  )
191
192
  );
192
193
  const existing = await readConfig(rootDir);
193
- const payload = { version: 1, taskDirs: existing.taskDirs, ignorePaths: existing.ignorePaths, order: normalized };
194
+ const payload = { version: 1, taskDirs: existing.taskDirs, ignorePaths: existing.ignorePaths, order: normalized, commands: existing.commands };
194
195
  await fs.writeFile(path.join(rootDir, CONFIG_FILE_NAME), `${JSON.stringify(payload, null, 2)}
195
196
  `, "utf8");
196
197
  }
197
- async function saveConfig(rootDir, taskDirs, ignorePaths) {
198
+ async function saveConfig(rootDir, taskDirs, ignorePaths, commands) {
198
199
  const validated = taskDirs.map((dir) => {
199
200
  const normalized = dir.trim().replace(/\\/g, "/").replace(/\/+$/, "") || ".";
200
201
  if (normalized.startsWith("../") || normalized.includes("/../")) {
@@ -207,7 +208,8 @@ async function saveConfig(rootDir, taskDirs, ignorePaths) {
207
208
  }
208
209
  const existing = await readConfig(rootDir);
209
210
  const validatedIgnorePaths = ignorePaths ?? existing.ignorePaths;
210
- const payload = { version: 1, taskDirs: validated, ignorePaths: validatedIgnorePaths, order: existing.order };
211
+ const validatedCommands = commands !== void 0 ? commands : existing.commands;
212
+ const payload = { version: 1, taskDirs: validated, ignorePaths: validatedIgnorePaths, order: existing.order, commands: validatedCommands };
211
213
  await fs.writeFile(path.join(rootDir, CONFIG_FILE_NAME), `${JSON.stringify(payload, null, 2)}
212
214
  `, "utf8");
213
215
  return payload;
@@ -419,9 +421,97 @@ function parseOrderPayload(input) {
419
421
  return input.map((item) => ensureMarkdownExtension(normalizeRelativePath(String(item))));
420
422
  }
421
423
 
424
+ // src/commandExecutor.ts
425
+ import { spawn } from "child_process";
426
+ import path2 from "path";
427
+ var TIMEOUT_MS = 3e4;
428
+ var VARIABLE_PATTERN = /\$\{?(TASK_TITLE|TASK_FILEPATH|TASK_BODY)\}?/g;
429
+ function substituteVariables(command, vars) {
430
+ return command.replace(VARIABLE_PATTERN, (_match, name) => vars[name] ?? "");
431
+ }
432
+ async function executeCommandPipeline(rootDir, steps, task) {
433
+ if (steps.length === 0) {
434
+ return { stdout: "", stderr: "", exitCode: 0, duration: 0 };
435
+ }
436
+ const absoluteFilePath = path2.resolve(rootDir, task.path);
437
+ const vars = {
438
+ TASK_TITLE: task.frontmatter.title,
439
+ TASK_FILEPATH: absoluteFilePath,
440
+ TASK_BODY: task.content
441
+ };
442
+ const startTime = Date.now();
443
+ return new Promise((resolve) => {
444
+ const resolvedCommands = steps.map((step, index) => {
445
+ let cmd = substituteVariables(step.command, vars);
446
+ if (index === 0 && step.passBody === "arg") {
447
+ const escaped = task.content.replace(/'/g, "'\\''");
448
+ cmd = `${cmd} '${escaped}'`;
449
+ }
450
+ return cmd;
451
+ });
452
+ const processes = [];
453
+ for (let index = 0; index < resolvedCommands.length; index++) {
454
+ const proc = spawn(resolvedCommands[index], {
455
+ shell: true,
456
+ cwd: rootDir,
457
+ stdio: ["pipe", "pipe", "pipe"]
458
+ });
459
+ if (index > 0) {
460
+ const prev = processes[index - 1];
461
+ if (prev?.stdout) {
462
+ prev.stdout.pipe(proc.stdin);
463
+ }
464
+ }
465
+ processes.push(proc);
466
+ }
467
+ const firstStep = steps[0];
468
+ const firstProc = processes[0];
469
+ if (firstStep.passBody === "stdin" && firstProc.stdin) {
470
+ firstProc.stdin.write(task.content);
471
+ }
472
+ firstProc.stdin?.end();
473
+ const lastProc = processes[processes.length - 1];
474
+ const stdoutChunks = [];
475
+ const stderrChunks = [];
476
+ lastProc.stdout?.on("data", (chunk) => stdoutChunks.push(chunk));
477
+ lastProc.stderr?.on("data", (chunk) => stderrChunks.push(chunk));
478
+ for (let i = 0; i < processes.length - 1; i++) {
479
+ processes[i].stderr?.on("data", (chunk) => stderrChunks.push(chunk));
480
+ }
481
+ const timeout = setTimeout(() => {
482
+ for (const proc of processes) {
483
+ proc.kill("SIGTERM");
484
+ }
485
+ }, TIMEOUT_MS);
486
+ lastProc.on("close", (code) => {
487
+ clearTimeout(timeout);
488
+ resolve({
489
+ stdout: Buffer.concat(stdoutChunks).toString("utf8"),
490
+ stderr: Buffer.concat(stderrChunks).toString("utf8"),
491
+ exitCode: code ?? 1,
492
+ duration: Date.now() - startTime
493
+ });
494
+ });
495
+ lastProc.on("error", (err) => {
496
+ clearTimeout(timeout);
497
+ resolve({
498
+ stdout: "",
499
+ stderr: err.message,
500
+ exitCode: 1,
501
+ duration: Date.now() - startTime
502
+ });
503
+ });
504
+ for (let i = 0; i < processes.length - 1; i++) {
505
+ processes[i].on("error", (err) => {
506
+ stderrChunks.push(Buffer.from(err.message));
507
+ });
508
+ }
509
+ });
510
+ }
511
+
422
512
  // src/server.ts
423
513
  var __filename = fileURLToPath(import.meta.url);
424
- var __dirname = path2.dirname(__filename);
514
+ var __dirname = path3.dirname(__filename);
425
515
  function resolveClientDir(explicitClientDir) {
426
516
  if (explicitClientDir === null) {
427
517
  return null;
@@ -429,7 +519,7 @@ function resolveClientDir(explicitClientDir) {
429
519
  if (explicitClientDir) {
430
520
  return explicitClientDir;
431
521
  }
432
- return path2.resolve(__dirname, "client");
522
+ return path3.resolve(__dirname, "client");
433
523
  }
434
524
  function sendJsonError(reply, error) {
435
525
  if (error instanceof ValidationError) {
@@ -517,12 +607,56 @@ async function createServer(options) {
517
607
  }
518
608
  ignorePaths = body.ignorePaths;
519
609
  }
520
- const config = await saveConfig(options.rootDir, taskDirs, ignorePaths);
610
+ let commands;
611
+ if (body?.commands !== void 0) {
612
+ if (!Array.isArray(body.commands)) {
613
+ throw new ValidationError("commands must be an array.");
614
+ }
615
+ commands = body.commands;
616
+ }
617
+ const config = await saveConfig(options.rootDir, taskDirs, ignorePaths, commands);
521
618
  return reply.send(config);
522
619
  } catch (error) {
523
620
  sendJsonError(reply, error);
524
621
  }
525
622
  });
623
+ app.post("/api/execute", async (request, reply) => {
624
+ try {
625
+ const body = request.body;
626
+ const taskPath = body?.taskPath;
627
+ if (!taskPath || typeof taskPath !== "string") {
628
+ throw new ValidationError("taskPath is required.");
629
+ }
630
+ let task;
631
+ try {
632
+ task = await parseTask(options.rootDir, taskPath);
633
+ } catch (error) {
634
+ const maybeError = error;
635
+ if (maybeError.code === "ENOENT") {
636
+ return reply.code(404).send({ error: "Task not found." });
637
+ }
638
+ throw error;
639
+ }
640
+ let commands = body?.commands;
641
+ if (!commands || commands.length === 0) {
642
+ const taskCommands = task.extraFrontmatter.commands;
643
+ if (Array.isArray(taskCommands) && taskCommands.length > 0) {
644
+ commands = taskCommands;
645
+ }
646
+ }
647
+ if (!commands || commands.length === 0) {
648
+ const config = await readConfig(options.rootDir);
649
+ commands = config.commands;
650
+ }
651
+ if (!commands || commands.length === 0) {
652
+ throw new ValidationError("No commands configured.");
653
+ }
654
+ const result = await executeCommandPipeline(options.rootDir, commands, task);
655
+ return reply.send(result);
656
+ } catch (error) {
657
+ sendJsonError(reply, error);
658
+ }
659
+ });
526
660
  app.get("/api/events", async (_request, reply) => {
527
661
  reply.raw.writeHead(200, {
528
662
  "Content-Type": "text/event-stream",
@@ -548,18 +682,18 @@ async function createServer(options) {
548
682
  });
549
683
  const watcher = chokidar.watch(options.rootDir, {
550
684
  ignoreInitial: true,
551
- ignored: (watchPath) => watchPath.includes(`${path2.sep}.git`) || watchPath.includes(`${path2.sep}node_modules`)
685
+ ignored: (watchPath) => watchPath.includes(`${path3.sep}.git`) || watchPath.includes(`${path3.sep}node_modules`)
552
686
  });
553
687
  watcher.on("all", (eventName, changedPath) => {
554
688
  const isMarkdown = changedPath.endsWith(".md") || changedPath.endsWith(".markdown");
555
- const isConfigFile = path2.basename(changedPath) === ".md-task-viewer.json";
689
+ const isConfigFile = path3.basename(changedPath) === ".md-task-viewer.json";
556
690
  if (!isMarkdown && !isConfigFile) {
557
691
  return;
558
692
  }
559
693
  const payload = JSON.stringify({
560
694
  type: "tasks-changed",
561
695
  eventName,
562
- path: path2.relative(options.rootDir, changedPath)
696
+ path: path3.relative(options.rootDir, changedPath)
563
697
  });
564
698
  for (const listener of listeners) {
565
699
  listener.send(payload);
@@ -606,7 +740,7 @@ function parseArgs(argv) {
606
740
  continue;
607
741
  }
608
742
  if (!current.startsWith("--")) {
609
- rootDir = path3.resolve(current);
743
+ rootDir = path4.resolve(current);
610
744
  }
611
745
  }
612
746
  return { rootDir, port, host, shouldOpen };
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/server.ts","../src/taskStore.ts","../src/types.ts","../src/slugify.ts"],"sourcesContent":["#!/usr/bin/env node\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport open from \"open\";\nimport { createServer } from \"./server.js\";\n\ninterface CliOptions {\n rootDir: string;\n port: number;\n host: string;\n shouldOpen: boolean;\n}\n\nfunction parseArgs(argv: string[]): CliOptions {\n let rootDir = process.cwd();\n let port = 3847;\n let host = \"127.0.0.1\";\n let shouldOpen = true;\n\n for (let index = 0; index < argv.length; index += 1) {\n const current = argv[index];\n if (current === \"--port\") {\n port = Number(argv[index + 1] ?? port);\n index += 1;\n continue;\n }\n if (current === \"--host\") {\n host = argv[index + 1] ?? host;\n index += 1;\n continue;\n }\n if (current === \"--no-open\") {\n shouldOpen = false;\n continue;\n }\n if (!current.startsWith(\"--\")) {\n rootDir = path.resolve(current);\n }\n }\n\n return { rootDir, port, host, shouldOpen };\n}\n\nasync function main(): Promise<void> {\n const options = parseArgs(process.argv.slice(2));\n const app = await createServer({ rootDir: options.rootDir });\n const address = await app.listen({\n port: options.port,\n host: options.host\n });\n\n const browserUrl = address.replace(options.host, options.host === \"0.0.0.0\" ? \"127.0.0.1\" : options.host);\n process.stdout.write(`Markdown Task Viewer\\nRoot: ${options.rootDir}\\nURL: ${browserUrl}\\n`);\n\n if (options.shouldOpen) {\n await open(browserUrl);\n }\n\n const shutdown = async (): Promise<void> => {\n await app.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n\nmain().catch((error) => {\n process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\\n`);\n process.exit(1);\n});\n","import Fastify, { type FastifyInstance } from \"fastify\";\nimport fastifyStatic from \"@fastify/static\";\nimport chokidar from \"chokidar\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n ConflictError,\n ValidationError,\n createTask,\n deleteTask,\n listTasks,\n parseOrderPayload,\n patchTaskFields,\n readConfig,\n saveConfig,\n saveOrder,\n updateTask\n} from \"./taskStore.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface CreateServerOptions {\n rootDir: string;\n clientDir?: string | null;\n}\n\nfunction resolveClientDir(explicitClientDir?: string | null): string | null {\n if (explicitClientDir === null) {\n return null;\n }\n if (explicitClientDir) {\n return explicitClientDir;\n }\n return path.resolve(__dirname, \"client\");\n}\n\nfunction sendJsonError(reply: { code: (statusCode: number) => { send: (payload: unknown) => void } }, error: unknown): void {\n if (error instanceof ValidationError) {\n reply.code(400).send({ error: error.message });\n return;\n }\n if (error instanceof ConflictError) {\n reply.code(409).send({ error: error.message });\n return;\n }\n reply.code(500).send({ error: error instanceof Error ? error.message : \"Internal server error\" });\n}\n\nexport async function createServer(options: CreateServerOptions): Promise<FastifyInstance> {\n const app = Fastify({ logger: false });\n const listeners = new Set<{ send: (payload: string) => void; close: () => void }>();\n const clientDir = resolveClientDir(options.clientDir);\n\n app.addHook(\"onClose\", async () => {\n for (const listener of listeners) {\n listener.close();\n }\n });\n\n app.get(\"/api/tasks\", async () => listTasks(options.rootDir));\n\n app.post(\"/api/tasks\", async (request, reply) => {\n try {\n const task = await createTask(options.rootDir, (request.body ?? {}) as never);\n return reply.code(201).send(task);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.patch(\"/api/tasks/*\", async (request, reply) => {\n const currentPath = decodeURIComponent((request.params as { \"*\": string })[\"*\"] ?? \"\");\n try {\n const task = await updateTask(options.rootDir, currentPath, (request.body ?? {}) as never);\n return reply.send(task);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.delete(\"/api/tasks/*\", async (request, reply) => {\n const currentPath = decodeURIComponent((request.params as { \"*\": string })[\"*\"] ?? \"\");\n try {\n await deleteTask(options.rootDir, currentPath);\n return reply.code(204).send();\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.patch(\"/api/task-fields/*\", async (request, reply) => {\n const currentPath = decodeURIComponent((request.params as { \"*\": string })[\"*\"] ?? \"\");\n try {\n const task = await patchTaskFields(options.rootDir, currentPath, (request.body ?? {}) as never);\n return reply.send(task);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.put(\"/api/order\", async (request, reply) => {\n try {\n const order = parseOrderPayload((request.body as { order?: unknown } | null)?.order ?? []);\n await saveOrder(options.rootDir, order);\n return reply.code(204).send();\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.get(\"/api/config\", async () => {\n try {\n return await readConfig(options.rootDir);\n } catch (error) {\n return { version: 1, taskDirs: [\".\"], order: [] };\n }\n });\n\n app.put(\"/api/config\", async (request, reply) => {\n try {\n const body = request.body as { taskDirs?: unknown; ignorePaths?: unknown } | null;\n const taskDirs = body?.taskDirs;\n if (!Array.isArray(taskDirs) || taskDirs.some((item) => typeof item !== \"string\")) {\n throw new ValidationError(\"taskDirs must be an array of strings.\");\n }\n let ignorePaths: string[] | undefined;\n if (body?.ignorePaths !== undefined) {\n if (!Array.isArray(body.ignorePaths) || body.ignorePaths.some((item) => typeof item !== \"string\")) {\n throw new ValidationError(\"ignorePaths must be an array of strings.\");\n }\n ignorePaths = body.ignorePaths as string[];\n }\n const config = await saveConfig(options.rootDir, taskDirs as string[], ignorePaths);\n return reply.send(config);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.get(\"/api/events\", async (_request, reply) => {\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\"\n });\n reply.raw.write(\"\\n\");\n\n const listener = {\n send(payload: string) {\n reply.raw.write(`data: ${payload}\\n\\n`);\n },\n close() {\n reply.raw.end();\n }\n };\n\n listeners.add(listener);\n reply.raw.on(\"close\", () => {\n listeners.delete(listener);\n });\n\n return reply.hijack();\n });\n\n const watcher = chokidar.watch(options.rootDir, {\n ignoreInitial: true,\n ignored: (watchPath) => watchPath.includes(`${path.sep}.git`) || watchPath.includes(`${path.sep}node_modules`)\n });\n\n watcher.on(\"all\", (eventName, changedPath) => {\n const isMarkdown = changedPath.endsWith(\".md\") || changedPath.endsWith(\".markdown\");\n const isConfigFile = path.basename(changedPath) === \".md-task-viewer.json\";\n if (!isMarkdown && !isConfigFile) {\n return;\n }\n\n const payload = JSON.stringify({\n type: \"tasks-changed\",\n eventName,\n path: path.relative(options.rootDir, changedPath)\n });\n\n for (const listener of listeners) {\n listener.send(payload);\n }\n });\n\n app.addHook(\"onClose\", async () => {\n await watcher.close();\n });\n\n if (clientDir) {\n await app.register(fastifyStatic, {\n root: clientDir,\n prefix: \"/\"\n });\n\n app.setNotFoundHandler(async (request, reply) => {\n if (request.raw.url?.startsWith(\"/api/\")) {\n return reply.code(404).send({ error: \"Not found\" });\n }\n return reply.sendFile(\"index.html\");\n });\n }\n\n return app;\n}\n","import matter from \"gray-matter\";\nimport picomatch from \"picomatch\";\nimport path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport {\n CONFIG_FILE_NAME,\n type ConfigFile,\n type CreateTaskInput,\n type PatchTaskFieldsInput,\n type TaskFrontmatter,\n type TaskListResponse,\n type TaskParseError,\n type TaskPriority,\n type TaskRecord,\n type TaskStatus,\n type UpdateTaskInput\n} from \"./types.js\";\nimport { slugify } from \"./slugify.js\";\n\nconst MARKDOWN_EXTENSIONS = new Set([\".md\", \".markdown\"]);\nconst REQUIRED_PRIORITY: TaskPriority[] = [\"MUST\", \"WANT\"];\nconst REQUIRED_STATUS: TaskStatus[] = [\"TODO\", \"WIP\", \"DONE\"];\n\nexport class ConflictError extends Error {}\nexport class ValidationError extends Error {}\n\nfunction toPosixPath(filePath: string): string {\n return filePath.split(path.sep).join(\"/\");\n}\n\nfunction normalizeRelativePath(candidate: string): string {\n const normalized = toPosixPath(path.posix.normalize(candidate.trim()));\n if (!normalized || normalized === \".\" || normalized.startsWith(\"../\") || normalized.includes(\"/../\")) {\n throw new ValidationError(\"Path must stay within the workspace root.\");\n }\n\n return normalized.replace(/^\\.\\/+/, \"\");\n}\n\nfunction ensureMarkdownExtension(filePath: string): string {\n return path.posix.extname(filePath) ? filePath : `${filePath}.md`;\n}\n\nfunction asUtcISOString(date: Date): string {\n return date.toISOString();\n}\n\nfunction buildDefaults(filePath: string, stats: { birthtime: Date; mtime: Date }): TaskFrontmatter {\n const basename = path.basename(filePath, path.extname(filePath));\n const title = basename.replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (char) => char.toUpperCase());\n\n return {\n title,\n priority: \"WANT\",\n status: \"TODO\",\n createdAt: asUtcISOString(stats.birthtime),\n updatedAt: asUtcISOString(stats.mtime)\n };\n}\n\nfunction splitFrontmatter(data: Record<string, unknown>, statsDefaults: TaskFrontmatter): {\n frontmatter: TaskFrontmatter;\n extraFrontmatter: Record<string, unknown>;\n normalized: boolean;\n} {\n const extraFrontmatter: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (![\"title\", \"priority\", \"status\", \"createdAt\", \"updatedAt\"].includes(key)) {\n extraFrontmatter[key] = value;\n }\n }\n\n const title = typeof data.title === \"string\" && data.title.trim() ? data.title : statsDefaults.title;\n const priority = REQUIRED_PRIORITY.includes(data.priority as TaskPriority)\n ? (data.priority as TaskPriority)\n : statsDefaults.priority;\n const status = REQUIRED_STATUS.includes(data.status as TaskStatus)\n ? (data.status as TaskStatus)\n : statsDefaults.status;\n const createdAt =\n typeof data.createdAt === \"string\" && !Number.isNaN(Date.parse(data.createdAt))\n ? new Date(data.createdAt).toISOString()\n : statsDefaults.createdAt;\n const updatedAt =\n typeof data.updatedAt === \"string\" && !Number.isNaN(Date.parse(data.updatedAt))\n ? new Date(data.updatedAt).toISOString()\n : statsDefaults.updatedAt;\n\n const normalized =\n title !== data.title ||\n priority !== data.priority ||\n status !== data.status ||\n createdAt !== data.createdAt ||\n updatedAt !== data.updatedAt;\n\n return {\n frontmatter: { title, priority, status, createdAt, updatedAt },\n extraFrontmatter,\n normalized\n };\n}\n\nexport function serializeTask(record: TaskRecord): string {\n const data = {\n ...record.extraFrontmatter,\n title: record.frontmatter.title,\n priority: record.frontmatter.priority,\n status: record.frontmatter.status,\n createdAt: record.frontmatter.createdAt,\n updatedAt: record.frontmatter.updatedAt\n };\n\n return matter.stringify(record.content, data);\n}\n\nasync function readDirectoryRecursive(rootDir: string, currentDir: string, results: string[]): Promise<void> {\n const entries = await fs.readdir(currentDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.name === \".git\" || entry.name === \"node_modules\") {\n continue;\n }\n\n const absolutePath = path.join(currentDir, entry.name);\n if (entry.isDirectory()) {\n await readDirectoryRecursive(rootDir, absolutePath, results);\n continue;\n }\n\n if (entry.name === CONFIG_FILE_NAME) {\n continue;\n }\n\n if (!MARKDOWN_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) {\n continue;\n }\n\n results.push(toPosixPath(path.relative(rootDir, absolutePath)));\n }\n}\n\nasync function listMarkdownFiles(rootDir: string, taskDirs: string[], ignorePaths: string[]): Promise<string[]> {\n const results: string[] = [];\n const seen = new Set<string>();\n\n const isIgnored = ignorePaths.length > 0 ? picomatch(ignorePaths) : null;\n\n for (const taskDir of taskDirs) {\n const scanDir = path.resolve(rootDir, taskDir);\n try {\n await fs.access(scanDir);\n } catch {\n continue;\n }\n const dirResults: string[] = [];\n await readDirectoryRecursive(rootDir, scanDir, dirResults);\n for (const filePath of dirResults) {\n if (!seen.has(filePath)) {\n seen.add(filePath);\n if (isIgnored && isIgnored(filePath)) {\n continue;\n }\n results.push(filePath);\n }\n }\n }\n\n return results.sort();\n}\n\nexport async function parseTask(rootDir: string, relativePath: string): Promise<TaskRecord> {\n const absolutePath = path.join(rootDir, relativePath);\n const raw = await fs.readFile(absolutePath, \"utf8\");\n const stats = await fs.stat(absolutePath);\n const parsed = matter(raw);\n const defaults = buildDefaults(relativePath, stats);\n const { frontmatter, extraFrontmatter, normalized } = splitFrontmatter(parsed.data, defaults);\n\n return {\n path: toPosixPath(relativePath),\n content: parsed.content,\n frontmatter,\n extraFrontmatter,\n raw,\n normalized\n };\n}\n\nexport async function readConfig(rootDir: string): Promise<ConfigFile> {\n const configFilePath = path.join(rootDir, CONFIG_FILE_NAME);\n\n try {\n const raw = await fs.readFile(configFilePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<ConfigFile>;\n const taskDirs = Array.isArray(parsed.taskDirs)\n ? parsed.taskDirs.filter((item): item is string => typeof item === \"string\")\n : [\".\"];\n const ignorePaths = Array.isArray(parsed.ignorePaths)\n ? parsed.ignorePaths.filter((item): item is string => typeof item === \"string\")\n : [];\n const order = Array.isArray(parsed.order)\n ? parsed.order.filter((item): item is string => typeof item === \"string\")\n : [];\n return { version: parsed.version ?? 1, taskDirs, ignorePaths, order };\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code !== \"ENOENT\") {\n throw error;\n }\n return { version: 1, taskDirs: [\".\"], ignorePaths: [], order: [] };\n }\n}\n\nasync function reconcileOrder(rootDir: string, taskPaths: string[]): Promise<{ order: string[]; changed: boolean }> {\n const config = await readConfig(rootDir);\n const order = config.order;\n\n const known = new Set(taskPaths);\n const nextOrder = order.filter((item) => known.has(item));\n for (const taskPath of taskPaths) {\n if (!nextOrder.includes(taskPath)) {\n nextOrder.push(taskPath);\n }\n }\n\n const changed = nextOrder.length !== order.length || nextOrder.some((item, index) => item !== order[index]);\n return { order: nextOrder, changed };\n}\n\nexport async function saveOrder(rootDir: string, order: string[]): Promise<void> {\n const normalized = Array.from(\n new Set(\n order.map((item) => ensureMarkdownExtension(normalizeRelativePath(item)))\n )\n );\n const existing = await readConfig(rootDir);\n const payload: ConfigFile = { version: 1, taskDirs: existing.taskDirs, ignorePaths: existing.ignorePaths, order: normalized };\n await fs.writeFile(path.join(rootDir, CONFIG_FILE_NAME), `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function saveConfig(rootDir: string, taskDirs: string[], ignorePaths?: string[]): Promise<ConfigFile> {\n const validated = taskDirs.map((dir) => {\n const normalized = dir.trim().replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\") || \".\";\n if (normalized.startsWith(\"../\") || normalized.includes(\"/../\")) {\n throw new ValidationError(\"taskDirs must stay within the workspace root.\");\n }\n return normalized;\n });\n if (validated.length === 0) {\n throw new ValidationError(\"taskDirs must contain at least one directory.\");\n }\n const existing = await readConfig(rootDir);\n const validatedIgnorePaths = ignorePaths ?? existing.ignorePaths;\n const payload: ConfigFile = { version: 1, taskDirs: validated, ignorePaths: validatedIgnorePaths, order: existing.order };\n await fs.writeFile(path.join(rootDir, CONFIG_FILE_NAME), `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n return payload;\n}\n\nexport async function listTasks(rootDir: string): Promise<TaskListResponse> {\n const config = await readConfig(rootDir);\n const files = await listMarkdownFiles(rootDir, config.taskDirs, config.ignorePaths);\n const errors: TaskParseError[] = [];\n const tasks = await Promise.all(\n files.map(async (relativePath) => {\n try {\n return await parseTask(rootDir, relativePath);\n } catch (error) {\n errors.push({\n path: relativePath,\n message: error instanceof Error ? error.message : \"Unknown parse error\"\n });\n return null;\n }\n })\n );\n\n const taskRecords = tasks.filter((task): task is TaskRecord => task !== null);\n const { order, changed } = await reconcileOrder(\n rootDir,\n taskRecords.map((task) => task.path)\n );\n\n if (changed) {\n await saveOrder(rootDir, order);\n }\n\n const orderIndex = new Map(order.map((item, index) => [item, index]));\n taskRecords.sort((left, right) => {\n const leftIndex = orderIndex.get(left.path) ?? Number.MAX_SAFE_INTEGER;\n const rightIndex = orderIndex.get(right.path) ?? Number.MAX_SAFE_INTEGER;\n return leftIndex - rightIndex || left.path.localeCompare(right.path);\n });\n\n return { tasks: taskRecords, errors };\n}\n\nasync function ensureDirectoryForFile(rootDir: string, relativeFilePath: string): Promise<string> {\n const normalized = ensureMarkdownExtension(normalizeRelativePath(relativeFilePath));\n const absolutePath = path.join(rootDir, normalized);\n const directory = path.dirname(absolutePath);\n await fs.mkdir(directory, { recursive: true });\n return normalized;\n}\n\nasync function nextAvailablePath(rootDir: string, directory: string, title: string): Promise<string> {\n const safeDirectory = directory ? normalizeRelativePath(directory) : \"\";\n const slug = slugify(title);\n const base = safeDirectory ? `${safeDirectory}/${slug}` : slug;\n\n let attempt = 0;\n while (true) {\n const candidate = ensureMarkdownExtension(attempt === 0 ? base : `${base}-${attempt + 1}`);\n try {\n await fs.access(path.join(rootDir, candidate));\n attempt += 1;\n } catch {\n return candidate;\n }\n }\n}\n\nexport async function createTask(rootDir: string, input: CreateTaskInput): Promise<TaskRecord> {\n if (!input.title.trim()) {\n throw new ValidationError(\"Title is required.\");\n }\n\n const now = asUtcISOString(new Date());\n const relativePath = input.path?.trim()\n ? await ensureDirectoryForFile(rootDir, input.path)\n : await nextAvailablePath(rootDir, input.directory ?? \"\", input.title);\n const absolutePath = path.join(rootDir, relativePath);\n\n try {\n await fs.access(absolutePath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n // The target path is available.\n } else if (maybeError.code) {\n throw error;\n } else {\n throw new ValidationError(\"A task already exists at that path.\");\n }\n }\n\n const record: TaskRecord = {\n path: relativePath,\n content: input.content ?? \"\",\n raw: \"\",\n normalized: false,\n extraFrontmatter: input.extraFrontmatter ?? {},\n frontmatter: {\n title: input.title.trim(),\n priority: input.priority ?? \"MUST\",\n status: input.status ?? \"TODO\",\n createdAt: now,\n updatedAt: now\n }\n };\n\n await fs.mkdir(path.dirname(absolutePath), { recursive: true });\n await fs.writeFile(absolutePath, serializeTask(record), \"utf8\");\n\n const current = await listTasks(rootDir);\n await saveOrder(rootDir, current.tasks.map((task) => task.path).concat(relativePath));\n return parseTask(rootDir, relativePath);\n}\n\nexport async function updateTask(rootDir: string, currentPath: string, input: UpdateTaskInput): Promise<TaskRecord> {\n const normalizedCurrentPath = ensureMarkdownExtension(normalizeRelativePath(currentPath));\n const absoluteCurrentPath = path.join(rootDir, normalizedCurrentPath);\n\n let existing: TaskRecord;\n try {\n existing = await parseTask(rootDir, normalizedCurrentPath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n throw new ConflictError(\"The task no longer exists.\");\n }\n throw error;\n }\n\n if (input.baseUpdatedAt && existing.frontmatter.updatedAt !== input.baseUpdatedAt) {\n throw new ConflictError(\"The task changed on disk. Reload before saving.\");\n }\n\n const nextPath = input.path?.trim()\n ? await ensureDirectoryForFile(rootDir, input.path)\n : normalizedCurrentPath;\n const absoluteNextPath = path.join(rootDir, nextPath);\n\n if (nextPath !== normalizedCurrentPath) {\n try {\n await fs.access(absoluteNextPath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n // The target path is available.\n } else if (maybeError.code) {\n throw error;\n } else {\n throw new ValidationError(\"A task already exists at the target path.\");\n }\n }\n }\n\n const record: TaskRecord = {\n path: nextPath,\n raw: existing.raw,\n normalized: false,\n content: input.content,\n extraFrontmatter: input.extraFrontmatter ?? existing.extraFrontmatter,\n frontmatter: {\n title: input.title.trim(),\n priority: input.priority,\n status: input.status,\n createdAt: existing.frontmatter.createdAt,\n updatedAt: asUtcISOString(new Date())\n }\n };\n\n await fs.writeFile(absoluteCurrentPath, serializeTask(record), \"utf8\");\n if (nextPath !== normalizedCurrentPath) {\n await fs.mkdir(path.dirname(absoluteNextPath), { recursive: true });\n await fs.rename(absoluteCurrentPath, absoluteNextPath);\n }\n\n const current = await listTasks(rootDir);\n const updatedOrder = current.tasks.map((task) => task.path);\n await saveOrder(rootDir, updatedOrder);\n return parseTask(rootDir, nextPath);\n}\n\nexport async function deleteTask(rootDir: string, relativePath: string): Promise<void> {\n const normalizedPath = ensureMarkdownExtension(normalizeRelativePath(relativePath));\n const absolutePath = path.join(rootDir, normalizedPath);\n\n try {\n await fs.unlink(absolutePath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n throw new ConflictError(\"The task no longer exists.\");\n }\n throw error;\n }\n\n const current = await listTasks(rootDir);\n await saveOrder(\n rootDir,\n current.tasks.map((task) => task.path)\n );\n}\n\nexport async function patchTaskFields(rootDir: string, currentPath: string, input: PatchTaskFieldsInput): Promise<TaskRecord> {\n const normalizedCurrentPath = ensureMarkdownExtension(normalizeRelativePath(currentPath));\n const absoluteCurrentPath = path.join(rootDir, normalizedCurrentPath);\n\n let existing: TaskRecord;\n try {\n existing = await parseTask(rootDir, normalizedCurrentPath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n throw new ConflictError(\"The task no longer exists.\");\n }\n throw error;\n }\n\n const priority = input.priority && REQUIRED_PRIORITY.includes(input.priority) ? input.priority : existing.frontmatter.priority;\n const status = input.status && REQUIRED_STATUS.includes(input.status) ? input.status : existing.frontmatter.status;\n\n if (priority === existing.frontmatter.priority && status === existing.frontmatter.status) {\n return existing;\n }\n\n const record: TaskRecord = {\n path: normalizedCurrentPath,\n raw: existing.raw,\n normalized: false,\n content: existing.content,\n extraFrontmatter: existing.extraFrontmatter,\n frontmatter: {\n ...existing.frontmatter,\n priority,\n status,\n updatedAt: asUtcISOString(new Date())\n }\n };\n\n await fs.writeFile(absoluteCurrentPath, serializeTask(record), \"utf8\");\n return parseTask(rootDir, normalizedCurrentPath);\n}\n\nexport function parseOrderPayload(input: unknown): string[] {\n if (!Array.isArray(input)) {\n throw new ValidationError(\"Order payload must be an array.\");\n }\n\n return input.map((item) => ensureMarkdownExtension(normalizeRelativePath(String(item))));\n}\n\nexport async function readOrder(rootDir: string): Promise<ConfigFile> {\n const config = await readConfig(rootDir);\n const { order } = await reconcileOrder(\n rootDir,\n (await listTasks(rootDir)).tasks.map((task) => task.path)\n );\n return { version: 1, taskDirs: config.taskDirs, ignorePaths: config.ignorePaths, order };\n}\n\nexport const taskStoreUtils = {\n slugify,\n normalizeRelativePath,\n ensureMarkdownExtension,\n splitFrontmatter,\n buildDefaults\n};\n","export const CONFIG_FILE_NAME = \".md-task-viewer.json\";\n\nexport type TaskPriority = \"MUST\" | \"WANT\";\nexport type TaskStatus = \"TODO\" | \"WIP\" | \"DONE\";\n\nexport interface TaskFrontmatter {\n title: string;\n priority: TaskPriority;\n status: TaskStatus;\n createdAt: string;\n updatedAt: string;\n [key: string]: unknown;\n}\n\nexport interface TaskRecord {\n path: string;\n content: string;\n frontmatter: TaskFrontmatter;\n extraFrontmatter: Record<string, unknown>;\n raw: string;\n normalized: boolean;\n}\n\nexport interface TaskParseError {\n path: string;\n message: string;\n}\n\nexport interface TaskListResponse {\n tasks: TaskRecord[];\n errors: TaskParseError[];\n}\n\nexport interface CreateTaskInput {\n title: string;\n priority?: TaskPriority;\n status?: TaskStatus;\n content?: string;\n directory?: string;\n path?: string;\n extraFrontmatter?: Record<string, unknown>;\n}\n\nexport interface UpdateTaskInput {\n path?: string;\n title: string;\n priority: TaskPriority;\n status: TaskStatus;\n content: string;\n extraFrontmatter?: Record<string, unknown>;\n baseUpdatedAt?: string;\n}\n\nexport interface PatchTaskFieldsInput {\n priority?: TaskPriority;\n status?: TaskStatus;\n}\n\nexport interface ConfigFile {\n version: number;\n taskDirs: string[];\n ignorePaths: string[];\n order: string[];\n}\n","export function slugify(value: string): string {\n const slug = value\n // Unicode結合文字列を正規合成形に統一(例: か+濁点 → が)\n .normalize(\"NFC\")\n // 半角・全角スペース(U+3000)など空白文字をハイフンに変換。近年では \\s は U+3000 にもマッチするが、明示的に記載\n .replace(/[\\s\\u3000]+/g, \"-\")\n // Unicode文字(L)・数字(N)・ハイフン以外を除去(記号や句読点など)\n .replace(/[^\\p{L}\\p{N}-]+/gu, \"\")\n // 先頭・末尾の余分なハイフンを除去\n .replace(/^-+|-+$/g, \"\");\n return slug || \"untitled-task\";\n}\n"],"mappings":"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","names":["path","path","path","path"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/server.ts","../src/taskStore.ts","../src/types.ts","../src/slugify.ts","../src/commandExecutor.ts"],"sourcesContent":["#!/usr/bin/env node\nimport path from \"node:path\";\nimport process from \"node:process\";\nimport open from \"open\";\nimport { createServer } from \"./server.js\";\n\ninterface CliOptions {\n rootDir: string;\n port: number;\n host: string;\n shouldOpen: boolean;\n}\n\nfunction parseArgs(argv: string[]): CliOptions {\n let rootDir = process.cwd();\n let port = 3847;\n let host = \"127.0.0.1\";\n let shouldOpen = true;\n\n for (let index = 0; index < argv.length; index += 1) {\n const current = argv[index];\n if (current === \"--port\") {\n port = Number(argv[index + 1] ?? port);\n index += 1;\n continue;\n }\n if (current === \"--host\") {\n host = argv[index + 1] ?? host;\n index += 1;\n continue;\n }\n if (current === \"--no-open\") {\n shouldOpen = false;\n continue;\n }\n if (!current.startsWith(\"--\")) {\n rootDir = path.resolve(current);\n }\n }\n\n return { rootDir, port, host, shouldOpen };\n}\n\nasync function main(): Promise<void> {\n const options = parseArgs(process.argv.slice(2));\n const app = await createServer({ rootDir: options.rootDir });\n const address = await app.listen({\n port: options.port,\n host: options.host\n });\n\n const browserUrl = address.replace(options.host, options.host === \"0.0.0.0\" ? \"127.0.0.1\" : options.host);\n process.stdout.write(`Markdown Task Viewer\\nRoot: ${options.rootDir}\\nURL: ${browserUrl}\\n`);\n\n if (options.shouldOpen) {\n await open(browserUrl);\n }\n\n const shutdown = async (): Promise<void> => {\n await app.close();\n process.exit(0);\n };\n\n process.on(\"SIGINT\", shutdown);\n process.on(\"SIGTERM\", shutdown);\n}\n\nmain().catch((error) => {\n process.stderr.write(`${error instanceof Error ? error.stack ?? error.message : String(error)}\\n`);\n process.exit(1);\n});\n","import Fastify, { type FastifyInstance } from \"fastify\";\nimport fastifyStatic from \"@fastify/static\";\nimport chokidar from \"chokidar\";\nimport path from \"node:path\";\nimport { fileURLToPath } from \"node:url\";\nimport {\n ConflictError,\n ValidationError,\n createTask,\n deleteTask,\n listTasks,\n parseOrderPayload,\n parseTask,\n patchTaskFields,\n readConfig,\n saveConfig,\n saveOrder,\n updateTask\n} from \"./taskStore.js\";\nimport type { CommandStep } from \"./types.js\";\nimport { executeCommandPipeline } from \"./commandExecutor.js\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\nexport interface CreateServerOptions {\n rootDir: string;\n clientDir?: string | null;\n}\n\nfunction resolveClientDir(explicitClientDir?: string | null): string | null {\n if (explicitClientDir === null) {\n return null;\n }\n if (explicitClientDir) {\n return explicitClientDir;\n }\n return path.resolve(__dirname, \"client\");\n}\n\nfunction sendJsonError(reply: { code: (statusCode: number) => { send: (payload: unknown) => void } }, error: unknown): void {\n if (error instanceof ValidationError) {\n reply.code(400).send({ error: error.message });\n return;\n }\n if (error instanceof ConflictError) {\n reply.code(409).send({ error: error.message });\n return;\n }\n reply.code(500).send({ error: error instanceof Error ? error.message : \"Internal server error\" });\n}\n\nexport async function createServer(options: CreateServerOptions): Promise<FastifyInstance> {\n const app = Fastify({ logger: false });\n const listeners = new Set<{ send: (payload: string) => void; close: () => void }>();\n const clientDir = resolveClientDir(options.clientDir);\n\n app.addHook(\"onClose\", async () => {\n for (const listener of listeners) {\n listener.close();\n }\n });\n\n app.get(\"/api/tasks\", async () => listTasks(options.rootDir));\n\n app.post(\"/api/tasks\", async (request, reply) => {\n try {\n const task = await createTask(options.rootDir, (request.body ?? {}) as never);\n return reply.code(201).send(task);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.patch(\"/api/tasks/*\", async (request, reply) => {\n const currentPath = decodeURIComponent((request.params as { \"*\": string })[\"*\"] ?? \"\");\n try {\n const task = await updateTask(options.rootDir, currentPath, (request.body ?? {}) as never);\n return reply.send(task);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.delete(\"/api/tasks/*\", async (request, reply) => {\n const currentPath = decodeURIComponent((request.params as { \"*\": string })[\"*\"] ?? \"\");\n try {\n await deleteTask(options.rootDir, currentPath);\n return reply.code(204).send();\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.patch(\"/api/task-fields/*\", async (request, reply) => {\n const currentPath = decodeURIComponent((request.params as { \"*\": string })[\"*\"] ?? \"\");\n try {\n const task = await patchTaskFields(options.rootDir, currentPath, (request.body ?? {}) as never);\n return reply.send(task);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.put(\"/api/order\", async (request, reply) => {\n try {\n const order = parseOrderPayload((request.body as { order?: unknown } | null)?.order ?? []);\n await saveOrder(options.rootDir, order);\n return reply.code(204).send();\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.get(\"/api/config\", async () => {\n try {\n return await readConfig(options.rootDir);\n } catch (error) {\n return { version: 1, taskDirs: [\".\"], order: [] };\n }\n });\n\n app.put(\"/api/config\", async (request, reply) => {\n try {\n const body = request.body as { taskDirs?: unknown; ignorePaths?: unknown; commands?: unknown } | null;\n const taskDirs = body?.taskDirs;\n if (!Array.isArray(taskDirs) || taskDirs.some((item) => typeof item !== \"string\")) {\n throw new ValidationError(\"taskDirs must be an array of strings.\");\n }\n let ignorePaths: string[] | undefined;\n if (body?.ignorePaths !== undefined) {\n if (!Array.isArray(body.ignorePaths) || body.ignorePaths.some((item) => typeof item !== \"string\")) {\n throw new ValidationError(\"ignorePaths must be an array of strings.\");\n }\n ignorePaths = body.ignorePaths as string[];\n }\n let commands: CommandStep[] | undefined;\n if (body?.commands !== undefined) {\n if (!Array.isArray(body.commands)) {\n throw new ValidationError(\"commands must be an array.\");\n }\n commands = body.commands as CommandStep[];\n }\n const config = await saveConfig(options.rootDir, taskDirs as string[], ignorePaths, commands);\n return reply.send(config);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.post(\"/api/execute\", async (request, reply) => {\n try {\n const body = request.body as { taskPath?: string; commands?: CommandStep[] } | null;\n const taskPath = body?.taskPath;\n if (!taskPath || typeof taskPath !== \"string\") {\n throw new ValidationError(\"taskPath is required.\");\n }\n\n let task;\n try {\n task = await parseTask(options.rootDir, taskPath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n return reply.code(404).send({ error: \"Task not found.\" });\n }\n throw error;\n }\n\n // Resolve commands: request body > task extraFrontmatter > global config\n let commands = body?.commands;\n if (!commands || commands.length === 0) {\n const taskCommands = task.extraFrontmatter.commands;\n if (Array.isArray(taskCommands) && taskCommands.length > 0) {\n commands = taskCommands as CommandStep[];\n }\n }\n if (!commands || commands.length === 0) {\n const config = await readConfig(options.rootDir);\n commands = config.commands;\n }\n if (!commands || commands.length === 0) {\n throw new ValidationError(\"No commands configured.\");\n }\n\n const result = await executeCommandPipeline(options.rootDir, commands, task);\n return reply.send(result);\n } catch (error) {\n sendJsonError(reply, error);\n }\n });\n\n app.get(\"/api/events\", async (_request, reply) => {\n reply.raw.writeHead(200, {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache, no-transform\",\n Connection: \"keep-alive\"\n });\n reply.raw.write(\"\\n\");\n\n const listener = {\n send(payload: string) {\n reply.raw.write(`data: ${payload}\\n\\n`);\n },\n close() {\n reply.raw.end();\n }\n };\n\n listeners.add(listener);\n reply.raw.on(\"close\", () => {\n listeners.delete(listener);\n });\n\n return reply.hijack();\n });\n\n const watcher = chokidar.watch(options.rootDir, {\n ignoreInitial: true,\n ignored: (watchPath) => watchPath.includes(`${path.sep}.git`) || watchPath.includes(`${path.sep}node_modules`)\n });\n\n watcher.on(\"all\", (eventName, changedPath) => {\n const isMarkdown = changedPath.endsWith(\".md\") || changedPath.endsWith(\".markdown\");\n const isConfigFile = path.basename(changedPath) === \".md-task-viewer.json\";\n if (!isMarkdown && !isConfigFile) {\n return;\n }\n\n const payload = JSON.stringify({\n type: \"tasks-changed\",\n eventName,\n path: path.relative(options.rootDir, changedPath)\n });\n\n for (const listener of listeners) {\n listener.send(payload);\n }\n });\n\n app.addHook(\"onClose\", async () => {\n await watcher.close();\n });\n\n if (clientDir) {\n await app.register(fastifyStatic, {\n root: clientDir,\n prefix: \"/\"\n });\n\n app.setNotFoundHandler(async (request, reply) => {\n if (request.raw.url?.startsWith(\"/api/\")) {\n return reply.code(404).send({ error: \"Not found\" });\n }\n return reply.sendFile(\"index.html\");\n });\n }\n\n return app;\n}\n","import matter from \"gray-matter\";\nimport picomatch from \"picomatch\";\nimport path from \"node:path\";\nimport { promises as fs } from \"node:fs\";\nimport {\n CONFIG_FILE_NAME,\n type CommandStep,\n type ConfigFile,\n type CreateTaskInput,\n type PatchTaskFieldsInput,\n type TaskFrontmatter,\n type TaskListResponse,\n type TaskParseError,\n type TaskPriority,\n type TaskRecord,\n type TaskStatus,\n type UpdateTaskInput\n} from \"./types.js\";\nimport { slugify } from \"./slugify.js\";\n\nconst MARKDOWN_EXTENSIONS = new Set([\".md\", \".markdown\"]);\nconst REQUIRED_PRIORITY: TaskPriority[] = [\"MUST\", \"WANT\"];\nconst REQUIRED_STATUS: TaskStatus[] = [\"TODO\", \"WIP\", \"DONE\"];\n\nexport class ConflictError extends Error {}\nexport class ValidationError extends Error {}\n\nfunction toPosixPath(filePath: string): string {\n return filePath.split(path.sep).join(\"/\");\n}\n\nfunction normalizeRelativePath(candidate: string): string {\n const normalized = toPosixPath(path.posix.normalize(candidate.trim()));\n if (!normalized || normalized === \".\" || normalized.startsWith(\"../\") || normalized.includes(\"/../\")) {\n throw new ValidationError(\"Path must stay within the workspace root.\");\n }\n\n return normalized.replace(/^\\.\\/+/, \"\");\n}\n\nfunction ensureMarkdownExtension(filePath: string): string {\n return path.posix.extname(filePath) ? filePath : `${filePath}.md`;\n}\n\nfunction asUtcISOString(date: Date): string {\n return date.toISOString();\n}\n\nfunction buildDefaults(filePath: string, stats: { birthtime: Date; mtime: Date }): TaskFrontmatter {\n const basename = path.basename(filePath, path.extname(filePath));\n const title = basename.replace(/[-_]+/g, \" \").replace(/\\b\\w/g, (char) => char.toUpperCase());\n\n return {\n title,\n priority: \"WANT\",\n status: \"TODO\",\n createdAt: asUtcISOString(stats.birthtime),\n updatedAt: asUtcISOString(stats.mtime)\n };\n}\n\nfunction splitFrontmatter(data: Record<string, unknown>, statsDefaults: TaskFrontmatter): {\n frontmatter: TaskFrontmatter;\n extraFrontmatter: Record<string, unknown>;\n normalized: boolean;\n} {\n const extraFrontmatter: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(data)) {\n if (![\"title\", \"priority\", \"status\", \"createdAt\", \"updatedAt\"].includes(key)) {\n extraFrontmatter[key] = value;\n }\n }\n\n const title = typeof data.title === \"string\" && data.title.trim() ? data.title : statsDefaults.title;\n const priority = REQUIRED_PRIORITY.includes(data.priority as TaskPriority)\n ? (data.priority as TaskPriority)\n : statsDefaults.priority;\n const status = REQUIRED_STATUS.includes(data.status as TaskStatus)\n ? (data.status as TaskStatus)\n : statsDefaults.status;\n const createdAt =\n typeof data.createdAt === \"string\" && !Number.isNaN(Date.parse(data.createdAt))\n ? new Date(data.createdAt).toISOString()\n : statsDefaults.createdAt;\n const updatedAt =\n typeof data.updatedAt === \"string\" && !Number.isNaN(Date.parse(data.updatedAt))\n ? new Date(data.updatedAt).toISOString()\n : statsDefaults.updatedAt;\n\n const normalized =\n title !== data.title ||\n priority !== data.priority ||\n status !== data.status ||\n createdAt !== data.createdAt ||\n updatedAt !== data.updatedAt;\n\n return {\n frontmatter: { title, priority, status, createdAt, updatedAt },\n extraFrontmatter,\n normalized\n };\n}\n\nexport function serializeTask(record: TaskRecord): string {\n const data = {\n ...record.extraFrontmatter,\n title: record.frontmatter.title,\n priority: record.frontmatter.priority,\n status: record.frontmatter.status,\n createdAt: record.frontmatter.createdAt,\n updatedAt: record.frontmatter.updatedAt\n };\n\n return matter.stringify(record.content, data);\n}\n\nasync function readDirectoryRecursive(rootDir: string, currentDir: string, results: string[]): Promise<void> {\n const entries = await fs.readdir(currentDir, { withFileTypes: true });\n\n for (const entry of entries) {\n if (entry.name === \".git\" || entry.name === \"node_modules\") {\n continue;\n }\n\n const absolutePath = path.join(currentDir, entry.name);\n if (entry.isDirectory()) {\n await readDirectoryRecursive(rootDir, absolutePath, results);\n continue;\n }\n\n if (entry.name === CONFIG_FILE_NAME) {\n continue;\n }\n\n if (!MARKDOWN_EXTENSIONS.has(path.extname(entry.name).toLowerCase())) {\n continue;\n }\n\n results.push(toPosixPath(path.relative(rootDir, absolutePath)));\n }\n}\n\nasync function listMarkdownFiles(rootDir: string, taskDirs: string[], ignorePaths: string[]): Promise<string[]> {\n const results: string[] = [];\n const seen = new Set<string>();\n\n const isIgnored = ignorePaths.length > 0 ? picomatch(ignorePaths) : null;\n\n for (const taskDir of taskDirs) {\n const scanDir = path.resolve(rootDir, taskDir);\n try {\n await fs.access(scanDir);\n } catch {\n continue;\n }\n const dirResults: string[] = [];\n await readDirectoryRecursive(rootDir, scanDir, dirResults);\n for (const filePath of dirResults) {\n if (!seen.has(filePath)) {\n seen.add(filePath);\n if (isIgnored && isIgnored(filePath)) {\n continue;\n }\n results.push(filePath);\n }\n }\n }\n\n return results.sort();\n}\n\nexport async function parseTask(rootDir: string, relativePath: string): Promise<TaskRecord> {\n const absolutePath = path.join(rootDir, relativePath);\n const raw = await fs.readFile(absolutePath, \"utf8\");\n const stats = await fs.stat(absolutePath);\n const parsed = matter(raw);\n const defaults = buildDefaults(relativePath, stats);\n const { frontmatter, extraFrontmatter, normalized } = splitFrontmatter(parsed.data, defaults);\n\n return {\n path: toPosixPath(relativePath),\n content: parsed.content,\n frontmatter,\n extraFrontmatter,\n raw,\n normalized\n };\n}\n\nexport async function readConfig(rootDir: string): Promise<ConfigFile> {\n const configFilePath = path.join(rootDir, CONFIG_FILE_NAME);\n\n try {\n const raw = await fs.readFile(configFilePath, \"utf8\");\n const parsed = JSON.parse(raw) as Partial<ConfigFile>;\n const taskDirs = Array.isArray(parsed.taskDirs)\n ? parsed.taskDirs.filter((item): item is string => typeof item === \"string\")\n : [\".\"];\n const ignorePaths = Array.isArray(parsed.ignorePaths)\n ? parsed.ignorePaths.filter((item): item is string => typeof item === \"string\")\n : [];\n const order = Array.isArray(parsed.order)\n ? parsed.order.filter((item): item is string => typeof item === \"string\")\n : [];\n const commands = Array.isArray(parsed.commands)\n ? (parsed.commands as CommandStep[])\n : undefined;\n return { version: parsed.version ?? 1, taskDirs, ignorePaths, order, commands };\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code !== \"ENOENT\") {\n throw error;\n }\n return { version: 1, taskDirs: [\".\"], ignorePaths: [], order: [] };\n }\n}\n\nasync function reconcileOrder(rootDir: string, taskPaths: string[]): Promise<{ order: string[]; changed: boolean }> {\n const config = await readConfig(rootDir);\n const order = config.order;\n\n const known = new Set(taskPaths);\n const nextOrder = order.filter((item) => known.has(item));\n for (const taskPath of taskPaths) {\n if (!nextOrder.includes(taskPath)) {\n nextOrder.push(taskPath);\n }\n }\n\n const changed = nextOrder.length !== order.length || nextOrder.some((item, index) => item !== order[index]);\n return { order: nextOrder, changed };\n}\n\nexport async function saveOrder(rootDir: string, order: string[]): Promise<void> {\n const normalized = Array.from(\n new Set(\n order.map((item) => ensureMarkdownExtension(normalizeRelativePath(item)))\n )\n );\n const existing = await readConfig(rootDir);\n const payload: ConfigFile = { version: 1, taskDirs: existing.taskDirs, ignorePaths: existing.ignorePaths, order: normalized, commands: existing.commands };\n await fs.writeFile(path.join(rootDir, CONFIG_FILE_NAME), `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n}\n\nexport async function saveConfig(rootDir: string, taskDirs: string[], ignorePaths?: string[], commands?: CommandStep[]): Promise<ConfigFile> {\n const validated = taskDirs.map((dir) => {\n const normalized = dir.trim().replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\") || \".\";\n if (normalized.startsWith(\"../\") || normalized.includes(\"/../\")) {\n throw new ValidationError(\"taskDirs must stay within the workspace root.\");\n }\n return normalized;\n });\n if (validated.length === 0) {\n throw new ValidationError(\"taskDirs must contain at least one directory.\");\n }\n const existing = await readConfig(rootDir);\n const validatedIgnorePaths = ignorePaths ?? existing.ignorePaths;\n const validatedCommands = commands !== undefined ? commands : existing.commands;\n const payload: ConfigFile = { version: 1, taskDirs: validated, ignorePaths: validatedIgnorePaths, order: existing.order, commands: validatedCommands };\n await fs.writeFile(path.join(rootDir, CONFIG_FILE_NAME), `${JSON.stringify(payload, null, 2)}\\n`, \"utf8\");\n return payload;\n}\n\nexport async function listTasks(rootDir: string): Promise<TaskListResponse> {\n const config = await readConfig(rootDir);\n const files = await listMarkdownFiles(rootDir, config.taskDirs, config.ignorePaths);\n const errors: TaskParseError[] = [];\n const tasks = await Promise.all(\n files.map(async (relativePath) => {\n try {\n return await parseTask(rootDir, relativePath);\n } catch (error) {\n errors.push({\n path: relativePath,\n message: error instanceof Error ? error.message : \"Unknown parse error\"\n });\n return null;\n }\n })\n );\n\n const taskRecords = tasks.filter((task): task is TaskRecord => task !== null);\n const { order, changed } = await reconcileOrder(\n rootDir,\n taskRecords.map((task) => task.path)\n );\n\n if (changed) {\n await saveOrder(rootDir, order);\n }\n\n const orderIndex = new Map(order.map((item, index) => [item, index]));\n taskRecords.sort((left, right) => {\n const leftIndex = orderIndex.get(left.path) ?? Number.MAX_SAFE_INTEGER;\n const rightIndex = orderIndex.get(right.path) ?? Number.MAX_SAFE_INTEGER;\n return leftIndex - rightIndex || left.path.localeCompare(right.path);\n });\n\n return { tasks: taskRecords, errors };\n}\n\nasync function ensureDirectoryForFile(rootDir: string, relativeFilePath: string): Promise<string> {\n const normalized = ensureMarkdownExtension(normalizeRelativePath(relativeFilePath));\n const absolutePath = path.join(rootDir, normalized);\n const directory = path.dirname(absolutePath);\n await fs.mkdir(directory, { recursive: true });\n return normalized;\n}\n\nasync function nextAvailablePath(rootDir: string, directory: string, title: string): Promise<string> {\n const safeDirectory = directory ? normalizeRelativePath(directory) : \"\";\n const slug = slugify(title);\n const base = safeDirectory ? `${safeDirectory}/${slug}` : slug;\n\n let attempt = 0;\n while (true) {\n const candidate = ensureMarkdownExtension(attempt === 0 ? base : `${base}-${attempt + 1}`);\n try {\n await fs.access(path.join(rootDir, candidate));\n attempt += 1;\n } catch {\n return candidate;\n }\n }\n}\n\nexport async function createTask(rootDir: string, input: CreateTaskInput): Promise<TaskRecord> {\n if (!input.title.trim()) {\n throw new ValidationError(\"Title is required.\");\n }\n\n const now = asUtcISOString(new Date());\n const relativePath = input.path?.trim()\n ? await ensureDirectoryForFile(rootDir, input.path)\n : await nextAvailablePath(rootDir, input.directory ?? \"\", input.title);\n const absolutePath = path.join(rootDir, relativePath);\n\n try {\n await fs.access(absolutePath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n // The target path is available.\n } else if (maybeError.code) {\n throw error;\n } else {\n throw new ValidationError(\"A task already exists at that path.\");\n }\n }\n\n const record: TaskRecord = {\n path: relativePath,\n content: input.content ?? \"\",\n raw: \"\",\n normalized: false,\n extraFrontmatter: input.extraFrontmatter ?? {},\n frontmatter: {\n title: input.title.trim(),\n priority: input.priority ?? \"MUST\",\n status: input.status ?? \"TODO\",\n createdAt: now,\n updatedAt: now\n }\n };\n\n await fs.mkdir(path.dirname(absolutePath), { recursive: true });\n await fs.writeFile(absolutePath, serializeTask(record), \"utf8\");\n\n const current = await listTasks(rootDir);\n await saveOrder(rootDir, current.tasks.map((task) => task.path).concat(relativePath));\n return parseTask(rootDir, relativePath);\n}\n\nexport async function updateTask(rootDir: string, currentPath: string, input: UpdateTaskInput): Promise<TaskRecord> {\n const normalizedCurrentPath = ensureMarkdownExtension(normalizeRelativePath(currentPath));\n const absoluteCurrentPath = path.join(rootDir, normalizedCurrentPath);\n\n let existing: TaskRecord;\n try {\n existing = await parseTask(rootDir, normalizedCurrentPath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n throw new ConflictError(\"The task no longer exists.\");\n }\n throw error;\n }\n\n if (input.baseUpdatedAt && existing.frontmatter.updatedAt !== input.baseUpdatedAt) {\n throw new ConflictError(\"The task changed on disk. Reload before saving.\");\n }\n\n const nextPath = input.path?.trim()\n ? await ensureDirectoryForFile(rootDir, input.path)\n : normalizedCurrentPath;\n const absoluteNextPath = path.join(rootDir, nextPath);\n\n if (nextPath !== normalizedCurrentPath) {\n try {\n await fs.access(absoluteNextPath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n // The target path is available.\n } else if (maybeError.code) {\n throw error;\n } else {\n throw new ValidationError(\"A task already exists at the target path.\");\n }\n }\n }\n\n const record: TaskRecord = {\n path: nextPath,\n raw: existing.raw,\n normalized: false,\n content: input.content,\n extraFrontmatter: input.extraFrontmatter ?? existing.extraFrontmatter,\n frontmatter: {\n title: input.title.trim(),\n priority: input.priority,\n status: input.status,\n createdAt: existing.frontmatter.createdAt,\n updatedAt: asUtcISOString(new Date())\n }\n };\n\n await fs.writeFile(absoluteCurrentPath, serializeTask(record), \"utf8\");\n if (nextPath !== normalizedCurrentPath) {\n await fs.mkdir(path.dirname(absoluteNextPath), { recursive: true });\n await fs.rename(absoluteCurrentPath, absoluteNextPath);\n }\n\n const current = await listTasks(rootDir);\n const updatedOrder = current.tasks.map((task) => task.path);\n await saveOrder(rootDir, updatedOrder);\n return parseTask(rootDir, nextPath);\n}\n\nexport async function deleteTask(rootDir: string, relativePath: string): Promise<void> {\n const normalizedPath = ensureMarkdownExtension(normalizeRelativePath(relativePath));\n const absolutePath = path.join(rootDir, normalizedPath);\n\n try {\n await fs.unlink(absolutePath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n throw new ConflictError(\"The task no longer exists.\");\n }\n throw error;\n }\n\n const current = await listTasks(rootDir);\n await saveOrder(\n rootDir,\n current.tasks.map((task) => task.path)\n );\n}\n\nexport async function patchTaskFields(rootDir: string, currentPath: string, input: PatchTaskFieldsInput): Promise<TaskRecord> {\n const normalizedCurrentPath = ensureMarkdownExtension(normalizeRelativePath(currentPath));\n const absoluteCurrentPath = path.join(rootDir, normalizedCurrentPath);\n\n let existing: TaskRecord;\n try {\n existing = await parseTask(rootDir, normalizedCurrentPath);\n } catch (error) {\n const maybeError = error as NodeJS.ErrnoException;\n if (maybeError.code === \"ENOENT\") {\n throw new ConflictError(\"The task no longer exists.\");\n }\n throw error;\n }\n\n const priority = input.priority && REQUIRED_PRIORITY.includes(input.priority) ? input.priority : existing.frontmatter.priority;\n const status = input.status && REQUIRED_STATUS.includes(input.status) ? input.status : existing.frontmatter.status;\n\n if (priority === existing.frontmatter.priority && status === existing.frontmatter.status) {\n return existing;\n }\n\n const record: TaskRecord = {\n path: normalizedCurrentPath,\n raw: existing.raw,\n normalized: false,\n content: existing.content,\n extraFrontmatter: existing.extraFrontmatter,\n frontmatter: {\n ...existing.frontmatter,\n priority,\n status,\n updatedAt: asUtcISOString(new Date())\n }\n };\n\n await fs.writeFile(absoluteCurrentPath, serializeTask(record), \"utf8\");\n return parseTask(rootDir, normalizedCurrentPath);\n}\n\nexport function parseOrderPayload(input: unknown): string[] {\n if (!Array.isArray(input)) {\n throw new ValidationError(\"Order payload must be an array.\");\n }\n\n return input.map((item) => ensureMarkdownExtension(normalizeRelativePath(String(item))));\n}\n\nexport async function readOrder(rootDir: string): Promise<ConfigFile> {\n const config = await readConfig(rootDir);\n const { order } = await reconcileOrder(\n rootDir,\n (await listTasks(rootDir)).tasks.map((task) => task.path)\n );\n return { version: 1, taskDirs: config.taskDirs, ignorePaths: config.ignorePaths, order, commands: config.commands };\n}\n\nexport const taskStoreUtils = {\n slugify,\n normalizeRelativePath,\n ensureMarkdownExtension,\n splitFrontmatter,\n buildDefaults\n};\n","export const CONFIG_FILE_NAME = \".md-task-viewer.json\";\n\nexport type TaskPriority = \"MUST\" | \"WANT\";\nexport type TaskStatus = \"TODO\" | \"WIP\" | \"DONE\";\n\nexport interface TaskFrontmatter {\n title: string;\n priority: TaskPriority;\n status: TaskStatus;\n createdAt: string;\n updatedAt: string;\n [key: string]: unknown;\n}\n\nexport interface TaskRecord {\n path: string;\n content: string;\n frontmatter: TaskFrontmatter;\n extraFrontmatter: Record<string, unknown>;\n raw: string;\n normalized: boolean;\n}\n\nexport interface TaskParseError {\n path: string;\n message: string;\n}\n\nexport interface TaskListResponse {\n tasks: TaskRecord[];\n errors: TaskParseError[];\n}\n\nexport interface CreateTaskInput {\n title: string;\n priority?: TaskPriority;\n status?: TaskStatus;\n content?: string;\n directory?: string;\n path?: string;\n extraFrontmatter?: Record<string, unknown>;\n}\n\nexport interface UpdateTaskInput {\n path?: string;\n title: string;\n priority: TaskPriority;\n status: TaskStatus;\n content: string;\n extraFrontmatter?: Record<string, unknown>;\n baseUpdatedAt?: string;\n}\n\nexport interface PatchTaskFieldsInput {\n priority?: TaskPriority;\n status?: TaskStatus;\n}\n\nexport interface CommandStep {\n command: string;\n passBody?: \"arg\" | \"stdin\" | false;\n}\n\nexport interface CommandExecutionResult {\n stdout: string;\n stderr: string;\n exitCode: number;\n duration: number;\n}\n\nexport interface ConfigFile {\n version: number;\n taskDirs: string[];\n ignorePaths: string[];\n order: string[];\n commands?: CommandStep[];\n}\n","export function slugify(value: string): string {\n const slug = value\n // Unicode結合文字列を正規合成形に統一(例: か+濁点 → が)\n .normalize(\"NFC\")\n // 半角・全角スペース(U+3000)など空白文字をハイフンに変換。近年では \\s は U+3000 にもマッチするが、明示的に記載\n .replace(/[\\s\\u3000]+/g, \"-\")\n // Unicode文字(L)・数字(N)・ハイフン以外を除去(記号や句読点など)\n .replace(/[^\\p{L}\\p{N}-]+/gu, \"\")\n // 先頭・末尾の余分なハイフンを除去\n .replace(/^-+|-+$/g, \"\");\n return slug || \"untitled-task\";\n}\n","import { spawn } from \"node:child_process\";\nimport path from \"node:path\";\nimport type { CommandStep, CommandExecutionResult, TaskRecord } from \"./types.js\";\n\nconst TIMEOUT_MS = 30_000;\n\nconst VARIABLE_PATTERN = /\\$\\{?(TASK_TITLE|TASK_FILEPATH|TASK_BODY)\\}?/g;\n\nexport function substituteVariables(command: string, vars: Record<string, string>): string {\n return command.replace(VARIABLE_PATTERN, (_match, name: string) => vars[name] ?? \"\");\n}\n\nexport async function executeCommandPipeline(\n rootDir: string,\n steps: CommandStep[],\n task: TaskRecord\n): Promise<CommandExecutionResult> {\n if (steps.length === 0) {\n return { stdout: \"\", stderr: \"\", exitCode: 0, duration: 0 };\n }\n\n const absoluteFilePath = path.resolve(rootDir, task.path);\n const vars: Record<string, string> = {\n TASK_TITLE: task.frontmatter.title,\n TASK_FILEPATH: absoluteFilePath,\n TASK_BODY: task.content\n };\n\n const startTime = Date.now();\n\n return new Promise<CommandExecutionResult>((resolve) => {\n const resolvedCommands = steps.map((step, index) => {\n let cmd = substituteVariables(step.command, vars);\n if (index === 0 && step.passBody === \"arg\") {\n const escaped = task.content.replace(/'/g, \"'\\\\''\");\n cmd = `${cmd} '${escaped}'`;\n }\n return cmd;\n });\n\n const processes: ReturnType<typeof spawn>[] = [];\n for (let index = 0; index < resolvedCommands.length; index++) {\n const proc = spawn(resolvedCommands[index], {\n shell: true,\n cwd: rootDir,\n stdio: [\"pipe\", \"pipe\", \"pipe\"]\n });\n\n // pipe stdout of previous process to stdin of current\n if (index > 0) {\n const prev = processes[index - 1];\n if (prev?.stdout) {\n prev.stdout.pipe(proc.stdin!);\n }\n }\n\n processes.push(proc);\n }\n\n // Handle first command's passBody option\n const firstStep = steps[0];\n const firstProc = processes[0];\n if (firstStep.passBody === \"stdin\" && firstProc.stdin) {\n firstProc.stdin.write(task.content);\n }\n // Always close first process stdin (body written above if passBody is stdin)\n firstProc.stdin?.end();\n\n const lastProc = processes[processes.length - 1];\n const stdoutChunks: Buffer[] = [];\n const stderrChunks: Buffer[] = [];\n\n lastProc.stdout?.on(\"data\", (chunk: Buffer) => stdoutChunks.push(chunk));\n lastProc.stderr?.on(\"data\", (chunk: Buffer) => stderrChunks.push(chunk));\n\n // Collect stderr from all intermediate processes too\n for (let i = 0; i < processes.length - 1; i++) {\n processes[i].stderr?.on(\"data\", (chunk: Buffer) => stderrChunks.push(chunk));\n }\n\n const timeout = setTimeout(() => {\n for (const proc of processes) {\n proc.kill(\"SIGTERM\");\n }\n }, TIMEOUT_MS);\n\n lastProc.on(\"close\", (code) => {\n clearTimeout(timeout);\n resolve({\n stdout: Buffer.concat(stdoutChunks).toString(\"utf8\"),\n stderr: Buffer.concat(stderrChunks).toString(\"utf8\"),\n exitCode: code ?? 1,\n duration: Date.now() - startTime\n });\n });\n\n lastProc.on(\"error\", (err) => {\n clearTimeout(timeout);\n resolve({\n stdout: \"\",\n stderr: err.message,\n exitCode: 1,\n duration: Date.now() - startTime\n });\n });\n\n // Handle errors on intermediate processes\n for (let i = 0; i < processes.length - 1; i++) {\n processes[i].on(\"error\", (err) => {\n stderrChunks.push(Buffer.from(err.message));\n });\n }\n });\n}\n"],"mappings":"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","names":["path","path","path","path","path"]}