К основному содержанию
скилл CX Codex

integrate-file-viewer — скилл для Claude Code: что делает

Пошагово внедряет компонент CogniteFileViewer в приложения Flows для предварительного просмотра файлов CDF, отчётов и изображений.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add cognitedata/builder-skills --skill integrate-file-viewer -a claude-code
Открыть на GitHub

Что делает integrate-file-viewer

Скилл автоматизирует перенос библиотеки просмотра файлов в проект на базе Flows. Агент проверяет package.json и vite.config.ts, копирует исходные модули просмотрщика в папку src/cognite-file-viewer/ и устанавливает зависимость react-pdf@^9.1.1. Отдельно ставить pdfjs-dist не требуется, так как пакет уже включён в состав react-pdf.

В vite.config.ts добавляется исключение optimizeDeps.exclude: ['pdfjs-dist']. Это предотвращает предварительную сборку Vite, которая ломает работу воркера PDF.js. Компонент поддерживает просмотр PDF, картинок (JPEG, PNG, WebP, SVG, TIFF), текста (.txt, .csv, .json), а также документов Office через конвертацию CDF Document Preview API.

Без явной высоты контейнера просмотрщик схлопнется в ноль, поэтому для родителя или через свойство style обязательно задавать размеры. Источник данных передаётся через instanceId, internalId или прямую ссылку url.

Какие задачи решает

  • встроить CogniteFileViewer в приложение Flows
  • настроить react-pdf и воркер PDF.js в сборке Vite
  • отобразить PDF, офисные документы и изображения из CDF
  • подключить слой аннотаций схем для файлов с instanceId

Примеры запросов агенту

  • Встрой просмотрщик CDF-файлов в наш компонент карточки актива
  • Добавь просмотр PDF и офисных документов через CogniteFileViewer
  • Настрой отображение файлов из CDF с поддержкой зума и слоя аннотаций

Как установить integrate-file-viewer

1Через Skills CLI (Vercel)

npx skills add cognitedata/builder-skills --skill integrate-file-viewer -a claude-code

2Вручную: положить файлы

~/.claude/skills/integrate-file-viewer/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/integrate-file-viewer/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о integrate-file-viewer

Как установить integrate-file-viewer в Claude Code?

Выполните в терминале команду npx skills add cognitedata/builder-skills --skill integrate-file-viewer -a claude-code. Файл навыка появится по пути ~/.claude/skills/integrate-file-viewer/SKILL.md.

Что делает скилл integrate-file-viewer?

Он направляет агента по шагам интеграции: переносит модули просмотрщика в src/cognite-file-viewer/, добавляет react-pdf@^9.1.1 и исключает pdfjs-dist из оптимизации Vite.

Какие форматы файлов поддерживает просмотрщик?

Компонент открывает PDF, текст (.txt, .csv, .json), растровые и векторные изображения, а также документы Word, Excel, PowerPoint и LibreOffice через предварительную конвертацию в CDF.

Исходный текст

SKILL.md · Apache-2.0
---
name: integrate-file-viewer
description: "MUST be used whenever integrating CogniteFileViewer into a Flows app to preview CDF files (PDFs, images, text). Do NOT manually wire up react-pdf or file resolution — this skill handles installation, Vite config, worker setup, and component usage. Triggers: file viewer, file preview, CogniteFileViewer, PDF viewer, view CDF files, document viewer, preview file."
allowed-tools: Read, Glob, Grep, Edit, Write, Bash
---

# Integrate CogniteFileViewer

Add `CogniteFileViewer` to this Flows app to preview CDF files (PDF, image, text).

## Dependencies

The file-viewer library files (copied in Step 2) require this npm package:

| Package | Version |
|---|---|
| `react-pdf` | `^9.1.1` |

`pdfjs-dist` ships as a dependency of `react-pdf` at the correct version — do not install it separately.
`react` and `@cognite/sdk` are assumed to already be present in Flows apps.

---

## Your job

Complete these steps in order. Read each file before modifying it.

---

## Step 1 — Understand the app

Read these files before touching anything:

