@makinbakin/sdk 0.0.1-rc.2 → 0.0.1-rc.21

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 (125) hide show
  1. package/README.md +1 -0
  2. package/_internal/app/components/agent-select.d.ts +16 -2
  3. package/_internal/app/components/asset-picker.d.ts +25 -0
  4. package/_internal/app/components/charts/bar-chart.d.ts +16 -0
  5. package/_internal/app/components/charts/chart-data-table.d.ts +31 -0
  6. package/_internal/app/components/charts/chart-explainer.d.ts +9 -0
  7. package/_internal/app/components/charts/chart-tooltip.d.ts +8 -0
  8. package/_internal/app/components/charts/line-chart.d.ts +13 -0
  9. package/_internal/app/components/charts/palette.d.ts +24 -0
  10. package/_internal/app/components/charts/sparkline.d.ts +12 -0
  11. package/_internal/app/components/charts/stacked-column-chart.d.ts +40 -0
  12. package/_internal/app/components/confirm-dialog.d.ts +54 -0
  13. package/_internal/app/components/conversation/activity-group.d.ts +15 -0
  14. package/_internal/app/components/conversation/agent-turn.d.ts +36 -0
  15. package/_internal/app/components/conversation/attention.d.ts +56 -0
  16. package/_internal/app/components/conversation/composer.d.ts +35 -0
  17. package/_internal/app/components/conversation/conversation-empty-state.d.ts +8 -0
  18. package/_internal/app/components/conversation/conversation-panel.d.ts +33 -0
  19. package/_internal/app/components/conversation/conversation.d.ts +14 -0
  20. package/_internal/app/components/conversation/fold.d.ts +129 -0
  21. package/_internal/app/components/conversation/notification-sound.d.ts +8 -0
  22. package/_internal/app/components/conversation/relative-time.d.ts +8 -0
  23. package/_internal/app/components/conversation/reply-toast.d.ts +15 -0
  24. package/_internal/app/components/conversation/thread-id.d.ts +8 -0
  25. package/_internal/app/components/conversation/tool-call-drawer.d.ts +7 -0
  26. package/_internal/app/components/conversation/turn-recorder.d.ts +37 -0
  27. package/_internal/app/components/conversation/use-conversation-attention.d.ts +64 -0
  28. package/_internal/app/components/conversation/use-conversation-thread.d.ts +55 -0
  29. package/_internal/app/components/conversation/user-message.d.ts +11 -0
  30. package/_internal/app/components/danger-zone.d.ts +28 -0
  31. package/_internal/app/components/empty-state.d.ts +18 -6
  32. package/_internal/app/components/plugin-header.d.ts +4 -3
  33. package/_internal/app/components/save-bar.d.ts +32 -0
  34. package/_internal/app/components/score-overlay.d.ts +33 -0
  35. package/_internal/app/components/search-degraded-chip.d.ts +4 -0
  36. package/_internal/app/components/search-partial-chip.d.ts +13 -0
  37. package/_internal/app/components/search-unavailable.d.ts +12 -0
  38. package/_internal/app/components/section-card.d.ts +22 -0
  39. package/_internal/app/components/segmented-control.d.ts +28 -0
  40. package/_internal/app/components/stat-tile.d.ts +26 -0
  41. package/_internal/app/components/status-badge.d.ts +19 -0
  42. package/_internal/app/components/turn-output-view.d.ts +57 -0
  43. package/_internal/app/components/ui/badge.d.ts +1 -1
  44. package/_internal/app/components/ui/button.d.ts +1 -1
  45. package/_internal/app/components/underline-tabs.d.ts +6 -2
  46. package/_internal/app/components/unsaved-changes-guard.d.ts +34 -0
  47. package/_internal/app/core/conversation-turns.d.ts +148 -0
  48. package/_internal/app/core/logger.d.ts +1 -0
  49. package/_internal/app/hooks/use-available-models.d.ts +5 -0
  50. package/_internal/app/hooks/use-content-store.d.ts +0 -9
  51. package/_internal/app/hooks/use-file-drop.d.ts +25 -0
  52. package/_internal/app/hooks/use-history-back.d.ts +1 -0
  53. package/_internal/app/hooks/use-horizontal-resize.d.ts +22 -0
  54. package/_internal/app/hooks/use-json-fetch.d.ts +26 -0
  55. package/_internal/app/hooks/use-nav-badge.d.ts +13 -0
  56. package/_internal/app/hooks/use-plugin-event.d.ts +19 -0
  57. package/_internal/app/hooks/use-query-state.d.ts +2 -0
  58. package/_internal/app/hooks/use-resizable-pane.d.ts +35 -0
  59. package/_internal/app/hooks/use-schedule.d.ts +47 -1
  60. package/_internal/app/hooks/use-search.d.ts +27 -8
  61. package/_internal/app/hooks/use-task-run-history.d.ts +26 -0
  62. package/_internal/app/hooks/use-toast.d.ts +3 -3
  63. package/_internal/app/hooks/use-vertical-resize.d.ts +6 -7
  64. package/_internal/app/lib/browser-notify.d.ts +12 -1
  65. package/_internal/app/types/index.d.ts +1 -105
  66. package/_internal/core/adapters/runtime/concepts.d.ts +671 -99
  67. package/_internal/core/adapters/runtime/errors.d.ts +98 -0
  68. package/_internal/core/adapters/runtime/helpers.d.ts +19 -0
  69. package/_internal/core/adapters/runtime/index.d.ts +7 -2
  70. package/_internal/core/adapters/runtime/testing.d.ts +79 -0
  71. package/_internal/core/adapters/runtime/turn-activity.d.ts +23 -0
  72. package/_internal/core/adapters/shared.d.ts +122 -12
  73. package/_internal/core/content-dir.d.ts +9 -0
  74. package/_internal/core/docs/route.d.ts +1 -1
  75. package/_internal/core/format/structured.d.ts +44 -0
  76. package/_internal/core/format.d.ts +13 -0
  77. package/_internal/core/media/downscale.d.ts +18 -0
  78. package/_internal/core/media/sharp-loader.d.ts +36 -0
  79. package/_internal/core/plugin-types.d.ts +216 -499
  80. package/_internal/core/routing/define.d.ts +26 -3
  81. package/_internal/core/routing/dispatcher.d.ts +15 -6
  82. package/_internal/core/routing/index.d.ts +1 -1
  83. package/_internal/core/routing/types.d.ts +13 -70
  84. package/_internal/core/storage/atomic-write.d.ts +11 -0
  85. package/_internal/core/tasks/store.d.ts +129 -0
  86. package/_internal/core/tasks/testing.d.ts +2 -0
  87. package/_internal/{plugins/workflows/lib → core/workflows}/notification-channel-registry.d.ts +1 -1
  88. package/_internal/plugins/team/types.d.ts +61 -4
  89. package/_internal/plugins/workflows/hooks/use-notification-channels.d.ts +1 -1
  90. package/components/index.d.ts +111 -5
  91. package/components/index.js +61815 -30060
  92. package/hooks/index.d.ts +90 -9
  93. package/hooks/index.js +15181 -685
  94. package/hooks/router.d.ts +20 -4
  95. package/index.d.ts +20 -3
  96. package/index.js +297 -259
  97. package/internal/index.d.ts +70 -0
  98. package/internal/index.js +409 -0
  99. package/metadata/index.d.ts +14 -1
  100. package/package.json +9 -2
  101. package/register.d.ts +63 -9
  102. package/routing/index.d.ts +6 -1
  103. package/routing/index.js +187 -147
  104. package/slots/index.d.ts +16 -24
  105. package/slots/index.js +215 -30
  106. package/testing/index.d.ts +122 -0
  107. package/testing/index.js +21874 -0
  108. package/types/index.d.ts +19 -919
  109. package/types/index.js +16 -0
  110. package/ui/index.js +2 -1
  111. package/utils/index.d.ts +46 -6
  112. package/utils/index.js +322 -249
  113. package/_internal/app/components/integrated-brainstorm/activity.d.ts +0 -23
  114. package/_internal/app/components/integrated-brainstorm/collapsed-header.d.ts +0 -14
  115. package/_internal/app/components/integrated-brainstorm/empty-state.d.ts +0 -5
  116. package/_internal/app/components/integrated-brainstorm/index.d.ts +0 -8
  117. package/_internal/app/components/integrated-brainstorm/input-row.d.ts +0 -16
  118. package/_internal/app/components/integrated-brainstorm/message-list.d.ts +0 -8
  119. package/_internal/app/components/integrated-brainstorm/session.d.ts +0 -16
  120. package/_internal/app/components/integrated-brainstorm/sse.d.ts +0 -8
  121. package/_internal/app/components/integrated-brainstorm/thinking-indicator.d.ts +0 -19
  122. package/_internal/app/components/integrated-brainstorm/types.d.ts +0 -63
  123. package/_internal/app/components/integrated-brainstorm/use-auto-grow.d.ts +0 -6
  124. package/_internal/app/components/integrated-brainstorm/use-brainstorm-state.d.ts +0 -21
  125. package/_internal/app/hooks/use-assets.d.ts +0 -25
