Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .agents/skills/custom-commands/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ with the following sub-clients:
|-------|------|-------------|
| `client.inboxes` | `agentmail_sdk::api::InboxesClient` | inboxes operations |
| `client.api_keys` | `agentmail_sdk::api::ApiKeysClient2` | api_keys operations |
| `client.browser_credentials` | `agentmail_sdk::api::BrowserCredentialsClient` | browser_credentials operations |
| `client.drafts` | `agentmail_sdk::api::DraftsClient2` | drafts operations |
| `client.events` | `agentmail_sdk::api::EventsClient` | events operations |
| `client.lists` | `agentmail_sdk::api::ListsClient2` | lists operations |
Expand Down
16 changes: 16 additions & 0 deletions .fern/replay.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.fern/replay.lock linguist-generated=true
72 changes: 52 additions & 20 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -141,14 +141,20 @@ jobs:
# that needs /lib/ld-musl-*.so.1 at runtime — which defeats the point
# of a musl build and crashes where that loader is absent. Left alone,
# rustc links the self-contained musl objects statically.
#
# Built with the `dist` profile — the same one cargo-dist uses for the
# GitHub Release — so npm and the Release ship byte-identical binaries
# for a given tag. Building `--release` here meant two channels
# shipping different bytes under one version, which surfaces as an
# unreproducible bug report.
- name: Build release binary
shell: bash
run: |
if [[ "${{ matrix.rust-target }}" == *-linux-musl ]]; then
TARGET_UNDERSCORE=$(echo "${{ matrix.rust-target }}" | tr '-' '_')
export "CC_${TARGET_UNDERSCORE}=musl-gcc"
fi
cargo build --release --target ${{ matrix.rust-target }}
cargo build --profile dist --target ${{ matrix.rust-target }}

- name: Package and publish npm platform package
shell: bash
Expand All @@ -165,7 +171,9 @@ jobs:
if [[ "${{ matrix.rust-target }}" == *"windows"* ]]; then
BINARY_NAME="agentmail.exe"
fi
cp "target/${{ matrix.rust-target }}/release/${BINARY_NAME}" "${PKG_DIR}/"
# A custom cargo profile writes to target/<triple>/<profile>/, not
# .../release/.
cp "target/${{ matrix.rust-target }}/dist/${BINARY_NAME}" "${PKG_DIR}/"

# Write platform package.json
cat > "${PKG_DIR}/package.json" <<PKGJSON
Expand All @@ -185,14 +193,22 @@ jobs:
PKGJSON

