@makinbakin/sdk 0.0.1-rc.20 → 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 (110) hide show
  1. package/_internal/app/components/agent-select.d.ts +10 -1
  2. package/_internal/app/components/asset-picker.d.ts +25 -0
  3. package/_internal/app/components/charts/bar-chart.d.ts +16 -0
  4. package/_internal/app/components/charts/chart-data-table.d.ts +31 -0
  5. package/_internal/app/components/charts/chart-explainer.d.ts +9 -0
  6. package/_internal/app/components/charts/chart-tooltip.d.ts +8 -0
  7. package/_internal/app/components/charts/line-chart.d.ts +13 -0
  8. package/_internal/app/components/charts/palette.d.ts +24 -0
  9. package/_internal/app/components/charts/sparkline.d.ts +12 -0
  10. package/_internal/app/components/charts/stacked-column-chart.d.ts +40 -0
  11. package/_internal/app/components/confirm-dialog.d.ts +23 -2
  12. package/_internal/app/components/conversation/activity-group.d.ts +15 -0
  13. package/_internal/app/components/conversation/agent-turn.d.ts +36 -0
  14. package/_internal/app/components/conversation/attention.d.ts +56 -0
  15. package/_internal/app/components/conversation/composer.d.ts +35 -0
  16. package/_internal/app/components/conversation/conversation-empty-state.d.ts +8 -0
  17. package/_internal/app/components/conversation/conversation-panel.d.ts +33 -0
  18. package/_internal/app/components/conversation/conversation.d.ts +14 -0
  19. package/_internal/app/components/conversation/fold.d.ts +129 -0
  20. package/_internal/app/components/conversation/notification-sound.d.ts +8 -0
  21. package/_internal/app/components/conversation/relative-time.d.ts +8 -0
  22. package/_internal/app/components/conversation/reply-toast.d.ts +15 -0
  23. package/_internal/app/components/conversation/thread-id.d.ts +8 -0
  24. package/_internal/app/components/conversation/tool-call-drawer.d.ts +7 -0
  25. package/_internal/app/components/conversation/turn-recorder.d.ts +37 -0
  26. package/_internal/app/components/conversation/use-conversation-attention.d.ts +64 -0
  27. package/_internal/app/components/conversation/use-conversation-thread.d.ts +55 -0
  28. package/_internal/app/components/conversation/user-message.d.ts +11 -0
  29. package/_internal/app/components/danger-zone.d.ts +28 -0
  30. package/_internal/app/components/empty-state.d.ts +5 -2
  31. package/_internal/app/components/plugin-header.d.ts +4 -3
  32. package/_internal/app/components/save-bar.d.ts +32 -0
  33. package/_internal/app/components/score-overlay.d.ts +33 -0
  34. package/_internal/app/components/search-degraded-chip.d.ts +4 -0
  35. package/_internal/app/components/search-partial-chip.d.ts +13 -0
  36. package/_internal/app/components/search-unavailable.d.ts +12 -0
  37. package/_internal/app/components/section-card.d.ts +22 -0
  38. package/_internal/app/components/segmented-control.d.ts +28 -0
  39. package/_internal/app/components/stat-tile.d.ts +26 -0
  40. package/_internal/app/components/status-badge.d.ts +19 -0
  41. package/_internal/app/components/turn-output-view.d.ts +57 -0
  42. package/_internal/app/components/ui/button.d.ts +1 -1
  43. package/_internal/app/components/underline-tabs.d.ts +6 -2
  44. package/_internal/app/components/unsaved-changes-guard.d.ts +34 -0
  45. package/_internal/app/core/conversation-turns.d.ts +148 -0
  46. package/_internal/app/core/logger.d.ts +1 -0
  47. package/_internal/app/hooks/use-file-drop.d.ts +25 -0
  48. package/_internal/app/hooks/use-history-back.d.ts +1 -0
  49. package/_internal/app/hooks/use-json-fetch.d.ts +5 -0
  50. package/_internal/app/hooks/use-query-state.d.ts +2 -0
  51. package/_internal/app/hooks/use-schedule.d.ts +45 -0
  52. package/_internal/app/hooks/use-search.d.ts +27 -8
  53. package/_internal/app/hooks/use-toast.d.ts +3 -3
  54. package/_internal/app/lib/browser-notify.d.ts +12 -1
  55. package/_internal/core/adapters/runtime/concepts.d.ts +547 -49
  56. package/_internal/core/adapters/runtime/errors.d.ts +13 -1
  57. package/_internal/core/adapters/runtime/helpers.d.ts +19 -0
  58. package/_internal/core/adapters/runtime/index.d.ts +5 -2
  59. package/_internal/core/adapters/runtime/testing.d.ts +79 -0
  60. package/_internal/core/adapters/runtime/turn-activity.d.ts +23 -0
  61. package/_internal/core/adapters/shared.d.ts +122 -12
  62. package/_internal/core/content-dir.d.ts +8 -0
  63. package/_internal/core/docs/route.d.ts +1 -1
  64. package/_internal/core/format/structured.d.ts +44 -0
  65. package/_internal/core/format.d.ts +5 -1
  66. package/_internal/core/media/downscale.d.ts +18 -0
  67. package/_internal/core/media/sharp-loader.d.ts +36 -0
  68. package/_internal/core/plugin-types.d.ts +102 -39
  69. package/_internal/core/routing/define.d.ts +26 -3
  70. package/_internal/core/routing/dispatcher.d.ts +15 -6
  71. package/_internal/core/routing/index.d.ts +1 -1
  72. package/_internal/core/routing/types.d.ts +13 -70
  73. package/_internal/core/storage/atomic-write.d.ts +11 -0
  74. package/_internal/core/tasks/store.d.ts +129 -0
  75. package/_internal/core/tasks/testing.d.ts +2 -0
  76. package/_internal/{plugins/workflows/lib → core/workflows}/notification-channel-registry.d.ts +1 -1
  77. package/_internal/plugins/team/types.d.ts +47 -0
  78. package/_internal/plugins/workflows/hooks/use-notification-channels.d.ts +1 -1
  79. package/components/index.d.ts +87 -19
  80. package/components/index.js +32904 -15368
  81. package/hooks/index.d.ts +24 -4
  82. package/hooks/index.js +837 -561
  83. package/hooks/router.d.ts +20 -4
  84. package/index.d.ts +5 -50
  85. package/index.js +223 -406
  86. package/internal/index.d.ts +70 -0
  87. package/internal/index.js +409 -0
  88. package/package.json +9 -2
  89. package/register.d.ts +19 -1
  90. package/routing/index.js +175 -147
  91. package/slots/index.js +20 -1
  92. package/testing/index.d.ts +122 -0
  93. package/testing/index.js +21874 -0
  94. package/types/index.d.ts +4 -0
  95. package/types/index.js +16 -0
  96. package/utils/index.d.ts +28 -25
  97. package/utils/index.js +279 -263
  98. package/_internal/app/components/integrated-brainstorm/activity.d.ts +0 -23
  99. package/_internal/app/components/integrated-brainstorm/collapsed-header.d.ts +0 -14
  100. package/_internal/app/components/integrated-brainstorm/empty-state.d.ts +0 -5
  101. package/_internal/app/components/integrated-brainstorm/index.d.ts +0 -8
  102. package/_internal/app/components/integrated-brainstorm/input-row.d.ts +0 -16
  103. package/_internal/app/components/integrated-brainstorm/message-list.d.ts +0 -8
  104. package/_internal/app/components/integrated-brainstorm/session.d.ts +0 -16
  105. package/_internal/app/components/integrated-brainstorm/sse.d.ts +0 -8
  106. package/_internal/app/components/integrated-brainstorm/thinking-indicator.d.ts +0 -19
  107. package/_internal/app/components/integrated-brainstorm/types.d.ts +0 -63
  108. package/_internal/app/components/integrated-brainstorm/use-auto-grow.d.ts +0 -6
  109. package/_internal/app/components/integrated-brainstorm/use-brainstorm-state.d.ts +0 -21
  110. /package/_internal/{plugins/models → app}/hooks/use-available-models.d.ts +0 -0