@@ -1,8 +1,24 @@
1
1
  /**
2
- * Plugin system type definitions for Bakin.
3
- * All plugin interfaces are defined here — no behavioral changes.
2
+ * Plugin system type definitions for Bakin (the internal, in-process surface).
3
+ *
4
+ * Two-tier contract — read before "deduplicating" against the SDK:
5
+ * `@makinbakin/sdk/types` is the PUBLISHED, self-contained, deliberately
6
+ * NARROWER plugin-author surface; this file is the INTERNAL surface that
7
+ * in-process core plugins actually receive. They are NOT a fork to collapse.
8
+ * Concretely:
9
+ * - `PluginContext.runtime` here is the FULL `AgentRuntimeAdapter`
10
+ * (adapters/runtime/concepts.ts: agents×11, tools, sessions, memory,
11
+ * config, images, media, restart…). Core plugins use ~15 full-only
12
+ * methods. The SDK exposes a curated subset.
13
+ * - `ctx.tasks` here returns the `PluginTask` projection; the SDK returns
14
+ * `Task`. `BakinPlugin` here adds `routes?`. `StorageAdapter`/`NavItem`/
15
+ * `APIRoute`/`HookAPI`/`SkillDefinition` are intentionally fuller here.
16
+ * Genuinely-identical LEAF data types (health, exec-result, search, manifest,
17
+ * EventBus/ActivityAPI/PluginLogger, TaskLogEntry, …) ARE single-homed in the
18
+ * SDK and re-exported below. Collapsing the boundary itself is WS2 work.
4
19
  */
5
- import type { ZodRawShape, ZodType } from 'zod';
20
+ import type { z, ZodRawShape, ZodType } from 'zod';
21
+ import type { ActivityAPI, ActivityClass, ConversationTurnsAPI, EventBus, ExecToolResult, HealthCheckRegistrationInput, HealthOwner, HealthRepairActionDefinition, PluginLogger, SearchAPI, TaskLogEntry } from '@makinbakin/sdk/types';
6
22
  import type { ContractStability, ContractVisibility, DocsExample, SchemaLike, SourceLocation } from './docs';
7
23
  import type { AgentRuntimeAdapter } from './adapters/runtime';
8
24
  import type { APIRoute as DeclarativeAPIRoute, PluginContextLite } from './routing/types';