- `package.json` — detect package manager (`packageManager` field or lock file) and existing deps
- `vite.config.ts` — understand current Vite setup
- The component where the viewer should be added

---

## Step 2 — Copy the file-viewer source files

The file-viewer library lives in the `code/` directory next to this skill file. Read and copy
**all** files from there into `src/cognite-file-viewer/` inside the app:

- `code/types.ts`
- `code/mimeTypes.ts`
- `code/fileResolution.ts`
- `code/useViewport.ts`
- `code/useFileResolver.ts`
- `code/useDocumentAnnotations.ts`
- `code/DocumentAnnotationOverlay.tsx`
- `code/CogniteFileViewer.tsx`
- `code/index.ts`

> The PDF.js worker is configured inside `CogniteFileViewer.tsx` — no separate consumer setup is needed.

---

## Step 3 — Install dependencies

Install `react-pdf` (see **Dependencies** above) using the app's package manager:

- pnpm → `pnpm add react-pdf@^9.1.1`
- npm  → `npm install react-pdf@^9.1.1`
- yarn → `yarn add react-pdf@^9.1.1`

> **pnpm users:** pnpm's strict linking may prevent the browser from resolving `pdfjs-dist`. Either add `pdfjs-dist` as a direct dependency (`pnpm add pdfjs-dist`), or add `public-hoist-pattern[]=pdfjs-dist` to `.npmrc`.

---

## Step 4 — Configure Vite

Add `optimizeDeps.exclude: ['pdfjs-dist']` to `vite.config.ts` to prevent Vite from pre-bundling pdfjs-dist (which breaks the worker):

```ts
export default defineConfig({
  // ... existing config ...
  optimizeDeps: {
    exclude: ['pdfjs-dist'],
  },
});
```

---

## Step 5 — Use the component

Import and render `CogniteFileViewer` from the locally copied files:

```tsx
import { CogniteFileViewer } from './cognite-file-viewer';
```

Get the `sdk` from the `useDune()` hook (already available in every Flows app):

```tsx
import { useDune } from '@cognite/dune';
const { sdk } = useDune();
```

### Supported file types

| Type | Formats |
|---|---|
| PDF | `.pdf` — page navigation, zoom, pan, diagram annotation overlay |
| Office documents | Word, PowerPoint, Excel, ODS, ODP, ODT, RTF, TSV — converted to PDF via the CDF Document Preview API, then rendered identically to PDF |
| Image | JPEG, PNG, WebP, SVG, TIFF — zoom, pan, rotation |
| Text | `.txt`, `.csv`, `.json` — rendered as preformatted text |
| Other | Falls back to `renderUnsupported` |

### Minimal usage

This is all you need — zoom, pan, and touch gestures are handled internally:

```tsx
<CogniteFileViewer
  source={{ type: 'internalId', id: file.id }}
  client={sdk}
  style={{ width: '100%', height: '600px' }}
/>
```

> **The component needs a defined height.** If the parent has no explicit height, the viewer will collapse to zero. Always set a `height` via `style`, `className`, or the parent container.

### File source

Pass any of three source types:

```tsx
// By instance ID (data-modelled file — enables annotations)
<CogniteFileViewer
  source={{ type: 'instanceId', space: 'my-space', externalId: 'my-file' }}
  client={sdk}
/>

// By CDF internal ID
<CogniteFileViewer
  source={{ type: 'internalId', id: 12345 }}
  client={sdk}
/>

// By direct URL
<CogniteFileViewer
  source={{ type: 'url', url: 'https://...', mimeType: 'application/pdf' }}
/>
```

**Prefer `instanceId` when available** — it's the only source type that enables the diagram annotation overlay. When listing files via `sdk.files.list()`, check `file.instanceId` first:

```tsx
source={
  file.instanceId
    ? { type: 'instanceId', space: file.instanceId.space, externalId: file.instanceId.externalId }
    : { type: 'internalId', id: file.id }
}
```

### Full props reference

