Contributions ABI (contrib)¶
Source:
Plugins/SDK/contrib.h— this page is generated from that header bydocs/scripts/gen-api-reference.py; edit the header, not this page.
contrib.h — Peach Commander plugin contributions, behavior ABI (SPEC-013).
The declarative side of a contribution (WHAT commands/views a plugin offers and
WHERE they appear: menus, context menus, keybindings, view containers) lives in
the plugin's Info.plist PCContributions. This header is ONLY the behavior ABI:
the host runs a declared command or builds a declared view by id. It is id-based
and supersedes PTX's index-based tool ABI (PtxGetToolCount/Info/Execute).
A single plugin of ANY type (pcx/pfx/plx/pdx) may also carry contributions — the layer is orthogonal to the file-op ABIs. Self-contained C11 on pc_common.h; all char* are UTF-8; version-checked via PcGetApiVersion.
Entry points & functions¶
PcCloseViewPcConfigurePcGetApiVersionPcInvokeToolPcMakeViewPcNotifyThemeChangedPcNotifyViewPcRunCommand
Callbacks & service members¶
cursorPathlocalCursorPathselectionCountselectionPathmoveToTrashdeletePermanentlyreloadActivePanelpresentInfogetContextinvokeCommandcryptregisterToolWindowopenPathopenPathInPanelpresentSidebarViewdismissSidebarViewautomationToolsJsonautomationContextJsonautomationInvokeautomationConfirmautomationFreegetFileCommentsetFileComment
Full header¶
// SPDX-License-Identifier: Apache-2.0
/*
* contrib.h — Peach Commander plugin contributions, behavior ABI (SPEC-013).
*
* The declarative side of a contribution (WHAT commands/views a plugin offers and
* WHERE they appear: menus, context menus, keybindings, view containers) lives in
* the plugin's Info.plist `PCContributions`. This header is ONLY the behavior ABI:
* the host runs a declared command or builds a declared view by id. It is id-based
* and supersedes PTX's index-based tool ABI (PtxGetToolCount/Info/Execute).
*
* A single plugin of ANY type (pcx/pfx/plx/pdx) may also carry contributions — the
* layer is orthogonal to the file-op ABIs. Self-contained C11 on pc_common.h; all
* char* are UTF-8; version-checked via PcGetApiVersion.
*/
#ifndef PC_CONTRIB_H
#define PC_CONTRIB_H
#include <stdint.h>
#include "pc_common.h"
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unified host-services table — the superset of the per-type service tables
* (PtxHostServices / PfxHostServices). `host` is an opaque token passed back to
* each callback. "get" callbacks fill a caller-allocated UTF-8 buffer and return
* 1 on success / 0 if unavailable.
*/
typedef struct PcHostServices {
void *host;
/* Cursor & selection. */
int (*cursorPath)(void *host, char *out, int maxlen); /* full path */
int (*localCursorPath)(void *host, char *out, int maxlen); /* local (VFS→temp) */
int (*selectionCount)(void *host);
int (*selectionPath)(void *host, int index, char *out, int maxlen);
/* Mutations (routed through the host's op engine). */
void (*moveToTrash)(void *host, const char *const *paths, int count);
void (*deletePermanently)(void *host, const char *const *paths, int count);
void (*reloadActivePanel)(void *host);
/* UI + composition. */
void (*presentInfo)(void *host, const char *title, const char *message);
/* Read a context value by key (same keys the declarative `when` sees), e.g.
"cursorPath", "selectionCount", "panelScheme". 1 on success.
Colour theme (F-338): "theme.id", "theme.isDark" ("1"/"0"), and colours as
"#RRGGBB" — or "#RRGGBBAA" when translucent. A semantic set a plugin view can
draw with directly: theme.background, theme.windowBackground, theme.text,
theme.secondaryText, theme.accent, theme.separator,
theme.selectionBackground, theme.selectionText, theme.markedText,
theme.controlBackground, theme.controlText. Every host panel colour is also
available raw as "theme.color.<name>" (the names a user theme file uses).
Read them when building a view and again on PcNotifyThemeChanged; fall back to
the system colours if a key is absent, which is what an older host returns. */
int (*getContext)(void *host, const char *key, char *out, int maxlen);
/* Trigger any host or plugin command by id (composition). */
void (*invokeCommand)(void *host, const char *commandId);
/* Keychain-backed credential store (mode is a PC_CRYPT_* value). */
int (*crypt)(void *host, int mode, const char *store, char *password, int maxlen);
/* Register a plugin WINDOW's own menu-bar menus so the host installs them
while that window is key (like the built-in tool windows). Call this once,
synchronously, while opening the window; `window` is an NSWindow pointer and
`editMenu` / `contentMenu` are NSMenu pointers (the plugin owns them and
keeps the window alive). The host removes them automatically when the window
closes - no teardown call is needed. `title` names the content menu (may be
NULL). */
void (*registerToolWindow)(void *host, void *window, void *editMenu,
void *contentMenu, const char *title);
void *parentWindow; /* NSWindow* to present sheets over (may be NULL) */
void *parentView; /* NSView* container for view commands (may be NULL) */
/* Resolve an internal link: navigate to a folder, or reveal/open a file, in
the active panel. Appended at the end so the struct stays ABI-compatible
with plugins built before this field existed. */
void (*openPath)(void *host, const char *path);
/* Open `path` in a SPECIFIC main panel (side: 0 = left, 1 = right). If `path`
is a file, the host navigates to its parent folder and selects it.
Appended at the end for ABI compatibility. */
void (*openPathInPanel)(void *host, int side, const char *path);
/* On-demand sidebar view. `presentSidebarView` mounts the plugin's view
`viewId` in the sidebar immediately, rooted at `rootPath`; the view reads
its root via getContext("sidebarViewRoot"). `dismissSidebarView` removes it
again. Both appended at the end for ABI compatibility. */
void (*presentSidebarView)(void *host, const char *viewId, const char *rootPath);
void (*dismissSidebarView)(void *host, const char *viewId);
/* Automation core — the host's file-manager tool engine (the same one that
drives the MCP server), so a plugin (e.g. the AI assistant) can run tools
under the host's permission policy. Each returns a host-allocated UTF-8
JSON string the caller MUST release with `automationFree` (NULL on error).
The host applies its configured autonomy policy: `automationInvoke` returns
an outcome envelope {"status":"ok","payloadB64":..} / {"status":
"needsConfirmation","plan":..,"token":..} / {"status":"refused","reason":..}
/ {"status":"failed","error":..}; a "needsConfirmation" is executed by
calling `automationConfirm` with its token. `automationToolsJson` returns the
tool catalogue (JSON array); `automationContextJson` the live UI context.
IMPORTANT: these BLOCK until the async host op completes, so they must be
called OFF the main thread. Appended at the end for ABI compatibility. */
char *(*automationToolsJson)(void *host);
char *(*automationContextJson)(void *host);
char *(*automationInvoke)(void *host, const char *toolName, const char *argumentsJson);
char *(*automationConfirm)(void *host, const char *token);
void (*automationFree)(void *host, char *str);
/* Per-file comments — the `descript.ion` entry the host shows in its Comment
column and edits with Ctrl+Z, mirrored into the macOS Finder comment for local
files. A plugin cannot reach these on its own: they live in a file the host
reads through the VFS, so they are available on network locations too, and the
Finder mirror is the host's business.
This exists so a note-taking plugin does not become a *second*, disconnected
place where a note about a file can live. `getFileComment` writes at most
`maxlen` bytes including the terminator and returns 1 on success (0 when there
is no comment or the path is unknown); `setFileComment` with NULL or an empty
string clears it. Both appended at the end for ABI compatibility. */
int (*getFileComment)(void *host, const char *path, char *out, int maxlen);
void (*setFileComment)(void *host, const char *path, const char *comment);
} PcHostServices;
/* ---- Behavior entry points --------------------------------------------- */
/* ABI handshake. */
int PcGetApiVersion(void);
/* Run the command declared with `commandId` (Info.plist PCContributions.commands).
The plugin performs its work (may open its own windows) via `services`. */
void PcRunCommand(const char *commandId, const PcHostServices *services);
/* Build the view declared with `viewId` for the named `containerId`
(e.g. "sidebar", "preview"). Returns an NSView* as void*, or NULL. The plugin
owns it until PcCloseView; `services` stays valid for the view's lifetime. */
void *PcMakeView(const char *viewId, const char *containerId, const PcHostServices *services);
/* Release a view previously returned by PcMakeView. */
void PcCloseView(void *view);
/* Show the plugin's configuration UI (parentWindow may host a sheet). */
void PcConfigure(void *parentWindow);
/* Execute a tool the plugin declared (Info.plist PCContributions.tools) by id, with
JSON arguments, returning a host-allocated UTF-8 result string (the host frees it).
Lets a plugin add tools to the assistant's catalogue; the host gates them by the
declared capability and routes calls here. May be NULL if the plugin has no tools. */
char *PcInvokeTool(const char *toolName, const char *argumentsJson, const PcHostServices *services);
/* Notify the plugin that the host's colour theme changed, so any window or view it
already opened can re-read the `theme.*` context keys (see getContext) and repaint.
Optional — a plugin that does not export it is simply not called, and a plugin that
does still works with an older host that never calls it. Called on the main thread.
Views built with PcMakeView also receive PcNotifyView(view, "theme", <themeId>);
this entry point exists for the plugin's OWN windows, which the host cannot address
by view pointer. */
void PcNotifyThemeChanged(void);
/* Notify a view previously returned by PcMakeView that a host context value
changed, e.g. key "cursorPath" or "dir" (both UTF-8). Lets an embedded view
(e.g. a sidebar panel) follow the active panel. Optional; called on the main
thread. */
void PcNotifyView(void *view, const char *key, const char *value);
#ifdef __cplusplus
}
#endif
#endif /* PC_CONTRIB_H */