Sign In

@nowline/cli

Package Overview
Dependencies
Maintainers
1
Versions
58
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@nowline/cli

Command-line tool to check, convert, and create Nowline roadmaps.

npmnpm
Version
0.8.1
Version published
Weekly downloads
60
-64.07%
Maintainers
1
Weekly downloads
 
Created
Source

@nowline/cli

The nowline command-line tool parses, validates, and renders .nowline roadmap files.

License: Apache 2.0 Part of: lolay/nowline monorepo

Install

A single nowline binary ships every export format (SVG, PNG, PDF, HTML, Markdown+Mermaid, XLSX, MS Project XML) plus AST round-trip (jsonnowline). Approximate size: ~70 MB (the bun runtime is ~60 MB of that — see specs/cli-distribution.md for why we don't ship a smaller "tiny" tier).

# macOS / Linux / WSL — Homebrew
brew install lolay/tap/nowline

# Debian / Ubuntu — download .deb from GitHub Releases
curl -L -o nowline.deb \
  https://github.com/lolay/nowline/releases/latest/download/nowline_amd64.deb
sudo dpkg -i nowline.deb

# Windows — direct .exe download from GitHub Releases
#   nowline-windows-x64.exe
#   (unsigned; see SmartScreen walkthrough below)

# npm (any platform)
npm install -g @nowline/cli
# or one-shot: npx @nowline/cli roadmap.nowline -o -

After any of the package-manager installs above, man nowline shows the CLI manual (flags + a LANGUAGE cheatsheet) and man 5 nowline shows the full .nowline DSL reference. The Homebrew formula's resource "manpage" / resource "manpage5", the .deb's /usr/share/man/man1/nowline.1.gz / /usr/share/man/man5/nowline.5.gz, and npm's "man" field (which lists both files) all install the same hand-authored mdoc sources from man/nowline.1 and man/nowline.5. For direct binary downloads from GitHub Releases, both man pages ship as separate nowline.1 and nowline.5 assets alongside the platform binaries.

Usage

nowline is verbless: rendering is the default. Other modes are flags on the same command:

nowline <input> [options]              # render (default)
nowline <input> --serve [-p <port>]    # live HTTP preview
nowline --init [<name>]                # scaffold a starter file
nowline <input> --dry-run              # validate-only (no write)
nowline --help                         # print help
nowline --version                      # print version
nowline                                # no args → print help

Examples

nowline roadmap.nowline                          # writes ./roadmap.svg in cwd
nowline roadmap.nowline -f png                   # writes ./roadmap.png
nowline roadmap.nowline -f pdf                   # writes ./roadmap.pdf
nowline roadmap.nowline -f html                  # writes ./roadmap.html
nowline roadmap.nowline -f mermaid               # writes ./roadmap.md
nowline roadmap.nowline -f xlsx                  # writes ./roadmap.xlsx
nowline roadmap.nowline -f msproj                # writes ./roadmap.xml
nowline roadmap.nowline -o roadmap.pdf           # format inferred from extension
nowline roadmap.nowline -o -                     # SVG → stdout (Unix dash)
nowline roadmap.json -f svg                      # JSON-AST input
cat foo.nowline | nowline -                      # stdin → ./roadmap.svg
nowline roadmap.nowline -f json -o roadmap.json  # convert text → JSON
nowline roadmap.nowline --dry-run                # validate-only; nothing written
nowline roadmap.nowline --serve -p 8080          # live preview on :8080
nowline --init                                   # ./roadmap.nowline
nowline --init my-project                        # ./my-project.nowline
nowline roadmap.nowline -f pdf -o report         # auto-extension → report.pdf
nowline roadmap.nowline -f pdf --page-size a4 --orientation landscape --margin 0.5in
nowline roadmap.nowline -f png --scale 3         # 3x raster
nowline roadmap.nowline --headless               # bundled DejaVu fonts (deterministic)

Flags

I/O

FlagDefaultNotes
-f, --format <fmt>inferredsvg, png, pdf, html, mermaid, xlsx, msproj, json, nowline.
-o, --output <path><cwd>/<input-base>.<format>- for stdout. Existing files silently overwritten.
--input-format <fmt>by extension; stdin → nowlinenowline or json.

Mode flags (mutually exclusive)

FlagDescription
--serveLive HTTP preview. Opt-in -o <path> writes on each rebuild.
--init [<name>]Scaffold a starter .nowline in cwd. Auto-appends .nowline.
-n, --dry-runRun pipeline; skip the write. Replaces the old validate verb.

Render options

FlagDefaultNotes
-t, --theme <name>lightlight | dark.
--now YYYY-MM-DDtoday (UTC)Override the now-line anchor date. Use --now - to suppress it.
--no-links(off)Omit link icons from items.
-s, --scale <n>1Raster scale (PNG only).
--strict(off)Promote asset / sanitizer warnings to errors.
-w, --width <px>1280Canvas width.
--asset-root <dir>input dirRoot for logo: / image refs.

Format-specific options

FlagDefaultApplies toNotes
--page-size <size>letterpdfPreset (letter, legal, tabloid, ledger, a1a5, b3b5), content for auto-fit, or WxHunit for custom (8.5x11in, 210x297mm).
--orientation <name>autopdfportrait | landscape | auto.
--margin <length>36ptpdfPage margin. Bare numbers are points; 0.5in, 12mm, 1cm accepted.
--font-sans <path|alias>platform-resolvedpng, pdfTTF/OTF path, or alias sf, helvetica, dejavu, etc.
--font-mono <path|alias>platform-resolvedpng, pdfTTF/OTF path or alias for monospace.
--headless(off)png, pdfSkip platform font probe; use bundled DejaVu pair. Byte-stable across machines.
--start YYYY-MM-DDtodaymsprojAnchor date for relative-only roadmaps.

Serve options

FlagDefault
-p, --port <n>4318
--host <host>127.0.0.1
--open(off)

Logging (mutually exclusive)

FlagDescription
-v, --verboseExtra diagnostics on stderr.
-q, --quietSuppress non-error stderr.

Standard

FlagDescription
-h, --helpPrint help, exit 0.
-V, --versionPrint version, exit 0.

Behavior contracts

Format resolution (precedence chain)

  • -f / --format flag — explicit always wins.
  • -o <path> extension — recognized: .svg, .png, .pdf, .html/.htm, .md/.markdown (mermaid), .xlsx, .json, .nowline. .xml is ambiguous and requires -f msproj.
  • .nowlinerc defaultFormat — project default.
  • svg — built-in fallback.

If -f and -o extension disagree, -f wins and the output filename is preserved as written (no auto-rename).

Output extension auto-add

  • -o report -f pdfreport.pdf (no extension → append canonical).
  • -o report.pdf -f pdfreport.pdf (matching → leave alone).
  • -o foo.txt -f pdffoo.txt (mismatched → leave alone, write PDF bytes there).
  • -o - (stdout) is never rewritten.

Default output paths

All default-named outputs land in cwd:

  • File input: <cwd>/<input-base>.<format>.
  • Stdin input: <cwd>/roadmap.<format>.
  • --init (no -o): <cwd>/<name>.nowline (default name roadmap).

Existing files are silently overwritten — no --force flag, matching POSIX redirection and peer tools (mmdc, d2, prettier, tsc).

Stdout

  • -o - is the only way to write to stdout (Unix dash convention).
  • Binary formats (png, pdf, xlsx) on a TTY are refused with exit 2 (nowline: binary output (png) to terminal refused; use -o or pipe to a file). Pipes / redirects are fine.

Mode dispatch

Mutual exclusivity rules (all exit 2 with a message):

  • --serve + --init.
  • --dry-run + --serve (serve doesn't write by default).
  • --dry-run + --init (init is the write).
  • -v / --verbose + -q / --quiet.

nowline (no args) prints help and exits 0 (matches git, kubectl, gh, cargo, docker).

Exit codes

CodeMeaning
0Success
1Validation error
2Usage error (missing input, bad flags, unsupported format, file not found, binary→TTY refusal)
3Output error (cannot write to destination, exporter failure, page too small for margin)

Configuration: .nowlinerc

On any operation that takes an <input> file, nowline walks up from the input file's directory looking for a .nowlinerc (JSON or YAML). The nearest one wins. CLI flags override config values. Environment variables are not consulted.

# .nowlinerc (YAML)
theme: dark
defaultFormat: svg
width: 1200

# m2c format defaults — override with CLI flags at any time
pdfPageSize: a4            # --page-size
pdfOrientation: landscape  # --orientation
pdfMargin: 0.5in           # --margin
fontSans: sf               # --font-sans  (alias or path)
fontMono: sf-mono          # --font-mono
headlessFonts: false       # --headless
{
  "theme": "dark",
  "defaultFormat": "svg",
  "width": 1200,
  "pdfPageSize": "a4",
  "pdfOrientation": "landscape",
  "pdfMargin": "0.5in",
  "fontSans": "sf",
  "fontMono": "sf-mono",
  "headlessFonts": false
}

Unknown keys are ignored.

Validation (--dry-run)

nowline roadmap.nowline --dry-run
nowline roadmap.nowline -n                       # short alias
nowline roadmap.nowline -n --diagnostic-format json

Each diagnostic is rendered in a biome/oxc-style frame via @babel/code-frame:

roadmap.nowline:7:34 error: Unknown reference 'auth-refactro' in after — did you mean 'auth-refactor'?
  5 |   item auth-refactor "Auth refactor" size:l
  6 |   parallel after:auth-refactor
> 7 |     group audit-track "Audit Track" labels:security
    |                                     ^^^^^^^^^^^^^^^
  8 |       item audit-log "Audit log v2" size:xl before:code-freeze

--diagnostic-format json emits the stable diagnostic schema:

type Diagnostic = {
  file: string;
  line: number;        // 1-based
  column: number;      // 1-based
  severity: 'error' | 'warning';
  code: string;
  message: string;
  suggestion?: string;
};

Exit 0 if no errors; exit 1 if any errors. Warnings never change the exit code.

JSON AST round-trip

-f json emits the JSON AST; -f nowline re-prints canonical .nowline:

nowline roadmap.nowline -f json -o roadmap.json   # text → JSON
nowline roadmap.json -f nowline -o roadmap.nowline # JSON → text (canonical)

The JSON form is a versioned, published contract ($nowlineSchema: "1") intended for MCP (m7) and editor (m5) round-trips:

type NowlineDocument = {
  $nowlineSchema: "1";
  file: { uri: string; source: string };
  ast: NowlineFileNode;
};

Every node carries $type, $position, and the properties defined by the corresponding @nowline/core AST interface. Container back-references ($container, $containerProperty, $containerIndex) are omitted — parent-child relationship is captured by document structure.

Canonical .nowline printer rules

  • Indent: 2 spaces.
  • Positional order on declaration lines: idtitle → keyed properties.
  • Keyed-property order: date, length, on, duration, status, owner, after, before, remaining, labels, style, link, (any remaining keys, alphabetical).
  • List shape: single-element lists render as bare (labels:enterprise); multi-element lists use bracket form (labels:[enterprise, security]).
  • description sub-directive: rendered on its own line indented one level under its host.
  • Comments: not preserved across round-trips. Documented limitation; a follow-up grammar ticket will add trivia support.

Round-trip property: for every file in examples/, text → json → text and json → text → json are idempotent modulo comment loss. Enforced by the test suite.

--serve

Live-reload preview. Opens a minimal HTML shell at http://<host>:<port>/ that fetches /svg and subscribes to /events (SSE). On file changes, the server re-parses, re-validates, re-lays-out, and re-renders; clients refresh automatically. Validation errors appear as an overlay on top of the most recent successful render.

nowline roadmap.nowline --serve
nowline roadmap.nowline --serve -p 4400 -t dark --open
nowline roadmap.nowline --serve -o latest.svg     # rewrites latest.svg on each rebuild

--serve is intended for local authoring only. It is not a production preview service. -o - (stdout) is rejected.

--init

Create a starter .nowline file in the current directory. Three templates (minimal, teams, product) correspond to the three files in examples/ and are embedded into the CLI at build time — binaries are self-contained.

  • Positional argument is the project name, not a file path.
  • .nowline is auto-appended if missing.
  • Other extensions (.txt, .json) are rejected with exit 2.
  • Existing files are silently overwritten.
nowline --init                    # ./roadmap.nowline (default name)
nowline --init my-project         # ./my-project.nowline (auto-append)
nowline --init my-plan.nowline    # ./my-plan.nowline (literal)
nowline --init --template product # use the product template

Arg parser choice

@nowline/cli parses arguments with Node's native util.parseArgs. Reasons:

  • Zero runtime dependency.
  • Native short/long flag support, kebab-case option names, mixed-position positionals, and the -- end-of-options sentinel.
  • Verbless dispatch is straightforward — modes are just boolean flags resolved after parsing.

Supporting libraries:

  • @babel/code-frame — biome/oxc-style source excerpts with caret/tilde underlines for --dry-run text output.
  • js-yaml.nowlinerc YAML parsing (JSON also supported).

Distribution

A single nowline binary ships per platform, bundling every @nowline/export-* package. Compiled with bun build --compile; the CLI's format dispatch uses dynamic import() of each per-format package so the heavy exporter deps stay off cold paths and the binary stays straightforward to slim down later if a profile change ever justifies re-introducing a tier (see specs/cli-distribution.md).

Six platform binaries ship per release (macOS arm64/x64, Linux x64/arm64, Windows x64/arm64), attached to every GitHub Release. Size budgets are per target (Bun's standalone runtime varies by ~50 MB across platforms): macOS-arm64 ~70 MB, macOS-x64 ~75 MB, Linux ~107 MB, Windows ~119–122 MB. CI asserts on disk for every target via packages/cli/scripts/compile.mjs. See specs/cli-distribution.md for the full ceiling table.

Windows SmartScreen walkthrough

The shipped .exe binaries are unsigned. Windows may show a SmartScreen warning ("Windows protected your PC"). To run the downloaded binary:

  • Right-click the .exeProperties.
  • Check Unblock at the bottom of the General tab → OK.
  • Run the binary from a terminal (cmd or PowerShell).

Corporate endpoints may block unsigned binaries entirely. In that case, npm install -g @nowline/cli (which runs on Node/Bun) is an alternative.

FAQs

Package last updated on 17 Jun 2026

Related posts