@@ -17,18 +33,18 @@ export interface StorageAdapter {
17
33
  append(path: string, content: string): void;
18
34
  exists(path: string): boolean;
19
35
  readAll(): Record<string, string>;
20
- list?(path?: string): string[];
21
- remove?(path: string): void;
22
- rename?(from: string, to: string): void;
23
- stat?(path: string): {
36
+ list(path?: string): string[];
37
+ remove(path: string): void;
38
+ rename(from: string, to: string): void;
39
+ stat(path: string): {
24
40
  path: string;
25
41
  size: number;
26
42
  mtimeMs: number;
27
43
  isFile: boolean;
28
44
  isDirectory: boolean;
29
45
  } | null;
30
- readJson?<T = unknown>(path: string): T | null;
31
- writeJson?(path: string, value: unknown): void;
46
+ readJson<T = unknown>(path: string): T | null;
47
+ writeJson(path: string, value: unknown): void;
32
48
  /**
33
49
  * Convert a plugin-storage-relative path or glob to the content-dir-relative
34
50
  * path seen by file-backed search/watch APIs. Implementations never return
@@ -36,11 +52,8 @@ export interface StorageAdapter {
36
52
  */
37
53
  searchPath?(path: string): string;
38
54
  }
39
- export interface EventBus {
40
- emit(event: string, data?: Record<string, unknown>): void;
41
- on(pattern: string, handler: (event: string, data: Record<string, unknown>) => void): () => void;
42
- once(pattern: string, handler: (event: string, data: Record<string, unknown>) => void): () => void;
43
- }
55
+ export type { EventBus } from '@makinbakin/sdk/types';
56
+ export type NavSection = 'plan-and-automate' | 'create' | 'operations';
44
57
  export interface NavItem {
45
58
  id: string;
46
59
  label: string;
@@ -48,9 +61,17 @@ export interface NavItem {
48
61
  href: string;
49
62
  order?: number;
50
63
  children?: NavItem[];
51
- alwaysExpanded?: boolean;
64
+ section?: NavSection;
52
65
  }
53
- export interface APIRoute {
66
+ /**
67
+ * INTERNAL registered-route record — the erased shape routes take inside the
68
+ * plugin registry's state after declarative registration (typed schemas
69
+ * survive as extra fields the dispatcher reads). NOT a public authoring
70
+ * type: plugin authors declare routes with `defineRoute()` and the
71
+ * declarative-generic `APIRoute<C, P, Q, B>` from `@bakin/core/routing` /
72
+ * `@makinbakin/sdk` (audit 2026-07 H3 collapsed the two same-named types).
73
+ */
74
+ export interface RegisteredAPIRoute {
54
75
  path: string;
55
76
  method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
56
77
  handler: (req: Request, ctx: PluginContext) => Response | Promise<Response>;
@@ -64,6 +85,7 @@ export interface APIRoute {
64
85
  examples?: DocsExample[];
65
86
  source?: SourceLocation;
66
87
  permissions?: string[];
88
+ activityClass?: ActivityClass;
67
89
  }
68
90
  export interface UISlotRegistration {
69
91
  slot: string;
@@ -73,13 +95,7 @@ export interface UISlotRegistration {
73
95
  export interface ContentFile {
74
96
  path: string;
75
97
  }
76
- /** Result returned by execution tool handlers */
77
- export interface ExecToolResult {
78
- ok: boolean;
79
- error?: string;
80
- details?: unknown;
81
- [key: string]: unknown;
82
- }
98
+ export type { ExecToolResult } from '@makinbakin/sdk/types';
83
99
  /** Definition for a registerable execution tool */
84
100
  /** Context available to exec tool handlers — provides access to plugin services */
85
101
  export interface PluginToolContext {
@@ -94,13 +110,15 @@ export interface PluginToolContext {
94
110
  activity: ActivityAPI;
95
111
  getSettings<T = Record<string, unknown>>(): T;
96
112
  }
97
- export interface ExecToolDefinition {
113
+ export interface ExecToolDefinition<Shape extends ZodRawShape = ZodRawShape> {
98
114
  name: string;
99
115
  description: string;
100
116
  label?: string;
101
117
  activityDuplicate?: boolean;
102
- parameters: ZodRawShape;
103
- handler: (params: Record<string, unknown>, agent: string, ctx?: PluginToolContext) => Promise<ExecToolResult>;
118
+ activityClass?: ActivityClass;
119
+ parameters: Shape;
120
+ /** Params are inferred from `parameters` — declare the shape once, get typed params. */
121
+ handler: (params: z.infer<z.ZodObject<Shape>>, agent: string, ctx?: PluginToolContext) => Promise<ExecToolResult>;
104
122
  source?: string;
105
123
  }
106
124
  /** A skill that can be registered by plugins or loaded from disk */
@@ -109,6 +127,16 @@ export interface SkillDefinition {
109
127
  instructions: string;
110
128
  output_schema?: Record<string, unknown>;
111
129
  source?: string;
130
+ /** Absolute source markdown file path when the skill was loaded from a managed package/plugin file. */
131
+ sourcePath?: string;
132
+ }
133
+ export interface WorkflowLayoutInput {
134
+ positions?: Record<string, {
135
+ x: number;
136
+ y: number;
137
+ [key: string]: unknown;
138
+ }>;
139
+ [key: string]: unknown;
112
140
  }
113
141
  export interface WorkflowDefinitionInput {
114
142
  /** Stable workflow id. Falls back to slug(name) when omitted. */
@@ -117,23 +145,11 @@ export interface WorkflowDefinitionInput {
117
145
  description: string;
118
146
  version: number;
119
147
  inputs?: Record<string, unknown>;
148
+ layout?: WorkflowLayoutInput;
120
149
  steps: unknown[];
150
+ [key: string]: unknown;
121
151
  }
122
- export interface ActivityAPI {
123
- /** Log a human-readable message to the live activity feed */
124
- log(agent: string, message: string, opts?: {
125
- taskId?: string;
126
- category?: string;
127
- }): void;
128
- /** Log a structured audit event */
129
- audit(event: string, agent: string, data?: Record<string, unknown>): void;
130
- }
131
- export interface PluginLogger {
132
- debug(message: string, data?: Record<string, unknown>): void;
133
- info(message: string, data?: Record<string, unknown>): void;
134
- warn(message: string, errorOrData?: unknown, data?: Record<string, unknown>): void;
135
- error(message: string, errorOrData?: unknown, data?: Record<string, unknown>): void;
136
- }
152
+ export type { ActivityAPI, PluginLogger } from '@makinbakin/sdk/types';
137
153
  export interface HookAPI {
138
154
  /** Register a handler for a named hook. Returns unsubscribe function. */
139
155
  register(name: string, handler: (data: any) => any, metadata?: HookRegistrationMetadata): () => void;
@@ -200,7 +216,7 @@ export interface PluginNodeTypeInput<T = unknown> {
200
216
  * is prepended to `id` automatically (`{pluginId}.{id}`), matching the node-
201
217
  * type precedent. Built-in workflows-plugin runtime channels (general,
202
218
  * announcements, alerts, email) self-register at module load in
203
- * `plugins/workflows/lib/notification-channel-registry.ts`.
219
+ * `packages/core/src/workflows/notification-channel-registry.ts`.
204
220
  */
205
221
  export interface PluginNotificationChannelInput {
206
222
  id: string;
@@ -215,71 +231,18 @@ export interface NotificationChannelDef extends PluginNotificationChannelInput {
215
231
  /** Set when runtime === 'plugin'; identifies the owning plugin. */
216
232
  pluginId?: string;
217
233
  }
218
- /**
219
- * Canonical result shape for a single doctor check row.
220
- */
221
- export interface HealthCheckResult {
222
- check: string;
223
- status: 'ok' | 'warn' | 'error' | 'fixed';
224
- message: string;
225
- autoFixable: boolean;
226
- }
227
- export type HealthRepairSafety = 'safe' | 'manual' | 'destructive';
228
- export interface HealthRepairChange {
229
- kind: 'file' | 'setting' | 'service' | 'runtime' | 'task' | 'other';
230
- target: string;
231
- action: 'create' | 'update' | 'delete' | 'install' | 'invoke';
232
- description: string;
233
- }
234
- export interface HealthRepairPlanItem {
234
+ export type { ActionIncidentInput, AdvisoryIncidentInput, CanonicalErrorObservation, CanonicalHealthyObservation, CanonicalUnknownObservation, CanonicalWarningObservation, ErrorObservationInput, HealthCheckExecution, HealthCheckRegistrationInput, HealthCheckRunContext, HealthCheckRunInput, HealthCheckSnapshot, HealthCheckState, HealthDisposition, HealthFullSweep, HealthGroup, HealthIncident, HealthIncidentInput, HealthInstructionsResolution, HealthNavigateResolution, HealthNonEmptyArray, HealthObservation, HealthObservationInput, HealthObservationStatus, HealthOwner, HealthOwnerKind, HealthRepairActionDefinition, HealthRepairApplyRequest, HealthRepairApplyResult, HealthRepairSafety, HealthRepairChange, HealthRepairPlanItem, HealthRepairPlan, HealthRepairPrecondition, HealthRepairResolution, HealthRepairTarget, HealthReport, HealthReportStatus, HealthReportSummary, HealthResolution, HealthResource, HealthResourceKind, HealthRerunResolution, HealthyObservationInput, JsonObject, JsonValue, SearchReadiness, SearchReadinessStage, SearchReadinessStageKey, SearchReadinessStatus, SearchStageStatus, UnknownObservationInput, WarningObservationInput, WatchIncidentInput, } from '@makinbakin/sdk/types';
235
+ /** Core-internal canonical registration with its resolved owner and local id. */
236
+ export interface HealthCheckDef extends HealthCheckRegistrationInput {
235
237
  id: string;
236
- checkId: string;
237
- title: string;
238
- reason: string;
239
- safety: HealthRepairSafety;
240
- requiresConfirmation: boolean;
241
- changes: HealthRepairChange[];
238
+ localId: string;
239
+ owner: HealthOwner;
242
240
  }
243
- export interface HealthRepairApplyResult {
241
+ /** Core-internal canonical repair action with its resolved owner and local id. */
242
+ export interface HealthRepairActionDef extends HealthRepairActionDefinition {
244
243
  id: string;
245
- checkId: string;
246
- status: 'applied' | 'skipped' | 'failed';
247
- message: string;
248
- changes: HealthRepairChange[];
249
- }
250
- export interface HealthRepairHandler {
251
- plan(rows: HealthCheckResult[]): Promise<HealthRepairPlanItem[]>;
252
- apply(items: HealthRepairPlanItem[]): Promise<HealthRepairApplyResult[]>;
253
- }
254
- /**
255
- * Input shape plugins pass to `ctx.registerHealthCheck`. The plugin id is
256
- * auto-namespaced as `{pluginId}.{id}`. `run()` returns an array so one
257
- * registered check can contribute multiple result rows (mirrors how the
258
- * existing `checkPersonas` returns one per agent).
259
- */
260
- export interface PluginHealthCheckInput {
261
- id: string;
262
- name: string;
263
- /**
264
- * Runs the check, returns any number of result rows. Throws/rejects are
265
- * caught by the doctor orchestrator and converted to a synthetic error
266
- * result — a single bad handler never crashes the sweep.
267
- */
268
- run: () => Promise<HealthCheckResult[]>;
269
- /**
270
- * Legacy advisory flag for older admin surfaces. New code should derive
271
- * repairability from `repair`.
272
- */
273
- autoFix?: boolean;
274
- /**
275
- * Optional explicit repair contract. Diagnostics call only `run()`; repair
276
- * flows call `plan()` first, then `apply()` after explicit confirmation.
277
- */
278
- repair?: HealthRepairHandler;
279
- }
280
- export interface HealthCheckDef extends PluginHealthCheckInput {
281
- runtime: 'plugin';
282
- pluginId: string;
244
+ localId: string;
245
+ owner: HealthOwner;
283
246
  }
284
247
  export interface PluginContext {
285
248
  storage: StorageAdapter;
@@ -289,25 +252,17 @@ export interface PluginContext {
289
252
  tasks: PluginTaskService;
290
253
  assets: AssetsAPI;
291
254
  registerNav(items: NavItem[]): void;
292
- /**
293
- * @deprecated Use `definePlugin({ routes: [defineRoute({...})] })` to declare
294
- * routes. This adapter remains during the migration window for any
295
- * out-of-tree plugin that still calls `ctx.registerRoute(...)` from
296
- * `activate()`. In-repo plugins migrated in T6–T13 / T20 — none of them
297
- * call this. The dispatcher adapts the legacy shape (input → body,
298
- * output → responses[200]) when invoked through this path.
299
- */
300
- registerRoute(route: APIRoute): void;
301
255
  registerSlot(registration: UISlotRegistration): void;
302
- registerExecTool(tool: ExecToolDefinition): void;
256
+ registerExecTool<Shape extends ZodRawShape>(tool: ExecToolDefinition<Shape>): void;
303
257
  registerSkill(skill: SkillDefinition): void;
304
258
  /**
305
259
  * Register a workflow definition shipped by this plugin. Disk-resident
306
260
  * user definitions in `~/.bakin/workflows/definitions/` always win on id
307
261
  * collision (user-wins). A second plugin claiming an id already taken by
308
- * another plugin is a containment error: it's logged but does not throw
309
- * out of `activate()`. Re-registering the same id from the same plugin
310
- * is idempotent (newer wins) so hot reload works.
262
+ * another plugin THROWS out of `activate()` (R18 the activation fails
263
+ * and the plugin's partial registrations are swept). Re-registering the
264
+ * same id from the same plugin is an update (newer wins) so hot reload
265
+ * works.
311
266
  */
312
267
  registerWorkflow(definition: WorkflowDefinitionInput, opts?: {
313
268
  readOnly?: boolean;
@@ -334,7 +289,9 @@ export interface PluginContext {
334
289
  * sweep — throws are isolated, a single bad check never crashes the
335
290
  * doctor. Returns the namespaced id.
336
291
  */
337
- registerHealthCheck(def: PluginHealthCheckInput): string;
292
+ registerHealthCheck(def: HealthCheckRegistrationInput): string;
293
+ /** Register an owner-local repair action referenced by Health observations. */
294
+ registerHealthRepairAction(def: HealthRepairActionDefinition): string;
338
295
  watchFiles(patterns: string[]): void;
339
296
  /** Read this plugin's persisted settings */
340
297
  getSettings<T = Record<string, unknown>>(): T;
@@ -342,12 +299,14 @@ export interface PluginContext {
342
299
  updateSettings(patch: Record<string, unknown>): void;
343
300
  /** Structured activity logging */
344
301
  activity: ActivityAPI;
345
- /** Plugin-scoped server log. Prefer this over console.* for lifecycle logs. */
346
- log?: PluginLogger;
302
+ /** Plugin-scoped server log. Always provided; prefer over console.*. */
303
+ log: PluginLogger;
347
304
  /** Cross-plugin hook registration */
348
305
  hooks: HookAPI;
349
306
  /** Adapter-backed search — register content types, index, query */
350
307
  search: SearchAPI;
308
+ /** Shared conversation turn engine — background turns for chat-like surfaces (#703) */
309
+ conversations: ConversationTurnsAPI;
351
310
  }
352
311
  export type PluginTaskColumn = 'backlog' | 'todo' | 'inProgress' | 'review' | 'done' | 'blocked' | 'archived';
353
312
  export interface PluginTask {
@@ -366,6 +325,7 @@ export interface PluginTask {
366
325
  workflowId?: string;
367
326
  scheduleJobId?: string;
368
327
  projectId?: string;
328
+ brandId?: string;
369
329
  availableAt?: string;
370
330
  dueAt?: string;
371
331
  source?: PluginTaskSource;
@@ -379,12 +339,7 @@ export interface PluginTaskSource {
379
339
  entityId?: string;
380
340
  purpose?: string;
381
341
  }
382
- export interface TaskLogEntry {
383
- timestamp: string;
384
- author: string;
385
- message: string;
386
- data?: Record<string, unknown>;
387
- }
342
+ export type { TaskLogEntry } from '@makinbakin/sdk/types';
388
343
  export interface PluginTaskCreateInput {
389
344
  id?: string;
390
345
  title: string;
@@ -395,6 +350,7 @@ export interface PluginTaskCreateInput {
395
350
  date?: string;
396
351
  workflowId?: string;
397
352
  projectId?: string;
353
+ brandId?: string;
398
354
  parentId?: string | null;
399
355
  availableAt?: string;
400
356
  dueAt?: string;
@@ -413,6 +369,7 @@ export interface PluginTaskUpdateInput {
413
369
  workflowId?: string;
414
370
  scheduleJobId?: string;
415
371
  projectId?: string;
372
+ brandId?: string;
416
373
  parentId?: string | null;
417
374
  availableAt?: string | null;
418
375
  dueAt?: string | null;
@@ -428,349 +385,154 @@ export interface PluginTaskService {
428
385
  column?: PluginTaskColumn;
429
386
  agent?: string;
430
387
  projectId?: string;
388
+ brandId?: string;
431
389
  }): Promise<PluginTask[]>;
432
390
  appendLog(id: string, entry: TaskLogEntry): Promise<void>;
433
391
  }
434
- export interface AssetVariantMeta {
435
- role: 'thumbnail' | 'optimized' | 'webp';
436
- path: string;
437
- filename: string;
438
- size: number;
439
- mimeType: string;
440
- }
441
- export interface AssetMeta {
442
- path: string;
443
- filename: string;
444
- type: 'text' | 'images' | 'video' | 'audio' | 'plans' | 'research' | 'pdf' | 'data' | 'other';
445
- mimeType: string;
446
- size: number;
447
- mtimeMs?: number;
448
- metadata: {
449
- agent: string;
450
- taskId: string | null;
451
- created: string;
452
- tool?: string;
453
- description?: string;
454
- tags?: string[];
455
- originalFilename?: string;
392
+ /** The asset type taxonomy (mirrors ASSET_TYPES in the assets plugin). */
393
+ export type AssetTypeName = 'text' | 'images' | 'video' | 'audio' | 'plans' | 'research' | 'pdf' | 'data' | 'other';
394
+ /** Per-version generation provenance (matches the manifest's `generation` block). */
395
+ export interface AssetGenerationInfo {
396
+ provider: string;
397
+ model: string;
398
+ surface: string;
399
+ /** Honored only on the shim path; native generations omit it (#379). */
400
+ quality?: string;
401
+ routeSource: string;
402
+ routeReason?: string;
403
+ /** Reference/context images that conditioned this generation (#418). */
404
+ references?: Array<{
405
+ assetId: string;
406
+ version: number;
407
+ }>;
408
+ /** Brand provenance (#419): brand id + content fingerprint as-used. */
409
+ brandId?: string;
410
+ brandFingerprint?: string;
411
+ }
412
+ /** Create a new versioned asset (v1) from a source file. */
413
+ export interface AssetCreateInput {
414
+ sourceFilePath: string;
415
+ type: AssetTypeName;
416
+ agent: string;
417
+ taskId: string | null;
418
+ slug?: string;
419
+ op?: 'generate' | 'upload' | 'import';
420
+ tool?: string | null;
421
+ prompt?: string | null;
422
+ promptHash?: string | null;
423
+ description?: string;
424
+ tags?: string[];
425
+ source?: {
426
+ kind: 'generated' | 'upload' | 'import' | 'clipboard' | 'workspace-file';
427
+ path: string | null;
456
428
  };
457
- variants?: AssetVariantMeta[];
458
- }
459
- export interface AssetFileRef {
460
- kind: 'asset';
461
- filename: string;
462
- mimeType?: string;
463
- }
464
- export interface AssetsAPI {
465
- getByFilename(filename: string): Promise<AssetMeta | null>;
466
- list(filter?: {
467
- type?: AssetMeta['type'];
468
- taskId?: string | null;
469
- }): Promise<AssetMeta[]>;
470
- exists(filename: string): Promise<boolean>;
471
- fileRef(filename: string): Promise<AssetFileRef>;
472
- }
473
- /** Field type for search content type schemas */
474
- export interface SearchSchemaField {
475
- type: 'text' | 'keyword' | 'number' | 'boolean' | 'datetime' | 'array';
429
+ generation?: AssetGenerationInfo | null;
476
430
  }
477
431
  /**
478
- * One vector index on a search table. A content type can declare multiple
479
- * indexes to embed the same document into several vector spaces — e.g. a
480
- * text index using BGE and a visual index using CLIP on the assets table.
481
- * Each index has its own embedder (resolved via embedderRef), input
482
- * declaration, and optional chunker config.
432
+ * Append a new version to an existing asset. Note: no `tags` tags are an
433
+ * asset-level organizational namespace that versioning never touches.
483
434
  */
484
- export interface SearchIndexDefinition {
485
- /** Index name as stored by the search adapter. Must be stable across restarts. */
486
- name: string;
487
- /** Ref into settings.search.settings.embedders — 'default', 'visual', or custom. */
488
- embedderRef: string;
489
- /** Handlebars template for this index's text embedding input. */
490
- embeddingTemplate?: string;
491
- /**
492
- * Document field containing a URL to media bytes for visual/multimodal
493
- * embedding input. The search adapter owns provider-specific helper syntax.
494
- */
495
- mediaUrlField?: string;
496
- /** Per-index chunker config, overrides any table-level default. */
497
- chunker?: {
498
- enabled: boolean;
499
- targetTokens?: number;
500
- overlapTokens?: number;
501
- };
502
- }
503
- /** Definition for a searchable content type registered by a plugin */
504
- export interface SearchContentTypeDefinition {
505
- /** Table name — auto-prefixed with `bakin_`. E.g., 'tasks' → 'bakin_tasks' */
506
- table: string;
507
- /** Schema for the document fields */
508
- schema: Record<string, SearchSchemaField>;
509
- /** Fields to include in full-text search */
510
- searchableFields: string[];
511
- /**
512
- * Handlebars template for embedding generation. Used when `indexes` is
513
- * not provided — the registry synthesizes a single default index named
514
- * `embeddings` with this template and the default embedder.
515
- */
516
- embeddingTemplate: string;
517
- /**
518
- * Optional per-index definitions. When provided, overrides
519
- * `embeddingTemplate` and creates one embedding index per entry with
520
- * its own embedder. Used by content types that want multimodal indexing
521
- * (e.g. assets with both a text index and a visual index).
522
- */
523
- indexes?: SearchIndexDefinition[];
524
- /** Fields to expose as aggregatable facets */
525
- facets?: string[];
526
- /**
527
- * Document field to use as input for the cross-encoder reranker. When
528
- * set, queries against this content type attach the configured reranker
529
- * and score the query-document pair using the value at this field.
530
- * When unset, queries skip reranking for this content type.
531
- */
532
- rerankField?: string;
533
- /** TTL duration (Go format: '24h', '7d', '30d') */
534
- ttl?: string;
535
- /** TTL field (defaults to 'created_at') */
536
- ttlField?: string;
537
- /** Chunking config for long documents — used by the synthesized default index. */
538
- chunker?: {
539
- enabled: boolean;
540
- targetTokens?: number;
541
- overlapTokens?: number;
542
- };
543
- /**
544
- * Backfill function — called during full/per-table reindex.
545
- * Must yield ALL documents for this content type from source.
546
- */
547
- reindex: () => AsyncGenerator<{
548
- key: string;
549
- doc: Record<string, unknown>;
550
- }>;
551
- /**
552
- * Existence check — called during orphan cleanup.
553
- * Returns true if the source document for this key still exists.
554
- */
555
- verifyExists: (key: string) => Promise<boolean>;
556
- }
557
- /** Parameters for a search query */
558
- export interface SearchQueryParams {
559
- /** Search query string */
560
- q: string;
561
- /** Structured keyword filters */
562
- filters?: Record<string, string | boolean | number>;
563
- /** Facets to include in aggregations */
564
- facets?: string[];
565
- /** Max results */
566
- limit?: number;
567
- /** Result offset for pagination */
568
- offset?: number;
569
- /**
570
- * Whether to run the cross-encoder reranker on results. Defaults to
571
- * true when the reranker is enabled in settings. Set false for latency-
572
- * sensitive paths (facet-only queries, ID lookups, bulk scans) where
573
- * the extra ~100-500ms isn't worth it.
574
- */
575
- rerank?: boolean;
576
- /**
577
- * Raw adapter-specific aggregations passed through unchanged to the query layer.
578
- * Use for date histograms, range buckets, stats aggregations, or any
579
- * other shape beyond the term-facet convenience in `facets`. Merged
580
- * with facet-derived aggregations (these win on key collision).
581
- * See the active search adapter docs for the aggregation schema.
582
- */
583
- aggregations?: Record<string, unknown>;
584
- /**
585
- * Search strategy override. Defaults to the site-wide search strategy.
586
- * Pass 'full_text_only' for filter-driven
587
- * counts or ID lookups — semantic search rejects `limit: 0` queries
588
- * with the "semantic search requires topk limit to be positive" error.
589
- */
590
- strategy?: 'rrf' | 'semantic_only' | 'full_text_only';
591
- }
592
- /** A single search result */
593
- export interface SearchResult {
594
- id: string;
595
- table: string;
596
- score: number;
597
- fields: Record<string, unknown>;
598
- /** Cross-encoder reranker score (present when a reranker was used). */
599
- rerankScore?: number;
600
- }
601
- /** Search response from a query */
602
- export interface SearchResponse {
603
- results: SearchResult[];
604
- /**
605
- * Mapped term-facet aggregations — keyed by facet field, each a list
606
- * of { value, count }. Populated from `params.facets` for convenience.
607
- */
608
- aggregations?: Record<string, Array<{
609
- value: string;
610
- count: number;
611
- }>>;
612
- /**
613
- * Raw aggregation response from the search adapter, unmodified. Populated whenever
614
- * the underlying query returned aggregations — use this for non-term
615
- * shapes like date_histogram, range, stats, etc.
616
- */
617
- rawAggregations?: Record<string, unknown>;
618
- meta: {
619
- query: string;
620
- total: number;
621
- took_ms: number;
622
- source: 'search' | 'fallback';
623
- };
624
- }
625
- export interface SearchHealthIndex {
626
- name: string;
627
- type: string;
628
- totalIndexed: number;
629
- walBacklog: number;
630
- error?: string;
631
- rebuilding: boolean;
632
- backfillProgress?: number;
633
- }
634
- export interface SearchHealthTable {
635
- table: string;
636
- pluginId: string;
637
- stats: Record<string, unknown> | null;
638
- indexHealth?: SearchHealthIndex[];
639
- healthy: boolean;
640
- }
641
- export interface SearchHealthSnapshot {
642
- enabled: boolean;
643
- tables: SearchHealthTable[];
435
+ export interface AssetVersionCreateInput {
436
+ sourceFilePath: string;
437
+ op?: 'edit' | 'generate' | 'upload' | 'import';
438
+ tool?: string | null;
439
+ prompt?: string | null;
440
+ promptHash?: string | null;
441
+ description?: string;
442
+ generation?: AssetGenerationInfo | null;
443
+ }
444
+ /** Render a derived export of a version (keyed/idempotent by surface). */
445
+ export interface AssetExportRequest {
446
+ fromVersion?: number;
447
+ surface: string;
448
+ format: 'jpg' | 'png' | 'webp';
449
+ width: number;
450
+ height: number;
451
+ quality?: number;
452
+ }
453
+ export interface VersionedAssetRef {
454
+ assetId: string;
455
+ version: number;
644
456
  }
645
- /** Atomic transform operation (update fields without re-embedding) */
646
- export interface SearchTransformOp {
647
- op: '$set' | '$inc' | '$push';
648
- field?: string;
649
- value: unknown;
457
+ export interface AssetVersionFileRef {
458
+ absPath: string;
459
+ mimeType: string;
460
+ version: number;
650
461
  }
651
- /**
652
- * One file-pattern → mapper pair used by `FileBackedContentTypeDefinition`.
653
- * A registration may carry multiple of these when a single content type
654
- * draws from several distinct file shapes (e.g. workflows store
655
- * definitions as `.yaml` and instances as `.json`, both indexed into the
656
- * same `bakin_workflows` table with different key prefixes).
657
- */
658
- export interface FilePatternMapper {
659
- /** Glob pattern relative to contentDir. First-match-wins across the patterns array. */
660
- pattern: string;
661
- /**
662
- * Derive the search key for a file matching this pattern. Return null
663
- * to skip the file (e.g. it matches the glob but is missing required
664
- * companion data).
665
- */
666
- fileToId: (relPath: string) => string | null;
667
- /**
668
- * Build the search document for a file matching this pattern.
669
- * `content` is the raw file bytes as a UTF-8 string (empty for binary
670
- * assets, which the watcher recognizes by their `assets/` prefix).
671
- * Return null to skip indexing (e.g. derived state isn't ready yet).
672
- */
673
- fileToDoc: (relPath: string, content: string) => Promise<Record<string, unknown> | null>;
462
+ /** Current-version summary of an asset, addressed by id. */
463
+ export interface AssetSummary {
464
+ assetId: string;
465
+ type: AssetTypeName;
466
+ agent: string;
467
+ taskId: string | null;
468
+ created: string;
469
+ updated: string;
470
+ currentVersion: number;
471
+ versionCount: number;
472
+ description: string;
473
+ tags: string[];
474
+ mimeType: string;
475
+ width: number | null;
476
+ height: number | null;
477
+ size: number;
478
+ hasThumb: boolean;
674
479
  }
675
480
  /**
676
- * A content type whose source of truth is one or more files under
677
- * `~/.bakin/`. Registering via `registerFileBackedContentType` wires up:
678
- *
679
- * 1. Standard `registerContentType` (table creation, schema, reindex).
680
- * 2. A watcher sync hook that re-indexes on add/change.
681
- * 3. A watcher unlink hook that removes on delete.
682
- * 4. A startup reconcile that detects mtime drift and corrects it.
683
- *
684
- * Plugins should reach for this helper first. Use raw `registerContentType`
685
- * only when the source of truth is NOT the filesystem (e.g. SQLite,
686
- * external API, runtime adapter).
481
+ * Per-version detail of a versioned asset (mirrors the manifest's version
482
+ * entries provenance fields are null when the version wasn't produced by a
483
+ * generation tool).
687
484
  */
688
- export interface FileBackedContentTypeDefinition extends SearchContentTypeDefinition {
689
- /**
690
- * One or more file-pattern mappers. Patterns should not overlap;
691
- * first match wins. A file that matches no pattern is ignored.
692
- */
693
- filePatterns: FilePatternMapper[];
694
- /**
695
- * Optional exclude patterns applied BEFORE any mapper matches. Useful
696
- * for skipping subdirectories like `assets/**\/.trash/**` or sidecar
697
- * files like `**\/*.meta.json`.
698
- */
699
- excludePatterns?: string[];
700
- /**
701
- * Escape hatch for sync events. When provided, the helper invokes
702
- * this instead of the default `fileToDoc → ctx.search.index` flow for
703
- * any file matching this content type's patterns. The plugin takes
704
- * full responsibility for indexing.
705
- *
706
- * Use when pairing logic (e.g. assets' binary↔sidecar coupling) can't
707
- * be expressed as a single mapper. The matched `FilePatternMapper` is
708
- * still consulted for `fileToId` if the plugin needs the canonical key.
709
- */
710
- onSync?: (relPath: string, content: string) => Promise<void>;
711
- /**
712
- * Escape hatch for unlink events. Same story as `onSync`. If unset,
713
- * the helper calls the matched mapper's `fileToId(relPath)` and then
714
- * `ctx.search.remove(id)`.
715
- */
716
- onUnlink?: (relPath: string) => Promise<void>;
717
- /**
718
- * Whether to run the startup reconcile loop on plugin activation.
719
- * Defaults to true. Set false only when the plugin wants to drive its
720
- * own initial population (rare).
721
- */
722
- buildOnStartup?: boolean;
485
+ export interface AssetVersionDetail {
486
+ version: number;
487
+ /** Version file name inside the asset directory (e.g. `v2.png`). */
488
+ file: string;
489
+ width: number | null;
490
+ height: number | null;
491
+ op: 'generate' | 'edit' | 'upload' | 'import';
492
+ tool: string | null;
493
+ prompt: string | null;
494
+ promptHash: string | null;
495
+ generation: AssetGenerationInfo | null;
723
496
  }
724
- /** Search API provided to plugins via ctx.search */
725
- export interface SearchAPI {
726
- /**
727
- * Register a content type this plugin will index.
728
- * Must be called during activate(). Creates the search table if needed.
729
- *
730
- * Prefer `registerFileBackedContentType` when the source of truth is
731
- * a file under `~/.bakin/` — it wires up watcher hooks and startup
732
- * reconcile automatically. Use this raw form only for non-filesystem
733
- * sources (SQLite, external APIs, runtime adapters).
734
- */
735
- registerContentType(def: SearchContentTypeDefinition): void;
736
- /**
737
- * Register a file-backed content type. Wraps `registerContentType` and
738
- * additionally wires watcher sync + unlink hooks scoped to the declared
739
- * file patterns, plus a startup reconcile that detects mtime drift on
740
- * boot. This is the blessed API for any plugin whose data lives in the
741
- * filesystem under `~/.bakin/`.
742
- */
743
- registerFileBackedContentType(def: FileBackedContentTypeDefinition): void;
744
- /** Index or update a document. Fire-and-forget. */
745
- index(key: string, doc: Record<string, unknown>): Promise<void>;
746
- /** Remove a document from the index. */
747
- remove(key: string): Promise<void>;
748
- /** Atomic field update without re-embedding. For metadata-only changes. */
749
- transform(key: string, operations: SearchTransformOp[]): Promise<void>;
750
- /** Search this plugin's content type. */
751
- query(params: SearchQueryParams): Promise<SearchResponse>;
752
- /** Global search adapter and registered-table health snapshot. */
753
- health?(): Promise<SearchHealthSnapshot>;
497
+ export interface AssetsAPI {
498
+ createAsset(input: AssetCreateInput): Promise<VersionedAssetRef>;
499
+ /** Read an asset's current-version summary by id (metadata: type/description/tags/etc.), or null. */
500
+ getAsset(assetId: string): Promise<AssetSummary | null>;
501
+ addVersion(assetId: string, input: AssetVersionCreateInput): Promise<VersionedAssetRef>;
502
+ addExport(assetId: string, input: AssetExportRequest): Promise<{
503
+ name: string;
504
+ file: string;
505
+ }>;
506
+ resolveVersionFile(assetId: string, version?: number): Promise<AssetVersionFileRef | null>;
507
+ /** List asset summaries, optionally filtered by type and/or owning task. */
508
+ listAssets(filter?: {
509
+ type?: AssetTypeName;
510
+ taskId?: string;
511
+ }): Promise<AssetSummary[]>;
512
+ /** Read an asset's version history (current pointer + per-version detail), or null. */
513
+ getAssetVersions(assetId: string): Promise<{
514
+ currentVersion: number;
515
+ versions: AssetVersionDetail[];
516
+ } | null>;
517
+ /**
518
+ * Source-path-keyed upsert: create v1 if no asset tracks `sourcePath`,
519
+ * append a version if its content changed, or no-op if identical
520
+ * (`changed: false`). A path inside the asset store reflects to the asset
521
+ * it already belongs to never a duplicate.
522
+ */
523
+ upsertFromSource(sourcePath: string, input: AssetCreateInput): Promise<VersionedAssetRef & {
524
+ changed: boolean;
525
+ }>;
754
526
  /**
755
- * Plugin-scoped maintenance operations for indexers that own non-file-backed
756
- * tables. This is intentionally narrower than the raw adapter: callers can
757
- * only touch their own registered content type.
527
+ * Map an absolute path INSIDE the asset store back to its asset identity.
528
+ * `absPath` in the result is always the REAL version file (never the thumb).
529
+ * Null for anything outside the store or store-internal non-version files.
758
530
  */
759
- maintenance?: SearchMaintenanceAPI;
760
- }
761
- export interface SearchMaintenanceAPI {
762
- /** Whether the backing search service is reachable. */
763
- available(): Promise<boolean>;
764
- /** Iterate every document in this plugin's registered content type. */
765
- scan(): AsyncIterable<{
766
- key: string;
767
- document: Record<string, unknown>;
768
- }>;
769
- /** Remove several documents from this plugin's registered content type. */
770
- batchRemove(keys: string[]): Promise<number>;
771
- /** Drop and recreate this plugin's registered content type table. */
772
- resetContentType(): Promise<void>;
531
+ resolveStoreFile(absPath: string): Promise<(VersionedAssetRef & {
532
+ absPath: string;
533
+ }) | null>;
773
534
  }
535
+ export type { SearchSchemaField, SearchIndexDefinition, SearchContentTypeDefinition, SearchQueryParams, SearchResult, SearchResponse, SearchHealthIndex, SearchHealthTable, SearchHealthSnapshot, SearchReindexItem, SearchTransformOp, SearchScanOptions, FilePatternMapper, FileBackedContentTypeDefinition, SearchAPI, SearchMaintenanceAPI, } from '@makinbakin/sdk/types';
774
536
  interface BaseSettingsField {
775
537
  key: string;
776
538
  label: string;
@@ -859,52 +621,7 @@ export interface BakinPlugin {
859
621
  * a bare `routes: APIRoute[]` annotation widens types and breaks the
860
622
  * per-route inference that drives the dispatcher's typed `parsed` argument.
861
623
  *
862
- * Optional during the migration window (T1–T16); plugins still using
863
- * `ctx.registerRoute(...)` from `activate()` continue to work via the
864
- * dispatcher adapter.
865
624
  */
866
625
  routes?: ReadonlyArray<DeclarativeAPIRoute<PluginContextLite, any, any, any>>;
867
626
  }
868
- export interface PluginManifestSignature {
869
- algorithm: 'ed25519';
870
- signer: string;
871
- publicKey: string;
872
- signature: string;
873
- }
874
- export interface SecretDeclaration {
875
- /** Canonical environment variable name, for example `ANTHROPIC_API_KEY`. */
876
- name: string;
877
- /** Human-readable setup note. Never include a secret value here. */
878
- description: string;
879
- /** Missing required secrets should be reported by setup/health checks. Defaults to true. */
880
- required: boolean;
881
- }
882
- export interface PluginManifest {
883
- id: string;
884
- name: string;
885
- version: string;
886
- bakin: string;
887
- description: string;
888
- entry: {
889
- server: string;
890
- client?: string;
891
- };
892
- contentFiles?: string[];
893
- secrets?: SecretDeclaration[];
894
- tests?: string;
895
- dependencies?: string[];
896
- permissions?: string[];
897
- signature?: PluginManifestSignature;
898
- }
899
- export interface PluginEntry {
900
- path: string;
901
- enabled?: boolean;
902
- }
903
- export interface BakinConfig {
904
- plugins: PluginEntry[];
905
- theme?: Record<string, string>;
906
- storage?: {
907
- contentDir?: string;
908
- };
909
- }
910
- export {};
627
+ export type { PluginManifestSignature, SecretDeclaration, PluginManifest, PluginEntry, BakinConfig, } from '@makinbakin/sdk/types';