@spinabot/brigade 1.3.2 → 1.5.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 (238) hide show
  1. package/README.md +74 -11
  2. package/convex/config.d.ts +2 -2
  3. package/convex/extensions.d.ts +2 -2
  4. package/convex/logs.d.ts +2 -2
  5. package/convex/memory.d.ts +7 -7
  6. package/convex/messages.d.ts +4 -4
  7. package/convex/schema.d.ts +17 -17
  8. package/convex/subagents.d.ts +12 -12
  9. package/dist/agents/agent-loop.d.ts +1 -0
  10. package/dist/agents/agent-loop.d.ts.map +1 -1
  11. package/dist/agents/agent-loop.js +1 -1
  12. package/dist/agents/agent-loop.js.map +1 -1
  13. package/dist/agents/channels/access-control/format-allow-from.d.ts +50 -0
  14. package/dist/agents/channels/access-control/format-allow-from.d.ts.map +1 -0
  15. package/dist/agents/channels/access-control/format-allow-from.js +64 -0
  16. package/dist/agents/channels/access-control/format-allow-from.js.map +1 -0
  17. package/dist/agents/channels/access-control/index.d.ts +2 -1
  18. package/dist/agents/channels/access-control/index.d.ts.map +1 -1
  19. package/dist/agents/channels/access-control/index.js +2 -1
  20. package/dist/agents/channels/access-control/index.js.map +1 -1
  21. package/dist/agents/channels/access-control/store.d.ts +15 -0
  22. package/dist/agents/channels/access-control/store.d.ts.map +1 -1
  23. package/dist/agents/channels/access-control/store.js +44 -1
  24. package/dist/agents/channels/access-control/store.js.map +1 -1
  25. package/dist/agents/channels/bundled-channel-metas.d.ts +26 -0
  26. package/dist/agents/channels/bundled-channel-metas.d.ts.map +1 -0
  27. package/dist/agents/channels/bundled-channel-metas.js +44 -0
  28. package/dist/agents/channels/bundled-channel-metas.js.map +1 -0
  29. package/dist/agents/channels/channel-messaging-registry.d.ts +130 -0
  30. package/dist/agents/channels/channel-messaging-registry.d.ts.map +1 -0
  31. package/dist/agents/channels/channel-messaging-registry.js +211 -0
  32. package/dist/agents/channels/channel-messaging-registry.js.map +1 -0
  33. package/dist/agents/channels/channel-meta-registry.d.ts +60 -0
  34. package/dist/agents/channels/channel-meta-registry.d.ts.map +1 -0
  35. package/dist/agents/channels/channel-meta-registry.js +128 -0
  36. package/dist/agents/channels/channel-meta-registry.js.map +1 -0
  37. package/dist/agents/channels/channel-security-registry.d.ts +138 -0
  38. package/dist/agents/channels/channel-security-registry.d.ts.map +1 -0
  39. package/dist/agents/channels/channel-security-registry.js +265 -0
  40. package/dist/agents/channels/channel-security-registry.js.map +1 -0
  41. package/dist/agents/channels/exposure.d.ts +44 -0
  42. package/dist/agents/channels/exposure.d.ts.map +1 -0
  43. package/dist/agents/channels/exposure.js +48 -0
  44. package/dist/agents/channels/exposure.js.map +1 -0
  45. package/dist/agents/channels/general-callback.d.ts +25 -0
  46. package/dist/agents/channels/general-callback.d.ts.map +1 -0
  47. package/dist/agents/channels/general-callback.js +31 -0
  48. package/dist/agents/channels/general-callback.js.map +1 -0
  49. package/dist/agents/channels/inbound-pipeline.d.ts +9 -0
  50. package/dist/agents/channels/inbound-pipeline.d.ts.map +1 -1
  51. package/dist/agents/channels/inbound-pipeline.js +429 -39
  52. package/dist/agents/channels/inbound-pipeline.js.map +1 -1
  53. package/dist/agents/channels/markdown-capability.d.ts +44 -0
  54. package/dist/agents/channels/markdown-capability.d.ts.map +1 -0
  55. package/dist/agents/channels/markdown-capability.js +66 -0
  56. package/dist/agents/channels/markdown-capability.js.map +1 -0
  57. package/dist/agents/channels/sdk.d.ts +170 -10
  58. package/dist/agents/channels/sdk.d.ts.map +1 -1
  59. package/dist/agents/channels/sdk.js +138 -6
  60. package/dist/agents/channels/sdk.js.map +1 -1
  61. package/dist/agents/channels/telegram/account-config.d.ts +41 -0
  62. package/dist/agents/channels/telegram/account-config.d.ts.map +1 -1
  63. package/dist/agents/channels/telegram/account-config.js +79 -0
  64. package/dist/agents/channels/telegram/account-config.js.map +1 -1
  65. package/dist/agents/channels/telegram/adapter.d.ts +6 -0
  66. package/dist/agents/channels/telegram/adapter.d.ts.map +1 -1
  67. package/dist/agents/channels/telegram/adapter.js +185 -6
  68. package/dist/agents/channels/telegram/adapter.js.map +1 -1
  69. package/dist/agents/channels/telegram/allowed-updates.d.ts +14 -5
  70. package/dist/agents/channels/telegram/allowed-updates.d.ts.map +1 -1
  71. package/dist/agents/channels/telegram/allowed-updates.js +8 -4
  72. package/dist/agents/channels/telegram/allowed-updates.js.map +1 -1
  73. package/dist/agents/channels/telegram/connection.d.ts +118 -1
  74. package/dist/agents/channels/telegram/connection.d.ts.map +1 -1
  75. package/dist/agents/channels/telegram/connection.js +380 -8
  76. package/dist/agents/channels/telegram/connection.js.map +1 -1
  77. package/dist/agents/channels/telegram/draft-stream.d.ts +98 -0
  78. package/dist/agents/channels/telegram/draft-stream.d.ts.map +1 -0
  79. package/dist/agents/channels/telegram/draft-stream.js +222 -0
  80. package/dist/agents/channels/telegram/draft-stream.js.map +1 -0
  81. package/dist/agents/channels/telegram/format.d.ts +17 -0
  82. package/dist/agents/channels/telegram/format.d.ts.map +1 -1
  83. package/dist/agents/channels/telegram/format.js +36 -0
  84. package/dist/agents/channels/telegram/format.js.map +1 -1
  85. package/dist/agents/channels/telegram/inbound-extras.d.ts +27 -2
  86. package/dist/agents/channels/telegram/inbound-extras.d.ts.map +1 -1
  87. package/dist/agents/channels/telegram/inbound-extras.js +134 -7
  88. package/dist/agents/channels/telegram/inbound-extras.js.map +1 -1
  89. package/dist/agents/channels/telegram/inline-keyboard.d.ts +36 -0
  90. package/dist/agents/channels/telegram/inline-keyboard.d.ts.map +1 -0
  91. package/dist/agents/channels/telegram/inline-keyboard.js +62 -0
  92. package/dist/agents/channels/telegram/inline-keyboard.js.map +1 -0
  93. package/dist/agents/channels/telegram/media.d.ts +8 -0
  94. package/dist/agents/channels/telegram/media.d.ts.map +1 -1
  95. package/dist/agents/channels/telegram/media.js +30 -2
  96. package/dist/agents/channels/telegram/media.js.map +1 -1
  97. package/dist/agents/channels/telegram/plugin.d.ts.map +1 -1
  98. package/dist/agents/channels/telegram/plugin.js +7 -11
  99. package/dist/agents/channels/telegram/plugin.js.map +1 -1
  100. package/dist/agents/channels/telegram/reasoning-lane.d.ts +41 -0
  101. package/dist/agents/channels/telegram/reasoning-lane.d.ts.map +1 -0
  102. package/dist/agents/channels/telegram/reasoning-lane.js +67 -0
  103. package/dist/agents/channels/telegram/reasoning-lane.js.map +1 -0
  104. package/dist/agents/channels/telegram/socks-dispatcher.d.ts +32 -0
  105. package/dist/agents/channels/telegram/socks-dispatcher.d.ts.map +1 -0
  106. package/dist/agents/channels/telegram/socks-dispatcher.js +97 -0
  107. package/dist/agents/channels/telegram/socks-dispatcher.js.map +1 -0
  108. package/dist/agents/channels/types.adapters.d.ts +137 -4
  109. package/dist/agents/channels/types.adapters.d.ts.map +1 -1
  110. package/dist/agents/channels/types.adapters.js +2 -2
  111. package/dist/agents/channels/types.core.d.ts +26 -2
  112. package/dist/agents/channels/types.core.d.ts.map +1 -1
  113. package/dist/agents/channels/types.plugin.d.ts +25 -7
  114. package/dist/agents/channels/types.plugin.d.ts.map +1 -1
  115. package/dist/agents/channels/types.plugin.js +6 -5
  116. package/dist/agents/channels/types.plugin.js.map +1 -1
  117. package/dist/agents/channels/whatsapp/adapter.d.ts +8 -0
  118. package/dist/agents/channels/whatsapp/adapter.d.ts.map +1 -1
  119. package/dist/agents/channels/whatsapp/adapter.js +7 -4
  120. package/dist/agents/channels/whatsapp/adapter.js.map +1 -1
  121. package/dist/agents/channels/whatsapp/connection.d.ts +24 -2
  122. package/dist/agents/channels/whatsapp/connection.d.ts.map +1 -1
  123. package/dist/agents/channels/whatsapp/connection.js +26 -5
  124. package/dist/agents/channels/whatsapp/connection.js.map +1 -1
  125. package/dist/agents/channels/whatsapp/plugin.d.ts.map +1 -1
  126. package/dist/agents/channels/whatsapp/plugin.js +6 -10
  127. package/dist/agents/channels/whatsapp/plugin.js.map +1 -1
  128. package/dist/agents/extensions/activation-planner.d.ts +125 -0
  129. package/dist/agents/extensions/activation-planner.d.ts.map +1 -0
  130. package/dist/agents/extensions/activation-planner.js +221 -0
  131. package/dist/agents/extensions/activation-planner.js.map +1 -0
  132. package/dist/agents/extensions/diagnose.d.ts +84 -0
  133. package/dist/agents/extensions/diagnose.d.ts.map +1 -0
  134. package/dist/agents/extensions/diagnose.js +123 -0
  135. package/dist/agents/extensions/diagnose.js.map +1 -0
  136. package/dist/agents/extensions/discovery.d.ts +85 -7
  137. package/dist/agents/extensions/discovery.d.ts.map +1 -1
  138. package/dist/agents/extensions/discovery.js +200 -15
  139. package/dist/agents/extensions/discovery.js.map +1 -1
  140. package/dist/agents/extensions/index.d.ts +3 -2
  141. package/dist/agents/extensions/index.d.ts.map +1 -1
  142. package/dist/agents/extensions/index.js +3 -2
  143. package/dist/agents/extensions/index.js.map +1 -1
  144. package/dist/agents/extensions/install-scan.d.ts +63 -0
  145. package/dist/agents/extensions/install-scan.d.ts.map +1 -0
  146. package/dist/agents/extensions/install-scan.js +201 -0
  147. package/dist/agents/extensions/install-scan.js.map +1 -0
  148. package/dist/agents/extensions/install.d.ts +135 -0
  149. package/dist/agents/extensions/install.d.ts.map +1 -0
  150. package/dist/agents/extensions/install.js +414 -0
  151. package/dist/agents/extensions/install.js.map +1 -0
  152. package/dist/agents/extensions/loader.d.ts +13 -2
  153. package/dist/agents/extensions/loader.d.ts.map +1 -1
  154. package/dist/agents/extensions/loader.js +126 -13
  155. package/dist/agents/extensions/loader.js.map +1 -1
  156. package/dist/agents/extensions/registry.d.ts +109 -0
  157. package/dist/agents/extensions/registry.d.ts.map +1 -1
  158. package/dist/agents/extensions/registry.js +172 -0
  159. package/dist/agents/extensions/registry.js.map +1 -1
  160. package/dist/agents/extensions/sdk-alias.d.ts +45 -0
  161. package/dist/agents/extensions/sdk-alias.d.ts.map +1 -0
  162. package/dist/agents/extensions/sdk-alias.js +94 -0
  163. package/dist/agents/extensions/sdk-alias.js.map +1 -0
  164. package/dist/agents/extensions/types.d.ts +166 -1
  165. package/dist/agents/extensions/types.d.ts.map +1 -1
  166. package/dist/agents/extensions/types.js.map +1 -1
  167. package/dist/agents/tools/composio-tool.d.ts +9 -1
  168. package/dist/agents/tools/composio-tool.d.ts.map +1 -1
  169. package/dist/agents/tools/composio-tool.js +68 -4
  170. package/dist/agents/tools/composio-tool.js.map +1 -1
  171. package/dist/agents/tools/message-action-tool.d.ts +6 -1
  172. package/dist/agents/tools/message-action-tool.d.ts.map +1 -1
  173. package/dist/agents/tools/message-action-tool.js +52 -2
  174. package/dist/agents/tools/message-action-tool.js.map +1 -1
  175. package/dist/agents/tools/send-message-tool.d.ts +1 -0
  176. package/dist/agents/tools/send-message-tool.d.ts.map +1 -1
  177. package/dist/agents/tools/send-message-tool.js +56 -1
  178. package/dist/agents/tools/send-message-tool.js.map +1 -1
  179. package/dist/buildstamp.json +1 -1
  180. package/dist/channel-sdk.d.ts +28 -0
  181. package/dist/channel-sdk.d.ts.map +1 -0
  182. package/dist/channel-sdk.js +28 -0
  183. package/dist/channel-sdk.js.map +1 -0
  184. package/dist/cli/commands/channels.d.ts.map +1 -1
  185. package/dist/cli/commands/channels.js +8 -8
  186. package/dist/cli/commands/channels.js.map +1 -1
  187. package/dist/cli/commands/connect.d.ts +8 -11
  188. package/dist/cli/commands/connect.d.ts.map +1 -1
  189. package/dist/cli/commands/connect.js +157 -17
  190. package/dist/cli/commands/connect.js.map +1 -1
  191. package/dist/cli/commands/convex-cmd.d.ts +2 -1
  192. package/dist/cli/commands/convex-cmd.d.ts.map +1 -1
  193. package/dist/cli/commands/convex-cmd.js +79 -6
  194. package/dist/cli/commands/convex-cmd.js.map +1 -1
  195. package/dist/cli/commands/doctor.d.ts.map +1 -1
  196. package/dist/cli/commands/doctor.js +64 -0
  197. package/dist/cli/commands/doctor.js.map +1 -1
  198. package/dist/cli/commands/extensions.d.ts +46 -0
  199. package/dist/cli/commands/extensions.d.ts.map +1 -0
  200. package/dist/cli/commands/extensions.js +578 -0
  201. package/dist/cli/commands/extensions.js.map +1 -0
  202. package/dist/cli/commands/pairing.d.ts.map +1 -1
  203. package/dist/cli/commands/pairing.js +16 -2
  204. package/dist/cli/commands/pairing.js.map +1 -1
  205. package/dist/cli/commands/update.d.ts +17 -0
  206. package/dist/cli/commands/update.d.ts.map +1 -0
  207. package/dist/cli/commands/update.js +104 -0
  208. package/dist/cli/commands/update.js.map +1 -0
  209. package/dist/cli/program/build-program.d.ts.map +1 -1
  210. package/dist/cli/program/build-program.js +114 -1
  211. package/dist/cli/program/build-program.js.map +1 -1
  212. package/dist/config/paths.d.ts +1 -0
  213. package/dist/config/paths.d.ts.map +1 -1
  214. package/dist/config/paths.js +9 -0
  215. package/dist/config/paths.js.map +1 -1
  216. package/dist/core/server.d.ts.map +1 -1
  217. package/dist/core/server.js +134 -2
  218. package/dist/core/server.js.map +1 -1
  219. package/dist/protocol.d.ts +25 -0
  220. package/dist/protocol.d.ts.map +1 -1
  221. package/dist/protocol.js.map +1 -1
  222. package/dist/system-prompt/assembler.d.ts.map +1 -1
  223. package/dist/system-prompt/assembler.js +17 -0
  224. package/dist/system-prompt/assembler.js.map +1 -1
  225. package/dist/system-prompt/identity-defaults.d.ts +28 -0
  226. package/dist/system-prompt/identity-defaults.d.ts.map +1 -1
  227. package/dist/system-prompt/identity-defaults.js +47 -0
  228. package/dist/system-prompt/identity-defaults.js.map +1 -1
  229. package/dist/ui/editor.d.ts.map +1 -1
  230. package/dist/ui/editor.js +1 -0
  231. package/dist/ui/editor.js.map +1 -1
  232. package/dist/version.d.ts +4 -3
  233. package/dist/version.d.ts.map +1 -1
  234. package/dist/version.js +27 -5
  235. package/dist/version.js.map +1 -1
  236. package/package.json +21 -4
  237. package/scripts/build-done.mjs +11 -2
  238. package/scripts/convex-dev.mjs +28 -2
