# Public Host API
HaloForge plugins should be able to feel deeply integrated even when the host is treated as a black box.
This repository now exposes a documented host-facing layer across all three deliverables:
1. Rust crate: `haloforge-plugin-api`
2. Frontend SDK: `@haloforge/plugin-sdk`
3. Packaging / linting CLI: `@haloforge/plugin-pack`
## Goal
Plugin authors should depend on documented SDK APIs instead of:
- reading `window.__HF_HOST` directly
- polling private host stores
- hard-coding internal host IPC command names
## Manifest additions
Plugins can now declare:
```json
{
"compatibility": {
"min_app_version": "0.1.0",
"min_host_api_version": "0.1.0"
},
"host_capabilities": [
"navigation",
"app_state",
"file_intents",
"file_dialogs",
"aichat",
"theme_read",
"event_subscribe"
]
}
```
### Supported `host_capabilities`
- `navigation`
- `app_state`
- `file_intents`
- `file_dialogs`
- `aichat`
- `theme_read`
- `event_subscribe`
These declarations are meant to describe which stable host features the plugin expects through the public SDK layer.
## Rust crate
The Rust crate now exports:
- `HostCapability`
- `PUBLIC_HOST_API_VERSION`
The permission model also includes explicit host-facing permissions:
- `host_navigation`
- `host_app_state_read`
- `host_file_intents`
- `host_file_dialogs`
- `host_aichat_access`
- `host_theme_read`
- `host_event_subscribe`
This keeps host integration auditable instead of hidden inside private bridge calls.
## Frontend SDK
Use the public SDK hooks:
```tsx
import {
registerPlugin,
definePlugin,
useHostNavigation,
useHostFileIntent,
useHostAI,
useHostTheme,
pickHostFile,
} from "@haloforge/plugin-sdk";
function ExamplePanel() {
const { openSettingsTab } = useHostNavigation();
const { intent, consume } = useHostFileIntent();
const { models, selectedModelId, sendMessage, createSession, getStreamState } = useHostAI();
const { theme } = useHostTheme();
return null;
}
export default registerPlugin("dev.haloforge.example", definePlugin({
panel: ExamplePanel,
}));
```
### Public host hooks
- `useHostAppState()`
- `useHostNavigation()`
- `useHostFileIntent()`
- `useHostModels()`
- `useAvailableModels()`
- `useHostAI()`
- `useHostTheme()`
- `useHostEvent()`
- `pickHostFile()`
- `pickHostDirectory()`
- `saveHostFile()`
The SDK may still adapt to HaloForge's current bridge internally, but plugin code no longer needs to know how the host is wired underneath.
## `hf-pack` guidance
`hf-pack check` and `hf-pack pack` now warn when plugin source code appears to rely on:
- direct `__HF_HOST` access
- direct host IPC calls such as `aichat_send_message`
Those warnings are there to keep plugins aligned with the public SDK and improve long-term black-box compatibility.
They now also warn on direct `plugin_invoke` usage so plugin frontends are nudged toward `invokePlugin()` / `invokeOtherPlugin()` instead of hand-built wire names.