@spinabot/brigade 1.3.1 → 1.4.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 (231) hide show
  1. package/README.md +54 -10
  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 +178 -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 +108 -1
  74. package/dist/agents/channels/telegram/connection.d.ts.map +1 -1
  75. package/dist/agents/channels/telegram/connection.js +219 -3
  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/inbound-extras.d.ts +10 -1
  82. package/dist/agents/channels/telegram/inbound-extras.d.ts.map +1 -1
  83. package/dist/agents/channels/telegram/inbound-extras.js +66 -0
  84. package/dist/agents/channels/telegram/inbound-extras.js.map +1 -1
  85. package/dist/agents/channels/telegram/inline-keyboard.d.ts +36 -0
  86. package/dist/agents/channels/telegram/inline-keyboard.d.ts.map +1 -0
  87. package/dist/agents/channels/telegram/inline-keyboard.js +62 -0
  88. package/dist/agents/channels/telegram/inline-keyboard.js.map +1 -0
  89. package/dist/agents/channels/telegram/plugin.d.ts.map +1 -1
  90. package/dist/agents/channels/telegram/plugin.js +7 -11
  91. package/dist/agents/channels/telegram/plugin.js.map +1 -1
  92. package/dist/agents/channels/telegram/reasoning-lane.d.ts +41 -0
  93. package/dist/agents/channels/telegram/reasoning-lane.d.ts.map +1 -0
  94. package/dist/agents/channels/telegram/reasoning-lane.js +67 -0
  95. package/dist/agents/channels/telegram/reasoning-lane.js.map +1 -0
  96. package/dist/agents/channels/telegram/socks-dispatcher.d.ts +32 -0
  97. package/dist/agents/channels/telegram/socks-dispatcher.d.ts.map +1 -0
  98. package/dist/agents/channels/telegram/socks-dispatcher.js +97 -0
  99. package/dist/agents/channels/telegram/socks-dispatcher.js.map +1 -0
  100. package/dist/agents/channels/types.adapters.d.ts +137 -4
  101. package/dist/agents/channels/types.adapters.d.ts.map +1 -1
  102. package/dist/agents/channels/types.adapters.js +2 -2
  103. package/dist/agents/channels/types.core.d.ts +26 -2
  104. package/dist/agents/channels/types.core.d.ts.map +1 -1
  105. package/dist/agents/channels/types.plugin.d.ts +25 -7
  106. package/dist/agents/channels/types.plugin.d.ts.map +1 -1
  107. package/dist/agents/channels/types.plugin.js +6 -5
  108. package/dist/agents/channels/types.plugin.js.map +1 -1
  109. package/dist/agents/channels/whatsapp/adapter.d.ts +8 -0
  110. package/dist/agents/channels/whatsapp/adapter.d.ts.map +1 -1
  111. package/dist/agents/channels/whatsapp/adapter.js +7 -4
  112. package/dist/agents/channels/whatsapp/adapter.js.map +1 -1
  113. package/dist/agents/channels/whatsapp/connection.d.ts +24 -2
  114. package/dist/agents/channels/whatsapp/connection.d.ts.map +1 -1
  115. package/dist/agents/channels/whatsapp/connection.js +26 -5
  116. package/dist/agents/channels/whatsapp/connection.js.map +1 -1
  117. package/dist/agents/channels/whatsapp/plugin.d.ts.map +1 -1
  118. package/dist/agents/channels/whatsapp/plugin.js +6 -10
  119. package/dist/agents/channels/whatsapp/plugin.js.map +1 -1
  120. package/dist/agents/extensions/activation-planner.d.ts +125 -0
  121. package/dist/agents/extensions/activation-planner.d.ts.map +1 -0
  122. package/dist/agents/extensions/activation-planner.js +221 -0
  123. package/dist/agents/extensions/activation-planner.js.map +1 -0
  124. package/dist/agents/extensions/diagnose.d.ts +84 -0
  125. package/dist/agents/extensions/diagnose.d.ts.map +1 -0
  126. package/dist/agents/extensions/diagnose.js +123 -0
  127. package/dist/agents/extensions/diagnose.js.map +1 -0
  128. package/dist/agents/extensions/discovery.d.ts +85 -7
  129. package/dist/agents/extensions/discovery.d.ts.map +1 -1
  130. package/dist/agents/extensions/discovery.js +200 -15
  131. package/dist/agents/extensions/discovery.js.map +1 -1
  132. package/dist/agents/extensions/index.d.ts +3 -2
  133. package/dist/agents/extensions/index.d.ts.map +1 -1
  134. package/dist/agents/extensions/index.js +3 -2
  135. package/dist/agents/extensions/index.js.map +1 -1
  136. package/dist/agents/extensions/install-scan.d.ts +63 -0
  137. package/dist/agents/extensions/install-scan.d.ts.map +1 -0
  138. package/dist/agents/extensions/install-scan.js +201 -0
  139. package/dist/agents/extensions/install-scan.js.map +1 -0
  140. package/dist/agents/extensions/install.d.ts +135 -0
  141. package/dist/agents/extensions/install.d.ts.map +1 -0
  142. package/dist/agents/extensions/install.js +414 -0
  143. package/dist/agents/extensions/install.js.map +1 -0
  144. package/dist/agents/extensions/loader.d.ts +13 -2
  145. package/dist/agents/extensions/loader.d.ts.map +1 -1
  146. package/dist/agents/extensions/loader.js +126 -13
  147. package/dist/agents/extensions/loader.js.map +1 -1
  148. package/dist/agents/extensions/registry.d.ts +109 -0
  149. package/dist/agents/extensions/registry.d.ts.map +1 -1
  150. package/dist/agents/extensions/registry.js +172 -0
  151. package/dist/agents/extensions/registry.js.map +1 -1
  152. package/dist/agents/extensions/sdk-alias.d.ts +45 -0
  153. package/dist/agents/extensions/sdk-alias.d.ts.map +1 -0
  154. package/dist/agents/extensions/sdk-alias.js +94 -0
  155. package/dist/agents/extensions/sdk-alias.js.map +1 -0
  156. package/dist/agents/extensions/types.d.ts +155 -1
  157. package/dist/agents/extensions/types.d.ts.map +1 -1
  158. package/dist/agents/extensions/types.js.map +1 -1
  159. package/dist/agents/tools/composio-tool.d.ts +9 -1
  160. package/dist/agents/tools/composio-tool.d.ts.map +1 -1
  161. package/dist/agents/tools/composio-tool.js +68 -4
  162. package/dist/agents/tools/composio-tool.js.map +1 -1
  163. package/dist/agents/tools/message-action-tool.d.ts +6 -1
  164. package/dist/agents/tools/message-action-tool.d.ts.map +1 -1
  165. package/dist/agents/tools/message-action-tool.js +52 -2
  166. package/dist/agents/tools/message-action-tool.js.map +1 -1
  167. package/dist/agents/tools/send-message-tool.d.ts +1 -0
  168. package/dist/agents/tools/send-message-tool.d.ts.map +1 -1
  169. package/dist/agents/tools/send-message-tool.js +56 -1
  170. package/dist/agents/tools/send-message-tool.js.map +1 -1
  171. package/dist/buildstamp.json +1 -1
  172. package/dist/channel-sdk.d.ts +28 -0
  173. package/dist/channel-sdk.d.ts.map +1 -0
  174. package/dist/channel-sdk.js +28 -0
  175. package/dist/channel-sdk.js.map +1 -0
  176. package/dist/cli/commands/channels.d.ts.map +1 -1
  177. package/dist/cli/commands/channels.js +8 -8
  178. package/dist/cli/commands/channels.js.map +1 -1
  179. package/dist/cli/commands/connect.d.ts +8 -11
  180. package/dist/cli/commands/connect.d.ts.map +1 -1
  181. package/dist/cli/commands/connect.js +157 -17
  182. package/dist/cli/commands/connect.js.map +1 -1
  183. package/dist/cli/commands/doctor.d.ts.map +1 -1
  184. package/dist/cli/commands/doctor.js +64 -0
  185. package/dist/cli/commands/doctor.js.map +1 -1
  186. package/dist/cli/commands/extensions.d.ts +46 -0
  187. package/dist/cli/commands/extensions.d.ts.map +1 -0
  188. package/dist/cli/commands/extensions.js +578 -0
  189. package/dist/cli/commands/extensions.js.map +1 -0
  190. package/dist/cli/commands/gateway.d.ts.map +1 -1
  191. package/dist/cli/commands/gateway.js +6 -0
  192. package/dist/cli/commands/gateway.js.map +1 -1
  193. package/dist/cli/commands/pairing.d.ts.map +1 -1
  194. package/dist/cli/commands/pairing.js +16 -2
  195. package/dist/cli/commands/pairing.js.map +1 -1
  196. package/dist/cli/commands/update.d.ts +17 -0
  197. package/dist/cli/commands/update.d.ts.map +1 -0
  198. package/dist/cli/commands/update.js +104 -0
  199. package/dist/cli/commands/update.js.map +1 -0
  200. package/dist/cli/program/build-program.d.ts.map +1 -1
  201. package/dist/cli/program/build-program.js +113 -0
  202. package/dist/cli/program/build-program.js.map +1 -1
  203. package/dist/config/paths.d.ts +1 -0
  204. package/dist/config/paths.d.ts.map +1 -1
  205. package/dist/config/paths.js +9 -0
  206. package/dist/config/paths.js.map +1 -1
  207. package/dist/core/gateway-probe.d.ts.map +1 -1
  208. package/dist/core/gateway-probe.js +9 -1
  209. package/dist/core/gateway-probe.js.map +1 -1
  210. package/dist/core/server.d.ts.map +1 -1
  211. package/dist/core/server.js +134 -2
  212. package/dist/core/server.js.map +1 -1
  213. package/dist/protocol.d.ts +25 -0
  214. package/dist/protocol.d.ts.map +1 -1
  215. package/dist/protocol.js.map +1 -1
  216. package/dist/system-prompt/assembler.d.ts.map +1 -1
  217. package/dist/system-prompt/assembler.js +17 -0
  218. package/dist/system-prompt/assembler.js.map +1 -1
  219. package/dist/system-prompt/identity-defaults.d.ts +28 -0
  220. package/dist/system-prompt/identity-defaults.d.ts.map +1 -1
  221. package/dist/system-prompt/identity-defaults.js +47 -0
  222. package/dist/system-prompt/identity-defaults.js.map +1 -1
  223. package/dist/ui/editor.d.ts.map +1 -1
  224. package/dist/ui/editor.js +1 -0
  225. package/dist/ui/editor.js.map +1 -1
  226. package/dist/version.d.ts +4 -3
  227. package/dist/version.d.ts.map +1 -1
  228. package/dist/version.js +27 -5
  229. package/dist/version.js.map +1 -1
  230. package/package.json +21 -4
  231. package/scripts/build-done.mjs +11 -2
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Extension install / remove engine — the source-agnostic machinery behind
3
+ * `brigade extensions add <source>` and `brigade extensions remove <id>`.
4
+ *
5
+ * `add` brings a third-party module into `~/.brigade/extensions/<id>/` from one
6
+ * of three source forms:
7
+ * • a LOCAL PATH (a folder or a single file) → copied in;
8
+ * • an NPM SPEC (`name`, `name@version`, `@scope/name@1.2.3`) → fetched with
9
+ * `npm pack` into a temp dir, unpacked, and moved in (npm only — never pnpm);
10
+ * • a GIT URL (`https://…/repo.git`, `git@…`, `git+…`) → cloned in.
11
+ *
12
+ * The installed module's id is resolved from its `brigade.extension.json`
13
+ * manifest id, else its `package.json` name, else the source basename. An
14
+ * existing id is refused unless `force` is set.
15
+ *
16
+ * After the files land, two read-only gates run:
17
+ * 1. COMPAT — read the installed manifest and compare `minBrigadeVersion` /
18
+ * `pluginApi` against the running build. A module that needs a NEWER
19
+ * Brigade is refused (the only hard failure here); a missing field is
20
+ * lenient (compatible).
21
+ * 2. SCAN — `install-scan.ts` does a static dual-use pattern sweep. Findings
22
+ * are SURFACED, never auto-blocking; the CLI asks the operator to ack.
23
+ *
24
+ * This module does the filesystem + compat work and RETURNS a structured result;
25
+ * the CLI layer (`commands/extensions.ts`) owns all rendering + the interactive
26
+ * scan acknowledgement. Keeping the two apart lets the install logic be unit-
27
+ * tested against a tempdir source with no TTY + no network.
28
+ */
29
+ import { type ScanReport } from "./install-scan.js";
30
+ import type { BrigadeModuleManifest } from "./types.js";
31
+ /** Which kind of source `add` resolved the argument to. */
32
+ export type InstallSourceKind = "local" | "npm" | "git";
33
+ /** Verdict from the compat (version) gate. */
34
+ export interface CompatVerdict {
35
+ /** True when the module is safe to run on this Brigade build. */
36
+ compatible: boolean;
37
+ /** Running Brigade version (for display). */
38
+ brigadeVersion: string;
39
+ /** The module's declared minimum Brigade version, when it set one. */
40
+ minBrigadeVersion?: string;
41
+ /** The module's declared plugin-API generation, when it set one. */
42
+ pluginApi?: string;
43
+ /** One operator-facing line — why it's (in)compatible. */
44
+ reason: string;
45
+ }
46
+ /** Everything the CLI needs to render a completed install. */
47
+ export interface InstallResult {
48
+ /** Resolved extension id (the folder name under the extensions dir). */
49
+ id: string;
50
+ /** Absolute folder the module landed in. */
51
+ dir: string;
52
+ /** How the source argument was classified. */
53
+ sourceKind: InstallSourceKind;
54
+ /** The original source argument, echoed back. */
55
+ source: string;
56
+ /** Installed manifest, when the module shipped a sidecar. */
57
+ manifest?: BrigadeModuleManifest;
58
+ /** Compat (version) verdict. */
59
+ compat: CompatVerdict;
60
+ /** Static security-scan report. */
61
+ scan: ScanReport;
62
+ /** True when `--force` overwrote a pre-existing extension of the same id. */
63
+ replacedExisting: boolean;
64
+ }
65
+ /** A thrown install failure carrying an operator-facing message. */
66
+ export declare class InstallError extends Error {
67
+ }
68
+ /**
69
+ * The plugin-API generation THIS Brigade build implements. Bumped only on a
70
+ * breaking change to the module/SDK contract. A module whose manifest
71
+ * `pluginApi` is a higher integer than this targets a future Brigade and is
72
+ * refused by the compat gate.
73
+ */
74
+ export declare const CURRENT_PLUGIN_API = 1;
75
+ /**
76
+ * Classify the source argument. A path that exists on disk is always `local`
77
+ * (so a folder literally named like a package still installs from disk); then
78
+ * git URLs; then everything else is treated as an npm spec.
79
+ */
80
+ export declare function classifySource(source: string): InstallSourceKind;
81
+ /**
82
+ * Normalise an arbitrary string into a safe extensions-folder id: lowercase,
83
+ * `[a-z0-9-]`, no leading digit-only weirdness. Mirrors the `init` id rules
84
+ * loosely (we accept what we can sanitise rather than reject).
85
+ */
86
+ export declare function sanitizeId(raw: string): string;
87
+ /**
88
+ * Resolve the target id for an extracted/staged module: manifest id wins, then
89
+ * package.json name, then the supplied `fallback` (source basename). All run
90
+ * through `sanitizeId`.
91
+ */
92
+ export declare function resolveModuleId(stagedDir: string, fallback: string): string;
93
+ /**
94
+ * Decide whether a module (by its manifest) is compatible with the running
95
+ * Brigade. Lenient by design: a module that declares neither field is always
96
+ * compatible. The two hard-fail cases are forward-incompatibility — the module
97
+ * needs a NEWER Brigade than this build, or targets a NEWER plugin-API
98
+ * generation than this build implements.
99
+ *
100
+ * `brigadeVersionOverride` / `pluginApiOverride` are test seams.
101
+ */
102
+ export declare function checkCompat(manifest: BrigadeModuleManifest | undefined, brigadeVersionOverride?: string, pluginApiOverride?: number): CompatVerdict;
103
+ export interface InstallOptions {
104
+ /** The extensions dir to install into (`~/.brigade/extensions` in prod). */
105
+ extensionsDir: string;
106
+ /** Overwrite an existing extension of the same id. */
107
+ force?: boolean;
108
+ /** Test seam — override the running Brigade version for the compat gate. */
109
+ brigadeVersionOverride?: string;
110
+ /** Test seam — override the plugin-API generation for the compat gate. */
111
+ pluginApiOverride?: number;
112
+ }
113
+ /**
114
+ * Install an extension from a source. Does NOT prompt — it stages, resolves the
115
+ * id, refuses an existing id unless `force`, copies the module into place, then
116
+ * runs the compat + scan gates and returns the structured result. The CLI layer
117
+ * decides whether to keep it (e.g. after the operator acks the scan). The
118
+ * compat gate is the one hard failure: a forward-incompatible module is
119
+ * REMOVED again and an `InstallError` is thrown.
120
+ */
121
+ export declare function installExtension(source: string, opts: InstallOptions): Promise<InstallResult>;
122
+ /** Outcome of a remove. */
123
+ export interface RemoveResult {
124
+ id: string;
125
+ dir: string;
126
+ }
127
+ /**
128
+ * Remove an installed extension by id. Refuses cleanly (throws `InstallError`)
129
+ * when no extension of that id is installed. `id` is sanitised the same way
130
+ * install resolves it, so `remove My-Plugin` matches the `my-plugin` folder.
131
+ */
132
+ export declare function removeExtension(id: string, extensionsDir: string): RemoveResult;
133
+ /** List installed extension ids (folder names) under the extensions dir. */
134
+ export declare function listInstalledIds(extensionsDir: string): string[];
135
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.d.ts","sourceRoot":"","sources":["../../../src/agents/extensions/install.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAiBH,OAAO,EAAuB,KAAK,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACzE,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAIxD,2DAA2D;AAC3D,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,CAAC;AAExD,8CAA8C;AAC9C,MAAM,WAAW,aAAa;IAC7B,iEAAiE;IACjE,UAAU,EAAE,OAAO,CAAC;IACpB,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,oEAAoE;IACpE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,MAAM,EAAE,MAAM,CAAC;CACf;AAED,8DAA8D;AAC9D,MAAM,WAAW,aAAa;IAC7B,wEAAwE;IACxE,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,GAAG,EAAE,MAAM,CAAC;IACZ,8CAA8C;IAC9C,UAAU,EAAE,iBAAiB,CAAC;IAC9B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,gCAAgC;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,mCAAmC;IACnC,IAAI,EAAE,UAAU,CAAC;IACjB,6EAA6E;IAC7E,gBAAgB,EAAE,OAAO,CAAC;CAC1B;AAED,oEAAoE;AACpE,qBAAa,YAAa,SAAQ,KAAK;CAAG;AAI1C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,IAAI,CAAC;AAcpC;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,iBAAiB,CAchE;AAqDD;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAQ9C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc3E;AAqBD;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAC1B,QAAQ,EAAE,qBAAqB,GAAG,SAAS,EAC3C,sBAAsB,CAAC,EAAE,MAAM,EAC/B,iBAAiB,CAAC,EAAE,MAAM,GACxB,aAAa,CA2Cf;AAiFD,MAAM,WAAW,cAAc;IAC9B,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,sDAAsD;IACtD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,4EAA4E;IAC5E,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,0EAA0E;IAC1E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAyDnG;AAED,2BAA2B;AAC3B,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;CACZ;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,YAAY,CAe/E;AAED,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,EAAE,CAehE"}
@@ -0,0 +1,414 @@
1
+ /**
2
+ * Extension install / remove engine — the source-agnostic machinery behind
3
+ * `brigade extensions add <source>` and `brigade extensions remove <id>`.
4
+ *
5
+ * `add` brings a third-party module into `~/.brigade/extensions/<id>/` from one
6
+ * of three source forms:
7
+ * • a LOCAL PATH (a folder or a single file) → copied in;
8
+ * • an NPM SPEC (`name`, `name@version`, `@scope/name@1.2.3`) → fetched with
9
+ * `npm pack` into a temp dir, unpacked, and moved in (npm only — never pnpm);
10
+ * • a GIT URL (`https://…/repo.git`, `git@…`, `git+…`) → cloned in.
11
+ *
12
+ * The installed module's id is resolved from its `brigade.extension.json`
13
+ * manifest id, else its `package.json` name, else the source basename. An
14
+ * existing id is refused unless `force` is set.
15
+ *
16
+ * After the files land, two read-only gates run:
17
+ * 1. COMPAT — read the installed manifest and compare `minBrigadeVersion` /
18
+ * `pluginApi` against the running build. A module that needs a NEWER
19
+ * Brigade is refused (the only hard failure here); a missing field is
20
+ * lenient (compatible).
21
+ * 2. SCAN — `install-scan.ts` does a static dual-use pattern sweep. Findings
22
+ * are SURFACED, never auto-blocking; the CLI asks the operator to ack.
23
+ *
24
+ * This module does the filesystem + compat work and RETURNS a structured result;
25
+ * the CLI layer (`commands/extensions.ts`) owns all rendering + the interactive
26
+ * scan acknowledgement. Keeping the two apart lets the install logic be unit-
27
+ * tested against a tempdir source with no TTY + no network.
28
+ */
29
+ import { execFileSync } from "node:child_process";
30
+ import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, } from "node:fs";
31
+ import { tmpdir } from "node:os";
32
+ import path from "node:path";
33
+ import { getBuildInfo } from "../../version.js";
34
+ import { scanInstalledModule } from "./install-scan.js";
35
+ const SIDECAR_BASENAME = "brigade.extension.json";
36
+ /** A thrown install failure carrying an operator-facing message. */
37
+ export class InstallError extends Error {
38
+ }
39
+ /* ─────────────────────────── plugin-API generation ─────────────────────────── */
40
+ /**
41
+ * The plugin-API generation THIS Brigade build implements. Bumped only on a
42
+ * breaking change to the module/SDK contract. A module whose manifest
43
+ * `pluginApi` is a higher integer than this targets a future Brigade and is
44
+ * refused by the compat gate.
45
+ */
46
+ export const CURRENT_PLUGIN_API = 1;
47
+ /* ─────────────────────────── source classification ─────────────────────────── */
48
+ /** Does the argument look like a git URL we should clone? */
49
+ function isGitUrl(source) {
50
+ return (/^git\+/.test(source) ||
51
+ /^git@/.test(source) ||
52
+ /^(?:https?|git|ssh):\/\/.*\.git(?:#.*)?$/.test(source) ||
53
+ /^(?:https?:\/\/)?(?:www\.)?(?:github|gitlab|bitbucket)\.com\/[^/]+\/[^/]+/.test(source));
54
+ }
55
+ /**
56
+ * Classify the source argument. A path that exists on disk is always `local`
57
+ * (so a folder literally named like a package still installs from disk); then
58
+ * git URLs; then everything else is treated as an npm spec.
59
+ */
60
+ export function classifySource(source) {
61
+ const trimmed = source.trim();
62
+ if (trimmed.length === 0)
63
+ throw new InstallError("No source given. Pass a folder, a file, an npm package, or a git URL.");
64
+ // An on-disk path always wins — unambiguous + offline.
65
+ try {
66
+ if (existsSync(trimmed))
67
+ return "local";
68
+ }
69
+ catch {
70
+ /* fall through to remote classification */
71
+ }
72
+ // Explicit relative/absolute path markers that don't (yet) exist → still local
73
+ // (the install step then reports "no such file" clearly rather than trying npm).
74
+ if (/^[.~]/.test(trimmed) || path.isAbsolute(trimmed))
75
+ return "local";
76
+ if (isGitUrl(trimmed))
77
+ return "git";
78
+ return "npm";
79
+ }
80
+ /* ─────────────────────────── manifest + id resolution ─────────────────────────── */
81
+ /** Read + parse a JSON file, returning `undefined` on any failure. */
82
+ function readJson(file) {
83
+ try {
84
+ const parsed = JSON.parse(readFileSync(file, "utf8"));
85
+ return parsed && typeof parsed === "object" ? parsed : undefined;
86
+ }
87
+ catch {
88
+ return undefined;
89
+ }
90
+ }
91
+ /** Find + read the sidecar manifest at the root of an installed/extracted module. */
92
+ function readManifestAt(dir) {
93
+ const sidecar = path.join(dir, SIDECAR_BASENAME);
94
+ const parsed = readJson(sidecar);
95
+ if (parsed && typeof parsed.id === "string")
96
+ return parsed;
97
+ return undefined;
98
+ }
99
+ /** Read a `package.json` `name` at the root of a module, when present. */
100
+ function readPackageName(dir) {
101
+ const parsed = readJson(path.join(dir, "package.json"));
102
+ const name = parsed?.name;
103
+ return typeof name === "string" && name.length > 0 ? name : undefined;
104
+ }
105
+ /** Strip an npm scope + version range to a bare, folder-safe id. */
106
+ function bareNameFromSpec(spec) {
107
+ // `@scope/name@1.2.3` → `name`; `name@^2` → `name`; `name` → `name`.
108
+ let s = spec.trim();
109
+ // Drop a trailing version range (the LAST `@` that isn't the scope `@`).
110
+ const at = s.lastIndexOf("@");
111
+ if (at > 0)
112
+ s = s.slice(0, at);
113
+ // Drop the scope prefix.
114
+ if (s.startsWith("@")) {
115
+ const slash = s.indexOf("/");
116
+ if (slash >= 0)
117
+ s = s.slice(slash + 1);
118
+ }
119
+ return s;
120
+ }
121
+ /** Strip a git URL down to its repo basename (sans `.git` + fragment). */
122
+ function repoNameFromGit(url) {
123
+ let s = url.trim().replace(/^git\+/, "");
124
+ s = s.split("#")[0] ?? s; // drop a `#branch` fragment
125
+ s = s.replace(/\/+$/, ""); // trailing slashes
126
+ const last = s.split(/[/:]/).pop() ?? s;
127
+ return last.replace(/\.git$/i, "");
128
+ }
129
+ /**
130
+ * Normalise an arbitrary string into a safe extensions-folder id: lowercase,
131
+ * `[a-z0-9-]`, no leading digit-only weirdness. Mirrors the `init` id rules
132
+ * loosely (we accept what we can sanitise rather than reject).
133
+ */
134
+ export function sanitizeId(raw) {
135
+ const cleaned = raw
136
+ .trim()
137
+ .toLowerCase()
138
+ .replace(/[^a-z0-9-]+/g, "-")
139
+ .replace(/-+/g, "-")
140
+ .replace(/^-+|-+$/g, "");
141
+ return cleaned;
142
+ }
143
+ /**
144
+ * Resolve the target id for an extracted/staged module: manifest id wins, then
145
+ * package.json name, then the supplied `fallback` (source basename). All run
146
+ * through `sanitizeId`.
147
+ */
148
+ export function resolveModuleId(stagedDir, fallback) {
149
+ const manifest = readManifestAt(stagedDir);
150
+ if (manifest?.id) {
151
+ const id = sanitizeId(manifest.id);
152
+ if (id)
153
+ return id;
154
+ }
155
+ const pkgName = readPackageName(stagedDir);
156
+ if (pkgName) {
157
+ const id = sanitizeId(bareNameFromSpec(pkgName));
158
+ if (id)
159
+ return id;
160
+ }
161
+ const id = sanitizeId(fallback);
162
+ if (id)
163
+ return id;
164
+ throw new InstallError("Couldn't work out a name for this extension. Give it one by adding a brigade.extension.json with an \"id\".");
165
+ }
166
+ /* ─────────────────────────── compat (version) gate ─────────────────────────── */
167
+ /** Parse a leading `major.minor.patch` from a version string → numeric tuple. */
168
+ function parseSemverLead(v) {
169
+ const m = /^\s*v?(\d+)(?:\.(\d+))?(?:\.(\d+))?/.exec(v);
170
+ if (!m)
171
+ return null;
172
+ return [Number(m[1] ?? 0), Number(m[2] ?? 0), Number(m[3] ?? 0)];
173
+ }
174
+ /** Compare two semver leads: -1 / 0 / 1. */
175
+ function compareSemver(a, b) {
176
+ for (let i = 0; i < 3; i++) {
177
+ const av = a[i] ?? 0;
178
+ const bv = b[i] ?? 0;
179
+ if (av !== bv)
180
+ return av < bv ? -1 : 1;
181
+ }
182
+ return 0;
183
+ }
184
+ /**
185
+ * Decide whether a module (by its manifest) is compatible with the running
186
+ * Brigade. Lenient by design: a module that declares neither field is always
187
+ * compatible. The two hard-fail cases are forward-incompatibility — the module
188
+ * needs a NEWER Brigade than this build, or targets a NEWER plugin-API
189
+ * generation than this build implements.
190
+ *
191
+ * `brigadeVersionOverride` / `pluginApiOverride` are test seams.
192
+ */
193
+ export function checkCompat(manifest, brigadeVersionOverride, pluginApiOverride) {
194
+ const brigadeVersion = brigadeVersionOverride ?? getBuildInfo().version;
195
+ const currentApi = pluginApiOverride ?? CURRENT_PLUGIN_API;
196
+ const minBrigadeVersion = manifest?.minBrigadeVersion;
197
+ const pluginApi = manifest?.pluginApi;
198
+ // (1) plugin-API generation — a forward-incompatible module targets a newer
199
+ // generation than this build understands.
200
+ if (typeof pluginApi === "string" && pluginApi.trim().length > 0) {
201
+ const wanted = Number.parseInt(pluginApi.trim(), 10);
202
+ if (Number.isFinite(wanted) && wanted > currentApi) {
203
+ return {
204
+ compatible: false,
205
+ brigadeVersion,
206
+ minBrigadeVersion,
207
+ pluginApi,
208
+ reason: `This extension targets plugin API v${wanted}, but this Brigade only supports up to v${currentApi}. Update Brigade first.`,
209
+ };
210
+ }
211
+ }
212
+ // (2) minimum Brigade version — module needs a newer Brigade than is running.
213
+ if (typeof minBrigadeVersion === "string" && minBrigadeVersion.trim().length > 0) {
214
+ const need = parseSemverLead(minBrigadeVersion);
215
+ const have = parseSemverLead(brigadeVersion);
216
+ if (need && have && compareSemver(have, need) < 0) {
217
+ return {
218
+ compatible: false,
219
+ brigadeVersion,
220
+ minBrigadeVersion,
221
+ pluginApi,
222
+ reason: `This extension needs Brigade ${minBrigadeVersion} or newer; you're on ${brigadeVersion}. Update Brigade first.`,
223
+ };
224
+ }
225
+ }
226
+ return {
227
+ compatible: true,
228
+ brigadeVersion,
229
+ minBrigadeVersion,
230
+ pluginApi,
231
+ reason: "Compatible with this version of Brigade.",
232
+ };
233
+ }
234
+ /* ─────────────────────────── staging by source kind ─────────────────────────── */
235
+ /** Copy a local path (file OR folder) into a fresh staging dir; return it. */
236
+ function stageLocal(source, stageRoot) {
237
+ const abs = path.resolve(source.replace(/^~(?=$|[/\\])/, () => process.env.HOME ?? process.env.USERPROFILE ?? "~"));
238
+ let st;
239
+ try {
240
+ st = statSync(abs);
241
+ }
242
+ catch {
243
+ throw new InstallError(`No file or folder found at ${abs}.`);
244
+ }
245
+ const stagedDir = path.join(stageRoot, "staged");
246
+ mkdirSync(stagedDir, { recursive: true });
247
+ if (st.isDirectory()) {
248
+ cpSync(abs, stagedDir, { recursive: true });
249
+ return { stagedDir, fallbackName: path.basename(abs) };
250
+ }
251
+ // Single file → place it as the module's index, preserving its extension.
252
+ const ext = path.extname(abs) || ".js";
253
+ const indexName = `index${ext}`;
254
+ cpSync(abs, path.join(stagedDir, indexName));
255
+ return { stagedDir, fallbackName: path.basename(abs, ext) };
256
+ }
257
+ /** Run a command, surfacing a clean error. `cwd` defaults to the stage root. */
258
+ function runTool(cmd, args, cwd) {
259
+ try {
260
+ execFileSync(cmd, args, { cwd, stdio: "pipe", windowsHide: true });
261
+ }
262
+ catch (err) {
263
+ const detail = err instanceof Error ? err.message : String(err);
264
+ throw new InstallError(`\`${cmd} ${args.join(" ")}\` failed: ${detail}`);
265
+ }
266
+ }
267
+ /** Fetch an npm package via `npm pack`, unpack the tarball, return the dir. */
268
+ function stageNpm(spec, stageRoot) {
269
+ // `npm pack <spec>` downloads the tarball into cwd and prints its filename.
270
+ let out;
271
+ try {
272
+ out = execFileSync("npm", ["pack", spec, "--silent"], {
273
+ cwd: stageRoot,
274
+ stdio: ["ignore", "pipe", "pipe"],
275
+ encoding: "utf8",
276
+ windowsHide: true,
277
+ }).trim();
278
+ }
279
+ catch (err) {
280
+ const detail = err instanceof Error ? err.message : String(err);
281
+ throw new InstallError(`Couldn't download "${spec}" from npm: ${detail}`);
282
+ }
283
+ // `npm pack` may print multiple lines; the tarball name is the last non-empty.
284
+ const tarball = out.split(/\r?\n/).map((l) => l.trim()).filter(Boolean).pop();
285
+ if (!tarball)
286
+ throw new InstallError(`npm didn't produce a package tarball for "${spec}".`);
287
+ const tarballPath = path.join(stageRoot, tarball);
288
+ const extractDir = path.join(stageRoot, "unpacked");
289
+ mkdirSync(extractDir, { recursive: true });
290
+ // Tarballs from `npm pack` always nest under a top-level `package/` dir.
291
+ runTool("tar", ["-xzf", tarballPath, "-C", extractDir], stageRoot);
292
+ const inner = path.join(extractDir, "package");
293
+ const stagedDir = existsSync(inner) ? inner : extractDir;
294
+ return { stagedDir, fallbackName: bareNameFromSpec(spec) };
295
+ }
296
+ /** Clone a git URL (shallow) into a staging dir; return it. */
297
+ function stageGit(url, stageRoot) {
298
+ const stagedDir = path.join(stageRoot, "cloned");
299
+ const cleanUrl = url.replace(/^git\+/, "");
300
+ runTool("git", ["clone", "--depth", "1", cleanUrl, stagedDir], stageRoot);
301
+ // Drop the `.git` dir so it isn't carried into the extensions folder (and
302
+ // doesn't trip the scanner's skip rules either way).
303
+ try {
304
+ rmSync(path.join(stagedDir, ".git"), { recursive: true, force: true });
305
+ }
306
+ catch {
307
+ /* best-effort */
308
+ }
309
+ return { stagedDir, fallbackName: repoNameFromGit(url) };
310
+ }
311
+ /**
312
+ * Install an extension from a source. Does NOT prompt — it stages, resolves the
313
+ * id, refuses an existing id unless `force`, copies the module into place, then
314
+ * runs the compat + scan gates and returns the structured result. The CLI layer
315
+ * decides whether to keep it (e.g. after the operator acks the scan). The
316
+ * compat gate is the one hard failure: a forward-incompatible module is
317
+ * REMOVED again and an `InstallError` is thrown.
318
+ */
319
+ export async function installExtension(source, opts) {
320
+ const sourceKind = classifySource(source);
321
+ const stageRoot = mkdtempSync(path.join(tmpdir(), "brigade-ext-install-"));
322
+ try {
323
+ // 1. Stage the bytes into a temp dir based on the source kind.
324
+ const staged = sourceKind === "local"
325
+ ? stageLocal(source, stageRoot)
326
+ : sourceKind === "npm"
327
+ ? stageNpm(source, stageRoot)
328
+ : stageGit(source, stageRoot);
329
+ // 2. Resolve the id (manifest → package.json → basename).
330
+ const id = resolveModuleId(staged.stagedDir, staged.fallbackName);
331
+ // 3. Collision check.
332
+ const targetDir = path.join(opts.extensionsDir, id);
333
+ const exists = existsSync(targetDir);
334
+ if (exists && !opts.force) {
335
+ throw new InstallError(`An extension named "${id}" is already installed. Re-run with --force to replace it, or remove it first with \`brigade extensions remove ${id}\`.`);
336
+ }
337
+ // 4. Copy the staged module into the extensions dir.
338
+ mkdirSync(opts.extensionsDir, { recursive: true });
339
+ if (exists)
340
+ rmSync(targetDir, { recursive: true, force: true });
341
+ cpSync(staged.stagedDir, targetDir, { recursive: true });
342
+ // 5. Compat gate — the one hard failure. Roll back on incompatibility.
343
+ const manifest = readManifestAt(targetDir);
344
+ const compat = checkCompat(manifest, opts.brigadeVersionOverride, opts.pluginApiOverride);
345
+ if (!compat.compatible) {
346
+ rmSync(targetDir, { recursive: true, force: true });
347
+ throw new InstallError(compat.reason);
348
+ }
349
+ // 6. Security scan — surfaced, never auto-blocking.
350
+ const scan = scanInstalledModule(targetDir);
351
+ return {
352
+ id,
353
+ dir: targetDir,
354
+ sourceKind,
355
+ source,
356
+ manifest,
357
+ compat,
358
+ scan,
359
+ replacedExisting: exists,
360
+ };
361
+ }
362
+ finally {
363
+ try {
364
+ rmSync(stageRoot, { recursive: true, force: true });
365
+ }
366
+ catch {
367
+ /* best-effort temp cleanup */
368
+ }
369
+ }
370
+ }
371
+ /**
372
+ * Remove an installed extension by id. Refuses cleanly (throws `InstallError`)
373
+ * when no extension of that id is installed. `id` is sanitised the same way
374
+ * install resolves it, so `remove My-Plugin` matches the `my-plugin` folder.
375
+ */
376
+ export function removeExtension(id, extensionsDir) {
377
+ const safeId = sanitizeId(id);
378
+ if (!safeId)
379
+ throw new InstallError(`"${id}" isn't a valid extension name.`);
380
+ const dir = path.join(extensionsDir, safeId);
381
+ let isDir = false;
382
+ try {
383
+ isDir = statSync(dir).isDirectory();
384
+ }
385
+ catch {
386
+ isDir = false;
387
+ }
388
+ if (!isDir) {
389
+ throw new InstallError(`No extension named "${safeId}" is installed. Run \`brigade extensions list\` to see what you have.`);
390
+ }
391
+ rmSync(dir, { recursive: true, force: true });
392
+ return { id: safeId, dir };
393
+ }
394
+ /** List installed extension ids (folder names) under the extensions dir. */
395
+ export function listInstalledIds(extensionsDir) {
396
+ try {
397
+ return readdirSync(extensionsDir)
398
+ .filter((name) => {
399
+ if (name.startsWith("."))
400
+ return false;
401
+ try {
402
+ return statSync(path.join(extensionsDir, name)).isDirectory();
403
+ }
404
+ catch {
405
+ return false;
406
+ }
407
+ })
408
+ .sort();
409
+ }
410
+ catch {
411
+ return [];
412
+ }
413
+ }
414
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"install.js","sourceRoot":"","sources":["../../../src/agents/extensions/install.ts"],"names":[],"mappings":"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"}
@@ -12,8 +12,19 @@
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 { BrigadeExtensionRegistry, type RegistryContextMeta } from "./registry.js";
19
30
  import type { BrigadeModule } from "./types.js";
@@ -1 +1 @@
1
- {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/agents/extensions/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AASH,OAAO,EAAE,wBAAwB,EAAE,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAmChD,MAAM,WAAW,eAAe;IAC/B,yCAAyC;IACzC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAWD;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAgG1F"}
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../../src/agents/extensions/loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAkBH,OAAO,EAAE,wBAAwB,EAAqB,KAAK,mBAAmB,EAAE,MAAM,eAAe,CAAC;AACtG,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAmChD,MAAM,WAAW,eAAe;IAC/B,yCAAyC;IACzC,OAAO,EAAE,aAAa,EAAE,CAAC;IACzB,IAAI,EAAE,mBAAmB,CAAC;IAC1B,gEAAgE;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,qFAAqF;IACrF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,WAAW,CAAC,EAAE,OAAO,CAAC;CACtB;AAkBD;;;;;GAKG;AACH,wBAAsB,WAAW,CAAC,IAAI,EAAE,eAAe,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAiM1F"}