@shepai/cli 1.90.0-pr267.6b99b63 → 1.90.0-pr267.f30e3b2

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.
Files changed (115) hide show
  1. package/dist/src/presentation/web/app/api/attachments/preview/route.d.ts.map +1 -1
  2. package/dist/src/presentation/web/app/api/attachments/preview/route.js +47 -11
  3. package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.d.ts.map +1 -1
  4. package/dist/src/presentation/web/components/common/inline-attachments/inline-attachments.js +7 -2
  5. package/dist/tsconfig.build.tsbuildinfo +1 -1
  6. package/package.json +1 -1
  7. package/web/.next/BUILD_ID +1 -1
  8. package/web/.next/build-manifest.json +2 -2
  9. package/web/.next/fallback-build-manifest.json +2 -2
  10. package/web/.next/prerender-manifest.json +3 -3
  11. package/web/.next/server/app/(dashboard)/@drawer/create/page/server-reference-manifest.json +18 -18
  12. package/web/.next/server/app/(dashboard)/@drawer/create/page.js.nft.json +1 -1
  13. package/web/.next/server/app/(dashboard)/@drawer/create/page_client-reference-manifest.js +1 -1
  14. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page/server-reference-manifest.json +21 -21
  15. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page.js.nft.json +1 -1
  16. package/web/.next/server/app/(dashboard)/@drawer/feature/[featureId]/page_client-reference-manifest.js +1 -1
  17. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  18. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page.js.nft.json +1 -1
  19. package/web/.next/server/app/(dashboard)/@drawer/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  20. package/web/.next/server/app/(dashboard)/create/page/server-reference-manifest.json +18 -18
  21. package/web/.next/server/app/(dashboard)/create/page.js.nft.json +1 -1
  22. package/web/.next/server/app/(dashboard)/create/page_client-reference-manifest.js +1 -1
  23. package/web/.next/server/app/(dashboard)/feature/[featureId]/page/server-reference-manifest.json +21 -21
  24. package/web/.next/server/app/(dashboard)/feature/[featureId]/page.js.nft.json +1 -1
  25. package/web/.next/server/app/(dashboard)/feature/[featureId]/page_client-reference-manifest.js +1 -1
  26. package/web/.next/server/app/(dashboard)/page/server-reference-manifest.json +14 -14
  27. package/web/.next/server/app/(dashboard)/page.js.nft.json +1 -1
  28. package/web/.next/server/app/(dashboard)/page_client-reference-manifest.js +1 -1
  29. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page/server-reference-manifest.json +14 -14
  30. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page.js.nft.json +1 -1
  31. package/web/.next/server/app/(dashboard)/repository/[repositoryId]/page_client-reference-manifest.js +1 -1
  32. package/web/.next/server/app/_global-error.html +2 -2
  33. package/web/.next/server/app/_global-error.rsc +1 -1
  34. package/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  35. package/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  36. package/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  37. package/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  38. package/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  39. package/web/.next/server/app/_not-found/page/server-reference-manifest.json +1 -1
  40. package/web/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  41. package/web/.next/server/app/settings/page/server-reference-manifest.json +5 -5
  42. package/web/.next/server/app/settings/page_client-reference-manifest.js +1 -1
  43. package/web/.next/server/app/skills/page/server-reference-manifest.json +6 -6
  44. package/web/.next/server/app/skills/page_client-reference-manifest.js +1 -1
  45. package/web/.next/server/app/tools/page/server-reference-manifest.json +6 -6
  46. package/web/.next/server/app/tools/page_client-reference-manifest.js +1 -1
  47. package/web/.next/server/app/version/page/server-reference-manifest.json +1 -1
  48. package/web/.next/server/app/version/page_client-reference-manifest.js +1 -1
  49. package/web/.next/server/chunks/[root-of-the-server]__0b10355c._.js +1 -1
  50. package/web/.next/server/chunks/[root-of-the-server]__0b10355c._.js.map +1 -1
  51. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js +1 -1
  52. package/web/.next/server/chunks/ssr/744ca_web_components_common_control-center-drawer_create-drawer-client_tsx_5e26fc0a._.js.map +1 -1
  53. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js +1 -1
  54. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_@drawer_repository_[repositoryId]_page_actions_da7eef33.js.map +1 -1
  55. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js +1 -1
  56. package/web/.next/server/chunks/ssr/8ba4b_server_app_(dashboard)_repository_[repositoryId]_page_actions_0a9251aa.js.map +1 -1
  57. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js +1 -1
  58. package/web/.next/server/chunks/ssr/[root-of-the-server]__11033878._.js.map +1 -1
  59. package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.js +1 -1
  60. package/web/.next/server/chunks/ssr/[root-of-the-server]__17143953._.js.map +1 -1
  61. package/web/.next/server/chunks/ssr/[root-of-the-server]__4be9a9bb._.js +1 -1
  62. package/web/.next/server/chunks/ssr/[root-of-the-server]__5d87af2e._.js +1 -1
  63. package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js +1 -1
  64. package/web/.next/server/chunks/ssr/[root-of-the-server]__9de266fa._.js.map +1 -1
  65. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js +1 -1
  66. package/web/.next/server/chunks/ssr/[root-of-the-server]__aad040c0._.js.map +1 -1
  67. package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js +1 -1
  68. package/web/.next/server/chunks/ssr/[root-of-the-server]__b3a4cef4._.js.map +1 -1
  69. package/web/.next/server/chunks/ssr/[root-of-the-server]__f0d8d054._.js +2 -2
  70. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js +1 -1
  71. package/web/.next/server/chunks/ssr/[root-of-the-server]__fdc75809._.js.map +1 -1
  72. package/web/.next/server/chunks/ssr/_135edb9c._.js +1 -1
  73. package/web/.next/server/chunks/ssr/_135edb9c._.js.map +1 -1
  74. package/web/.next/server/chunks/ssr/_752e01fd._.js +1 -1
  75. package/web/.next/server/chunks/ssr/_752e01fd._.js.map +1 -1
  76. package/web/.next/server/chunks/ssr/{_d965a58b._.js → _79036bb2._.js} +2 -2
  77. package/web/.next/server/chunks/ssr/{_d965a58b._.js.map → _79036bb2._.js.map} +1 -1
  78. package/web/.next/server/chunks/ssr/_8dacd1e7._.js +1 -1
  79. package/web/.next/server/chunks/ssr/_8dacd1e7._.js.map +1 -1
  80. package/web/.next/server/chunks/ssr/_cc77a143._.js +1 -1
  81. package/web/.next/server/chunks/ssr/_cc77a143._.js.map +1 -1
  82. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js +1 -1
  83. package/web/.next/server/chunks/ssr/b1a17_presentation_web_components_features_settings_settings-page-client_tsx_6ed9d5f8._.js.map +1 -1
  84. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js +1 -1
  85. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_(dashboard)_page_actions_021a05f2.js.map +1 -1
  86. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js +1 -1
  87. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_skills_page_actions_1fa8042e.js.map +1 -1
  88. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js +1 -1
  89. package/web/.next/server/chunks/ssr/src_presentation_web__next-internal_server_app_tools_page_actions_24684200.js.map +1 -1
  90. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js +2 -2
  91. package/web/.next/server/chunks/ssr/src_presentation_web_c4348b8a._.js.map +1 -1
  92. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js +1 -1
  93. package/web/.next/server/chunks/ssr/src_presentation_web_components_bf50c527._.js.map +1 -1
  94. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js +1 -1
  95. package/web/.next/server/chunks/ssr/src_presentation_web_components_de814675._.js.map +1 -1
  96. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js +1 -1
  97. package/web/.next/server/chunks/ssr/src_presentation_web_components_features_control-center_7ac3562e._.js.map +1 -1
  98. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js +2 -2
  99. package/web/.next/server/chunks/ssr/src_presentation_web_e4510d10._.js.map +1 -1
  100. package/web/.next/server/pages/500.html +2 -2
  101. package/web/.next/server/server-reference-manifest.js +1 -1
  102. package/web/.next/server/server-reference-manifest.json +28 -28
  103. package/web/.next/static/chunks/{ab07bf5a8c88560e.js → 08372bd32f7ff048.js} +1 -1
  104. package/web/.next/static/chunks/{13ebcef78ac5e737.js → 089c6624a6b65aa6.js} +2 -2
  105. package/web/.next/static/chunks/{64bf17550dd80c0e.js → 2294be2651cb4268.js} +1 -1
  106. package/web/.next/static/chunks/{36853f0e820cedca.js → 2a0002004b1b4095.js} +1 -1
  107. package/web/.next/static/chunks/{25d8823528107515.js → 6a3efa213caf5bcc.js} +1 -1
  108. package/web/.next/static/chunks/{bb48075ff0122a07.js → 8fc22e351afc1a5a.js} +1 -1
  109. package/web/.next/static/chunks/{26d72d8897a99d1e.js → 98979c38eae9bf30.js} +1 -1
  110. package/web/.next/static/chunks/{ffa17a204838a32b.js → a4e8dfae13e5bafb.js} +1 -1
  111. package/web/.next/static/chunks/{287cd780b9f2f8f8.js → e2874b94dac4d6d2.js} +1 -1
  112. package/web/.next/static/chunks/{7b73382d30dc5f0d.js → f6bc7bfd851e65b0.js} +1 -1
  113. /package/web/.next/static/{fYMY23FE9Amz0ldEbZOF1 → dzCQAZQBMOakjSP170WZV}/_buildManifest.js +0 -0
  114. /package/web/.next/static/{fYMY23FE9Amz0ldEbZOF1 → dzCQAZQBMOakjSP170WZV}/_clientMiddlewareManifest.json +0 -0
  115. /package/web/.next/static/{fYMY23FE9Amz0ldEbZOF1 → dzCQAZQBMOakjSP170WZV}/_ssgManifest.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/attachments/preview/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAsB3C,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA6BrE"}
