Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
b6667ff
docs: add monorepo structure refactor design spec
cabcookie Apr 15, 2026
a7cb223
docs: add monorepo structure refactor implementation plan
cabcookie Apr 15, 2026
9c093c5
ref: Migrate from pnpm to npm workspaces
cabcookie Apr 15, 2026
578f917
build: add husky pre-commit hook with lint-staged
cabcookie Apr 15, 2026
e22ffc7
build: update amplify.yml for npm
cabcookie Apr 15, 2026
86d384a
build: tighten biome rules to match amplify-backend conventions
cabcookie Apr 15, 2026
0c5e41f
build: add tsconfig.base.json with composite project config
cabcookie Apr 15, 2026
6ff0181
build: update package tsconfigs for tsc composite builds
cabcookie Apr 15, 2026
6afbc09
build: migrate from tsup to tsc composite builds
cabcookie Apr 15, 2026
36daa0b
build: add Microsoft API Extractor for public API tracking
cabcookie Apr 15, 2026
cd361d8
build: add c8 coverage config with 85% thresholds
cabcookie Apr 15, 2026
7e8cc9d
test: migrate from vitest to Node test runner
cabcookie Apr 15, 2026
a096283
build(scripts): add tsconfig and shared utility clients
cabcookie Apr 15, 2026
18ff4f2
build(scripts): add validation scripts
cabcookie Apr 15, 2026
a06b357
build(scripts): Add test runner scripts
cabcookie Apr 15, 2026
3be5097
build(scripts): add API change detection scripts
cabcookie Apr 15, 2026
a352470
build(scripts): add publishing and release management scripts
cabcookie Apr 15, 2026
b6a502a
chore: update .gitignore for tsbuildinfo files
cabcookie Apr 15, 2026
5abcda1
build(scripts): add utility scripts and update pre-commit hook
cabcookie Apr 15, 2026
33d6fe8
ci: add composite actions for Node setup, caching, and AWS profiles
cabcookie Apr 15, 2026
f62d707
ci: replace ci.yml and publish.yml with health_checks.yml
cabcookie Apr 15, 2026
1679f58
ci: add supporting workflows
cabcookie Apr 15, 2026
681b7b1
ci: add CODEOWNERS, dependabot, dependency review, issue/PR templates
cabcookie Apr 15, 2026
a00eec0
docs: add GitHub Actions AWS access setup guide
cabcookie Apr 15, 2026
8ca3994
build(scripts): add E2E infrastructure scripts
cabcookie Apr 15, 2026
9728b09
chore: update package tsconfigs with references and formatting
cabcookie Apr 15, 2026
6784491
ci: add E2E account selection and test runner actions
cabcookie Apr 15, 2026
aebb697
ci: wire E2E tests and resource cleanup into workflows
cabcookie Apr 15, 2026
20a9bc3
docs: update CLAUDE.md for new infrastructure
cabcookie Apr 15, 2026
3d1a8e8
docs: update Claude Code skills for new infrastructure
cabcookie Apr 15, 2026
ada874d
chore: update Claude Code permissions for npm
cabcookie Apr 15, 2026
00f83ed
build(scripts): Format tsconfig output with Biome after updating refs
cabcookie Apr 15, 2026
54db6c6
ci: support alpha/beta branch workflow in health_checks
cabcookie Apr 15, 2026
fe307be
fix(overtone): export EmailDefinition from root entry point
cabcookie Apr 16, 2026
5f85573
fix(overtone): resolve ae-forgotten-export warnings in API report
cabcookie Apr 16, 2026
36f5563
docs: replace remaining pnpm references with npm
cabcookie Apr 16, 2026
076d2ca
docs: add API reference section to navigation
cabcookie Apr 16, 2026
94af0c8
docs(website): generate API reference pages from API.api.md reports
cabcookie Apr 16, 2026
b505547
docs: add CI, canary, and package version badges to README
cabcookie Apr 16, 2026
45f3b4b
fix(website): fix fumadocs import and API reference page generation
cabcookie Apr 16, 2026
28580e4
fix(website): improve trailing comment stripping in API transform
cabcookie Apr 16, 2026
094c846
chore: add changeset for monorepo structure refactor
cabcookie Apr 16, 2026
5b43869
fix: resolve CI build and script failures
cabcookie Apr 16, 2026
2e6c34a
chore: temporarily raise PR size limit for monorepo refactor
cabcookie Apr 16, 2026
2c34666
chore: remove test-import, update lockfile and next-env types
cabcookie Apr 16, 2026
3339923
fix: scope build and typecheck to publishable packages only
cabcookie Apr 16, 2026
115c0f9
fix: handle npm ls non-zero exit in check_dependencies
cabcookie Apr 16, 2026
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
18 changes: 18 additions & 0 deletions .c8rc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
{
"lines": 85,
"functions": 85,
"branches": 85,
"exclude": [
"docs",
"scripts",
"packages/website",
"packages/test-infra",
"packages/integration-tests",
"packages/docs",
"**/*.test.ts",
"**/test/**"
],
"all": true,
"check-coverage": true,
"src": "packages/"
}
6 changes: 6 additions & 0 deletions .changeset/monorepo-structure-refactor.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@nxsflow/amplify-overtone": patch
"@nxsflow/amplify-overtone-client": patch
---

