@evermore.work/plugin-sdk 2026.509.0-canary.0

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.
Files changed (62) hide show
  1. package/README.md +1215 -0
  2. package/dist/bundlers.d.ts +57 -0
  3. package/dist/bundlers.d.ts.map +1 -0
  4. package/dist/bundlers.js +106 -0
  5. package/dist/bundlers.js.map +1 -0
  6. package/dist/define-plugin.d.ts +266 -0
  7. package/dist/define-plugin.d.ts.map +1 -0
  8. package/dist/define-plugin.js +85 -0
  9. package/dist/define-plugin.js.map +1 -0
  10. package/dist/dev-cli.d.ts +3 -0
  11. package/dist/dev-cli.d.ts.map +1 -0
  12. package/dist/dev-cli.js +49 -0
  13. package/dist/dev-cli.js.map +1 -0
  14. package/dist/dev-server.d.ts +34 -0
  15. package/dist/dev-server.d.ts.map +1 -0
  16. package/dist/dev-server.js +194 -0
  17. package/dist/dev-server.js.map +1 -0
  18. package/dist/host-client-factory.d.ts +272 -0
  19. package/dist/host-client-factory.d.ts.map +1 -0
  20. package/dist/host-client-factory.js +481 -0
  21. package/dist/host-client-factory.js.map +1 -0
  22. package/dist/index.d.ts +84 -0
  23. package/dist/index.d.ts.map +1 -0
  24. package/dist/index.js +84 -0
  25. package/dist/index.js.map +1 -0
  26. package/dist/protocol.d.ts +1285 -0
  27. package/dist/protocol.d.ts.map +1 -0
  28. package/dist/protocol.js +306 -0
  29. package/dist/protocol.js.map +1 -0
  30. package/dist/testing.d.ts +166 -0
  31. package/dist/testing.d.ts.map +1 -0
  32. package/dist/testing.js +1766 -0
  33. package/dist/testing.js.map +1 -0
  34. package/dist/types.d.ts +1330 -0
  35. package/dist/types.d.ts.map +1 -0
  36. package/dist/types.js +12 -0
  37. package/dist/types.js.map +1 -0
  38. package/dist/ui/components.d.ts +511 -0
  39. package/dist/ui/components.d.ts.map +1 -0
  40. package/dist/ui/components.js +135 -0
  41. package/dist/ui/components.js.map +1 -0
  42. package/dist/ui/hooks.d.ts +155 -0
  43. package/dist/ui/hooks.d.ts.map +1 -0
  44. package/dist/ui/hooks.js +195 -0
  45. package/dist/ui/hooks.js.map +1 -0
  46. package/dist/ui/index.d.ts +54 -0
  47. package/dist/ui/index.d.ts.map +1 -0
  48. package/dist/ui/index.js +51 -0
  49. package/dist/ui/index.js.map +1 -0
  50. package/dist/ui/runtime.d.ts +3 -0
  51. package/dist/ui/runtime.d.ts.map +1 -0
  52. package/dist/ui/runtime.js +30 -0
  53. package/dist/ui/runtime.js.map +1 -0
  54. package/dist/ui/types.d.ts +388 -0
  55. package/dist/ui/types.d.ts.map +1 -0
  56. package/dist/ui/types.js +17 -0
  57. package/dist/ui/types.js.map +1 -0
  58. package/dist/worker-rpc-host.d.ts +127 -0
  59. package/dist/worker-rpc-host.d.ts.map +1 -0
  60. package/dist/worker-rpc-host.js +1279 -0
  61. package/dist/worker-rpc-host.js.map +1 -0
  62. package/package.json +88 -0
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Bundling presets for Evermore plugins.
3
+ *
4
+ * These helpers return plain config objects so plugin authors can use them
5
+ * with esbuild or rollup without re-implementing host contract defaults.
6
+ */
7
+ export interface PluginBundlerPresetInput {
8
+ pluginRoot?: string;
9
+ manifestEntry?: string;
10
+ workerEntry?: string;
11
+ uiEntry?: string;
12
+ outdir?: string;
13
+ sourcemap?: boolean;
14
+ minify?: boolean;
15
+ }
16
+ export interface EsbuildLikeOptions {
17
+ entryPoints: string[];
18
+ outdir: string;
19
+ bundle: boolean;
20
+ format: "esm";
21
+ platform: "node" | "browser";
22
+ target: string;
23
+ sourcemap?: boolean;
24
+ minify?: boolean;
25
+ external?: string[];
26
+ }
27
+ export interface RollupLikeConfig {
28
+ input: string;
29
+ output: {
30
+ dir: string;
31
+ format: "es";
32
+ sourcemap?: boolean;
33
+ entryFileNames?: string;
34
+ };
35
+ external?: string[];
36
+ plugins?: unknown[];
37
+ }
38
+ export interface PluginBundlerPresets {
39
+ esbuild: {
40
+ worker: EsbuildLikeOptions;
41
+ ui?: EsbuildLikeOptions;
42
+ manifest: EsbuildLikeOptions;
43
+ };
44
+ rollup: {
45
+ worker: RollupLikeConfig;
46
+ ui?: RollupLikeConfig;
47
+ manifest: RollupLikeConfig;
48
+ };
49
+ }
50
+ /**
51
+ * Build esbuild/rollup baseline configs for plugin worker, manifest, and UI bundles.
52
+ *
53
+ * The presets intentionally externalize host/runtime deps (`react`, SDK packages)
54
+ * to match the Evermore plugin loader contract.
55
+ */
56
+ export declare function createPluginBundlerPresets(input?: PluginBundlerPresetInput): PluginBundlerPresets;
57
+ //# sourceMappingURL=bundlers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundlers.d.ts","sourceRoot":"","sources":["../src/bundlers.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,wBAAwB;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,kBAAkB;IACjC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,EAAE,KAAK,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,MAAM,EAAE,IAAI,CAAC;QACb,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,cAAc,CAAC,EAAE,MAAM,CAAC;KACzB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE;QACP,MAAM,EAAE,kBAAkB,CAAC;QAC3B,EAAE,CAAC,EAAE,kBAAkB,CAAC;QACxB,QAAQ,EAAE,kBAAkB,CAAC;KAC9B,CAAC;IACF,MAAM,EAAE;QACN,MAAM,EAAE,gBAAgB,CAAC;QACzB,EAAE,CAAC,EAAE,gBAAgB,CAAC;QACtB,QAAQ,EAAE,gBAAgB,CAAC;KAC5B,CAAC;CACH;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,GAAE,wBAA6B,GAAG,oBAAoB,CAoGrG"}
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Bundling presets for Evermore plugins.
3
+ *
4
+ * These helpers return plain config objects so plugin authors can use them
5
+ * with esbuild or rollup without re-implementing host contract defaults.
6
+ */
7
+ /**
8
+ * Build esbuild/rollup baseline configs for plugin worker, manifest, and UI bundles.
9
+ *
10
+ * The presets intentionally externalize host/runtime deps (`react`, SDK packages)
11
+ * to match the Evermore plugin loader contract.
12
+ */
13
+ export function createPluginBundlerPresets(input = {}) {
14
+ const uiExternal = [
15
+ "@evermore.work/plugin-sdk/ui",
16
+ "@evermore.work/plugin-sdk/ui/hooks",
17
+ "react",
18
+ "react-dom",
19
+ "react/jsx-runtime",
20
+ ];
21
+ const outdir = input.outdir ?? "dist";
22
+ const workerEntry = input.workerEntry ?? "src/worker.ts";
23
+ const manifestEntry = input.manifestEntry ?? "src/manifest.ts";
24
+ const uiEntry = input.uiEntry;
25
+ const sourcemap = input.sourcemap ?? true;
26
+ const minify = input.minify ?? false;
27
+ const esbuildWorker = {
28
+ entryPoints: [workerEntry],
29
+ outdir,
30
+ bundle: true,
31
+ format: "esm",
32
+ platform: "node",
33
+ target: "node20",
34
+ sourcemap,
35
+ minify,
36
+ external: ["react", "react-dom"],
37
+ };
38
+ const esbuildManifest = {
39
+ entryPoints: [manifestEntry],
40
+ outdir,
41
+ bundle: true,
42
+ format: "esm",
43
+ platform: "node",
44
+ target: "node20",
45
+ sourcemap,
46
+ external: ["@evermore.work/plugin-sdk"],
47
+ };
48
+ const esbuildUi = uiEntry
49
+ ? {
50
+ entryPoints: [uiEntry],
51
+ outdir: `${outdir}/ui`,
52
+ bundle: true,
53
+ format: "esm",
54
+ platform: "browser",
55
+ target: "es2022",
56
+ sourcemap,
57
+ minify,
58
+ external: uiExternal,
59
+ }
60
+ : undefined;
61
+ const rollupWorker = {
62
+ input: workerEntry,
63
+ output: {
64
+ dir: outdir,
65
+ format: "es",
66
+ sourcemap,
67
+ entryFileNames: "worker.js",
68
+ },
69
+ external: ["react", "react-dom"],
70
+ };
71
+ const rollupManifest = {
72
+ input: manifestEntry,
73
+ output: {
74
+ dir: outdir,
75
+ format: "es",
76
+ sourcemap,
77
+ entryFileNames: "manifest.js",
78
+ },
79
+ external: ["@evermore.work/plugin-sdk"],
80
+ };
81
+ const rollupUi = uiEntry
82
+ ? {
83
+ input: uiEntry,
84
+ output: {
85
+ dir: `${outdir}/ui`,
86
+ format: "es",
87
+ sourcemap,
88
+ entryFileNames: "index.js",
89
+ },
90
+ external: uiExternal,
91
+ }
92
+ : undefined;
93
+ return {
94
+ esbuild: {
95
+ worker: esbuildWorker,
96
+ manifest: esbuildManifest,
97
+ ...(esbuildUi ? { ui: esbuildUi } : {}),
98
+ },
99
+ rollup: {
100
+ worker: rollupWorker,
101
+ manifest: rollupManifest,
102
+ ...(rollupUi ? { ui: rollupUi } : {}),
103
+ },
104
+ };
105
+ }
106
+ //# sourceMappingURL=bundlers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bundlers.js","sourceRoot":"","sources":["../src/bundlers.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,266 @@
1
+ /**
2
+ * `definePlugin` — the top-level helper for authoring a Evermore plugin.
3
+ *
4
+ * Plugin authors call `definePlugin()` and export the result as the default
5
+ * export from their worker entrypoint. The host imports the worker module,
6
+ * calls `setup()` with a `PluginContext`, and from that point the plugin
7
+ * responds to events, jobs, webhooks, and UI requests through the context.
8
+ *
9
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // dist/worker.ts
14
+ * import { definePlugin } from "@evermore.work/plugin-sdk";
15
+ *
16
+ * export default definePlugin({
17
+ * async setup(ctx) {
18
+ * ctx.logger.info("Linear sync plugin starting");
19
+ *
20
+ * // Subscribe to events
21
+ * ctx.events.on("issue.created", async (event) => {
22
+ * const config = await ctx.config.get();
23
+ * await ctx.http.fetch(`https://api.linear.app/...`, {
24
+ * method: "POST",
25
+ * headers: { Authorization: `Bearer ${await ctx.secrets.resolve(config.apiKeyRef as string)}` },
26
+ * body: JSON.stringify({ title: event.payload.title }),
27
+ * });
28
+ * });
29
+ *
30
+ * // Register a job handler
31
+ * ctx.jobs.register("full-sync", async (job) => {
32
+ * ctx.logger.info("Running full-sync job", { runId: job.runId });
33
+ * // ... sync logic
34
+ * });
35
+ *
36
+ * // Register data for the UI
37
+ * ctx.data.register("sync-health", async ({ companyId }) => {
38
+ * const state = await ctx.state.get({
39
+ * scopeKind: "company",
40
+ * scopeId: String(companyId),
41
+ * stateKey: "last-sync",
42
+ * });
43
+ * return { lastSync: state };
44
+ * });
45
+ * },
46
+ * });
47
+ * ```
48
+ */
49
+ import type { PluginContext } from "./types.js";
50
+ import type { PluginEnvironmentAcquireLeaseParams, PluginEnvironmentDestroyLeaseParams, PluginEnvironmentExecuteParams, PluginEnvironmentExecuteResult, PluginEnvironmentLease, PluginEnvironmentProbeParams, PluginEnvironmentProbeResult, PluginEnvironmentRealizeWorkspaceParams, PluginEnvironmentRealizeWorkspaceResult, PluginEnvironmentReleaseLeaseParams, PluginEnvironmentResumeLeaseParams, PluginEnvironmentValidateConfigParams, PluginEnvironmentValidationResult } from "./protocol.js";
51
+ /**
52
+ * Optional plugin-reported diagnostics returned from the `health()` RPC method.
53
+ *
54
+ * @see PLUGIN_SPEC.md §13.2 — `health`
55
+ */
56
+ export interface PluginHealthDiagnostics {
57
+ /** Machine-readable status: `"ok"` | `"degraded"` | `"error"`. */
58
+ status: "ok" | "degraded" | "error";
59
+ /** Human-readable description of the current health state. */
60
+ message?: string;
61
+ /** Plugin-reported key-value diagnostics (e.g. connection status, queue depth). */
62
+ details?: Record<string, unknown>;
63
+ }
64
+ /**
65
+ * Result returned from the `validateConfig()` RPC method.
66
+ *
67
+ * @see PLUGIN_SPEC.md §13.3 — `validateConfig`
68
+ */
69
+ export interface PluginConfigValidationResult {
70
+ /** Whether the config is valid. */
71
+ ok: boolean;
72
+ /** Non-fatal warnings about the config. */
73
+ warnings?: string[];
74
+ /** Validation errors (populated when `ok` is `false`). */
75
+ errors?: string[];
76
+ }
77
+ /**
78
+ * Input received by the plugin worker's `handleWebhook` handler.
79
+ *
80
+ * @see PLUGIN_SPEC.md §13.7 — `handleWebhook`
81
+ */
82
+ export interface PluginWebhookInput {
83
+ /** Endpoint key matching the manifest declaration. */
84
+ endpointKey: string;
85
+ /** Inbound request headers. */
86
+ headers: Record<string, string | string[]>;
87
+ /** Raw request body as a UTF-8 string. */
88
+ rawBody: string;
89
+ /** Parsed JSON body (if applicable and parseable). */
90
+ parsedBody?: unknown;
91
+ /** Unique request identifier for idempotency checks. */
92
+ requestId: string;
93
+ }
94
+ export interface PluginApiRequestInput {
95
+ routeKey: string;
96
+ method: string;
97
+ path: string;
98
+ params: Record<string, string>;
99
+ query: Record<string, string | string[]>;
100
+ body: unknown;
101
+ actor: {
102
+ actorType: "user" | "agent";
103
+ actorId: string;
104
+ agentId?: string | null;
105
+ userId?: string | null;
106
+ runId?: string | null;
107
+ };
108
+ companyId: string;
109
+ headers: Record<string, string>;
110
+ }
111
+ export interface PluginApiResponse {
112
+ status?: number;
113
+ headers?: Record<string, string>;
114
+ body?: unknown;
115
+ }
116
+ /**
117
+ * The plugin definition shape passed to `definePlugin()`.
118
+ *
119
+ * The only required field is `setup`, which receives the `PluginContext` and
120
+ * is where the plugin registers its handlers (events, jobs, data, actions,
121
+ * tools, etc.).
122
+ *
123
+ * All other lifecycle hooks are optional. If a hook is not implemented the
124
+ * host applies default behaviour (e.g. restarting the worker on config change
125
+ * instead of calling `onConfigChanged`).
126
+ *
127
+ * @see PLUGIN_SPEC.md §13 — Host-Worker Protocol
128
+ */
129
+ export interface PluginDefinition {
130
+ /**
131
+ * Called once when the plugin worker starts up, after `initialize` completes.
132
+ *
133
+ * This is where the plugin registers all its handlers: event subscriptions,
134
+ * job handlers, data/action handlers, and tool registrations. Registration
135
+ * must be synchronous after `setup` resolves — do not register handlers
136
+ * inside async callbacks that may resolve after `setup` returns.
137
+ *
138
+ * @param ctx - The full plugin context provided by the host
139
+ */
140
+ setup(ctx: PluginContext): Promise<void>;
141
+ /**
142
+ * Called when the host wants to know if the plugin is healthy.
143
+ *
144
+ * The host polls this on a regular interval and surfaces the result in the
145
+ * plugin health dashboard. If not implemented, the host infers health from
146
+ * worker process liveness.
147
+ *
148
+ * @see PLUGIN_SPEC.md §13.2 — `health`
149
+ */
150
+ onHealth?(): Promise<PluginHealthDiagnostics>;
151
+ /**
152
+ * Called when the operator updates the plugin's instance configuration at
153
+ * runtime, without restarting the worker.
154
+ *
155
+ * If not implemented, the host restarts the worker to apply the new config.
156
+ *
157
+ * @param newConfig - The newly resolved configuration
158
+ * @see PLUGIN_SPEC.md §13.4 — `configChanged`
159
+ */
160
+ onConfigChanged?(newConfig: Record<string, unknown>): Promise<void>;
161
+ /**
162
+ * Called when the host is about to shut down the plugin worker.
163
+ *
164
+ * The worker has at most 10 seconds (configurable via plugin config) to
165
+ * finish in-flight work and resolve this promise. After the deadline the
166
+ * host sends SIGTERM, then SIGKILL.
167
+ *
168
+ * @see PLUGIN_SPEC.md §12.5 — Graceful Shutdown Policy
169
+ */
170
+ onShutdown?(): Promise<void>;
171
+ /**
172
+ * Called to validate the current plugin configuration.
173
+ *
174
+ * The host calls this:
175
+ * - after the plugin starts (to surface config errors immediately)
176
+ * - after the operator saves a new config (to validate before persisting)
177
+ * - via the "Test Connection" button in the settings UI
178
+ *
179
+ * @param config - The configuration to validate
180
+ * @see PLUGIN_SPEC.md §13.3 — `validateConfig`
181
+ */
182
+ onValidateConfig?(config: Record<string, unknown>): Promise<PluginConfigValidationResult>;
183
+ /**
184
+ * Called to handle an inbound webhook delivery.
185
+ *
186
+ * The host routes `POST /api/plugins/:pluginId/webhooks/:endpointKey` to
187
+ * this handler. The plugin is responsible for signature verification using
188
+ * a resolved secret ref.
189
+ *
190
+ * If not implemented but webhooks are declared in the manifest, the host
191
+ * returns HTTP 501 for webhook deliveries.
192
+ *
193
+ * @param input - Webhook delivery metadata and payload
194
+ * @see PLUGIN_SPEC.md §13.7 — `handleWebhook`
195
+ */
196
+ onWebhook?(input: PluginWebhookInput): Promise<void>;
197
+ /**
198
+ * Called for manifest-declared scoped JSON API routes under
199
+ * `/api/plugins/:pluginId/api/*` after the host has enforced auth, company
200
+ * access, capabilities, and checkout policy.
201
+ */
202
+ onApiRequest?(input: PluginApiRequestInput): Promise<PluginApiResponse>;
203
+ /**
204
+ * Called to validate provider-specific configuration for a plugin-hosted
205
+ * environment driver.
206
+ */
207
+ onEnvironmentValidateConfig?(params: PluginEnvironmentValidateConfigParams): Promise<PluginEnvironmentValidationResult>;
208
+ /** Called to test reachability or readiness of a plugin-hosted environment. */
209
+ onEnvironmentProbe?(params: PluginEnvironmentProbeParams): Promise<PluginEnvironmentProbeResult>;
210
+ /** Called before a run starts to acquire a provider lease. */
211
+ onEnvironmentAcquireLease?(params: PluginEnvironmentAcquireLeaseParams): Promise<PluginEnvironmentLease>;
212
+ /** Called to reconnect to a previously acquired provider lease. */
213
+ onEnvironmentResumeLease?(params: PluginEnvironmentResumeLeaseParams): Promise<PluginEnvironmentLease>;
214
+ /** Called when a run finishes and the provider lease can be released. */
215
+ onEnvironmentReleaseLease?(params: PluginEnvironmentReleaseLeaseParams): Promise<void>;
216
+ /** Called when the host needs to force-destroy provider state. */
217
+ onEnvironmentDestroyLease?(params: PluginEnvironmentDestroyLeaseParams): Promise<void>;
218
+ /** Called to materialize the run workspace inside the provider lease. */
219
+ onEnvironmentRealizeWorkspace?(params: PluginEnvironmentRealizeWorkspaceParams): Promise<PluginEnvironmentRealizeWorkspaceResult>;
220
+ /** Called to execute a command inside the provider lease. */
221
+ onEnvironmentExecute?(params: PluginEnvironmentExecuteParams): Promise<PluginEnvironmentExecuteResult>;
222
+ }
223
+ /**
224
+ * The sealed plugin object returned by `definePlugin()`.
225
+ *
226
+ * Plugin authors export this as the default export from their worker
227
+ * entrypoint. The host imports it and calls the lifecycle methods.
228
+ *
229
+ * @see PLUGIN_SPEC.md §14 — SDK Surface
230
+ */
231
+ export interface EvermorePlugin {
232
+ /** The original plugin definition passed to `definePlugin()`. */
233
+ readonly definition: PluginDefinition;
234
+ }
235
+ /**
236
+ * Define a Evermore plugin.
237
+ *
238
+ * Call this function in your worker entrypoint and export the result as the
239
+ * default export. The host will import the module and call lifecycle methods
240
+ * on the returned object.
241
+ *
242
+ * @param definition - Plugin lifecycle handlers
243
+ * @returns A sealed `EvermorePlugin` object for the host to consume
244
+ *
245
+ * @example
246
+ * ```ts
247
+ * import { definePlugin } from "@evermore.work/plugin-sdk";
248
+ *
249
+ * export default definePlugin({
250
+ * async setup(ctx) {
251
+ * ctx.logger.info("Plugin started");
252
+ * ctx.events.on("issue.created", async (event) => {
253
+ * // handle event
254
+ * });
255
+ * },
256
+ *
257
+ * async onHealth() {
258
+ * return { status: "ok" };
259
+ * },
260
+ * });
261
+ * ```
262
+ *
263
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
264
+ */
265
+ export declare function definePlugin(definition: PluginDefinition): EvermorePlugin;
266
+ //# sourceMappingURL=define-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-plugin.d.ts","sourceRoot":"","sources":["../src/define-plugin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * `definePlugin` — the top-level helper for authoring a Evermore plugin.
3
+ *
4
+ * Plugin authors call `definePlugin()` and export the result as the default
5
+ * export from their worker entrypoint. The host imports the worker module,
6
+ * calls `setup()` with a `PluginContext`, and from that point the plugin
7
+ * responds to events, jobs, webhooks, and UI requests through the context.
8
+ *
9
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
10
+ *
11
+ * @example
12
+ * ```ts
13
+ * // dist/worker.ts
14
+ * import { definePlugin } from "@evermore.work/plugin-sdk";
15
+ *
16
+ * export default definePlugin({
17
+ * async setup(ctx) {
18
+ * ctx.logger.info("Linear sync plugin starting");
19
+ *
20
+ * // Subscribe to events
21
+ * ctx.events.on("issue.created", async (event) => {
22
+ * const config = await ctx.config.get();
23
+ * await ctx.http.fetch(`https://api.linear.app/...`, {
24
+ * method: "POST",
25
+ * headers: { Authorization: `Bearer ${await ctx.secrets.resolve(config.apiKeyRef as string)}` },
26
+ * body: JSON.stringify({ title: event.payload.title }),
27
+ * });
28
+ * });
29
+ *
30
+ * // Register a job handler
31
+ * ctx.jobs.register("full-sync", async (job) => {
32
+ * ctx.logger.info("Running full-sync job", { runId: job.runId });
33
+ * // ... sync logic
34
+ * });
35
+ *
36
+ * // Register data for the UI
37
+ * ctx.data.register("sync-health", async ({ companyId }) => {
38
+ * const state = await ctx.state.get({
39
+ * scopeKind: "company",
40
+ * scopeId: String(companyId),
41
+ * stateKey: "last-sync",
42
+ * });
43
+ * return { lastSync: state };
44
+ * });
45
+ * },
46
+ * });
47
+ * ```
48
+ */
49
+ // ---------------------------------------------------------------------------
50
+ // definePlugin — top-level factory
51
+ // ---------------------------------------------------------------------------
52
+ /**
53
+ * Define a Evermore plugin.
54
+ *
55
+ * Call this function in your worker entrypoint and export the result as the
56
+ * default export. The host will import the module and call lifecycle methods
57
+ * on the returned object.
58
+ *
59
+ * @param definition - Plugin lifecycle handlers
60
+ * @returns A sealed `EvermorePlugin` object for the host to consume
61
+ *
62
+ * @example
63
+ * ```ts
64
+ * import { definePlugin } from "@evermore.work/plugin-sdk";
65
+ *
66
+ * export default definePlugin({
67
+ * async setup(ctx) {
68
+ * ctx.logger.info("Plugin started");
69
+ * ctx.events.on("issue.created", async (event) => {
70
+ * // handle event
71
+ * });
72
+ * },
73
+ *
74
+ * async onHealth() {
75
+ * return { status: "ok" };
76
+ * },
77
+ * });
78
+ * ```
79
+ *
80
+ * @see PLUGIN_SPEC.md §14.1 — Example SDK Shape
81
+ */
82
+ export function definePlugin(definition) {
83
+ return Object.freeze({ definition });
84
+ }
85
+ //# sourceMappingURL=define-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"define-plugin.js","sourceRoot":"","sources":["../src/define-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+CG;AAmQH,8EAA8E;AAC9E,mCAAmC;AACnC,8EAA8E;AAE9E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,UAAU,YAAY,CAAC,UAA4B;IACvD,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC;AACvC,CAAC"}
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=dev-cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-cli.d.ts","sourceRoot":"","sources":["../src/dev-cli.ts"],"names":[],"mappings":""}
@@ -0,0 +1,49 @@
1
+ #!/usr/bin/env node
2
+ import path from "node:path";
3
+ import { startPluginDevServer } from "./dev-server.js";
4
+ function parseArg(flag) {
5
+ const index = process.argv.indexOf(flag);
6
+ if (index < 0)
7
+ return undefined;
8
+ return process.argv[index + 1];
9
+ }
10
+ /**
11
+ * CLI entrypoint for the local plugin UI preview server.
12
+ *
13
+ * This is intentionally minimal and delegates all serving behavior to
14
+ * `startPluginDevServer` so tests and programmatic usage share one path.
15
+ */
16
+ async function main() {
17
+ const rootDir = parseArg("--root") ?? process.cwd();
18
+ const uiDir = parseArg("--ui-dir") ?? "dist/ui";
19
+ const host = parseArg("--host") ?? "127.0.0.1";
20
+ const rawPort = parseArg("--port") ?? "4177";
21
+ const port = Number.parseInt(rawPort, 10);
22
+ if (!Number.isFinite(port) || port <= 0 || port > 65535) {
23
+ throw new Error(`Invalid --port value: ${rawPort}`);
24
+ }
25
+ const server = await startPluginDevServer({
26
+ rootDir: path.resolve(rootDir),
27
+ uiDir,
28
+ host,
29
+ port,
30
+ });
31
+ // eslint-disable-next-line no-console
32
+ console.log(`Evermore plugin dev server listening at ${server.url}`);
33
+ const shutdown = async () => {
34
+ await server.close();
35
+ process.exit(0);
36
+ };
37
+ process.on("SIGINT", () => {
38
+ void shutdown();
39
+ });
40
+ process.on("SIGTERM", () => {
41
+ void shutdown();
42
+ });
43
+ }
44
+ void main().catch((error) => {
45
+ // eslint-disable-next-line no-console
46
+ console.error(error instanceof Error ? error.message : String(error));
47
+ process.exit(1);
48
+ });
49
+ //# sourceMappingURL=dev-cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-cli.js","sourceRoot":"","sources":["../src/dev-cli.ts"],"names":[],"mappings":";AACA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAEvD,SAAS,QAAQ,CAAC,IAAY;IAC5B,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACzC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IAChC,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;AACjC,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,IAAI;IACjB,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;IACpD,MAAM,KAAK,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,SAAS,CAAC;IAChD,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,WAAW,CAAC;IAC/C,MAAM,OAAO,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,MAAM,CAAC;IAC7C,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1C,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;QACxD,MAAM,IAAI,KAAK,CAAC,yBAAyB,OAAO,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC;QACxC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;QAC9B,KAAK;QACL,IAAI;QACJ,IAAI;KACL,CAAC,CAAC;IAEH,sCAAsC;IACtC,OAAO,CAAC,GAAG,CAAC,2CAA2C,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC;IAErE,MAAM,QAAQ,GAAG,KAAK,IAAI,EAAE;QAC1B,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACrB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IAEF,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,KAAK,QAAQ,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;IACH,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE;QACzB,KAAK,QAAQ,EAAE,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC;AAED,KAAK,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;IAC1B,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;IACtE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,34 @@
1
+ export interface PluginDevServerOptions {
2
+ /** Plugin project root. Defaults to `process.cwd()`. */
3
+ rootDir?: string;
4
+ /** Relative path from root to built UI assets. Defaults to `dist/ui`. */
5
+ uiDir?: string;
6
+ /** Bind port for local preview server. Defaults to `4177`. */
7
+ port?: number;
8
+ /** Bind host. Defaults to `127.0.0.1`. */
9
+ host?: string;
10
+ }
11
+ export interface PluginDevServer {
12
+ url: string;
13
+ close(): Promise<void>;
14
+ }
15
+ /**
16
+ * Start a local static server for plugin UI assets with SSE reload events.
17
+ *
18
+ * Endpoint summary:
19
+ * - `GET /__evermore__/health` for diagnostics
20
+ * - `GET /__evermore__/events` for hot-reload stream
21
+ * - Any other path serves files from the configured UI build directory
22
+ */
23
+ export declare function startPluginDevServer(options?: PluginDevServerOptions): Promise<PluginDevServer>;
24
+ /**
25
+ * Return a stable file+mtime snapshot for a built plugin UI directory.
26
+ *
27
+ * Used by the polling watcher fallback and useful for tests that need to assert
28
+ * whether a UI build has changed between runs.
29
+ */
30
+ export declare function getUiBuildSnapshot(rootDir: string, uiDir?: string): Promise<Array<{
31
+ file: string;
32
+ mtimeMs: number;
33
+ }>>;
34
+ //# sourceMappingURL=dev-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dev-server.d.ts","sourceRoot":"","sources":["../src/dev-server.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,sBAAsB;IACrC,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0CAA0C;IAC1C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAkGD;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,GAAE,sBAA2B,GAAG,OAAO,CAAC,eAAe,CAAC,CAiFzG;AAED;;;;;GAKG;AACH,wBAAsB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,SAAY,GAAG,OAAO,CAAC,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC,CAY9H"}