Phials developer documentation
User guide

Metadata

Metadata providers extract structured fields from files and optionally declare a schema so Phials can show Details columns and property UI. Multiple providers can match one file; the host merges keyed values into ExtractedMetadata (later providers overwrite duplicate keys).

Types: MetadataProvider, MetadataAPI, MetadataColumnPolicy, DirectoryMetadataProfile.

Related: Plugin overview · Plugin API · Preview

Mental model

  1. Raw metadata — string map from the host file-metadata pipeline plus timestamps from FileEntry.
  2. extract(file, rawMeta, api) — returns ExtractedMetadata (JSON-serializable values).
  3. Merge — order follows matched providers sorted by priority (higher first); collisions favor later providers in that list.
  4. schema — optional MetadataSchemaField list (key, label, type, …) for columns and formatting.
  5. columnPolicy — controls column picker and auto-visible behavior (dominance sampling, caps, exclusions).

Matching providers

Same style of extension / MIME / category index as previews, plus global providers:

  • A provider with empty extensions, mimeTypes, and categories, and no canHandle, is treated as global and considered for every file.

Per candidate:

  • If canHandle exists, it must return true (signature (file: FileEntry) => boolean only — unlike preview canHandle).
  • Otherwise match on extension, MIME, category, or global.

Sort by priority (higher first) before running extract.

MetadataAPI

Extends the plugin API with read helpers for file content used in extraction. Declare filesystem.read (and the Phials version you need) so readFile / readTextFile are allowed for your plugin.

Column policy (summary)

FieldMeaning
showInColumnMenuOmit from column picker when false (entire provider); takes precedence over columnWhitelist.
columnWhitelistIf set, only these schema keys appear in the column picker and in auto-visible picks. Omit for all schema fields. An empty array excludes the provider from column contributions.
autoVisibleControls automatic column insertion (never, dominance-based, …).
defaultVisibleFieldsSubset of schema keys when auto-visible runs (subject to caps).
excludeFromDominanceSkip when computing dominant provider stats for a directory.
requiresValueSamplingExclude from naive auto-visible heuristics.

Directory dominance profiles sample files in a folder to decide which metadata columns should appear by default; exact thresholds ship with the app version you target — test against real directories.

Minimal example

const myMetadata: MetadataProvider = {
	type: "metadata",
	id: "my.vendor.metadata",
	name: "My Metadata",
	priority: 20,
	extensions: ["log"],
	extract: async (file, rawMeta, api) => {
		const text = await api.readTextFile(file.path);
		const lines = text.split("\n").length;
		return { logLines: lines };
	},
	schema: {
		fields: [{ key: "logLines", label: "Lines", type: "number" }],
	},
	columnPolicy: {
		autoVisible: "when-dominant",
		defaultVisibleFields: ["logLines"],
	},
};

Pitfalls

  • canHandle vs global — Empty filters plus canHandle does not make a provider global.
  • Merged keys — use prefixed keys (myPlugin.foo) to avoid collisions with other providers.
  • Raw vs extracted — guard missing rawMeta keys; coerce types defensively.
  • readTextFile / readFile require filesystem.read in your manifest (and a minAppVersion that supports the behavior you rely on).