package/routing/index.js CHANGED
@@ -14,151 +14,6 @@ var __export = (target, all) => {
14
14
  });
15
15
  };
16
16
 
17
- // packages/core/src/routing/define.ts
18
- function defineRoute(route) {
19
- return route;
20
- }
21
- function defineCoreRoute(route) {
22
- return route;
23
- }
24
- function definePlugin(plugin) {
25
- return plugin;
26
- }
27
- // packages/core/src/routing/operation-id.ts
28
- function operationIdFor(scope, method, path) {
29
- return `${scope}.${method.toLowerCase()}.${slugifyPath(path)}`;
30
- }
31
- function slugifyPath(path) {
32
- const trimmed = path.replace(/^\/+/, "").replace(/\/+$/, "");
33
- if (trimmed === "")
34
- return "root";
35
- const segments = trimmed.split("/").map((seg) => {
36
- if (seg.startsWith(":"))
37
- return camelToKebab(seg.slice(1));
38
- if (seg.startsWith("{") && seg.endsWith("}"))
39
- return camelToKebab(seg.slice(1, -1));
40
- return camelToKebab(seg);
41
- }).filter(Boolean);
42
- return segments.join("-");
43
- }
44
- function camelToKebab(input) {
45
- return input.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
46
- }
47
-
48
- // packages/core/src/routing/registry.ts
49
- function parseSegments(path) {
50
- return path.split("/").filter(Boolean).map((seg) => {
51
- if (seg === "*" || seg.startsWith("..."))
52
- return { kind: "wildcard" };
53
- if (seg.startsWith(":"))
54
- return { kind: "param", name: seg.slice(1) };
55
- if (seg.startsWith("{") && seg.endsWith("}")) {
56
- return { kind: "param", name: seg.slice(1, -1) };
57
- }
58
- return { kind: "literal", value: seg };
59
- });
60
- }
61
- function specificityScore(segments) {
62
- let score = 0;
63
- for (const seg of segments) {
64
- if (seg.kind === "literal")
65
- score += 2;
66
- else if (seg.kind === "param")
67
- score += 1;
68
- }
69
- return score;
70
- }
71
- function matchSegments(pathSegments, routeSegments) {
72
- const lastIsWildcard = routeSegments.length > 0 && routeSegments[routeSegments.length - 1].kind === "wildcard";
73
- if (!lastIsWildcard && pathSegments.length !== routeSegments.length)
74
- return null;
75
- if (lastIsWildcard && pathSegments.length < routeSegments.length - 1)
76
- return null;
77
- const params = {};
78
- for (let i = 0;i < routeSegments.length; i++) {
79
- const rseg = routeSegments[i];
80
- if (rseg.kind === "wildcard")
81
- return params;
82
- const pseg = pathSegments[i];
83
- if (rseg.kind === "literal") {
84
- if (rseg.value !== pseg)
85
- return null;
86
- } else {
87
- params[rseg.name] = pseg;
88
- }
89
- }
90
- return params;
91
- }
92
-
93
- class RouteRegistry {
94
- byMethod = new Map;
95
- operationIds = new Set;
96
- fullPaths = new Set;
97
- register(input) {
98
- const { route } = input;
99
- const pluginId = input.scope === "plugin" ? input.pluginId : null;
100
- const fullPath = pluginId !== null ? `/api/plugins/${pluginId}${route.path}` : route.path;
101
- const operationId = route.operationId ?? operationIdFor(pluginId ?? "core", route.method, route.path);
102
- const dupKey = `${route.method} ${fullPath}`;
103
- if (this.fullPaths.has(dupKey)) {
104
- throw new Error(`duplicate route registration: ${dupKey}`);
105
- }
106
- if (this.operationIds.has(operationId)) {
107
- throw new Error(`duplicate operationId: ${operationId} (route: ${dupKey})`);
108
- }
109
- this.fullPaths.add(dupKey);
110
- this.operationIds.add(operationId);
111
- const segments = parseSegments(fullPath);
112
- const indexed = {
113
- registered: {
114
- route,
115
- scope: pluginId ?? "core",
116
- fullPath,
117
- operationId
118
- },
119
- segments,
120
- score: specificityScore(segments)
121
- };
122
- let bucket = this.byMethod.get(route.method);
123
- if (!bucket) {
124
- bucket = [];
125
- this.byMethod.set(route.method, bucket);
126
- }
127
- bucket.push(indexed);
128
- bucket.sort((a, b) => b.score - a.score);
129
- return indexed.registered;
130
- }
131
- match(method, path) {
132
- const bucket = this.byMethod.get(method);
133
- if (!bucket)
134
- return null;
135
- const normalized = path.replace(/\/+$/, "") || "/";
136
- const pathSegments = normalized.split("/").filter(Boolean);
137
- for (const indexed of bucket) {
138
- const params = matchSegments(pathSegments, indexed.segments);
139
- if (params !== null) {
140
- return {
141
- ...indexed.registered,
142
- params
143
- };
144
- }
145
- }
146
- return null;
147
- }
148
- all() {
149
- const out = [];
150
- for (const bucket of this.byMethod.values()) {
151
- for (const entry of bucket)
152
- out.push(entry.registered);
153
- }
154
- return out;
155
- }
156
- clear() {
157
- this.byMethod.clear();
158
- this.operationIds.clear();
159
- this.fullPaths.clear();
160
- }
161
- }
162
17
  // node_modules/.bun/zod@4.3.6/node_modules/zod/v4/classic/external.js
