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
2 changes: 1 addition & 1 deletion .env.production.example
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Web deployment
VITE_CONVEX_URL=https://your-production-convex.convex.cloud
VITE_CONVEX_SITE_URL=https://your-production-convex.convex.site
VITE_DOCS_URL=https://docs.amend.sh/docs
VITE_DOCS_URL=https://amend.sh/docs
VITE_POSTHOG_TOKEN=phc_BCb25jVTo59jtEMPysgGUvgt85bUYGwN8XBNA2oMNLY7
VITE_POSTHOG_HOST=https://us.i.posthog.com
VITE_POSTHOG_PROJECT_ID=441195
Expand Down
23 changes: 7 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,15 +103,6 @@ The artifact includes a `$schema` field documented in `docs/agent-ready-status-r
validate a saved status artifact with
`bun run agent-ready:status:validate-report agent-ready-status.json`; add `--require-ok` when CI
should fail unless the no-secret status is blocker-free.
Use `bun run agent-ready:next-steps` when an operator needs the same no-secret env, deployment,
and DNS blockers as a short checklist. Use
`bun --silent scripts/agent-ready-next-steps.ts --json --json-file agent-ready-next-steps.json`
when CI needs that checklist as an artifact. The artifact keeps the flat env list, records safe
public production values, groups missing values into web deployment and Convex deployment steps, and includes deploy/host-attachment steps
before DNS wiring. It includes a `$schema` field documented in
`docs/agent-ready-next-steps-report.schema.json`; validate a saved checklist with
`bun run agent-ready:next-steps:validate-report agent-ready-next-steps.json`; add `--require-ok`
when CI should fail unless the checklist is blocker-free.

If you only need to recheck the already-deployed public hosts, run:

Expand Down Expand Up @@ -139,8 +130,8 @@ Use `bun run agent-ready:refresh-report` when CI should refresh the saved report
timestamps, validate the artifact, run the completion audit in production-blocker-tolerant mode, and
still exit red while production blockers remain. Use `bun run agent-ready:final-gate` after
production env and DNS are ready to regenerate the saved reports, run the strict completion audit,
refresh and validate the no-secret status and next-steps reports, require the production, live,
status, completion audit, and next-steps reports to be green, and verify synced audit evidence. Use
refresh and validate the no-secret status report, require the production, live, status, and
completion audit reports to be green, and verify synced audit evidence. Use
`bun run agent-ready:completion-audit` as the
strict prompt-to-artifact gate; it exits non-zero until strict readiness, production env, the live
validator, and the saved production report are all green. Use
Expand All @@ -153,8 +144,8 @@ schema endpoint. Validate it with
add `--require-ok` when CI should fail unless the completion audit is fully green.
After saving a report, run `bun run agent-ready:sync-audit agent-ready-production-report.json` to
sync the launch audit timestamps, then `bun run agent-ready:audit:check` to validate the saved
production, live, status, completion audit, and next-steps reports and confirm the audits are
synced to the production report.
production, live, status, and completion audit reports and confirm the audits are synced to the
production report.

The live gate checks registration, DNS delegation, A/AAAA/CNAME DNS records, final response origin,
`robots.txt`, `sitemap.xml`, unique on-origin sitemap locs, `llms.txt` links aligned to the matching
Expand All @@ -168,7 +159,7 @@ metadata and
parseable JSON-LD, crawlable canonical/Open Graph HTML for every web sitemap page, private-route
`noindex`, docs root canonical/Open Graph/parseable WebSite JSON-LD HTML, and docs index
canonical/Open Graph/parseable TechArticle JSON-LD HTML plus the production, live, status,
completion audit, and next-steps report schema endpoints for `amend.sh` and `docs.amend.sh`.
and completion audit report schema endpoints for `amend.sh` and `docs.amend.sh`.

## Convex Setup

Expand Down Expand Up @@ -245,8 +236,8 @@ Your app will connect to the configured Convex deployment automatically.
The normal `bun run dev`, `bun run dev:web`, and `bun run dev:docs` commands set
`WORKTREE_NAME=${WORKTREE_NAME:-$(basename "$PWD")}` and use portless. The web app reads
`VITE_DOCS_URL` for docs links. Local development defaults to the matching
`http://docs.$WORKTREE_NAME.localhost:1355/docs`; this launch uses `https://docs.amend.sh/docs` in
production.
`http://docs.$WORKTREE_NAME.localhost:1355/docs`; this launch uses `https://amend.sh/docs` for
product links in production while `https://docs.amend.sh` remains the canonical docs origin.

## UI Customization

Expand Down
94 changes: 94 additions & 0 deletions apps/fumadocs/content/docs/api-reference.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
---
title: API Reference
description: Beta REST and SDK contract for portal reads, customer writes, owner mutations, and webhooks.
---

The REST API is served by Convex HTTP actions under `/api/v1`. The SDK wraps the same route
families and keeps the workspace slug in the `project` option.

```ts
import { Amend } from "@amend/sdk";

const amend = new Amend({
project: "amend-labs",
apiBaseUrl: "http://127.0.0.1:3211/api/v1",
token: process.env.AMEND_API_TOKEN,
});
```

