mercury-agent 0.4.5
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/LICENSE +22 -0
- package/README.md +438 -0
- package/container/Dockerfile +127 -0
- package/container/Dockerfile.base +109 -0
- package/container/Dockerfile.power +17 -0
- package/container/agent-package.json +8 -0
- package/container/build.sh +54 -0
- package/docs/TODOS.md +147 -0
- package/docs/auth/dashboard.md +28 -0
- package/docs/auth/overview.md +109 -0
- package/docs/auth/whatsapp.md +173 -0
- package/docs/configuration.md +54 -0
- package/docs/container-lifecycle.md +349 -0
- package/docs/context-architecture.md +87 -0
- package/docs/deployment.md +199 -0
- package/docs/extensions.md +375 -0
- package/docs/graceful-shutdown.md +62 -0
- package/docs/kb-distillation.md +77 -0
- package/docs/media/overview.md +140 -0
- package/docs/media/whatsapp.md +171 -0
- package/docs/memory.md +137 -0
- package/docs/permissions.md +217 -0
- package/docs/pipeline.md +228 -0
- package/docs/prd-chat-memory.md +76 -0
- package/docs/prd-config-load.md +82 -0
- package/docs/rate-limiting.md +166 -0
- package/docs/scheduler.md +288 -0
- package/docs/setup-discord.md +100 -0
- package/docs/setup-slack.md +119 -0
- package/docs/setup-whatsapp.md +94 -0
- package/docs/subagents.md +166 -0
- package/docs/web-search.md +62 -0
- package/examples/extensions/README.md +12 -0
- package/examples/extensions/charts/index.ts +13 -0
- package/examples/extensions/charts/skill/SKILL.md +98 -0
- package/examples/extensions/gws/README.md +52 -0
- package/examples/extensions/gws/index.ts +106 -0
- package/examples/extensions/gws/skill/SKILL.md +57 -0
- package/examples/extensions/gws/skill/references/calendar.md +101 -0
- package/examples/extensions/gws/skill/references/docs.md +65 -0
- package/examples/extensions/gws/skill/references/drive.md +79 -0
- package/examples/extensions/gws/skill/references/gmail.md +85 -0
- package/examples/extensions/gws/skill/references/sheets.md +60 -0
- package/examples/extensions/napkin/index.ts +821 -0
- package/examples/extensions/napkin/prompts/consolidation-monthly.md +73 -0
- package/examples/extensions/napkin/prompts/consolidation-weekly.md +67 -0
- package/examples/extensions/napkin/prompts/kb-distillation.md +176 -0
- package/examples/extensions/napkin/skill/SKILL.md +728 -0
- package/examples/extensions/pdf/index.ts +23 -0
- package/examples/extensions/pdf/skill/LICENSE.txt +30 -0
- package/examples/extensions/pdf/skill/SKILL.md +314 -0
- package/examples/extensions/pdf/skill/forms.md +294 -0
- package/examples/extensions/pdf/skill/reference.md +612 -0
- package/examples/extensions/pdf/skill/scripts/check_bounding_boxes.py +65 -0
- package/examples/extensions/pdf/skill/scripts/check_fillable_fields.py +11 -0
- package/examples/extensions/pdf/skill/scripts/convert_pdf_to_images.py +33 -0
- package/examples/extensions/pdf/skill/scripts/create_validation_image.py +37 -0
- package/examples/extensions/pdf/skill/scripts/extract_form_field_info.py +122 -0
- package/examples/extensions/pdf/skill/scripts/extract_form_structure.py +115 -0
- package/examples/extensions/pdf/skill/scripts/fill_fillable_fields.py +98 -0
- package/examples/extensions/pdf/skill/scripts/fill_pdf_form_with_annotations.py +107 -0
- package/examples/extensions/permission-guard/index.ts +65 -0
- package/examples/extensions/pinchtab/index.ts +199 -0
- package/examples/extensions/pinchtab/lib/session-injector.ts +144 -0
- package/examples/extensions/pinchtab/skill/SKILL.md +224 -0
- package/examples/extensions/pinchtab/skill/TRUST.md +69 -0
- package/examples/extensions/pinchtab/skill/references/api.md +297 -0
- package/examples/extensions/pinchtab/skill/references/env.md +45 -0
- package/examples/extensions/pinchtab/skill/references/profiles.md +107 -0
- package/examples/extensions/tradestation/host/refresh.ts +102 -0
- package/examples/extensions/tradestation/index.ts +153 -0
- package/examples/extensions/tradestation/skill/SKILL.md +67 -0
- package/examples/extensions/tradestation/skill/scripts/ts-cli.ts +111 -0
- package/examples/extensions/voice-synth/index.ts +94 -0
- package/examples/extensions/voice-synth/skill/SKILL.md +38 -0
- package/examples/extensions/voice-transcribe/index.ts +381 -0
- package/examples/extensions/voice-transcribe/requirements.txt +8 -0
- package/examples/extensions/voice-transcribe/scripts/transcribe.py +179 -0
- package/examples/extensions/voice-transcribe/skill/SKILL.md +53 -0
- package/examples/extensions/web-search/index.ts +22 -0
- package/examples/extensions/web-search/skill/SKILL.md +114 -0
- package/examples/extensions/web-search/skill/references/apartments.md +178 -0
- package/examples/extensions/web-search/skill/references/car-purchase.md +132 -0
- package/examples/extensions/web-search/skill/references/car-rental.md +113 -0
- package/examples/extensions/web-search/skill/references/flights.md +133 -0
- package/examples/extensions/web-search/skill/references/hotels.md +148 -0
- package/examples/extensions/yahoo-mail/cli/bun.lock +66 -0
- package/examples/extensions/yahoo-mail/cli/package.json +13 -0
- package/examples/extensions/yahoo-mail/cli/ymail.mjs +353 -0
- package/examples/extensions/yahoo-mail/index.ts +57 -0
- package/examples/extensions/yahoo-mail/skill/SKILL.md +78 -0
- package/package.json +106 -0
- package/resources/agents/explore.md +50 -0
- package/resources/agents/worker.md +24 -0
- package/resources/builtin-extensions.txt +3 -0
- package/resources/connection-env-vars.json +25 -0
- package/resources/extensions/.gitkeep +0 -0
- package/resources/pi-extensions/subagent/agents.ts +126 -0
- package/resources/pi-extensions/subagent/index.ts +964 -0
- package/resources/profiles/coding/AGENTS.md +43 -0
- package/resources/profiles/coding/mercury-profile.yaml +15 -0
- package/resources/profiles/general/AGENTS.md +31 -0
- package/resources/profiles/general/mercury-profile.yaml +15 -0
- package/resources/profiles/research/AGENTS.md +40 -0
- package/resources/profiles/research/mercury-profile.yaml +15 -0
- package/resources/skills/config/SKILL.md +25 -0
- package/resources/skills/context/SKILL.md +33 -0
- package/resources/skills/conversation-recap/SKILL.md +19 -0
- package/resources/skills/media/SKILL.md +27 -0
- package/resources/skills/mutes/SKILL.md +31 -0
- package/resources/skills/permissions/SKILL.md +19 -0
- package/resources/skills/preferences/SKILL.md +31 -0
- package/resources/skills/recall/SKILL.md +24 -0
- package/resources/skills/roles/SKILL.md +18 -0
- package/resources/skills/spaces/SKILL.md +18 -0
- package/resources/skills/tasks/SKILL.md +45 -0
- package/resources/templates/AGENTS.md +157 -0
- package/resources/templates/env.template +34 -0
- package/resources/templates/mercury.example.yaml +75 -0
- package/src/adapters/discord-native.ts +534 -0
- package/src/adapters/discord.ts +38 -0
- package/src/adapters/setup.ts +89 -0
- package/src/adapters/slack.ts +9 -0
- package/src/adapters/whatsapp-media.ts +337 -0
- package/src/adapters/whatsapp.ts +629 -0
- package/src/agent/api-socket.ts +127 -0
- package/src/agent/container-entry.ts +967 -0
- package/src/agent/container-error.ts +49 -0
- package/src/agent/container-runner.ts +1272 -0
- package/src/agent/model-capabilities-core.ts +23 -0
- package/src/agent/model-capabilities.ts +231 -0
- package/src/agent/pi-failure-class.ts +83 -0
- package/src/agent/pi-jsonl-parser.ts +306 -0
- package/src/agent/preferences-prompt.ts +20 -0
- package/src/agent/user-error-messages.ts +78 -0
- package/src/bridges/discord.ts +171 -0
- package/src/bridges/slack.ts +177 -0
- package/src/bridges/teams.ts +160 -0
- package/src/bridges/telegram.ts +571 -0
- package/src/bridges/whatsapp.ts +290 -0
- package/src/chat-shim.ts +259 -0
- package/src/cli/mercury.ts +2508 -0
- package/src/cli/mrctl-http.ts +27 -0
- package/src/cli/mrctl.ts +611 -0
- package/src/cli/whatsapp-auth.ts +260 -0
- package/src/config-file.ts +397 -0
- package/src/config-model-chain.ts +30 -0
- package/src/config.ts +316 -0
- package/src/core/api-types.ts +58 -0
- package/src/core/api.ts +105 -0
- package/src/core/commands.ts +76 -0
- package/src/core/conversation.ts +47 -0
- package/src/core/handler.ts +206 -0
- package/src/core/media.ts +200 -0
- package/src/core/mute-duration.ts +22 -0
- package/src/core/outbox.ts +76 -0
- package/src/core/permissions.ts +192 -0
- package/src/core/profiles.ts +245 -0
- package/src/core/rate-limiter.ts +127 -0
- package/src/core/router.ts +191 -0
- package/src/core/routes/chat.ts +172 -0
- package/src/core/routes/config-builtin.ts +107 -0
- package/src/core/routes/config.ts +81 -0
- package/src/core/routes/connections.ts +190 -0
- package/src/core/routes/console.ts +668 -0
- package/src/core/routes/control.ts +46 -0
- package/src/core/routes/conversations.ts +66 -0
- package/src/core/routes/dashboard.ts +2491 -0
- package/src/core/routes/extensions.ts +37 -0
- package/src/core/routes/index.ts +14 -0
- package/src/core/routes/media.ts +72 -0
- package/src/core/routes/messages.ts +37 -0
- package/src/core/routes/mutes.ts +89 -0
- package/src/core/routes/prefs.ts +95 -0
- package/src/core/routes/roles.ts +125 -0
- package/src/core/routes/spaces.ts +60 -0
- package/src/core/routes/storage.ts +126 -0
- package/src/core/routes/tasks.ts +189 -0
- package/src/core/routes/tradestation.ts +268 -0
- package/src/core/routes/tts.ts +51 -0
- package/src/core/runtime.ts +1140 -0
- package/src/core/space-queue.ts +103 -0
- package/src/core/storage-cleanup.ts +140 -0
- package/src/core/storage-guard.ts +24 -0
- package/src/core/task-scheduler.ts +132 -0
- package/src/core/telegram-format.ts +178 -0
- package/src/core/trigger.ts +142 -0
- package/src/dashboard/index.html +729 -0
- package/src/dashboard/tokens.css +53 -0
- package/src/extensions/api.ts +252 -0
- package/src/extensions/catalog.ts +117 -0
- package/src/extensions/config-registry.ts +83 -0
- package/src/extensions/context.ts +36 -0
- package/src/extensions/hooks.ts +156 -0
- package/src/extensions/image-builder.ts +617 -0
- package/src/extensions/installer.ts +306 -0
- package/src/extensions/jobs.ts +122 -0
- package/src/extensions/loader.ts +271 -0
- package/src/extensions/permission-guard.ts +52 -0
- package/src/extensions/reserved.ts +28 -0
- package/src/extensions/skills.ts +123 -0
- package/src/extensions/types.ts +462 -0
- package/src/logger.ts +174 -0
- package/src/main.ts +586 -0
- package/src/server.ts +391 -0
- package/src/storage/db.ts +1624 -0
- package/src/storage/memory.ts +45 -0
- package/src/storage/pi-auth.ts +95 -0
- package/src/text/markdown.ts +117 -0
- package/src/text/rtl.ts +38 -0
- package/src/tradestation/host-api.ts +77 -0
- package/src/tradestation/pending-orders.ts +69 -0
- package/src/tts/azure.ts +52 -0
- package/src/tts/google.ts +128 -0
- package/src/tts/index.ts +8 -0
- package/src/tts/language.ts +20 -0
- package/src/tts/synthesize.ts +133 -0
- package/src/types.ts +295 -0
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: yahoo-mail
|
|
3
|
+
description: Read, search, organize, send, and reply to Yahoo Mail via the ymail CLI. Use for email listing, search, read messages, move, delete, mark read/unread, send new emails, and reply to messages. Triggers on any Yahoo Mail or inbox management request.
|
|
4
|
+
allowed-tools: Bash
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Yahoo Mail (ymail)
|
|
8
|
+
|
|
9
|
+
Use the `ymail` CLI via Bash for all Yahoo Mail operations.
|
|
10
|
+
|
|
11
|
+
## Presentation rules — always enforce
|
|
12
|
+
|
|
13
|
+
**Never paste raw ymail output into a reply.** Translate every result into plain language before responding.
|
|
14
|
+
|
|
15
|
+
| Raw output field | What to show instead |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `uid` | Never shown; use internally only for follow-up commands |
|
|
18
|
+
| `messageId` | Never shown; used internally for threading |
|
|
19
|
+
| `inReplyTo` | Never shown |
|
|
20
|
+
| `from` | Show name and address naturally ("From John Smith") |
|
|
21
|
+
| `flags` | Translate: `\Seen` → "read", absence → "unread", `\Flagged` → "starred" |
|
|
22
|
+
| JSON objects or arrays | Summarise in prose or a clean list |
|
|
23
|
+
| Error JSON | Explain the issue in plain language |
|
|
24
|
+
| `total` count | "You have X messages" or "Found X results" |
|
|
25
|
+
|
|
26
|
+
## Credentials
|
|
27
|
+
|
|
28
|
+
Environment variables `MERCURY_YAHOO_EMAIL` and `MERCURY_YAHOO_APP_PASSWORD` are pre-injected. No setup step needed — the CLI reads them directly.
|
|
29
|
+
|
|
30
|
+
If authentication fails, tell the user:
|
|
31
|
+
> "Your Yahoo Mail connection needs to be refreshed. Go to your console's Connections page and reconnect Yahoo Mail with a new app-specific password."
|
|
32
|
+
|
|
33
|
+
## Sending safety
|
|
34
|
+
|
|
35
|
+
When the user asks to send or reply:
|
|
36
|
+
- **Always confirm** the recipient, subject, and a brief preview of the message body before sending.
|
|
37
|
+
- Never send an email without the user's explicit "yes" / "send it" / "go ahead" confirmation.
|
|
38
|
+
- If the user's intent is ambiguous (e.g. "email John about the meeting"), draft the message and present it for approval first.
|
|
39
|
+
|
|
40
|
+
## Dispatch table
|
|
41
|
+
|
|
42
|
+
| User intent | Command | Example |
|
|
43
|
+
|---|---|---|
|
|
44
|
+
| List folders | `ymail list-folders` | "What folders do I have?" |
|
|
45
|
+
| Show recent inbox | `ymail list-inbox [folder] [limit]` | "Show my last 10 emails" → `ymail list-inbox INBOX 10` |
|
|
46
|
+
| Search email | `ymail search "<query>" [folder] [limit]` | "Find emails from John" → `ymail search "John" INBOX 20` |
|
|
47
|
+
| Read a message | `ymail read <uid> [folder]` | After listing, read a specific message by its uid |
|
|
48
|
+
| Move a message | `ymail move <uid> <destination> [source]` | "Move that to Trash" → `ymail move 12345 Trash INBOX` |
|
|
49
|
+
| Delete a message | `ymail delete <uid> [folder]` | "Delete that email" → `ymail delete 12345 INBOX` |
|
|
50
|
+
| Mark as read | `ymail mark-read <uid> [folder]` | "Mark that as read" |
|
|
51
|
+
| Mark as unread | `ymail mark-unread <uid> [folder]` | "Mark that as unread" |
|
|
52
|
+
| Send new email | `ymail send <to> <subject> <body>` | "Email john@example.com about the meeting" → confirm, then `ymail send "john@example.com" "Meeting update" "Hi John, ..."` |
|
|
53
|
+
| Reply to email | `ymail reply <uid> <body> [folder]` | "Reply to that email" → read the original, compose reply, confirm, then `ymail reply 12345 "Thanks, ..."` |
|
|
54
|
+
|
|
55
|
+
## Workflow patterns
|
|
56
|
+
|
|
57
|
+
**Inbox triage:** `list-inbox` → present summary → user picks messages → `read`, `move`, `delete`, or `mark-read` as directed.
|
|
58
|
+
|
|
59
|
+
**Search then act:** `search` → present matches → user selects → `read` or `move`.
|
|
60
|
+
|
|
61
|
+
**Folder overview:** `list-folders` → present folder names and message counts.
|
|
62
|
+
|
|
63
|
+
**Reply flow:** `read <uid>` → compose reply text → present for confirmation → `reply <uid> <body>`.
|
|
64
|
+
|
|
65
|
+
**Compose flow:** user requests email → draft subject + body → present for confirmation → `send <to> <subject> <body>`.
|
|
66
|
+
|
|
67
|
+
## Common folder names
|
|
68
|
+
|
|
69
|
+
| Folder | Yahoo IMAP path |
|
|
70
|
+
|---|---|
|
|
71
|
+
| Inbox | `INBOX` |
|
|
72
|
+
| Sent | `Sent` |
|
|
73
|
+
| Drafts | `Draft` |
|
|
74
|
+
| Trash | `Trash` |
|
|
75
|
+
| Spam | `Bulk Mail` |
|
|
76
|
+
| Archive | `Archive` |
|
|
77
|
+
|
|
78
|
+
When the user says "spam folder", use `"Bulk Mail"`. When they say "drafts", use `"Draft"`.
|
package/package.json
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mercury-agent",
|
|
3
|
+
"version": "0.4.5",
|
|
4
|
+
"description": "Personal AI assistant for chat platforms (WhatsApp, Slack, Discord, Telegram)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Avishai Tsabari",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"ai",
|
|
9
|
+
"assistant",
|
|
10
|
+
"whatsapp",
|
|
11
|
+
"slack",
|
|
12
|
+
"discord",
|
|
13
|
+
"telegram",
|
|
14
|
+
"chatbot",
|
|
15
|
+
"pi"
|
|
16
|
+
],
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "https://github.com/Avishai-Tsabari/mercury"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"exports": {
|
|
23
|
+
"./extensions/types": {
|
|
24
|
+
"types": "./src/extensions/types.ts",
|
|
25
|
+
"default": "./src/extensions/types.ts"
|
|
26
|
+
},
|
|
27
|
+
"./tts": {
|
|
28
|
+
"types": "./src/tts/index.ts",
|
|
29
|
+
"default": "./src/tts/index.ts"
|
|
30
|
+
},
|
|
31
|
+
"./types": {
|
|
32
|
+
"types": "./src/types.ts",
|
|
33
|
+
"default": "./src/types.ts"
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"bin": {
|
|
37
|
+
"mercury": "./src/cli/mercury.ts",
|
|
38
|
+
"mercury-ctl": "./src/cli/mrctl.ts"
|
|
39
|
+
},
|
|
40
|
+
"files": [
|
|
41
|
+
"src",
|
|
42
|
+
"resources",
|
|
43
|
+
"container",
|
|
44
|
+
"docs",
|
|
45
|
+
"examples",
|
|
46
|
+
"README.md"
|
|
47
|
+
],
|
|
48
|
+
"scripts": {
|
|
49
|
+
"dev": "bun run src/main.ts",
|
|
50
|
+
"start": "bun run src/main.ts",
|
|
51
|
+
"build": "bun build src/main.ts --outdir dist --target bun",
|
|
52
|
+
"typecheck": "bunx tsc --noEmit",
|
|
53
|
+
"lint": "bunx biome check src/ tests/",
|
|
54
|
+
"lint:fix": "bunx biome check --fix src/ tests/",
|
|
55
|
+
"check:silent-catch": "bun run scripts/check-silent-catch.ts",
|
|
56
|
+
"check:sync-calls": "bun run scripts/check-sync-calls.ts",
|
|
57
|
+
"check:dep-floors": "bun run scripts/check-dep-floors.ts",
|
|
58
|
+
"check:no-hijack-verbs": "bun run scripts/check-no-hijack-verbs.ts src",
|
|
59
|
+
"check": "bun run check:silent-catch && bun run check:sync-calls && bun run check:dep-floors && bun run check:no-hijack-verbs && bun run typecheck && bun run lint && bun test",
|
|
60
|
+
"check:fix": "bun run check:silent-catch && bun run check:sync-calls && bun run check:dep-floors && bun run check:no-hijack-verbs && bun run typecheck && bun run lint:fix && bun test"
|
|
61
|
+
},
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"@chat-adapter/discord": "^4.14.0",
|
|
64
|
+
"@chat-adapter/slack": "^4.14.0",
|
|
65
|
+
"@chat-adapter/teams": "^4.17.0",
|
|
66
|
+
"@chat-adapter/telegram": "^4.26.0",
|
|
67
|
+
"@mariozechner/pi-agent-core": "^0.65.2",
|
|
68
|
+
"@mariozechner/pi-ai": "^0.67.6",
|
|
69
|
+
"@mariozechner/pi-coding-agent": "^0.65.2",
|
|
70
|
+
"@whiskeysockets/baileys": "^7.0.0-rc.9",
|
|
71
|
+
"axios": "^1.15.1",
|
|
72
|
+
"chat": "^4.14.0",
|
|
73
|
+
"commander": "^14.0.3",
|
|
74
|
+
"cron-parser": "^5.5.0",
|
|
75
|
+
"discord.js": "^14.26.3",
|
|
76
|
+
"hono": "^4.12.25",
|
|
77
|
+
"qrcode-terminal": "^0.12.0",
|
|
78
|
+
"yaml": "^2.8.3",
|
|
79
|
+
"zod": "^4.3.6"
|
|
80
|
+
},
|
|
81
|
+
"devDependencies": {
|
|
82
|
+
"@biomejs/biome": "^2.4.12",
|
|
83
|
+
"@types/node": "^25.6.0",
|
|
84
|
+
"@types/qrcode-terminal": "^0.12.2",
|
|
85
|
+
"bun-types": "^1.3.5",
|
|
86
|
+
"typescript": "^5.8.0"
|
|
87
|
+
},
|
|
88
|
+
"engines": {
|
|
89
|
+
"bun": ">=1.2.0"
|
|
90
|
+
},
|
|
91
|
+
"overrides": {
|
|
92
|
+
"undici": ">=6.23.0",
|
|
93
|
+
"basic-ftp": ">=6.0.0",
|
|
94
|
+
"fast-xml-parser": ">=5.7.0",
|
|
95
|
+
"fast-xml-builder": ">=1.2.0",
|
|
96
|
+
"@anthropic-ai/sdk": ">=0.91.1",
|
|
97
|
+
"brace-expansion": ">=5.0.5",
|
|
98
|
+
"ip-address": ">10.1.0",
|
|
99
|
+
"protobufjs": "^7.5.6",
|
|
100
|
+
"@protobufjs/utf8": ">=1.1.1",
|
|
101
|
+
"fast-uri": ">=3.1.2",
|
|
102
|
+
"ws": ">=8.20.1",
|
|
103
|
+
"qs": ">=6.15.2",
|
|
104
|
+
"lodash": ">=4.18.1"
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: explore
|
|
3
|
+
description: Fast codebase recon that returns compressed context for handoff to other agents
|
|
4
|
+
tools: read, grep, find, ls, bash
|
|
5
|
+
model: claude-haiku-4-5
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
You are an explorer. Quickly investigate a codebase and return structured findings that another agent can use without re-reading everything.
|
|
9
|
+
|
|
10
|
+
Your output will be passed to an agent who has NOT seen the files you explored.
|
|
11
|
+
|
|
12
|
+
Thoroughness (infer from task, default medium):
|
|
13
|
+
- Quick: Targeted lookups, key files only
|
|
14
|
+
- Medium: Follow imports, read critical sections
|
|
15
|
+
- Thorough: Trace all dependencies, check tests/types
|
|
16
|
+
|
|
17
|
+
Strategy:
|
|
18
|
+
1. grep/find to locate relevant code
|
|
19
|
+
2. Read key sections (not entire files)
|
|
20
|
+
3. Identify types, interfaces, key functions
|
|
21
|
+
4. Note dependencies between files
|
|
22
|
+
|
|
23
|
+
Output format:
|
|
24
|
+
|
|
25
|
+
## Files Retrieved
|
|
26
|
+
List with exact line ranges:
|
|
27
|
+
1. `path/to/file.ts` (lines 10-50) - Description of what's here
|
|
28
|
+
2. `path/to/other.ts` (lines 100-150) - Description
|
|
29
|
+
3. ...
|
|
30
|
+
|
|
31
|
+
## Key Code
|
|
32
|
+
Critical types, interfaces, or functions:
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
interface Example {
|
|
36
|
+
// actual code from the files
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
function keyFunction() {
|
|
42
|
+
// actual implementation
|
|
43
|
+
}
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Architecture
|
|
47
|
+
Brief explanation of how the pieces connect.
|
|
48
|
+
|
|
49
|
+
## Start Here
|
|
50
|
+
Which file to look at first and why.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: worker
|
|
3
|
+
description: General-purpose subagent with full capabilities, isolated context
|
|
4
|
+
model: claude-sonnet-4-5
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
You are a worker agent with full capabilities. You operate in an isolated context window to handle delegated tasks without polluting the main conversation.
|
|
8
|
+
|
|
9
|
+
Work autonomously to complete the assigned task. Use all available tools as needed.
|
|
10
|
+
|
|
11
|
+
Output format when finished:
|
|
12
|
+
|
|
13
|
+
## Completed
|
|
14
|
+
What was done.
|
|
15
|
+
|
|
16
|
+
## Files Changed
|
|
17
|
+
- `path/to/file.ts` - what changed
|
|
18
|
+
|
|
19
|
+
## Notes (if any)
|
|
20
|
+
Anything the main agent should know.
|
|
21
|
+
|
|
22
|
+
If handing off to another agent (e.g. reviewer), include:
|
|
23
|
+
- Exact file paths changed
|
|
24
|
+
- Key functions/types touched (short list)
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"gws": {
|
|
3
|
+
"credentialEnvVar": "MERCURY_GWS_CREDENTIALS_JSON",
|
|
4
|
+
"env": {
|
|
5
|
+
"credentials": "MERCURY_GWS_CREDENTIALS_JSON",
|
|
6
|
+
"legacyCredentialsFile": "MERCURY_GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE"
|
|
7
|
+
}
|
|
8
|
+
},
|
|
9
|
+
"yahoo-mail": {
|
|
10
|
+
"credentialEnvVar": "MERCURY_YAHOO_APP_PASSWORD",
|
|
11
|
+
"env": {
|
|
12
|
+
"email": "MERCURY_YAHOO_EMAIL",
|
|
13
|
+
"appPassword": "MERCURY_YAHOO_APP_PASSWORD"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"tradestation": {
|
|
17
|
+
"credentialEnvVar": null,
|
|
18
|
+
"env": {
|
|
19
|
+
"refreshToken": "MERCURY_TRADESTATION_REFRESH_TOKEN",
|
|
20
|
+
"accessToken": "MERCURY_TRADESTATION_ACCESS_TOKEN",
|
|
21
|
+
"clientId": "MERCURY_TS_CLIENT_ID",
|
|
22
|
+
"clientSecret": "MERCURY_TS_CLIENT_SECRET"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
File without changes
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent discovery and configuration
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import * as fs from "node:fs";
|
|
6
|
+
import * as path from "node:path";
|
|
7
|
+
import { getAgentDir, parseFrontmatter } from "@mariozechner/pi-coding-agent";
|
|
8
|
+
|
|
9
|
+
export type AgentScope = "user" | "project" | "both";
|
|
10
|
+
|
|
11
|
+
export interface AgentConfig {
|
|
12
|
+
name: string;
|
|
13
|
+
description: string;
|
|
14
|
+
tools?: string[];
|
|
15
|
+
model?: string;
|
|
16
|
+
systemPrompt: string;
|
|
17
|
+
source: "user" | "project";
|
|
18
|
+
filePath: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface AgentDiscoveryResult {
|
|
22
|
+
agents: AgentConfig[];
|
|
23
|
+
projectAgentsDir: string | null;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function loadAgentsFromDir(dir: string, source: "user" | "project"): AgentConfig[] {
|
|
27
|
+
const agents: AgentConfig[] = [];
|
|
28
|
+
|
|
29
|
+
if (!fs.existsSync(dir)) {
|
|
30
|
+
return agents;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
let entries: fs.Dirent[];
|
|
34
|
+
try {
|
|
35
|
+
entries = fs.readdirSync(dir, { withFileTypes: true });
|
|
36
|
+
} catch {
|
|
37
|
+
return agents;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
for (const entry of entries) {
|
|
41
|
+
if (!entry.name.endsWith(".md")) continue;
|
|
42
|
+
if (!entry.isFile() && !entry.isSymbolicLink()) continue;
|
|
43
|
+
|
|
44
|
+
const filePath = path.join(dir, entry.name);
|
|
45
|
+
let content: string;
|
|
46
|
+
try {
|
|
47
|
+
content = fs.readFileSync(filePath, "utf-8");
|
|
48
|
+
} catch {
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
const { frontmatter, body } = parseFrontmatter<Record<string, string>>(content);
|
|
53
|
+
|
|
54
|
+
if (!frontmatter.name || !frontmatter.description) {
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
const tools = frontmatter.tools
|
|
59
|
+
?.split(",")
|
|
60
|
+
.map((t: string) => t.trim())
|
|
61
|
+
.filter(Boolean);
|
|
62
|
+
|
|
63
|
+
agents.push({
|
|
64
|
+
name: frontmatter.name,
|
|
65
|
+
description: frontmatter.description,
|
|
66
|
+
tools: tools && tools.length > 0 ? tools : undefined,
|
|
67
|
+
model: frontmatter.model,
|
|
68
|
+
systemPrompt: body,
|
|
69
|
+
source,
|
|
70
|
+
filePath,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
return agents;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isDirectory(p: string): boolean {
|
|
78
|
+
try {
|
|
79
|
+
return fs.statSync(p).isDirectory();
|
|
80
|
+
} catch {
|
|
81
|
+
return false;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
function findNearestProjectAgentsDir(cwd: string): string | null {
|
|
86
|
+
let currentDir = cwd;
|
|
87
|
+
while (true) {
|
|
88
|
+
const candidate = path.join(currentDir, ".pi", "agents");
|
|
89
|
+
if (isDirectory(candidate)) return candidate;
|
|
90
|
+
|
|
91
|
+
const parentDir = path.dirname(currentDir);
|
|
92
|
+
if (parentDir === currentDir) return null;
|
|
93
|
+
currentDir = parentDir;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function discoverAgents(cwd: string, scope: AgentScope): AgentDiscoveryResult {
|
|
98
|
+
const userDir = path.join(getAgentDir(), "agents");
|
|
99
|
+
const projectAgentsDir = findNearestProjectAgentsDir(cwd);
|
|
100
|
+
|
|
101
|
+
const userAgents = scope === "project" ? [] : loadAgentsFromDir(userDir, "user");
|
|
102
|
+
const projectAgents = scope === "user" || !projectAgentsDir ? [] : loadAgentsFromDir(projectAgentsDir, "project");
|
|
103
|
+
|
|
104
|
+
const agentMap = new Map<string, AgentConfig>();
|
|
105
|
+
|
|
106
|
+
if (scope === "both") {
|
|
107
|
+
for (const agent of userAgents) agentMap.set(agent.name, agent);
|
|
108
|
+
for (const agent of projectAgents) agentMap.set(agent.name, agent);
|
|
109
|
+
} else if (scope === "user") {
|
|
110
|
+
for (const agent of userAgents) agentMap.set(agent.name, agent);
|
|
111
|
+
} else {
|
|
112
|
+
for (const agent of projectAgents) agentMap.set(agent.name, agent);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
return { agents: Array.from(agentMap.values()), projectAgentsDir };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function formatAgentList(agents: AgentConfig[], maxItems: number): { text: string; remaining: number } {
|
|
119
|
+
if (agents.length === 0) return { text: "none", remaining: 0 };
|
|
120
|
+
const listed = agents.slice(0, maxItems);
|
|
121
|
+
const remaining = agents.length - listed.length;
|
|
122
|
+
return {
|
|
123
|
+
text: listed.map((a) => `${a.name} (${a.source}): ${a.description}`).join("; "),
|
|
124
|
+
remaining,
|
|
125
|
+
};
|
|
126
|
+
}
|