diff --git a/plugin-agent-inbox-config/README.md b/plugin-agent-inbox-config/README.md new file mode 100644 index 0000000..71e1bc2 --- /dev/null +++ b/plugin-agent-inbox-config/README.md @@ -0,0 +1,106 @@ +# @paperclipai/plugin-agent-inbox-config + +Plugin for configuring per-agent inbox-lite filter settings via UI. + +## What It Does + +This plugin provides a UI for configuring which issues appear in each agent's inbox via the `inbox-lite` endpoint. Instead of using query parameters or code changes, users can use a simple interface with toggles to control: + +- **Issue statuses** - Which issue statuses (todo, in_progress, blocked, etc.) should appear in the inbox +- **Project filter** - Optionally limit to issues from a specific project +- **Goal filter** - Optionally limit to issues linked to a specific goal +- **Search query** - Optional text search to filter issues by title, description, or comments +- **Include backlog** - Toggle to include/exclude backlog issues + +## UI Slots + +The plugin registers three UI slots: + +1. **Sidebar entry** (`agent-inbox-config-sidebar`) - Quick access to select an agent and navigate to their inbox config +2. **Page** (`agent-inbox-config-page`) - Overview page showing all agents with their current inbox configuration summaries +3. **Agent detail tab** (`agent-inbox-tab`) - Full configuration form on each agent's detail page + +## Configuration + +### Instance Config Schema + +The plugin supports the following instance-level configuration: + +```json +{ + "defaultStatuses": "todo,in_progress,blocked", + "includeBacklog": false, + "maxIssuesPerAgent": 50 +} +``` + +- `defaultStatuses`: Comma-separated list of statuses to use as default for new agents +- `includeBacklog`: Whether to include backlog issues by default +- `maxIssuesPerAgent`: Maximum number of issues returned per agent inbox (1-500) + +### Per-Agent Config Storage + +Each agent's inbox configuration is stored in two places: + +1. **Plugin state** - Under the key `agentInboxConfigs` scoped to `instance`. This allows the plugin to quickly read/write configs without querying the database. + +2. **Agent runtimeConfig** - The config is also persisted to the agent's `runtimeConfig.inboxConfig` field for durability and to be available even if the plugin is uninstalled. + +## Data Handlers + +The plugin registers the following data handlers for UI components: + +- `agents` - Lists all agents in a company +- `getAgentInboxConfig` - Gets the inbox config for a specific agent +- `listAgentInboxConfigs` - Lists all agent inbox configs + +## Action Handlers + +The plugin registers the following action handlers: + +- `setAgentInboxConfig` - Sets or updates an agent's inbox configuration +- `resetAgentInboxConfig` - Resets an agent's config to defaults + +## Events + +The plugin subscribes to: + +- `agent.created` - Automatically sets default inbox config for new agents + +## Capabilities Required + +```json +[ + "agents.read", + "projects.read", + "goals.read", + "issues.read", + "plugin.state.read", + "plugin.state.write", + "ui.sidebar.register", + "ui.page.register" +] +``` + +## Local Install (Dev) + +From the repo root, build the plugin and install it: + +```bash +pnpm --filter @paperclipai/plugin-agent-inbox-config build +pnpm paperclipai plugin install ./packages/plugins/plugin-agent-inbox-config +``` + +## Usage + +1. Navigate to an agent's detail page in Paperclip +2. Click the "Inbox Settings" tab +3. Configure the filters: + - Check/uncheck issue statuses + - Select a project filter (optional) + - Select a goal filter (optional) + - Enter a search query (optional) + - Toggle include backlog +4. Click "Save Configuration" + +The agent's inbox-lite endpoint will now return issues matching these filters. diff --git a/plugin-agent-inbox-config/dist/constants.d.ts b/plugin-agent-inbox-config/dist/constants.d.ts new file mode 100644 index 0000000..07b802b --- /dev/null +++ b/plugin-agent-inbox-config/dist/constants.d.ts @@ -0,0 +1,20 @@ +export declare const PLUGIN_ID = "paperclip.plugin-agent-inbox-config"; +export declare const PLUGIN_VERSION = "0.1.0"; +export declare const SIDEBAR_SLOT_ID = "agent-inbox-config-sidebar"; +export declare const PAGE_SLOT_ID = "agent-inbox-config-page"; +export declare const AGENT_TAB_SLOT_ID = "agent-inbox-tab"; +export declare const EXPORT_NAMES: { + readonly sidebar: "InboxConfigSidebar"; + readonly page: "InboxConfigPage"; + readonly agentTab: "AgentInboxSettingsTab"; +}; +export declare const DEFAULT_INBOX_CONFIG: { + statuses: string; + includeBacklog: boolean; + projectId: string | null; + goalId: string | null; + labelIds: string[]; + query: string | null; +}; +export type AgentInboxConfig = typeof DEFAULT_INBOX_CONFIG; +//# sourceMappingURL=constants.d.ts.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/constants.d.ts.map b/plugin-agent-inbox-config/dist/constants.d.ts.map new file mode 100644 index 0000000..20e58a9 --- /dev/null +++ b/plugin-agent-inbox-config/dist/constants.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,SAAS,wCAAwC,CAAC;AAC/D,eAAO,MAAM,cAAc,UAAU,CAAC;AAGtC,eAAO,MAAM,eAAe,+BAA+B,CAAC;AAC5D,eAAO,MAAM,YAAY,4BAA4B,CAAC;AACtD,eAAO,MAAM,iBAAiB,oBAAoB,CAAC;AAGnD,eAAO,MAAM,YAAY;;;;CAIf,CAAC;AAGX,eAAO,MAAM,oBAAoB;;;eAGZ,MAAM,GAAG,IAAI;YAChB,MAAM,GAAG,IAAI;cACb,MAAM,EAAE;WACT,MAAM,GAAG,IAAI;CAC7B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,OAAO,oBAAoB,CAAC"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/constants.js b/plugin-agent-inbox-config/dist/constants.js new file mode 100644 index 0000000..8364cac --- /dev/null +++ b/plugin-agent-inbox-config/dist/constants.js @@ -0,0 +1,22 @@ +export const PLUGIN_ID = "paperclip.plugin-agent-inbox-config"; +export const PLUGIN_VERSION = "0.1.0"; +// Slot IDs +export const SIDEBAR_SLOT_ID = "agent-inbox-config-sidebar"; +export const PAGE_SLOT_ID = "agent-inbox-config-page"; +export const AGENT_TAB_SLOT_ID = "agent-inbox-tab"; +// Export names +export const EXPORT_NAMES = { + sidebar: "InboxConfigSidebar", + page: "InboxConfigPage", + agentTab: "AgentInboxSettingsTab", +}; +// Default config +export const DEFAULT_INBOX_CONFIG = { + statuses: "todo,in_progress,blocked", + includeBacklog: false, + projectId: null, + goalId: null, + labelIds: [], + query: null, +}; +//# sourceMappingURL=constants.js.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/constants.js.map b/plugin-agent-inbox-config/dist/constants.js.map new file mode 100644 index 0000000..619ab3e --- /dev/null +++ b/plugin-agent-inbox-config/dist/constants.js.map @@ -0,0 +1 @@ +{"version":3,"file":"constants.js","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,SAAS,GAAG,qCAAqC,CAAC;AAC/D,MAAM,CAAC,MAAM,cAAc,GAAG,OAAO,CAAC;AAEtC,WAAW;AACX,MAAM,CAAC,MAAM,eAAe,GAAG,4BAA4B,CAAC;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAG,yBAAyB,CAAC;AACtD,MAAM,CAAC,MAAM,iBAAiB,GAAG,iBAAiB,CAAC;AAEnD,eAAe;AACf,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,oBAAoB;IAC7B,IAAI,EAAE,iBAAiB;IACvB,QAAQ,EAAE,uBAAuB;CACzB,CAAC;AAEX,iBAAiB;AACjB,MAAM,CAAC,MAAM,oBAAoB,GAAG;IAClC,QAAQ,EAAE,0BAA0B;IACpC,cAAc,EAAE,KAAK;IACrB,SAAS,EAAE,IAAqB;IAChC,MAAM,EAAE,IAAqB;IAC7B,QAAQ,EAAE,EAAc;IACxB,KAAK,EAAE,IAAqB;CAC7B,CAAC"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/index.d.ts b/plugin-agent-inbox-config/dist/index.d.ts new file mode 100644 index 0000000..c6741c2 --- /dev/null +++ b/plugin-agent-inbox-config/dist/index.d.ts @@ -0,0 +1,3 @@ +export { default as manifest } from "./manifest.js"; +export { default as worker } from "./worker.js"; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/index.d.ts.map b/plugin-agent-inbox-config/dist/index.d.ts.map new file mode 100644 index 0000000..4e82043 --- /dev/null +++ b/plugin-agent-inbox-config/dist/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/index.js b/plugin-agent-inbox-config/dist/index.js new file mode 100644 index 0000000..f8d8134 --- /dev/null +++ b/plugin-agent-inbox-config/dist/index.js @@ -0,0 +1,3 @@ +export { default as manifest } from "./manifest.js"; +export { default as worker } from "./worker.js"; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/index.js.map b/plugin-agent-inbox-config/dist/index.js.map new file mode 100644 index 0000000..a86f938 --- /dev/null +++ b/plugin-agent-inbox-config/dist/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,aAAa,CAAC"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/manifest.d.ts b/plugin-agent-inbox-config/dist/manifest.d.ts new file mode 100644 index 0000000..a927ec9 --- /dev/null +++ b/plugin-agent-inbox-config/dist/manifest.d.ts @@ -0,0 +1,8 @@ +import type { PaperclipPluginManifestV1 } from "@paperclipai/plugin-sdk"; +/** + * Plugin that provides per-agent inbox-lite configuration via UI toggles. + * Allows configuring which issues appear in each agent's inbox without code changes. + */ +declare const manifest: PaperclipPluginManifestV1; +export default manifest; +//# sourceMappingURL=manifest.d.ts.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/manifest.d.ts.map b/plugin-agent-inbox-config/dist/manifest.d.ts.map new file mode 100644 index 0000000..750215a --- /dev/null +++ b/plugin-agent-inbox-config/dist/manifest.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,yBAAyB,CAAC;AAKzE;;;GAGG;AACH,QAAA,MAAM,QAAQ,EAAE,yBAoEf,CAAC;AAEF,eAAe,QAAQ,CAAC"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/manifest.js b/plugin-agent-inbox-config/dist/manifest.js new file mode 100644 index 0000000..4c56254 --- /dev/null +++ b/plugin-agent-inbox-config/dist/manifest.js @@ -0,0 +1,77 @@ +const PLUGIN_ID = "paperclip.plugin-agent-inbox-config"; +const PLUGIN_VERSION = "0.1.0"; +/** + * Plugin that provides per-agent inbox-lite configuration via UI toggles. + * Allows configuring which issues appear in each agent's inbox without code changes. + */ +const manifest = { + id: PLUGIN_ID, + apiVersion: 1, + version: PLUGIN_VERSION, + displayName: "Agent Inbox Configuration", + description: "Configure per-agent inbox-lite filters via UI toggles. Control which issues appear in each agent's inbox based on status, project, goal, labels, and search queries.", + author: "Paperclip", + categories: ["ui", "automation"], + capabilities: [ + "agents.read", + "projects.read", + "goals.read", + "issues.read", + "plugin.state.read", + "plugin.state.write", + "http.outbound", + "ui.detailTab.register", + "ui.page.register", + ], + entrypoints: { + worker: "./dist/worker.js", + ui: "./dist/ui", + }, + instanceConfigSchema: { + type: "object", + title: "Agent Inbox Config Plugin Settings", + description: "Default inbox configuration settings for agents.", + properties: { + defaultStatuses: { + type: "string", + title: "Default Statuses", + description: "Default statuses to include in inbox (comma-separated). Override per-agent via agent settings.", + default: "todo,in_progress,blocked", + }, + includeBacklog: { + type: "boolean", + title: "Include Backlog by Default", + description: "Whether backlog issues are included by default.", + default: false, + }, + maxIssuesPerAgent: { + type: "integer", + title: "Max Issues Per Agent", + description: "Maximum number of issues to return per agent inbox.", + default: 50, + minimum: 1, + maximum: 500, + }, + }, + }, + ui: { + slots: [ + { + type: "page", + id: "agent-inbox-config-page", + displayName: "Agent Inbox Configuration", + exportName: "InboxConfigPage", + routePath: "inbox-config", + }, + { + type: "detailTab", + id: "agent-inbox-tab", + displayName: "Inbox Settings", + exportName: "AgentInboxSettingsTab", + entityTypes: ["agent"], + }, + ], + }, +}; +export default manifest; +//# sourceMappingURL=manifest.js.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/manifest.js.map b/plugin-agent-inbox-config/dist/manifest.js.map new file mode 100644 index 0000000..199b091 --- /dev/null +++ b/plugin-agent-inbox-config/dist/manifest.js.map @@ -0,0 +1 @@ +{"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"AAEA,MAAM,SAAS,GAAG,qCAAqC,CAAC;AACxD,MAAM,cAAc,GAAG,OAAO,CAAC;AAE/B;;;GAGG;AACH,MAAM,QAAQ,GAA8B;IAC1C,EAAE,EAAE,SAAS;IACb,UAAU,EAAE,CAAC;IACb,OAAO,EAAE,cAAc;IACvB,WAAW,EAAE,2BAA2B;IACxC,WAAW,EAAE,sKAAsK;IACnL,MAAM,EAAE,WAAW;IACnB,UAAU,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC;IAChC,YAAY,EAAE;QACZ,aAAa;QACb,eAAe;QACf,YAAY;QACZ,aAAa;QACb,mBAAmB;QACnB,oBAAoB;QACpB,eAAe;QACf,uBAAuB;QACvB,kBAAkB;KACnB;IACD,WAAW,EAAE;QACX,MAAM,EAAE,kBAAkB;QAC1B,EAAE,EAAE,WAAW;KAChB;IACD,oBAAoB,EAAE;QACpB,IAAI,EAAE,QAAQ;QACd,KAAK,EAAE,oCAAoC;QAC3C,WAAW,EAAE,kDAAkD;QAC/D,UAAU,EAAE;YACV,eAAe,EAAE;gBACf,IAAI,EAAE,QAAQ;gBACd,KAAK,EAAE,kBAAkB;gBACzB,WAAW,EAAE,gGAAgG;gBAC7G,OAAO,EAAE,0BAA0B;aACpC;YACD,cAAc,EAAE;gBACd,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,4BAA4B;gBACnC,WAAW,EAAE,iDAAiD;gBAC9D,OAAO,EAAE,KAAK;aACf;YACD,iBAAiB,EAAE;gBACjB,IAAI,EAAE,SAAS;gBACf,KAAK,EAAE,sBAAsB;gBAC7B,WAAW,EAAE,qDAAqD;gBAClE,OAAO,EAAE,EAAE;gBACX,OAAO,EAAE,CAAC;gBACV,OAAO,EAAE,GAAG;aACb;SACF;KACF;IACD,EAAE,EAAE;QACF,KAAK,EAAE;YACL;gBACE,IAAI,EAAE,MAAM;gBACZ,EAAE,EAAE,yBAAyB;gBAC7B,WAAW,EAAE,2BAA2B;gBACxC,UAAU,EAAE,iBAAiB;gBAC7B,SAAS,EAAE,cAAc;aAC1B;YACD;gBACE,IAAI,EAAE,WAAW;gBACjB,EAAE,EAAE,iBAAiB;gBACrB,WAAW,EAAE,gBAAgB;gBAC7B,UAAU,EAAE,uBAAuB;gBACnC,WAAW,EAAE,CAAC,OAAO,CAAC;aACvB;SACF;KACF;CACF,CAAC;AAEF,eAAe,QAAQ,CAAC"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/ui/index.d.ts b/plugin-agent-inbox-config/dist/ui/index.d.ts new file mode 100644 index 0000000..daabbc9 --- /dev/null +++ b/plugin-agent-inbox-config/dist/ui/index.d.ts @@ -0,0 +1,4 @@ +import { type PluginPageProps, type PluginDetailTabProps } from "@paperclipai/plugin-sdk/ui"; +export declare function InboxConfigPage({ context }: PluginPageProps): import("react/jsx-runtime").JSX.Element; +export declare function AgentInboxSettingsTab({ context }: PluginDetailTabProps): import("react/jsx-runtime").JSX.Element; +//# sourceMappingURL=index.d.ts.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/ui/index.d.ts.map b/plugin-agent-inbox-config/dist/ui/index.d.ts.map new file mode 100644 index 0000000..a07a9f6 --- /dev/null +++ b/plugin-agent-inbox-config/dist/ui/index.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAKL,KAAK,eAAe,EACpB,KAAK,oBAAoB,EAC1B,MAAM,4BAA4B,CAAC;AAuHpC,wBAAgB,eAAe,CAAC,EAAE,OAAO,EAAE,EAAE,eAAe,2CA+E3D;AA+CD,wBAAgB,qBAAqB,CAAC,EAAE,OAAO,EAAE,EAAE,oBAAoB,2CA4OtE"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/ui/index.js b/plugin-agent-inbox-config/dist/ui/index.js new file mode 100644 index 0000000..ce87381 --- /dev/null +++ b/plugin-agent-inbox-config/dist/ui/index.js @@ -0,0 +1,251 @@ +import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; +import { useState, useEffect } from "react"; +import { usePluginAction, usePluginData, usePluginToast, } from "@paperclipai/plugin-sdk/ui"; +import { DEFAULT_INBOX_CONFIG, PAGE_SLOT_ID, AGENT_TAB_SLOT_ID, } from "../constants.js"; +// ----------------------------------------------------------------------------- +// Styles +// ----------------------------------------------------------------------------- +const containerStyle = { + display: "grid", + gap: "16px", +}; +const cardStyle = { + border: "1px solid var(--border, #e5e7eb)", + borderRadius: "12px", + padding: "16px", + background: "var(--card, white)", +}; +const sectionHeaderStyle = { + display: "flex", + alignItems: "center", + justifyContent: "space-between", + marginBottom: "12px", +}; +const buttonStyle = { + appearance: "none", + border: "1px solid var(--border, #e5e7eb)", + borderRadius: "8px", + background: "transparent", + color: "inherit", + padding: "8px 14px", + fontSize: "13px", + cursor: "pointer", +}; +const primaryButtonStyle = { + ...buttonStyle, + background: "var(--foreground, #1f2937)", + color: "var(--background, white)", +}; +const inputStyle = { + width: "100%", + border: "1px solid var(--border, #e5e7eb)", + borderRadius: "8px", + padding: "10px 12px", + background: "transparent", + color: "inherit", + fontSize: "13px", +}; +const selectStyle = { + ...inputStyle, +}; +const checkboxStyle = { + width: "18px", + height: "18px", + accentColor: "var(--foreground, #1f2937)", +}; +const rowStyle = { + display: "flex", + alignItems: "center", + gap: "10px", + marginBottom: "12px", +}; +const mutedTextStyle = { + fontSize: "12px", + opacity: 0.7, + lineHeight: 1.5, +}; +// ----------------------------------------------------------------------------- +// Helper functions +// ----------------------------------------------------------------------------- +function getStatusOptions() { + return [ + { value: "todo", label: "Todo" }, + { value: "in_progress", label: "In Progress" }, + { value: "blocked", label: "Blocked" }, + { value: "backlog", label: "Backlog" }, + { value: "in_review", label: "In Review" }, + { value: "done", label: "Done" }, + { value: "cancelled", label: "Cancelled" }, + ]; +} +function getStatusLabel(value) { + const option = getStatusOptions().find((o) => o.value === value); + return option?.label || value; +} +// ----------------------------------------------------------------------------- +// Page Component - Shows all agents and their inbox configs +// ----------------------------------------------------------------------------- +export function InboxConfigPage({ context }) { + const [agents, setAgents] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + useEffect(() => { + async function loadAgents() { + if (!context.companyId) + return; + setLoading(true); + try { + const response = await fetch(`/api/companies/${context.companyId}/agents`, { + credentials: "include", + }); + if (!response.ok) + throw new Error(`Failed to load agents: ${response.status}`); + const data = await response.json(); + setAgents(Array.isArray(data) ? data : []); + setError(null); + } + catch (err) { + setError(err instanceof Error ? err.message : String(err)); + } + finally { + setLoading(false); + } + } + void loadAgents(); + }, [context.companyId]); + const agentPath = (agentId) => { + const prefix = context.companyPrefix || ""; + return `${prefix ? "/${prefix}" : "/"}/agents/${agentId}`; + }; + if (!context.companyId) { + return (_jsx("div", { style: { padding: "24px", fontSize: "14px", opacity: 0.7 }, children: "Select a company to configure agent inboxes." })); + } + if (loading) { + return _jsx("div", { style: { padding: "24px", fontSize: "14px" }, children: "Loading agents\u2026" }); + } + return (_jsxs("div", { style: { padding: "24px", maxWidth: "1000px", margin: "0 auto" }, children: [_jsx("h1", { style: { fontSize: "24px", fontWeight: 700, marginBottom: "8px" }, children: "Agent Inbox Configuration" }), _jsx("p", { style: { ...mutedTextStyle, marginBottom: "24px", fontSize: "14px" }, children: "Configure which issues appear in each agent's inbox via the inbox-lite endpoint." }), error ? (_jsx("div", { style: { ...cardStyle, color: "var(--destructive, #dc2626)" }, children: error })) : (_jsxs("div", { style: { display: "grid", gap: "16px" }, children: [agents.map((agent) => (_jsxs("div", { style: cardStyle, children: [_jsxs("div", { style: sectionHeaderStyle, children: [_jsx("strong", { style: { fontSize: "15px" }, children: agent.name }), _jsx("a", { href: `${agentPath(agent.id)}?tab=plugin:${PAGE_SLOT_ID}:${AGENT_TAB_SLOT_ID}`, style: { fontSize: "12px", textDecoration: "underline", cursor: "pointer" }, children: "Configure \u2192" })] }), _jsx("div", { style: { display: "grid", gap: "8px", fontSize: "13px" }, children: _jsx(AgentInboxSummary, { agentId: agent.id }) })] }, agent.id))), agents.length === 0 && (_jsx("div", { style: { ...cardStyle, padding: "24px", textAlign: "center", opacity: 0.7 }, children: "No agents found in this company." }))] }))] })); +} +// ----------------------------------------------------------------------------- +// Agent Inbox Summary Component (used in page view) +// ----------------------------------------------------------------------------- +function AgentInboxSummary({ agentId }) { + const config = usePluginData("getAgentInboxConfig", { agentId }); + if (config.loading) + return _jsx("div", { style: { fontSize: "12px", opacity: 0.6 }, children: "Loading\u2026" }); + if (config.error) + return _jsx("div", { style: { fontSize: "12px", color: "var(--destructive, #dc2626)" }, children: "Error loading config" }); + const c = config.data || DEFAULT_INBOX_CONFIG; + return (_jsxs("div", { style: { display: "grid", gap: "6px", fontSize: "12px" }, children: [_jsxs("div", { children: [_jsx("strong", { children: "Statuses:" }), " ", c.statuses] }), c.projectId ? (_jsxs("div", { children: [_jsx("strong", { children: "Project:" }), " Filtered"] })) : null, c.goalId ? (_jsxs("div", { children: [_jsx("strong", { children: "Goal:" }), " Filtered"] })) : null, c.labelIds && c.labelIds.length > 0 ? (_jsxs("div", { children: [_jsx("strong", { children: "Labels:" }), " ", c.labelIds.length, " filter(s)"] })) : null, c.query ? (_jsxs("div", { children: [_jsx("strong", { children: "Search:" }), " \"", c.query, "\""] })) : null] })); +} +// ----------------------------------------------------------------------------- +// Agent Detail Tab Component - Configure inbox for a specific agent +// ----------------------------------------------------------------------------- +export function AgentInboxSettingsTab({ context }) { + const { entityId, entityType } = context; + if (entityType !== "agent") { + return (_jsx("div", { style: { padding: "24px", fontSize: "13px", opacity: 0.7 }, children: "This tab is only available on agent detail pages." })); + } + const agentId = entityId; + const toast = usePluginToast(); + // Fetch current config + const configData = usePluginData("getAgentInboxConfig", { agentId }); + // Fetch projects for dropdown + const [projects, setProjects] = useState([]); + const [goals, setGoals] = useState([]); + const [loadingOptions, setLoadingOptions] = useState(true); + // Form state + const [formState, setFormState] = useState({ + ...DEFAULT_INBOX_CONFIG, + statuses: configData.data?.statuses || DEFAULT_INBOX_CONFIG.statuses, + includeBacklog: configData.data?.includeBacklog || DEFAULT_INBOX_CONFIG.includeBacklog, + projectId: configData.data?.projectId || null, + goalId: configData.data?.goalId || null, + labelIds: configData.data?.labelIds || [], + query: configData.data?.query || null, + }); + const [saving, setSaving] = useState(false); + // Load projects and goals + useEffect(() => { + async function loadOptions() { + if (!context.companyId) + return; + setLoadingOptions(true); + try { + const [projectsRes, goalsRes] = await Promise.all([ + fetch(`/api/companies/${context.companyId}/projects`, { credentials: "include" }), + fetch(`/api/companies/${context.companyId}/goals`, { credentials: "include" }), + ]); + if (projectsRes.ok) { + const data = await projectsRes.json(); + setProjects(Array.isArray(data) ? data : []); + } + if (goalsRes.ok) { + const data = await goalsRes.json(); + setGoals(Array.isArray(data) ? data : []); + } + } + catch (err) { + console.error("Failed to load options:", err); + } + finally { + setLoadingOptions(false); + } + } + void loadOptions(); + }, [context.companyId]); + // Update form when config data loads + useEffect(() => { + if (configData.data) { + setFormState({ ...DEFAULT_INBOX_CONFIG, ...configData.data }); + } + }, [configData.data]); + const saveConfig = usePluginAction("setAgentInboxConfig"); + async function handleSave(e) { + e.preventDefault(); + if (!agentId) + return; + setSaving(true); + try { + await saveConfig({ + agentId, + config: { + statuses: formState.statuses, + includeBacklog: formState.includeBacklog, + projectId: formState.projectId, + goalId: formState.goalId, + labelIds: formState.labelIds, + query: formState.query, + }, + }); + toast({ + title: "Inbox config saved", + body: `Configuration updated for this agent.`, + tone: "success", + }); + } + catch (err) { + const message = err instanceof Error ? err.message : String(err); + toast({ + title: "Failed to save config", + body: message, + tone: "error", + }); + } + finally { + setSaving(false); + } + } + const statusOptions = getStatusOptions(); + const selectedStatuses = formState.statuses.split(","); + return (_jsxs("div", { style: { padding: "20px", maxWidth: "700px" }, children: [_jsx("h2", { style: { fontSize: "18px", fontWeight: 600, marginBottom: "8px" }, children: "Inbox Configuration" }), _jsx("p", { style: { ...mutedTextStyle, marginBottom: "20px", fontSize: "13px" }, children: "Configure which issues appear in this agent's inbox via the inbox-lite endpoint." }), _jsxs("form", { onSubmit: handleSave, style: { display: "grid", gap: "20px" }, children: [_jsxs("div", { style: cardStyle, children: [_jsx("div", { style: { fontWeight: 600, marginBottom: "12px", fontSize: "14px" }, children: "Issue Statuses" }), _jsx("p", { style: { ...mutedTextStyle, marginBottom: "12px", fontSize: "12px" }, children: "Select which issue statuses should appear in this agent's inbox." }), _jsx("div", { style: { display: "grid", gap: "8px" }, children: statusOptions.map((option) => (_jsxs("label", { style: { display: "flex", alignItems: "center", gap: "10px", fontSize: "13px" }, children: [_jsx("input", { type: "checkbox", checked: selectedStatuses.includes(option.value), onChange: (e) => { + const isChecked = e.target.checked; + const current = formState.statuses.split(","); + const next = isChecked + ? [...current, option.value].filter(Boolean) + : current.filter((s) => s !== option.value); + setFormState({ ...formState, statuses: next.join(",") }); + }, style: checkboxStyle }), _jsx("span", { children: option.label })] }, option.value))) })] }), _jsxs("div", { style: cardStyle, children: [_jsx("div", { style: { fontWeight: 600, marginBottom: "12px", fontSize: "14px" }, children: "Project Filter" }), _jsx("p", { style: { ...mutedTextStyle, marginBottom: "12px", fontSize: "12px" }, children: "Optionally limit inbox to issues from a specific project." }), _jsxs("select", { style: selectStyle, value: formState.projectId || "", onChange: (e) => setFormState({ ...formState, projectId: e.target.value || null }), disabled: loadingOptions, children: [_jsx("option", { value: "", children: "No filter (all projects)" }), projects.map((project) => (_jsx("option", { value: project.id, children: project.name }, project.id)))] })] }), _jsxs("div", { style: cardStyle, children: [_jsx("div", { style: { fontWeight: 600, marginBottom: "12px", fontSize: "14px" }, children: "Goal Filter" }), _jsx("p", { style: { ...mutedTextStyle, marginBottom: "12px", fontSize: "12px" }, children: "Optionally limit inbox to issues linked to a specific goal." }), _jsxs("select", { style: selectStyle, value: formState.goalId || "", onChange: (e) => setFormState({ ...formState, goalId: e.target.value || null }), disabled: loadingOptions, children: [_jsx("option", { value: "", children: "No filter (all goals)" }), goals.map((goal) => (_jsx("option", { value: goal.id, children: goal.title }, goal.id)))] })] }), _jsxs("div", { style: cardStyle, children: [_jsx("div", { style: { fontWeight: 600, marginBottom: "12px", fontSize: "14px" }, children: "Search Query" }), _jsx("p", { style: { ...mutedTextStyle, marginBottom: "12px", fontSize: "12px" }, children: "Optional search query to filter issues by title, description, or comments." }), _jsx("input", { type: "text", style: inputStyle, value: formState.query || "", onChange: (e) => setFormState({ ...formState, query: e.target.value || null }), placeholder: "e.g., docker, deployment, urgent" })] }), _jsxs("div", { style: cardStyle, children: [_jsxs("label", { style: { display: "flex", alignItems: "center", gap: "10px" }, children: [_jsx("input", { type: "checkbox", checked: formState.includeBacklog, onChange: (e) => setFormState({ ...formState, includeBacklog: e.target.checked }), style: checkboxStyle }), _jsx("span", { style: { fontSize: "13px" }, children: "Include backlog issues" })] }), _jsx("p", { style: { ...mutedTextStyle, marginTop: "6px", fontSize: "12px" }, children: "When enabled, issues with status \"backlog\" will be included in the inbox." })] }), _jsxs("div", { style: { display: "flex", gap: "10px", justifyContent: "flex-end" }, children: [_jsx("button", { type: "button", style: buttonStyle, onClick: () => { + setFormState({ ...DEFAULT_INBOX_CONFIG }); + }, children: "Reset to Defaults" }), _jsx("button", { type: "submit", style: primaryButtonStyle, disabled: saving || configData.loading || loadingOptions, children: saving ? "Saving…" : "Save Configuration" })] })] })] })); +} +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/ui/index.js.map b/plugin-agent-inbox-config/dist/ui/index.js.map new file mode 100644 index 0000000..e4e4910 --- /dev/null +++ b/plugin-agent-inbox-config/dist/ui/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/ui/index.tsx"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/worker.d.ts b/plugin-agent-inbox-config/dist/worker.d.ts new file mode 100644 index 0000000..29d035d --- /dev/null +++ b/plugin-agent-inbox-config/dist/worker.d.ts @@ -0,0 +1,4 @@ +import { type PaperclipPlugin } from "@paperclipai/plugin-sdk"; +declare const plugin: PaperclipPlugin; +export default plugin; +//# sourceMappingURL=worker.d.ts.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/worker.d.ts.map b/plugin-agent-inbox-config/dist/worker.d.ts.map new file mode 100644 index 0000000..cc1ddd5 --- /dev/null +++ b/plugin-agent-inbox-config/dist/worker.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"worker.d.ts","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAUxF,QAAA,MAAM,MAAM,EAAE,eAqLZ,CAAC;AAEH,eAAe,MAAM,CAAC"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/worker.js b/plugin-agent-inbox-config/dist/worker.js new file mode 100644 index 0000000..2f032f7 --- /dev/null +++ b/plugin-agent-inbox-config/dist/worker.js @@ -0,0 +1,165 @@ +import { definePlugin, runWorker } from "@paperclipai/plugin-sdk"; +import { DEFAULT_INBOX_CONFIG, PLUGIN_ID, PLUGIN_VERSION, } from "./constants.js"; +const WORKER_KEY = "agent-inbox-config-worker"; +const plugin = definePlugin({ + async setup(ctx) { + ctx.logger.info(`${PLUGIN_ID} v${PLUGIN_VERSION} starting...`); + // Initialize plugin state with default inbox configs per agent + const existingState = await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" }); + if (!existingState) { + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, {}); + } + const versionState = await ctx.state.get({ scopeKind: "instance", stateKey: "version" }); + if (!versionState) { + await ctx.state.set({ scopeKind: "instance", stateKey: "version" }, PLUGIN_VERSION); + } + // Register data handlers for UI to fetch data + ctx.data.register("agents", async (params) => { + const companyId = typeof params?.companyId === "string" ? params.companyId : ""; + if (!companyId) + return []; + return await ctx.agents.list({ companyId, limit: 100, offset: 0 }); + }); + ctx.data.register("getAgentInboxConfig", async (params) => { + const agentId = typeof params?.agentId === "string" ? params.agentId : ""; + if (!agentId) + return null; + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + return configs[agentId] || null; + }); + ctx.data.register("listAgentInboxConfigs", async () => { + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + return Object.entries(configs).map(([agentId, config]) => ({ agentId, config })); + }); + // Register action handlers for UI to perform actions + ctx.actions.register("setAgentInboxConfig", async (params) => { + const agentId = typeof params?.agentId === "string" ? params.agentId : ""; + const config = params?.config; + if (!agentId) { + throw new Error("agentId is required"); + } + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + // Merge with defaults + const mergedConfig = { + ...DEFAULT_INBOX_CONFIG, + statuses: config?.statuses || DEFAULT_INBOX_CONFIG.statuses, + includeBacklog: config?.includeBacklog ?? DEFAULT_INBOX_CONFIG.includeBacklog, + projectId: config?.projectId ?? null, + goalId: config?.goalId ?? null, + labelIds: config?.labelIds || [], + query: config?.query ?? null, + }; + configs[agentId] = mergedConfig; + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, configs); + // Also persist to agent's runtimeConfig for durability and server-side access + try { + const agentResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + }); + if (agentResponse.ok) { + const agentData = await agentResponse.json(); + const currentRuntimeConfig = agentData.runtimeConfig || {}; + const agentUpdateResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + runtimeConfig: { + ...currentRuntimeConfig, + inboxConfig: mergedConfig, + }, + }), + }); + if (!agentUpdateResponse.ok) { + ctx.logger.warn("Failed to update agent runtimeConfig with inbox config", { agentId, status: agentUpdateResponse.status }); + } + } + } + catch (err) { + ctx.logger.warn("Failed to persist inbox config to agent runtimeConfig", { agentId, error: err }); + } + ctx.logger.info("Inbox config updated for agent", { agentId }); + return { success: true, agentId, config: mergedConfig }; + }); + ctx.actions.register("resetAgentInboxConfig", async (params) => { + const agentId = typeof params?.agentId === "string" ? params.agentId : ""; + if (!agentId) { + throw new Error("agentId is required"); + } + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + delete configs[agentId]; + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, configs); + // Also clear inboxConfig from agent's runtimeConfig + try { + const agentResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + }); + if (agentResponse.ok) { + const agentData = await agentResponse.json(); + const currentRuntimeConfig = agentData.runtimeConfig || {}; + // Remove inboxConfig from runtimeConfig + const updatedRuntimeConfig = { ...currentRuntimeConfig }; + delete updatedRuntimeConfig.inboxConfig; + const agentUpdateResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + runtimeConfig: updatedRuntimeConfig, + }), + }); + if (!agentUpdateResponse.ok) { + ctx.logger.warn("Failed to clear agent runtimeConfig inbox config", { agentId, status: agentUpdateResponse.status }); + } + } + } + catch (err) { + ctx.logger.warn("Failed to clear inbox config from agent runtimeConfig", { agentId, error: err }); + } + ctx.logger.info("Inbox config reset for agent", { agentId }); + return { success: true, agentId }; + }); + // Event handler for agent creation - set default inbox config + ctx.events.on("agent.created", async (event) => { + const agentId = event.entityId || ""; + if (!agentId) + return; + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + // Set default config for new agent in plugin state + configs[agentId] = { + ...DEFAULT_INBOX_CONFIG, + }; + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, configs); + // Also set default inboxConfig in agent's runtimeConfig + try { + const agentResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + runtimeConfig: { + inboxConfig: { ...DEFAULT_INBOX_CONFIG }, + }, + }), + }); + if (!agentResponse.ok) { + ctx.logger.warn("Failed to set default inbox config on new agent", { agentId, status: agentResponse.status }); + } + } + catch (err) { + ctx.logger.warn("Failed to set default inbox config on new agent runtimeConfig", { agentId, error: err }); + } + ctx.logger.info("Default inbox config set for new agent", { agentId }); + }); + ctx.logger.info(`${PLUGIN_ID} initialized successfully`); + }, + async onHealth() { + return { + status: "ok", + message: "Agent Inbox Config plugin ready", + details: {}, + }; + }, +}); +export default plugin; +runWorker(plugin, import.meta.url); +//# sourceMappingURL=worker.js.map \ No newline at end of file diff --git a/plugin-agent-inbox-config/dist/worker.js.map b/plugin-agent-inbox-config/dist/worker.js.map new file mode 100644 index 0000000..853fe1a --- /dev/null +++ b/plugin-agent-inbox-config/dist/worker.js.map @@ -0,0 +1 @@ +{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/plugin-agent-inbox-config/node_modules/.bin/paperclip-plugin-dev-server b/plugin-agent-inbox-config/node_modules/.bin/paperclip-plugin-dev-server new file mode 100755 index 0000000..9565bb4 --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/.bin/paperclip-plugin-dev-server @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/mike/code/paperclip/packages/plugins/sdk/dist/node_modules:/home/mike/code/paperclip/packages/plugins/sdk/node_modules:/home/mike/code/paperclip/packages/plugins/node_modules:/home/mike/code/paperclip/packages/node_modules:/home/mike/code/paperclip/node_modules:/home/mike/code/node_modules:/home/mike/node_modules:/home/node_modules:/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/mike/code/paperclip/packages/plugins/sdk/dist/node_modules:/home/mike/code/paperclip/packages/plugins/sdk/node_modules:/home/mike/code/paperclip/packages/plugins/node_modules:/home/mike/code/paperclip/packages/node_modules:/home/mike/code/paperclip/node_modules:/home/mike/code/node_modules:/home/mike/node_modules:/home/node_modules:/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../@paperclipai/plugin-sdk/dist/dev-cli.js" "$@" +else + exec node "$basedir/../@paperclipai/plugin-sdk/dist/dev-cli.js" "$@" +fi diff --git a/plugin-agent-inbox-config/node_modules/.bin/tsc b/plugin-agent-inbox-config/node_modules/.bin/tsc new file mode 100755 index 0000000..8eccfff --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/.bin/tsc @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@" +else + exec node "$basedir/../typescript/bin/tsc" "$@" +fi diff --git a/plugin-agent-inbox-config/node_modules/.bin/tsserver b/plugin-agent-inbox-config/node_modules/.bin/tsserver new file mode 100755 index 0000000..6a96c7a --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/.bin/tsserver @@ -0,0 +1,17 @@ +#!/bin/sh +basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')") + +case `uname` in + *CYGWIN*) basedir=`cygpath -w "$basedir"`;; +esac + +if [ -z "$NODE_PATH" ]; then + export NODE_PATH="/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/node_modules" +else + export NODE_PATH="/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/bin/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules/typescript/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/typescript@5.9.3/node_modules:/home/mike/code/paperclip/node_modules/.pnpm/node_modules:$NODE_PATH" +fi +if [ -x "$basedir/node" ]; then + exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@" +else + exec node "$basedir/../typescript/bin/tsserver" "$@" +fi diff --git a/plugin-agent-inbox-config/node_modules/@paperclipai/plugin-sdk b/plugin-agent-inbox-config/node_modules/@paperclipai/plugin-sdk new file mode 120000 index 0000000..7a5d3de --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/@paperclipai/plugin-sdk @@ -0,0 +1 @@ +../../../sdk \ No newline at end of file diff --git a/plugin-agent-inbox-config/node_modules/@types/node b/plugin-agent-inbox-config/node_modules/@types/node new file mode 120000 index 0000000..af20f97 --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/@types/node @@ -0,0 +1 @@ +../../../../../node_modules/.pnpm/@types+node@24.12.0/node_modules/@types/node \ No newline at end of file diff --git a/plugin-agent-inbox-config/node_modules/@types/react b/plugin-agent-inbox-config/node_modules/@types/react new file mode 120000 index 0000000..e15f894 --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/@types/react @@ -0,0 +1 @@ +../../../../../node_modules/.pnpm/@types+react@19.2.14/node_modules/@types/react \ No newline at end of file diff --git a/plugin-agent-inbox-config/node_modules/@types/react-dom b/plugin-agent-inbox-config/node_modules/@types/react-dom new file mode 120000 index 0000000..2ea8be6 --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/@types/react-dom @@ -0,0 +1 @@ +../../../../../node_modules/.pnpm/@types+react-dom@19.2.3_@types+react@19.2.14/node_modules/@types/react-dom \ No newline at end of file diff --git a/plugin-agent-inbox-config/node_modules/react b/plugin-agent-inbox-config/node_modules/react new file mode 120000 index 0000000..50ba5f0 --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/react @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/react@19.2.4/node_modules/react \ No newline at end of file diff --git a/plugin-agent-inbox-config/node_modules/react-dom b/plugin-agent-inbox-config/node_modules/react-dom new file mode 120000 index 0000000..8f24a6e --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/react-dom @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/react-dom@19.2.4_react@19.2.4/node_modules/react-dom \ No newline at end of file diff --git a/plugin-agent-inbox-config/node_modules/typescript b/plugin-agent-inbox-config/node_modules/typescript new file mode 120000 index 0000000..8ca86b1 --- /dev/null +++ b/plugin-agent-inbox-config/node_modules/typescript @@ -0,0 +1 @@ +../../../../node_modules/.pnpm/typescript@5.9.3/node_modules/typescript \ No newline at end of file diff --git a/plugin-agent-inbox-config/package.json b/plugin-agent-inbox-config/package.json new file mode 100644 index 0000000..b4eaf78 --- /dev/null +++ b/plugin-agent-inbox-config/package.json @@ -0,0 +1,36 @@ +{ + "name": "@paperclipai/plugin-agent-inbox-config", + "version": "0.1.0", + "description": "Plugin for configuring per-agent inbox-lite filter settings via UI", + "type": "module", + "type": "module", + "private": true, + "exports": { + ".": "./src/index.ts" + }, + "paperclipPlugin": { + "manifest": "./dist/manifest.js", + "worker": "./dist/worker.js", + "ui": "./dist/ui/" + }, + "scripts": { + "prebuild": "node ../../../scripts/ensure-plugin-build-deps.mjs", + "build": "tsc", + "clean": "rm -rf dist", + "typecheck": "pnpm --filter @paperclipai/plugin-sdk build && tsc --noEmit" + }, + "dependencies": { + "@paperclipai/plugin-sdk": "workspace:*" + }, + "devDependencies": { + "@types/node": "^24.6.0", + "@types/react": "^19.0.8", + "@types/react-dom": "^19.0.3", + "react": "^19.0.0", + "react-dom": "^19.0.0", + "typescript": "^5.7.3" + }, + "peerDependencies": { + "react": ">=18" + } +} diff --git a/plugin-agent-inbox-config/src/constants.ts b/plugin-agent-inbox-config/src/constants.ts new file mode 100644 index 0000000..9fc7406 --- /dev/null +++ b/plugin-agent-inbox-config/src/constants.ts @@ -0,0 +1,26 @@ +export const PLUGIN_ID = "paperclip.plugin-agent-inbox-config"; +export const PLUGIN_VERSION = "0.1.0"; + +// Slot IDs +export const SIDEBAR_SLOT_ID = "agent-inbox-config-sidebar"; +export const PAGE_SLOT_ID = "agent-inbox-config-page"; +export const AGENT_TAB_SLOT_ID = "agent-inbox-tab"; + +// Export names +export const EXPORT_NAMES = { + sidebar: "InboxConfigSidebar", + page: "InboxConfigPage", + agentTab: "AgentInboxSettingsTab", +} as const; + +// Default config +export const DEFAULT_INBOX_CONFIG = { + statuses: "todo,in_progress,blocked", + includeBacklog: false, + projectId: null as string | null, + goalId: null as string | null, + labelIds: [] as string[], + query: null as string | null, +}; + +export type AgentInboxConfig = typeof DEFAULT_INBOX_CONFIG; diff --git a/plugin-agent-inbox-config/src/index.ts b/plugin-agent-inbox-config/src/index.ts new file mode 100644 index 0000000..f301da5 --- /dev/null +++ b/plugin-agent-inbox-config/src/index.ts @@ -0,0 +1,2 @@ +export { default as manifest } from "./manifest.js"; +export { default as worker } from "./worker.js"; diff --git a/plugin-agent-inbox-config/src/manifest.ts b/plugin-agent-inbox-config/src/manifest.ts new file mode 100644 index 0000000..ab175ec --- /dev/null +++ b/plugin-agent-inbox-config/src/manifest.ts @@ -0,0 +1,80 @@ +import type { PaperclipPluginManifestV1 } from "@paperclipai/plugin-sdk"; + +const PLUGIN_ID = "paperclip.plugin-agent-inbox-config"; +const PLUGIN_VERSION = "0.1.0"; + +/** + * Plugin that provides per-agent inbox-lite configuration via UI toggles. + * Allows configuring which issues appear in each agent's inbox without code changes. + */ +const manifest: PaperclipPluginManifestV1 = { + id: PLUGIN_ID, + apiVersion: 1, + version: PLUGIN_VERSION, + displayName: "Agent Inbox Configuration", + description: "Configure per-agent inbox-lite filters via UI toggles. Control which issues appear in each agent's inbox based on status, project, goal, labels, and search queries.", + author: "Paperclip", + categories: ["ui", "automation"], + capabilities: [ + "agents.read", + "projects.read", + "goals.read", + "issues.read", + "plugin.state.read", + "plugin.state.write", + "http.outbound", + "ui.detailTab.register", + "ui.page.register", + ], + entrypoints: { + worker: "./dist/worker.js", + ui: "./dist/ui", + }, + instanceConfigSchema: { + type: "object", + title: "Agent Inbox Config Plugin Settings", + description: "Default inbox configuration settings for agents.", + properties: { + defaultStatuses: { + type: "string", + title: "Default Statuses", + description: "Default statuses to include in inbox (comma-separated). Override per-agent via agent settings.", + default: "todo,in_progress,blocked", + }, + includeBacklog: { + type: "boolean", + title: "Include Backlog by Default", + description: "Whether backlog issues are included by default.", + default: false, + }, + maxIssuesPerAgent: { + type: "integer", + title: "Max Issues Per Agent", + description: "Maximum number of issues to return per agent inbox.", + default: 50, + minimum: 1, + maximum: 500, + }, + }, + }, + ui: { + slots: [ + { + type: "page", + id: "agent-inbox-config-page", + displayName: "Agent Inbox Configuration", + exportName: "InboxConfigPage", + routePath: "inbox-config", + }, + { + type: "detailTab", + id: "agent-inbox-tab", + displayName: "Inbox Settings", + exportName: "AgentInboxSettingsTab", + entityTypes: ["agent"], + }, + ], + }, +}; + +export default manifest; diff --git a/plugin-agent-inbox-config/src/ui/index.tsx b/plugin-agent-inbox-config/src/ui/index.tsx new file mode 100644 index 0000000..004b101 --- /dev/null +++ b/plugin-agent-inbox-config/src/ui/index.tsx @@ -0,0 +1,490 @@ +import { useState, useEffect, type FormEvent } from "react"; +import { + useHostContext, + usePluginAction, + usePluginData, + usePluginToast, + type PluginPageProps, + type PluginDetailTabProps, +} from "@paperclipai/plugin-sdk/ui"; + +import { + DEFAULT_INBOX_CONFIG, + EXPORT_NAMES, + PAGE_SLOT_ID, + AGENT_TAB_SLOT_ID, + type AgentInboxConfig, +} from "../constants.js"; + +// ----------------------------------------------------------------------------- +// Types +// ----------------------------------------------------------------------------- + +type AgentRecord = { + id: string; + name: string; + status: string; + urlKey?: string; +}; + +// ----------------------------------------------------------------------------- +// Styles +// ----------------------------------------------------------------------------- + +const containerStyle: React.CSSProperties = { + display: "grid", + gap: "16px", +}; + +const cardStyle: React.CSSProperties = { + border: "1px solid var(--border, #e5e7eb)", + borderRadius: "12px", + padding: "16px", + background: "var(--card, white)", +}; + +const sectionHeaderStyle: React.CSSProperties = { + display: "flex", + alignItems: "center", + justifyContent: "space-between", + marginBottom: "12px", +}; + +const buttonStyle: React.CSSProperties = { + appearance: "none", + border: "1px solid var(--border, #e5e7eb)", + borderRadius: "8px", + background: "transparent", + color: "inherit", + padding: "8px 14px", + fontSize: "13px", + cursor: "pointer", +}; + +const primaryButtonStyle: React.CSSProperties = { + ...buttonStyle, + background: "var(--foreground, #1f2937)", + color: "var(--background, white)", +}; + +const inputStyle: React.CSSProperties = { + width: "100%", + border: "1px solid var(--border, #e5e7eb)", + borderRadius: "8px", + padding: "10px 12px", + background: "transparent", + color: "inherit", + fontSize: "13px", +}; + +const selectStyle: React.CSSProperties = { + ...inputStyle, +}; + +const checkboxStyle: React.CSSProperties = { + width: "18px", + height: "18px", + accentColor: "var(--foreground, #1f2937)", +}; + +const rowStyle: React.CSSProperties = { + display: "flex", + alignItems: "center", + gap: "10px", + marginBottom: "12px", +}; + +const mutedTextStyle: React.CSSProperties = { + fontSize: "12px", + opacity: 0.7, + lineHeight: 1.5, +}; + +// ----------------------------------------------------------------------------- +// Helper functions +// ----------------------------------------------------------------------------- + +function getStatusOptions(): Array<{ value: string; label: string }> { + return [ + { value: "todo", label: "Todo" }, + { value: "in_progress", label: "In Progress" }, + { value: "blocked", label: "Blocked" }, + { value: "backlog", label: "Backlog" }, + { value: "in_review", label: "In Review" }, + { value: "done", label: "Done" }, + { value: "cancelled", label: "Cancelled" }, + ]; +} + +function getStatusLabel(value: string): string { + const option = getStatusOptions().find((o) => o.value === value); + return option?.label || value; +} + +// ----------------------------------------------------------------------------- +// Page Component - Shows all agents and their inbox configs +// ----------------------------------------------------------------------------- + +export function InboxConfigPage({ context }: PluginPageProps) { + const [agents, setAgents] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + async function loadAgents() { + if (!context.companyId) return; + setLoading(true); + try { + const response = await fetch(`/api/companies/${context.companyId}/agents`, { + credentials: "include", + }); + if (!response.ok) throw new Error(`Failed to load agents: ${response.status}`); + const data = await response.json(); + setAgents(Array.isArray(data) ? data : []); + setError(null); + } catch (err) { + setError(err instanceof Error ? err.message : String(err)); + } finally { + setLoading(false); + } + } + void loadAgents(); + }, [context.companyId]); + + const agentPath = (agentId: string) => { + const prefix = context.companyPrefix || ""; + return `${prefix ? "/${prefix}" : "/"}/agents/${agentId}`; + }; + + if (!context.companyId) { + return ( +
+ Select a company to configure agent inboxes. +
+ ); + } + + if (loading) { + return
Loading agents…
; + } + + return ( +
+

Agent Inbox Configuration

+

+ Configure which issues appear in each agent's inbox via the inbox-lite endpoint. +

+ + {error ? ( +
{error}
+ ) : ( +
+ {agents.map((agent) => ( +
+
+ {agent.name} + + Configure → + +
+
+ +
+
+ ))} + {agents.length === 0 && ( +
+ No agents found in this company. +
+ )} +
+ )} +
+ ); +} + +// ----------------------------------------------------------------------------- +// Agent Inbox Summary Component (used in page view) +// ----------------------------------------------------------------------------- + +function AgentInboxSummary({ agentId }: { agentId: string }) { + const config = usePluginData("getAgentInboxConfig", { agentId }); + + if (config.loading) return
Loading…
; + if (config.error) return
Error loading config
; + + const c = config.data || DEFAULT_INBOX_CONFIG; + + return ( +
+
+ Statuses: {c.statuses} +
+ {c.projectId ? ( +
+ Project: Filtered +
+ ) : null} + {c.goalId ? ( +
+ Goal: Filtered +
+ ) : null} + {c.labelIds && c.labelIds.length > 0 ? ( +
+ Labels: {c.labelIds.length} filter(s) +
+ ) : null} + {c.query ? ( +
+ Search: "{c.query}" +
+ ) : null} +
+ ); +} + +// ----------------------------------------------------------------------------- +// Agent Detail Tab Component - Configure inbox for a specific agent +// ----------------------------------------------------------------------------- + +export function AgentInboxSettingsTab({ context }: PluginDetailTabProps) { + const { entityId, entityType } = context; + + if (entityType !== "agent") { + return ( +
+ This tab is only available on agent detail pages. +
+ ); + } + + const agentId = entityId; + const toast = usePluginToast(); + + // Fetch current config + const configData = usePluginData("getAgentInboxConfig", { agentId }); + + // Fetch projects for dropdown + const [projects, setProjects] = useState>([]); + const [goals, setGoals] = useState>([]); + const [loadingOptions, setLoadingOptions] = useState(true); + + // Form state + const [formState, setFormState] = useState({ + ...DEFAULT_INBOX_CONFIG, + statuses: configData.data?.statuses || DEFAULT_INBOX_CONFIG.statuses, + includeBacklog: configData.data?.includeBacklog || DEFAULT_INBOX_CONFIG.includeBacklog, + projectId: configData.data?.projectId || null, + goalId: configData.data?.goalId || null, + labelIds: configData.data?.labelIds || [], + query: configData.data?.query || null, + }); + + const [saving, setSaving] = useState(false); + + // Load projects and goals + useEffect(() => { + async function loadOptions() { + if (!context.companyId) return; + setLoadingOptions(true); + try { + const [projectsRes, goalsRes] = await Promise.all([ + fetch(`/api/companies/${context.companyId}/projects`, { credentials: "include" }), + fetch(`/api/companies/${context.companyId}/goals`, { credentials: "include" }), + ]); + + if (projectsRes.ok) { + const data = await projectsRes.json(); + setProjects(Array.isArray(data) ? data : []); + } + if (goalsRes.ok) { + const data = await goalsRes.json(); + setGoals(Array.isArray(data) ? data : []); + } + } catch (err) { + console.error("Failed to load options:", err); + } finally { + setLoadingOptions(false); + } + } + void loadOptions(); + }, [context.companyId]); + + // Update form when config data loads + useEffect(() => { + if (configData.data) { + setFormState({ ...DEFAULT_INBOX_CONFIG, ...configData.data }); + } + }, [configData.data]); + + const saveConfig = usePluginAction("setAgentInboxConfig"); + + async function handleSave(e: FormEvent) { + e.preventDefault(); + if (!agentId) return; + + setSaving(true); + try { + await saveConfig({ + agentId, + config: { + statuses: formState.statuses, + includeBacklog: formState.includeBacklog, + projectId: formState.projectId, + goalId: formState.goalId, + labelIds: formState.labelIds, + query: formState.query, + }, + }); + toast({ + title: "Inbox config saved", + body: `Configuration updated for this agent.`, + tone: "success", + }); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + toast({ + title: "Failed to save config", + body: message, + tone: "error", + }); + } finally { + setSaving(false); + } + } + + const statusOptions = getStatusOptions(); + const selectedStatuses = formState.statuses.split(","); + + return ( +
+

