mercury-agent 0.4.28 → 0.5.1
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 +451 -451
- package/container/Dockerfile +127 -127
- package/container/Dockerfile.base +109 -109
- package/container/Dockerfile.power +17 -17
- package/container/agent-package.json +8 -8
- package/container/build.sh +54 -54
- package/docs/ARCHITECTURE.md +4 -0
- package/docs/ROADMAP.md +4 -5
- package/docs/{backlog/applicative-profiles.md → archive/applicative-profiles/2026-07-01-applicative-profiles.md} +29 -18
- package/docs/{backlog/caller-bound-capability-token.md → archive/applicative-profiles/2026-07-01-caller-bound-capability-token.md} +15 -11
- package/docs/archive/summarization/2026-07-02-recent-dev-summary.md +71 -0
- package/docs/auth/dashboard.md +28 -28
- package/docs/auth/overview.md +109 -109
- package/docs/auth/whatsapp.md +173 -173
- package/docs/authoring-profiles.md +174 -0
- package/docs/configuration.md +54 -54
- package/docs/container-lifecycle.md +349 -349
- package/docs/{bugs/bwrap-privileged-linux-docker.md → debug/major/2026-07-02-bwrap-privileged-linux-docker.md} +21 -1
- package/docs/{bugs/e2big-prompt-delivery-fix.md → debug/major/2026-07-02-e2big-prompt-delivery-fix.md} +27 -1
- package/docs/{bugs/registry-pull-no-local-fallback.md → debug/major/2026-07-02-registry-pull-no-local-fallback.md} +27 -1
- package/docs/debug/summarization/2026-07-02-common-bug-patterns.md +72 -0
- package/docs/deployment.md +199 -199
- package/docs/extensions.md +375 -375
- package/docs/graceful-shutdown.md +62 -62
- package/docs/kb-distillation.md +77 -77
- package/docs/media/overview.md +140 -140
- package/docs/media/whatsapp.md +171 -171
- package/docs/memory.md +137 -137
- package/docs/permissions.md +217 -217
- package/docs/pipeline.md +228 -228
- package/docs/prd-chat-memory.md +76 -76
- package/docs/prd-config-load.md +82 -82
- package/docs/rate-limiting.md +229 -229
- package/docs/scheduler.md +288 -288
- package/docs/setup-discord.md +100 -100
- package/docs/setup-slack.md +119 -119
- package/docs/setup-whatsapp.md +94 -94
- package/docs/subagents.md +166 -166
- package/docs/web-search.md +62 -62
- package/examples/extensions/README.md +12 -12
- package/examples/extensions/charts/index.ts +13 -13
- package/examples/extensions/charts/skill/SKILL.md +98 -98
- package/examples/extensions/gws/README.md +52 -52
- package/examples/extensions/gws/skill/SKILL.md +57 -57
- package/examples/extensions/gws/skill/references/calendar.md +101 -101
- package/examples/extensions/gws/skill/references/docs.md +65 -65
- package/examples/extensions/gws/skill/references/drive.md +79 -79
- package/examples/extensions/gws/skill/references/gmail.md +85 -85
- package/examples/extensions/gws/skill/references/sheets.md +60 -60
- package/examples/extensions/napkin/skill/SKILL.md +728 -728
- package/examples/extensions/pdf/skill/LICENSE.txt +30 -30
- package/examples/extensions/pdf/skill/SKILL.md +314 -314
- package/examples/extensions/pdf/skill/forms.md +294 -294
- package/examples/extensions/pdf/skill/reference.md +611 -611
- package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -65
- package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -11
- package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -33
- package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -37
- package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -122
- package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -115
- package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -98
- package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -107
- package/examples/extensions/permission-guard/index.ts +65 -65
- package/examples/extensions/pinchtab/skill/SKILL.md +224 -224
- package/examples/extensions/pinchtab/skill/TRUST.md +69 -69
- package/examples/extensions/pinchtab/skill/references/api.md +297 -297
- package/examples/extensions/pinchtab/skill/references/env.md +45 -45
- package/examples/extensions/pinchtab/skill/references/profiles.md +107 -107
- package/examples/extensions/tradestation/host/refresh.ts +102 -102
- package/examples/extensions/tradestation/index.ts +153 -153
- package/examples/extensions/tradestation/skill/SKILL.md +67 -67
- package/examples/extensions/voice-synth/index.ts +94 -94
- package/examples/extensions/voice-synth/skill/SKILL.md +38 -38
- package/examples/extensions/voice-transcribe/requirements.txt +8 -8
- package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -179
- package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -53
- package/examples/extensions/yahoo-mail/cli/package.json +13 -13
- package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -78
- package/package.json +106 -106
- package/resources/agents/explore.md +50 -50
- package/resources/agents/worker.md +24 -24
- package/resources/connection-env-vars.json +25 -25
- package/resources/pi-extensions/subagent/agents.ts +126 -126
- package/resources/pi-extensions/subagent/index.ts +964 -964
- package/resources/profiles/coding/AGENTS.md +43 -43
- package/resources/profiles/coding/mercury-profile.yaml +15 -15
- package/resources/profiles/general/AGENTS.md +31 -31
- package/resources/profiles/general/mercury-profile.yaml +15 -15
- package/resources/profiles/research/AGENTS.md +40 -40
- package/resources/profiles/research/mercury-profile.yaml +15 -15
- package/resources/skills/config/SKILL.md +25 -25
- package/resources/skills/context/SKILL.md +33 -33
- package/resources/skills/conversation-recap/SKILL.md +19 -19
- package/resources/skills/mutes/SKILL.md +31 -31
- package/resources/skills/permissions/SKILL.md +19 -19
- package/resources/skills/preferences/SKILL.md +31 -31
- package/resources/skills/recall/SKILL.md +24 -24
- package/resources/skills/roles/SKILL.md +18 -18
- package/resources/skills/spaces/SKILL.md +18 -18
- package/resources/skills/tasks/SKILL.md +45 -45
- package/resources/templates/AGENTS.md +157 -157
- package/resources/templates/env.template +38 -38
- package/resources/templates/mercury.example.yaml +15 -0
- package/src/agent/container-runner.ts +23 -0
- package/src/cli/mercury.ts +38 -6
- package/src/cli/mrctl.ts +25 -0
- package/src/config-file.ts +3 -0
- package/src/config.ts +15 -0
- package/src/core/api.ts +23 -3
- package/src/core/caller-token.ts +101 -0
- package/src/core/permissions.ts +37 -5
- package/src/core/profiles.ts +110 -84
- package/src/core/routes/capability.ts +70 -0
- package/src/core/routes/index.ts +1 -0
- package/src/core/runtime.ts +14 -0
- package/src/dashboard/index.html +729 -729
- package/src/extensions/api.ts +21 -0
- package/src/extensions/loader.ts +15 -0
- package/src/extensions/types.ts +55 -0
- package/src/main.ts +19 -0
- package/docs/pending-updates/dm-auto-space.md +0 -15
- /package/docs/archive/{2026-07-01-dm-auto-space.md → applicative-profiles/2026-07-01-dm-auto-space.md} +0 -0
package/src/extensions/api.ts
CHANGED
|
@@ -11,6 +11,7 @@ import type { ModelCapabilityKey } from "../agent/model-capabilities.js";
|
|
|
11
11
|
import { registerPermission } from "../core/permissions.js";
|
|
12
12
|
import type { Db } from "../storage/db.js";
|
|
13
13
|
import type {
|
|
14
|
+
CapabilityHandler,
|
|
14
15
|
CliDef,
|
|
15
16
|
ConfigDef,
|
|
16
17
|
ConnectionCategory,
|
|
@@ -63,6 +64,7 @@ export class MercuryExtensionAPIImpl implements MercuryExtensionAPI {
|
|
|
63
64
|
jobs: new Map(),
|
|
64
65
|
configs: new Map(),
|
|
65
66
|
widgets: [],
|
|
67
|
+
capabilities: new Map(),
|
|
66
68
|
envVars: [],
|
|
67
69
|
};
|
|
68
70
|
}
|
|
@@ -235,6 +237,25 @@ export class MercuryExtensionAPIImpl implements MercuryExtensionAPI {
|
|
|
235
237
|
this.meta.connection = def;
|
|
236
238
|
}
|
|
237
239
|
|
|
240
|
+
capability(name: string, handler: CapabilityHandler): void {
|
|
241
|
+
if (!name || !/^[a-z0-9][a-z0-9-]*$/.test(name)) {
|
|
242
|
+
throw new Error(
|
|
243
|
+
`Extension "${this.name}": capability() requires a lowercase alphanumeric name`,
|
|
244
|
+
);
|
|
245
|
+
}
|
|
246
|
+
if (typeof handler !== "function") {
|
|
247
|
+
throw new Error(
|
|
248
|
+
`Extension "${this.name}": capability("${name}") requires a handler function`,
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
if (this.meta.capabilities.has(name)) {
|
|
252
|
+
throw new Error(
|
|
253
|
+
`Extension "${this.name}": capability "${name}" already registered`,
|
|
254
|
+
);
|
|
255
|
+
}
|
|
256
|
+
this.meta.capabilities.set(name, handler);
|
|
257
|
+
}
|
|
258
|
+
|
|
238
259
|
get store(): ExtensionStore {
|
|
239
260
|
return {
|
|
240
261
|
get: (key: string) => this.db.getExtState(this.name, key),
|
package/src/extensions/loader.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { MercuryExtensionAPIImpl } from "./api.js";
|
|
|
14
14
|
import type { ConfigRegistry } from "./config-registry.js";
|
|
15
15
|
import { RESERVED_EXTENSION_NAMES } from "./reserved.js";
|
|
16
16
|
import type {
|
|
17
|
+
CapabilityHandler,
|
|
17
18
|
EventHandler,
|
|
18
19
|
ExtensionMeta,
|
|
19
20
|
JobDef,
|
|
@@ -182,6 +183,20 @@ export class ExtensionRegistry {
|
|
|
182
183
|
return this.list().filter((ext) => ext.clis.length > 0);
|
|
183
184
|
}
|
|
184
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Find a registered host-side capability handler by name, with its owning
|
|
188
|
+
* extension. Returns undefined when no extension registered it.
|
|
189
|
+
*/
|
|
190
|
+
getCapability(
|
|
191
|
+
name: string,
|
|
192
|
+
): { ext: ExtensionMeta; handler: CapabilityHandler } | undefined {
|
|
193
|
+
for (const ext of this.extensions.values()) {
|
|
194
|
+
const handler = ext.capabilities.get(name);
|
|
195
|
+
if (handler) return { ext, handler };
|
|
196
|
+
}
|
|
197
|
+
return undefined;
|
|
198
|
+
}
|
|
199
|
+
|
|
185
200
|
/** Get all env var source names claimed by extensions (for passthrough filtering). */
|
|
186
201
|
getClaimedEnvSources(): Set<string> {
|
|
187
202
|
const sources = new Set<string>();
|
package/src/extensions/types.ts
CHANGED
|
@@ -187,6 +187,45 @@ export interface WidgetDef {
|
|
|
187
187
|
render: (ctx: MercuryExtensionContext) => string;
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
+
// ---------------------------------------------------------------------------
|
|
191
|
+
// Capabilities — host-side broker actions invoked from the container
|
|
192
|
+
// ---------------------------------------------------------------------------
|
|
193
|
+
|
|
194
|
+
/** A single broker request, dispatched from `POST /api/capability/:name/:action`. */
|
|
195
|
+
export interface CapabilityRequest {
|
|
196
|
+
/** Capability name (matches the required permission). */
|
|
197
|
+
name: string;
|
|
198
|
+
/** Sub-action within the capability (e.g. "book", "cancel"). */
|
|
199
|
+
action: string;
|
|
200
|
+
/**
|
|
201
|
+
* The authoritative, token-derived caller id. Trustworthy for ownership
|
|
202
|
+
* checks — NOT a container-supplied argument.
|
|
203
|
+
*/
|
|
204
|
+
callerId: string;
|
|
205
|
+
/** The space the call was made from. */
|
|
206
|
+
spaceId: string;
|
|
207
|
+
/** Parsed JSON request body (or null). */
|
|
208
|
+
body: unknown;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/** Result returned by a capability handler. */
|
|
212
|
+
export interface CapabilityResult {
|
|
213
|
+
/** HTTP status to return (default 200). */
|
|
214
|
+
status?: number;
|
|
215
|
+
/** JSON-serializable response payload. */
|
|
216
|
+
data: unknown;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* Host-side handler for a capability. Runs in the Mercury host process with the
|
|
221
|
+
* full extension context (credentials in host storage stay on the host). The
|
|
222
|
+
* container never sees secrets — only the returned `data`.
|
|
223
|
+
*/
|
|
224
|
+
export type CapabilityHandler = (
|
|
225
|
+
req: CapabilityRequest,
|
|
226
|
+
ctx: MercuryExtensionContext,
|
|
227
|
+
) => Promise<CapabilityResult>;
|
|
228
|
+
|
|
190
229
|
// ---------------------------------------------------------------------------
|
|
191
230
|
// Store
|
|
192
231
|
// ---------------------------------------------------------------------------
|
|
@@ -310,6 +349,20 @@ export interface MercuryExtensionAPI {
|
|
|
310
349
|
*/
|
|
311
350
|
connection(def: ConnectionDef): void;
|
|
312
351
|
|
|
352
|
+
/**
|
|
353
|
+
* Register a host-side capability handler, invoked from the container via
|
|
354
|
+
* `mrctl capability <name> <action> <json>` → `POST /api/capability/:name/:action`.
|
|
355
|
+
* The caller must hold the `<name>` permission. Credentials used by the
|
|
356
|
+
* handler stay on the host and never enter the agent container.
|
|
357
|
+
*
|
|
358
|
+
* @example
|
|
359
|
+
* mercury.capability("barber", async (req, ctx) => {
|
|
360
|
+
* if (req.action === "book") return { data: await book(req.callerId, req.body) };
|
|
361
|
+
* return { status: 400, data: { error: "unknown action" } };
|
|
362
|
+
* });
|
|
363
|
+
*/
|
|
364
|
+
capability(name: string, handler: CapabilityHandler): void;
|
|
365
|
+
|
|
313
366
|
/** Scoped key-value store for persistent extension state. */
|
|
314
367
|
readonly store: ExtensionStore;
|
|
315
368
|
}
|
|
@@ -448,6 +501,8 @@ export interface ExtensionMeta {
|
|
|
448
501
|
configs: Map<string, ConfigDef>;
|
|
449
502
|
/** Dashboard widgets. */
|
|
450
503
|
widgets: WidgetDef[];
|
|
504
|
+
/** Host-side capability handlers, keyed by capability name. */
|
|
505
|
+
capabilities: Map<string, CapabilityHandler>;
|
|
451
506
|
/** Declared environment variables. */
|
|
452
507
|
envVars: EnvDef[];
|
|
453
508
|
/** Personal service connection metadata, if declared via `mercury.connection()`. */
|
package/src/main.ts
CHANGED
|
@@ -34,6 +34,11 @@ import { WhatsAppBridge } from "./bridges/whatsapp.js";
|
|
|
34
34
|
import { createChatShim } from "./chat-shim.js";
|
|
35
35
|
import { loadConfig, resolveProjectPath } from "./config.js";
|
|
36
36
|
import { createMessageHandler } from "./core/handler.js";
|
|
37
|
+
import { setActiveProfileMemberPermissions } from "./core/permissions.js";
|
|
38
|
+
import {
|
|
39
|
+
loadActiveProfile,
|
|
40
|
+
setActiveProfileSystemPrompt,
|
|
41
|
+
} from "./core/profiles.js";
|
|
37
42
|
import { MercuryCoreRuntime } from "./core/runtime.js";
|
|
38
43
|
import { runStorageCleanup } from "./core/storage-cleanup.js";
|
|
39
44
|
import { isOverQuota } from "./core/storage-guard.js";
|
|
@@ -214,6 +219,20 @@ async function main() {
|
|
|
214
219
|
]);
|
|
215
220
|
logger.info("Extensions loaded", { count: registry.size });
|
|
216
221
|
|
|
222
|
+
// Activate the applicative profile (project-wide member permission scoping).
|
|
223
|
+
// Done after extensions load so extension-registered permissions (e.g. a
|
|
224
|
+
// profile's own CLI permission) are recognized as valid.
|
|
225
|
+
const activeProfile = loadActiveProfile(resolveProjectPath(config.dataDir));
|
|
226
|
+
if (activeProfile) {
|
|
227
|
+
setActiveProfileMemberPermissions(activeProfile.memberPermissions ?? null);
|
|
228
|
+
setActiveProfileSystemPrompt(activeProfile.systemPrompt ?? null);
|
|
229
|
+
logger.info("Applicative profile active", {
|
|
230
|
+
profile: activeProfile.name,
|
|
231
|
+
memberPermissions:
|
|
232
|
+
activeProfile.memberPermissions?.join(",") ?? "(unscoped)",
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
|
|
217
236
|
logExtensionCapabilityMismatches(
|
|
218
237
|
registry.list(),
|
|
219
238
|
config.resolvedModelChainCapabilities,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
slug: dm-auto-space
|
|
3
|
-
shipped: 2026-07-01
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
## ROADMAP changes
|
|
7
|
-
|
|
8
|
-
**Remove from:** Next (table row where Item = dm-auto-space)
|
|
9
|
-
|
|
10
|
-
**Also pull:** none
|
|
11
|
-
|
|
12
|
-
**Add to Shipped table** (insert at top, after header row):
|
|
13
|
-
| **dm-auto-space** | 2026-07-01 | Auto-create space per customer DM with rate limits and dashboard controls |
|
|
14
|
-
|
|
15
|
-
**Milestone Map:** none
|
|
File without changes
|