@spinabot/brigade 1.19.0 → 1.19.2
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.
- package/README.md +12 -7
- package/dist/agents/channels/bluebubbles/media.d.ts.map +1 -1
- package/dist/agents/channels/bluebubbles/media.js +5 -1
- package/dist/agents/channels/bluebubbles/media.js.map +1 -1
- package/dist/agents/channels/channel-messaging-registry.d.ts.map +1 -1
- package/dist/agents/channels/channel-messaging-registry.js +4 -2
- package/dist/agents/channels/channel-messaging-registry.js.map +1 -1
- package/dist/agents/channels/slack/format.d.ts.map +1 -1
- package/dist/agents/channels/slack/format.js +4 -2
- package/dist/agents/channels/slack/format.js.map +1 -1
- package/dist/agents/channels/telegram/format.d.ts.map +1 -1
- package/dist/agents/channels/telegram/format.js +7 -4
- package/dist/agents/channels/telegram/format.js.map +1 -1
- package/dist/agents/channels/telegram/media.d.ts.map +1 -1
- package/dist/agents/channels/telegram/media.js +31 -1
- package/dist/agents/channels/telegram/media.js.map +1 -1
- package/dist/agents/channels/whatsapp/connection.d.ts.map +1 -1
- package/dist/agents/channels/whatsapp/connection.js +59 -5
- package/dist/agents/channels/whatsapp/connection.js.map +1 -1
- package/dist/agents/extensions/modules/duckduckgo.d.ts.map +1 -1
- package/dist/agents/extensions/modules/duckduckgo.js +13 -1
- package/dist/agents/extensions/modules/duckduckgo.js.map +1 -1
- package/dist/agents/extensions/modules/wikipedia.d.ts.map +1 -1
- package/dist/agents/extensions/modules/wikipedia.js +16 -8
- package/dist/agents/extensions/modules/wikipedia.js.map +1 -1
- package/dist/agents/memory/graph.js +2 -2
- package/dist/agents/memory/graph.js.map +1 -1
- package/dist/agents/memory/records.d.ts.map +1 -1
- package/dist/agents/memory/records.js +6 -1
- package/dist/agents/memory/records.js.map +1 -1
- package/dist/agents/routing/account-id.d.ts.map +1 -1
- package/dist/agents/routing/account-id.js +17 -7
- package/dist/agents/routing/account-id.js.map +1 -1
- package/dist/agents/routing/session-key.d.ts.map +1 -1
- package/dist/agents/routing/session-key.js +15 -7
- package/dist/agents/routing/session-key.js.map +1 -1
- package/dist/agents/skills/install.d.ts.map +1 -1
- package/dist/agents/skills/install.js +11 -2
- package/dist/agents/skills/install.js.map +1 -1
- package/dist/agents/tools/ooxml-images.d.ts.map +1 -1
- package/dist/agents/tools/ooxml-images.js +5 -2
- package/dist/agents/tools/ooxml-images.js.map +1 -1
- package/dist/agents/tools/web-fetch-utils.d.ts.map +1 -1
- package/dist/agents/tools/web-fetch-utils.js +26 -6
- package/dist/agents/tools/web-fetch-utils.js.map +1 -1
- package/dist/buildstamp.json +1 -1
- package/dist/cli/run-main.js +1 -1
- package/dist/cli/run-main.js.map +1 -1
- package/dist/core/daemon/systemd.js +1 -1
- package/dist/core/daemon/systemd.js.map +1 -1
- package/dist/core/server.js +1 -1
- package/dist/core/server.js.map +1 -1
- package/dist/security/media-path-guard.d.ts.map +1 -1
- package/dist/security/media-path-guard.js +11 -3
- package/dist/security/media-path-guard.js.map +1 -1
- package/package.json +1 -1
- package/scripts/convex-dev.mjs +24 -6
- package/skills/coding-agent/SKILL.md +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-path-guard.d.ts","sourceRoot":"","sources":["../../src/security/media-path-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;
|
|
1
|
+
{"version":3,"file":"media-path-guard.d.ts","sourceRoot":"","sources":["../../src/security/media-path-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,MAAM,WAAW,gBAAgB;IAChC,EAAE,EAAE,OAAO,CAAC;IACZ,qFAAqF;IACrF,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AAwCD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CA+C3E"}
|
|
@@ -32,9 +32,13 @@ const SENSITIVE_BASENAMES = new Set([
|
|
|
32
32
|
"auth-profiles.json",
|
|
33
33
|
"models.json",
|
|
34
34
|
"exec-approvals.json",
|
|
35
|
+
// Brigade encryption key (stored outside ~/.brigade by design)
|
|
36
|
+
"encryption.key",
|
|
37
|
+
// Convex local backend admin key
|
|
38
|
+
"admin-key.txt",
|
|
35
39
|
]);
|
|
36
40
|
/** Path fragments that mark a credentials directory (platform-normalized separators). */
|
|
37
|
-
const SENSITIVE_DIR_NAMES = [".ssh", ".aws", ".gnupg", ".kube", ".docker", "gcloud"];
|
|
41
|
+
const SENSITIVE_DIR_NAMES = [".ssh", ".aws", ".gnupg", ".kube", ".docker", "gcloud", ".convex-data"];
|
|
38
42
|
/** Resolved-prefix roots that are off-limits regardless of filename. */
|
|
39
43
|
function systemRoots() {
|
|
40
44
|
if (process.platform === "win32") {
|
|
@@ -89,8 +93,12 @@ export function validateOutboundMediaPath(rawPath) {
|
|
|
89
93
|
}
|
|
90
94
|
}
|
|
91
95
|
// Brigade's sealed per-agent auth subtree (…/agents/<id>/agent/…) and any
|
|
92
|
-
// auth
|
|
93
|
-
|
|
96
|
+
// `auth` path component under a .brigade dir — denied regardless of basename.
|
|
97
|
+
// Walk the already-split segments (linear, no regex backtracking).
|
|
98
|
+
const sealedPerAgent = segments.some((seg, i) => seg === "agents" && i + 2 < segments.length && segments[i + 2] === "agent" && Boolean(segments[i + 1]));
|
|
99
|
+
const brigadeIdx = segments.indexOf(".brigade");
|
|
100
|
+
const authUnderBrigade = brigadeIdx >= 0 && segments.slice(brigadeIdx + 1).some((seg) => seg.includes("auth"));
|
|
101
|
+
if (sealedPerAgent || authUnderBrigade) {
|
|
94
102
|
return { ok: false, reason: "refusing to attach from the credential store" };
|
|
95
103
|
}
|
|
96
104
|
return { ok: true };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-path-guard.js","sourceRoot":"","sources":["../../src/security/media-path-guard.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAQ7B,kGAAkG;AAClG,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IACnC,MAAM;IACN,QAAQ;IACR,SAAS;IACT,QAAQ;IACR,kBAAkB;IAClB,aAAa;IACb,QAAQ;IACR,YAAY;IACZ,UAAU;IACV,QAAQ;IACR,oCAAoC;IACpC,cAAc;IACd,WAAW;IACX,oBAAoB;IACpB,aAAa;IACb,qBAAqB;
|
|
1
|
+
{"version":3,"file":"media-path-guard.js","sourceRoot":"","sources":["../../src/security/media-path-guard.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
package/scripts/convex-dev.mjs
CHANGED
|
@@ -19,7 +19,7 @@ import { mkdirSync, existsSync, writeFileSync, readFileSync, unlinkSync } from "
|
|
|
19
19
|
import { randomBytes } from "node:crypto";
|
|
20
20
|
import { createServer } from "node:http";
|
|
21
21
|
import { readFile, stat } from "node:fs/promises";
|
|
22
|
-
import { extname, join, dirname, resolve } from "node:path";
|
|
22
|
+
import { extname, join, dirname, resolve, sep } from "node:path";
|
|
23
23
|
import { fileURLToPath } from "node:url";
|
|
24
24
|
|
|
25
25
|
const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), "..");
|
|
@@ -235,12 +235,26 @@ const MIME = {
|
|
|
235
235
|
".woff2": "font/woff2",
|
|
236
236
|
};
|
|
237
237
|
|
|
238
|
+
// Confine a request-derived file path under DASHBOARD_DIR. `req.url` is
|
|
239
|
+
// attacker-controllable (any local process can hit 127.0.0.1:6791), so a
|
|
240
|
+
// decoded `..` segment must never let `join` escape the served root. Resolve
|
|
241
|
+
// to an absolute path and reject anything outside DASHBOARD_DIR.
|
|
242
|
+
const DASHBOARD_ROOT = resolve(DASHBOARD_DIR);
|
|
243
|
+
function confineToDashboard(candidate) {
|
|
244
|
+
const resolved = resolve(candidate);
|
|
245
|
+
if (resolved === DASHBOARD_ROOT || resolved.startsWith(DASHBOARD_ROOT + sep)) {
|
|
246
|
+
return resolved;
|
|
247
|
+
}
|
|
248
|
+
return null;
|
|
249
|
+
}
|
|
250
|
+
|
|
238
251
|
const dashboardServer = createServer(async (req, res) => {
|
|
239
252
|
try {
|
|
240
253
|
let urlPath = decodeURIComponent((req.url ?? "/").split("?")[0]);
|
|
241
254
|
if (urlPath === "/") urlPath = "/index.html";
|
|
242
255
|
|
|
243
|
-
let filePath = join(DASHBOARD_DIR, urlPath);
|
|
256
|
+
let filePath = confineToDashboard(join(DASHBOARD_DIR, urlPath));
|
|
257
|
+
if (!filePath) { res.writeHead(404); res.end("Not Found"); return; }
|
|
244
258
|
|
|
245
259
|
// SPA fallback — if the requested path has no extension and doesn't exist,
|
|
246
260
|
// try $path.html, then fall back to index.html.
|
|
@@ -248,11 +262,12 @@ const dashboardServer = createServer(async (req, res) => {
|
|
|
248
262
|
try { st = await stat(filePath); } catch {}
|
|
249
263
|
if (!st || st.isDirectory()) {
|
|
250
264
|
const candidates = [
|
|
251
|
-
filePath + ".html",
|
|
252
|
-
join(filePath, "index.html"),
|
|
253
|
-
join(
|
|
265
|
+
confineToDashboard(filePath + ".html"),
|
|
266
|
+
confineToDashboard(join(filePath, "index.html")),
|
|
267
|
+
join(DASHBOARD_ROOT, "index.html"),
|
|
254
268
|
];
|
|
255
269
|
for (const c of candidates) {
|
|
270
|
+
if (!c) continue;
|
|
256
271
|
try {
|
|
257
272
|
const s = await stat(c);
|
|
258
273
|
if (s.isFile()) { filePath = c; st = s; break; }
|
|
@@ -294,8 +309,11 @@ const dashboardServer = createServer(async (req, res) => {
|
|
|
294
309
|
}
|
|
295
310
|
res.end(await readFile(filePath));
|
|
296
311
|
} catch (err) {
|
|
312
|
+
// Log the detail locally; never echo the raw error (path/stack) to the
|
|
313
|
+
// HTTP response.
|
|
314
|
+
console.error(`\x1b[31m▌ dashboard request failed: ${String(err)}\x1b[0m`);
|
|
297
315
|
res.writeHead(500);
|
|
298
|
-
res.end(
|
|
316
|
+
res.end("Internal Server Error");
|
|
299
317
|
}
|
|
300
318
|
});
|
|
301
319
|
|
|
@@ -208,7 +208,7 @@ bash pty:true workdir:~/project command:"opencode run 'Your task'"
|
|
|
208
208
|
## Pi Coding Agent
|
|
209
209
|
|
|
210
210
|
```bash
|
|
211
|
-
# Install: npm install -g @
|
|
211
|
+
# Install: npm install -g @earendil-works/pi-coding-agent
|
|
212
212
|
bash pty:true workdir:~/project command:"pi 'Your task'"
|
|
213
213
|
|
|
214
214
|
# Non-interactive mode (PTY still recommended)
|