@@ -12,15 +12,27 @@
12
12
  * Activation traceability: EVERY module decision (activated / skipped) emits a
13
13
  * structured log line under the `extensions/loader` subsystem. The reason is a
14
14
  * stable enum (`disabled`/`requiresEnv`/`eligible`/`allowlist`/`configSchema`/
15
- * `registerFailed`) so an operator running `brigade doctor` or scraping the
16
- * JSONL log can answer "why didn't my plugin load" without source-diving.
15
+ * `registerFailed`/`activation-not-triggered`) so an operator running
16
+ * `brigade doctor` or scraping the JSONL log can answer "why didn't my plugin
17
+ * load" without source-diving.
18
+ *
19
+ * Step 5 — manifest-driven LAZY activation. User modules are no longer imported
20
+ * eagerly. The loader lists candidates WITHOUT importing, reads each one's
21
+ * sidecar `brigade.extension.json` manifest, and consults the activation planner
22
+ * (`activation-planner.ts`) against an active-config snapshot. A module whose
23
+ * declared `activation` triggers don't fire is NEVER imported (its top-level
24
+ * never runs) — O(manifest) boot. A module with no sidecar manifest is imported
25
+ * to recover its `manifest` field, then re-planned from the body, so back-compat
26
+ * holds (no manifest / no triggers ⇒ always activate). Skips here log
27
+ * `reason=activation-not-triggered`.
17
28
  */
