Lines 1-40javascript
2// Dispatcher for the roadmapped package — the only published entry point (spec
3// 2026-07-08-distribution, §2). Three families of verbs:
4// init / upgrade → install plumbing in the host repo (scripts/install.mjs)
5// dashboard → Vite (dev) from the PACKAGE, data anchored to the HOST repo
6// everything else → transparent proxy to scripts/task.mjs (portable CLI:
7// `npx roadmapped done 42` works in any repo)
9// NO static .ts import here: we first check the Node version (native strip-types
10// required — locked decision: we ship the raw .ts), so it fails with a clear
11// message rather than a cryptic SyntaxError.
13const [major = 0, minor = 0] = process.versions.node.split('.').map(Number)
14if (major < 22 || (major === 22 && minor < 18)) {
16 `roadmapped requires Node >= 22.18 (native TypeScript imports, strip-types) — detected version: ${process.versions.node}.`,
21const { spawnSync } = await import('node:child_process')
22const { fileURLToPath, pathToFileURL } = await import('node:url')
HighChild Process
Package source references child process execution.
bin/roadmapped.mjsView on unpkg · L20 HighEntrypoint Build Divergence
Manifest entrypoint contains risky behavior absent from dist/build output.
bin/roadmapped.mjsView on unpkg · L20 MediumDynamic Require
Package source references dynamic require/import behavior.
bin/roadmapped.mjsView on unpkg · L20 23const { dirname, join, resolve } = await import('node:path')
25// Root of the PACKAGE (where this bin lives) — NOT the host repo (= cwd walked up, cf. paths.ts).
26const packageDir = resolve(dirname(fileURLToPath(import.meta.url)), '..')
27const [cmd, ...rest] = process.argv.slice(2)
29const importPkg = (rel) => import(pathToFileURL(join(packageDir, rel)).href)
31// Node refuses to strip types under node_modules: we register the amaro loader
32// BEFORE any .ts import (see scripts/register-ts.mjs). The subprocesses (task.mjs
33// proxy) get the same loader via --import.
34const registerTs = join(packageDir, 'scripts', 'register-ts.mjs')
35await import(pathToFileURL(registerTs).href)
36const nodeTs = (script, args) => [
37 '--import', registerTs, join(packageDir, 'scripts', script), ...args,
40const USAGE = `Usage: roadmapped <command>