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 +2 -2
- package/docs/container-lifecycle.md +1 -1
- package/package.json +1 -1
- package/src/core/permissions.ts +15 -8
- package/src/storage/db.ts +9 -0
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 #
|
|
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 (
|
|
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
|
|
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
package/src/core/permissions.ts
CHANGED
|
@@ -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.
|
|
93
|
-
* `role.member.permissions` override
|
|
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
|
-
|
|
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,
|