Skip to content

Project configuration and commands

Joshua Reynolds edited this page Oct 7, 2026 · 1 revision

Project configuration and commands

The .expec file describes contracts and examples. expec.json selects source entries, dependencies, a connected project and outputs. It is strict JSON, not .expec source.

Start with checking

The Quick start has a minimal manifest with no outputs. Source entry names are literal files, not globs. Paths are relative to the manifest unless already absolute.

Setting Purpose
formatVersion Manifest format; currently 1
version Your specification's complete SemVer, such as 0.1.0
build.entries One or more source entry files
build.sourceRoots Optional additional source roots, as literal directories
project.root Connected project directory
outputs Selected registered output IDs and their options
libraries Specification library module identities and version requirements
packages Package aliases, names, version requirements and phases

Unknown settings, duplicate output IDs/aliases and invalid versions are errors. Each output validates its own options. A bare library module identity is not a local file path; direct local source imports use relative file locators.

Connect a TypeScript project

A typical connected manifest requests code contracts:

{
  "formatVersion": 1,
  "version": "0.1.0",
  "project": { "root": "./game" },
  "build": { "entries": ["main.expec"] },
  "outputs": [
    { "id": "typescript", "options": { "directory": "src", "configFile": "tsconfig.json" } }
  ]
}

This assumes the connected project's native configuration exists. Initialization can create a supported starter instead; existing handwritten-project adoption has an explicit mapping/baseline workflow and is not inferred from matching names.

For a new TypeScript starter, begin with the minimal manifest, then run:

node node_modules/executable-specification-language/dist/cli-entry.js init --root ./game --target typescript --yes
node node_modules/executable-specification-language/dist/cli-entry.js install
node node_modules/executable-specification-language/dist/cli-entry.js check
node node_modules/executable-specification-language/dist/cli-entry.js build

--yes supplies explicit initialization consent. Without consent, noninteractive use does not create a project. In an interactive terminal the command can ask. Initialization records the connection; installation remains a separate operation.

Commands

Command Author-visible responsibility
check Load and check the specified sources and configured prerequisites
init Create a chosen supported starter and record the connection, with consent
install Explicitly acquire declared native requirements
build Check and apply supported generated changes to the connected project
test Run current generated acceptance through its native profile
--help Show command forms
--version Show the installed tool version

Use --config path/to/expec.json to select a different manifest and --json for structured reports. After editing .expec, build before testing. test does not silently regenerate authored assertions. Editing an implementation alone can be tested without rebuilding the specification.

Build/read/test do not silently install dependencies. Missing, skipped, failed or unfinished current generated cases cannot establish successful test completion.

Native starters

Choose one executable native profile per connected project. Java and Kotlin need an existing ordinary JDK 21 directory. Python needs CPython 3.12 and uv 0.12.23. Use your actual paths:

node node_modules/executable-specification-language/dist/cli-entry.js init --root ./game --target java --java-home "/absolute/path/to/jdk-21" --yes
node node_modules/executable-specification-language/dist/cli-entry.js init --root ./game --target kotlin --java-home "/absolute/path/to/jdk-21" --yes
node node_modules/executable-specification-language/dist/cli-entry.js init --root ./game --target python --python "/absolute/path/to/python3.12" --uv "/absolute/path/to/uv" --yes

These are alternative commands, not three commands to run against one starter. On Windows, use quoted Windows paths. Toolchain installation is not performed by initialization. Follow the released README for complete native setup and the extra Kotlin acceptance selection.

install --offline is currently a Python-profile option. It uses available cached requirements and fails when a required package is absent.

Evolving an existing specification

Changing a name can require an identity decision so the tool retains the right implementation. build --json reports an identity-correspondence diagnostic. Supply deliberate choices with build --decisions changes.json; use the actual prior ID and the new declaration's 1-based source location.

A retirement decision is not permission to destroy handwritten code. Resolve preservation conflicts and inspect any partial write receipt before retrying. The README describes the decision-file format and public adoption recipe; this reference does not expose a private ledger as an authoring API.

Related: Dependencies and files · Output support · Troubleshooting

Clone this wiki locally