Inbox Configuration

+

+ Configure which issues appear in this agent's inbox via the inbox-lite endpoint. +

+ +
+ {/* Statuses */} +
+
Issue Statuses
+

+ Select which issue statuses should appear in this agent's inbox. +

+
+ {statusOptions.map((option) => ( + + ))} +
+
+ + {/* Project Filter */} +
+
Project Filter
+

+ Optionally limit inbox to issues from a specific project. +

+ +
+ + {/* Goal Filter */} +
+
Goal Filter
+

+ Optionally limit inbox to issues linked to a specific goal. +

+ +
+ + {/* Search Query */} +
+
Search Query
+

+ Optional search query to filter issues by title, description, or comments. +

+ setFormState({ ...formState, query: e.target.value || null })} + placeholder="e.g., docker, deployment, urgent" + /> +
+ + {/* Include Backlog Toggle */} +
+ +

+ When enabled, issues with status "backlog" will be included in the inbox. +

+
+ + {/* Actions */} +
+ + +
+
+
+ ); +} diff --git a/plugin-agent-inbox-config/src/worker.ts b/plugin-agent-inbox-config/src/worker.ts new file mode 100644 index 0000000..d09337c --- /dev/null +++ b/plugin-agent-inbox-config/src/worker.ts @@ -0,0 +1,195 @@ +import { definePlugin, runWorker, type PaperclipPlugin } from "@paperclipai/plugin-sdk"; +import { + DEFAULT_INBOX_CONFIG, + PLUGIN_ID, + PLUGIN_VERSION, + type AgentInboxConfig, +} from "./constants.js"; + +const WORKER_KEY = "agent-inbox-config-worker"; + +const plugin: PaperclipPlugin = definePlugin({ + async setup(ctx) { + ctx.logger.info(`${PLUGIN_ID} v${PLUGIN_VERSION} starting...`); + + // Initialize plugin state with default inbox configs per agent + const existingState = await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" }); + if (!existingState) { + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, {}); + } + + const versionState = await ctx.state.get({ scopeKind: "instance", stateKey: "version" }); + if (!versionState) { + await ctx.state.set({ scopeKind: "instance", stateKey: "version" }, PLUGIN_VERSION); + } + + // Register data handlers for UI to fetch data + ctx.data.register("agents", async (params) => { + const companyId = typeof params?.companyId === "string" ? params.companyId : ""; + if (!companyId) return []; + return await ctx.agents.list({ companyId, limit: 100, offset: 0 }); + }); + + ctx.data.register("getAgentInboxConfig", async (params) => { + const agentId = typeof params?.agentId === "string" ? params.agentId : ""; + if (!agentId) return null; + + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + return (configs as Record)[agentId] || null; + }); + + ctx.data.register("listAgentInboxConfigs", async () => { + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + return Object.entries(configs).map(([agentId, config]) => ({ agentId, config })); + }); + + // Register action handlers for UI to perform actions + ctx.actions.register("setAgentInboxConfig", async (params) => { + const agentId = typeof params?.agentId === "string" ? params.agentId : ""; + const config = params?.config as Partial; + + if (!agentId) { + throw new Error("agentId is required"); + } + + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + + // Merge with defaults + const mergedConfig: AgentInboxConfig = { + ...DEFAULT_INBOX_CONFIG, + statuses: config?.statuses || DEFAULT_INBOX_CONFIG.statuses, + includeBacklog: config?.includeBacklog ?? DEFAULT_INBOX_CONFIG.includeBacklog, + projectId: config?.projectId ?? null, + goalId: config?.goalId ?? null, + labelIds: config?.labelIds || [], + query: config?.query ?? null, + }; + + (configs as Record)[agentId] = mergedConfig; + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, configs); + + // Also persist to agent's runtimeConfig for durability and server-side access + try { + const agentResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + }); + if (agentResponse.ok) { + const agentData = await agentResponse.json(); + const currentRuntimeConfig = agentData.runtimeConfig || {}; + + const agentUpdateResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + runtimeConfig: { + ...currentRuntimeConfig, + inboxConfig: mergedConfig, + }, + }), + }); + if (!agentUpdateResponse.ok) { + ctx.logger.warn("Failed to update agent runtimeConfig with inbox config", { agentId, status: agentUpdateResponse.status }); + } + } + } catch (err) { + ctx.logger.warn("Failed to persist inbox config to agent runtimeConfig", { agentId, error: err }); + } + + ctx.logger.info("Inbox config updated for agent", { agentId }); + return { success: true, agentId, config: mergedConfig }; + }); + + ctx.actions.register("resetAgentInboxConfig", async (params) => { + const agentId = typeof params?.agentId === "string" ? params.agentId : ""; + + if (!agentId) { + throw new Error("agentId is required"); + } + + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + delete (configs as Record)[agentId]; + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, configs); + + // Also clear inboxConfig from agent's runtimeConfig + try { + const agentResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "GET", + headers: { "Content-Type": "application/json" }, + }); + if (agentResponse.ok) { + const agentData = await agentResponse.json(); + const currentRuntimeConfig = agentData.runtimeConfig || {}; + + // Remove inboxConfig from runtimeConfig + const updatedRuntimeConfig = { ...currentRuntimeConfig }; + delete updatedRuntimeConfig.inboxConfig; + + const agentUpdateResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + runtimeConfig: updatedRuntimeConfig, + }), + }); + if (!agentUpdateResponse.ok) { + ctx.logger.warn("Failed to clear agent runtimeConfig inbox config", { agentId, status: agentUpdateResponse.status }); + } + } + } catch (err) { + ctx.logger.warn("Failed to clear inbox config from agent runtimeConfig", { agentId, error: err }); + } + + ctx.logger.info("Inbox config reset for agent", { agentId }); + return { success: true, agentId }; + }); + + // Event handler for agent creation - set default inbox config + ctx.events.on("agent.created", async (event) => { + const agentId = event.entityId || ""; + if (!agentId) return; + + const configs = (await ctx.state.get({ scopeKind: "instance", stateKey: "agentInboxConfigs" })) || {}; + + // Set default config for new agent in plugin state + (configs as Record)[agentId] = { + ...DEFAULT_INBOX_CONFIG, + }; + + await ctx.state.set({ scopeKind: "instance", stateKey: "agentInboxConfigs" }, configs); + + // Also set default inboxConfig in agent's runtimeConfig + try { + const agentResponse = await ctx.http.fetch(`/api/agents/${agentId}`, { + method: "PATCH", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + runtimeConfig: { + inboxConfig: { ...DEFAULT_INBOX_CONFIG }, + }, + }), + }); + if (!agentResponse.ok) { + ctx.logger.warn("Failed to set default inbox config on new agent", { agentId, status: agentResponse.status }); + } + } catch (err) { + ctx.logger.warn("Failed to set default inbox config on new agent runtimeConfig", { agentId, error: err }); + } + + ctx.logger.info("Default inbox config set for new agent", { agentId }); + }); + + ctx.logger.info(`${PLUGIN_ID} initialized successfully`); + }, + + async onHealth() { + return { + status: "ok", + message: "Agent Inbox Config plugin ready", + details: {}, + }; + }, +}); + +export default plugin; +runWorker(plugin, import.meta.url); diff --git a/plugin-agent-inbox-config/tsconfig.json b/plugin-agent-inbox-config/tsconfig.json new file mode 100644 index 0000000..aef23a9 --- /dev/null +++ b/plugin-agent-inbox-config/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "../../../tsconfig.json", + "compilerOptions": { + "outDir": "dist", + "rootDir": "src", + "lib": ["ES2023", "DOM"], + "jsx": "react-jsx" + }, + "include": ["src"] +}