@pome-sh/cli 0.7.0 → 0.9.0
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/dist/build-info.json +3 -3
- package/dist/src/cli/agent-identity.js +7 -2
- package/dist/src/cli/compile-seeds.js +51 -5
- package/dist/src/cli/docs-topics.js +5 -3
- package/dist/src/cli/main.js +21 -11
- package/dist/src/cli/project-config.d.ts +8 -0
- package/dist/src/cli/project-config.js +18 -0
- package/dist/src/cli/register.d.ts +15 -0
- package/dist/src/cli/register.js +26 -3
- package/dist/src/cli/session.d.ts +10 -0
- package/dist/src/cli/session.js +28 -2
- package/dist/src/fix-prompt/index.d.ts +1 -1
- package/dist/src/fix-prompt/index.js +2 -2
- package/dist/src/fix-prompt/prompt.d.ts +2 -2
- package/dist/src/fix-prompt/prompt.js +9 -9
- package/dist/src/hosted/client.d.ts +8 -2
- package/dist/src/hosted/client.js +108 -26
- package/dist/src/hosted/errors.d.ts +14 -0
- package/dist/src/hosted/errors.js +22 -0
- package/dist/src/hosted/evalResultCache.d.ts +4 -4
- package/dist/src/hosted/evalResultCache.js +10 -3
- package/dist/src/recorder/artifacts.d.ts +1 -1
- package/dist/src/recorder/artifacts.js +8 -1
- package/dist/src/runner/runTask.d.ts +14 -0
- package/dist/src/runner/runTaskHosted.js +9 -2
- package/dist/src/runner/runTrialGroup.js +4 -1
- package/dist/src/task/taskSchema.d.ts +52 -16
- package/node_modules/@pome-sh/shared-types/dist/seed-state.d.ts +27 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-state.js +12 -0
- package/node_modules/@pome-sh/shared-types/dist/seed-state.js.map +1 -1
- package/node_modules/@pome-sh/shared-types/dist/task.d.ts +18 -0
- package/node_modules/@pome-sh/shared-types/package.json +1 -1
- package/node_modules/@pome-sh/shared-types/trace-contract.json +1 -1
- package/node_modules/@pome-sh/twin-gmail/CHANGELOG.md +21 -0
- package/node_modules/@pome-sh/twin-gmail/HOSTED.md +37 -15
- package/node_modules/@pome-sh/twin-gmail/LIMITS.md +10 -0
- package/node_modules/@pome-sh/twin-gmail/README.md +52 -11
- package/node_modules/@pome-sh/twin-gmail/dist/fixtures/mcp-tools-list.canonical.json +242 -7
- package/node_modules/@pome-sh/twin-gmail/dist/src/db.js +6 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/db.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/drafts.d.ts +41 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/drafts.js +138 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/drafts.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/filters.d.ts +10 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/{domain-search.js → domain/filters.js} +52 -36
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/filters.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/{domain.d.ts → domain/gmail-domain.d.ts} +45 -34
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/gmail-domain.js +174 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/gmail-domain.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/hydrate.d.ts +8 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/hydrate.js +122 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/hydrate.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/index.d.ts +4 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/index.js +5 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/index.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/labels.d.ts +40 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/labels.js +122 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/labels.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/messages.d.ts +49 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/messages.js +276 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/messages.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/search-sql.d.ts +19 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/search-sql.js +179 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/search-sql.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/settings.d.ts +27 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/settings.js +98 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain/settings.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/errors.js +2 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/errors.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/faults.d.ts +21 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/faults.js +52 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/faults.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/identity.d.ts +1 -6
- package/node_modules/@pome-sh/twin-gmail/dist/src/identity.js +0 -11
- package/node_modules/@pome-sh/twin-gmail/dist/src/identity.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/index.d.ts +4 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/index.js +3 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/index.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp-schemas.d.ts +48 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp-schemas.js +23 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp-schemas.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp.d.ts +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp.js +39 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/mcp.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-drafts.js +4 -5
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-drafts.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-kit.d.ts +2 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-kit.js +4 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-kit.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-messages.js +7 -8
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-messages.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-resources.js +20 -21
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes-resources.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-routes.d.ts +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-serializers.d.ts +2 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-serializers.js +4 -6
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-serializers.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-match.d.ts +4 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-match.js +179 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-match.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-parse.d.ts +61 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-parse.js +318 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search-parse.js.map +1 -0
- package/node_modules/@pome-sh/twin-gmail/dist/src/search.d.ts +3 -61
- package/node_modules/@pome-sh/twin-gmail/dist/src/search.js +2 -503
- package/node_modules/@pome-sh/twin-gmail/dist/src/search.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/seed.d.ts +13 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/seed.js +3 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/seed.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/server.js +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/server.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/storage.js +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/storage.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/twin.d.ts +2 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/twin.js +1 -4
- package/node_modules/@pome-sh/twin-gmail/dist/src/twin.js.map +1 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/types.d.ts +1 -0
- package/node_modules/@pome-sh/twin-gmail/fidelity.inventory.json +42 -435
- package/node_modules/@pome-sh/twin-gmail/fixtures/README.md +4 -4
- package/node_modules/@pome-sh/twin-gmail/fixtures/mcp-tools-list.canonical.json +242 -7
- package/node_modules/@pome-sh/twin-gmail/fixtures/mcp-tools-list.meta.json +3 -3
- package/node_modules/@pome-sh/twin-gmail/package.json +3 -2
- package/node_modules/hono/dist/cjs/client/utils.js +1 -1
- package/node_modules/hono/dist/cjs/helper/streaming/sse.js +5 -4
- package/node_modules/hono/dist/cjs/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/compress/index.js +2 -1
- package/node_modules/hono/dist/cjs/middleware/method-override/index.js +5 -3
- package/node_modules/hono/dist/cjs/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/cjs/request.js +8 -3
- package/node_modules/hono/dist/cjs/utils/accept.js +1 -1
- package/node_modules/hono/dist/cjs/utils/body.js +6 -0
- package/node_modules/hono/dist/cjs/utils/url.js +1 -1
- package/node_modules/hono/dist/client/utils.js +1 -1
- package/node_modules/hono/dist/helper/streaming/sse.js +5 -4
- package/node_modules/hono/dist/middleware/cache/index.js +1 -1
- package/node_modules/hono/dist/middleware/compress/index.js +2 -1
- package/node_modules/hono/dist/middleware/method-override/index.js +5 -3
- package/node_modules/hono/dist/middleware/secure-headers/secure-headers.js +10 -4
- package/node_modules/hono/dist/request.js +8 -3
- package/node_modules/hono/dist/types/adapter/aws-lambda/types.d.ts +9 -0
- package/node_modules/hono/dist/types/helper/websocket/index.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/combine/index.d.ts +1 -1
- package/node_modules/hono/dist/utils/accept.js +1 -1
- package/node_modules/hono/dist/utils/body.js +6 -0
- package/node_modules/hono/dist/utils/url.js +1 -1
- package/node_modules/hono/package.json +3 -3
- package/package.json +3 -3
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain-search.d.ts +0 -5
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain-search.js.map +0 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain.js +0 -407
- package/node_modules/@pome-sh/twin-gmail/dist/src/domain.js.map +0 -1
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-store.d.ts +0 -75
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-store.js +0 -282
- package/node_modules/@pome-sh/twin-gmail/dist/src/rest-store.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Gmail twin fixtures (Gate 0 oracles)
|
|
1
|
+
# Gmail twin fixtures (Gate 0/1 oracles)
|
|
2
2
|
|
|
3
3
|
Immutable upstream captures for `@pome-sh/twin-gmail`. Normal tests must not require Google credentials.
|
|
4
4
|
|
|
@@ -15,8 +15,8 @@ Immutable upstream captures for `@pome-sh/twin-gmail`. Normal tests must not req
|
|
|
15
15
|
| File | Purpose |
|
|
16
16
|
| --- | --- |
|
|
17
17
|
| `mcp-tools-list.raw.json` | Live unauthenticated `tools/list` (13 tools as returned) |
|
|
18
|
-
| `mcp-tools-list.canonical.json` |
|
|
19
|
-
| `mcp-tools-list.meta.json` | Endpoint, protocol version, SHA-256,
|
|
18
|
+
| `mcp-tools-list.canonical.json` | Gate-1 launch 13-tool listing oracle (schemas from live capture) |
|
|
19
|
+
| `mcp-tools-list.meta.json` | Endpoint, protocol version, SHA-256, Gate-1 promotions |
|
|
20
20
|
| `mcp-initialize.raw.json` / `.meta.json` | Live `initialize` (protocolVersion) |
|
|
21
21
|
| `mcp-tools-call-unauth-error.raw.json` | Live unauthenticated `tools/call` error envelope |
|
|
22
22
|
| `mcp-tools-call.representative.json` | Schema-derived representative success call shapes |
|
|
@@ -25,4 +25,4 @@ Immutable upstream captures for `@pome-sh/twin-gmail`. Normal tests must not req
|
|
|
25
25
|
|
|
26
26
|
- `tools/list` and `initialize` were captured live without OAuth on 2026-07-20 against `https://gmailmcp.googleapis.com/mcp/v1`.
|
|
27
27
|
- Authenticated `tools/call` success was **not** available; representative success fixtures are reconstructed from live `outputSchema` + public docs and are marked as such.
|
|
28
|
-
-
|
|
28
|
+
- Gate 1 expands the OSS launch set to the full live 13-tool listing, promoting `get_message`, `apply_sensitive_thread_label`, and `apply_sensitive_message_label` that Gate 0 treated as preview drift.
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"meta": {
|
|
3
|
-
"source": "
|
|
3
|
+
"source": "live_unauthenticated_tools_list_gate1_launch_set",
|
|
4
4
|
"endpoint": "https://gmailmcp.googleapis.com/mcp/v1",
|
|
5
5
|
"method": "tools/list",
|
|
6
6
|
"protocol": "JSON-RPC 2.0 over HTTP (accept: application/json, text/event-stream)",
|
|
7
7
|
"protocolVersion": "2025-03-26",
|
|
8
8
|
"captureDate": "2026-07-20",
|
|
9
9
|
"rawFileSha256": "6ef35bad568967015c101f89e995148c4eb2131b3a6dd244f7237058abae8e7a",
|
|
10
|
-
"launchToolCount":
|
|
10
|
+
"launchToolCount": 13,
|
|
11
11
|
"liveToolCount": 13,
|
|
12
12
|
"liveToolOrder": [
|
|
13
13
|
"create_draft",
|
|
@@ -28,28 +28,43 @@
|
|
|
28
28
|
"create_draft",
|
|
29
29
|
"list_drafts",
|
|
30
30
|
"get_thread",
|
|
31
|
+
"get_message",
|
|
31
32
|
"search_threads",
|
|
32
33
|
"label_thread",
|
|
33
34
|
"unlabel_thread",
|
|
35
|
+
"apply_sensitive_thread_label",
|
|
34
36
|
"list_labels",
|
|
35
37
|
"label_message",
|
|
36
38
|
"unlabel_message",
|
|
39
|
+
"apply_sensitive_message_label",
|
|
37
40
|
"create_label"
|
|
38
41
|
],
|
|
39
|
-
"
|
|
42
|
+
"gate0LaunchToolOrder": [
|
|
43
|
+
"create_draft",
|
|
44
|
+
"list_drafts",
|
|
45
|
+
"get_thread",
|
|
46
|
+
"search_threads",
|
|
47
|
+
"label_thread",
|
|
48
|
+
"unlabel_thread",
|
|
49
|
+
"list_labels",
|
|
50
|
+
"label_message",
|
|
51
|
+
"unlabel_message",
|
|
52
|
+
"create_label"
|
|
53
|
+
],
|
|
54
|
+
"gate1PromotedFromPreview": [
|
|
40
55
|
"get_message",
|
|
41
56
|
"apply_sensitive_thread_label",
|
|
42
57
|
"apply_sensitive_message_label"
|
|
43
58
|
],
|
|
44
59
|
"notes": [
|
|
45
60
|
"Raw live tools/list returned 13 tools without auth (Developer Preview).",
|
|
46
|
-
"Gate
|
|
47
|
-
"Schemas/annotations/descriptions for launch tools are copied verbatim from the live capture.",
|
|
48
|
-
"
|
|
61
|
+
"Gate 1 expands the OSS launch set from the Gate 0 ten-tool freeze to the full live 13-tool listing.",
|
|
62
|
+
"Schemas/annotations/descriptions for all launch tools are copied verbatim from the live capture.",
|
|
63
|
+
"Promoted Gate-1 tools: get_message, apply_sensitive_thread_label, apply_sensitive_message_label.",
|
|
49
64
|
"Authenticated tools/call success envelopes were unavailable; see mcp-tools-call.representative.json and mcp-tools-call-unauth-error.raw.json.",
|
|
50
65
|
"initialize returned protocolVersion=2025-03-26 (see mcp-initialize.raw.json)."
|
|
51
66
|
],
|
|
52
|
-
"canonicalSha256": "
|
|
67
|
+
"canonicalSha256": "56b5e86181c13ead63fdc8ea0d4bedc6860c1a3fdb17372fdca76591e48a4eed"
|
|
53
68
|
},
|
|
54
69
|
"jsonrpc": "2.0",
|
|
55
70
|
"id": 1,
|
|
@@ -463,6 +478,138 @@
|
|
|
463
478
|
"type": "object"
|
|
464
479
|
}
|
|
465
480
|
},
|
|
481
|
+
{
|
|
482
|
+
"annotations": {
|
|
483
|
+
"destructiveHint": false,
|
|
484
|
+
"idempotentHint": true,
|
|
485
|
+
"openWorldHint": false,
|
|
486
|
+
"readOnlyHint": true,
|
|
487
|
+
"title": "Retrieves a specific email message from the authenticated user's Gmail account."
|
|
488
|
+
},
|
|
489
|
+
"description": "Retrieves a specific email message from the authenticated user's Gmail account by its unique message ID.\n\nUse this tool to inspect a single, individual email when you already know its message ID. If the user wants to read a specific email in detail, check the exact wording of a message, or examine attachment metadata for a single email, this is the right tool. It is not suitable for retrieving entire conversations or viewing back-and-forth discussion threads; use the 'get_thread' tool instead.\nKey indicators include if the user asks for the full content of a specific message ID returned by a previous search, or if the query asks to inspect a specific individual email rather than an entire thread.\nExample user prompts are: \"Get the full text of message ID 18f123456789abcd.\", \"Read the latest message in that thread from Alice.\", and \"What are the attachment names in the email I just received from HR?\" \n\nThe optional `messageFormat` parameter controls the format of the message returned. By default (or with `FULL_CONTENT`), it returns the full content of the message. Use `MINIMAL` to include only subject and snippet (excluding body). Use `METADATA_ONLY` to include only basic metadata (message ID, thread ID, labels, timestamp, and size estimate). \n",
|
|
490
|
+
"inputSchema": {
|
|
491
|
+
"description": "Request message for GetMessage RPC.",
|
|
492
|
+
"properties": {
|
|
493
|
+
"messageFormat": {
|
|
494
|
+
"description": "Optional. Specifies the format of the message returned. Defaults to FULL_CONTENT.",
|
|
495
|
+
"enum": [
|
|
496
|
+
"MESSAGE_FORMAT_UNSPECIFIED",
|
|
497
|
+
"MINIMAL",
|
|
498
|
+
"FULL_CONTENT",
|
|
499
|
+
"METADATA_ONLY"
|
|
500
|
+
],
|
|
501
|
+
"type": "string",
|
|
502
|
+
"x-google-enum-descriptions": [
|
|
503
|
+
"Defaults to FULL_CONTENT.",
|
|
504
|
+
"Returns message snippets and key headers (Subject, From, To, Cc, Date).",
|
|
505
|
+
"Returns all information in \"MINIMAL\" plus the full body content of each message.",
|
|
506
|
+
"Metadata only: does not include subject, snippet, body, attachment filenames."
|
|
507
|
+
]
|
|
508
|
+
},
|
|
509
|
+
"messageId": {
|
|
510
|
+
"description": "Required. The unique identifier of the message to fetch.",
|
|
511
|
+
"type": "string"
|
|
512
|
+
}
|
|
513
|
+
},
|
|
514
|
+
"required": [
|
|
515
|
+
"messageId"
|
|
516
|
+
],
|
|
517
|
+
"type": "object"
|
|
518
|
+
},
|
|
519
|
+
"name": "get_message",
|
|
520
|
+
"outputSchema": {
|
|
521
|
+
"$defs": {
|
|
522
|
+
"AttachmentMetadata": {
|
|
523
|
+
"description": "Represents an attachment associated with a message.",
|
|
524
|
+
"properties": {
|
|
525
|
+
"filename": {
|
|
526
|
+
"description": "The filename of the attachment.",
|
|
527
|
+
"type": "string"
|
|
528
|
+
},
|
|
529
|
+
"id": {
|
|
530
|
+
"description": "Output only. The ID of the attachment.",
|
|
531
|
+
"readOnly": true,
|
|
532
|
+
"type": "string"
|
|
533
|
+
},
|
|
534
|
+
"mimeType": {
|
|
535
|
+
"description": "The MIME type of the attachment.",
|
|
536
|
+
"type": "string"
|
|
537
|
+
}
|
|
538
|
+
},
|
|
539
|
+
"type": "object"
|
|
540
|
+
}
|
|
541
|
+
},
|
|
542
|
+
"description": "Message within a thread.",
|
|
543
|
+
"properties": {
|
|
544
|
+
"attachmentIds": {
|
|
545
|
+
"description": "Output only. The attachment ids, only populated if MessageFormat was FULL_CONTENT.",
|
|
546
|
+
"items": {
|
|
547
|
+
"type": "string"
|
|
548
|
+
},
|
|
549
|
+
"readOnly": true,
|
|
550
|
+
"type": "array"
|
|
551
|
+
},
|
|
552
|
+
"attachments": {
|
|
553
|
+
"description": "Output only. The attachments, only populated if MessageFormat was FULL_CONTENT.",
|
|
554
|
+
"items": {
|
|
555
|
+
"$ref": "#/$defs/AttachmentMetadata"
|
|
556
|
+
},
|
|
557
|
+
"readOnly": true,
|
|
558
|
+
"type": "array"
|
|
559
|
+
},
|
|
560
|
+
"ccRecipients": {
|
|
561
|
+
"description": "CC recipient email addresses.",
|
|
562
|
+
"items": {
|
|
563
|
+
"type": "string"
|
|
564
|
+
},
|
|
565
|
+
"type": "array"
|
|
566
|
+
},
|
|
567
|
+
"date": {
|
|
568
|
+
"description": "Date of the message in ISO 8601 format (YYYY-MM-DD).",
|
|
569
|
+
"type": "string"
|
|
570
|
+
},
|
|
571
|
+
"htmlBody": {
|
|
572
|
+
"description": "The HTML content of the email, only populated if MessageFormat was FULL_CONTENT.",
|
|
573
|
+
"type": "string"
|
|
574
|
+
},
|
|
575
|
+
"id": {
|
|
576
|
+
"description": "The unique identifier of the message.",
|
|
577
|
+
"type": "string"
|
|
578
|
+
},
|
|
579
|
+
"labelIds": {
|
|
580
|
+
"description": "The ids of the labels attached to the message. Includes ids of user labels and standard system labels limited to \"INBOX\", \"SPAM\", \"TRASH\", \"UNREAD\", \"STARRED\", \"IMPORTANT\", \"SENT\", \"DRAFT\", \"CHAT\".",
|
|
581
|
+
"items": {
|
|
582
|
+
"type": "string"
|
|
583
|
+
},
|
|
584
|
+
"type": "array"
|
|
585
|
+
},
|
|
586
|
+
"plaintextBody": {
|
|
587
|
+
"description": "Full body content, only populated if MessageFormat was FULL_CONTENT.",
|
|
588
|
+
"type": "string"
|
|
589
|
+
},
|
|
590
|
+
"sender": {
|
|
591
|
+
"description": "Sender email address.",
|
|
592
|
+
"type": "string"
|
|
593
|
+
},
|
|
594
|
+
"snippet": {
|
|
595
|
+
"description": "Snippet of the message body.",
|
|
596
|
+
"type": "string"
|
|
597
|
+
},
|
|
598
|
+
"subject": {
|
|
599
|
+
"description": "The message subject extracted from headers:",
|
|
600
|
+
"type": "string"
|
|
601
|
+
},
|
|
602
|
+
"toRecipients": {
|
|
603
|
+
"description": "To recipient email addresses.",
|
|
604
|
+
"items": {
|
|
605
|
+
"type": "string"
|
|
606
|
+
},
|
|
607
|
+
"type": "array"
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
"type": "object"
|
|
611
|
+
}
|
|
612
|
+
},
|
|
466
613
|
{
|
|
467
614
|
"annotations": {
|
|
468
615
|
"destructiveHint": false,
|
|
@@ -716,6 +863,50 @@
|
|
|
716
863
|
"type": "object"
|
|
717
864
|
}
|
|
718
865
|
},
|
|
866
|
+
{
|
|
867
|
+
"annotations": {
|
|
868
|
+
"destructiveHint": true,
|
|
869
|
+
"idempotentHint": true,
|
|
870
|
+
"openWorldHint": false,
|
|
871
|
+
"readOnlyHint": false,
|
|
872
|
+
"title": "Adds a sensitive label (Trash or Spam) to a thread."
|
|
873
|
+
},
|
|
874
|
+
"description": "Adds a sensitive label (Trash or Spam) to an entire thread in the authenticated user's Gmail account. This operation affects all messages currently in the thread and any future messages added to it.\n\nUse this tool to trash or mark a thread as spam. If unsure of the thread ID, use the `search_threads` tool first.\n",
|
|
875
|
+
"inputSchema": {
|
|
876
|
+
"description": "Request message for ApplySensitiveThreadLabel RPC.",
|
|
877
|
+
"properties": {
|
|
878
|
+
"labelOption": {
|
|
879
|
+
"description": "Required. The sensitive label option to add.",
|
|
880
|
+
"enum": [
|
|
881
|
+
"LABEL_OPTION_UNSPECIFIED",
|
|
882
|
+
"TRASH",
|
|
883
|
+
"SPAM"
|
|
884
|
+
],
|
|
885
|
+
"type": "string",
|
|
886
|
+
"x-google-enum-descriptions": [
|
|
887
|
+
"Unspecified label option.",
|
|
888
|
+
"Trash label.",
|
|
889
|
+
"Spam label."
|
|
890
|
+
]
|
|
891
|
+
},
|
|
892
|
+
"threadId": {
|
|
893
|
+
"description": "Required. The ID of the thread to add the label to.",
|
|
894
|
+
"type": "string"
|
|
895
|
+
}
|
|
896
|
+
},
|
|
897
|
+
"required": [
|
|
898
|
+
"threadId",
|
|
899
|
+
"labelOption"
|
|
900
|
+
],
|
|
901
|
+
"type": "object"
|
|
902
|
+
},
|
|
903
|
+
"name": "apply_sensitive_thread_label",
|
|
904
|
+
"outputSchema": {
|
|
905
|
+
"description": "Response message for ApplySensitiveThreadLabel RPC.",
|
|
906
|
+
"properties": {},
|
|
907
|
+
"type": "object"
|
|
908
|
+
}
|
|
909
|
+
},
|
|
719
910
|
{
|
|
720
911
|
"annotations": {
|
|
721
912
|
"destructiveHint": false,
|
|
@@ -877,6 +1068,50 @@
|
|
|
877
1068
|
"type": "object"
|
|
878
1069
|
}
|
|
879
1070
|
},
|
|
1071
|
+
{
|
|
1072
|
+
"annotations": {
|
|
1073
|
+
"destructiveHint": true,
|
|
1074
|
+
"idempotentHint": true,
|
|
1075
|
+
"openWorldHint": false,
|
|
1076
|
+
"readOnlyHint": false,
|
|
1077
|
+
"title": "Adds a sensitive label (Trash or Spam) to a message."
|
|
1078
|
+
},
|
|
1079
|
+
"description": "Adds a sensitive label (Trash or Spam) to a specific message in the authenticated user's Gmail account.\n\nUse this tool to trash or mark a message as spam. To find the message ID, use tools like `search_threads` or `get_thread`.\n",
|
|
1080
|
+
"inputSchema": {
|
|
1081
|
+
"description": "Request message for ApplySensitiveMessageLabel RPC.",
|
|
1082
|
+
"properties": {
|
|
1083
|
+
"labelOption": {
|
|
1084
|
+
"description": "Required. The sensitive label option to add.",
|
|
1085
|
+
"enum": [
|
|
1086
|
+
"LABEL_OPTION_UNSPECIFIED",
|
|
1087
|
+
"TRASH",
|
|
1088
|
+
"SPAM"
|
|
1089
|
+
],
|
|
1090
|
+
"type": "string",
|
|
1091
|
+
"x-google-enum-descriptions": [
|
|
1092
|
+
"Unspecified label option.",
|
|
1093
|
+
"Trash label.",
|
|
1094
|
+
"Spam label."
|
|
1095
|
+
]
|
|
1096
|
+
},
|
|
1097
|
+
"messageId": {
|
|
1098
|
+
"description": "Required. The ID of the message to add the label to.",
|
|
1099
|
+
"type": "string"
|
|
1100
|
+
}
|
|
1101
|
+
},
|
|
1102
|
+
"required": [
|
|
1103
|
+
"messageId",
|
|
1104
|
+
"labelOption"
|
|
1105
|
+
],
|
|
1106
|
+
"type": "object"
|
|
1107
|
+
},
|
|
1108
|
+
"name": "apply_sensitive_message_label",
|
|
1109
|
+
"outputSchema": {
|
|
1110
|
+
"description": "Response message for ApplySensitiveMessageLabel RPC.",
|
|
1111
|
+
"properties": {},
|
|
1112
|
+
"type": "object"
|
|
1113
|
+
}
|
|
1114
|
+
},
|
|
880
1115
|
{
|
|
881
1116
|
"annotations": {
|
|
882
1117
|
"destructiveHint": false,
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"captureDate": "2026-07-20",
|
|
7
7
|
"httpStatus": 200,
|
|
8
8
|
"sha256": "6ef35bad568967015c101f89e995148c4eb2131b3a6dd244f7237058abae8e7a",
|
|
9
|
-
"canonicalSha256": "
|
|
9
|
+
"canonicalSha256": "56b5e86181c13ead63fdc8ea0d4bedc6860c1a3fdb17372fdca76591e48a4eed",
|
|
10
10
|
"request": {
|
|
11
11
|
"headers": {
|
|
12
12
|
"content-type": "application/json",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
},
|
|
21
21
|
"auth": "none (unauthenticated capture succeeded for tools/list and initialize)",
|
|
22
22
|
"liveToolCount": 13,
|
|
23
|
-
"launchToolCount":
|
|
24
|
-
"
|
|
23
|
+
"launchToolCount": 13,
|
|
24
|
+
"gate1PromotedFromPreview": [
|
|
25
25
|
"get_message",
|
|
26
26
|
"apply_sensitive_thread_label",
|
|
27
27
|
"apply_sensitive_message_label"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pome-sh/twin-gmail",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Deterministic Gmail-shaped twin for agent testing — SQLite-backed domain core.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
@@ -47,8 +47,9 @@
|
|
|
47
47
|
"access": "public"
|
|
48
48
|
},
|
|
49
49
|
"dependencies": {
|
|
50
|
+
"@hono/node-server": "^2.0.10",
|
|
50
51
|
"@pome-sh/sdk": "0.5.1",
|
|
51
|
-
"hono": "^4.12.
|
|
52
|
+
"hono": "^4.12.31",
|
|
52
53
|
"zod": "^4.1.13"
|
|
53
54
|
},
|
|
54
55
|
"keywords": [
|
|
@@ -36,7 +36,7 @@ const mergePath = (base, path) => {
|
|
|
36
36
|
};
|
|
37
37
|
const replaceUrlParam = (urlString, params) => {
|
|
38
38
|
for (const [k, v] of Object.entries(params)) {
|
|
39
|
-
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??");
|
|
39
|
+
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??(?=/|$)");
|
|
40
40
|
urlString = urlString.replace(reg, v ? `/${v}` : "");
|
|
41
41
|
}
|
|
42
42
|
return urlString;
|
|
@@ -33,16 +33,17 @@ class SSEStreamingApi extends import_stream.StreamingApi {
|
|
|
33
33
|
const dataLines = data.split(/\r\n|\r|\n/).map((line) => {
|
|
34
34
|
return `data: ${line}`;
|
|
35
35
|
}).join("\n");
|
|
36
|
-
for (const key of ["event", "id"
|
|
37
|
-
|
|
36
|
+
for (const key of ["event", "id"]) {
|
|
37
|
+
const value = message[key];
|
|
38
|
+
if (value && /[\r\n]/.test(value)) {
|
|
38
39
|
throw new Error(`${key} must not contain "\\r" or "\\n"`);
|
|
39
40
|
}
|
|
40
41
|
}
|
|
41
42
|
const sseData = [
|
|
42
43
|
message.event && `event: ${message.event}`,
|
|
43
44
|
dataLines,
|
|
44
|
-
message.id && `id: ${message.id}`,
|
|
45
|
-
message.retry && `retry: ${message.retry}`
|
|
45
|
+
message.id !== void 0 && `id: ${message.id}`,
|
|
46
|
+
message.retry !== void 0 && `retry: ${message.retry}`
|
|
46
47
|
].filter(Boolean).join("\n") + "\n\n";
|
|
47
48
|
await this.write(sseData);
|
|
48
49
|
}
|
|
@@ -55,7 +55,7 @@ const cache = (options) => {
|
|
|
55
55
|
);
|
|
56
56
|
const addHeader = (c, responseVary) => {
|
|
57
57
|
if (cacheControlDirectives) {
|
|
58
|
-
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0]) ?? [];
|
|
58
|
+
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0].toLowerCase()) ?? [];
|
|
59
59
|
for (const directive of cacheControlDirectives) {
|
|
60
60
|
let [name, value] = directive.trim().split("=", 2);
|
|
61
61
|
name = name.toLowerCase();
|
|
@@ -57,7 +57,8 @@ const compress = (options) => {
|
|
|
57
57
|
return async function compress2(ctx, next) {
|
|
58
58
|
await next();
|
|
59
59
|
const contentLength = ctx.res.headers.get("Content-Length");
|
|
60
|
-
if (ctx.res.
|
|
60
|
+
if (ctx.res.status === 206 || // partial content, Content-Range refers to the uncompressed bytes
|
|
61
|
+
ctx.res.headers.has("Content-Encoding") || // already encoded
|
|
61
62
|
ctx.res.headers.has("Transfer-Encoding") || // already encoded or chunked
|
|
62
63
|
ctx.req.method === "HEAD" || // HEAD request
|
|
63
64
|
contentLength && Number(contentLength) < threshold || // content-length below threshold
|
|
@@ -80,11 +80,13 @@ const methodOverride = (options) => async function methodOverride2(c, next) {
|
|
|
80
80
|
if (method) {
|
|
81
81
|
const url = new URL(c.req.url);
|
|
82
82
|
url.searchParams.delete(queryName);
|
|
83
|
-
const
|
|
83
|
+
const requestInit = {
|
|
84
84
|
body: c.req.raw.body,
|
|
85
85
|
headers: c.req.raw.headers,
|
|
86
|
-
method
|
|
87
|
-
|
|
86
|
+
method,
|
|
87
|
+
duplex: c.req.raw.body ? "half" : void 0
|
|
88
|
+
};
|
|
89
|
+
const request = new Request(url.toString(), requestInit);
|
|
88
90
|
return app.fetch(request, c.env, getExecutionCtx(c));
|
|
89
91
|
}
|
|
90
92
|
}
|
|
@@ -71,14 +71,20 @@ const secureHeaders = (customOptions) => {
|
|
|
71
71
|
const headersToSet = getFilteredHeaders(options);
|
|
72
72
|
const callbacks = [];
|
|
73
73
|
if (options.contentSecurityPolicy) {
|
|
74
|
-
const [callback, value] = getCSPDirectives(
|
|
74
|
+
const [callback, value] = getCSPDirectives(
|
|
75
|
+
options.contentSecurityPolicy,
|
|
76
|
+
"Content-Security-Policy"
|
|
77
|
+
);
|
|
75
78
|
if (callback) {
|
|
76
79
|
callbacks.push(callback);
|
|
77
80
|
}
|
|
78
81
|
headersToSet.push(["Content-Security-Policy", value]);
|
|
79
82
|
}
|
|
80
83
|
if (options.contentSecurityPolicyReportOnly) {
|
|
81
|
-
const [callback, value] = getCSPDirectives(
|
|
84
|
+
const [callback, value] = getCSPDirectives(
|
|
85
|
+
options.contentSecurityPolicyReportOnly,
|
|
86
|
+
"Content-Security-Policy-Report-Only"
|
|
87
|
+
);
|
|
82
88
|
if (callback) {
|
|
83
89
|
callbacks.push(callback);
|
|
84
90
|
}
|
|
@@ -111,7 +117,7 @@ function getFilteredHeaders(options) {
|
|
|
111
117
|
return typeof overrideValue === "string" ? [defaultValue[0], overrideValue] : defaultValue;
|
|
112
118
|
});
|
|
113
119
|
}
|
|
114
|
-
function getCSPDirectives(contentSecurityPolicy) {
|
|
120
|
+
function getCSPDirectives(contentSecurityPolicy, headerName) {
|
|
115
121
|
const callbacks = [];
|
|
116
122
|
const resultValues = [];
|
|
117
123
|
for (const [directive, value] of Object.entries(contentSecurityPolicy)) {
|
|
@@ -136,7 +142,7 @@ function getCSPDirectives(contentSecurityPolicy) {
|
|
|
136
142
|
resultValues.pop();
|
|
137
143
|
return callbacks.length === 0 ? [void 0, resultValues.join("")] : [
|
|
138
144
|
(ctx, headersToSet) => headersToSet.map((values) => {
|
|
139
|
-
if (values[0] ===
|
|
145
|
+
if (values[0] === headerName) {
|
|
140
146
|
const clone = values[1].slice();
|
|
141
147
|
callbacks.forEach((cb) => {
|
|
142
148
|
cb(ctx, clone);
|
|
@@ -98,7 +98,7 @@ class HonoRequest {
|
|
|
98
98
|
if (name) {
|
|
99
99
|
return this.raw.headers.get(name) ?? void 0;
|
|
100
100
|
}
|
|
101
|
-
const headerData =
|
|
101
|
+
const headerData = /* @__PURE__ */ Object.create(null);
|
|
102
102
|
this.raw.headers.forEach((value, key) => {
|
|
103
103
|
headerData[key] = value;
|
|
104
104
|
});
|
|
@@ -316,11 +316,16 @@ const cloneRawRequest = async (req) => {
|
|
|
316
316
|
message: "Cannot clone request: body was already consumed and not cached. Please use HonoRequest methods (e.g., req.json(), req.text()) instead of consuming req.raw directly."
|
|
317
317
|
});
|
|
318
318
|
}
|
|
319
|
+
const body = await req[cacheKey]();
|
|
320
|
+
const headers = req.header();
|
|
321
|
+
if (body instanceof FormData) {
|
|
322
|
+
delete headers["content-type"];
|
|
323
|
+
}
|
|
319
324
|
const requestInit = {
|
|
320
|
-
body
|
|
325
|
+
body,
|
|
321
326
|
cache: req.raw.cache,
|
|
322
327
|
credentials: req.raw.credentials,
|
|
323
|
-
headers
|
|
328
|
+
headers,
|
|
324
329
|
integrity: req.raw.integrity,
|
|
325
330
|
keepalive: req.raw.keepalive,
|
|
326
331
|
method: req.method,
|
|
@@ -146,7 +146,7 @@ const getNextParam = (acceptHeader, startIndex) => {
|
|
|
146
146
|
const getNextAcceptValue = (acceptHeader, startIndex) => {
|
|
147
147
|
const accept = {
|
|
148
148
|
type: "",
|
|
149
|
-
params:
|
|
149
|
+
params: /* @__PURE__ */ Object.create(null),
|
|
150
150
|
q: 1
|
|
151
151
|
};
|
|
152
152
|
startIndex = consumeWhitespace(acceptHeader, startIndex);
|
|
@@ -33,6 +33,12 @@ const parseBody = async (request, options = /* @__PURE__ */ Object.create(null))
|
|
|
33
33
|
return {};
|
|
34
34
|
};
|
|
35
35
|
async function parseFormData(request, options) {
|
|
36
|
+
if (!isRawRequest(request) && request.bodyCache.formData) {
|
|
37
|
+
return convertFormDataToBodyData(
|
|
38
|
+
await request.bodyCache.formData,
|
|
39
|
+
options
|
|
40
|
+
);
|
|
41
|
+
}
|
|
36
42
|
const headers = isRawRequest(request) ? request.headers : request.raw.headers;
|
|
37
43
|
const arrayBuffer = await request.arrayBuffer();
|
|
38
44
|
const formDataPromise = (0, import_buffer.bufferToFormData)(arrayBuffer, headers.get("Content-Type") || "");
|
|
@@ -192,7 +192,7 @@ const _getQueryParam = (url, key, multiple) => {
|
|
|
192
192
|
return void 0;
|
|
193
193
|
}
|
|
194
194
|
}
|
|
195
|
-
const results =
|
|
195
|
+
const results = /* @__PURE__ */ Object.create(null);
|
|
196
196
|
encoded ??= /[%+]/.test(url);
|
|
197
197
|
let keyIndex = url.indexOf("?", 8);
|
|
198
198
|
while (keyIndex !== -1) {
|
|
@@ -8,7 +8,7 @@ var mergePath = (base, path) => {
|
|
|
8
8
|
};
|
|
9
9
|
var replaceUrlParam = (urlString, params) => {
|
|
10
10
|
for (const [k, v] of Object.entries(params)) {
|
|
11
|
-
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??");
|
|
11
|
+
const reg = new RegExp("/:" + k + "(?:{[^/]+})?\\??(?=/|$)");
|
|
12
12
|
urlString = urlString.replace(reg, v ? `/${v}` : "");
|
|
13
13
|
}
|
|
14
14
|
return urlString;
|
|
@@ -11,16 +11,17 @@ var SSEStreamingApi = class extends StreamingApi {
|
|
|
11
11
|
const dataLines = data.split(/\r\n|\r|\n/).map((line) => {
|
|
12
12
|
return `data: ${line}`;
|
|
13
13
|
}).join("\n");
|
|
14
|
-
for (const key of ["event", "id"
|
|
15
|
-
|
|
14
|
+
for (const key of ["event", "id"]) {
|
|
15
|
+
const value = message[key];
|
|
16
|
+
if (value && /[\r\n]/.test(value)) {
|
|
16
17
|
throw new Error(`${key} must not contain "\\r" or "\\n"`);
|
|
17
18
|
}
|
|
18
19
|
}
|
|
19
20
|
const sseData = [
|
|
20
21
|
message.event && `event: ${message.event}`,
|
|
21
22
|
dataLines,
|
|
22
|
-
message.id && `id: ${message.id}`,
|
|
23
|
-
message.retry && `retry: ${message.retry}`
|
|
23
|
+
message.id !== void 0 && `id: ${message.id}`,
|
|
24
|
+
message.retry !== void 0 && `retry: ${message.retry}`
|
|
24
25
|
].filter(Boolean).join("\n") + "\n\n";
|
|
25
26
|
await this.write(sseData);
|
|
26
27
|
}
|
|
@@ -34,7 +34,7 @@ var cache = (options) => {
|
|
|
34
34
|
);
|
|
35
35
|
const addHeader = (c, responseVary) => {
|
|
36
36
|
if (cacheControlDirectives) {
|
|
37
|
-
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0]) ?? [];
|
|
37
|
+
const existingDirectives = c.res.headers.get("Cache-Control")?.split(",").map((d) => d.trim().split("=", 1)[0].toLowerCase()) ?? [];
|
|
38
38
|
for (const directive of cacheControlDirectives) {
|
|
39
39
|
let [name, value] = directive.trim().split("=", 2);
|
|
40
40
|
name = name.toLowerCase();
|
|
@@ -35,7 +35,8 @@ var compress = (options) => {
|
|
|
35
35
|
return async function compress2(ctx, next) {
|
|
36
36
|
await next();
|
|
37
37
|
const contentLength = ctx.res.headers.get("Content-Length");
|
|
38
|
-
if (ctx.res.
|
|
38
|
+
if (ctx.res.status === 206 || // partial content, Content-Range refers to the uncompressed bytes
|
|
39
|
+
ctx.res.headers.has("Content-Encoding") || // already encoded
|
|
39
40
|
ctx.res.headers.has("Transfer-Encoding") || // already encoded or chunked
|
|
40
41
|
ctx.req.method === "HEAD" || // HEAD request
|
|
41
42
|
contentLength && Number(contentLength) < threshold || // content-length below threshold
|
|
@@ -59,11 +59,13 @@ var methodOverride = (options) => async function methodOverride2(c, next) {
|
|
|
59
59
|
if (method) {
|
|
60
60
|
const url = new URL(c.req.url);
|
|
61
61
|
url.searchParams.delete(queryName);
|
|
62
|
-
const
|
|
62
|
+
const requestInit = {
|
|
63
63
|
body: c.req.raw.body,
|
|
64
64
|
headers: c.req.raw.headers,
|
|
65
|
-
method
|
|
66
|
-
|
|
65
|
+
method,
|
|
66
|
+
duplex: c.req.raw.body ? "half" : void 0
|
|
67
|
+
};
|
|
68
|
+
const request = new Request(url.toString(), requestInit);
|
|
67
69
|
return app.fetch(request, c.env, getExecutionCtx(c));
|
|
68
70
|
}
|
|
69
71
|
}
|