@inteeka/task-cli 0.1.4 → 0.1.6

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
@@ -416,6 +416,9 @@ function sleep(ms) {
416
416
 
417
417
  // src/api/client.ts
418
418
  import { request as request3 } from "undici";
419
+ import { mkdir as mkdir2, writeFile as writeFile2 } from "fs/promises";
420
+ import { homedir as homedir2 } from "os";
421
+ import { join as join2 } from "path";
419
422
 
420
423
  // src/auth/refresh.ts
421
424
  import { request as request2 } from "undici";
@@ -480,6 +483,32 @@ async function manualRefresh() {
480
483
  }
481
484
 
482
485
  // src/api/client.ts
486
+ async function dumpServerError(method, path, status, rawBody, headers) {
487
+ try {
488
+ const dir = join2(homedir2(), ".cache", "task", "api-debug");
489
+ await mkdir2(dir, { recursive: true });
490
+ const file = join2(dir, `${Date.now()}-${status}.log`);
491
+ const safeHeaders = { ...headers };
492
+ delete safeHeaders["Authorization"];
493
+ delete safeHeaders["authorization"];
494
+ await writeFile2(
495
+ file,
496
+ [
497
+ `## ${method} ${path}`,
498
+ `## status ${status}`,
499
+ "",
500
+ "## request_headers",
501
+ JSON.stringify(safeHeaders, null, 2),
502
+ "",
503
+ "## response_body",
504
+ rawBody || "(empty)"
505
+ ].join("\n")
506
+ );
507
+ process.stderr.write(` (server response saved to ${file})
508
+ `);
509
+ } catch {
510
+ }
511
+ }
483
512
  async function apiCall(method, path, options = {}) {
484
513
  const authenticated = options.authenticated !== false;
485
514
  let creds = null;
@@ -537,19 +566,32 @@ async function apiCall(method, path, options = {}) {
537
566
  );
538
567
  }
539
568
  const status = res.statusCode;
540
- let parsed;
569
+ let rawBody;
541
570
  try {
542
- parsed = await res.body.json();
571
+ rawBody = await res.body.text();
543
572
  } catch {
544
- parsed = void 0;
573
+ rawBody = "";
574
+ }
575
+ let parsed;
576
+ if (rawBody) {
577
+ try {
578
+ parsed = JSON.parse(rawBody);
579
+ } catch {
580
+ parsed = void 0;
581
+ }
545
582
  }
546
583
  if (status >= 200 && status < 300) {
547
584
  const body = parsed;
548
585
  return { ok: true, status, data: body?.data ?? parsed };
549
586
  }
587
+ if (status >= 500) {
588
+ await dumpServerError(method, path, status, rawBody, headers).catch(() => void 0);
589
+ }
550
590
  const errBody = parsed;
551
591
  const code = errBody?.error?.code ?? `HTTP_${status}`;
552
- const message = errBody?.error?.message ?? `Request failed with status ${status}`;
592
+ const requestId = errBody?.error?.request_id;
593
+ const baseMessage = errBody?.error?.message ?? `Request failed with status ${status}`;
594
+ const message = requestId ? `${baseMessage} (request_id: ${requestId})` : baseMessage;
553
595
  if (status === 401 && (code === "UNAUTHORIZED" || code === "TOKEN_EXPIRED" || code === "INVALID_GRANT")) {
554
596
  await clearCredentials();
555
597
  throw new CliError(
@@ -591,10 +633,10 @@ async function apiCallOrThrow(method, path, options = {}) {
591
633
  }
592
634
 
593
635
  // src/config/local-config.ts
594
- import { mkdir as mkdir2, readFile as readFile2, writeFile as writeFile2 } from "fs/promises";
595
- import { homedir as homedir2 } from "os";
596
- import { dirname as dirname2, join as join2 } from "path";
597
- var CONFIG_PATH = join2(homedir2(), ".config", "task", "config.json");
636
+ import { mkdir as mkdir3, readFile as readFile2, writeFile as writeFile3 } from "fs/promises";
637
+ import { homedir as homedir3 } from "os";
638
+ import { dirname as dirname2, join as join3 } from "path";
639
+ var CONFIG_PATH = join3(homedir3(), ".config", "task", "config.json");
598
640
  var DEFAULT_CONFIG = {
599
641
  api_url: process.env["TASK_API_URL"] ?? "http://localhost:3400",
600
642
  default_project: null,
@@ -614,8 +656,8 @@ async function readLocalConfig() {
614
656
  }
615
657
  }
616
658
  async function writeLocalConfig(config) {
617
- await mkdir2(dirname2(CONFIG_PATH), { recursive: true });
618
- await writeFile2(CONFIG_PATH, JSON.stringify(config, null, 2));
659
+ await mkdir3(dirname2(CONFIG_PATH), { recursive: true });
660
+ await writeFile3(CONFIG_PATH, JSON.stringify(config, null, 2));
619
661
  }
620
662
  async function setConfigValue(key, value) {
621
663
  const cfg = await readLocalConfig();
@@ -734,14 +776,14 @@ function registerAuthRefresh(program2) {
734
776
  }
735
777
 
736
778
  // src/commands/link.ts
737
- import { readFile as readFile4, writeFile as writeFile4, appendFile, access } from "fs/promises";
779
+ import { readFile as readFile4, writeFile as writeFile5, appendFile, access } from "fs/promises";
738
780
  import { constants as fsConstants } from "fs";
739
- import { join as join4 } from "path";
781
+ import { join as join5 } from "path";
740
782
  import inquirer from "inquirer";
741
783
 
742
784
  // src/config/project.ts
743
- import { mkdir as mkdir3, readFile as readFile3, writeFile as writeFile3, unlink as unlink2 } from "fs/promises";
744
- import { dirname as dirname3, join as join3, resolve } from "path";
785
+ import { mkdir as mkdir4, readFile as readFile3, writeFile as writeFile4, unlink as unlink2 } from "fs/promises";
786
+ import { dirname as dirname3, join as join4, resolve } from "path";
745
787
  import { execSync } from "child_process";
746
788
  function findRepoRoot(start = process.cwd()) {
747
789
  try {
@@ -752,7 +794,7 @@ function findRepoRoot(start = process.cwd()) {
752
794
  }
753
795
  }
754
796
  function configPath(repoRoot) {
755
- return join3(repoRoot ?? findRepoRoot(), ".task", "config.json");
797
+ return join4(repoRoot ?? findRepoRoot(), ".task", "config.json");
756
798
  }
757
799
  async function readProjectConfig(repoRoot) {
758
800
  const path = configPath(repoRoot);
@@ -766,8 +808,8 @@ async function readProjectConfig(repoRoot) {
766
808
  }
767
809
  async function writeProjectConfig(config, repoRoot) {
768
810
  const path = configPath(repoRoot);
769
- await mkdir3(dirname3(path), { recursive: true });
770
- await writeFile3(path, JSON.stringify(config, null, 2));
811
+ await mkdir4(dirname3(path), { recursive: true });
812
+ await writeFile4(path, JSON.stringify(config, null, 2));
771
813
  }
772
814
  async function clearProjectConfig(repoRoot) {
773
815
  const path = configPath(repoRoot);
@@ -864,7 +906,7 @@ async function resolveProject(projects, opts) {
864
906
  return picked;
865
907
  }
866
908
  async function ensureGitignored(repoRoot) {
867
- const gitignorePath = join4(repoRoot, ".gitignore");
909
+ const gitignorePath = join5(repoRoot, ".gitignore");
868
910
  let existing = null;
869
911
  try {
870
912
  await access(gitignorePath, fsConstants.F_OK);
@@ -879,7 +921,7 @@ async function ensureGitignored(repoRoot) {
879
921
  await appendFile(gitignorePath, block);
880
922
  return "added";
881
923
  }
882
- await writeFile4(gitignorePath, "# task CLI link config\n.task/\n");
924
+ await writeFile5(gitignorePath, "# task CLI link config\n.task/\n");
883
925
  return "created";
884
926
  }
885
927
 
@@ -1108,9 +1150,9 @@ import inquirer2 from "inquirer";
1108
1150
 
1109
1151
  // src/agent/agent-service.ts
1110
1152
  import { spawn } from "child_process";
1111
- import { mkdir as mkdir4, writeFile as writeFile5 } from "fs/promises";
1112
- import { homedir as homedir3 } from "os";
1113
- import { join as join5 } from "path";
1153
+ import { mkdir as mkdir5, writeFile as writeFile6 } from "fs/promises";
1154
+ import { homedir as homedir4 } from "os";
1155
+ import { join as join6 } from "path";
1114
1156
 
1115
1157
  // src/agent/allowed-tools.ts
1116
1158
  var ALLOWED_TOOLS = CLI_ALLOWED_TOOLS;
@@ -1167,10 +1209,10 @@ async function runAgent(args) {
1167
1209
  let outputLogPath = null;
1168
1210
  let logHandle = null;
1169
1211
  if (args.silent) {
1170
- const dir = join5(homedir3(), ".cache", "task", "runs");
1171
- await mkdir4(dir, { recursive: true });
1172
- outputLogPath = join5(dir, `${args.runId}.log`);
1173
- await writeFile5(outputLogPath, "");
1212
+ const dir = join6(homedir4(), ".cache", "task", "runs");
1213
+ await mkdir5(dir, { recursive: true });
1214
+ outputLogPath = join6(dir, `${args.runId}.log`);
1215
+ await writeFile6(outputLogPath, "");
1174
1216
  const { createWriteStream } = await import("fs");
1175
1217
  logHandle = createWriteStream(outputLogPath, { flags: "a" });
1176
1218
  }
@@ -1706,9 +1748,9 @@ function autopilotExitCode(code, status) {
1706
1748
 
1707
1749
  // src/scan/llm.ts
1708
1750
  import { spawn as spawn2 } from "child_process";
1709
- import { mkdir as mkdir5, writeFile as writeFile6 } from "fs/promises";
1710
- import { homedir as homedir4 } from "os";
1711
- import { join as join6 } from "path";
1751
+ import { mkdir as mkdir6, writeFile as writeFile7 } from "fs/promises";
1752
+ import { homedir as homedir5 } from "os";
1753
+ import { join as join7 } from "path";
1712
1754
  var FIX_PROMPT_JSON_SCHEMA = {
1713
1755
  type: "object",
1714
1756
  required: ["summary", "suspected_files", "proposed_changes", "confidence"],
@@ -1900,10 +1942,10 @@ function readEnvelopeTokens(raw, userPrompt, innerText) {
1900
1942
  async function maybeDumpDebug(ticketId, stdout, stderr) {
1901
1943
  if (!DEBUG && stdout.length === 0 && stderr.length === 0) return null;
1902
1944
  try {
1903
- const dir = join6(homedir4(), ".cache", "task", "scan-debug");
1904
- await mkdir5(dir, { recursive: true });
1905
- const path = join6(dir, `${ticketId}-${Date.now()}.log`);
1906
- await writeFile6(
1945
+ const dir = join7(homedir5(), ".cache", "task", "scan-debug");
1946
+ await mkdir6(dir, { recursive: true });
1947
+ const path = join7(dir, `${ticketId}-${Date.now()}.log`);
1948
+ await writeFile7(
1907
1949
  path,
1908
1950
  ["## ticket_id", ticketId, "", "## stdout", stdout, "", "## stderr", stderr].join("\n")
1909
1951
  );
@@ -1970,7 +2012,13 @@ function parseStructuredJson(raw) {
1970
2012
  function registerScan(program2) {
1971
2013
  program2.command("scan").description(
1972
2014
  "Drive the AI fix-prompt autopilot loop locally \u2014 same flow as the /task-autopilot skill, run by the CLI binary"
1973
- ).option("--project <slugOrId>", "Restrict to one project (default: every visible project)").option("--max <n>", "Max submissions per project token", "50").option("--batch <n>", "Tickets per /prepare batch (1-10)", "5").option("--api-url <url>", "Override TASK_API_URL").option("--silent", "Suppress per-ticket progress chrome").action(async (opts) => {
2015
+ ).option(
2016
+ "--project <slugOrId>",
2017
+ "Restrict to one project (default: the linked project from .task/config.json, falling back to every visible project if the repo is not linked)"
2018
+ ).option(
2019
+ "--all-projects",
2020
+ "Override the linked-project default and scan every CLI-eligible project the admin token can see"
2021
+ ).option("--max <n>", "Max submissions per project token", "50").option("--batch <n>", "Tickets per /prepare batch (1-10)", "5").option("--api-url <url>", "Override TASK_API_URL").option("--silent", "Suppress per-ticket progress chrome").action(async (opts) => {
1974
2022
  await runScan(opts);
1975
2023
  });
1976
2024
  }
@@ -1992,10 +2040,26 @@ async function runScan(opts) {
1992
2040
  );
1993
2041
  }
1994
2042
  const localCfg = await readLocalConfig();
1995
- const apiUrl = (opts.apiUrl ?? process.env["TASK_API_URL"] ?? localCfg.api_url ?? "http://localhost:3400").replace(/\/$/, "");
2043
+ const linkedProject = await readProjectConfig(findRepoRoot());
2044
+ const apiUrl = (opts.apiUrl ?? process.env["TASK_API_URL"] ?? localCfg.api_url ?? linkedProject?.api_url ?? "http://localhost:3400").replace(/\/$/, "");
1996
2045
  const max = clampInt(opts.max, 1, 500, 50);
1997
2046
  const batchSize = clampInt(opts.batch, 1, 10, 5);
1998
2047
  const silent = !!opts.silent || localCfg.silent;
2048
+ if (opts.project && opts.allProjects) {
2049
+ throw new CliError(
2050
+ CLI_EXIT_CODES.MISCONFIGURATION,
2051
+ "--project and --all-projects are mutually exclusive"
2052
+ );
2053
+ }
2054
+ let projectFilter = null;
2055
+ let filterSource = null;
2056
+ if (opts.project) {
2057
+ projectFilter = opts.project;
2058
+ filterSource = "flag";
2059
+ } else if (linkedProject && !opts.allProjects) {
2060
+ projectFilter = linkedProject.project_id;
2061
+ filterSource = "link";
2062
+ }
1999
2063
  const api = new AutopilotApi({ apiUrl, apiKey, actorEmail });
2000
2064
  if (!silent) process.stdout.write(`${c.dim("Discovering eligible projects\u2026")}
2001
2065
  `);
@@ -2004,15 +2068,33 @@ async function runScan(opts) {
2004
2068
  process.stdout.write(c.dim("No CLI-eligible tickets across any visible project.\n"));
2005
2069
  return;
2006
2070
  }
2007
- const projects = opts.project ? all.filter(
2008
- (p) => p.project_id === opts.project || p.project_slug === opts.project || `${p.organisation_slug}/${p.project_slug}` === opts.project
2071
+ const projects = projectFilter ? all.filter(
2072
+ (p) => p.project_id === projectFilter || p.project_slug === projectFilter || `${p.organisation_slug}/${p.project_slug}` === projectFilter
2009
2073
  ) : all;
2010
2074
  if (projects.length === 0) {
2075
+ if (filterSource === "link" && linkedProject) {
2076
+ throw new CliError(
2077
+ CLI_EXIT_CODES.GENERIC_ERROR,
2078
+ `Linked project ${linkedProject.organisation_slug}/${linkedProject.project_slug} has no CLI-eligible tickets right now`,
2079
+ "Mark a ticket as CLI-eligible from the dashboard, or pass --all-projects to scan everything the admin token can see."
2080
+ );
2081
+ }
2011
2082
  throw new CliError(
2012
2083
  CLI_EXIT_CODES.GENERIC_ERROR,
2013
2084
  `Project "${opts.project}" not found among eligible projects`
2014
2085
  );
2015
2086
  }
2087
+ if (!silent && filterSource === "link" && linkedProject) {
2088
+ process.stdout.write(
2089
+ `${c.dim("Scanning linked project")} ${c.bold(`${linkedProject.organisation_slug}/${linkedProject.project_slug}`)}${c.dim(" \u2014 pass --all-projects to scan every visible project.")}
2090
+ `
2091
+ );
2092
+ } else if (!silent && filterSource === null && !linkedProject) {
2093
+ process.stdout.write(
2094
+ `${c.dim("Repo is not linked. Scanning every visible project \u2014 run")} ${c.cyan("task link")} ${c.dim("to scope future runs to one project.")}
2095
+ `
2096
+ );
2097
+ }
2016
2098
  const aggregates = [];
2017
2099
  const claudePath = localCfg.claude_path ?? void 0;
2018
2100
  let interrupted = false;
@@ -2196,9 +2278,9 @@ import { randomUUID as randomUUID3 } from "crypto";
2196
2278
  import { platform as platform2 } from "os";
2197
2279
 
2198
2280
  // src/scheduler/launchd.ts
2199
- import { mkdir as mkdir6, readFile as readFile5, writeFile as writeFile7, unlink as unlink3, readdir } from "fs/promises";
2200
- import { homedir as homedir5 } from "os";
2201
- import { join as join7 } from "path";
2281
+ import { mkdir as mkdir7, readFile as readFile5, writeFile as writeFile8, unlink as unlink3, readdir } from "fs/promises";
2282
+ import { homedir as homedir6 } from "os";
2283
+ import { join as join8 } from "path";
2202
2284
  import { execFileSync as execFileSync5, spawn as spawn3 } from "child_process";
2203
2285
 
2204
2286
  // src/scheduler/cron-translate.ts
@@ -2300,14 +2382,14 @@ function expandField(field, min, max) {
2300
2382
  }
2301
2383
 
2302
2384
  // src/scheduler/launchd.ts
2303
- var PLIST_DIR = join7(homedir5(), "Library", "LaunchAgents");
2385
+ var PLIST_DIR = join8(homedir6(), "Library", "LaunchAgents");
2304
2386
  var LABEL_PREFIX = "com.inteeka.task.cli.";
2305
2387
  var SAFE_ID_RE = /^[0-9a-zA-Z._-]+$/;
2306
2388
  function plistPath(id) {
2307
2389
  if (!SAFE_ID_RE.test(id) || id.includes("..")) {
2308
2390
  throw new Error(`Refusing to compute plist path for unsafe id: ${id}`);
2309
2391
  }
2310
- return join7(PLIST_DIR, `${LABEL_PREFIX}${id}.plist`);
2392
+ return join8(PLIST_DIR, `${LABEL_PREFIX}${id}.plist`);
2311
2393
  }
2312
2394
  function buildPlist(entry) {
2313
2395
  const calendars = translateToLaunchd(entry.cron);
@@ -2343,9 +2425,9 @@ ${fields}
2343
2425
  ` <string>/usr/local/bin:/usr/bin:/bin:/opt/homebrew/bin</string>`,
2344
2426
  ` </dict>`,
2345
2427
  ` <key>StandardOutPath</key>`,
2346
- ` <string>${escapeXml(join7(homedir5(), ".cache", "task", "launchd-stdout.log"))}</string>`,
2428
+ ` <string>${escapeXml(join8(homedir6(), ".cache", "task", "launchd-stdout.log"))}</string>`,
2347
2429
  ` <key>StandardErrorPath</key>`,
2348
- ` <string>${escapeXml(join7(homedir5(), ".cache", "task", "launchd-stderr.log"))}</string>`,
2430
+ ` <string>${escapeXml(join8(homedir6(), ".cache", "task", "launchd-stderr.log"))}</string>`,
2349
2431
  !entry.enabled ? ` <key>Disabled</key>
2350
2432
  <true/>` : "",
2351
2433
  "</dict>",
@@ -2363,9 +2445,9 @@ function bootstrapDomain() {
2363
2445
  }
2364
2446
  var launchdAdapter = {
2365
2447
  async upsert(entry) {
2366
- await mkdir6(PLIST_DIR, { recursive: true });
2448
+ await mkdir7(PLIST_DIR, { recursive: true });
2367
2449
  const path = plistPath(entry.id);
2368
- await writeFile7(path, buildPlist(entry));
2450
+ await writeFile8(path, buildPlist(entry));
2369
2451
  try {
2370
2452
  execFileSync5("launchctl", ["bootout", bootstrapDomain(), path], { stdio: "ignore" });
2371
2453
  } catch {
@@ -2394,7 +2476,7 @@ var launchdAdapter = {
2394
2476
  for (const file of ours) {
2395
2477
  const id = file.slice(LABEL_PREFIX.length, -".plist".length);
2396
2478
  try {
2397
- const xml = await readFile5(join7(PLIST_DIR, file), "utf8");
2479
+ const xml = await readFile5(join8(PLIST_DIR, file), "utf8");
2398
2480
  const cron = xml.match(/<key>StartCalendarInterval<\/key>[\s\S]*?<\/array>/)?.[0] ?? "";
2399
2481
  const command = xml.match(/<key>ProgramArguments<\/key>\s*<array>([\s\S]*?)<\/array>/)?.[1] ?? "";
2400
2482
  const disabled = /<key>Disabled<\/key>\s*<true\/>/.test(xml);
@@ -2440,7 +2522,7 @@ var launchdAdapter = {
2440
2522
  }
2441
2523
  if (enabled) {
2442
2524
  xml = xml.replace(/\s*<key>Disabled<\/key>\s*<true\/>/, "");
2443
- await writeFile7(path, xml);
2525
+ await writeFile8(path, xml);
2444
2526
  try {
2445
2527
  execFileSync5("launchctl", ["bootout", bootstrapDomain(), path], { stdio: "ignore" });
2446
2528
  } catch {
@@ -2452,7 +2534,7 @@ var launchdAdapter = {
2452
2534
  "</dict>\n</plist>",
2453
2535
  " <key>Disabled</key>\n <true/>\n</dict>\n</plist>"
2454
2536
  );
2455
- await writeFile7(path, xml);
2537
+ await writeFile8(path, xml);
2456
2538
  }
2457
2539
  try {
2458
2540
  execFileSync5("launchctl", ["bootout", bootstrapDomain(), path], { stdio: "ignore" });
@@ -2805,10 +2887,10 @@ var unsupportedAdapter = {
2805
2887
  };
2806
2888
 
2807
2889
  // src/scheduler/registry.ts
2808
- import { mkdir as mkdir7, readFile as readFile6, writeFile as writeFile8 } from "fs/promises";
2809
- import { homedir as homedir6 } from "os";
2810
- import { dirname as dirname4, join as join8 } from "path";
2811
- var REGISTRY_PATH = join8(homedir6(), ".config", "task", "schedules.json");
2890
+ import { mkdir as mkdir8, readFile as readFile6, writeFile as writeFile9 } from "fs/promises";
2891
+ import { homedir as homedir7 } from "os";
2892
+ import { dirname as dirname4, join as join9 } from "path";
2893
+ var REGISTRY_PATH = join9(homedir7(), ".config", "task", "schedules.json");
2812
2894
  var UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
2813
2895
  function looksLikeRegistryRow(value) {
2814
2896
  if (!value || typeof value !== "object") return false;
@@ -2828,8 +2910,8 @@ async function readRegistry() {
2828
2910
  }
2829
2911
  }
2830
2912
  async function writeRegistry(rows) {
2831
- await mkdir7(dirname4(REGISTRY_PATH), { recursive: true });
2832
- await writeFile8(REGISTRY_PATH, JSON.stringify(rows, null, 2));
2913
+ await mkdir8(dirname4(REGISTRY_PATH), { recursive: true });
2914
+ await writeFile9(REGISTRY_PATH, JSON.stringify(rows, null, 2));
2833
2915
  }
2834
2916
  async function upsertRegistry(row) {
2835
2917
  if (!UUID_RE.test(row.id)) {
@@ -3069,8 +3151,8 @@ function stripAnsi(s) {
3069
3151
 
3070
3152
  // src/commands/runs.ts
3071
3153
  import { readFile as readFile7 } from "fs/promises";
3072
- import { homedir as homedir7 } from "os";
3073
- import { join as join9 } from "path";
3154
+ import { homedir as homedir8 } from "os";
3155
+ import { join as join10 } from "path";
3074
3156
  function registerRuns(program2) {
3075
3157
  const cmd = program2.command("runs").description("Inspect agentic CLI run history");
3076
3158
  cmd.command("list").description("List recent runs").option("--limit <n>", "Max rows", "50").option("--ticket <id>", "Filter by ticket").option("--schedule <id>", "Filter by schedule").action(async (opts) => {
@@ -3099,7 +3181,7 @@ function registerRuns(program2) {
3099
3181
  process.stdout.write(JSON.stringify(row, null, 2) + "\n");
3100
3182
  });
3101
3183
  cmd.command("logs <id>").description("Show captured agent output for a run, if available").action(async (id) => {
3102
- const localPath = join9(homedir7(), ".cache", "task", "runs", `${id}.log`);
3184
+ const localPath = join10(homedir8(), ".cache", "task", "runs", `${id}.log`);
3103
3185
  try {
3104
3186
  const text = await readFile7(localPath, "utf8");
3105
3187
  process.stdout.write(text);
@@ -3251,7 +3333,7 @@ function checkBinary(name, command) {
3251
3333
  }
3252
3334
 
3253
3335
  // src/commands/version.ts
3254
- var CLI_VERSION = true ? "0.1.4" : "0.0.0-dev";
3336
+ var CLI_VERSION = true ? "0.1.6" : "0.0.0-dev";
3255
3337
  function registerVersion(program2) {
3256
3338
  program2.command("version").description("Print the CLI version").action(() => {
3257
3339
  process.stdout.write(CLI_VERSION + "\n");