kandown 0.27.1 → 0.28.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.28.1 — 2026-07-20 — "Robust Global Auto-Updater"
4
+
5
+ - **Fixed**: **Global package manager auto-update commands** — updated `checkForUpdate()` and `cmdUpdate()` to run `pnpm add -g kandown@latest` (instead of `pnpm install -g kandown`), with fallback chain across `pnpm`, `npm`, `yarn`, and `bun`.
6
+ - **Fixed**: **`kandown update` command behavior** — `kandown update` now queries the npm registry for the latest release, updates the global CLI package using the active package manager, and refreshes project `.kandown/kandown.html` files.
7
+ - **Fixed**: **Terminal & tmux auto-update compatibility** — fixed `checkForUpdate()` invocation so interactive terminal sessions (including tmux and iTerm) automatically detect and offer updates.
8
+
9
+ ## 0.28.0 — 2026-07-20 — "Agent Instruction Modes & CLI Reference"
10
+
11
+ - **Added**: **3 Base Agent Rule Modes (Verbose, Optimized, Caveman)** — redesigned the Agent instructions settings into 3 distinct rule density modes. Users can choose between **Verbose** (full reference guide), **Optimized** (concise, high-density structured rules tailored for LLMs), and **Caveman** (ultra-compact minimal token rules).
12
+ - **Added**: **Quick CLI Commands Reference in Agent Rules** — added a concise CLI cheatsheet table (`kandown work`, `kandown list`, `kandown show`, `kandown create`, `kandown move`, `kandown assign`, `kandown commit`) right at the top of base rules across all modes so AI agents immediately know the native CLI commands available to interact with the board.
13
+ - **Added**: **3-Step Numbered Layout for Agent Settings** — reorganized the Agent Instructions settings page into 3 clear numbered step cards: Step 1 (Base Rules mode & density), Step 2 (Project Guidelines stored in `.kandown/instructions.md`), and Step 3 (Live Board State data filters).
14
+ - **Added**: **Quick Preset Instruction Chips** — added 1-click template insertion chips (`📦 pnpm`, `🧪 Test rule`, `🌳 Git rule`, `⚡ Task log`) below the project instructions editor for adding repository rules instantly.
15
+ - **Added**: **Terminal-Style Sticky Live Preview Panel** — added an independent sticky preview panel on the right with window dot indicators, token estimation badge, layer legend badges (🟢 Step 1, 🟡 Step 2, 🔵 Step 3), 1-click Copy button, and real-time interactive color highlighting when hovering over options.
16
+
3
17
  ## 0.27.1 — 2026-07-20 — "Auto-Updater & Daemon Process Upgrade"
4
18
 
5
19
  - **Fixed**: **Environment inheritance during background auto-update** — cleaned inherited `npm_config_*` and `npm_*` environment variables when spawning `npm install -g kandown` in `checkForUpdate()`. Previously, if Kandown was run via `npx` or `npm run`, inherited local prefix overrides could cause global background updates to fail or target a temporary cache.