The beta OpenAPI contract lives in `packages/api-spec/openapi.yaml`.

## Authentication

When `AMEND_API_TOKEN` is configured, owner-level mutations require:

```http
Authorization: Bearer <AMEND_API_TOKEN>
```

Public portal reads, feedback submissions, identity mapping, event tracking, unsubscribes, and
signed provider webhooks remain callable without the owner token where appropriate.

## Public Reads

| Method | Endpoint | SDK method |
| ------ | ------------------------------- | ----------------------------- |
| `GET` | `/api/v1/version` | `amend.version()` |
| `GET` | `/api/v1/:workspace/portal` | `amend.portal()` |
| `GET` | `/api/v1/:workspace/roadmap` | `amend.roadmap()` |
| `GET` | `/api/v1/:workspace/changelog` | `amend.changelog()` |
| `GET` | `/api/v1/:workspace/updates` | `amend.updatesForUser()` |
| `GET` | `/api/v1/:workspace/github-app` | `amend.githubApp()` |
| `GET` | `/api/v1/:workspace/plans` | `amend.plans()` |
| `GET` | `/api/v1/_/domains` | `amend.resolveCustomDomain()` |

## Customer Writes

| Method | Endpoint | SDK method |
| ------ | --------------------------------- | -------------------------------------- |
| `POST` | `/api/v1/:workspace/identity` | `amend.identify()` |
| `POST` | `/api/v1/:workspace/feedback` | `amend.submitRequest()` |
| `POST` | `/api/v1/:workspace/interactions` | `amend.vote()`, `comment()`, `react()` |
| `POST` | `/api/v1/:workspace/events` | `amend.track()` |
| `POST` | `/api/v1/:workspace/preferences` | `amend.setNotificationPreference()` |

## Owner Reads

| Method | Endpoint | SDK method |
| ------ | ---------------------------------- | ----------------------------- |
| `GET` | `/api/v1/:workspace/settings` | `amend.settings()` |
| `GET` | `/api/v1/:workspace/decisions` | `amend.automationDecisions()` |
| `GET` | `/api/v1/:workspace/source-events` | `amend.sourceEvents()` |
| `GET` | `/api/v1/:workspace/build-briefs` | `amend.buildBriefs()` |
| `GET` | `/api/v1/:workspace/agent-runs` | `amend.agentRuns()` |
| `GET` | `/api/v1/:workspace/deliveries` | `amend.deliveryOutbox()` |
| `GET` | `/api/v1/:workspace/projects` | `amend.projects()` |

## Owner Mutations

| Method | Endpoint | SDK method |
| ------ | ------------------------------------ | -------------------------------------------- |
| `POST` | `/api/v1/:workspace/projects` | `amend.createProject()` |
| `POST` | `/api/v1/:workspace/repositories` | `amend.connectRepository()` |
| `POST` | `/api/v1/:workspace/source-events` | `amend.importSourceEvent()` |
| `POST` | `/api/v1/:workspace/drafts` | `amend.draftChangelog()` |
| `POST` | `/api/v1/:workspace/changelog` | `amend.upsertChangelog()` |
| `POST` | `/api/v1/:workspace/roadmap` | `amend.upsertRoadmapItem()` |
| `POST` | `/api/v1/:workspace/rules` | `amend.updateAutomationRules()` |
| `POST` | `/api/v1/:workspace/members` | `amend.upsertWorkspaceMember()` |
| `POST` | `/api/v1/:workspace/integrations` | `amend.upsertIntegration()` |
| `POST` | `/api/v1/:workspace/portal-settings` | `amend.updatePortalSettings()` |
| `POST` | `/api/v1/:workspace/domains` | `amend.registerCustomDomain()` |
| `POST` | `/api/v1/:workspace/deliveries` | `amend.planDeliveries()`, `sendDeliveries()` |
| `POST` | `/api/v1/:workspace/plans` | `amend.updatePlan()` |
| `POST` | `/api/v1/:workspace/checkout` | `amend.createCheckoutSession()` |

## Webhooks

| Method | Endpoint | Verification |
| ------ | --------------------------- | -------------------------------------------------- |
| `POST` | `/api/v1/:workspace/github` | `X-Hub-Signature-256` with `GITHUB_WEBHOOK_SECRET` |
| `POST` | `/api/v1/:workspace/stripe` | Stripe webhook secret and raw body |

Use the OpenAPI file for schema-level details and generated client types. Use this page for the
route/auth map when wiring product surfaces.
96 changes: 96 additions & 0 deletions apps/fumadocs/content/docs/automation.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
---
title: Automation
description: Configure Mostly Auto rules, AI drafting, proactive agent runs, and delivery safety.
---

Automation should start review-first, then become more automatic where the source evidence is strong.
Amend stores decisions with source context so teams can inspect why something changed before it
becomes public.

## Rules

Use Mostly Auto when safe status updates can apply automatically, but public copy and high-impact
notifications still require review.