cd "${PKG_DIR}"
# Pre-release detection — require the semver "-" separator so a
# release tag like v1.0.0 for a package whose version string
# happens to contain "alpha"/"beta" as a substring isn't
# mis-tagged on npm.
if [[ "${VERSION}" == *-alpha* ]]; then
npm publish --access public --tag alpha
elif [[ "${VERSION}" == *-beta* ]]; then
npm publish --access public --tag beta
# Pre-release detection. ANY SemVer pre-release (a "-" after the
# version core) must get a non-latest dist-tag: matching only
# -alpha/-beta let a v1.1.0-rc.1 or -next.1 tag fall through to a
# bare `npm publish`, which moves `latest` to a pre-release for
# every existing installer. The tag is the first dot-separated
# pre-release identifier, stripped to a safe slug, so -rc.1 -> rc
# and -next.1 -> next; an all-numeric or empty identifier falls
# back to "prerelease" because npm rejects a numeric dist-tag.
PRERELEASE="${VERSION#*-}"
if [[ "${VERSION}" == *-* ]]; then
TAG=$(echo "${PRERELEASE%%.*}" | tr -cd '[:alnum:]-')
if [[ -z "${TAG}" || "${TAG}" =~ ^[0-9]+$ ]]; then
TAG=prerelease
fi
echo "Publishing pre-release ${VERSION} with --tag ${TAG}"
npm publish --access public --tag "${TAG}"
else
PKG_NAME=$(node -p "require('./package.json').name")
PKG_VERSION=$(node -p "require('./package.json').version")
Expand Down Expand Up @@ -288,22 +304,38 @@ jobs:
try {
execFileSync(binPath, process.argv.slice(2), { stdio: "inherit" });
} catch (e) {
if (e && typeof e === "object" && "status" in e) {
process.exit(e.status);
if (e && typeof e === "object") {
// Propagate the child's exit code; a signal death has no
// numeric status, so report it as 128+signum like a shell does.
if (typeof e.status === "number") {
process.exit(e.status);
}
if (typeof e.signal === "string") {
const SIGNUM = { SIGHUP: 1, SIGINT: 2, SIGQUIT: 3, SIGILL: 4, SIGABRT: 6, SIGFPE: 8, SIGKILL: 9, SIGSEGV: 11, SIGPIPE: 13, SIGALRM: 14, SIGTERM: 15 };
process.exit(128 + (SIGNUM[e.signal] || 0));
}
}
throw e;
}
LAUNCHER

cd "${PKG_DIR}"
# Pre-release detection — require the semver "-" separator so a
# release tag like v1.0.0 for a package whose version string
# happens to contain "alpha"/"beta" as a substring isn't
# mis-tagged on npm.
if [[ "${VERSION}" == *-alpha* ]]; then
npm publish --access public --tag alpha
elif [[ "${VERSION}" == *-beta* ]]; then
npm publish --access public --tag beta
# Pre-release detection. ANY SemVer pre-release (a "-" after the
# version core) must get a non-latest dist-tag: matching only
# -alpha/-beta let a v1.1.0-rc.1 or -next.1 tag fall through to a
# bare `npm publish`, which moves `latest` to a pre-release for
# every existing installer. The tag is the first dot-separated
# pre-release identifier, stripped to a safe slug, so -rc.1 -> rc
# and -next.1 -> next; an all-numeric or empty identifier falls
# back to "prerelease" because npm rejects a numeric dist-tag.
PRERELEASE="${VERSION#*-}"
if [[ "${VERSION}" == *-* ]]; then
TAG=$(echo "${PRERELEASE%%.*}" | tr -cd '[:alnum:]-')
if [[ -z "${TAG}" || "${TAG}" =~ ^[0-9]+$ ]]; then
TAG=prerelease
fi
echo "Publishing pre-release ${VERSION} with --tag ${TAG}"
npm publish --access public --tag "${TAG}"
else
PKG_NAME=$(node -p "require('./package.json').name")
PKG_VERSION=$(node -p "require('./package.json').version")
Expand Down
17 changes: 16 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,22 @@ jobs:
# Write and read notes from a file to avoid quoting breaking things
echo "$ANNOUNCEMENT_BODY" > $RUNNER_TEMP/notes.txt

gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
# Re-runs and pre-created releases must not fail after a successful build.
# --draft=false publishes a release that was drafted in the UI:
# gh release view finds drafts, so without it the assets upload into
# a release nobody can see and the job still reports success. A draft
# has no tag yet, so --target decides where that tag lands; for an
# already-published release the tag exists and GitHub ignores it.
if gh release view "${{ needs.plan.outputs.tag }}" > /dev/null 2>&1; then
if [[ -n "$PRERELEASE_FLAG" ]]; then
gh release edit "${{ needs.plan.outputs.tag }}" --title "$ANNOUNCEMENT_TITLE" --target "$RELEASE_COMMIT" --notes-file "$RUNNER_TEMP/notes.txt" --draft=false --prerelease
else
gh release edit "${{ needs.plan.outputs.tag }}" --title "$ANNOUNCEMENT_TITLE" --target "$RELEASE_COMMIT" --notes-file "$RUNNER_TEMP/notes.txt" --draft=false --prerelease=false
fi
gh release upload "${{ needs.plan.outputs.tag }}" artifacts/* --clobber
else
gh release create "${{ needs.plan.outputs.tag }}" --target "$RELEASE_COMMIT" $PRERELEASE_FLAG --title "$ANNOUNCEMENT_TITLE" --notes-file "$RUNNER_TEMP/notes.txt" artifacts/*
fi

announce:
needs:
Expand Down
61 changes: 47 additions & 14 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "agentmail-cli"
version = "1.0.0"
version = "1.1.0"
edition = "2021"
description = "Command-line interface for the AgentMail API. Send, receive, reply, and manage threaded email conversations from your terminal."
license = "MIT"
Expand Down
Loading
Loading