package/bin/kandown.js CHANGED
@@ -313,40 +313,14 @@ async function checkForUpdate(argv = process.argv) {
313
313
 
314
314
  // 📖 Step 3: Run the update via npm or pnpm with animated progress.
315
315
  tuiProgress(`Updating to ${latest}…`, 25);
316
-
317
- const updateOk = await new Promise((resolve) => {
318
- const tryInstall = (cmd) => {
319
- return new Promise((res) => {
320
- const cleanEnv = { ...process.env };
321
- for (const k of Object.keys(cleanEnv)) {
322
- if (k.startsWith('npm_config_') || k.startsWith('npm_') || k === 'INIT_CWD') {
323
- delete cleanEnv[k];
324
- }
325
- }
326
- const child = spawn(cmd, ['install', '-g', 'kandown'], {
327
- timeout: 60000,
328
- stdio: ['pipe', 'pipe', 'pipe'],
329
- env: cleanEnv,
330
- detached: false,
331
- });
332
- child.stderr.on('data', () => {}); // silence npm noise
333
- child.stdout.on('data', () => {});
334
- child.on('error', () => res(false));
335
- child.on('close', (code) => res(code === 0));
336
- });
337
- };
338
- tryInstall('npm').then((ok) => {
339
- if (ok) resolve(true);
340
- else tryInstall('pnpm').then(resolve);
341
- });
342
- });
316
+ const updateOk = await performGlobalPackageUpdate(`kandown@${latest}`);
343
317
 
344
318
  // 📖 Clean up lock file regardless of outcome.
345
319
  try { if (existsSync(lockFile)) unlinkSync(lockFile); } catch { /* ignore */ }
346
320
 
347
321
  if (!updateOk) {
348
322
  tuiDone('✗', `${c.yellow}Auto-update failed${c.reset} — continuing with current version`);
349
- log(` Run ${c.cyan}npm install -g kandown${c.reset} to upgrade manually`);
323
+ log(` Run ${c.cyan}pnpm add -g kandown@latest${c.reset} or ${c.cyan}npm install -g kandown@latest${c.reset} to upgrade manually`);
350
324
  log('');
351
325
  return;
352
326
  }
@@ -1018,29 +992,55 @@ function cmdInit(rawArgs) {
1018
992
  log('');
1019
993
  }
1020
994
 
1021
- function cmdUpdate(rawArgs) {
995
+ async function cmdUpdate(rawArgs) {
1022
996
  const current = getCurrentVersion();
1023
997
  log(`${c.bold}kandown update${c.reset} ${c.dim}— v${current}${c.reset}`);
1024
- printVersionChangelog(current);
998
+
999
+ // 📖 Step 1: Check latest version on npm registry
1000
+ const latest = await new Promise((resolve) => {
1001
+ const child = spawn('npm', ['view', 'kandown', 'version'], {
1002
+ timeout: 6000,
1003
+ stdio: ['pipe', 'pipe', 'pipe'],
1004
+ env: { ...process.env },
1005
+ detached: false,
1006
+ });
1007
+ let stdout = '';
1008
+ child.stdout.on('data', (d) => { stdout += d; });
1009
+ child.stderr.on('data', () => {});
1010
+ child.on('error', () => resolve(null));
1011
+ child.on('close', (code) => {
1012
+ if (code !== 0) return resolve(null);
1013
+ const v = stdout.trim().replace(/^"|"$/g, '');
1014
+ resolve(v || null);
1015
+ });
1016
+ });
1017
+
1018
+ if (latest && semverGt(latest, current) > 0) {
1019
+ tuiProgress(`Updating kandown package v${current} → v${latest}…`, 30);
1020
+ const updateOk = await performGlobalPackageUpdate(`kandown@${latest}`);
1021
+ if (updateOk) {
1022
+ tuiDone('✓', `${c.green}Successfully upgraded kandown to v${latest}${c.reset}`);
1023
+ printVersionChangelog(latest);
1024
+ } else {
1025
+ tuiDone('✗', `${c.yellow}Global CLI update failed${c.reset} — try running: ${c.cyan}pnpm add -g kandown@latest${c.reset} or ${c.cyan}npm install -g kandown@latest${c.reset}`);
1026
+ }
1027
+ } else {
1028
+ printVersionChangelog(current);
1029
+ info(`kandown CLI is already up to date (v${current}).`);
1030
+ }
1025
1031
 
1026
1032
  const args = parseArgs(rawArgs);
1027
1033
  const cwd = process.cwd();
1028
1034
  const kandownDir = resolve(cwd, args.path);
1029
1035
  const htmlDest = join(kandownDir, 'kandown.html');
1030
1036
 
1031
- if (!existsSync(htmlDest)) {
1032
- err(`No kandown.html found at ${c.bold}${htmlDest}${c.reset}`);
1033
- log(` Run ${c.cyan}npx kandown init${c.reset} first.`);
1034
- process.exit(1);
1035
- }
1036
-
1037
- const htmlSrc = join(PKG_ROOT, 'dist', 'index.html');
1038
- if (!existsSync(htmlSrc)) {
1039
- err(`Missing build output. Did you run 'npm run build'?`);
1040
- process.exit(1);
1037
+ if (existsSync(htmlDest)) {
1038
+ const htmlSrc = join(PKG_ROOT, 'dist', 'index.html');
1039
+ if (existsSync(htmlSrc)) {
1040
+ copyFileSync(htmlSrc, htmlDest);
1041
+ success(`Refreshed ${args.path}/kandown.html`);
1042
+ }
1041
1043
  }
1042
- copyFileSync(htmlSrc, htmlDest);
1043
- success(`Updated ${args.path}/kandown.html`);
1044
1044
  }
1045
1045
 
1046
1046
  /* ═════════════ One-shot task commands ═════════════ */
@@ -1575,18 +1575,32 @@ function priorityRank(p) {
1575
1575
  }
1576
1576
 
1577
1577
  const WORK_OUTPUT_SECTION_IDS = ['baseRules', 'projectInstructions', 'boardDigest'];
1578
- const CONCISE_AGENT_RULES = `# Kandown agent rules — concise
1578
+ const OPTIMIZED_AGENT_RULES = `# Kandown agent rules
1579
1579
 
1580
+ ## CLI Commands
1581
+ - \`kandown list\` (list tasks) · \`kandown show <id>\` (view task)
1582
+ - \`kandown create "<title>"\` (create task) · \`kandown move <id> <status>\` (move task column)
1583
+ - \`kandown assign <id> <user>\` · \`kandown commit\` (commit board to git)
1584
+
1585
+ ## Rules
1580
1586
  - Task state lives in project-root \`tasks/*.md\`; do not maintain a separate board index.
1581
1587
  - Before work, read the relevant task file and keep it updated while you progress.
1582
1588
  - Move tasks by editing frontmatter \`status:\`; complete work by setting \`status: Done\` and adding a markdown \`report:\` summary.
1583
1589
  - Update subtasks in-place: \`- [ ]\` → \`- [x]\`, with a short \`report:\` line for meaningful progress.
1584
1590
  - Board columns live in \`.kandown/kandown.json\` under \`board.columns\`; project instructions live in \`.kandown/instructions.md\`.
1585
1591
  - Never put Kandown task data inside \`.kandown/\`; tasks belong in \`./tasks/\`.`;
1592
+
1593
+ const CAVEMAN_AGENT_RULES = `# Kandown agent rules
1594
+
1595
+ CLI: kandown list | kandown show <id> | kandown create "<title>" | kandown move <id> <status> | kandown assign <id> <user> | kandown commit
1596
+ RULES: TASKS IN ./tasks/*.md. READ TASK BEFORE WORK. UPDATE SUBTASKS - [ ] -> - [x] + REPORT. MOVE: EDIT status:. DONE: status: Done + report:.`;
1597
+
1598
+ const CONCISE_AGENT_RULES = OPTIMIZED_AGENT_RULES;
1599
+
1586
1600
  const DEFAULT_WORK_OUTPUT = {
1587
1601
  mode: 'blocks',
1588
1602
  includeBaseRules: true,
1589
- baseRulesMode: 'full',
1603
+ baseRulesMode: 'verbose',
1590
1604
  includeProjectInstructions: true,
1591
1605
  includeBoardDigest: true,
1592
1606
  sectionOrder: WORK_OUTPUT_SECTION_IDS,
@@ -1612,11 +1626,13 @@ function normalizeWorkOutputConfig(config) {
1612
1626
  ? raw.sectionOrder.filter(id => WORK_OUTPUT_SECTION_IDS.includes(id))
1613
1627
  : DEFAULT_WORK_OUTPUT.sectionOrder;
1614
1628
  const order = sectionOrder.length > 0 ? sectionOrder : DEFAULT_WORK_OUTPUT.sectionOrder;
1629
+ const validBaseModes = ['verbose', 'optimized', 'caveman', 'full', 'concise'];
1630
+ const baseMode = validBaseModes.includes(raw.baseRulesMode) ? raw.baseRulesMode : DEFAULT_WORK_OUTPUT.baseRulesMode;
1615
1631
  return {
1616
1632
  ...DEFAULT_WORK_OUTPUT,
1617
1633
  ...raw,
1618
1634
  mode: raw.mode === 'raw' ? 'raw' : 'blocks',
1619
- baseRulesMode: raw.baseRulesMode === 'concise' ? 'concise' : 'full',
1635
+ baseRulesMode: baseMode,
1620
1636
  sectionOrder: order,
1621
1637
  rawTemplate: typeof raw.rawTemplate === 'string' && raw.rawTemplate.trim()
1622
1638
  ? raw.rawTemplate
@@ -1625,8 +1641,9 @@ function normalizeWorkOutputConfig(config) {
1625
1641
  };
1626
1642
  }
1627
1643
 
1628
- function readBaseAgentRules(mode = 'full') {
1629
- if (mode === 'concise') return CONCISE_AGENT_RULES;
1644
+ function readBaseAgentRules(mode = 'verbose') {
1645
+ if (mode === 'caveman') return CAVEMAN_AGENT_RULES;
1646
+ if (mode === 'optimized' || mode === 'concise') return OPTIMIZED_AGENT_RULES;
1630
1647
  try {
1631
1648
  return readFileSync(join(PKG_ROOT, 'templates', 'AGENT_KANDOWN.md'), 'utf8').trim();
1632
1649
  } catch (e) {
@@ -3391,7 +3408,7 @@ switch (cmd) {
3391
3408
  break;
3392
3409
 
3393
3410
  case 'update':
3394
- cmdUpdate(rest);
3411
+ await cmdUpdate(rest);
3395
3412
  break;
3396
3413
 
3397
3414
  // 📖 One-shot task commands — top-level, no "shell" wrapper. These are the