@spinabot/brigade 1.3.2 → 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 (225) 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/pairing.d.ts.map +1 -1
  191. package/dist/cli/commands/pairing.js +16 -2
  192. package/dist/cli/commands/pairing.js.map +1 -1
  193. package/dist/cli/commands/update.d.ts +17 -0
  194. package/dist/cli/commands/update.d.ts.map +1 -0
  195. package/dist/cli/commands/update.js +104 -0
  196. package/dist/cli/commands/update.js.map +1 -0
  197. package/dist/cli/program/build-program.d.ts.map +1 -1
  198. package/dist/cli/program/build-program.js +113 -0
  199. package/dist/cli/program/build-program.js.map +1 -1
  200. package/dist/config/paths.d.ts +1 -0
  201. package/dist/config/paths.d.ts.map +1 -1
  202. package/dist/config/paths.js +9 -0
  203. package/dist/config/paths.js.map +1 -1
  204. package/dist/core/server.d.ts.map +1 -1
  205. package/dist/core/server.js +134 -2
  206. package/dist/core/server.js.map +1 -1
  207. package/dist/protocol.d.ts +25 -0
  208. package/dist/protocol.d.ts.map +1 -1
  209. package/dist/protocol.js.map +1 -1
  210. package/dist/system-prompt/assembler.d.ts.map +1 -1
  211. package/dist/system-prompt/assembler.js +17 -0
  212. package/dist/system-prompt/assembler.js.map +1 -1
  213. package/dist/system-prompt/identity-defaults.d.ts +28 -0
  214. package/dist/system-prompt/identity-defaults.d.ts.map +1 -1
  215. package/dist/system-prompt/identity-defaults.js +47 -0
  216. package/dist/system-prompt/identity-defaults.js.map +1 -1
  217. package/dist/ui/editor.d.ts.map +1 -1
  218. package/dist/ui/editor.js +1 -0
  219. package/dist/ui/editor.js.map +1 -1
  220. package/dist/version.d.ts +4 -3
  221. package/dist/version.d.ts.map +1 -1
  222. package/dist/version.js +27 -5
  223. package/dist/version.js.map +1 -1
  224. package/package.json +21 -4
  225. package/scripts/build-done.mjs +11 -2
