@pragmap/cli
v0.1.5
Published
CLI for Pragmap golden-path function contracts
Downloads
950
Maintainers
Readme
@pragmap/cli
CLI for Pragmap golden-path function contracts.
Pragmap lets a codebase declare important execution paths with lightweight @pragmap comments, run a real flow, and verify that the expected functions still executed in the expected order.
Install
npm install -D @pragmap/cliThen run the local binary:
npx pragmap --helpYou can also use package-manager equivalents such as pnpm exec pragmap or npm exec pragmap.
5-minute quickstart
1. Add @pragmap comments to important seams
// @pragmap checkout.success required order=1 label="Validate checkout"
export function validateCheckout(input: CheckoutInput) {
// normal app code
}
// @pragmap checkout.success required order=2 label="Create order"
export async function createOrder(input: CheckoutInput) {
// normal app code
}Pragmap works best with explicit exported seams:
- top-level exported domain functions
- top-level exported service functions
- top-level exported React / React Native screen components
- explicit object-literal members with
@pragmapcomments, such as Zustand actions supported by the transformer
2. Add a .pragmap.yml contract
version: 1
paths:
checkout.success:
description: User submits checkout details and receives an order.
driver:
type: vitest
command: npm test -- checkout.test.ts
required:
- id: checkout.validate
label: Validate checkout
description: Confirms the submitted details are safe before an order is created.
file: src/checkout.ts
symbol: validateCheckout
order: 1
- id: checkout.create_order
label: Create order
description: Persists the order only after validation succeeds.
file: src/orders.ts
symbol: createOrder
order: 2
forbidden: []3. Verify the path
npx pragmap verify checkout.success --contract .pragmap.yml --timeout 60s --transformWith --transform, Pragmap temporarily instruments the contract source files, runs the contract driver command, reads emitted probe events, verifies the contract, and restores the original source files.
Authoring reliable contracts
Pragmap works best when contract steps map to meaningful, named code seams in the product path. Treat the contract as an execution-aware code map: each required step should prove that a business-critical phase actually happened.
Good required step anchors include functions for:
- authorization or policy enforcement
- input validation
- persistence
- audit logging
- external sync requests
- streaming or response construction
Avoid using the same broad entrypoint for many steps. For example, multiple required steps all anchored to the same GET, POST, or handleSubmit symbol are ambiguous: Pragmap can prove the entrypoint ran, but not that each internal phase ran in the intended order. Prefer extracting and anchoring separate helper functions for important phases.
Forbidden steps
Forbidden steps should point at distinct unsafe functions or bypass paths. They should not point at a function that normally executes in the successful path.
Good forbidden anchors:
bypassAuthorizationForDemoskipPolicyChecklegacyUnsafePublishfallbackWithoutAudit
Bad forbidden anchors:
- the same symbol used by a required step
- a normal API client required by the success path
- a screen/component that renders during success
- a store getter or selector that is expected to run
A forbidden step should include file and symbol so Pragmap can validate the exact source anchor. If a forbidden step points at code that runs during normal success, verification will correctly fail with forbidden_observed.
Next.js route handlers
Next.js App Router route modules should only export route-supported names such as GET, POST, and route config exports. Do not add arbitrary exported helper functions directly to route.ts; generated Next.js route type checks can reject those exports.
For route-driven paths, keep the route handler small and move anchorable helper symbols into route-adjacent modules:
app/api/orders/route.ts
app/api/orders/policy.ts
app/api/orders/stream.ts
app/api/orders/audit.tsThen anchor contract steps to meaningful helpers such as:
enforceOrderStreamPolicyopenOrderStreamwriteOrderStreamAuditEvent
This makes the contract clearer for humans and agents, and it gives Pragmap more useful observed ordering than anchoring every step to the route handler entrypoint.
Next.js / Node example
Next.js server actions, server-side services, and unit/integration tests usually use the Node runtime.
version: 1
paths:
admin.publish_product.success:
description: Admin publishes a product after authorization and validation.
driver:
type: playwright
command: npm run test:e2e -- publish-product.spec.ts
runtime: node
required:
- id: admin.publish_product.authorize
label: Authorize admin
description: Ensures only permitted admins can publish catalog content.
file: src/services/authz.ts
symbol: assertCanPublishProduct
order: 1
- id: admin.publish_product.validate
label: Validate product
description: Protects catalog quality before the product becomes visible.
file: src/services/product-validation.ts
symbol: validateProductForPublish
order: 2Run:
npx pragmap verify admin.publish_product.success --contract .pragmap.yml --timeout 60s --transformUse driver.runtime: node when a browser-driven test, such as Playwright, triggers server-side code that writes probe events from Node.
React Native / Expo example
React Native and Expo are supported today through Jest/Jest-Expo or React Native Testing Library flows. Device/simulator E2E is future work.
Pragmap is strongest today for:
- API client flows (fetch, tRPC, GraphQL)
- pure/business logic (mappers, validators, formatters)
- store/action flows covered by Jest
Be cautious with screen-level lifecycle paths — they require component tests or E2E to execute the screen code.
version: 1
paths:
mobile.capture_to_result.success:
description: User captures item context and sees a recommendation.
driver:
type: jest-expo
command: npm run test:ci -- capture-to-result.test.tsx
required:
- id: mobile.capture.prepare
label: Prepare capture
description: Builds the item context the recommendation depends on.
file: src/features/capture/capture-flow.ts
symbol: prepareCapture
order: 1
- id: mobile.result.render
label: Render result
description: Shows the recommendation and next step to the user.
file: src/features/result/result-screen.tsx
symbol: FeedScreen
order: 2Run:
npx pragmap verify mobile.capture_to_result.success --contract .pragmap.yml --timeout 60s --transformDriver types such as jest-expo, expo-jest, react-native-testing-library, and rntl infer the Node runtime because they run in a Jest-like process.
For memory-runtime event flushing in React Native tests, use the optional helper package:
npm install -D @pragmap/react-nativeimport { flushPragmapReactNativeEvents } from "@pragmap/react-native";
await flushPragmapReactNativeEvents();Named exports preferred
Pragmap source-anchor validation is most reliable with named exports. If a default-exported screen must be a step, use a named export plus default export:
// @pragmap mobile.feed.load.success required order=1 label="Render feed"
export function FeedScreen() {
return <Feed />;
}
export default FeedScreen;If verification struggles with the screen anchor, anchor the contract to the store action or API client that the screen calls.
Runtime targets
Pragmap currently supports these transform runtime targets:
node— writes JSONL probe events toPRAGMAP_PROBE_OUTPUTbrowser— stores probe events onglobalThis.__PRAGMAP_EVENTS__memory— stores probe events onglobalThis.__PRAGMAP_EVENTS__using a platform-neutral name
Resolution order:
--runtime → driver.runtime → driver.type inference → driver.command inference → node defaultCommands
Scan
npx pragmap scan .
npx pragmap scan . --changed
npx pragmap scan . --dry-run-transformTour
npx pragmap tour checkout.success --contract .pragmap.ymlVerify
npx pragmap verify checkout.success --contract .pragmap.yml --timeout 60s --transformRecord
npx pragmap record checkout.success --contract .pragmap.yml --timeout 60s --transformPropose an update
npx pragmap update checkout.success --contract .pragmap.yml --propose --timeout 60s --transformCommon troubleshooting
Source anchor validation failed
Pragmap could not find a listed file or symbol from the contract. Confirm that each contract step points at a real source file and exported symbol.
No events observed
Check that:
- the test command actually exercises the golden path
- source files contain matching
@pragmapcomments --transformis enabled- the selected runtime matches where the instrumented code executes
Browser-driven test but server-side probes
Use:
driver:
type: playwright
runtime: nodeThis is common for Next.js tests where Playwright clicks through the browser but the instrumented functions run in server actions or services.
React Native simulator/device E2E
The current MVP supports Jest/Jest-Expo and React Native Testing Library. Simulator/device support, such as Detox or Maestro collection, is planned as future work.