Align monorepo infrastructure with aws-amplify/amplify-backend patterns: migrate from pnpm to npm workspaces, replace tsup with tsc composite builds (output in lib/ instead of dist/), migrate tests from vitest to Node test runner (node:test + node:assert), add Microsoft API Extractor for public API tracking, add c8 coverage, add husky + lint-staged, and set up comprehensive GitHub Actions CI with health checks, canary builds, and multi-account E2E infrastructure
52 changes: 24 additions & 28 deletions .claude/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,36 +14,32 @@
"Bash(gh run view:*)",
"Bash(gh search:*)",
"Bash(git ls-tree:*)",
"Bash(npm ci:*)",
"Bash(npm install:*)",
"Bash(npm run build:*)",
"Bash(npm run check:*)",
"Bash(npm run clean:*)",
"Bash(npm run client:*)",
"Bash(npm run diff:*)",
"Bash(npm run e2e:*)",
"Bash(npm run format:*)",
"Bash(npm run lint:*)",
"Bash(npm run overtone:*)",
"Bash(npm run test:*)",
"Bash(npm run test-infra:*)",
"Bash(npm run typecheck:*)",
"Bash(npm run update:*)",
"Bash(npm run vend:*)",
"Bash(npm run watch:*)",
"Bash(npm run website:*)",
"Bash(npm test:*)",
"Bash(npm view:*)",
"Bash(npx api-extractor:*)",
"Bash(npx biome:*)",
"Bash(npx vitest run:*)",
"Bash(pnpm add:*)",
"Bash(pnpm biome check:*)",
"Bash(pnpm build)",
"Bash(pnpm changeset:*)",
"Bash(pnpm client:build)",
"Bash(pnpm client:test)",
"Bash(pnpm client:typecheck)",
"Bash(pnpm e2e:test)",
"Bash(pnpm e2e:typecheck)",
"Bash(pnpm format)",
"Bash(pnpm install:*)",
"Bash(pnpm lint)",
"Bash(pnpm lint:*)",
"Bash(pnpm list:*)",
"Bash(pnpm overtone:build)",
"Bash(pnpm overtone:test)",
"Bash(pnpm overtone:test:*)",
"Bash(pnpm overtone:typecheck)",
"Bash(pnpm test)",
"Bash(pnpm test-infra:bootstrap)",
"Bash(pnpm test-infra:build)",
"Bash(pnpm test-infra:deploy)",
"Bash(pnpm test-infra:destroy)",
"Bash(pnpm test-infra:typecheck)",
"Bash(pnpm typecheck:*)",
"Bash(pnpm --filter website build)",
"Bash(pnpm --filter @nxsflow/test-infra typecheck:*)",
"Bash(npx c8:*)",
"Bash(npx changeset:*)",
"Bash(npx husky:*)",
"Bash(npx tsx:*)",
"Fetch",
"mcp__aws-knowledge-mcp-server__*",
"mcp__awslabs_aws-documentation-mcp-server__*",
Expand Down
29 changes: 20 additions & 9 deletions .claude/skills/cdk-construct-development/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ CDK provides a powerful assertions API. Use it for construct unit tests:
// packages/amplify-overtone/test/construct.test.ts
import { App, Stack } from "aws-cdk-lib";
import { Template } from "aws-cdk-lib/assertions";
import { describe, expect, it } from "vitest";
import { describe, it } from "node:test";
import assert from "node:assert/strict";
import { OvertoneConstruct } from "../src/construct.js";

