本文へ移動
cccskills
無料GitHub で公開

enhance-file-type

Adding a file type or upgrading any of its capability slots in the files feature (preview, edit, thumbnail, grid card, info, share, versions, conversion, diff, rail panel). Use when supporting a new extension or MIME type, building a previewer, touching FILE_TYPES, PreviewKind, FilePreview.tsx, EDITABLE_KINDS, or surfaces/single-file/, or working the FILE_SURFACES.md wishlist.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md13.2 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Enhance a file type

The matrx-admin file system has one registry (FILE_TYPES), one preview dispatcher (FilePreview.tsx), one edit dispatcher (FileTabsBody.tsx → EditTabContent), and two viewer shells (PreviewPane side panel + SingleFileShell full page). A "complete" file type touches ~55 capability slots organized into 9 groups (Identity, List/Grid, Preview, Edit, Companion tabs, Actions, Cross-feature, Creation, Bundle). Every kind lives somewhere on a T0 → T1 → T2 curve and the inventory tracks both current state and per-type wishlists.

Use this skill when

  • Adding a new file extension or MIME type to the registry
  • Building a new <Kind>Preview previewer or upgrading an existing one
  • Adding a previewKind to the PreviewKind union
  • Wiring the Edit tab for a new kind (extending EDITABLE_KINDS and Monaco's LANGUAGE_BY_EXT)
  • Building a rail panel in surfaces/single-file/ for a new editing/preview mode
  • Adding a new control to FileViewerControlsContext
  • Working any item off FILE_SURFACES.md (common-docs)'s per-type wishlist
  • Upgrading a thumbnail strategy, Info-tab field, Analysis detector, or action-bar button for a specific kind

Mental model — 9 capability groups

GroupWhat it coversWhere it lives
1. Identityextensions, MIME, category, icon, color, previewKind, sensitivityFILE_TYPES registry
2. List + Gridicons, kind chip, thumbnail strategy, grid card body, quick-lookFILE_TYPES, FileIcon, grid card components
3. Previewpreviewer component, streaming policy, size cap, rail panel, error/loading statespreviewers/<Kind>Preview.tsx, rail under single-file/
4. EditEDITABLE_KINDS, Monaco language, save handler, format-on-save, starter templatesEditTabContent, CloudFileInlineEditor
5. Companion tabsDocument (RAG), Analysis, Info, Versions, Share, diffEach tab's component + backend
6. Actionsuniversal actions, edit handoff, open-in-feature, convert-to, per-type extraspreview-actions.ts, useFileActions
7. Cross-featureinline chip, drag-to-slot, citation deep-links, paste-from-clipboardVarious consumers
8. Creation"New <type>" entry, templates, virtual-source provisioningFuture work
9. Bundle/Opsdynamic-import declaration, bundle weight, codec caveatsFilePreview.tsx, this doc

Full slot list (numbered 1–55) lives in ../common-docs/systems/files/file-service/FILE_SURFACES.md → Part 1 — Capability framework. Read that section before scoping any non-trivial change.

Workflow

Copy this checklist and tick items as you go:

- [ ] Step 1 — Scope: identify file type + capability slot
- [ ] Step 2 — Read the inventory entry for that type
- [ ] Step 3 — Map the slot to code surfaces (use the table below)
- [ ] Step 4 — Implement (≤4 files for most changes)
- [ ] Step 5 — Verify in both PreviewPane and SingleFileShell
- [ ] Step 6 — Run lints + tsc
- [ ] Step 7 — Update FILE_SURFACES.md (common-docs) (matrix + wishlist + priorities)
- [ ] Step 8 — Update features/files/FEATURE.md change log

Step 1 — Scope

Decide one of:

A. New file extension to an existing previewKind — e.g. add .heif to image. Single registry change.

B. New previewKind — e.g. add Jupyter notebook renderer. Touches the PreviewKind union, the registry, the preview dispatcher, and a new previewer file.

C. Capability upgrade on an existing kind — e.g. add click-and-drag pan to Image, or wire the PDF Extractor into the PDF Edit tab. Touches the previewer/rail/context.

D. Cross-cutting capability — e.g. add format-on-save (slot #28), or add convertTo to the action bar (slot #42). Touches the platform, then per-kind opt-in.

If unsure which slot a request maps to, scan Part 1 of the inventory.

Step 2 — Read the inventory entry

Open ../common-docs/systems/files/file-service/FILE_SURFACES.md and read:

  1. Part 2's wishlist for the type you're touching (Image / PDF / HTML / Markdown / Video / Code — these have full per-type wishlists today). If your type doesn't have a Part 2 entry yet, find it in Part 3's matrix.
  2. Part 1 to confirm which slot # you're filling.

If your work fulfills a wishlist item, you'll be checking it off in Step 7.

Step 3 — Map the slot to code

Use this table. Match the slot number to the file(s) you'll touch:

SlotsFiles to touch
1–9 (Identity)features/files/utils/file-types.ts → FILE_TYPES[]
10–12 (Icon / thumb strategy)file-types.ts + FileIcon; for real thumbs: useFileAsset variants
13–14 (Grid card / quick-look)Grid card components in features/files/components/... (search for FileGridCard)
15 (Kind-filter chip)Kind filter chip data
17–23 (Preview tab)core/FilePreview/FilePreview.tsx (dispatcher), previewers/<Kind>Preview.tsx, optional surfaces/single-file/<Mode>Controls.tsx for the rail, surfaces/FileViewerControlsContext.tsx if you need new shared state
24–26 (Edit tab core)surfaces/FileTabsBody.tsx → EditTabContent, core/FilePreview/preview-actions.ts → EDITABLE_KINDS, core/FileEditor/CloudFileInlineEditor.tsx → LANGUAGE_BY_EXT
27 (Non-text editor)New component under core/FileEditor/<Kind>Editor.tsx, plus a branch in EditTabContent
28 (Format-on-save)CloudFileInlineEditor.handleSave — add a per-language formatter dispatch
30–31 (Document / RAG)Python backend; no per-type front-end work for ingest
32 (Analysis detectors)features/file-analysis/** (detectors live there); register the kind in the Analysis tab
33–34 (Info tab)FileInfoTab.tsx + the metadata source (signed URL extraction, EXIF, etc.)
35–36 (Versions / diff)FileVersionsList.tsx; for diffs, new <Kind>Diff.tsx rendered from the versions list
37 (Share)FileShareTab.tsx (uniform — rarely per-type)
38–39 (Actions)preview-actions.ts; for edit gating: EDITABLE_KINDS
40–41 (Open-in-feature, per-type extras)preview-actions.ts + the destination feature's route adapter
42 (Convert-to)Platform-level dropdown (does not exist yet — design first)
43 (Print)block-print-system skill
44 (Inline chip)FileResourceChip
53–54 (Bundle)next/dynamic declaration in FilePreview.tsx

Step 4 — Implement

Most changes are 1–4 files. Patterns:

Pattern A — Add an extension to an existing previewKind

Edit FILE_TYPES in features/files/utils/file-types.ts. Add the ext + MIME to the matching entry. Done.

Pattern B — Add a new previewKind

  1. Add the literal to the PreviewKind union in file-types.ts
  2. Add the registry entries pointing at it
  3. Add a case "<kind>": in FilePreview.tsx's dispatcher with a next/dynamic import
  4. Create core/FilePreview/previewers/<Kind>Preview.tsx
  5. If editable: add "<kind>" to EDITABLE_KINDS + ensure EditTabContent routes it
  6. If it has interactive controls in SingleFileShell: add a <Mode>Controls.tsx panel + register it in FileViewerControlRail, and add any shared state to FileViewerControlsContext

Pattern C — Upgrade an existing previewer

  1. Make the change in previewers/<Kind>Preview.tsx
  2. If it introduces new rail state: extend FileViewerControlsContext (typed props + setters)
  3. Add/extend the matching <Mode>Controls.tsx panel
  4. Verify the previewer still works without context (passive mode in PreviewPane)

Step 5 — Verify in both surfaces

This is the #1 thing agents get wrong. Previewers run in two surfaces:

  • PreviewPane — side panel from the files browser. The FileViewerControlsContext is NOT mounted here. Previewers must work in passive mode with no rail.
  • SingleFileShell — dedicated /files/f/{id} route. The rail is mounted, context is populated, controls drive the previewer.

Test paths:

  1. https://www.aimatrx.com/files → click a file row → verify side-panel preview works
  2. https://www.aimatrx.com/files/f/{id} → verify full-page preview + rail controls work

Previewers should useFileViewerControls()-style read context but never require context. Always have a sensible default.

Step 6 — Lints + tsc

pnpm lint
NODE_OPTIONS="--max-old-space-size=8192" pnpm tsc --noEmit

Step 7 — Update the inventory

Open ../common-docs/systems/files/file-service/FILE_SURFACES.md and update:

  1. Part 3 (matrix) — change the ✅/🟡/🔴/🐛 marker in the relevant row + update the Notes column
  2. Part 2 (wishlist) — if you completed a wishlist item, either strike it through (~~item~~ ✅ **Shipped.** …) or remove it. Add any newly-discovered follow-up items.
  3. Priority recommendations (end of doc) — if your work knocked out a numbered item, mark it shipped the same way HTML and Image were.

If you added a new previewKind or graduated a kind to T1/T2, add a new Part 2 entry following the template (Has / Wishlist / Code touchpoints).

Step 8 — Update the feature doc

Append a one-line entry to features/files/FEATURE.md's Change Log with the date and a summary. If your change touches an invariant (e.g. "previewers must work without rail context"), update that section too.

Common pitfalls

  1. Forgetting EDITABLE_KINDS. Adding Monaco support without adding the kind to EDITABLE_KINDS means the Edit button stays hidden.
  2. Forgetting Monaco's LANGUAGE_BY_EXT. Adding a previewKind: "code" extension without a LANGUAGE_BY_EXT entry opens it as plaintext in Monaco — no syntax highlighting in Edit.
  3. Tightly coupling a previewer to the rail context. Previewers run in PreviewPane (no rail) AND SingleFileShell (with rail). Read useFileViewerControls() with a default fallback, never require it.
  4. Size-cap mismatch. Streaming previewers (image, video, audio, pdf, html) should override previewSizeCapOverride via getFilePreviewProfile — they don't blob-fetch the whole file. Non-streaming previewers respect the default cap.
  5. Sandbox policy on HTML-like content. The HTML iframe sandbox is allow-scripts allow-popups allow-forms and does not include allow-same-origin. Anything that needs cookies/localStorage cannot run there — and shouldn't.
  6. Skipping the Part 2 update. The wishlist is the operating doc. If you ship a wishlist item without checking it off, the next agent will think the work is still open.
  7. Adding a new top-level .md for the new feature. Don't. One doc per concern — extend FILE_SURFACES.md (common-docs) and the file's FEATURE.md.

Decision matrix — which surface holds the control?

When a previewer needs an interactive control (zoom, viewport, line-wrap, …):

Where the control belongsWhen
Inline in the previewer's own headerThe control is fundamental to viewing (e.g. Rendered/Source toggle for HTML). Must work in PreviewPane.
In a single-file/<Mode>Controls.tsx rail panelThe control is power-user / space-intensive (zoom slider, viewport picker, font size, minimap toggle). Only mounted in SingleFileShell.
BothProvide a minimal version inline and a richer version on the rail. The inline version reads FileViewerControlsContext if mounted, else its own local state.

Default: rich controls on the rail, with a sensible default applied when the previewer renders without context.

Bundle budget

Previewers are dynamically imported (next/dynamic). Heavy deps (PDF.js, SheetJS, Three.js when added) must stay dynamic — never import them at the top of FilePreview.tsx or any of its eagerly-loaded ancestors. Annotate bundle weight in FilePreview.tsx if it's non-trivial.

Pre-PR checklist

  • Registry entry has all 9 Group-1 fields populated (or N/A justified)
  • Previewer renders in PreviewPane (no rail) without errors
  • Previewer renders in SingleFileShell (with rail) with controls wired
  • If editable: EDITABLE_KINDS and LANGUAGE_BY_EXT both updated
  • Lints pass, tsc --noEmit passes
  • FILE_SURFACES.md (common-docs) Part 3 markers updated for affected rows
  • FILE_SURFACES.md (common-docs) Part 2 wishlist entries struck through / amended
  • FILE_SURFACES.md (common-docs) Priority recommendations updated if a numbered item shipped
  • features/files/FEATURE.md Change Log appended
  • No new top-level .md files created
  • No DEBUG rings / DebugLayerLabel re-introduced

Additional resources

  • Inventory + framework + wishlists: ../common-docs/systems/files/file-service/FILE_SURFACES.md
  • Files feature doc: features/files/FEATURE.md
  • File handler skill: features/files/handler/FEATURE.md (for upload / asset URL questions — different concern)
  • Print system skill: .claude/skills/block-print-system/SKILL.md (for slot #43 — print)
  • Window panels skill: .claude/skills/window-panels/SKILL.md (if your enhancement opens an overlay)

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Admin debug system wiring for the floating AdminIndicator's live debug data and Copy Full Context. Use when adding debug visibility to a route or feature, wiring useDebugContext or the debug panel, capturing console errors, or enabling the copy-context workflow for a page.

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

Compact two-icon Copy / Copy-for-AI controls (components/agent-copy). Use when adding copy buttons to a row, card, list, or record; merging duplicate Copy/JSON/AI controls; continuing the copy rollout; or writing a Copy-for-AI payload. NOT for markdown content actions (use rich-document-actions).

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

Disclosing a surface's existing fixed AI jobs in the shell's top Agents menu. Use when a page, panel, overlay, or window already runs a mandate behind a button, assist, automatic action, or mode; when the agent-disclosure guard names a file; or during a surface check.

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

The watch-fix-rerun method for making an existing platform agent or automated process efficient and correct: baseline its ledger, run one unit yourself, fix the class behind every wasted call, rerun, record. Use when asked to improve, optimize, watch, or 'make efficient' an agent, a sandbox session, a sync job, or any recurring automated process.

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

Redux state for agent execution and firing agent shortcuts. Use when editing features/agents/redux/, building agent UI, creating a conversation, touching assembleRequest or NDJSON stream state, wiring agent-state selectors, adding a per-conversation capability, or triggering a shortcut from a button, menu, or code (useShortcutTrigger, launchAgentExecution).

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

The provision for a call site: the exhaustive menu of values that place in the code can realistically produce. Use before creating or fixing a mandate or agent that reasons about more than its own input, when deciding whether an agent can answer at all with what it is sent, or when its output 'looks right' but nobody checked it could be. NOT for building the agent (use create-agent).

日本語の概要は準備中です。原文の説明を表示しています。

armanisadeghi/ai-matrx32026年10月13日 更新

armanisadeghi のスキルをすべて見る

このスキルの問題を報告する