Amazon Q Developer: Custom Context Packs for Private Monorepos

Amazon Q Developer: Custom Context Packs for Private Monorepos

Amazon Q in a private monorepo is only as good as the context you feed it. Dumping the whole tree invents internal APIs that never shipped. The unfair advantage is curated context packs: ownership maps, ADRs, forbidden libraries, and service contracts indexed on purpose — small enough to fit, specific enough that autocomplete stops hallucinating @acme/legacy-utils.

⚡ TL;DR: Build versioned context packs (Markdown + JSON manifests) per domain: auth, billing, platform. Include CODEOWNERS slices, ADR summaries, public barrel exports, and a hard negative list. Point Q customizations / workspace context at those packs — not packages/**. Refresh on merge via CI. Cross-check suggestions against OpenAPI and package exports. Related: Cursor Rules for TypeScript Monorepos, RAG on AWS: OpenSearch vs Aurora pgvector.

What belongs in a context pack

A pack is not a second repo clone. It is a deliberate digest.

context-packs/
  billing/
    PACK.json          # manifest + content hash
    adr-summaries.md   # 1 paragraph per ADR
    public-api.md      # exported symbols from package.json exports
    forbidden.md       # banned libs and patterns
    ownership.md       # CODEOWNERS excerpt
    contracts/         # OpenAPI snippets for billing APIs
{
  "name": "billing",
  "packages": ["@acme/billing", "@acme/billing-client"],
  "maxTokens": 12000,
  "negatives": ["moment", "request", "aws-sdk@2"],
  "sha": "content-hash-of-all-files"
}

Generate packs from truth, not vibes

Automate extraction so packs cannot drift from main.

// scripts/build-context-pack.ts
import { readFileSync, writeFileSync } from "fs";
import { createHash } from "crypto";

export function buildPublicApi(pkgRoot: string): string {
  const pkg = JSON.parse(readFileSync(`${pkgRoot}/package.json`, "utf8"));
  const exports = pkg.exports ?? { ".": pkg.main };
  // ✅ Only document real export paths
  return Object.keys(exports)
    .map((k) => `- \`${pkg.name}${k === "." ? "" : "/" + k.replace(/^\.\//, "")}\``)
    .join("\n");
}

export function writePack(dir: string, files: Record<string, string>) {
  const body = Object.entries(files)
    .sort(([a], [b]) => a.localeCompare(b))
    .map(([k, v]) => `# ${k}\n\n${v}`)
    .join("\n\n");
  const sha = createHash("sha256").update(body).digest("hex").slice(0, 16);
  writeFileSync(`${dir}/PACK.md`, body);
  writeFileSync(`${dir}/PACK.json`, JSON.stringify({ sha, bytes: body.length }, null, 2));
}
# ❌ Wrong: zip the entire monorepo into Q context
tar czf q-context.tgz packages/ apps/ node_modules/

Negatives beat more positives

Hard bans prevent the model from “helpfully” adding moment or SDK v2.

## Forbidden in billing pack

- ❌ `moment` / `moment-timezone` — use `luxon`
- ❌ `aws-sdk` v2 — use `@aws-sdk/*` v3 modular clients
- ❌ Deep imports from `@acme/billing/src/**` — public barrels only
- ✅ Prefer `@acme/billing-client` for cross-service calls

Pair negatives with Cursor/agent rules so IDE and Q stay aligned (Cursor Rules).

Wire packs into Amazon Q customizations

Keep pack artifacts in-repo; point Q Developer customizations or workspace indexing includes at context-packs/** and critical **/README.md / **/ADR*.md only. Exclude secrets, .env*, and customer data paths.

# .amazonq/context.yml (illustrative)
include:
  - context-packs/**/*.md
  - docs/adr/**/*.md
exclude:
  - "**/.env*"
  - "**/secrets/**"
  - "**/fixtures/pii/**"
max_file_bytes: 64000

For retrieval-heavy assistants beyond IDE Q, the same digests feed Bedrock Knowledge Bases — see RAG on AWS and Bedrock Prompt Caching.

Refresh on merge, fail on drift

# CI: rebuild packs and fail if committed hash mismatches
- run: pnpm tsx scripts/build-context-pack.ts
- run: git diff --exit-code context-packs/
Signal Action
Public export changed Rebuild public-api.md
New ADR Append summary ≤ 120 words
Banned lib in PR CI deny + pack negative already lists it
Pack > token budget Split by domain, do not truncate mid-API

Closing checklist

✅ Dos
– ✅ One pack per bounded context with content hash
– ✅ Generate public API lists from package.json exports
– ✅ Maintain hard negatives (libs, deep imports, SDK v2)
– ✅ Exclude secrets and PII paths from indexing
– ✅ Rebuild packs in CI and fail on drift

❌ Don’ts
– ❌ Don’t dump entire packages/ into Q context
– ❌ Don’t hand-write API lists that rot
– ❌ Don’t include customer fixtures or .env samples with real values
– ❌ Don’t mix billing and auth packs into one blob
– ❌ Don’t skip negatives because “the model knows better”

Related reading

Last updated on September 11, 2026


Discover more from CheatCoders

Subscribe to get the latest posts sent to your email.

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply