@phoundry/phials-plugin-sdk 1.0.0 → 1.0.2

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.
@@ -29,9 +29,9 @@ type CommandContextKey =
29
29
  | "selectionIsFile" // All selected are files
30
30
  | "selectionIsDirectory" // All selected are directories
31
31
  | "selectionIsMixed" // Mix of files and directories
32
- // Vial/Collection state
33
- | "inVial" // Current directory is a vial
34
- | "hasVialSelection" // Selected files are in a vial
32
+ // Workspace/Collection state
33
+ | "inWorkspace" // Current directory is a workspace
34
+ | "hasWorkspaceSelection" // Selected files are in a workspace
35
35
  // Clipboard
36
36
  | "hasClipboard" // Files in clipboard (cut/copy)
37
37
  | "clipboardIsCut" // Clipboard operation is cut
@@ -62,8 +62,8 @@ interface CommandContext {
62
62
  /** Current directory path */
63
63
  currentPath: string;
64
64
 
65
- /** Whether current directory is a vial */
66
- isVial: boolean;
65
+ /** Whether current directory is a workspace */
66
+ isWorkspace: boolean;
67
67
 
68
68
  /** Whether the saved-views scope has a property schema (e.g. Boards). */
69
69
  hasPropertySchema: boolean;
@@ -143,9 +143,7 @@ interface ContextMenuPlacementConfig extends CommandPlacementBase {
143
143
  /**
144
144
  * Union of all placement configurations.
145
145
  */
146
- type CommandPlacement =
147
- | ToolbarPlacementConfig
148
- | ContextMenuPlacementConfig;
146
+ type CommandPlacement = ToolbarPlacementConfig | ContextMenuPlacementConfig;
149
147
 
150
148
  // ─── Command Definition ──────────────────────────────────────────────────────
151
149
 
@@ -257,6 +255,14 @@ interface Command {
257
255
  */
258
256
  children?: Command[];
259
257
 
258
+ /**
259
+ * Optional custom items for menu surfaces that present this command as a
260
+ * submenu. Semantic children remain available to the Command Bar.
261
+ */
262
+ submenuItems?: (
263
+ ctx: CommandContext,
264
+ ) => import("phoundry-ui").MenuItem[];
265
+
260
266
  // ─── Custom Rendering ─────────────────────────────────────────────────────
261
267
 
262
268
  /**
@@ -37,7 +37,7 @@ interface EventSubscription {
37
37
  */
38
38
  type EventHandler<T = unknown> = (payload: T) => void | Promise<void>;
39
39
 
40
- /** Details column layout live-sync payload (ADR-0010). */
40
+ /** Details column layout live-sync payload. */
41
41
  interface ColumnLayoutChangedPayload {
42
42
  browsedPath: string;
43
43
  savedViewsCount: number;
@@ -94,22 +94,27 @@ interface CoreEvents {
94
94
  /** Persisted File Note content was created, updated, or removed */
95
95
  "core.file-note.saved": {
96
96
  path: string;
97
- vialPath: string;
97
+ workspacePath: string;
98
98
  hasNote: boolean;
99
99
  };
100
- /** Portable Page visibility/order changed for one Vial. */
101
- "core.vial-page-config.changed": {
102
- vialPath: string;
103
- page: VialPageConfig;
100
+ /** Portable Page visibility/order changed for one Workspace. */
101
+ "core.workspace-page-config.changed": {
102
+ workspacePath: string;
103
+ page: WorkspacePageConfig;
104
+ };
105
+ /** Canonical cell deltas or a filtered compatibility refetch for one Workspace. */
106
+ "core.workspace-values.changed": WorkspaceValuesChangedEvent;
107
+ /** Workspace Folder Property schemas changed, including paired Relations. */
108
+ "core.workspace-properties.changed": {
109
+ workspaceIds: string[];
110
+ sourcePaneId: string;
104
111
  };
105
- /** Canonical cell deltas or a filtered compatibility refetch for one Vial. */
106
- "core.vial-values.changed": VialValuesChangedEvent;
107
112
  /** Formula output types changed; every pane must normalize its consumers. */
108
- "core.vial-formula-output-types.changed": {
109
- vialId?: string;
110
- vialPath: string;
113
+ "core.workspace-formula-output-types.changed": {
114
+ workspaceId?: string;
115
+ workspacePath: string;
111
116
  propertyIds: string[];
112
- savedViews: SavedVialView[];
117
+ savedViews: SavedWorkspaceView[];
113
118
  sourcePaneId: string;
114
119
  };
115
120
  /** File opened */
@@ -129,8 +134,8 @@ interface CoreEvents {
129
134
  /** App setting value changed */
130
135
  "core.settings.changed": { key: string; value: unknown };
131
136
 
132
- /** Known vials list changed (add/remove/rename in session) */
133
- "core.known-vials.changed": { paths: string[] };
137
+ /** Known workspaces list changed (add/remove/rename in session) */
138
+ "core.known-workspaces.changed": { paths: string[] };
134
139
 
135
140
  /** Explorer always-hide globs changed */
136
141
  "core.config.hidden-globs.changed": { globs: string[] };
@@ -21,6 +21,7 @@ type FileCategory =
21
21
  | "ebook"
22
22
  | "spreadsheet"
23
23
  | "presentation"
24
+ | "plain text"
24
25
  // Code & Data
25
26
  | "code"
26
27
  | "code - data"
@@ -54,14 +55,16 @@ interface FileEntry {
54
55
  icon?: string;
55
56
  is_file: boolean;
56
57
  is_dir: boolean;
57
- is_vial: boolean;
58
- /** Nested vial folder when listing inside a parent vial */
59
- isChildVial?: boolean;
58
+ is_workspace: boolean;
59
+ /** Nested workspace folder when listing inside a parent workspace */
60
+ isChildWorkspace?: boolean;
60
61
  /** Listing node is a symlink or Windows directory junction */
61
62
  is_symlink?: boolean;
62
63
  /** Resolved absolute target when healthy; stored link text when broken */
63
64
  symlink_target?: string | null;
64
65
  symlink_broken?: boolean;
66
+ /** Bytes are not local. Set from listing metadata; absent means local or unknown. */
67
+ online_only?: boolean;
65
68
  size: number;
66
69
  created?: number | null;
67
70
  modified?: number | null;
@@ -91,6 +94,7 @@ type SortOrder = "asc" | "desc";
91
94
  type ViewMode =
92
95
  | "details"
93
96
  | "thumbnails"
97
+ | "masonry"
94
98
  | "column"
95
99
  | "tree"
96
100
  | "boards"
@@ -100,7 +104,7 @@ type ViewMode =
100
104
  /** Calendar view zoom level */
101
105
  type CalendarScope = "year" | "month" | "week" | "3day" | "day";
102
106
 
103
- /** Built-in calendar date sources (`created`, `modified`) or a vial property id */
107
+ /** Built-in calendar date sources (`created`, `modified`) or a workspace property id */
104
108
  type CalendarDateSourceId = "created" | "modified" | (string & {});
105
109
 
106
110
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phoundry/phials-plugin-sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "Public plugin SDK contract for Phials",
5
5
  "type": "module",
6
6
  "types": "./phials-plugin-sdk.d.ts",
@@ -110,6 +110,9 @@ type ProviderType = "preview" | "metadata" | "view" | "module" | "command";
110
110
 
111
111
  type PreviewDestination = "module" | "gallery" | "page" | "embed";
112
112
 
113
+ /** File-mode vs inspection chrome for a Preview surface. Destination still names the host. */
114
+ type PreviewPresentation = "file" | "inspection";
115
+
113
116
  /** Provider-owned state shared by every presentation of one file preview. */
114
117
  interface PreviewSession {
115
118
  /** Clean unreferenced sessions are disposed; unresolved work can retain itself. */
@@ -151,6 +154,12 @@ interface PreviewDestinationCapabilities {
151
154
  embed?: boolean;
152
155
  }
153
156
 
157
+ /** Intrinsic content dimensions reported by a thumbnail provider. */
158
+ interface ThumbnailIntrinsicDimensions {
159
+ width: number;
160
+ height: number;
161
+ }
162
+
154
163
  /**
155
164
  * Props passed to thumbnail components
156
165
  */
@@ -160,6 +169,10 @@ interface ThumbnailProviderProps {
160
169
  size: number;
161
170
  generatedSize?: number;
162
171
  quality?: number;
172
+ /** Report meaningful rendered dimensions to hosts that support ratio-aware layouts. */
173
+ onIntrinsicDimensions?: (
174
+ dimensions: ThumbnailIntrinsicDimensions,
175
+ ) => void;
163
176
  }
164
177
 
165
178
  /**
@@ -321,7 +334,11 @@ interface MetadataColumnPolicy {
321
334
  */
322
335
  columnWhitelist?: string[];
323
336
 
324
- /** Whether columns can be auto-shown from file matching alone. Default "when-dominant". */
337
+ /**
338
+ * Whether columns can be auto-shown from file matching alone.
339
+ * `"when-dominant"` means uniquely leading in the Folder (match ratio, then
340
+ * priority). It does not use the profile `dominant` flag.
341
+ */
325
342
  autoVisible?: "never" | "when-any" | "when-dominant";
326
343
 
327
344
  /** Fields to show automatically when the provider qualifies. Defaults to the first few schema fields. */
@@ -487,13 +504,13 @@ interface FileBrowserViewProvider {
487
504
  /** Optional: custom column configuration for this view */
488
505
  columns?: ViewColumnDefinition[];
489
506
 
490
- /** If true, this view is only available in collections (vials) */
507
+ /** If true, this view is only available in collections (workspaces) */
491
508
  collectionOnly?: boolean;
492
509
 
493
510
  /**
494
511
  * Default item size when a folder has no per-folder override (`itemSize` null).
495
- * Details family uses row-height ticks; thumbnails / gallery use grid ticks;
496
- * Boards uses its column-width ticks.
512
+ * Details family uses row-height ticks; Thumbnails, Masonry, and Gallery each
513
+ * have their own S/M/L grid ticks; Boards uses its column-width ticks.
497
514
  */
498
515
  defaultItemSizePreset?: ViewItemSizePreset;
499
516
 
@@ -891,6 +908,8 @@ interface PluginSettings {
891
908
  unset(key: string): Promise<void>;
892
909
  /** Remove every durable value and reveal all schema defaults. */
893
910
  reset(): Promise<void>;
911
+ /** Open the Phials settings window directly to this plugin's settings page. */
912
+ open(): Promise<void>;
894
913
  onChange(
895
914
  handler: (change: PluginSettingsChange) => void,
896
915
  ): PluginSettingsSubscription;
@@ -1082,6 +1101,9 @@ interface EventsAPI {
1082
1101
  * Base Plugin API - available to all providers
1083
1102
  */
1084
1103
  interface PluginAPI {
1104
+ /** Open the Phials settings window directly to this plugin's settings page. */
1105
+ openSettings(): Promise<void>;
1106
+
1085
1107
  /** Plugin's own settings */
1086
1108
  settings: PluginSettings;
1087
1109
 
@@ -44,7 +44,7 @@ type PluginPathOutcome =
44
44
  readonly path: string;
45
45
  readonly status: "failed";
46
46
  readonly failure: PluginFileFailure;
47
- };
47
+ };
48
48
 
49
49
  interface PluginDirectoryReadResult {
50
50
  readonly entries: readonly FileEntry[];
@@ -61,7 +61,7 @@ type PluginBinaryWriteResult =
61
61
  | {
62
62
  readonly status: "conflict";
63
63
  readonly actualRevision: string | null;
64
- };
64
+ };
65
65
 
66
66
  interface FolderSummary {
67
67
  readonly path: string;
@@ -105,6 +105,7 @@ type WorkspaceFolderPropertyType =
105
105
  | "text"
106
106
  | "number"
107
107
  | "date"
108
+ | "calendar"
108
109
  | "boolean"
109
110
  | "select"
110
111
  | "multi-select"
@@ -117,6 +118,18 @@ type WorkspaceFolderPropertyType =
117
118
 
118
119
  type WorkspaceFolderPropertyValue = JsonValue;
119
120
 
121
+ type WorkspaceFolderCalendarValue =
122
+ | {
123
+ readonly kind: "date";
124
+ readonly start: string;
125
+ readonly end?: string;
126
+ }
127
+ | {
128
+ readonly kind: "datetime";
129
+ readonly start: string;
130
+ readonly end?: string;
131
+ };
132
+
120
133
  interface WorkspaceFolderPropertyOption {
121
134
  readonly id: string;
122
135
  readonly name: string;
@@ -159,9 +172,7 @@ interface WorkspaceFolderPropertyWrite {
159
172
 
160
173
  interface WorkspaceFoldersAPI {
161
174
  isWorkspaceFolder(path: string): Promise<boolean>;
162
- getSchema(
163
- workspaceFolderIdOrPath: string,
164
- ): Promise<WorkspaceFolderSchema>;
175
+ getSchema(workspaceFolderIdOrPath: string): Promise<WorkspaceFolderSchema>;
165
176
  getPropertyValue(
166
177
  file: WorkspaceFolderFileRef,
167
178
  propertyId: string,
@@ -176,9 +187,22 @@ interface WorkspaceFoldersAPI {
176
187
  values: readonly WorkspaceFolderPropertyWrite[],
177
188
  ): Promise<void>;
178
189
  getTags(file: WorkspaceFolderFileRef): Promise<readonly string[]>;
179
- setTags(file: WorkspaceFolderFileRef, tags: readonly string[]): Promise<void>;
190
+ setTags(
191
+ file: WorkspaceFolderFileRef,
192
+ tags: readonly string[],
193
+ ): Promise<void>;
180
194
  getRating(file: WorkspaceFolderFileRef): Promise<number | null>;
181
- setRating(file: WorkspaceFolderFileRef, rating: number | null): Promise<void>;
195
+ setRating(
196
+ file: WorkspaceFolderFileRef,
197
+ rating: number | null,
198
+ ): Promise<void>;
199
+ getCalendar(
200
+ file: WorkspaceFolderFileRef,
201
+ ): Promise<WorkspaceFolderCalendarValue | null>;
202
+ setCalendar(
203
+ file: WorkspaceFolderFileRef,
204
+ value: WorkspaceFolderCalendarValue | null,
205
+ ): Promise<void>;
182
206
  listKnown(): Promise<readonly KnownWorkspaceFolder[]>;
183
207
  openPage(
184
208
  file: WorkspaceFolderFileRef,
@@ -205,11 +229,7 @@ type PluginDatabaseValue = JsonPrimitive | Uint8Array;
205
229
  interface PluginDatabaseSchemaOperations {
206
230
  createTable(table: PluginTableDefinition): Promise<void>;
207
231
  addColumn(table: string, column: PluginColumnDefinition): Promise<void>;
208
- renameColumn(
209
- table: string,
210
- from: string,
211
- to: string,
212
- ): Promise<void>;
232
+ renameColumn(table: string, from: string, to: string): Promise<void>;
213
233
  dropColumn(table: string, column: string): Promise<void>;
214
234
  createIndex(table: string, index: PluginIndexDefinition): Promise<void>;
215
235
  dropIndex(table: string, index: string): Promise<void>;
@@ -271,7 +291,7 @@ interface DetailsViewColumnConfig {
271
291
 
272
292
  type PagePropertyVisibility = "always" | "not-empty" | "hidden";
273
293
 
274
- interface VialPageConfig {
294
+ interface WorkspacePageConfig {
275
295
  readonly propertyOrder?: readonly string[];
276
296
  readonly propertyVisibility?: Readonly<
277
297
  Record<string, PagePropertyVisibility>
@@ -280,7 +300,7 @@ interface VialPageConfig {
280
300
  readonly fullWidth?: boolean;
281
301
  }
282
302
 
283
- interface SavedVialView {
303
+ interface SavedWorkspaceView {
284
304
  readonly id: string;
285
305
  readonly name: string;
286
306
  readonly icon?: string;
@@ -290,38 +310,39 @@ interface SavedVialView {
290
310
  }
291
311
 
292
312
  type PropertyValue = WorkspaceFolderPropertyValue;
293
- type VialCellDeltaOperation = "set" | "clear" | "pending";
313
+ type WorkspaceCellDeltaOperation = "set" | "clear" | "pending";
294
314
 
295
- interface VialCellDelta {
296
- readonly vialId: string;
297
- readonly vialPath: string;
315
+ interface WorkspaceCellDelta {
316
+ readonly workspaceId: string;
317
+ readonly workspacePath: string;
298
318
  readonly fileId: string;
299
319
  readonly filePath: string;
300
320
  readonly propertyId: string;
301
- readonly operation: VialCellDeltaOperation;
321
+ readonly operation: WorkspaceCellDeltaOperation;
302
322
  readonly value: PropertyValue | null;
303
323
  readonly mutationVersion: number;
304
324
  }
305
325
 
306
- interface VialValueDeltaEvent {
326
+ interface WorkspaceValueDeltaEvent {
307
327
  readonly kind: "delta";
308
328
  readonly sourcePaneId: string;
309
- readonly cell: VialCellDelta;
310
- readonly dependentDeltas: readonly VialCellDelta[];
329
+ readonly cell: WorkspaceCellDelta;
330
+ readonly dependentDeltas: readonly WorkspaceCellDelta[];
311
331
  }
312
332
 
313
- interface VialValueRefetchEvent {
333
+ interface WorkspaceValueRefetchEvent {
314
334
  readonly kind: "refetch";
315
335
  readonly sourcePaneId: string;
316
- readonly vialId: string;
317
- readonly vialPath: string;
336
+ readonly workspaceId: string;
337
+ readonly workspacePath: string;
318
338
  readonly fileIds?: readonly string[];
319
339
  readonly filePaths?: readonly string[];
320
340
  readonly propertyIds?: readonly string[];
321
341
  readonly reason: "legacy" | "plugin" | "schema";
322
342
  }
323
343
 
324
- type VialValuesChangedEvent = VialValueDeltaEvent | VialValueRefetchEvent;
344
+ type WorkspaceValuesChangedEvent =
345
+ WorkspaceValueDeltaEvent | WorkspaceValueRefetchEvent;
325
346
 
326
347
  type DrivesChangedPayload = {
327
348
  readonly reason: "mounted" | "unmounted" | "changed" | "poll";