```ts
await amend.updateAutomationRules({
mode: "mostly_auto",
autoDraftChangelog: true,
autoPublishChangelog: false,
autoNotifyUsers: false,
autoUpdateFeedbackStatus: true,
requireReviewBelowConfidence: 0.82,
requireReviewForHighImpact: true,
requireReviewForPublicCopy: true,
});
```

## Changelog Drafting

Local dry-runs do not require provider credentials:

```ts
await amend.draftChangelog({
title: "Webhook retry status",
kind: "pull_request",
dryRun: true,
});
```

Production AI drafting requires provider keys in the Convex environment. Keep model policy
server-side:

```bash
bunx convex env set OPENAI_API_KEY "replace-with-provider-key"
bunx convex env set OPENAI_MODEL "gpt-5.1-mini"
```

The proactive agent can also use Crof/Kimi-compatible settings:

```bash
bunx convex env set CROF_API_KEY "replace-with-crof-key"
bunx convex env set CROF_MODEL "kimi-k2.6"
bunx convex env set CROF_BASE_URL "https://crof.ai/v1"
```

If the provider is missing or returns invalid output, the backend records a local fallback decision
instead of inventing source links.

## Decisions And Build Briefs

The SDK exposes the agent-readable review queues:

```ts
const decisions = await amend.automationDecisions();
const runs = await amend.agentRuns({ projectSlug: "web-app" });
const briefs = await amend.buildBriefs({ status: "in_review" });
```

Use these records to build reviewer workflows or hand a coding agent a demand-backed brief.

## Delivery Outbox

Plan deliveries before sending them. Keep `dryRun: true` until email, Slack, or webhook credentials
are verified.

```ts
await amend.planDeliveries({
channel: "email",
notificationKey: "notification-changelog-review-ready",
});

await amend.sendDeliveries({
channel: "email",
dryRun: true,
limit: 10,
});
```

Real email sends require `RESEND_API_KEY` and `EMAIL_FROM` in Convex.

## Safety Bar

- Public copy should stay reviewable until the workspace explicitly allows auto-publish.
- Low-confidence source matches should suggest investigation, not publish.
- Delivery sends should start as dry-runs and move to production only after a test recipient works.
- Every automated action should leave enough source evidence for a reviewer to reverse or edit it.
112 changes: 112 additions & 0 deletions apps/fumadocs/content/docs/customer-surfaces.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: Customer Surfaces
description: Wire customer identity, feedback, update feeds, and the embedded Amend panel.
---

Customer surfaces are the parts of Amend that live inside your product or public portal. Start with
identity, then feedback, then the update feed. The source-linked automation only becomes useful
after Amend knows who asked for what.

## Identity

Use IDs from your application database. Email helps notification delivery and support lookup, but it
should not be the only stable identifier.

```ts
import { Amend } from "@amend/sdk";

const amend = new Amend({
project: "amend-labs",
apiBaseUrl: "http://127.0.0.1:3211/api/v1",
});

await amend.identify({
externalUserId: user.id,
accountId: workspace.id,
email: user.email,
name: user.name,
traits: { plan: workspace.plan },
});

await amend.identifyAccount(workspace.id, {
plan: workspace.plan,
seats: workspace.seats,
});
```

## Feedback

Customer feedback should carry enough context to become useful source work later:

```ts
await amend.submitRequest({
title: "Show the merged PR on shipped requests",
body: "Our admins want to audit which change closed each request.",
authorEmail: user.email,
authorName: user.name,
labels: ["admin", "audit"],
sourceUrl: "https://app.example.com/feedback/123",
});
```

Use interactions to keep demand and notification eligibility connected:

```ts
await amend.vote("feedback-show-shipping-pr", user.id);
await amend.comment("feedback-show-shipping-pr", "This would help our admins.", user.id);
await amend.react("feedback-show-shipping-pr", "heart", user.id);
```

## Update Feed

Use `updatesForUser` or `updatesForContact` when your app has enough identity to filter shipped
updates for a person:

```ts
const updates = await amend.updatesForContact({
userId: user.id,
email: user.email,
});

await amend.markUpdateSeen("changelog-reviewable-publishing", user.id);
await amend.trackShippedFeature("roadmap-source-linked-portal", user.id);
```

## Embedded Panel

Use the embedded panel when you want a working request/update surface before building custom UI:

```ts
import { createAmendPanel } from "@amend/sdk/embed";

createAmendPanel({
project: "amend-labs",
apiBaseUrl: "http://127.0.0.1:3211/api/v1",
});
```

In local development, open the browser demo at:

```txt
http://amend.localhost:1355/embed-demo
```

## Notification Preferences

Notification preferences are part of the customer surface because they decide who can receive
targeted shipped updates.

```ts
await amend.setNotificationPreference({
externalUserId: user.id,
email: user.email,
mode: "digest",
digestDay: "friday",
digestHour: 16,
});

await amend.unsubscribe({ email: user.email });
```

Unsubscribe writes remain available even when owner-level writes are protected by
`AMEND_API_TOKEN`.
Loading
Loading