release: prepare v1.5.0 — client version bumps, changelogs, beta docs - #772
Conversation
Bump @e2a/sdk 5.4.0→5.5.0, e2a (PyPI) 5.4.0→5.5.0, @e2a/cli 2.1.0→2.2.0, and the e2a plugin 0.5.0→0.6.0 across the Claude/Codex/Cursor manifests and both marketplace manifests; refresh the root lockfile. Add user-focused 5.5.0/2.2.0 changelog entries covering contacts/outreach, scheduled sending (send_at), and the beta thread_id. Teach the e2a skill (v24) scheduled-send semantics: status=scheduled is durable success, scheduled_at is the future submission time, wait=sent does not wait for it, and send_at vs next_action_at/contact.due are different concepts. Add the beta Contacts & Outreach section to docs/api.md (all 11 operations, scopes, ETags/If-Match, metadata/import bounds, idempotency, safe import-reversal retention rule, derived vs caller-owned fields, contact.due). Correct docs/events.md: contact.due is a notification only a deployed webhook receiver can act on. Add beta contacts + scheduled-sending bullets to the README feature list. tests/sdk-monitor pins stay at the published 5.4.0/2.1.0 until the new packages are actually on npm/PyPI (main's image build installs from the public registries). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Per Josh's direction the core /v1 surface is presented as stable/GA with the beta set explicitly enumerated, grounded in the spec's machine-readable x-stability-level markers (verified against api/openapi.yaml: 43 GA ops, 29 beta ops). - docs/api.md: new 'Stability: GA and beta surface' section near the top — GA/beta matrix by resource group, beta fields on otherwise-GA operations (send_at/scheduled_at/scheduled, thread_id, template refs, managed unsubscribe, review-hold projections, export interior schemas), and beta events; cross-references x-stability-level and the Beta operations table. - README: replace the stale 'release candidates / GA planned by July 31, 2026' banner with the GA statement + enumerated beta list, linking the matrix. - AGENTS.md: same one-sentence posture fix (was repeating the release-candidate claim). - Changelogs (TS 5.5.0 / Py 5.5.0 / CLI 2.2.0): one-line pointer to the stability matrix. - cli/README.md: mark 'e2a contacts' beta (MCP README already was). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
jiashuoz
left a comment
There was a problem hiding this comment.
Team review at exact head 1eeb187 found four release-blocking documentation/package issues plus one packaging cleanup:
-
[P2] Regenerate the Python lockfile. sdks/python/pyproject.toml is 5.5.0, but sdks/python/uv.lock still records the editable e2a package as 5.4.0. On this exact head, uv lock --check reports that the lockfile needs updating, so locked contributor/CI environments are no longer reproducible. Please update uv.lock and consider checking it in CI.
-
[P2] Remove sdks/python/.coverage from the source distribution. This tracked SQLite coverage database is included by the current Hatch sdist configuration and exposes absolute local development/worktree paths. The wheel is clean, but the sdist is not. Please remove and ignore the artifact, exclude it defensively from sdists, and add an artifact-content assertion.
-
[P2] Resolve the GA baseline contradiction. README.md now says v1.0.x predates the freeze and is not a compatibility baseline, while docs/api.md says the stable surface is stable as of e2a 1.0 and later still says /v1 is not yet GA. Pick the real baseline (apparently 1.5.0), state it consistently, and convert the remaining pre-GA language to present tense.
-
[P2] Complete the promised exhaustive beta inventory. lifecycle_transitions is beta on seven otherwise-GA event payload schemas, but the new top-level matrix and README omit it. The README also says beta is identified by x-stability-level, while beta enum/status values use x-experimental-values (including scheduled, beta event-type values, and blocked_by_policy). The older compatibility inventory is missing additional surfaces such as contacts/outreach, lifecycle, and thread_id. Please consolidate this into one complete source of truth and document both extension mechanisms.
-
[P3] Exclude compiled CLI tests from the npm package. npm pack --dry-run includes dist/tests/*.test.js because the production build compiles all of src and the package publishes dist. A production tsconfig or explicit package allowlist would avoid shipping test code.
Verification on the exact head: the OpenAPI operation counts are internally consistent (72 total: 43 GA, 29 beta), the detailed beta operation table matches all 29 beta operations, SDK version sync/plugin validation/repository text-integrity checks pass, TS and CLI builds pass, and GitHub CI is green. These findings are therefore release-preparation gaps rather than failures of the new operation-count inventory.
The version-bump commit touched pyproject.toml but not uv.lock, so `uv lock --check` failed and `uv sync --locked` broke at this head. Regenerated with `uv lock`; the only change is the editable e2a package 5.4.0 -> 5.5.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
sdks/python/.coverage is a pytest-cov SQLite DB whose file.path rows embed absolute local paths; it has been tracked since v1.3.0 and was shipping in the sdist (hatchling default selection — pyproject had only a wheel target). Untrack it, gitignore sdks/python/.coverage*, and add a defensive sdist exclude so a build from a tree containing one stays clean. The wheel was already clean. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The new stability matrix says the /v1 freeze lands at >=1.5.0, but two pre-existing api.md passages still claimed 'stable as of e2a 1.0' and 'Once /v1 is GA ... (Pre-GA, the API is still being frozen ...)', and SECURITY.md still said no official GA release exists. Name 1.5.0 as the real baseline, move the pre-GA removal note to past tense, and update the SECURITY.md supported-versions story to match. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
- Add the property-level lifecycle_transitions beta marker (on the seven otherwise-stable event payload schemas) to the summary list of beta fields on otherwise-GA operations — it was documented deeper in api.md and events.md but missing from the new summary. - Name both marker mechanisms wherever the marker story is told: x-stability-level for beta operations/schemas/fields, and x-experimental-values for beta values of stable fields (scheduled, the screening/review-hold event types, blocked_by_policy). README previously mentioned only x-stability-level. - Collapse the older compatibility-rules beta enumeration (which had drifted: it was missing contacts & outreach, message lifecycle diagnostics, and thread_id) into a pointer at the stability matrix, leaving one source of truth. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
cli/tsconfig.json included src wholesale, so tsc emitted dist/__tests__/*.test.js and 'files': ['dist'] shipped them (17 of 36 packed files). Exclude src/__tests__ from the build config and add a tsconfig.test.json + typecheck script (mirroring sdks/typescript) so the tests stay typechecked via npm test. npm pack now ships 19 files, all runtime dist output. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
# Conflicts: # .gitignore
Resolves conflicts with the #780/#776/#781/#782/#783/#772 batch: - contacts_import.go: keep #780's removal of the per-row maxLength schema tags (over-long rows must fail per-row, not 422 the batch); keep this branch's Metadata doc rewording. - outbound.go: combine both edits to the 400 description — this branch's SMTP octet limits on invalid_request/invalid_recipient plus #780's filename/CRLF cases on invalid_attachment. - api/openapi.yaml + both SDK generated files: regenerated from the resolved sources (make spec, make generate-sdk). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The branch adds the whole command group (list/add/remove, account-wide vs --agent routing) plus README docs but never touched cli/CHANGELOG.md. Document it in the unpublished 2.2.0 section, matching the existing entries' detail level, with the #772 stability split stated: account-wide suppressions GA, agent-scoped suppression management beta. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Summary
Release-prep for the additive v1.5.0 product release (contacts/outreach beta, scheduled sending beta, webhook delivery observability, thread identity beta, MIME/DKIM hardening). Version bumps + changelogs + agent-guidance and public-doc updates only — no code changes. (No API surface changes, so the client-surface checklist is omitted.)
Update (per Josh's direction): the core
/v1surface is now presented as stable/GA with the beta set explicitly enumerated, grounded in the spec's machine-readablex-stability-levelmarkers. Verified againstapi/openapi.yamlin this tree: 43 GA operations, 29 beta operations (note: the templates+starter-templates beta group is 8 ops, not 9 — the 29 total holds). Changes in the second commit (1eeb187c):docs/api.md— new prominent "Stability: GA and beta surface" section near the top: GA/beta matrix by resource group, the beta-fields-on-GA-operations list (scheduled sending,thread_id, template refs, managed unsubscribe, review-hold projections, export interior schemas), and the beta events, cross-referencingx-stability-levelas the source of truth and the existing "Beta operations" table.README.md— the stale "release candidates / GA planned by July 31, 2026" banner replaced with the GA statement + enumerated beta list, linking the matrix.AGENTS.md— the same one-sentence release-candidate claim fixed (it would otherwise keep telling agents the API is unstable).cli/README.md—e2a contactsmarked beta (MCP README already was).Version bumps
@e2a/sdk(TS)sdks/typescript/package.jsone2a(PyPI)sdks/python/pyproject.toml@e2a/clicli/package.json.claude-plugin/.codex-plugin/.cursor-pluginplugin.json +.claude-plugin/.cursor-pluginmarketplace.jsonRoot
package-lock.jsonrefreshed (workspace version entries only). TheInternal SDK version syncgate has no separate fixture file —scripts/check-sdk-version-sync.mjsreads the live package.jsons;cli/mcpdeclare@e2a/sdk@^5.0.0, satisfied by 5.5.0 (verified green).@e2a/mcp-serverstays frozen at 0.5.0 (npm publish retired — the 0.5.0 there is unrelated to the plugin's old 0.5.0).Deliberately NOT bumped:
tests/sdk-monitorpins the exact published@e2a/sdk@5.4.0/@e2a/cli@2.1.0/e2a==5.4.0. Main's monitor image build installs from the public registries and would fail on unpublished versions — the monitor pins are updated in a follow-up only after the packages are visible on npm/PyPI (release-order step 4 below).Changelog highlights (TS 5.5.0 / Py 5.5.0 / CLI 2.2.0)
contact.dueevent.send_aton send/reply/forward, up to 90 days ahead;status=scheduled+scheduled_atare durable acceptance; cancel via trash-before-submission, restore-before-scheduled_atre-arms; review holds drop the schedule.e2a contactscommand tree (incl. CSV import with--dry-run) and--send-atonsend/reply.thread_idon message reads (PR feat(threading): materialize mailbox-local email thread identity #765) — server-owned mailbox-local topology identity, response-only.Guidance & docs
plugins/e2a/skills/e2a/SKILL.md(skill v23 → v24; skill integer version and plugin semver remain distinct concepts):status=scheduledis durable success — never retry;scheduled_atis the future submission time;wait=sentdoes not wait for a futuresend_at;send_at(scheduled sending) vsnext_action_at/contact.due(outreach scheduling) explicitly contrasted.docs/api.md: new Contacts & Outreach (beta) resource section — all 11 operations, account-vs-agent scope split, pagination/filters, ETag/If-Match, metadata bounds (flat, ≤50 keys, ≤128 B keys, ≤4 KiB values, ≤16 KiB total) and import bounds, idempotency, import-reversal retention rule matched tointernal/identity/contacts.go(DeleteImportBatch: untouched-only deletion —updated_at == created_at, no wire activity, no message history, no surviving engagement; provenance tags never move on merge re-import), derived vs caller-owned engagement fields,contact.duebehavior. This also fulfills the OpenAPImetadatafield's "see the field bounds in the API docs" pointer.docs/events.md:contact.duecorrected — it is a notification, not an execution mechanism; only a deployed webhook receiver (or events-log poller) can use it to wake an agent runtime; it does not start an MCP/WebSocket/Claude Code/Codex session.README.md: contacts/outreach and scheduled sending added to the feature list, both marked beta.Required release order
ts-sdk-v5.5.0andpython-v5.5.0.v1.5.0tag — builds server/web/MCP images and publishes the CLI (CLI publish requires thecli/package.jsonbump in this PR; npm rejects republish otherwise).tests/sdk-monitorpins in a follow-up PR.release.envbump).Test evidence (all local/offline)
node scripts/check-sdk-version-sync.mjs— green (cli + mcp in sync with workspace SDK 5.5.0)node scripts/validate-plugin.mjs— green (4 skills, version 0.6.0, manifests in sync across Claude/Codex/Cursor)node --test scripts/plugin-agent-guidance.test.mjs— 9/9 passbash scripts/check-repository-text-integrity.sh— green (incl. agent-doc mirrors + SDK example contracts)npm run build && npm test --workspace @e2a/sdk— 228/228 pass + type testsnpm run build && npm test --workspace @e2a/cli— 266/266 passnpm run build && npm test --workspace @e2a/mcp-server— 291/291 pass + type testspytest tests/(excl. live contract) — 498 pass / 13 skip, coverage 94%;mypy— cleanOpen questions for Josh
GA-language contradiction:Resolved by Josh's direction — the core/v1surface is stable/GA with the beta set explicitly enumerated; README and AGENTS.md now say so anddocs/api.md's stable-contract stance stands (see the stability-matrix update above).contact.duepayload is still untyped (internal/contactdue, noEventEnvelopedata schema) while every other stable event has one — fine for beta, but worth a typed schema before it's declared stable.Review fixes (applied at
08ed71ba)Five validated fixes from the pre-merge review pass, one commit each:
a7cdfeef— regenerate stale Pythonuv.lock. The 5.5.0 version bump touchedpyproject.tomlbut not the lock, souv lock --checkfailed at the previous head (contributors/CI onuv sync --lockedwould break at the release tag). Regenerated; the only change is the editablee2apackage5.4.0 → 5.5.0, no third-party pin churn.uv lock --checknow passes.c8e59d56— untracksdks/python/.coverageand keep it out of the sdist. A 53 KB pytest-cov SQLite DB with absolute local paths, tracked since v1.3.0 and shipping in the sdist (hatchling default selection). Untracked, gitignored (sdks/python/.coverage*), plus a defensive[tool.hatch.build.targets.sdist] exclude—uv build --sdistverified clean. (Same untracking is also in flight on the fix(api): input validation and error mapping #780 branch; the two converge at merge.) No packaging/artifact-content test exists in the repo to extend — noted rather than inventing one.de55f072— GA baseline reconciled to the 1.5.0 freeze.docs/api.mdno longer says "stable … as of e2a 1.0" (now names 1.5.0 and repeats the not-a-baseline caveat forv1.0.xtags) and the "Once/v1is GA … (Pre-GA, the API is still being frozen …)" deprecation bullet is present-tense with the endpoint removal as history.SECURITY.md's "has not yet published its official GA release" supported-versions story updated to match. Historical uses of "pre-GA" (changelogs, design docs, code comments,docs/api-compatibility-gate.md's freeze-anchor mechanics) deliberately left as history.12ee043f— beta inventory completed, both markers named. The summary list of beta-fields-on-GA-operations now includes the property-levellifecycle_transitionsmarker on the seven event payload schemas; README (and the api.md list header) now documentx-experimental-valuesalongsidex-stability-level; and the older compatibility-rules beta enumeration (which had drifted — no contacts, lifecycle diagnostics, orthread_id) is collapsed into a pointer at the stability matrix, leaving one source of truth. Inventory re-derived from the spec: 29 op-level, 63 schema-level, 30 property-levelx-stability-levelmarkers + 6x-experimental-valuessites — all accounted for in the matrix.08ed71ba— CLI npm tarball no longer ships compiled tests.dist/__tests__/*.test.jswas 17 of 36 packed files.cli/tsconfig.jsonnow excludessrc/__tests__; a newcli/tsconfig.test.json+typecheckscript (mirroringsdks/typescript) keeps tests typechecked vianpm test.npm pack --dry-run: 19 files, all runtimedistoutput; CLI suite still 266/266.Verification at
08ed71ba:make spec-checkgreen (no spec changes),scripts/check-repository-text-integrity.shgreen,node scripts/validate-plugin.mjsgreen,node --test scripts/sync-agent-docs.test.mjs4/4, TS SDK + CLI builds green.🤖 Generated with Claude Code