```tsx
<CogniteFileViewer
  // Required
  source={source}
  client={sdk}              // required for instanceId and internalId sources

  // PDF pagination
  page={page}               // controlled current page (1-indexed)
  onPageChange={setPage}
  onDocumentLoad={({ numPages }) => setNumPages(numPages)}

  // Zoom & pan (works on PDF and images)
  zoom={zoom}               // 1 = 100%; Ctrl/Cmd+wheel, pinch-to-zoom, and middle-click drag built in
  onZoomChange={setZoom}
  minZoom={0.25}            // default
  maxZoom={5}               // default
  panOffset={pan}           // controlled pan offset; resets on page change
  onPanChange={setPan}

  // Fit mode
  fitMode="width"           // 'width' fits to container width; 'page' fits entire page in container

  // Rotation (PDFs and images)
  rotation={rotation}       // 0 | 90 | 180 | 270

  // Diagram annotations (instanceId sources only)
  showAnnotations={true}    // default
  onAnnotationClick={(annotation) => { /* annotation.linkedResource has space + externalId */ }}
  onAnnotationHover={(annotation) => {}}

  // Custom annotation tooltip (replaces native <title> tooltip)
  renderAnnotationTooltip={(annotation, rect) => (
    <div style={{
      position: 'absolute',
      left: rect.x + rect.width,
      top: rect.y,
      zIndex: 11,
    }}>
      {annotation.text}
    </div>
  )}

  // Custom overlay (SVG paths, highlights, drawings — works on PDF and images)
  renderOverlay={({ width, height, originalWidth, originalHeight, pageNumber, rotation }) => (
    <svg
      width={width}
      height={height}
      viewBox={`0 0 ${originalWidth} ${originalHeight}`}
      preserveAspectRatio="none"
      style={{ position: 'absolute', top: 0, left: 0, pointerEvents: 'all' }}
    >
      <path d="..." stroke="cyan" fill="none" />
    </svg>
  )}

  // Custom renderers (all optional)
  renderLoading={() => <MySpinner />}
  renderError={(error) => <MyError message={error.message} />}
  renderUnsupported={(mimeType) => <div>Cannot preview {mimeType}</div>}

  // Layout
  className="..."
  style={{ width: '100%', height: '100%' }}
/>
```

---

## Tips & tricks

**Reset page, zoom and rotation when the source changes.**
The component does not reset these automatically when you switch files — do it yourself:

```ts
const navigateToFile = (file: FileInfo) => {
  setSelectedFile(file);
  setPage(1);
  setZoom(1);
  setRotation(0);
};
```

**Gate pagination UI on `numPages > 0`.**
`onDocumentLoad` only fires for PDFs. Don't render pagination controls until you know there are pages to paginate:

```tsx
{numPages > 0 && (
  <>
    <button disabled={page <= 1} onClick={() => setPage(p => p - 1)}>‹</button>
    <span>{page} / {numPages}</span>
    <button disabled={page >= numPages} onClick={() => setPage(p => p + 1)}>›</button>
  </>
)}
```

**Annotation click → navigate to linked file.**
`annotation.linkedResource` contains the `space` and `externalId` of the linked CDF instance. Match it against `file.instanceId` to navigate:

```ts
onAnnotationClick={(annotation) => {
  if (!annotation.linkedResource) return;
  const { space, externalId } = annotation.linkedResource;
  const linked = files.find(
    f => f.instanceId?.space === space && f.instanceId?.externalId === externalId
  );
  if (linked) navigateToFile(linked);
}}
```

**Touch support is built in.** Two-finger pinch-to-zoom and two-finger drag-to-pan work on touch devices automatically. No configuration needed.

**Pan is middle-click drag** (when zoomed in) on desktop. Left-click remains free for annotation clicks and text selection.

**Ctrl/Cmd + wheel zooms toward the cursor** — also built in. Wire `zoom`/`onZoomChange` if you want programmatic zoom buttons or to persist zoom state; otherwise it works fully uncontrolled.

**`renderOverlay` receives original page dimensions** (`originalWidth`, `originalHeight`) so you can set up an SVG `viewBox` in the original coordinate space. Paths drawn in PDF-point or image-pixel coordinates will map correctly to the rendered page at any zoom level.

---

