Lines 24-84javascript
24 * → migrateTasksToTopLevel — silently moves legacy .kandown/tasks/ → ./tasks/
25 * → cmdInit — installs `.kandown` and top-level `tasks/`
26 * → cmdUpdate — refreshes installed kandown.html
27 * → injectServerRoot — injects the CLI server root into single-file HTML
28 * → createServeServer — creates the local zero-dependency HTTP server
29 * → readDaemonMetadata — reads per-project daemon status metadata
30 * → startDaemon — starts/reconnects the per-project web daemon
31 * → stopDaemon — stops the per-project web daemon
32 * → cmdDaemon — daemon lifecycle command router
33 * → cmdServe — starts/reconnects the daemon, opens web UI, and launches the board TUI
34 * → main — dispatches CLI commands
38/* eslint-disable no-console */
39// 📖 DEV=false prevents Ink from loading react-devtools-core (CJS-only, breaks ESM).
40// Must be set BEFORE any imports because ESM hoists all import statements.
41process.env.DEV = 'false';
42// 📖 Polyfill browser globals that some bundled modules expect.
43if (typeof globalThis.self === 'undefined') Object.defineProperty(globalThis, 'self', { value: globalThis });
44if (typeof globalThis.window === 'undefined') Object.defineProperty(globalThis, 'window', { value: globalThis });
45// 📖 Make require() available in this ESM module so bundled __require() shims work.
46// tsup's __require checks `typeof require !== "undefined"` — this makes it truthy.
MediumDynamic Require
Package source references dynamic require/import behavior.
bin/kandown.jsView on unpkg · L44 47import { createRequire } from 'node:module';
48globalThis.require = createRequire(import.meta.url);
50import { fileURLToPath } from 'node:url';
51import { createServer } from 'node:http';
52import { dirname, join, resolve } from 'node:path';
65import { spawnSync, spawn, execSync } from 'node:child_process';
66import { createConnection } from 'node:net';
HighChild Process
Package source references child process execution.
bin/kandown.jsView on unpkg · L64 68const __filename = fileURLToPath(import.meta.url);
69const __dirname = dirname(__filename);
70const PKG_ROOT = resolve(__dirname, '..');
71// 📖 Default localhost range for the zero-config `kandown` web UI server.
72// 📖 Single source of truth for the daemon port range. Each kandown project
73// gets its own daemon on the first free port in this range, so multiple
74// projects can run in parallel (A=2048, B=2050, C=2051, ...).
75const START_PORT_RANGE = 2048;
76const END_PORT_RANGE = 2150;
77const DAEMON_FILE = 'daemon.json';
80 * 📖 Ports that Chromium/Firefox/Safari refuse to load (net::ERR_UNSAFE_PORT).
81 * These are reserved for well-known services (NFS, ssh, smtp, X11, ...).
82 * Browsers block navigation to them with no recourse, so a daemon listening
83 * on one of these appears dead in the browser even though it serves fine via
84 * curl. We MUST skip them when allocating ports. The most common victim in