mercury-agent 0.5.10 → 0.5.11

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 CHANGED
@@ -218,7 +218,7 @@ mercury setup # Interactive guided setup (recommended for new proje
218
218
  mercury setup --profile <name> # Create from a profile (general, coding, research, or path/URL)
219
219
  mercury init # Manual init (creates .env, .mercury structure)
220
220
  mercury run
221
- mercury build # only needed when developing the base image from source
221
+ mercury build # rebuild agent container image (required after updates)
222
222
  mercury status
223
223
  mercury doctor # preflight check — validates Docker, Bun, credentials, adapters
224
224
 
@@ -256,7 +256,7 @@ mercury ext create <name> # Scaffold a new extension
256
256
  mercury ext validate <name> # Validate extension structure and load
257
257
  mercury ext test <name> # Dry-run load extension
258
258
 
259
- # service (recommended for background)
259
+ # service (macOS/Linux only — uses launchd/systemd)
260
260
  mercury service install
261
261
  mercury service uninstall
262
262
  mercury service status
@@ -4,7 +4,7 @@ Mercury runs agent code inside Docker containers. This document covers how conta
4
4
 
5
5
  ## Deployment Topology
6
6
 
7
- Mercury uses a two-layer container model. The layers differ between local and production (Hetzner) deployments.
7
+ Mercury uses a two-layer container model. The layers differ between local and production deployments.
8
8
 
9
9
  ### Local (`mercury run`)
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mercury-agent",
3
- "version": "0.5.10",
3
+ "version": "0.5.11",
4
4
  "description": "Personal AI assistant for chat platforms (WhatsApp, Slack, Discord, Telegram)",
5
5
  "license": "MIT",
6
6
  "author": "Avishai Tsabari",
@@ -89,8 +89,9 @@ export function resetPermissions(): void {
89
89
  * Project-wide (one profile per deployment): set once at startup from the
90
90
  * persisted profile activation. When non-null it is the EXHAUSTIVE member
91
91
  * permission set — no extension defaults are merged — so raw capabilities stay
92
- * admin-only unless the profile lists them. A per-space
93
- * `role.member.permissions` override still takes precedence over this.
92
+ * admin-only unless the profile lists them. An explicit per-space
93
+ * `role.member.permissions` override (set by an admin, dashboard, or console)
94
+ * still takes precedence, but dm-auto-space seeded defaults do not.
94
95
  */
95
96
  let activeProfileMemberPermissions: string[] | null = null;
96
97
 
@@ -182,15 +183,21 @@ export function getRolePermissions(
182
183
  const key = `role.${role}.permissions`;
183
184
  const stored = db.getSpaceConfig(spaceId, key);
184
185
 
185
- // Explicit per-space override wins over everything.
186
186
  if (stored !== null) {
187
- return toPermissionSet(stored.split(","));
187
+ // dm-auto-space seeded defaults yield to the active profile — they are
188
+ // deployment defaults, not intentional admin overrides. Any other source
189
+ // (admin, dashboard, console) is an explicit override and wins.
190
+ const isSeededDefault =
191
+ role === "member" &&
192
+ Array.isArray(activeProfileMemberPermissions) &&
193
+ db.getSpaceConfigUpdatedBy(spaceId, key) === "dm-auto-space";
194
+
195
+ if (!isSeededDefault) {
196
+ return toPermissionSet(stored.split(","));
197
+ }
198
+ // Fall through to profile check below.
188
199
  }
189
200
 
190
- // An active profile sets the exhaustive member permission set (project-wide),
191
- // ahead of built-in/extension defaults. Members only; profiles never widen
192
- // admin/system. Guard with Array.isArray so a malformed persisted activation
193
- // (missing/non-array value) falls back to defaults instead of throwing here.
194
201
  if (role === "member" && Array.isArray(activeProfileMemberPermissions)) {
195
202
  return toPermissionSet(activeProfileMemberPermissions);
196
203
  }
package/src/storage/db.ts CHANGED
@@ -1276,6 +1276,15 @@ export class Db {
1276
1276
  return row?.value ?? null;
1277
1277
  }
1278
1278
 
1279
+ getSpaceConfigUpdatedBy(spaceId: string, key: string): string | null {
1280
+ const row = this.db
1281
+ .query(
1282
+ "SELECT updated_by FROM space_config WHERE space_id = ? AND key = ?",
1283
+ )
1284
+ .get(spaceId, key) as { updated_by: string } | null;
1285
+ return row?.updated_by ?? null;
1286
+ }
1287
+
1279
1288
  setSpaceConfig(
1280
1289
  spaceId: string,
1281
1290
  key: string,