describe("OvertoneConstruct construct", () => {
Expand Down Expand Up @@ -122,7 +123,7 @@ describe("OvertoneConstruct construct", () => {

const template = Template.fromStack(stack);
// Assert on any additional resources created by the construct
expect(template.toJSON()).toBeDefined();
assert.ok(template.toJSON());
});
});
```
Expand Down Expand Up @@ -170,14 +171,24 @@ template.hasResourceProperties("AWS::IAM::Policy", {

---

## tsup Build Notes
## Build Notes

The library uses tsup with `external: ["aws-cdk-lib", "constructs", "@aws-amplify/plugin-types"]`.
The library uses `tsc` (TypeScript compiler) for building. Output goes to `lib/`.

- All CDK imports are externalized — they must be provided by the consumer's project
- Use `.js` extensions in source imports (tsup resolves them to `.ts` during build)
- `dts: true` generates `.d.ts` files from TypeScript source
- Build output: `dist/index.js` (ESM), `dist/index.cjs` (CJS), `dist/index.d.ts`
- All CDK imports are externalized — they must be provided by the consumer's project (listed as peer deps in `package.json`)
- Use `.js` extensions in source imports (tsc resolves them to `.ts` during build)
- Build output: `lib/index.js` (ESM), `lib/index.d.ts` (declaration file)

### API Extractor

The library uses [API Extractor](https://api-extractor.com/) to enforce the public API surface. After changing public exports, run:

```bash
npm run check:api # verifies the public API matches the committed report
npm run update:api # updates the API report file (commit the result)
```

The API report lives at `packages/amplify-overtone/api-report/amplify-overtone.api.md`. Commit changes to this file alongside the code change. CI runs `check:api` and fails if the report is out of date.

### Lambda handler bundling

Expand All @@ -195,7 +206,7 @@ Lambda handlers inside the construct (e.g. `packages/amplify-overtone/src/functi

**Rules:**

- Never bundle peer deps — they're externalized in tsup config
- Never bundle peer deps — they're listed as `peerDependencies` in `package.json` and excluded from the build output
- Test against the minimum supported version, not latest
- Keep ranges permissive (`^2.0.0` not `^2.170.0`) — consumers have their own CDK constraints
- Bumping a peer dep minimum range is a **major** version bump for this library
Expand Down
29 changes: 17 additions & 12 deletions .claude/skills/cdk-testing/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ packages/amplify-overtone/test/
packages/integration-tests/ # E2E tests against deployed infrastructure (private)
```

Vitest config for the construct package: `packages/amplify-overtone/vitest.config.ts` matches `include: ["test/**/*.test.ts"]`.
Tests use the Node.js native test runner (`node:test`). Run them with `npm test` in the package or `npm test` from the repo root.

**When to write which:**

Expand All @@ -40,7 +40,8 @@ Vitest config for the construct package: `packages/amplify-overtone/vitest.confi
`OvertoneFactory` uses a static counter to enforce one `defineOvertone()` per backend. Reset between tests:

