@iloom/cli 0.7.5 → 0.7.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/{PRManager-6ZJZRG5Z.js → PRManager-7F3AAY66.js} +3 -3
- package/dist/{chunk-TB6475EW.js → chunk-6YAMWLCP.js} +2 -2
- package/dist/{chunk-77VLG2KP.js → chunk-ETY2SBW5.js} +3 -3
- package/dist/chunk-ETY2SBW5.js.map +1 -0
- package/dist/{chunk-LZBSLO6S.js → chunk-NPEMVE27.js} +267 -6
- package/dist/chunk-NPEMVE27.js.map +1 -0
- package/dist/{chunk-KSXA2NOJ.js → chunk-WT4UGBE2.js} +7 -6
- package/dist/chunk-WT4UGBE2.js.map +1 -0
- package/dist/{cleanup-DB7EFBF3.js → cleanup-IO4KV2DL.js} +2 -2
- package/dist/cli.js +7 -7
- package/dist/{commit-NGMDWWAP.js → commit-3ULFKXNB.js} +2 -2
- package/dist/mcp/issue-management-server.js +263 -5
- package/dist/mcp/issue-management-server.js.map +1 -1
- package/dist/{summary-2KLNHVTN.js → summary-MPOOQIOX.js} +37 -6
- package/dist/summary-MPOOQIOX.js.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-77VLG2KP.js.map +0 -1
- package/dist/chunk-KSXA2NOJ.js.map +0 -1
- package/dist/chunk-LZBSLO6S.js.map +0 -1
- package/dist/summary-2KLNHVTN.js.map +0 -1
- /package/dist/{PRManager-6ZJZRG5Z.js.map → PRManager-7F3AAY66.js.map} +0 -0
- /package/dist/{chunk-TB6475EW.js.map → chunk-6YAMWLCP.js.map} +0 -0
- /package/dist/{cleanup-DB7EFBF3.js.map → cleanup-IO4KV2DL.js.map} +0 -0
- /package/dist/{commit-NGMDWWAP.js.map → commit-3ULFKXNB.js.map} +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
SessionSummaryService
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-WT4UGBE2.js";
|
|
5
5
|
import "./chunk-NXMDEL3F.js";
|
|
6
6
|
import {
|
|
7
7
|
CLIIsolationManager,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
EnvironmentManager,
|
|
10
10
|
LoomManager,
|
|
11
11
|
ResourceCleanup
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-ETY2SBW5.js";
|
|
13
13
|
import {
|
|
14
14
|
BuildRunner,
|
|
15
15
|
MergeManager
|
|
@@ -60,13 +60,13 @@ import {
|
|
|
60
60
|
import "./chunk-XPKN3QWY.js";
|
|
61
61
|
import {
|
|
62
62
|
PRManager
|
|
63
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-6YAMWLCP.js";
|
|
64
64
|
import {
|
|
65
65
|
openBrowser
|
|
66
66
|
} from "./chunk-YETJNRQM.js";
|
|
67
67
|
import {
|
|
68
68
|
IssueManagementProviderFactory
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-NPEMVE27.js";
|
|
70
70
|
import "./chunk-HBJITKSZ.js";
|
|
71
71
|
import {
|
|
72
72
|
getConfiguredRepoFromSettings,
|
|
@@ -2522,7 +2522,7 @@ program.command("finish").alias("dn").description("Merge work and cleanup worksp
|
|
|
2522
2522
|
program.command("commit").alias("c").description("Commit all uncommitted files with issue reference").option("-m, --message <text>", "Custom commit message (skip Claude generation)").option("--fixes", 'Use "Fixes #N" trailer instead of "Refs #N" (closes issue)').option("--no-review", "Skip commit message review prompt").option("--json", "Output result as JSON (implies --no-review)").option("--wip-commit", "Quick WIP commit: skip validations and pre-commit hooks").action(async (options) => {
|
|
2523
2523
|
const executeAction = async () => {
|
|
2524
2524
|
try {
|
|
2525
|
-
const { CommitCommand } = await import("./commit-
|
|
2525
|
+
const { CommitCommand } = await import("./commit-3ULFKXNB.js");
|
|
2526
2526
|
const command = new CommitCommand();
|
|
2527
2527
|
const noReview = options.review === false || options.json === true;
|
|
2528
2528
|
const result = await command.execute({
|
|
@@ -2664,7 +2664,7 @@ program.command("compile").alias("typecheck").description("Run the compile or ty
|
|
|
2664
2664
|
program.command("cleanup").alias("remove").alias("clean").description("Remove workspaces").argument("[identifier]", "Branch name or issue number to cleanup (auto-detected)").option("-l, --list", "List all worktrees").option("-a, --all", "Remove all worktrees (interactive confirmation)").option("-i, --issue <number>", "Cleanup by issue number", parseInt).option("-f, --force", "Skip confirmations and force removal").option("--dry-run", "Show what would be done without doing it").option("--json", "Output result as JSON").option("--defer <ms>", "Wait specified milliseconds before cleanup", parseInt).action(async (identifier, options) => {
|
|
2665
2665
|
const executeAction = async () => {
|
|
2666
2666
|
try {
|
|
2667
|
-
const { CleanupCommand } = await import("./cleanup-
|
|
2667
|
+
const { CleanupCommand } = await import("./cleanup-IO4KV2DL.js");
|
|
2668
2668
|
const command = new CleanupCommand();
|
|
2669
2669
|
const input = {
|
|
2670
2670
|
options: options ?? {}
|
|
@@ -3180,7 +3180,7 @@ program.command("test-prefix").description("Test worktree prefix configuration -
|
|
|
3180
3180
|
program.command("summary").description("Generate Claude session summary for a loom").argument("[identifier]", "Issue number, PR number (pr/123), or branch name (auto-detected if omitted)").option("--with-comment", "Post summary as a comment to the issue/PR").option("--json", "Output result as JSON").action(async (identifier, options) => {
|
|
3181
3181
|
const executeAction = async () => {
|
|
3182
3182
|
try {
|
|
3183
|
-
const { SummaryCommand } = await import("./summary-
|
|
3183
|
+
const { SummaryCommand } = await import("./summary-MPOOQIOX.js");
|
|
3184
3184
|
const command = new SummaryCommand();
|
|
3185
3185
|
const result = await command.execute({ identifier, options });
|
|
3186
3186
|
if (options.json && result) {
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
import "./chunk-XPKN3QWY.js";
|
|
11
11
|
import {
|
|
12
12
|
IssueManagementProviderFactory
|
|
13
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-NPEMVE27.js";
|
|
14
14
|
import "./chunk-HBJITKSZ.js";
|
|
15
15
|
import {
|
|
16
16
|
extractIssueNumber,
|
|
@@ -234,4 +234,4 @@ export {
|
|
|
234
234
|
CommitCommand,
|
|
235
235
|
WorktreeValidationError
|
|
236
236
|
};
|
|
237
|
-
//# sourceMappingURL=commit-
|
|
237
|
+
//# sourceMappingURL=commit-3ULFKXNB.js.map
|
|
@@ -236,6 +236,244 @@ async function addSubIssue(parentNodeId, childNodeId) {
|
|
|
236
236
|
]);
|
|
237
237
|
}
|
|
238
238
|
|
|
239
|
+
// src/utils/image-processor.ts
|
|
240
|
+
import { tmpdir } from "os";
|
|
241
|
+
import { join, extname } from "path";
|
|
242
|
+
import { existsSync as existsSync2, mkdirSync, createWriteStream, unlinkSync } from "fs";
|
|
243
|
+
import { pipeline } from "stream/promises";
|
|
244
|
+
import { Readable } from "stream";
|
|
245
|
+
import { createHash } from "crypto";
|
|
246
|
+
import { execa as execa3 } from "execa";
|
|
247
|
+
var SUPPORTED_EXTENSIONS = [".png", ".jpg", ".jpeg", ".gif", ".webp", ".svg"];
|
|
248
|
+
var MAX_IMAGE_SIZE = 10 * 1024 * 1024;
|
|
249
|
+
var REQUEST_TIMEOUT_MS = 3e4;
|
|
250
|
+
var CACHE_DIR = join(tmpdir(), "iloom-images");
|
|
251
|
+
var cachedGitHubToken;
|
|
252
|
+
function extractMarkdownImageUrls(content) {
|
|
253
|
+
if (!content) {
|
|
254
|
+
return [];
|
|
255
|
+
}
|
|
256
|
+
const matches = [];
|
|
257
|
+
const markdownRegex = /!\[([^\]]*)\]\(((?:[^()\s]|\((?:[^()\s]|\([^()]*\))*\))+)\)/g;
|
|
258
|
+
let match;
|
|
259
|
+
while ((match = markdownRegex.exec(content)) !== null) {
|
|
260
|
+
const url = match[2];
|
|
261
|
+
if (url) {
|
|
262
|
+
matches.push({
|
|
263
|
+
fullMatch: match[0],
|
|
264
|
+
url,
|
|
265
|
+
isMarkdown: true
|
|
266
|
+
});
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
const htmlImgRegex = /<img\s+[^>]*src=["']([^"']+)["'][^>]*\/?>/gi;
|
|
270
|
+
while ((match = htmlImgRegex.exec(content)) !== null) {
|
|
271
|
+
const url = match[1];
|
|
272
|
+
if (url) {
|
|
273
|
+
matches.push({
|
|
274
|
+
fullMatch: match[0],
|
|
275
|
+
url,
|
|
276
|
+
isMarkdown: false
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
return matches;
|
|
281
|
+
}
|
|
282
|
+
function isAuthenticatedImageUrl(url) {
|
|
283
|
+
try {
|
|
284
|
+
const parsedUrl = new URL(url);
|
|
285
|
+
const hostname = parsedUrl.hostname.toLowerCase();
|
|
286
|
+
if (hostname === "uploads.linear.app") {
|
|
287
|
+
return true;
|
|
288
|
+
}
|
|
289
|
+
if (hostname === "private-user-images.githubusercontent.com") {
|
|
290
|
+
return true;
|
|
291
|
+
}
|
|
292
|
+
if (hostname === "github.com" && parsedUrl.pathname.startsWith("/user-attachments/assets/")) {
|
|
293
|
+
return true;
|
|
294
|
+
}
|
|
295
|
+
return false;
|
|
296
|
+
} catch {
|
|
297
|
+
return false;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
function getExtensionFromUrl(url) {
|
|
301
|
+
try {
|
|
302
|
+
const parsedUrl = new URL(url);
|
|
303
|
+
const pathname = parsedUrl.pathname;
|
|
304
|
+
const ext = extname(pathname).toLowerCase();
|
|
305
|
+
if (SUPPORTED_EXTENSIONS.includes(ext)) {
|
|
306
|
+
return ext;
|
|
307
|
+
}
|
|
308
|
+
return null;
|
|
309
|
+
} catch {
|
|
310
|
+
return null;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
function getCacheKey(url) {
|
|
314
|
+
const parsedUrl = new URL(url);
|
|
315
|
+
if (parsedUrl.hostname === "private-user-images.githubusercontent.com") {
|
|
316
|
+
parsedUrl.searchParams.delete("jwt");
|
|
317
|
+
}
|
|
318
|
+
const stableUrl = parsedUrl.toString();
|
|
319
|
+
const hash = createHash("sha256").update(stableUrl).digest("hex").slice(0, 16);
|
|
320
|
+
const ext = getExtensionFromUrl(url) ?? ".png";
|
|
321
|
+
return `${hash}${ext}`;
|
|
322
|
+
}
|
|
323
|
+
function getCachedImagePath(url) {
|
|
324
|
+
const cacheKey = getCacheKey(url);
|
|
325
|
+
const cachedPath = join(CACHE_DIR, cacheKey);
|
|
326
|
+
if (existsSync2(cachedPath)) {
|
|
327
|
+
return cachedPath;
|
|
328
|
+
}
|
|
329
|
+
return void 0;
|
|
330
|
+
}
|
|
331
|
+
async function getAuthToken(provider) {
|
|
332
|
+
if (provider === "github") {
|
|
333
|
+
if (cachedGitHubToken !== void 0) {
|
|
334
|
+
return cachedGitHubToken;
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
const result = await execa3("gh", ["auth", "token"]);
|
|
338
|
+
cachedGitHubToken = result.stdout.trim();
|
|
339
|
+
return cachedGitHubToken;
|
|
340
|
+
} catch (error) {
|
|
341
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
342
|
+
logger.warn(`Failed to get GitHub auth token via gh CLI: ${message}`);
|
|
343
|
+
return void 0;
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
if (provider === "linear") {
|
|
347
|
+
return process.env.LINEAR_API_TOKEN;
|
|
348
|
+
}
|
|
349
|
+
return void 0;
|
|
350
|
+
}
|
|
351
|
+
async function downloadAndSaveImage(url, destPath, authHeader) {
|
|
352
|
+
const headers = {};
|
|
353
|
+
if (authHeader) {
|
|
354
|
+
headers["Authorization"] = authHeader;
|
|
355
|
+
}
|
|
356
|
+
const controller = new AbortController();
|
|
357
|
+
const timeoutId = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);
|
|
358
|
+
try {
|
|
359
|
+
const response = await fetch(url, { headers, signal: controller.signal });
|
|
360
|
+
if (!response.ok) {
|
|
361
|
+
throw new Error(`Failed to download image: ${response.status} ${response.statusText}`);
|
|
362
|
+
}
|
|
363
|
+
const contentLength = response.headers.get("Content-Length");
|
|
364
|
+
if (contentLength && parseInt(contentLength, 10) > MAX_IMAGE_SIZE) {
|
|
365
|
+
throw new Error(`Image too large: ${contentLength} bytes exceeds ${MAX_IMAGE_SIZE} byte limit`);
|
|
366
|
+
}
|
|
367
|
+
if (!response.body) {
|
|
368
|
+
throw new Error("Response body is null");
|
|
369
|
+
}
|
|
370
|
+
const reader = response.body.getReader();
|
|
371
|
+
let bytesWritten = 0;
|
|
372
|
+
const nodeReadable = new Readable({
|
|
373
|
+
async read() {
|
|
374
|
+
try {
|
|
375
|
+
const { done, value } = await reader.read();
|
|
376
|
+
if (done) {
|
|
377
|
+
this.push(null);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
bytesWritten += value.byteLength;
|
|
381
|
+
if (bytesWritten > MAX_IMAGE_SIZE) {
|
|
382
|
+
reader.cancel();
|
|
383
|
+
this.destroy(new Error(`Image too large: ${bytesWritten} bytes exceeds ${MAX_IMAGE_SIZE} byte limit`));
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
this.push(Buffer.from(value));
|
|
387
|
+
} catch (err) {
|
|
388
|
+
this.destroy(err instanceof Error ? err : new Error(String(err)));
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
});
|
|
392
|
+
if (!existsSync2(CACHE_DIR)) {
|
|
393
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
394
|
+
}
|
|
395
|
+
const writeStream = createWriteStream(destPath);
|
|
396
|
+
try {
|
|
397
|
+
await pipeline(nodeReadable, writeStream);
|
|
398
|
+
} catch (pipelineError) {
|
|
399
|
+
try {
|
|
400
|
+
if (existsSync2(destPath)) {
|
|
401
|
+
unlinkSync(destPath);
|
|
402
|
+
}
|
|
403
|
+
} catch {
|
|
404
|
+
}
|
|
405
|
+
throw pipelineError;
|
|
406
|
+
}
|
|
407
|
+
} catch (error) {
|
|
408
|
+
if (error instanceof Error && error.name === "AbortError") {
|
|
409
|
+
throw new Error(`Image download timed out after ${REQUEST_TIMEOUT_MS}ms`);
|
|
410
|
+
}
|
|
411
|
+
throw error;
|
|
412
|
+
} finally {
|
|
413
|
+
clearTimeout(timeoutId);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
function getCacheDestPath(url) {
|
|
417
|
+
if (!existsSync2(CACHE_DIR)) {
|
|
418
|
+
mkdirSync(CACHE_DIR, { recursive: true });
|
|
419
|
+
}
|
|
420
|
+
const cacheKey = getCacheKey(url);
|
|
421
|
+
return join(CACHE_DIR, cacheKey);
|
|
422
|
+
}
|
|
423
|
+
function rewriteMarkdownUrls(content, urlMap) {
|
|
424
|
+
let result = content;
|
|
425
|
+
for (const [originalUrl, localPath] of urlMap) {
|
|
426
|
+
const escapedUrl = originalUrl.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
427
|
+
const urlRegex = new RegExp(escapedUrl, "g");
|
|
428
|
+
result = result.replace(urlRegex, localPath);
|
|
429
|
+
}
|
|
430
|
+
return result;
|
|
431
|
+
}
|
|
432
|
+
async function processMarkdownImages(content, provider) {
|
|
433
|
+
if (!content) {
|
|
434
|
+
return "";
|
|
435
|
+
}
|
|
436
|
+
const images = extractMarkdownImageUrls(content);
|
|
437
|
+
if (images.length === 0) {
|
|
438
|
+
return content;
|
|
439
|
+
}
|
|
440
|
+
const authImages = images.filter((img) => isAuthenticatedImageUrl(img.url));
|
|
441
|
+
if (authImages.length === 0) {
|
|
442
|
+
return content;
|
|
443
|
+
}
|
|
444
|
+
const authToken = await getAuthToken(provider);
|
|
445
|
+
const uniqueUrls = [...new Set(authImages.map((img) => img.url))];
|
|
446
|
+
const urlMap = /* @__PURE__ */ new Map();
|
|
447
|
+
const downloadPromises = uniqueUrls.map(async (url) => {
|
|
448
|
+
try {
|
|
449
|
+
const cachedPath = getCachedImagePath(url);
|
|
450
|
+
if (cachedPath) {
|
|
451
|
+
logger.debug(`Using cached image: ${cachedPath}`);
|
|
452
|
+
return { url, localPath: cachedPath };
|
|
453
|
+
}
|
|
454
|
+
logger.debug(`Downloading image: ${url}`);
|
|
455
|
+
const destPath = getCacheDestPath(url);
|
|
456
|
+
await downloadAndSaveImage(
|
|
457
|
+
url,
|
|
458
|
+
destPath,
|
|
459
|
+
authToken ? `Bearer ${authToken}` : void 0
|
|
460
|
+
);
|
|
461
|
+
return { url, localPath: destPath };
|
|
462
|
+
} catch (error) {
|
|
463
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
464
|
+
logger.warn(`Failed to download image ${url}: ${message}`);
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
});
|
|
468
|
+
const results = await Promise.all(downloadPromises);
|
|
469
|
+
for (const result of results) {
|
|
470
|
+
if (result !== null) {
|
|
471
|
+
urlMap.set(result.url, result.localPath);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return rewriteMarkdownUrls(content, urlMap);
|
|
475
|
+
}
|
|
476
|
+
|
|
239
477
|
// src/mcp/GitHubIssueManagementProvider.ts
|
|
240
478
|
function normalizeAuthor(author) {
|
|
241
479
|
if (!author) return null;
|
|
@@ -314,6 +552,12 @@ var GitHubIssueManagementProvider = class {
|
|
|
314
552
|
...comment.updatedAt && { updatedAt: comment.updatedAt }
|
|
315
553
|
}));
|
|
316
554
|
}
|
|
555
|
+
result.body = await processMarkdownImages(result.body, "github");
|
|
556
|
+
if (result.comments) {
|
|
557
|
+
for (const comment of result.comments) {
|
|
558
|
+
comment.body = await processMarkdownImages(comment.body, "github");
|
|
559
|
+
}
|
|
560
|
+
}
|
|
317
561
|
return result;
|
|
318
562
|
}
|
|
319
563
|
/**
|
|
@@ -382,6 +626,12 @@ var GitHubIssueManagementProvider = class {
|
|
|
382
626
|
...comment.updatedAt && { updatedAt: comment.updatedAt }
|
|
383
627
|
}));
|
|
384
628
|
}
|
|
629
|
+
result.body = await processMarkdownImages(result.body, "github");
|
|
630
|
+
if (result.comments) {
|
|
631
|
+
for (const comment of result.comments) {
|
|
632
|
+
comment.body = await processMarkdownImages(comment.body, "github");
|
|
633
|
+
}
|
|
634
|
+
}
|
|
385
635
|
return result;
|
|
386
636
|
}
|
|
387
637
|
/**
|
|
@@ -401,9 +651,10 @@ var GitHubIssueManagementProvider = class {
|
|
|
401
651
|
"--jq",
|
|
402
652
|
"{id: .id, body: .body, user: .user, created_at: .created_at, updated_at: .updated_at, html_url: .html_url, reactions: .reactions}"
|
|
403
653
|
]);
|
|
654
|
+
const processedBody = await processMarkdownImages(raw.body, "github");
|
|
404
655
|
return {
|
|
405
656
|
id: String(raw.id),
|
|
406
|
-
body:
|
|
657
|
+
body: processedBody,
|
|
407
658
|
author: normalizeAuthor(raw.user),
|
|
408
659
|
created_at: raw.created_at,
|
|
409
660
|
...raw.updated_at && { updated_at: raw.updated_at },
|
|
@@ -752,7 +1003,7 @@ async function fetchLinearIssueComments(identifier) {
|
|
|
752
1003
|
|
|
753
1004
|
// src/utils/linear-markup-converter.ts
|
|
754
1005
|
import { appendFileSync } from "fs";
|
|
755
|
-
import { join, dirname, basename, extname } from "path";
|
|
1006
|
+
import { join as join2, dirname, basename, extname as extname2 } from "path";
|
|
756
1007
|
var LinearMarkupConverter = class {
|
|
757
1008
|
/**
|
|
758
1009
|
* Convert HTML details/summary blocks to Linear's collapsible format
|
|
@@ -888,7 +1139,7 @@ ${content}
|
|
|
888
1139
|
*/
|
|
889
1140
|
static getTimestampedLogPath(logFilePath) {
|
|
890
1141
|
const dir = dirname(logFilePath);
|
|
891
|
-
const ext =
|
|
1142
|
+
const ext = extname2(logFilePath);
|
|
892
1143
|
const base = basename(logFilePath, ext);
|
|
893
1144
|
const now = /* @__PURE__ */ new Date();
|
|
894
1145
|
const timestamp = [
|
|
@@ -900,7 +1151,7 @@ ${content}
|
|
|
900
1151
|
String(now.getMinutes()).padStart(2, "0"),
|
|
901
1152
|
String(now.getSeconds()).padStart(2, "0")
|
|
902
1153
|
].join("");
|
|
903
|
-
return
|
|
1154
|
+
return join2(dir, `${base}-${timestamp}${ext}`);
|
|
904
1155
|
}
|
|
905
1156
|
};
|
|
906
1157
|
|
|
@@ -949,6 +1200,12 @@ var LinearIssueManagementProvider = class {
|
|
|
949
1200
|
} catch {
|
|
950
1201
|
}
|
|
951
1202
|
}
|
|
1203
|
+
result.body = await processMarkdownImages(result.body, "linear");
|
|
1204
|
+
if (result.comments) {
|
|
1205
|
+
for (const comment of result.comments) {
|
|
1206
|
+
comment.body = await processMarkdownImages(comment.body, "linear");
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
952
1209
|
return result;
|
|
953
1210
|
}
|
|
954
1211
|
/**
|
|
@@ -982,9 +1239,10 @@ var LinearIssueManagementProvider = class {
|
|
|
982
1239
|
async getComment(input) {
|
|
983
1240
|
const { commentId } = input;
|
|
984
1241
|
const raw = await getLinearComment(commentId);
|
|
1242
|
+
const processedBody = await processMarkdownImages(raw.body, "linear");
|
|
985
1243
|
return {
|
|
986
1244
|
id: raw.id,
|
|
987
|
-
body:
|
|
1245
|
+
body: processedBody,
|
|
988
1246
|
author: null,
|
|
989
1247
|
// Linear SDK doesn't return comment author info in basic fetch
|
|
990
1248
|
created_at: raw.createdAt
|