mercury-agent 0.5.11 → 0.5.12
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/package.json +1 -1
- package/src/cli/mercury.ts +27 -0
- package/src/core/api-types.ts +2 -0
- package/src/core/routes/capability.ts +7 -0
package/package.json
CHANGED
package/src/cli/mercury.ts
CHANGED
|
@@ -2207,6 +2207,33 @@ profilesCommand
|
|
|
2207
2207
|
console.log(`\nUse with: mercury setup --profile ${absOutput}`);
|
|
2208
2208
|
});
|
|
2209
2209
|
|
|
2210
|
+
profilesCommand
|
|
2211
|
+
.command("apply <source>")
|
|
2212
|
+
.description("Apply an external profile (non-interactive)")
|
|
2213
|
+
.action(async (source: string) => {
|
|
2214
|
+
const { resolveProfileSource, loadProfileFromDir, applyProfile } =
|
|
2215
|
+
await import("../core/profiles.js");
|
|
2216
|
+
|
|
2217
|
+
let cleanup = () => {};
|
|
2218
|
+
try {
|
|
2219
|
+
const resolved = resolveProfileSource(source, PROFILES_DIR);
|
|
2220
|
+
cleanup = resolved.cleanup;
|
|
2221
|
+
const profile = loadProfileFromDir(resolved.dir);
|
|
2222
|
+
applyProfile(profile, resolved.dir, CWD);
|
|
2223
|
+
console.log(`Profile "${profile.name}" applied.`);
|
|
2224
|
+
console.log(
|
|
2225
|
+
"Run 'mercury service install' to rebuild the container image.",
|
|
2226
|
+
);
|
|
2227
|
+
} catch (err) {
|
|
2228
|
+
console.error(
|
|
2229
|
+
`Failed to apply profile: ${err instanceof Error ? err.message : String(err)}`,
|
|
2230
|
+
);
|
|
2231
|
+
process.exit(1);
|
|
2232
|
+
} finally {
|
|
2233
|
+
cleanup();
|
|
2234
|
+
}
|
|
2235
|
+
});
|
|
2236
|
+
|
|
2210
2237
|
const spacesCommand = program.command("spaces").description("Manage spaces");
|
|
2211
2238
|
|
|
2212
2239
|
spacesCommand
|
package/src/core/api-types.ts
CHANGED
|
@@ -3,6 +3,7 @@ import type { AgentContainerRunner } from "../agent/container-runner.js";
|
|
|
3
3
|
import type { AppConfig } from "../config.js";
|
|
4
4
|
import type { ConfigRegistry } from "../extensions/config-registry.js";
|
|
5
5
|
import type { ExtensionRegistry } from "../extensions/loader.js";
|
|
6
|
+
import { logger } from "../logger.js";
|
|
6
7
|
import type { Db } from "../storage/db.js";
|
|
7
8
|
import type { TradeStationFetch } from "../tradestation/host-api.js";
|
|
8
9
|
import { hasPermission } from "./permissions.js";
|
|
@@ -49,6 +50,7 @@ export const checkPerm = (
|
|
|
49
50
|
const { db } = c.get("apiCtx");
|
|
50
51
|
|
|
51
52
|
if (!hasPermission(db, spaceId, role, permission)) {
|
|
53
|
+
logger.warn("Permission denied", { spaceId, role, permission });
|
|
52
54
|
return c.json(
|
|
53
55
|
{ error: `Forbidden: requires '${permission}' permission` },
|
|
54
56
|
403,
|
|
@@ -33,6 +33,13 @@ capability.post("/:name/:action", async (c) => {
|
|
|
33
33
|
const { callerId, spaceId } = getAuth(c);
|
|
34
34
|
const { db, config, registry } = getApiCtx(c);
|
|
35
35
|
|
|
36
|
+
logger.info("Capability request", {
|
|
37
|
+
capability: name,
|
|
38
|
+
action,
|
|
39
|
+
callerId,
|
|
40
|
+
spaceId,
|
|
41
|
+
});
|
|
42
|
+
|
|
36
43
|
// Authorization reuses the permission whose name equals the capability, so a
|
|
37
44
|
// single grant (e.g. "barber" in member_permissions) gates both the CLI and
|
|
38
45
|
// this route.
|