Skip to content

Project CLI

Lee Yunjin edited this page Oct 7, 2026 · 1 revision

Project CLI

make install installs the cwist command (a Python 3 script) into $PREFIX/bin. It scaffolds projects, runs a hot-reload watcher, and generates OpenAPI documents and Protobuf models.

cwist new project NAME [--directory DIR]
cwist watcher [--project FILE] [--interval SEC] [--once] [--no-run] [--poll]
cwist openapi SOURCE [--output FILE] [--project FILE] [--title T] [--version V]
cwist proto SOURCE [--output FILE] [--descriptor-set]
cwist describe [--project FILE]
cwist audit [TARGET] [--category ...] [--style ...] [--json] [--gate] [--update-baseline] [--baseline FILE]

cwist new project

cwist new project demo --directory ~/src
cd ~/src/demo

The name must start with a letter and contain only letters, digits, _ and -. The command creates:

File Purpose
demo.cwpro project manifest (JSON, format cwist-project/v1)
src/main.c a health route declared with CWIST_OPENAPI_GET and OpenAPI annotations
Makefile builds bin/demo; make openapi regenerates openapi.json
.gitignore ignores bin/ and openapi.json

The generated Makefile links with -lcwist -lpthread only. Against an installed static libcwist.a that is not enough; replace the link flags with $(shell pkg-config --cflags --libs --static cwist) (see Linking).

The .cwpro manifest

{
  "format": "cwist-project/v1",
  "name": "demo",
  "version": "0.1.0",
  "language": "c",
  "entrypoint": "src/main.c",
  "build": {"command": "make", "binary": "bin/demo"},
  "dev": {"command": "./bin/demo", "debounce_ms": 150, "stop_timeout_ms": 5000},
  "dependencies": {"cwist": ">=0.1.0"},
  "openapi": {"source": "src", "output": "openapi.json", "title": "demo", "version": "0.1.0"}
}

The watcher and the generators read their settings from this file, so a project builds the same way on every machine. Commands that need a project look for exactly one *.cwpro in the current directory unless --project names one.

cwist watcher

Watches the project, rebuilds incrementally, and restarts the app after each successful build:

  • Uses inotify on Linux and kqueue on macOS/BSD, with an mtime snapshot and polling fallback so changes are not missed (--poll forces polling).
  • Works out the affected translation units and prints the recompile scope.
  • Runs build.command; on failure it keeps the previous process running.
  • Coalesces bursts of saves for dev.debounce_ms milliseconds and stops the old process gracefully, waiting up to dev.stop_timeout_ms.
  • --no-run rebuilds without starting the app (useful in CI); --once runs a single build cycle.

cwist openapi

Generates an OpenAPI 3.1 document from Doxygen-style annotations placed immediately before CWIST_OPENAPI_* route declarations. See OpenAPI and the OpenAPI and Swagger guide.

cwist openapi src --output openapi.json --title "Demo API" --version 1.0.0
cwist openapi src --project demo.cwpro      # take output/title/version from the manifest

cwist proto

Generates C models, encoders/decoders and gRPC method-path constants from a proto3 file or a protoc --descriptor_set_out binary (auto-detected, or forced with --descriptor-set). See Protobuf and Codegen.

cwist proto api.proto --output api.cwist.pb.h

cwist describe

Prints the manifest and the routes the tool detects in the source tree.

cwist audit

Lists allocation and pthread call sites by convention (CWIST allocator, GNU, BSD, full-GC, sub-app). CI uses cwist audit --gate to fail a build that adds a raw malloc/free call under src/ that is not in scripts/ci/malloc-baseline.txt; --update-baseline regenerates that file after an intentional change. The target can be a path or a query string such as 'style:bsd;folder:./src/net'.

Clone this wiki locally