```typescript
import { beforeEach, describe, expect, it } from "vitest";
import { beforeEach, describe, it } from "node:test";
import assert from "node:assert/strict";
import { OvertoneFactory } from "../../src/factory.js"; // relative within packages/amplify-overtone/
import { defineOvertone } from "../../src/index.js";

Expand All @@ -51,13 +52,13 @@ describe("defineOvertone", () => {

it("returns an object with a getInstance method", () => {
const factory = defineOvertone({});
expect(factory).toBeDefined();
expect(typeof factory.getInstance).toBe("function");
assert.ok(factory);
assert.strictEqual(typeof factory.getInstance, "function");
});

it("throws on second call", () => {
defineOvertone({});
expect(() => defineOvertone({})).toThrow();
assert.throws(() => defineOvertone({}));
});
});
```
Expand All @@ -68,7 +69,8 @@ Test that invalid props produce clear error messages:

```typescript
it("rejects invalid configuration", () => {
expect(() => defineOvertone({ invalidProp: "value" } as any)).toThrow(
assert.throws(
() => defineOvertone({ invalidProp: "value" } as any),
/invalid/i,
);
});
Expand Down Expand Up @@ -118,13 +120,15 @@ import { Capture, Match, Template } from "aws-cdk-lib/assertions";
Capture a dynamic value from the template for later assertion:

```typescript
import assert from "node:assert/strict";

const arnCapture = new Capture();
template.hasResourceProperties("AWS::IAM::Policy", {
PolicyDocument: {
Statement: [{ Resource: arnCapture }],
},
});
expect(arnCapture.asString()).toContain(":lambda:");
assert.ok(arnCapture.asString().includes(":lambda:"));
```

### Key Principles
Expand Down Expand Up @@ -165,7 +169,7 @@ Common `beforeEach` pattern:

```typescript
import { type Template } from "aws-cdk-lib/assertions";
import { beforeEach, describe, expect, it } from "vitest";
import { beforeEach, describe, it } from "node:test";
import { createOvertoneTemplate } from "./helpers.js";