163
18
  var exports_external = {};
164
19
  __export(exports_external, {
@@ -13760,9 +13615,13 @@ function getBakinPaths() {
13760
13615
  inbox: join(home, "inbox"),
13761
13616
  tasks: join(home, "tasks"),
13762
13617
  workflows: join(home, "workflows"),
13618
+ brands: join(home, "brands"),
13619
+ chat: join(home, "chat"),
13763
13620
  settings: join(home, "settings.json"),
13764
13621
  logs: join(home, "logs"),
13765
- db: join(home, "bakin.db")
13622
+ antfly: join(home, "antfly"),
13623
+ db: join(home, "bakin.db"),
13624
+ bin: join(home, "bin")
13766
13625
  };
13767
13626
  }
13768
13627
 
@@ -13934,7 +13793,6 @@ function suppressPrettyInfo(entry) {
13934
13793
  "search-cleanup",
13935
13794
  "search-startup",
13936
13795
  "hot-reload-coordinator",
13937
- "mcporter",
13938
13796
  "dispatch",
13939
13797
  "dispatch-state",
13940
13798
  "dispatch-turns",
@@ -14035,6 +13893,176 @@ function createLogger(module) {
14035
13893
 
14036
13894
  // packages/core/src/routing/dispatcher.ts
14037
13895
  var log = createLogger("dispatcher");
13896
+ var VALID_BODY_CONTENT_TYPES = ["application/json", "multipart/form-data", "*/*", "none"];
13897
+ function assertValidBodySpec(body, label) {
13898
+ if (body === undefined || body === null)
13899
+ return;
13900
+ if (isZodType(body))
13901
+ return;
13902
+ if (typeof body !== "object" || !("contentType" in body)) {
13903
+ throw new Error(`route ${label}: body spec must be a zod schema or declare a contentType (got ${JSON.stringify(body)})`);
13904
+ }
13905
+ const ct = body.contentType;
13906
+ if (!VALID_BODY_CONTENT_TYPES.includes(ct)) {
13907
+ throw new Error(`route ${label}: unknown body contentType '${String(ct)}' \u2014 valid values: ${VALID_BODY_CONTENT_TYPES.join(", ")}`);
13908
+ }
13909
+ if (ct === "application/json" && !isZodType(body.schema)) {
13910
+ throw new Error(`route ${label}: contentType 'application/json' requires a zod schema`);
13911
+ }
13912
+ }
13913
+ function isZodType(value) {
13914
+ if (!value || typeof value !== "object")
13915
+ return false;
13916
+ return value instanceof exports_external.ZodType || typeof value._zod === "object" && value._zod !== null;
13917
+ }
13918
+
13919
+ // packages/core/src/routing/define.ts
13920
+ function defineRoute(route) {
13921
+ assertValidBodySpec(route.body, `${route.method} ${route.path}`);
13922
+ return route;
13923
+ }
13924
+ function defineCoreRoute(route) {
13925
+ assertValidBodySpec(route.body, `${route.method} ${route.path}`);
13926
+ return route;
13927
+ }
13928
+ function definePlugin(plugin) {
13929
+ return plugin;
13930
+ }
13931
+ // packages/core/src/routing/operation-id.ts
13932
+ function operationIdFor(scope, method, path) {
13933
+ return `${scope}.${method.toLowerCase()}.${slugifyPath(path)}`;
13934
+ }
13935
+ function slugifyPath(path) {
13936
+ const trimmed = path.replace(/^\/+/, "").replace(/\/+$/, "");
13937
+ if (trimmed === "")
13938
+ return "root";
13939
+ const segments = trimmed.split("/").map((seg) => {
13940
+ if (seg.startsWith(":"))
13941
+ return camelToKebab(seg.slice(1));
13942
+ if (seg.startsWith("{") && seg.endsWith("}"))
13943
+ return camelToKebab(seg.slice(1, -1));
13944
+ return camelToKebab(seg);
13945
+ }).filter(Boolean);
13946
+ return segments.join("-");
13947
+ }
13948
+ function camelToKebab(input) {
13949
+ return input.replace(/([a-z0-9])([A-Z])/g, "$1-$2").replace(/[^a-zA-Z0-9-]+/g, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase();
13950
+ }
13951
+
13952
+ // packages/core/src/routing/registry.ts
13953
+ function parseSegments(path) {
13954
+ return path.split("/").filter(Boolean).map((seg) => {
13955
+ if (seg === "*" || seg.startsWith("..."))
13956
+ return { kind: "wildcard" };
13957
+ if (seg.startsWith(":"))
13958
+ return { kind: "param", name: seg.slice(1) };
13959
+ if (seg.startsWith("{") && seg.endsWith("}")) {
13960
+ return { kind: "param", name: seg.slice(1, -1) };
13961
+ }
13962
+ return { kind: "literal", value: seg };
13963
+ });
13964
+ }
13965
+ function specificityScore(segments) {
13966
+ let score = 0;
13967
+ for (const seg of segments) {
13968
+ if (seg.kind === "literal")
13969
+ score += 2;
13970
+ else if (seg.kind === "param")
13971
+ score += 1;
13972
+ }
13973
+ return score;
13974
+ }
13975
+ function matchSegments(pathSegments, routeSegments) {
13976
+ const lastIsWildcard = routeSegments.length > 0 && routeSegments[routeSegments.length - 1].kind === "wildcard";
13977
+ if (!lastIsWildcard && pathSegments.length !== routeSegments.length)
13978
+ return null;
13979
+ if (lastIsWildcard && pathSegments.length < routeSegments.length - 1)
13980
+ return null;
13981
+ const params = {};
13982
+ for (let i = 0;i < routeSegments.length; i++) {
13983
+ const rseg = routeSegments[i];
13984
+ if (rseg.kind === "wildcard")
13985
+ return params;
13986
+ const pseg = pathSegments[i];
13987
+ if (rseg.kind === "literal") {
13988
+ if (rseg.value !== pseg)
13989
+ return null;
13990
+ } else {
13991
+ params[rseg.name] = pseg;
13992
+ }
13993
+ }
13994
+ return params;
13995
+ }
13996
+
13997
+ class RouteRegistry {
13998
+ byMethod = new Map;
13999
+ operationIds = new Set;
14000
+ fullPaths = new Set;
14001
+ register(input) {
14002
+ const { route } = input;
14003
+ const pluginId = input.scope === "plugin" ? input.pluginId : null;
14004
+ const fullPath = pluginId !== null ? `/api/plugins/${pluginId}${route.path}` : route.path;
14005
+ const operationId = route.operationId ?? operationIdFor(pluginId ?? "core", route.method, route.path);
14006
+ const dupKey = `${route.method} ${fullPath}`;
14007
+ if (this.fullPaths.has(dupKey)) {
14008
+ throw new Error(`duplicate route registration: ${dupKey}`);
14009
+ }
14010
+ if (this.operationIds.has(operationId)) {
14011
+ throw new Error(`duplicate operationId: ${operationId} (route: ${dupKey})`);
14012
+ }
14013
+ this.fullPaths.add(dupKey);
14014
+ this.operationIds.add(operationId);
14015
+ const segments = parseSegments(fullPath);
14016
+ const indexed = {
14017
+ registered: {
14018
+ route,
14019
+ scope: pluginId ?? "core",
14020
+ fullPath,
14021
+ operationId
14022
+ },
14023
+ segments,
14024
+ score: specificityScore(segments)
14025
+ };
14026
+ let bucket = this.byMethod.get(route.method);
14027
+ if (!bucket) {
14028
+ bucket = [];
14029
+ this.byMethod.set(route.method, bucket);
14030
+ }
14031
+ bucket.push(indexed);
14032
+ bucket.sort((a, b) => b.score - a.score);
14033
+ return indexed.registered;
14034
+ }
14035
+ match(method, path) {
14036
+ const bucket = this.byMethod.get(method);
14037
+ if (!bucket)
14038
+ return null;
14039
+ const normalized = path.replace(/\/+$/, "") || "/";
14040
+ const pathSegments = normalized.split("/").filter(Boolean);
14041
+ for (const indexed of bucket) {
14042
+ const params = matchSegments(pathSegments, indexed.segments);
14043
+ if (params !== null) {
14044
+ return {
14045
+ ...indexed.registered,
14046
+ params
14047
+ };
14048
+ }
14049
+ }
14050
+ return null;
14051
+ }
14052
+ all() {
14053
+ const out = [];
14054
+ for (const bucket of this.byMethod.values()) {
14055
+ for (const entry of bucket)
14056
+ out.push(entry.registered);
14057
+ }
14058
+ return out;
14059
+ }
14060
+ clear() {
14061
+ this.byMethod.clear();
14062
+ this.operationIds.clear();
14063
+ this.fullPaths.clear();
14064
+ }
14065
+ }
14038
14066
  // packages/core/src/routing/search-route.ts
14039
14067
  var searchQuery = exports_external.object({
14040
14068
  q: exports_external.string().min(1),
package/slots/index.js CHANGED
@@ -66,7 +66,10 @@ function getRegistry2() {
66
66
  listeners: new Set,
67
67
  badgesByPlugin: new Map,
68
68
  badgesSnapshot: new Map,
69
- badgeListeners: new Set
69
+ badgeListeners: new Set,
70
+ hitRenderersByPlugin: new Map,
71
+ hitRenderersSnapshot: new Map,
72
+ hitRendererListeners: new Set
70
73
  };
71
74
  }
72
75
  const registry = g.__bakinClientRegistry;
@@ -81,8 +84,24 @@ function getRegistry2() {
81
84
  registry.badgesSnapshot = buildBadgesSnapshot(registry);
82
85
  if (!registry.badgeListeners)
83
86
  registry.badgeListeners = new Set;
87
+ if (!registry.hitRenderersByPlugin)
88
+ registry.hitRenderersByPlugin = new Map;
89
+ if (!registry.hitRenderersSnapshot)
90
+ registry.hitRenderersSnapshot = buildHitRenderersSnapshot(registry);
91
+ if (!registry.hitRendererListeners)
92
+ registry.hitRendererListeners = new Set;
84
93
  return registry;
85
94
  }
95
+ function buildHitRenderersSnapshot(registry) {
96
+ const snapshot = new Map;
97
+ for (const byType of registry.hitRenderersByPlugin.values()) {
98
+ for (const [type, renderer] of byType) {
99
+ if (!snapshot.has(type))
100
+ snapshot.set(type, renderer);
101
+ }
102
+ }
103
+ return snapshot;
104
+ }
86
105
  function buildBadgesSnapshot(registry) {
87
106
  const snapshot = new Map;
88
107
  for (const byNavItemId of registry.badgesByPlugin.values()) {
@@ -0,0 +1,122 @@
1
+ import type { BakinPlugin, ExecToolDefinition, ExecToolResult, HealthCheckRegistrationInput, HealthRepairActionDefinition, NavItem, PluginContext, PluginNodeTypeInput, PluginNotificationChannelInput, PluginToolContext, SearchResponse, SearchResult, SkillDefinition, UISlotRegistration, WorkflowDefinitionInput } from '../types/index';
2
+ import type { APIRoute } from '../routing/index';
3
+ /** One captured `ctx.log` line. */
4
+ export interface CapturedLog {
5
+ level: 'debug' | 'info' | 'warn' | 'error';
6
+ message: string;
7
+ data?: unknown;
8
+ }
9
+ /** One captured `ctx.activity.log` / `ctx.activity.audit` call. */
10
+ export interface CapturedActivity {
11
+ kind: 'log' | 'audit';
12
+ agent: string;
13
+ message: string;
14
+ data?: Record<string, unknown>;
15
+ }
16
+ /**
17
+ * The harness returned by {@link createTestContext} / {@link activatePlugin}.
18
+ * Everything the plugin registered is captured on plain arrays so tests can
19
+ * assert on it directly.
20
+ */
21
+ export interface PluginTestContext {
22
+ /** The isolated context — pass to `callRoute`, or to the plugin directly. */
23
+ ctx: PluginContext;
24
+ /** All routes: declarative `plugin.routes` + the auto-wired search route. */
25
+ routes: APIRoute[];
26
+ /** Exec tools registered via `ctx.registerExecTool`. */
27
+ execTools: ExecToolDefinition[];
28
+ /** Nav items registered via `ctx.registerNav`. */
29
+ navItems: NavItem[];
30
+ /** Slot registrations via `ctx.registerSlot`. */
31
+ slots: UISlotRegistration[];
32
+ /** Workflows registered via `ctx.registerWorkflow`. */
33
+ workflows: WorkflowDefinitionInput[];
34
+ /** Node types registered via `ctx.registerNodeType`. */
35
+ nodeTypes: PluginNodeTypeInput<unknown>[];
36
+ /** Notification channels registered via `ctx.registerNotificationChannel`. */
37
+ notificationChannels: PluginNotificationChannelInput[];
38
+ /** Health checks registered via `ctx.registerHealthCheck`. */
39
+ healthChecks: HealthCheckRegistrationInput[];
40
+ /** Repair actions registered via `ctx.registerHealthRepairAction`. */
41
+ healthRepairActions: HealthRepairActionDefinition[];
42
+ /** Runtime skills registered via `ctx.registerSkill`. */
43
+ skills: SkillDefinition[];
44
+ /** File-watch patterns passed to `ctx.watchFiles`. */
45
+ watchedPatterns: string[];
46
+ /** Everything logged through `ctx.log`. */
47
+ logs: CapturedLog[];
48
+ /** Everything sent to `ctx.activity`. */
49
+ activity: CapturedActivity[];
50
+ /** Absolute path of the temp directory backing `ctx.storage`. */
51
+ dir: string;
52
+ /**
53
+ * Seed `ctx.search.query()` responses. All subsequent queries return these
54
+ * results until re-seeded.
55
+ */
56
+ seedSearchResults(results: SearchResult[], aggregations?: SearchResponse['aggregations']): void;
57
+ /** Build the `PluginToolContext` an exec tool receives as its third arg. */
58
+ toolContext(): PluginToolContext;
59
+ /** Delete the temp directory. Call from `afterAll`. Safe to call twice. */
60
+ dispose(): void;
61
+ }
62
+ export interface CreateTestContextOptions {
63
+ /** Initial `ctx.getSettings()` value. `ctx.updateSettings` patches it. */
64
+ settings?: Record<string, unknown>;
65
+ /**
66
+ * Use this directory instead of a fresh temp dir. The harness will NOT
67
+ * delete a caller-provided directory on `dispose()`.
68
+ */
69
+ dir?: string;
70
+ }
71
+ /**
72
+ * Create an isolated `PluginContext` for `pluginId`.
73
+ *
74
+ * Storage is a real filesystem adapter rooted at a fresh temp directory;
75
+ * events are a real in-process bus; hooks are a local registry (the plugin
76
+ * can invoke its own hooks); runtime/tasks are the SDK mock implementations;
77
+ * search is seedable via `seedSearchResults`. Registration calls are
78
+ * captured, never applied to any global registry.
79
+ */
80
+ export declare function createTestContext(pluginId: string, options?: CreateTestContextOptions): PluginTestContext;
81
+ /**
82
+ * Activate a plugin against a fresh test context. Declarative `plugin.routes`
83
+ * are collected first (as the host does), then `activate(ctx)` runs and its
84
+ * registrations land on the same arrays.
85
+ */
86
+ export declare function activatePlugin(plugin: BakinPlugin, options?: CreateTestContextOptions): Promise<PluginTestContext>;
87
+ /** Find a route by method and declared path (`'GET', '/items/:id'`). */
88
+ export declare function findRoute(routes: APIRoute[], method: string, path: string): APIRoute | undefined;
89
+ /** Find an exec tool by name. */
90
+ export declare function findTool(tools: ExecToolDefinition[], name: string): ExecToolDefinition | undefined;
91
+ /** Build a `Request` the way the host's router would. */
92
+ export declare function makeRequest(path: string, opts?: {
93
+ method?: string;
94
+ body?: unknown;
95
+ searchParams?: Record<string, string>;
96
+ }): Request;
97
+ /**
98
+ * Call a route handler and return `{ status, body, response }`.
99
+ *
100
+ * Routes that declare typed contracts (`params`/`query`/`body`/`responses`)
101
+ * dispatch through the same router the host uses, so schema validation and
102
+ * the `(req, ctx, parsed)` handler signature behave exactly as in
103
+ * production. Path params resolve from `opts.path` (`'/abc-1/move'` binds
104
+ * `:taskId` for a route at `'/:taskId/move'`) or from `opts.searchParams`
105
+ * entries matching placeholder names.
106
+ */
107
+ export declare function callRoute(route: APIRoute, ctx: PluginContext, opts?: {
108
+ path?: string;
109
+ body?: unknown;
110
+ searchParams?: Record<string, string>;
111
+ rawResponse?: boolean;
112
+ }): Promise<{
113
+ status: number;
114
+ body: Record<string, unknown>;
115
+ response: Response;
116
+ }>;
117
+ /**
118
+ * Call an exec tool handler. Pass `toolCtx` (from `harness.toolContext()`)
119
+ * when the tool uses its third argument — scaffold-style tools that persist
120
+ * via `toolCtx.storage` need it.
121
+ */
122
+ export declare function callTool(tool: ExecToolDefinition, params: Record<string, unknown>, agent?: string, toolCtx?: PluginToolContext): Promise<ExecToolResult>;