kandown 0.24.0 → 0.25.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 +16 -0
- package/bin/kandown.js +25 -1
- package/dist/index.html +139 -139
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.25.1 — 2026-07-20 — "Stale Daemon Refresh"
|
|
4
|
+
|
|
5
|
+
- **Fixed**: **Deep-link refreshes after existing daemon sessions** — Kandown now detects when a project daemon was started by an older CLI version and restarts it when the current CLI is newer. This matters because URL refresh handling for paths like `/058?p=suzu` lives in the daemon process itself; refreshing `kandown.html` alone cannot teach an already-running old daemon to serve task deep-link routes.
|
|
6
|
+
- **Fixed**: **Direct task URLs no longer require manual daemon restarts after updates** — running `kandown` or `kandown daemon start` now upgrades stale daemon processes automatically, so newly published routing behavior becomes active for existing projects without users needing to hunt for old PIDs.
|
|
7
|
+
- **Changed**: **Daemon reconnect behavior** — reconnecting to a same-project daemon still reuses compatible current/newer daemons, but older or unknown-version daemons are stopped and relaunched with the current CLI before returning the daemon URL.
|
|
8
|
+
|
|
9
|
+
## 0.25.0 — 2026-07-20 — "Task Deep Links"
|
|
10
|
+
|
|
11
|
+
- **Added**: **Shareable task deep links** — opening a task drawer now updates the browser URL to a copy-pasteable route such as `/210?p=kandown`, where numeric task segments are normalized to Kandown task ids like `t210`. This makes it possible to send a direct link to a specific task instead of asking someone to find it manually on the board.
|
|
12
|
+
- **Added**: **Direct URL hydration for task drawers** — pasted links are parsed on web app startup and after browser navigation. Kandown now accepts the canonical `/210?p=kandown` format plus tolerant alternatives such as `/t210?p=kandown`, `?task=210`, and `?p=kandown/210`, then opens the matching drawer once the project is loaded.
|
|
13
|
+
- **Added**: **Browser history support for task navigation** — drawer open and close actions now synchronize with `pushState`/`replaceState`, and Kandown listens for `popstate` so browser Back and Forward switch between board-only and task-focused URLs instead of leaving stale drawer state behind.
|
|
14
|
+
- **Added**: **Copy URL action in the task drawer** — the opened task header now includes a lightweight Copy URL control that writes the absolute task link to the clipboard, with a toast fallback that displays the URL if clipboard access is denied.
|
|
15
|
+
- **Fixed**: **Daemon routing for deep links** — the local web daemon now serves the single-page app for safe one-segment task paths like `/210`, preventing direct task URLs from returning `404 Not found` before React has a chance to hydrate and open the drawer.
|
|
16
|
+
- **Changed**: **Project URL handling** — board/project URLs now go through shared URL helpers so project-only navigation keeps `/?p=<project>` while task navigation cleanly adds or removes the task path segment.
|
|
17
|
+
- **Changed**: **Board housekeeping** — completed Kandown task files were archived or removed from the active task set, new backlog tasks were added for upcoming archive/subtask/opened-task redesign work, and local board config/runtime ignore files were updated to match the current project workflow.
|
|
18
|
+
|
|
3
19
|
## 0.24.0 — 2026-07-20 — "Work Output Configurator"
|
|
4
20
|
|
|
5
21
|
- **Added**: **`kandown work` Output Configurator** — added a new Settings panel under Agent configuration that lets each project control the markdown emitted by `kandown work`. Users can enable or disable the base rules, project instructions, and live board digest blocks without editing generated files by hand.
|
package/bin/kandown.js
CHANGED
|
@@ -1987,7 +1987,21 @@ function releaseDaemonSpawnLock(lockPath) {
|
|
|
1987
1987
|
|
|
1988
1988
|
async function startDaemon(kandownDir, preferredPort) {
|
|
1989
1989
|
const current = await getDaemonStatus(kandownDir);
|
|
1990
|
-
if (current.running)
|
|
1990
|
+
if (current.running) {
|
|
1991
|
+
const currentVersion = getCurrentVersion();
|
|
1992
|
+
const daemonVersion = current.metadata?.version || null;
|
|
1993
|
+
// 📖 Deep-link routes and other daemon-owned behavior live in the long-running
|
|
1994
|
+
// daemon process, not in kandown.html. If the CLI updated while a daemon was
|
|
1995
|
+
// already running, reconnecting to the old process keeps old routing alive
|
|
1996
|
+
// (e.g. refreshing `/058?p=suzu` returned 404). Restart only when the local
|
|
1997
|
+
// CLI is newer; newer/dev daemons are left untouched.
|
|
1998
|
+
if (!daemonVersion || semverGt(currentVersion, daemonVersion) > 0) {
|
|
1999
|
+
warn(`Restarting daemon v${daemonVersion || 'unknown'} → v${currentVersion}...`);
|
|
2000
|
+
await stopDaemon(kandownDir);
|
|
2001
|
+
} else {
|
|
2002
|
+
return current;
|
|
2003
|
+
}
|
|
2004
|
+
}
|
|
1991
2005
|
|
|
1992
2006
|
const lock = acquireDaemonSpawnLock(kandownDir);
|
|
1993
2007
|
if (!lock) {
|
|
@@ -2726,6 +2740,15 @@ function serveStaticAsset(req, res, pathname) {
|
|
|
2726
2740
|
return false;
|
|
2727
2741
|
}
|
|
2728
2742
|
|
|
2743
|
+
function isTaskDeepLinkPath(pathname) {
|
|
2744
|
+
try {
|
|
2745
|
+
const cleaned = decodeURIComponent(pathname).replace(/^\/+|\/+$/g, '');
|
|
2746
|
+
return !!cleaned && !cleaned.includes('/') && !cleaned.includes('.') && /^[A-Za-z0-9_-]+$/.test(cleaned);
|
|
2747
|
+
} catch {
|
|
2748
|
+
return false;
|
|
2749
|
+
}
|
|
2750
|
+
}
|
|
2751
|
+
|
|
2729
2752
|
function createServeServer(kandownDir) {
|
|
2730
2753
|
try {
|
|
2731
2754
|
const tasksDir = getTasksDir(kandownDir);
|
|
@@ -2750,6 +2773,7 @@ function createServeServer(kandownDir) {
|
|
|
2750
2773
|
return handleApi(req, res, requestUrl, kandownDir);
|
|
2751
2774
|
}
|
|
2752
2775
|
if (serveStaticAsset(req, res, requestUrl.pathname)) return;
|
|
2776
|
+
if (req.method === 'GET' && isTaskDeepLinkPath(requestUrl.pathname)) return serveApp(res, kandownDir);
|
|
2753
2777
|
return writeText(res, 404, 'Not found');
|
|
2754
2778
|
});
|
|
2755
2779
|
}
|