@@ -0,0 +1,578 @@
1
+ /**
2
+ * `brigade extensions list / doctor / init` — operator + author CLI over the
3
+ * extension engine.
4
+ *
5
+ * • list — every extension Brigade knows about (built-in + the ones you
6
+ * dropped in your extensions folder), with whether each one loaded.
7
+ * • doctor — the "why didn't my plugin load" surface: per-file, did it pass
8
+ * the safety check, load, and export a Brigade module.
9
+ * • init — scaffold a runnable starter module (channel / tool / provider)
10
+ * into your extensions folder, plus a short README.
11
+ * • add — install a third-party module (local path / npm package / git URL)
12
+ * into your extensions folder, with a compat check + security scan.
13
+ * • remove — delete an installed module from your extensions folder.
14
+ *
15
+ * The discovery + diagnosis logic lives in `agents/extensions/diagnose.ts`; the
16
+ * install/remove machinery in `agents/extensions/install.ts`; this file is just
17
+ * the CLI surface (argument parsing + human/JSON rendering + the interactive
18
+ * scan acknowledgement). All operator-facing copy stays plain — no internal type
19
+ * names, no raw stack traces, no HTTP codes.
20
+ */
21
+ import { existsSync, mkdirSync, writeFileSync } from "node:fs";
22
+ import path from "node:path";
23
+ import readline from "node:readline/promises";
24
+ import chalk from "chalk";
25
+ import { BUNDLED_MODULES } from "../../agents/extensions/modules/index.js";
26
+ import { diagnoseExtensions, } from "../../agents/extensions/diagnose.js";
27
+ import { extensionsRootExists } from "../../agents/extensions/discovery.js";
28
+ import { InstallError, installExtension, removeExtension, } from "../../agents/extensions/install.js";
29
+ import { summarizeScan } from "../../agents/extensions/install-scan.js";
30
+ import { resolveExtensionsDir } from "../../config/paths.js";
31
+ /* ─────────────────────────────── list ─────────────────────────────── */
32
+ export async function runExtensionsList(opts = {}) {
33
+ const extensionsDir = resolveExtensionsDir();
34
+ const diagnosis = await diagnoseExtensions(BUNDLED_MODULES, extensionsDir);
35
+ if (opts.json) {
36
+ process.stdout.write(`${JSON.stringify(jsonView(diagnosis), null, 2)}\n`);
37
+ return 0;
38
+ }
39
+ const { extensions } = diagnosis;
40
+ const lines = [];
41
+ lines.push(chalk.bold("brigade extensions"));
42
+ lines.push("");
43
+ const idWidth = Math.max(4, ...extensions.map((e) => e.id.length));
44
+ const originWidth = 8; // "built-in" / "yours"
45
+ lines.push(` ${"NAME".padEnd(idWidth)} ${"SOURCE".padEnd(originWidth)} STATUS`);
46
+ for (const e of extensions) {
47
+ lines.push(` ${e.id.padEnd(idWidth)} ${originLabel(e.origin).padEnd(originWidth)} ${statusCell(e)}`);
48
+ if (e.status === "skipped" && e.reason) {
49
+ lines.push(` ${" ".repeat(idWidth)} ${" ".repeat(originWidth)} ${chalk.dim(`→ ${e.reason}`)}`);
50
+ }
51
+ }
52
+ lines.push("");
53
+ const userCount = extensions.filter((e) => e.origin === "user").length;
54
+ if (userCount === 0) {
55
+ lines.push(chalk.dim(`No add-on extensions found. Drop one into ${extensionsDir} (or run \`brigade extensions init <id>\`).`));
56
+ }
57
+ else {
58
+ const skipped = extensions.filter((e) => e.origin === "user" && e.status === "skipped").length;
59
+ if (skipped > 0) {
60
+ lines.push(chalk.yellow(`${skipped} of your extension${skipped === 1 ? "" : "s"} didn't load — run \`brigade extensions doctor\` to see why.`));
61
+ }
62
+ else {
63
+ lines.push(chalk.green("All your extensions loaded."));
64
+ }
65
+ }
66
+ lines.push("");
67
+ process.stdout.write(lines.join("\n"));
68
+ return 0;
69
+ }
70
+ /* ─────────────────────────────── doctor ─────────────────────────────── */
71
+ export async function runExtensionsDoctor(opts = {}) {
72
+ const extensionsDir = resolveExtensionsDir();
73
+ const diagnosis = await diagnoseExtensions(BUNDLED_MODULES, extensionsDir);
74
+ const userEntries = diagnosis.extensions.filter((e) => e.origin === "user");
75
+ if (opts.json) {
76
+ process.stdout.write(`${JSON.stringify({ extensionsDir, ok: userEntries.every((e) => e.status === "loaded"), extensions: userEntries.map(jsonEntry) }, null, 2)}\n`);
77
+ return 0;
78
+ }
79
+ const lines = [];
80
+ lines.push(chalk.bold("brigade extensions doctor"));
81
+ lines.push("");
82
+ if (!extensionsRootExists(extensionsDir)) {
83
+ lines.push(` Your extensions folder doesn't exist yet:`);
84
+ lines.push(` ${chalk.dim(extensionsDir)}`);
85
+ lines.push("");
86
+ lines.push(chalk.dim(" Run `brigade extensions init <id>` to scaffold your first one."));
87
+ lines.push("");
88
+ process.stdout.write(lines.join("\n"));
89
+ return 0;
90
+ }
91
+ if (userEntries.length === 0) {
92
+ lines.push(` No add-on extensions found in:`);
93
+ lines.push(` ${chalk.dim(extensionsDir)}`);
94
+ lines.push("");
95
+ lines.push(chalk.dim(" Run `brigade extensions init <id>` to scaffold your first one."));
96
+ lines.push("");
97
+ process.stdout.write(lines.join("\n"));
98
+ return 0;
99
+ }
100
+ for (const e of userEntries) {
101
+ const headGlyph = e.status === "loaded" ? chalk.green("✔") : chalk.red("✖");
102
+ lines.push(` ${headGlyph} ${chalk.bold(e.id)}`);
103
+ lines.push(` ${chalk.dim(e.source)}`);
104
+ const c = e.checks ?? { safe: false, imported: false, exportedModule: false };
105
+ lines.push(` ${stepGlyph(c.safe)} passes the safety check`);
106
+ lines.push(` ${stepGlyph(c.imported)} loads without errors`);
107
+ lines.push(` ${stepGlyph(c.exportedModule)} exports a Brigade module`);
108
+ if (e.status === "skipped" && e.reason) {
109
+ lines.push(` ${chalk.yellow(`→ ${e.reason}`)}`);
110
+ }
111
+ lines.push("");
112
+ }
113
+ const failed = userEntries.filter((e) => e.status === "skipped").length;
114
+ if (failed > 0) {
115
+ lines.push(chalk.yellow(`${failed} extension${failed === 1 ? "" : "s"} need attention (see above).`));
116
+ }
117
+ else {
118
+ lines.push(chalk.green("All your extensions are healthy."));
119
+ }
120
+ lines.push("");
121
+ process.stdout.write(lines.join("\n"));
122
+ return 0;
123
+ }
124
+ export async function runExtensionsInit(args, opts = {}) {
125
+ const id = (args.id ?? "").trim();
126
+ const kind = normalizeKind(args.kind);
127
+ if (kind === null) {
128
+ return fail(`Unknown kind "${args.kind}". Choose one of: channel, tool, provider.`, opts.json);
129
+ }
130
+ if (!isValidId(id)) {
131
+ return fail("Please give a simple name using lowercase letters, numbers and dashes (e.g. my-channel).", opts.json);
132
+ }
133
+ const extensionsDir = resolveExtensionsDir();
134
+ const targetDir = path.join(extensionsDir, id);
135
+ if (existsSync(targetDir)) {
136
+ return fail(`An extension named "${id}" already exists at ${targetDir}. Pick a different name or remove that folder first.`, opts.json);
137
+ }
138
+ try {
139
+ mkdirSync(targetDir, { recursive: true });
140
+ const indexPath = path.join(targetDir, "index.ts");
141
+ const readmePath = path.join(targetDir, "README.md");
142
+ writeFileSync(indexPath, scaffoldIndex(id, kind), "utf8");
143
+ writeFileSync(readmePath, scaffoldReadme(id, kind), "utf8");
144
+ if (opts.json) {
145
+ process.stdout.write(`${JSON.stringify({ ok: true, id, kind, dir: targetDir, files: [indexPath, readmePath] }, null, 2)}\n`);
146
+ return 0;
147
+ }
148
+ const lines = [];
149
+ lines.push(chalk.green(`Created a ${kind} extension "${id}".`));
150
+ lines.push("");
151
+ lines.push(` Folder: ${targetDir}`);
152
+ lines.push(` Files: index.ts, README.md`);
153
+ lines.push("");
154
+ lines.push("Next steps:");
155
+ lines.push(` 1. Edit index.ts to add your logic.`);
156
+ lines.push(` 2. Run \`brigade extensions doctor\` to confirm it loads.`);
157
+ lines.push("");
158
+ process.stdout.write(lines.join("\n"));
159
+ return 0;
160
+ }
161
+ catch (err) {
162
+ return fail(`Couldn't create the extension: ${err instanceof Error ? err.message : String(err)}`, opts.json);
163
+ }
164
+ }
165
+ /* ─────────────────────────────── add ─────────────────────────────── */
166
+ export async function runExtensionsAdd(args, opts = {}) {
167
+ const source = (args.source ?? "").trim();
168
+ if (!source) {
169
+ return fail("Give me something to install: a folder, a file, an npm package name, or a git URL.", opts.json);
170
+ }
171
+ const extensionsDir = resolveExtensionsDir();
172
+ let result;
173
+ try {
174
+ result = await installExtension(source, { extensionsDir, force: args.force });
175
+ }
176
+ catch (err) {
177
+ if (err instanceof InstallError)
178
+ return fail(err.message, opts.json);
179
+ return fail(`Couldn't install the extension: ${err instanceof Error ? err.message : String(err)}`, opts.json);
180
+ }
181
+ const high = result.scan.counts.high;
182
+ const total = result.scan.findings.length;
183
+ // JSON path is non-interactive: report what was installed + the full scan; the
184
+ // caller decides what to do with the findings. No prompt.
185
+ if (opts.json) {
186
+ process.stdout.write(`${JSON.stringify(jsonInstallView(result), null, 2)}\n`);
187
+ return 0;
188
+ }
189
+ // Human path — render the result, then (if the scan found anything) require an
190
+ // acknowledgement before keeping the install. `--yes` auto-accepts.
191
+ renderInstall(result);
192
+ if (total > 0) {
193
+ const accepted = await acknowledgeScan(result, args.yes === true);
194
+ if (!accepted) {
195
+ // Operator declined — undo the install so nothing risky lingers.
196
+ try {
197
+ removeExtension(result.id, extensionsDir);
198
+ }
199
+ catch {
200
+ /* best-effort rollback */
201
+ }
202
+ process.stderr.write(chalk.yellow(`\nRemoved "${result.id}" — you didn't accept its access. Nothing was kept.\n`));
203
+ return 1;
204
+ }
205
+ }
206
+ const lines = [];
207
+ lines.push("");
208
+ lines.push(chalk.green(`Installed "${result.id}".`));
209
+ lines.push("");
210
+ lines.push("Next steps:");
211
+ lines.push(` 1. Run \`brigade extensions doctor\` to confirm it loads.`);
212
+ lines.push(` 2. Restart the gateway (or reload extensions) to activate it.`);
213
+ lines.push("");
214
+ process.stdout.write(lines.join("\n"));
215
+ return 0;
216
+ }
217
+ /** Render the install summary block (what / where / compat / scan). */
218
+ function renderInstall(result) {
219
+ const sourceLabel = result.sourceKind === "local" ? "local path" : result.sourceKind === "npm" ? "npm package" : "git repository";
220
+ const lines = [];
221
+ lines.push(chalk.bold(`Installing extension`));
222
+ lines.push("");
223
+ lines.push(` From: ${result.source} ${chalk.dim(`(${sourceLabel})`)}`);
224
+ lines.push(` Name: ${chalk.bold(result.id)}${result.replacedExisting ? chalk.dim(" (replaced existing)") : ""}`);
225
+ lines.push(` Folder: ${result.dir}`);
226
+ lines.push("");
227
+ // Compat verdict (always compatible here — an incompatible one would've thrown).
228
+ const v = result.compat;
229
+ const compatBits = [`needs Brigade ${v.minBrigadeVersion ?? "(any)"}`];
230
+ if (v.pluginApi)
231
+ compatBits.push(`plugin API v${v.pluginApi}`);
232
+ lines.push(` ${chalk.green("✔")} Compatible with Brigade ${v.brigadeVersion} ${chalk.dim(`(${compatBits.join(", ")})`)}`);
233
+ // Scan summary.
234
+ const { findings, filesScanned, counts } = result.scan;
235
+ if (findings.length === 0) {
236
+ lines.push(` ${chalk.green("✔")} Security scan: nothing notable in ${filesScanned} file${filesScanned === 1 ? "" : "s"}.`);
237
+ }
238
+ else {
239
+ const glyph = counts.high > 0 ? chalk.yellow("!") : chalk.dim("•");
240
+ lines.push(` ${glyph} Security scan: ${summarizeScan(result.scan)} across ${filesScanned} file${filesScanned === 1 ? "" : "s"}.`);
241
+ }
242
+ lines.push("");
243
+ process.stdout.write(lines.join("\n"));
244
+ }
245
+ /**
246
+ * Show the scan findings + ask the operator to accept them. Returns true to
247
+ * proceed. `autoYes` (from `--yes`) accepts without prompting (non-interactive).
248
+ * When there's no TTY and no `--yes`, we DECLINE — never silently keep a module
249
+ * with flagged constructs the operator never saw.
250
+ */
251
+ async function acknowledgeScan(result, autoYes) {
252
+ const { findings } = result.scan;
253
+ const lines = [];
254
+ lines.push(chalk.yellow("Heads up — this extension uses some powerful capabilities:"));
255
+ lines.push("");
256
+ // Group by note for a compact list; show up to a few example locations each.
257
+ const grouped = groupFindings(findings);
258
+ for (const g of grouped) {
259
+ const sevTag = g.severity === "high" ? chalk.yellow("[high]") : g.severity === "medium" ? chalk.dim("[medium]") : chalk.dim("[low]");
260
+ lines.push(` ${sevTag} ${g.note}`);
261
+ for (const loc of g.locations.slice(0, 3)) {
262
+ lines.push(chalk.dim(` ${loc.file}:${loc.line} ${loc.snippet}`));
263
+ }
264
+ if (g.locations.length > 3) {
265
+ lines.push(chalk.dim(` …and ${g.locations.length - 3} more`));
266
+ }
267
+ }
268
+ lines.push("");
269
+ lines.push(chalk.dim("These are normal for many extensions (a chat channel needs the network, a tool may run commands). Only continue if you trust the source."));
270
+ lines.push("");
271
+ process.stdout.write(lines.join("\n"));
272
+ if (autoYes) {
273
+ process.stdout.write(chalk.dim("Accepted automatically (--yes).\n"));
274
+ return true;
275
+ }
276
+ if (!process.stdin.isTTY) {
277
+ process.stderr.write(chalk.yellow("Not a terminal — re-run with --yes to accept these capabilities non-interactively.\n"));
278
+ return false;
279
+ }
280
+ const rl = readline.createInterface({ input: process.stdin, output: process.stderr });
281
+ try {
282
+ const answer = (await rl.question("Keep this extension? [y/N] ")).trim().toLowerCase();
283
+ return answer === "y" || answer === "yes";
284
+ }
285
+ finally {
286
+ rl.close();
287
+ }
288
+ }
289
+ /** Collapse findings sharing a note into one row with example locations. */
290
+ function groupFindings(findings) {
291
+ const sevRank = { high: 0, medium: 1, low: 2 };
292
+ const byNote = new Map();
293
+ for (const f of findings) {
294
+ const existing = byNote.get(f.note);
295
+ if (existing) {
296
+ existing.locations.push({ file: f.file, line: f.line, snippet: f.snippet });
297
+ }
298
+ else {
299
+ byNote.set(f.note, {
300
+ note: f.note,
301
+ severity: f.severity,
302
+ locations: [{ file: f.file, line: f.line, snippet: f.snippet }],
303
+ });
304
+ }
305
+ }
306
+ return [...byNote.values()].sort((a, b) => sevRank[a.severity] - sevRank[b.severity]);
307
+ }
308
+ function jsonInstallView(result) {
309
+ return {
310
+ ok: true,
311
+ id: result.id,
312
+ dir: result.dir,
313
+ source: result.source,
314
+ sourceKind: result.sourceKind,
315
+ replacedExisting: result.replacedExisting,
316
+ compat: {
317
+ compatible: result.compat.compatible,
318
+ brigadeVersion: result.compat.brigadeVersion,
319
+ ...(result.compat.minBrigadeVersion ? { minBrigadeVersion: result.compat.minBrigadeVersion } : {}),
320
+ ...(result.compat.pluginApi ? { pluginApi: result.compat.pluginApi } : {}),
321
+ },
322
+ scan: {
323
+ summary: summarizeScan(result.scan),
324
+ filesScanned: result.scan.filesScanned,
325
+ counts: result.scan.counts,
326
+ findings: result.scan.findings,
327
+ },
328
+ };
329
+ }
330
+ /* ─────────────────────────────── remove ─────────────────────────────── */
331
+ export async function runExtensionsRemove(args, opts = {}) {
332
+ const id = (args.id ?? "").trim();
333
+ if (!id)
334
+ return fail("Tell me which extension to remove (its name).", opts.json);
335
+ const extensionsDir = resolveExtensionsDir();
336
+ try {
337
+ const removed = removeExtension(id, extensionsDir);
338
+ if (opts.json) {
339
+ process.stdout.write(`${JSON.stringify({ ok: true, id: removed.id, dir: removed.dir }, null, 2)}\n`);
340
+ return 0;
341
+ }
342
+ const lines = [];
343
+ lines.push(chalk.green(`Removed "${removed.id}".`));
344
+ lines.push(` Folder deleted: ${removed.dir}`);
345
+ lines.push("");
346
+ process.stdout.write(lines.join("\n"));
347
+ return 0;
348
+ }
349
+ catch (err) {
350
+ if (err instanceof InstallError)
351
+ return fail(err.message, opts.json);
352
+ return fail(`Couldn't remove the extension: ${err instanceof Error ? err.message : String(err)}`, opts.json);
353
+ }
354
+ }
355
+ /* ─────────────────────────────── helpers ─────────────────────────────── */
356
+ function originLabel(origin) {
357
+ return origin === "bundled" ? "built-in" : "yours";
358
+ }
359
+ function statusCell(e) {
360
+ return e.status === "loaded" ? chalk.green("loaded") : chalk.yellow("not loaded");
361
+ }
362
+ function stepGlyph(ok) {
363
+ return ok ? chalk.green("✔") : chalk.red("✖");
364
+ }
365
+ function jsonEntry(e) {
366
+ return {
367
+ id: e.id,
368
+ origin: e.origin,
369
+ source: e.source,
370
+ status: e.status,
371
+ ...(e.reason ? { reason: e.reason } : {}),
372
+ ...(e.checks ? { checks: e.checks } : {}),
373
+ // FIX 4 — only present when a live registry was available (gateway path);
374
+ // the discovery-only CLI default omits it, keeping output back-compatible.
375
+ ...(e.live ? { live: e.live } : {}),
376
+ };
377
+ }
378
+ function jsonView(d) {
379
+ return {
380
+ extensionsDir: d.extensionsDir,
381
+ extensions: d.extensions.map(jsonEntry),
382
+ };
383
+ }
384
+ function fail(message, json) {
385
+ if (json) {
386
+ process.stdout.write(`${JSON.stringify({ ok: false, error: message }, null, 2)}\n`);
387
+ }
388
+ else {
389
+ process.stderr.write(`${message}\n`);
390
+ }
391
+ return 1;
392
+ }
393
+ function normalizeKind(raw) {
394
+ const v = (raw ?? "channel").trim().toLowerCase();
395
+ if (v === "channel" || v === "tool" || v === "provider")
396
+ return v;
397
+ return null;
398
+ }
399
+ /** A safe folder/extension id: lowercase letters, digits, dashes; must start with a letter. */
400
+ function isValidId(id) {
401
+ return /^[a-z][a-z0-9-]*$/.test(id) && !id.includes("--") && !id.endsWith("-");
402
+ }
403
+ /** Turn a kebab id into a CamelCase suffix for generated identifiers. */
404
+ function toCamel(id) {
405
+ return id
406
+ .split("-")
407
+ .filter(Boolean)
408
+ .map((p) => p.charAt(0).toUpperCase() + p.slice(1))
409
+ .join("");
410
+ }
411
+ /* ─────────────────────────────── scaffolds ─────────────────────────────── */
412
+ function scaffoldIndex(id, kind) {
413
+ if (kind === "channel")
414
+ return scaffoldChannelIndex(id);
415
+ if (kind === "provider")
416
+ return scaffoldProviderIndex(id);
417
+ return scaffoldToolIndex(id);
418
+ }
419
+ function scaffoldChannelIndex(id) {
420
+ const Name = toCamel(id);
421
+ return `/**
422
+ * ${id} — a Brigade channel extension.
423
+ *
424
+ * A channel connects Brigade to a messaging surface: it listens for incoming
425
+ * messages, hands each one to Brigade for a reply, and sends the reply back.
426
+ * This starter implements the smallest working shape — fill in start/stop/send
427
+ * with your transport (a chat SDK, a webhook, a socket, …).
428
+ *
429
+ * Confirm it loads: brigade extensions doctor
430
+ */
431
+
432
+ import { defineModule } from "brigade/channel-sdk";
433
+ import type { ChannelAdapter, ChannelStartContext } from "brigade/channel-sdk";
434
+
435
+ function create${Name}Adapter(): ChannelAdapter {
436
+ return {
437
+ id: "${id}",
438
+ label: "${Name}",
439
+
440
+ // Return true only when this channel has what it needs to run (a token,
441
+ // a URL, …). Read from \`cfg\` / \`env\`. Returning false keeps it idle.
442
+ isConfigured(_cfg, _env) {
443
+ return false;
444
+ },
445
+
446
+ // Begin listening. Call \`ctx.onInbound(message)\` for every incoming
447
+ // message; Brigade runs a turn and replies via \`sendText\` below.
448
+ async start(_ctx: ChannelStartContext): Promise<void> {
449
+ // TODO: connect to your transport and wire incoming messages to
450
+ // ctx.onInbound({ channel: "${id}", conversationId, from, text }).
451
+ },
452
+
453
+ // Stop listening and tear down the connection.
454
+ async stop(): Promise<void> {
455
+ // TODO: close your transport.
456
+ },
457
+
458
+ // Deliver an outbound reply to a conversation.
459
+ async sendText(_conversationId: string, _text: string): Promise<void> {
460
+ // TODO: send the message through your transport.
461
+ },
462
+ };
463
+ }
464
+
465
+ export default defineModule({
466
+ id: "${id}",
467
+ register(b) {
468
+ b.channel(create${Name}Adapter());
469
+ },
470
+ });
471
+ `;
472
+ }
473
+ function scaffoldToolIndex(id) {
474
+ const Name = toCamel(id);
475
+ return `/**
476
+ * ${id} — a Brigade tool extension.
477
+ *
478
+ * A tool gives the agent a new action it can call during a turn. This starter
479
+ * registers one tool with a single text input and a text result — replace the
480
+ * parameters and the body with your own logic.
481
+ *
482
+ * Confirm it loads: brigade extensions doctor
483
+ */
484
+
485
+ import { defineModule } from "brigade/extension-sdk";
486
+
487
+ export default defineModule({
488
+ id: "${id}",
489
+ register(b) {
490
+ b.tool({
491
+ name: "${id.replace(/-/g, "_")}",
492
+ label: "${Name}",
493
+ description: "Describe what this tool does so the agent knows when to use it.",
494
+ parameters: {
495
+ type: "object",
496
+ properties: {
497
+ input: { type: "string", description: "The text to act on." },
498
+ },
499
+ required: ["input"],
500
+ },
501
+ // The body runs when the agent calls the tool. Return a short result.
502
+ async execute(args: { input: string }) {
503
+ const input = args?.input ?? "";
504
+ return { content: \`You sent: \${input}\` };
505
+ },
506
+ } as never);
507
+ },
508
+ });
509
+ `;
510
+ }
511
+ function scaffoldProviderIndex(id) {
512
+ const Name = toCamel(id);
513
+ return `/**
514
+ * ${id} — a Brigade provider extension.
515
+ *
516
+ * A provider plugs an external capability into Brigade. This starter registers
517
+ * a simple web-search provider as an example; swap the body for the service you
518
+ * want to integrate. Brigade only activates a provider once it reports itself as
519
+ * configured (a key/URL is present).
520
+ *
521
+ * Confirm it loads: brigade extensions doctor
522
+ */
523
+
524
+ import { defineModule } from "brigade/extension-sdk";
525
+
526
+ export default defineModule({
527
+ id: "${id}",
528
+ register(b) {
529
+ b.webSearch({
530
+ id: "${id}",
531
+ label: "${Name}",
532
+ hint: "Describe this search source in one line.",
533
+ requiresCredential: true,
534
+
535
+ // Return true only when your credential is present.
536
+ isConfigured(_cfg, _env) {
537
+ return false;
538
+ },
539
+
540
+ // Build the search tool when the provider is active. Return null when
541
+ // it isn't ready.
542
+ createTool(_ctx) {
543
+ return null;
544
+ },
545
+ });
546
+ },
547
+ });
548
+ `;
549
+ }
550
+ function scaffoldReadme(id, kind) {
551
+ const sdk = kind === "channel" ? "brigade/channel-sdk" : "brigade/extension-sdk";
552
+ return `# ${id}
553
+
554
+ A Brigade **${kind}** extension.
555
+
556
+ ## How it loads
557
+
558
+ Brigade discovers everything under your extensions folder automatically. This
559
+ folder ships an \`index.ts\` that exports a module via \`defineModule\` from
560
+ \`${sdk}\`. You don't need to install or build anything — Brigade reads the
561
+ TypeScript directly on startup.
562
+
563
+ ## Edit it
564
+
565
+ Open \`index.ts\` and fill in the parts marked \`TODO\`.
566
+
567
+ ## Check it
568
+
569
+ \`\`\`
570
+ brigade extensions doctor
571
+ \`\`\`
572
+
573
+ That shows whether this extension passed its safety check, loaded, and exported
574
+ a valid module. \`brigade extensions list\` shows it alongside the built-in
575
+ extensions.
576
+ `;
577
+ }
578
+ //# sourceMappingURL=extensions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../../src/cli/commands/extensions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/pairing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAavE,8BAA8B;AAC9B,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,SAAS,GAAG,IAAI,CAEzF;AAsDD,wBAAsB,cAAc,CACnC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1B,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAID,wBAAsB,iBAAiB,CACtC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EACxC,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,OAAO,CAAC,MAAM,CAAC,CAgCjB;AAID,wBAAsB,gBAAgB,CACrC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EACxC,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,OAAO,CAAC,MAAM,CAAC,CAajB"}
1
+ {"version":3,"file":"pairing.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/pairing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAmBvE,8BAA8B;AAC9B,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,SAAS,GAAG,IAAI,CAEzF;AAsDD,wBAAsB,cAAc,CACnC,IAAI,EAAE;IAAE,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EAC1B,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,OAAO,CAAC,MAAM,CAAC,CAmBjB;AAID,wBAAsB,iBAAiB,CACtC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EACxC,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,OAAO,CAAC,MAAM,CAAC,CAkDjB;AAID,wBAAsB,gBAAgB,CACrC,IAAI,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,EACxC,IAAI,GAAE;IAAE,IAAI,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3B,OAAO,CAAC,MAAM,CAAC,CAajB"}
@@ -11,7 +11,7 @@
11
11
  * channel is available).