18
29
  import { Check, Errors } from "typebox/value";
19
30
  import { resolveExtensionsDir } from "../../config/paths.js";
20
31
  import { withTimeout } from "../../core/extension-lifecycle.js";
21
32
  import { createSubsystemLogger } from "../../logging/subsystem-logger.js";
22
- import { discoverUserModules } from "./discovery.js";
23
- import { BrigadeExtensionRegistry } from "./registry.js";
33
+ import { buildActivationSnapshot, planActivation, } from "./activation-planner.js";
34
+ import { importDiscoveredModules, listDiscoveryCandidates, } from "./discovery.js";
35
+ import { BrigadeExtensionRegistry, diffCapabilityIds } from "./registry.js";
24
36
  const log = createSubsystemLogger("extensions/loader");
25
37
  // A module's register() should just record capabilities and return; cap it so a
26
38
  // buggy/hung one can't wedge boot or a turn.
@@ -58,19 +70,69 @@ export async function loadModules(args) {
58
70
  const allow = ext?.allow ?? [];
59
71
  const entries = ext?.entries ?? {};
60
72
  // Bundled first; then user modules (deduped — a bundled id wins).
73
+ //
74
+ // Step 5 — manifest-driven LAZY activation. Instead of importing every user
75
+ // candidate up front (eager, O(modules)), we list candidates WITHOUT
76
+ // importing, read each one's sidecar `brigade.extension.json` manifest, and
77
+ // consult the activation planner against the active-config snapshot. A
78
+ // candidate whose declared activation triggers don't fire is NEVER imported
79
+ // (its top-level never runs) — that's the cold-boot win. A candidate with no
80
+ // sidecar manifest is imported to recover its `manifest` field, then planned
81
+ // again from the body so back-compat is preserved (no manifest / no triggers
82
+ // ⇒ always activate).
61
83
  const bundledIds = new Set(args.modules.map((m) => m.id));
62
84
  const userModules = [];
63
85
  if (!args.noDiscovery) {
64
- const discovered = await discoverUserModules(args.extensionsDir ?? resolveExtensionsDir());
65
- for (const d of discovered) {
66
- if (bundledIds.has(d.module.id)) {
67
- log.warn("user extension shadows a bundled module id ignoring the user one", {
68
- id: d.module.id,
69
- source: d.source,
86
+ // Fold the command names the bundled modules declare in their manifest
87
+ // into the activation snapshot, so a user module gated only on
88
+ // `onCommands:["foo"]` can match when a bundled module contributes `foo`
89
+ // (the built-in channel commands are added by the snapshot itself when a
90
+ // channel is configured).
91
+ const declaredCommands = collectDeclaredCommandNames(args.modules);
92
+ const snapshot = buildActivationSnapshot(config, declaredCommands);
93
+ const candidates = listDiscoveryCandidates(args.extensionsDir ?? resolveExtensionsDir());
94
+ for (const cand of candidates) {
95
+ if (cand.safetyReason) {
96
+ log.warn("rejected user extension — POSIX safety check failed", {
97
+ source: cand.source,
98
+ reason: cand.safetyReason,
70
99
  });
71
100
  continue;
72
101
  }
73
- userModules.push(d);
102
+ // (a) Sidecar present → plan BEFORE importing. A non-triggered module is
103
+ // skipped here and its body never runs (the lazy-activation win).
104
+ if (cand.manifest) {
105
+ const decision = planActivation(cand.manifest, snapshot);
106
+ if (!decision.activate) {
107
+ logSkip(cand.manifest.id, "user", cand.source, "activation-not-triggered", decision.reason ?? "activation triggers did not match active config");
108
+ continue;
109
+ }
110
+ }
111
+ // (b) Import the body (sidecar said activate, or there was no sidecar so
112
+ // we must read the module's own `manifest` field). The sidecar manifest,
113
+ // when present, is authoritative over a body-carried one.
114
+ const discovered = await importDiscoveredModules(cand.source, cand.manifest);
115
+ for (const d of discovered) {
116
+ // (c) No sidecar → re-plan from the body manifest (could carry its own
117
+ // activation triggers). If it doesn't trigger, skip registration —
118
+ // the body did run (no sidecar to gate on), but we still don't
119
+ // register a module the active config doesn't want.
120
+ if (!cand.manifest) {
121
+ const decision = planActivation(d.manifest, snapshot);
122
+ if (!decision.activate) {
123
+ logSkip(d.module.id, "user", d.source, "activation-not-triggered", decision.reason ?? "activation triggers did not match active config");
124
+ continue;
125
+ }
126
+ }
127
+ if (bundledIds.has(d.module.id)) {
128
+ log.warn("user extension shadows a bundled module id — ignoring the user one", {
129
+ id: d.module.id,
130
+ source: d.source,
131
+ });
132
+ continue;
133
+ }
134
+ userModules.push(d);
135
+ }
74
136
  }
75
137
  }
76
138
  const all = [
@@ -87,6 +149,19 @@ export async function loadModules(args) {
87
149
  logSkip(m.id, origin, source, "allowlist", "extensions.allow does not include this id");
88
150
  continue;
89
151
  }
152
+ // `enabledByDefault: false` opt-out — a module (typically a bundled one)
153
+ // can declare it does NOT auto-activate. It stays dormant unless the
154
+ // operator explicitly turns it back on via `extensions.entries[id].enabled
155
+ // = true` or by naming it in a non-empty `extensions.allow`. (An explicit
156
+ // `disabled` already short-circuited above; the allowlist gate above means
157
+ // that if we got here with a non-empty allow list, the id IS listed.)
158
+ if (m.manifest?.enabledByDefault === false) {
159
+ const forcedOn = entries[m.id]?.enabled === true || (allow.length > 0 && allow.includes(m.id));
160
+ if (!forcedOn) {
161
+ logSkip(m.id, origin, source, "enabledByDefault", "manifest enabledByDefault=false and not explicitly enabled (set extensions.entries[id].enabled=true to opt in)");
162
+ continue;
163
+ }
164
+ }
90
165
  if (m.requiresEnv) {
91
166
  const missing = m.requiresEnv.find((v) => !env[v] || env[v]?.trim() === "");
92
167
  if (missing) {
@@ -106,20 +181,56 @@ export async function loadModules(args) {
106
181
  logSkip(m.id, origin, source, "configSchema", `config invalid at ${first?.path ?? "<root>"}: ${first?.message ?? "validation error"}`);
107
182
  continue;
108
183
  }
184
+ // FIX 4 — mark the module discovered (it passed gating) and snapshot the
185
+ // registry's capability ids so we can attribute what THIS module registers.
186
+ registry.markModuleDiscovered(m.id);
187
+ const capsBefore = registry.capabilitySnapshot();
109
188
  try {
110
189
  // Time-box register so a hung module (e.g. a stray network await) can't
111
190
  // wedge boot or the per-turn path. A well-behaved register just records
112
191
  // and resolves instantly.
113
192
  await withTimeout(Promise.resolve(m.register(registry.context({ ...args.meta, moduleConfig }))), REGISTER_TIMEOUT_MS, `module ${m.id} register`);
114
193
  registry.loadedModules.push(m);
115
- log.info("extension activated", { id: m.id, origin, source });
194
+ // FIX 4 — register() succeeded: attribute the newly-registered ids to
195
+ // this module and flip its record to `activated`.
196
+ registry.markModuleActivated(m.id, diffCapabilityIds(capsBefore, registry.capabilitySnapshot()));
197
+ // Per-module activation trace — one line per bundled module. At `info`
198
+ // this floods every short-lived CLI command (channels/pairing/agents all
199
+ // activate the full bundle just to enumerate adapters) and gateway boot.
200
+ // It's diagnostic detail, so it lives at `debug` (surface with --verbose
201
+ // / BRIGADE_LOG_LEVEL=debug). Failures + shadows still log at warn above.
202
+ log.debug("extension activated", { id: m.id, origin, source });
116
203
  }
117
204
  catch (err) {
205
+ // FIX 4 — record the register-phase failure so the CLI can show it live.
206
+ registry.markModuleFailed(m.id, "register");
118
207
  logSkip(m.id, origin, source, "registerFailed", err instanceof Error ? err.message : String(err));
119
208
  }
120
209
  }
121
210
  return registry;
122
211
  }
212
+ /**
213
+ * Collect the command names the given (bundled) modules declare in their
214
+ * manifest's `provides.commands` slot. Used to seed the activation snapshot's
215
+ * `commands` set so an `onCommands` trigger on a USER module can match a command
216
+ * a BUNDLED module provides. Deduped + trimmed; empties dropped.
217
+ *
218
+ * Note: a module's runtime `command()` / `channelCommand()` registrations aren't
219
+ * known until it's imported + registered, so we use the declarative manifest
220
+ * rather than running anything — keeping lazy activation lazy.
221
+ */
222
+ function collectDeclaredCommandNames(modules) {
223
+ const out = new Set();
224
+ for (const m of modules) {
225
+ const provided = m.manifest?.provides?.commands ?? [];
226
+ for (const name of provided) {
227
+ const norm = typeof name === "string" ? name.trim() : "";
228
+ if (norm)
229
+ out.add(norm);
230
+ }
231
+ }
232
+ return [...out];
233
+ }
123
234
  /**
124
235
  * Emit a stable, structured `extension skipped` log line. The shape is
125
236
  * deliberately fixed (`id`/`origin`/`source`/`reason`/`cause`) so a future
@@ -136,7 +247,9 @@ function logSkip(id, origin, source, reason, cause) {
136
247
  log.warn("extension register failed", fields);
137
248
  }
138
249
  else {
139
- log.info("extension skipped", fields);
250
+ // Per-module skip trace — same flood concern as "extension activated".
251
+ // Diagnostic detail → debug (surface with --verbose).
252
+ log.debug("extension skipped", fields);
140
253
  }
141
254
  }
142
255
  //# sourceMappingURL=loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/agents/extensions/loader.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/agents/extensions/loader.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
16
16
  import type { BrigadeConfig } from "../../config/io.js";
17
17
  import type { AnyBrigadeTool } from "../tools/types.js";
18
18
  import { type BrigadeHookName, type HookFireResult } from "./hook-runner.js";
19
+ import type { ChannelMessagingAdapter, ChannelSecurityAdapter } from "../channels/types.adapters.js";
19
20
  import type { BrigadeExtensionContext, ChannelAdapter, ChannelCommand, GatewayMethodHandler, HttpRoute, Integration, MediaGenProvider, ProviderAuthMethodRegistration, Service, SpeechProvider, TranscriptionProvider } from "./types.js";
20
21
  /** Per-load context Brigade supplies to each module's `register(b)`. */
21
22
  export interface RegistryContextMeta {
@@ -26,6 +27,56 @@ export interface RegistryContextMeta {
26
27
  /** This module's validated config block (see `BrigadeExtensionContext.moduleConfig`). */
27
28
  moduleConfig?: unknown;
28
29
  }
30
+ /**
31
+ * Lifecycle state of one module on the live registry (FIX 4 — the durable
32
+ * `PluginRecord` state machine the CLI can read live).
33
+ *
34
+ * - `discovered` — the loader decided to run this module (it passed gating) but
35
+ * `register()` has not completed yet.
36
+ * - `activated` — `register()` completed successfully; `capabilities` lists the
37
+ * capability ids this module contributed (attributed by diffing the registry
38
+ * before/after its `register()`).
39
+ * - `failed` — `register()` threw (or another register-phase step failed);
40
+ * `failurePhase` names where.
41
+ *
42
+ * Unlike the discovery-only `brigade extensions list`, this reflects the
43
+ * REGISTER phase — so an operator can see a module that imported fine but threw
44
+ * while registering, which discovery alone never surfaces.
45
+ */
46
+ export type PluginRecordStatus = "discovered" | "activated" | "failed";
47
+ /** Capability ids a module contributed, grouped by kind (empty arrays omitted-as-[]). */
48
+ export interface PluginCapabilityIds {
49
+ tools: string[];
50
+ hooks: string[];
51
+ commands: string[];
52
+ modelProviders: string[];
53
+ channels: string[];
54
+ channelCommands: string[];
55
+ channelMessagingAdapters: string[];
56
+ channelSecurityAdapters: string[];
57
+ speechProviders: string[];
58
+ transcriptionProviders: string[];
59
+ mediaGenProviders: string[];
60
+ memoryCapabilities: string[];
61
+ contextEngines: string[];
62
+ compactionProviders: string[];
63
+ agentHarnesses: string[];
64
+ webSearchProviders: string[];
65
+ webFetchProviders: string[];
66
+ integrations: string[];
67
+ services: string[];
68
+ httpRoutes: string[];
69
+ gatewayMethods: string[];
70
+ }
71
+ /** A per-module runtime record on the live registry. */
72
+ export interface PluginRecord {
73
+ id: string;
74
+ status: PluginRecordStatus;
75
+ /** When `status === "failed"`, the phase that failed (e.g. `"register"`). */
76
+ failurePhase?: string;
77
+ /** Capability ids this module registered (populated on `activated`). */
78
+ capabilities: PluginCapabilityIds;
79
+ }
29
80
  export declare class BrigadeExtensionRegistry {
30
81
  private readonly toolRegs;
31
82
  private readonly hookRegs;
@@ -34,6 +85,10 @@ export declare class BrigadeExtensionRegistry {
34
85
  private readonly providerAuthMethodRegs;
35
86
  private readonly channelMap;
36
87
  private readonly channelCommandMap;
88
+ /** OUTBOUND messaging adapters declared on a channel slot, keyed by lowercased channel id. */
89
+ private readonly channelMessagingMap;
90
+ /** SUPPLEMENTARY security adapters declared on a channel slot, keyed by lowercased channel id. */
91
+ private readonly channelSecurityMap;
37
92
  private readonly speechMap;
38
93
  private readonly transcriptionMap;
39
94
  private readonly mediaGenMap;
@@ -50,10 +105,56 @@ export declare class BrigadeExtensionRegistry {
50
105
  private readonly gatewayMethodMap;
51
106
  /** Modules that successfully registered — the loader fills this (used for reload). */
52
107
  readonly loadedModules: import("./types.js").BrigadeModule[];
108
+ /**
109
+ * Per-module runtime lifecycle records (FIX 4). The loader populates these as
110
+ * it registers each module: `discovered` before `register()`, then `activated`
111
+ * (with attributed capabilities) or `failed`. Insertion-ordered (Map) so the
112
+ * CLI renders them in load order. Read via `pluginRecord(id)` / `pluginRecords()`.
113
+ */
114
+ private readonly pluginRecordMap;
53
115
  /** Build the recording context a module's `register(b)` writes into. */
54
116
  context(meta: RegistryContextMeta): BrigadeExtensionContext;
117
+ /**
118
+ * Snapshot the FULL set of currently-registered capability ids, grouped by
119
+ * kind. The loader takes one of these BEFORE a module's `register()` and one
120
+ * AFTER, then diffs them to attribute the newly-registered ids to that module
121
+ * (see `diffCapabilityIds`). Pure read.
122
+ */
123
+ capabilitySnapshot(): PluginCapabilityIds;
124
+ /** Record that a module was selected to load (pre-`register()`). */
125
+ markModuleDiscovered(id: string): void;
126
+ /**
127
+ * Record that a module's `register()` succeeded. `capabilities` is the diff of
128
+ * the registry's capability ids across the module's `register()` (what THIS
129
+ * module added), produced by `diffCapabilityIds(before, after)` in the loader.
130
+ */
131
+ markModuleActivated(id: string, capabilities: PluginCapabilityIds): void;
132
+ /** Record that a module failed during a register-phase `phase`. */
133
+ markModuleFailed(id: string, phase: string): void;
134
+ /** Live lifecycle record for one module id, or `undefined` if never seen. */
135
+ pluginRecord(id: string): PluginRecord | undefined;
136
+ /** All live lifecycle records, in load order. */
137
+ pluginRecords(): PluginRecord[];
55
138
  get channels(): ChannelAdapter[];
56
139
  get channelCommands(): ChannelCommand[];
140
+ /**
141
+ * OUTBOUND messaging adapters declared via `b.channelMessaging(id, adapter)`,
142
+ * shaped `{ id, messaging }` so the boot can hand them straight to
143
+ * `syncChannelMessagingAdaptersFromPlugins(...)`. Parallel to `channels`.
144
+ */
145
+ get channelMessagingAdapters(): {
146
+ id: string;
147
+ messaging: ChannelMessagingAdapter;
148
+ }[];
149
+ /**
150
+ * SUPPLEMENTARY security adapters declared via `b.channelSecurity(id, adapter)`,
151
+ * shaped `{ id, security }` so the boot can hand them straight to
152
+ * `syncChannelSecurityAdaptersFromPlugins(...)`. Parallel to `channels`.
153
+ */
154
+ get channelSecurityAdapters(): {
155
+ id: string;
156
+ security: ChannelSecurityAdapter;
157
+ }[];
57
158
  get speechProviders(): SpeechProvider[];
58
159
  get transcriptionProviders(): TranscriptionProvider[];
59
160
  get mediaGenProviders(): MediaGenProvider[];
@@ -181,4 +282,12 @@ export declare class BrigadeExtensionRegistry {
181
282
  sessionKey?: string;
182
283
  }): ExtensionFactory;
183
284
  }
285
+ /**
286
+ * Diff two capability-id snapshots (`before`/`after` a single module's
287
+ * `register()`), returning ONLY the ids the module added. Multiset-aware per
288
+ * kind: if `before` had one `web_search` tool and `after` has two, the new one
289
+ * is attributed. Used by the loader to attribute capabilities to the module that
290
+ * registered them for its `PluginRecord`.
291
+ */
292
+ export declare function diffCapabilityIds(before: PluginCapabilityIds, after: PluginCapabilityIds): PluginCapabilityIds;
184
293
  //# sourceMappingURL=registry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/agents/extensions/registry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../../../src/agents/extensions/registry.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,31 @@
13
13
  * Product registrations dedupe by id (last wins) so re-running modules is safe.
14
14
  */
15
15
  import { createHookRunner } from "./hook-runner.js";
16
+ function emptyCapabilityIds() {
17
+ return {
18
+ tools: [],
19
+ hooks: [],
20
+ commands: [],
21
+ modelProviders: [],
22
+ channels: [],
23
+ channelCommands: [],
24
+ channelMessagingAdapters: [],
25
+ channelSecurityAdapters: [],
26
+ speechProviders: [],
27
+ transcriptionProviders: [],
28
+ mediaGenProviders: [],
29
+ memoryCapabilities: [],
30
+ contextEngines: [],
31
+ compactionProviders: [],
32
+ agentHarnesses: [],
33
+ webSearchProviders: [],
34
+ webFetchProviders: [],
35
+ integrations: [],
36
+ services: [],
37
+ httpRoutes: [],
38
+ gatewayMethods: [],
39
+ };
40
+ }
16
41
  export class BrigadeExtensionRegistry {
17
42
  toolRegs = [];
18
43
  hookRegs = [];
@@ -21,6 +46,10 @@ export class BrigadeExtensionRegistry {
21
46
  providerAuthMethodRegs = [];
22
47
  channelMap = new Map();
23
48
  channelCommandMap = new Map();
49
+ /** OUTBOUND messaging adapters declared on a channel slot, keyed by lowercased channel id. */
50
+ channelMessagingMap = new Map();
51
+ /** SUPPLEMENTARY security adapters declared on a channel slot, keyed by lowercased channel id. */
52
+ channelSecurityMap = new Map();
24
53
  speechMap = new Map();
25
54
  transcriptionMap = new Map();
26
55
  mediaGenMap = new Map();
@@ -37,6 +66,13 @@ export class BrigadeExtensionRegistry {
37
66
  gatewayMethodMap = new Map();
38
67
  /** Modules that successfully registered — the loader fills this (used for reload). */
39
68
  loadedModules = [];
69
+ /**
70
+ * Per-module runtime lifecycle records (FIX 4). The loader populates these as
71
+ * it registers each module: `discovered` before `register()`, then `activated`
72
+ * (with attributed capabilities) or `failed`. Insertion-ordered (Map) so the
73
+ * CLI renders them in load order. Read via `pluginRecord(id)` / `pluginRecords()`.
74
+ */
75
+ pluginRecordMap = new Map();
40
76
  /** Build the recording context a module's `register(b)` writes into. */
41
77
  context(meta) {
42
78
  return {
@@ -87,6 +123,21 @@ export class BrigadeExtensionRegistry {
87
123
  // case-insensitive dispatch (both sides use lowercase).
88
124
  this.channelCommandMap.set(command.name.toLowerCase(), command);
89
125
  },
126
+ channelMessaging: (channelId, adapter) => {
127
+ // Lowercase the key so it agrees with the channel-messaging registry's
128
+ // case-insensitive lookup (which normalizes the same way). A blank id
129
+ // is dropped — the registry would reject it anyway.
130
+ const id = channelId.trim().toLowerCase();
131
+ if (id)
132
+ this.channelMessagingMap.set(id, adapter);
133
+ },
134
+ channelSecurity: (channelId, adapter) => {
135
+ // Lowercase the key so it agrees with the channel-security registry's
136
+ // case-insensitive lookup. A blank id is dropped.
137
+ const id = channelId.trim().toLowerCase();
138
+ if (id)
139
+ this.channelSecurityMap.set(id, adapter);
140
+ },
90
141
  tts: (provider) => {
91
142
  this.speechMap.set(provider.id, provider);
92
143
  },
@@ -133,6 +184,71 @@ export class BrigadeExtensionRegistry {
133
184
  },
134
185
  };
135
186
  }
187
+ /* ── plugin lifecycle records (FIX 4) ── */
188
+ /**
189
+ * Snapshot the FULL set of currently-registered capability ids, grouped by
190
+ * kind. The loader takes one of these BEFORE a module's `register()` and one
191
+ * AFTER, then diffs them to attribute the newly-registered ids to that module
192
+ * (see `diffCapabilityIds`). Pure read.
193
+ */
194
+ capabilitySnapshot() {
195
+ return {
196
+ tools: this.toolRegs
197
+ .map((t) => (t.tool ? t.tool.name : t.factory?.create({ agentId: "", sessionKey: "" }).name))
198
+ .filter((n) => typeof n === "string"),
199
+ hooks: this.hookRegs.map((h) => h.event),
200
+ commands: this.commandRegs.map((c) => c.name),
201
+ modelProviders: this.modelProviderRegs.map((p) => p.name),
202
+ channels: [...this.channelMap.keys()],
203
+ channelCommands: [...this.channelCommandMap.keys()],
204
+ channelMessagingAdapters: [...this.channelMessagingMap.keys()],
205
+ channelSecurityAdapters: [...this.channelSecurityMap.keys()],
206
+ speechProviders: [...this.speechMap.keys()],
207
+ transcriptionProviders: [...this.transcriptionMap.keys()],
208
+ mediaGenProviders: [...this.mediaGenMap.keys()],
209
+ memoryCapabilities: [...this.memoryMap.keys()],
210
+ contextEngines: [...this.contextEngineMap.keys()],
211
+ compactionProviders: [...this.compactionProviderMap.keys()],
212
+ agentHarnesses: [...this.agentHarnessMap.keys()],
213
+ webSearchProviders: [...this.webSearchMap.keys()],
214
+ webFetchProviders: [...this.webFetchMap.keys()],
215
+ integrations: [...this.integrationMap.keys()],
216
+ services: [...this.serviceMap.keys()],
217
+ httpRoutes: [...this.httpRouteMap.keys()],
218
+ gatewayMethods: [...this.gatewayMethodMap.keys()],
219
+ };
220
+ }
221
+ /** Record that a module was selected to load (pre-`register()`). */
222
+ markModuleDiscovered(id) {
223
+ this.pluginRecordMap.set(id, { id, status: "discovered", capabilities: emptyCapabilityIds() });
224
+ }
225
+ /**
226
+ * Record that a module's `register()` succeeded. `capabilities` is the diff of
227
+ * the registry's capability ids across the module's `register()` (what THIS
228
+ * module added), produced by `diffCapabilityIds(before, after)` in the loader.
229
+ */
230
+ markModuleActivated(id, capabilities) {
231
+ this.pluginRecordMap.set(id, { id, status: "activated", capabilities });
232
+ }
233
+ /** Record that a module failed during a register-phase `phase`. */
234
+ markModuleFailed(id, phase) {
235
+ const prev = this.pluginRecordMap.get(id);
236
+ this.pluginRecordMap.set(id, {
237
+ id,
238
+ status: "failed",
239
+ failurePhase: phase,
240
+ capabilities: prev?.capabilities ?? emptyCapabilityIds(),
241
+ });
242
+ }
243
+ /** Live lifecycle record for one module id, or `undefined` if never seen. */
244
+ pluginRecord(id) {
245
+ const r = this.pluginRecordMap.get(id);
246
+ return r ? clonePluginRecord(r) : undefined;
247
+ }
248
+ /** All live lifecycle records, in load order. */
249
+ pluginRecords() {
250
+ return [...this.pluginRecordMap.values()].map(clonePluginRecord);
251
+ }
136
252
  /* ── product-level getters (the gateway consumes these) ── */
137
253
  get channels() {
138
254
  return [...this.channelMap.values()];
@@ -140,6 +256,22 @@ export class BrigadeExtensionRegistry {
140
256
  get channelCommands() {
141
257
  return [...this.channelCommandMap.values()];
142
258
  }
259
+ /**
260
+ * OUTBOUND messaging adapters declared via `b.channelMessaging(id, adapter)`,
261
+ * shaped `{ id, messaging }` so the boot can hand them straight to
262
+ * `syncChannelMessagingAdaptersFromPlugins(...)`. Parallel to `channels`.
263
+ */
264
+ get channelMessagingAdapters() {
265
+ return [...this.channelMessagingMap.entries()].map(([id, messaging]) => ({ id, messaging }));
266
+ }
267
+ /**
268
+ * SUPPLEMENTARY security adapters declared via `b.channelSecurity(id, adapter)`,
269
+ * shaped `{ id, security }` so the boot can hand them straight to
270
+ * `syncChannelSecurityAdaptersFromPlugins(...)`. Parallel to `channels`.
271
+ */
272
+ get channelSecurityAdapters() {
273
+ return [...this.channelSecurityMap.entries()].map(([id, security]) => ({ id, security }));
274
+ }
143
275
  get speechProviders() {
144
276
  return [...this.speechMap.values()];
145
277
  }
@@ -509,4 +641,44 @@ function filterByAllowDeny(candidates, allow, deny) {
509
641
  return true;
510
642
  });
511
643
  }
644
+ /** Deep-ish clone of a PluginRecord so callers can't mutate the registry's copy. */
645
+ function clonePluginRecord(r) {
646
+ const caps = {};
647
+ for (const key of Object.keys(r.capabilities)) {
648
+ caps[key] = [...r.capabilities[key]];
649
+ }
650
+ return {
651
+ id: r.id,
652
+ status: r.status,
653
+ ...(r.failurePhase !== undefined ? { failurePhase: r.failurePhase } : {}),
654
+ capabilities: caps,
655
+ };
656
+ }
657
+ /**
658
+ * Diff two capability-id snapshots (`before`/`after` a single module's
659
+ * `register()`), returning ONLY the ids the module added. Multiset-aware per
660
+ * kind: if `before` had one `web_search` tool and `after` has two, the new one
661
+ * is attributed. Used by the loader to attribute capabilities to the module that
662
+ * registered them for its `PluginRecord`.
663
+ */
664
+ export function diffCapabilityIds(before, after) {
665
+ const out = {};
666
+ for (const key of Object.keys(after)) {
667
+ const beforeCounts = new Map();
668
+ for (const id of before[key])
669
+ beforeCounts.set(id, (beforeCounts.get(id) ?? 0) + 1);
670
+ const added = [];
671
+ for (const id of after[key]) {
672
+ const remaining = beforeCounts.get(id) ?? 0;
673
+ if (remaining > 0) {
674
+ beforeCounts.set(id, remaining - 1); // consumed a pre-existing one
675
+ }
676
+ else {
677
+ added.push(id);
678
+ }
679
+ }
680
+ out[key] = added;
681
+ }
682
+ return out;
683
+ }
512
684
  //# sourceMappingURL=registry.js.map