Lesson 00 · Effect AgentCore · Setup

Project setup & installing dependencies

Before any code, a project that runs. This lesson gets your machine ready: the toolchain (Node + pnpm), the exact dependency set the whole course pins, the two workspace settings that make installs work, and the TypeScript config that lets us run .ts directly. Five minutes here means every later lesson just runs.

01Toolchain: Node and pnpm

The whole course lives on GitHub at knpkv/effect-course-agentcore — the runnable project is in course/. Clone it and work from there:

git clone https://github.com/knpkv/effect-course-agentcore.git
cd effect-course-agentcore/course

You need Node 22+ (we rely on import.meta.main to guard the server entrypoint in lesson 02) and pnpm as the package manager. The cleanest way to get the exact pnpm the project expects is corepack, which ships with Node:

node --version          # v22.x or newer
corepack enable         # makes pnpm available, pinned by the project
pnpm --version          # 11.5.0  (from packageManager in package.json)

The version is pinned by a "packageManager": "pnpm@11.5.0" field, so corepack hands everyone the same pnpm — no "works on my machine" drift. We use pnpm (not npm) because the course is a small workspace, and pnpm's workspace settings are where two install-time policies live (section 03).

02The dependencies

The whole course is one effect@4 program, so the dependency set is small and deliberately pinned. From inside course/:

# runtime
pnpm add effect@4.0.0-beta.74 \
         @effect/platform-node@4.0.0-beta.74 \
         alchemy@2.0.0-beta.44 \
         @distilled.cloud/aws@0.22.0

# dev
pnpm add -D @effect/vitest@4.0.0-beta.74 vitest tsx typescript @types/node

The result is the project's package.json — note the scripts you'll use every lesson:

{
  "name": "effect-agentcore",
  "type": "module",
  "scripts": {
    "dev": "tsx watch src/agent.ts",      // agent on :8080 (lesson 02)
    "deploy": "alchemy deploy",            // provision the stack (lesson 05+)
    "destroy": "alchemy destroy",
    "test": "vitest run"                   // drive the lesson tests green
  },
  "dependencies": {
    "alchemy": "2.0.0-beta.44",
    "effect": "4.0.0-beta.74",
    "@effect/platform-node": "4.0.0-beta.74",
    "@distilled.cloud/aws": "0.22.0"
  },
  "devDependencies": {
    "@effect/vitest": "4.0.0-beta.74",
    "@types/node": "^25.6.0",
    "tsx": "^4.21.0",
    "typescript": "^6.0.3",
    "vitest": "^4.1.5"
  }
}
Why these four, and what's NOT here

effect brings the agent server (effect/unstable/httpapi) and the AI module (effect/unstable/aiLanguageModel, Tool, Toolkit, Prompt, Response); @effect/platform-node runs it on Node; alchemy is Infrastructure-as-Effects; @distilled.cloud/aws is Alchemy's native-Effect AWS SDK (it gives us Bedrock Converse and the AgentCore control plane). Notably absent: the standalone @effect/ai — it's effect-3-only, but core's effect/unstable/ai covers it; we hand-write only the Bedrock provider in lesson 03. No raw @aws-sdk/* either.

src/effect-agentcore/package.json

03Approve native build scripts

pnpm reads a pnpm-workspace.yaml. A few dependencies ship native post-install build scripts (esbuild, workerd, msgpackr-extract) that pnpm won't run until they're listed:

# pnpm-workspace.yaml
allowBuilds:
  esbuild: true
  msgpackr-extract: true
  workerd: true

After the first install, approve the builds once:

pnpm install
pnpm approve-builds      # one-time: confirms the allowBuilds list
If pnpm test errors before any test runs

That's almost always an un-approved build: pnpm's pre-run dependency check fails on an ignored build script. The fix is the sequence above — corepack enablepnpm installpnpm approve-buildspnpm test. This bit us during scaffolding; getting the workspace settings right is what made the suite go green.

src/effect-agentcore/pnpm-workspace.yaml

04TypeScript config

We never compile to JavaScript — tsx runs .ts directly and tsc is only a type checker (--noEmit). A few flags follow from that:

// tsconfig.json
{
  "compilerOptions": {
    "target": "ES2022",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "strict": true,
    "exactOptionalPropertyTypes": true,
    "noEmit": true,
    "allowImportingTsExtensions": true,   // we import "./model.ts" with the extension
    "verbatimModuleSyntax": true,
    "skipLibCheck": true,
    "forceConsistentCasingInFileNames": true,
    "noUncheckedIndexedAccess": true,
    "types": ["node"]
  },
  "include": ["src", "given", "alchemy.run.ts"]
}
FlagWhy it's here
allowImportingTsExtensions + noEmitWe import "../given/ai/StubModel.ts" with the .ts suffix and run it via tsx — no build step, so emitting is off.
exactOptionalPropertyTypesDistinguishes "absent" from "undefined". It's why lesson 03 builds the Converse request by omitting toolConfig rather than setting it to undefined.
verbatimModuleSyntaxForces explicit import type — Effect codebases lean on it heavily.
noUncheckedIndexedAccessArray access is T | undefined; you'll see hits[0]! in tests where we've already checked length.

src/effect-agentcore/tsconfig.json

05Verify your setup

Two commands prove the project is ready. First, the test suite — it runs against the deterministic StubModel, so it needs no AWS credentials:

$ pnpm test
 Test Files  3 passed (3)
      Tests  9 passed (9)

Then the agent itself:

$ pnpm dev
[INFO] Listening on http://0.0.0.0:8080

$ curl -s localhost:8080/ping
{"status":"Healthy"}
Green light

If both of those work, your environment is correct and the rest of the course is additive — every lesson adds a few lines to a project that already compiles, tests, and runs. You won't touch setup again; you'll just keep this loop (pnpm test / pnpm dev) running.

06What's yours vs what's given

One last orientation before lesson 01. The project splits in two: code you grow, and a shipped library you consume.

given/ # SHIPPED — read it, don't edit it (lesson 10 opens its hood) agentcore/ # AgentCore.Runtime / Gateway / Memory Alchemy resources ai/ # LanguageModel contract + StubModel (local + tests) container/ # Dockerfile -> AgentCore-compatible image search/ # keyword-search core + bundled explainer corpus test/ # per-lesson vitest suites — the feedback loop src/ # YOURS — grows lesson by lesson agent.ts # HttpApi /ping + /invocations (lesson 02) model.ts # the minimal BedrockModel (Bedrock | Stub) (lesson 03) tools.ts # searchExplainers over given/search (lesson 03/06) alchemy.run.ts# Alchemy.Stack(...), resource by resource (lessons 04-08) solutions/ # CHECKPOINTS — the end state of each lesson (01..08, 10)

The given test/ suites define "done" for each lesson; you drive them green. Each lesson also has a full end-state checkpoint under solutions/<NN> — compare against it or copy from it if you get stuck. Now you're ready — Lesson 01 explains what AgentCore actually is and why we treat it as one Effect program.

course/README.md