1
+ {"version":3,"file":"route.d.ts","sourceRoot":"","sources":["../../../../../../../../src/presentation/web/app/api/attachments/preview/route.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA8D3C,wBAAsB,GAAG,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CA0BrE"}
@@ -1,6 +1,6 @@
1
1
  import { NextResponse } from 'next/server';
2
- import { readFile, stat } from 'fs/promises';
3
- import { extname, resolve } from 'path';
2
+ import { readFile, stat, readdir } from 'fs/promises';
3
+ import { basename, extname, join, resolve } from 'path';
4
4
  import { getShepHomeDir } from '../../../../../../../packages/core/src/infrastructure/services/filesystem/shep-directory.service.js';
5
5
  const MIME_MAP = {
6
6
  '.png': 'image/png',
@@ -18,6 +18,44 @@ const MIME_MAP = {
18
18
  '.yaml': 'text/yaml',
19
19
  '.yml': 'text/yaml',
20
20
  };
21
+ /**
22
+ * When the exact path doesn't exist (e.g. pending-<id> was renamed to <slug>),
23
+ * search all sibling attachment directories for the same filename.
24
+ */
25
+ async function findAttachmentFallback(requestedPath, attachmentsRoot) {
26
+ const filename = basename(requestedPath);
27
+ try {
28
+ const dirs = await readdir(attachmentsRoot, { withFileTypes: true });
29
+ for (const entry of dirs) {
30
+ if (!entry.isDirectory())
31
+ continue;
32
+ const candidate = join(attachmentsRoot, entry.name, filename);
33
+ try {
34
+ await stat(candidate);
35
+ return candidate;
36
+ }
37
+ catch {
38
+ // not in this directory
39
+ }
40
+ }
41
+ }
42
+ catch {
43
+ // attachments root doesn't exist
44
+ }
45
+ return null;
46
+ }
47
+ function serveFile(filePath, mimeTypeHint) {
48
+ return readFile(filePath).then((buffer) => {
49
+ const ext = extname(filePath).toLowerCase();
50
+ const contentType = MIME_MAP[ext] ?? mimeTypeHint ?? 'application/octet-stream';
51
+ return new NextResponse(buffer, {
52
+ headers: {
53
+ 'Content-Type': contentType,
54
+ 'Cache-Control': 'private, max-age=3600',
55
+ },
56
+ });
57
+ });
58
+ }
21
59
  export async function GET(request) {
22
60
  const path = request.nextUrl.searchParams.get('path');
23
61
  const mimeTypeHint = request.nextUrl.searchParams.get('mimeType');
@@ -31,17 +69,15 @@ export async function GET(request) {
31
69
  }
32
70
  try {
33
71
  await stat(path);
34
- const buffer = await readFile(path);
35
- const ext = extname(path).toLowerCase();
36
- const contentType = MIME_MAP[ext] ?? mimeTypeHint ?? 'application/octet-stream';
37
- return new NextResponse(buffer, {
38
- headers: {
39
- 'Content-Type': contentType,
40
- 'Cache-Control': 'private, max-age=3600',
41
- },
42
- });
72
+ return await serveFile(path, mimeTypeHint);
43
73
  }
44
74
  catch {
75
+ // File not found at exact path — try fallback search
76
+ // This handles the case where pending-<sessionId>/ was renamed to <featureSlug>/
77
+ const fallbackPath = await findAttachmentFallback(path, attachmentsRoot);
78
+ if (fallbackPath) {
79
+ return await serveFile(fallbackPath, mimeTypeHint);
80
+ }
45
81
  return NextResponse.json({ error: 'File not found' }, { status: 404 });
46
82
  }
47
83
  }
@@ -1 +1 @@
1
- {"version":3,"file":"inline-attachments.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/inline-attachments/inline-attachments.tsx"],"names":[],"mappings":"AA4BA,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,OAAO,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAE/C,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAwB3D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,sBAAsB,2CA4BlF"}
1
+ {"version":3,"file":"inline-attachments.d.ts","sourceRoot":"","sources":["../../../../../../../src/presentation/web/components/common/inline-attachments/inline-attachments.tsx"],"names":[],"mappings":"AA6BA,MAAM,WAAW,sBAAsB;IACrC,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;CAC5B;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAED,UAAU,iBAAiB;IACzB,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,KAAK,OAAO,GAAG,WAAW,GAAG,iBAAiB,CAAC;AAE/C,wEAAwE;AACxE,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,EAAE,CAwB3D;AAED,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,EAAE,sBAAsB,2CA4BlF"}
@@ -1,9 +1,10 @@
1
1
  /* eslint-disable @next/next/no-img-element -- Local file preview requires raw <img>, not next/image */
2
2
  'use client';
3
3
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
4
+ import { useState } from 'react';
4
5
  import { Dialog, DialogTrigger, DialogContent, DialogTitle } from '../../ui/dialog.js';
5
6
  import { VisuallyHidden } from 'radix-ui';
6
- import { DownloadIcon } from 'lucide-react';
7
+ import { DownloadIcon, ImageOff } from 'lucide-react';
7
8
  const IMAGE_EXTS = new Set(['.png', '.jpg', '.jpeg', '.gif', '.svg', '.webp', '.ico', '.bmp']);
8
9
  function isImagePath(path) {
9
10
  const dot = path.lastIndexOf('.');
@@ -60,8 +61,12 @@ export function InlineAttachments({ text, attachmentPaths }) {
60
61
  }
61
62
  function AttachmentPreview({ path }) {
62
63
  const filename = getFilename(path);
64
+ const [loadError, setLoadError] = useState(false);
63
65
  if (isImagePath(path)) {
64
- return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { asChild: true, children: _jsx("img", { src: previewUrl(path), alt: filename, "data-testid": "inline-attachment-image", className: "max-h-48 max-w-full cursor-pointer rounded-md border object-contain transition-opacity hover:opacity-80" }) }), _jsxs(DialogContent, { className: "max-w-3xl gap-0 overflow-hidden border-0 p-0 [&>button:last-child]:!cursor-pointer [&>button:last-child]:!rounded-full [&>button:last-child]:!bg-black/70 [&>button:last-child]:!p-1.5 [&>button:last-child]:!text-white [&>button:last-child]:!opacity-100 [&>button:last-child]:!shadow-lg [&>button:last-child]:!backdrop-blur-md [&>button:last-child]:hover:!bg-black/90", children: [_jsx(VisuallyHidden.Root, { children: _jsxs(DialogTitle, { children: ["Preview: ", filename] }) }), _jsx("div", { className: "relative bg-black/90", children: _jsx("img", { src: previewUrl(path), alt: filename, className: "h-auto max-h-[70vh] w-full object-contain" }) }), _jsxs("div", { className: "bg-background flex items-center gap-3 px-4 py-3", children: [_jsx("div", { className: "flex min-w-0 flex-1 flex-col", children: _jsx("span", { className: "truncate text-sm font-medium", children: filename }) }), _jsx("a", { href: previewUrl(path), download: filename, className: "text-muted-foreground hover:text-foreground shrink-0 cursor-pointer rounded p-1.5 transition-colors", "aria-label": `Download ${filename}`, children: _jsx(DownloadIcon, { className: "h-4 w-4" }) })] })] })] }));
66
+ if (loadError) {
67
+ return (_jsxs("div", { "data-testid": "inline-attachment-image-error", className: "text-muted-foreground flex items-center gap-2 rounded-md border px-3 py-2 text-sm", children: [_jsx(ImageOff, { className: "h-4 w-4 shrink-0" }), _jsx("span", { className: "truncate", children: filename })] }));
68
+ }
69
+ return (_jsxs(Dialog, { children: [_jsx(DialogTrigger, { asChild: true, children: _jsx("img", { src: previewUrl(path), alt: filename, "data-testid": "inline-attachment-image", onError: () => setLoadError(true), className: "max-h-48 max-w-full cursor-pointer rounded-md border object-contain transition-opacity hover:opacity-80" }) }), _jsxs(DialogContent, { className: "max-w-3xl gap-0 overflow-hidden border-0 p-0 [&>button:last-child]:!cursor-pointer [&>button:last-child]:!rounded-full [&>button:last-child]:!bg-black/70 [&>button:last-child]:!p-1.5 [&>button:last-child]:!text-white [&>button:last-child]:!opacity-100 [&>button:last-child]:!shadow-lg [&>button:last-child]:!backdrop-blur-md [&>button:last-child]:hover:!bg-black/90", children: [_jsx(VisuallyHidden.Root, { children: _jsxs(DialogTitle, { children: ["Preview: ", filename] }) }), _jsx("div", { className: "relative bg-black/90", children: _jsx("img", { src: previewUrl(path), alt: filename, className: "h-auto max-h-[70vh] w-full object-contain" }) }), _jsxs("div", { className: "bg-background flex items-center gap-3 px-4 py-3", children: [_jsx("div", { className: "flex min-w-0 flex-1 flex-col", children: _jsx("span", { className: "truncate text-sm font-medium", children: filename }) }), _jsx("a", { href: previewUrl(path), download: filename, className: "text-muted-foreground hover:text-foreground shrink-0 cursor-pointer rounded p-1.5 transition-colors", "aria-label": `Download ${filename}`, children: _jsx(DownloadIcon, { className: "h-4 w-4" }) })] })] })] }));
65
70
  }
66
71
  return (_jsx("a", { href: previewUrl(path), download: filename, "data-testid": "inline-attachment-file", className: "text-primary text-sm underline underline-offset-2", children: filename }));
67
72
  }