## Common pitfalls

| Problem | Cause | Fix |
|---|---|---|
| `Failed to resolve module specifier 'pdf.worker.mjs'` | pdfjs-dist not hoisted (pnpm) | Add `public-hoist-pattern[]=pdfjs-dist` to `.npmrc`, or `pnpm add pdfjs-dist` directly |
| `API version does not match Worker version` | `pdfjs-dist` version mismatch between app and `react-pdf` | Do not install `pdfjs-dist` separately — let `react-pdf` provide it. If already installed, remove it |
| Annotations never show | `instanceId` is `undefined` — annotation overlay is disabled without it | Use `instanceId` source, or fall back and accept no annotations for classic files |
| Annotations show but are empty | File has no `CogniteDiagramAnnotation` edges in CDF | Expected — only P&ID/diagram files synced to the data model have annotations |
| Viewer collapses to zero height | Parent has no explicit height | Set `height` via `style`, `className`, or parent CSS |

© cognitedata · Apache-2.0 · cognitedata/builder-skills

Похожие скиллы

Всё по теме «Фронтенд и UI» →
frontend-design официальный anthropics Скилл задаёт осмысленное визуальное направление для новых интерфейсов и редизайна. Подойдёт, когда стандартный шаблонный UI не устраивает. 1 025 790установок design-taste-frontend Leonxlnx Скилл задаёт арт-дирекцию для публичных страниц и рабочих экранов, а затем проверяет результат в браузере по скриншотам. Нужен, когда интерфейс выглядит шаблонным или недоработанным. CX Codex +1 678 700установок prototype Matt Pocock Создаёт временный прототип, чтобы проверить логику, модель состояния или вид интерфейса до работы над основным кодом. 986 201установок hyperframes heygen-com Скилл задаёт агенту правила рендера HTML-кода в видео через HyperFrames. Помогает собирать проморолики, эксплейнеры и титры прямо в коде проекта. CX Codex +1 1 200 000установок hyperframes-cli heygen-com Управляет проектами HyperFrames через терминал: собирает таймлайн, проверяет контраст кадров, запускает предпросмотр и рендерит видео локально или в облаке. CX Codex +1 1 300 000установок webapp-testing официальный anthropics Скилл запускает проверки локальных веб-приложений через Playwright: помогает отлаживать UI, делать скриншоты и смотреть логи браузера. 186 758установок

Из того же набора24

graph-viewer Скилл помогает встроить интерактивный граф модели данных CDF в приложение на Flows: узлы, связи и обратные связи. CX Codex +1 1 900установок setup-flows-auth Настраивает авторизацию React-приложений в Cognite Flows и Fusion iframe. Скилл определяет тип интеграции, ставит нужные SDK и правит конфигурацию Vite. CX Codex +1 1 900установок setup-python-tools Ставит клиентское выполнение Python-инструментов через Pyodide в приложение с уже готовым useAtlasChat. Нужен, когда агент отдаёт код инструмента, а считать он должен в браузере. CX Codex +1 1 900установок dm-limits-and-best-practices Справочный скилл про лимиты CDF Data Modeling: конкурентность и 429, пагинация, батчи, QueuedTaskRunner. Пригодится, когда код сыпет ошибками на нагрузке. CX Codex +1 1 900установок security Проходит по приложению Flows шаг за шагом: находит утечки секретов, опасный DOM, дыры в авторизации — и сразу правит их. CX Codex +1 1 900установок integrate-atlas-chat Скилл для встраивания чата Atlas прямо в интерфейс приложения Cognite. Нужен, когда сайдбар Fusion/EOS недоступен. CX Codex +1 1 900установок correctness-and-error-handling Скилл находит и устраняет сбои в React-коде Cognite Flows: монтирует Error Boundary, обрабатывает промисы и закрывает пустые состояния интерфейса. CX Codex +1 1 900установок integrate-todo-list Добавляет в приложение инструмент TodoWrite и панель, где видно, как агент Atlas выполняет многошаговую работу. CX Codex +1 1 900установок

Спонсоры проекта

Компании, которые помогают держать аналитику открытой