12
12
  */
13
13
  import { BUNDLED_MODULES, loadModules } from "../../agents/extensions/index.js";
14
- import { approvePairingCode, readPendingPairings, revokePairingCode } from "../../agents/channels/access-control/index.js";
14
+ import { approvePairingCode, readChannelOwner, readPendingPairings, revokePairingCode, setChannelOwner, } from "../../agents/channels/access-control/index.js";
15
15
  import { DEFAULT_AGENT_ID, resolveAgentWorkspaceDir } from "../../config/paths.js";
16
16
  import { loadConfig } from "../../core/config.js";
17
17
  /**
@@ -107,12 +107,26 @@ export async function runPairingApprove(args, opts = {}) {
107
107
  process.stderr.write(`${msg}\n`);
108
108
  return 1;
109
109
  }
110
+ // Owner bootstrap. On a channel whose bot account is SEPARATE from the
111
+ // operator (Telegram: `selfId()` is the bot, never the human), the FIRST
112
+ // approved sender becomes the recorded owner — so owner-only commands and the
113
+ // skip-challenge path work for them. Running `pairing approve` requires
114
+ // gateway-machine access, which IS the proof that this is the operator (a
115
+ // stranger who merely texts the bot can never reach here). Never overwrites an
116
+ // existing owner.
117
+ let becameOwner = false;
118
+ if (resolved.adapter.pairing?.botIsSeparateFromOperator && !readChannelOwner(resolved.id)) {
119
+ becameOwner = setChannelOwner(resolved.id, approved.senderId);
120
+ }
110
121
  if (opts.json) {
111
- process.stdout.write(`${JSON.stringify({ ok: true, channel: resolved.id, sender: approved.senderId }, null, 2)}\n`);
122
+ process.stdout.write(`${JSON.stringify({ ok: true, channel: resolved.id, sender: approved.senderId, owner: becameOwner }, null, 2)}\n`);
112
123
  }
113
124
  else {
114
125
  const who = approved.senderName ? `${approved.senderName} (${approved.senderId})` : approved.senderId;
115
126
  process.stdout.write(`Approved ${who} on ${resolved.id}. They can now DM the agent.\n`);
127
+ if (becameOwner) {
128
+ process.stdout.write(`Set ${who} as the OWNER of ${resolved.id} — they can now run admin commands (/pending, /approve, /allowlist) from the chat.\n`);
129
+ }
116
130
  }
117
131
  // Best-effort in-channel confirmation — when the channel adapter declares
118
132
  // a `pairing.notifyApproval` hook, fire it so the requester sees a