let template: Template;
Expand All @@ -181,7 +185,8 @@ beforeEach(() => {

```typescript
import { Match, type Template } from "aws-cdk-lib/assertions";
import { beforeEach, describe, expect, it } from "vitest";
import { beforeEach, describe, it } from "node:test";
import assert from "node:assert/strict";
import { createOvertoneTemplate } from "./helpers.js";

describe("Core resources", () => {
Expand All @@ -194,7 +199,7 @@ describe("Core resources", () => {
it("creates the primary resource", () => {
// Assert the main AWS resource type created by OvertoneConstruct
// Replace "AWS::SomeService::SomeResource" with the actual resource type
expect(template.toJSON().Resources).toBeDefined();
assert.ok(template.toJSON().Resources);
});

it("creates exactly one handler Lambda", () => {
Expand All @@ -207,7 +212,7 @@ describe("Core resources", () => {

```typescript
import { Match, type Template } from "aws-cdk-lib/assertions";
import { beforeEach, describe, expect, it } from "vitest";
import { beforeEach, describe, it } from "node:test";
import { createOvertoneTemplate } from "./helpers.js";

describe("Handler Lambda", () => {
Expand Down Expand Up @@ -240,7 +245,7 @@ describe("Handler Lambda", () => {

```typescript
import { Match, type Template } from "aws-cdk-lib/assertions";
import { beforeEach, describe, expect, it } from "vitest";
import { beforeEach, describe, it } from "node:test";
import { createOvertoneTemplate } from "./helpers.js";

describe("IAM permissions", () => {
Expand Down
2 changes: 1 addition & 1 deletion .claude/skills/commit/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ BREAKING CHANGE: OvertoneProps.config is now overtoneConfig
This project uses `@changesets/cli` to track version bumps. When your commit affects the published package (new feature, bug fix, breaking change), you need a changeset:

```bash
pnpm changeset
npx changeset
```

This creates a `.changeset/<random-name>.md` file. Commit it alongside your code:
Expand Down
34 changes: 22 additions & 12 deletions .claude/skills/versioning-and-releases/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ This preserves the invariant that `beta` is always a superset of `alpha` at the

```bash
# Create changeset with your feature
pnpm changeset
npx changeset
git add .changeset/ && git commit -m "feat: description"
# Open PR targeting `alpha` (or `beta` if skipping alpha)
```
Expand All @@ -74,13 +74,13 @@ When the user says a feature is "ready for alpha":

```bash
git checkout alpha
pnpm changeset pre enter alpha
npx changeset pre enter alpha
```

3. **Version and publish:**

```bash
pnpm changeset version # bumps to X.Y.Z-alpha.N
npx changeset version # bumps to X.Y.Z-alpha.N
git add .changeset/ packages/
git commit -m "chore(release): version X.Y.Z-alpha.N"
git push # CI publishes automatically
Expand All @@ -96,9 +96,9 @@ When the user says features are "ready for beta":

```bash
git checkout beta && git merge alpha
pnpm changeset pre exit
pnpm changeset pre enter beta
pnpm changeset version # bumps to X.Y.Z-beta.0
npx changeset pre exit
npx changeset pre enter beta
npx changeset version # bumps to X.Y.Z-beta.0
git add .changeset/ packages/
git commit -m "chore(release): version X.Y.Z-beta.0"
git push # CI publishes automatically
Expand All @@ -112,8 +112,8 @@ When the user says it's "ready to release" or "ready for stable":

```bash
git checkout beta
pnpm changeset pre exit
pnpm changeset version # bumps to stable X.Y.Z
npx changeset pre exit
npx changeset version # bumps to stable X.Y.Z
git add .changeset/ packages/
git commit -m "chore(release): exit pre-release, bump to X.Y.Z"
git push
Expand All @@ -139,13 +139,23 @@ npm view @nxsflow/amplify-overtone dist-tags
npm view @nxsflow/amplify-overtone-client dist-tags
```

## Local Publish Workflow (Verdaccio)

Use `npm run vend` to publish packages locally via Verdaccio for manual integration testing before pushing to npm:

```bash
npm run vend # starts Verdaccio, builds, and publishes packages locally
```

This spins up a local registry at `http://localhost:4873`. Useful for testing package installs in a consumer project without publishing to npm.

## CI Pipeline

See `.github/workflows/publish.yml` for implementation. Key behaviors:
See `.github/workflows/health_checks.yml` for implementation. Key behaviors:

- **main push**: `changesets/action` creates a "Version Packages" PR (bumps versions, updates changelogs). Merging that PR publishes to npm with `latest` tag after manual approval (`production` environment).
- **alpha/beta push**: Runs `changeset publish` directly. Pre mode sets the dist-tag automatically.
- **PRs to main**: `.github/workflows/ci.yml` runs all four gates (build, typecheck, test, lint).
- **main push**: `changesets/action` creates a "Version Packages" PR (bumps versions, updates changelogs). Merging that PR publishes to npm with `latest` tag after manual approval (`release` environment).
- **alpha/beta push**: `publish_prerelease` job runs `changeset publish` directly. Pre mode sets the dist-tag automatically.
- **PRs to main, alpha, or beta**: CI runs all gates (build, typecheck, test, lint, API checks).
- **Publishing uses npm Trusted Publishing (OIDC)** — no npm token needed.

## Rollback
Expand Down
9 changes: 9 additions & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# Default owners
* @nxsflow/amplify-overtone

# API approval - public surface and dependencies
**/API.md @nxsflow/amplify-overtone-api-approvers
**/package.json @nxsflow/amplify-overtone-api-approvers

# GitHub actions/checks approval
/.github/ @nxsflow/amplify-overtone-admins
28 changes: 28 additions & 0 deletions .github/ISSUE_TEMPLATE/bug-report.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Bug Report
description: Report a bug in Amplify Overtone
labels: ["bug"]
body:
- type: textarea
attributes:
label: Environment
description: Run `npx ampx info` and paste the output
validations:
required: true
- type: textarea
attributes:
label: Description
description: Describe the bug
validations:
required: true
- type: textarea
attributes:
label: Steps to reproduce
description: Minimal steps to reproduce the bug
validations:
required: true
- type: textarea
attributes:
label: Expected behavior
description: What did you expect to happen?
validations:
required: true
5 changes: 5 additions & 0 deletions .github/ISSUE_TEMPLATE/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: Community Support
url: https://github.com/nxsflow/amplify-overtone/discussions
about: Ask questions and discuss with the community
Loading
Loading