local-kanban 1.6.3
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 +381 -0
- package/LICENSE +21 -0
- package/README.md +144 -0
- package/README.ru.md +144 -0
- package/bin/kb +306 -0
- package/bin/local-kanban +217 -0
- package/ecosystem.example.cjs +25 -0
- package/package.json +52 -0
- package/public/app.js +18 -0
- package/public/boot-fallback.js +3 -0
- package/public/drawer-sync.js +14 -0
- package/public/favicon-180.png +0 -0
- package/public/favicon-32.png +0 -0
- package/public/favicon-64.png +0 -0
- package/public/favicon.ico +0 -0
- package/public/favicon.svg +6 -0
- package/public/icon-192.png +0 -0
- package/public/icon-512.png +0 -0
- package/public/icon-maskable-192.png +0 -0
- package/public/icon-maskable-512.png +0 -0
- package/public/index.html +138 -0
- package/public/js/board.js +698 -0
- package/public/js/chaos.js +247 -0
- package/public/js/core.js +821 -0
- package/public/js/dash.js +114 -0
- package/public/js/drawer.js +919 -0
- package/public/js/horizon.js +140 -0
- package/public/js/init.js +208 -0
- package/public/js/project.js +338 -0
- package/public/js/settings.js +905 -0
- package/public/js/sidebar.js +640 -0
- package/public/js/sse.js +386 -0
- package/public/manifest.webmanifest +32 -0
- package/public/offline.html +39 -0
- package/public/style.css +1247 -0
- package/public/sw.js +31 -0
- package/scripts/raycast/open-kanban.sh +18 -0
- package/scripts/update.js +43 -0
- package/skills/deploy/SKILL.md +70 -0
- package/skills/kanban/SKILL.md +217 -0
- package/src/backup.js +111 -0
- package/src/bus.js +10 -0
- package/src/config.js +40 -0
- package/src/db.js +321 -0
- package/src/error-handler.js +11 -0
- package/src/file-snapshot.js +22 -0
- package/src/origin-guard.js +32 -0
- package/src/pm2-services.js +31 -0
- package/src/query-params.js +17 -0
- package/src/repo-base.js +23 -0
- package/src/restore.js +153 -0
- package/src/routes/dashboard.js +132 -0
- package/src/routes/events.js +30 -0
- package/src/routes/horizons.js +66 -0
- package/src/routes/projects.js +532 -0
- package/src/routes/skills.js +116 -0
- package/src/routes/system.js +285 -0
- package/src/routes/tasks.js +477 -0
- package/src/schema.sql +135 -0
- package/src/server.js +100 -0
- package/src/skills.js +119 -0
- package/src/sync/github.js +265 -0
- package/src/sync/worker.js +136 -0
- package/src/task-shape.js +29 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Example pm2 config. Copy it to ecosystem.config.cjs (git-ignored, so local paths and env
|
|
2
|
+
// never leave your machine), adjust it, then: pm2 start ecosystem.config.cjs
|
|
3
|
+
module.exports = {
|
|
4
|
+
apps: [
|
|
5
|
+
{
|
|
6
|
+
name: 'kanban',
|
|
7
|
+
script: 'src/server.js',
|
|
8
|
+
// cwd: '/absolute/path/to/local-kanban', // when starting pm2 outside the project folder
|
|
9
|
+
env: {
|
|
10
|
+
PORT: '3100', // the board listens on 127.0.0.1 ONLY — never expose it
|
|
11
|
+
NODE_ENV: 'production',
|
|
12
|
+
// KB_DATA_DIR: '', // data directory (defaults to ~/.local-kanban, or data/ in a clone)
|
|
13
|
+
// KB_LOCAL_ROOT: '', // root of local project folders (defaults to ~/claude-projects)
|
|
14
|
+
// KB_GH_OWNER: '', // GitHub sync; empty = sync off (can also be set in Settings)
|
|
15
|
+
// KB_GH_REPO: '', // repository for issues, owner/repo
|
|
16
|
+
// KB_PANEL_URL: '', // custom HTTP source of service statuses; empty = local pm2
|
|
17
|
+
// KB_PANEL_INFO: '', // optional info.json of an external panel, for category sync
|
|
18
|
+
// // (the older names PANEL_URL/PANEL_INFO still work)
|
|
19
|
+
// KB_SKILLS_EXTRA: '', // extra skill root directories, ':'-separated
|
|
20
|
+
},
|
|
21
|
+
max_memory_restart: '200M',
|
|
22
|
+
merge_logs: true,
|
|
23
|
+
},
|
|
24
|
+
],
|
|
25
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "local-kanban",
|
|
3
|
+
"version": "1.6.3",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"author": "Dannylamao",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/lamaohub/local-kanban.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://github.com/lamaohub/local-kanban#readme",
|
|
11
|
+
"bugs": "https://github.com/lamaohub/local-kanban/issues",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=22"
|
|
15
|
+
},
|
|
16
|
+
"packageManager": "npm@10.0.0",
|
|
17
|
+
"bin": {
|
|
18
|
+
"kb": "bin/kb",
|
|
19
|
+
"local-kanban": "bin/local-kanban"
|
|
20
|
+
},
|
|
21
|
+
"description": "A local kanban board for working in tandem with Claude Code: the kb CLI plus a web board, with an optional GitHub mirror (issues + Projects v2)",
|
|
22
|
+
"scripts": {
|
|
23
|
+
"start": "node src/server.js",
|
|
24
|
+
"update": "node scripts/update.js"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@fastify/static": "^7.0.4",
|
|
28
|
+
"better-sqlite3": "^12.11.1",
|
|
29
|
+
"fastify": "^4.28.1"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"bin/",
|
|
33
|
+
"src/",
|
|
34
|
+
"public/",
|
|
35
|
+
"skills/",
|
|
36
|
+
"scripts/",
|
|
37
|
+
"ecosystem.example.cjs",
|
|
38
|
+
"README.md",
|
|
39
|
+
"README.ru.md",
|
|
40
|
+
"CHANGELOG.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
],
|
|
43
|
+
"keywords": [
|
|
44
|
+
"kanban",
|
|
45
|
+
"claude",
|
|
46
|
+
"claude-code",
|
|
47
|
+
"tasks",
|
|
48
|
+
"local-first",
|
|
49
|
+
"sqlite",
|
|
50
|
+
"cli"
|
|
51
|
+
]
|
|
52
|
+
}
|
package/public/app.js
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
|
|
2
|
+
import './js/init.js';
|
|
3
|
+
import { state, api, retryUnsaved } from './js/core.js';
|
|
4
|
+
import { refresh } from './js/sse.js';
|
|
5
|
+
import { selectProject, loadProjects, loadTasks, styledConfirm, styledPrompt } from './js/sidebar.js';
|
|
6
|
+
import { openDrawer, closeDrawer, deleteTask, cancelTask, setKbCursor } from './js/drawer.js';
|
|
7
|
+
import { openProjectSettings, closeProjectSettings } from './js/project.js';
|
|
8
|
+
import { openSettingsModal, getSetting, setSetting, applyTheme } from './js/settings.js';
|
|
9
|
+
import { renderDashboard } from './js/dash.js';
|
|
10
|
+
import { checkVersion } from './js/init.js';
|
|
11
|
+
|
|
12
|
+
Object.assign(window, {
|
|
13
|
+
state, api, refresh, loadTasks, loadProjects, selectProject,
|
|
14
|
+
openDrawer, closeDrawer, deleteTask, cancelTask, setKbCursor,
|
|
15
|
+
openProjectSettings, closeProjectSettings, openSettingsModal, getSetting, setSetting, applyTheme,
|
|
16
|
+
renderDashboard, styledConfirm, styledPrompt, checkVersion,
|
|
17
|
+
retryUnsaved,
|
|
18
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
(function (root, factory) {
|
|
2
|
+
const api = factory();
|
|
3
|
+
if (typeof module !== 'undefined' && module.exports) module.exports = api;
|
|
4
|
+
else root.DrawerSync = api;
|
|
5
|
+
})(typeof self !== 'undefined' ? self : this, function () {
|
|
6
|
+
function shouldSyncDrawerStatus(baseline, selectValue, serverStatus) {
|
|
7
|
+
if (serverStatus == null) return false;
|
|
8
|
+
if (serverStatus === baseline) return false;
|
|
9
|
+
if (selectValue !== baseline) return false;
|
|
10
|
+
return true;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return { shouldSyncDrawerStatus };
|
|
14
|
+
});
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 32 32">
|
|
2
|
+
<rect width="32" height="32" rx="7" fill="#e8704e"/>
|
|
3
|
+
<rect x="6" y="7" width="5.5" height="12" rx="2" fill="#fff" opacity=".95"/>
|
|
4
|
+
<rect x="13.25" y="7" width="5.5" height="18" rx="2" fill="#fff" opacity=".95"/>
|
|
5
|
+
<rect x="20.5" y="7" width="5.5" height="8" rx="2" fill="#fff" opacity=".95"/>
|
|
6
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" class="booting">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>Kanban</title>
|
|
7
|
+
<link rel="manifest" href="/manifest.webmanifest">
|
|
8
|
+
<meta name="theme-color" content="#e8704e">
|
|
9
|
+
<meta name="apple-mobile-web-app-capable" content="yes">
|
|
10
|
+
<meta name="apple-mobile-web-app-title" content="Kanban">
|
|
11
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="default">
|
|
12
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg">
|
|
13
|
+
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32.png">
|
|
14
|
+
<link rel="icon" type="image/png" sizes="64x64" href="/favicon-64.png">
|
|
15
|
+
<link rel="apple-touch-icon" href="/favicon-180.png">
|
|
16
|
+
<link rel="stylesheet" href="/style.css">
|
|
17
|
+
<script src="/boot-fallback.js"></script>
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
<div class="layout">
|
|
21
|
+
<aside class="sidebar">
|
|
22
|
+
<div class="sidebar-head">Projects</div>
|
|
23
|
+
<div id="projects"><div class="boot-side" aria-hidden="true">
|
|
24
|
+
<span class="boot-line"></span><span class="boot-line short"></span>
|
|
25
|
+
<span class="boot-line"></span><span class="boot-line short"></span>
|
|
26
|
+
<span class="boot-line"></span>
|
|
27
|
+
</div></div>
|
|
28
|
+
</aside>
|
|
29
|
+
|
|
30
|
+
<main class="main">
|
|
31
|
+
<header class="topbar">
|
|
32
|
+
<div class="topbar-left">
|
|
33
|
+
<h1 id="project-title">—</h1>
|
|
34
|
+
<button id="project-menu" class="btn-icon" title="Project settings">⋯</button>
|
|
35
|
+
<span id="project-meta" class="muted"></span>
|
|
36
|
+
</div>
|
|
37
|
+
<div class="topbar-right">
|
|
38
|
+
<span id="week-stats" class="muted" title="Done in the last 7 days"></span>
|
|
39
|
+
<button id="sound-badge" class="sound-badge hidden" title="The browser blocked sound until the first click — click to enable">sound off</button>
|
|
40
|
+
<button id="offline-badge" class="offline-badge hidden" title="The board could not reach the server — the change was not saved">not saved</button>
|
|
41
|
+
<span id="sync-badge" class="sync-badge" title="GitHub sync queue"></span>
|
|
42
|
+
</div>
|
|
43
|
+
</header>
|
|
44
|
+
<div id="toolbar" class="toolbar">
|
|
45
|
+
<input id="search" class="search" placeholder="Search tasks…">
|
|
46
|
+
<button id="new-task" class="btn-primary">New task +</button>
|
|
47
|
+
</div>
|
|
48
|
+
<div id="board" class="board"></div>
|
|
49
|
+
<svg id="link-lines" class="link-lines" aria-hidden="true"></svg>
|
|
50
|
+
<div id="dashboard" class="dashboard hidden"></div>
|
|
51
|
+
<div id="settings" class="settings hidden"></div>
|
|
52
|
+
<div id="horizon" class="horizon-view hidden"></div>
|
|
53
|
+
<div id="calendar" class="calendar-view hidden"></div>
|
|
54
|
+
<div id="chaos" class="chaos-view hidden"></div>
|
|
55
|
+
<div id="projset" class="projset-view hidden"></div>
|
|
56
|
+
|
|
57
|
+
<div id="boot" class="boot" aria-hidden="true">
|
|
58
|
+
<div class="boot-col"><span class="boot-head"></span>
|
|
59
|
+
<div class="boot-card"><span class="boot-line"></span><span class="boot-line short"></span></div>
|
|
60
|
+
<div class="boot-card"><span class="boot-line"></span></div>
|
|
61
|
+
<div class="boot-card"><span class="boot-line"></span><span class="boot-line short"></span></div>
|
|
62
|
+
</div>
|
|
63
|
+
<div class="boot-col"><span class="boot-head"></span>
|
|
64
|
+
<div class="boot-card"><span class="boot-line"></span></div>
|
|
65
|
+
<div class="boot-card"><span class="boot-line"></span><span class="boot-line short"></span></div>
|
|
66
|
+
</div>
|
|
67
|
+
<div class="boot-col"><span class="boot-head"></span>
|
|
68
|
+
<div class="boot-card"><span class="boot-line"></span><span class="boot-line short"></span></div>
|
|
69
|
+
</div>
|
|
70
|
+
<div class="boot-col"><span class="boot-head"></span>
|
|
71
|
+
<div class="boot-card"><span class="boot-line"></span></div>
|
|
72
|
+
<div class="boot-card"><span class="boot-line"></span><span class="boot-line short"></span></div>
|
|
73
|
+
</div>
|
|
74
|
+
</div>
|
|
75
|
+
</main>
|
|
76
|
+
|
|
77
|
+
<aside id="drawer" class="drawer hidden">
|
|
78
|
+
<div class="drawer-head">
|
|
79
|
+
<span id="drawer-id" class="drawer-key"></span>
|
|
80
|
+
<div class="drawer-head-actions">
|
|
81
|
+
<button id="d-return-icon" class="btn-icon hidden" title="Return to work">↩</button>
|
|
82
|
+
<button id="drawer-menu" class="btn-icon hidden" title="Card actions">⋯</button>
|
|
83
|
+
<button id="drawer-close" class="btn-icon" title="Close">✕</button>
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
|
|
87
|
+
<div id="drawer-empty" class="drawer-empty">Select a task — details will show up here</div>
|
|
88
|
+
|
|
89
|
+
<div id="drawer-multi" class="drawer-multi"></div>
|
|
90
|
+
|
|
91
|
+
<div id="drawer-content">
|
|
92
|
+
<div id="d-lock-note" class="lock-note hidden">Claude is working on this task — fields are locked, comments are open</div>
|
|
93
|
+
|
|
94
|
+
<div class="chip-row">
|
|
95
|
+
<div class="kbsel chip-sel hidden" id="d-project"></div>
|
|
96
|
+
<div class="kbsel chip-sel" id="d-status"></div>
|
|
97
|
+
<div class="kbsel chip-sel" id="d-priority"></div>
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
<div class="meta-row">
|
|
101
|
+
<div id="d-labels" class="labels-row"></div>
|
|
102
|
+
<div id="d-links" class="links-row hidden"></div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
<textarea id="d-title" class="d-title" rows="1" placeholder="Task title"></textarea>
|
|
106
|
+
<div class="desc-wrap">
|
|
107
|
+
<textarea id="d-desc" class="d-desc" placeholder="Description…"></textarea>
|
|
108
|
+
<button id="d-checklist-add" class="desc-menu-btn" title="Add checklist item" aria-label="Add checklist item">
|
|
109
|
+
<svg viewBox="0 0 16 16" width="15" height="15" aria-hidden="true"><path d="M2.5 4h11M2.5 8h11M2.5 12h11" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" fill="none"/></svg>
|
|
110
|
+
</button>
|
|
111
|
+
</div>
|
|
112
|
+
|
|
113
|
+
<div id="d-checklist" class="checklist hidden"></div>
|
|
114
|
+
|
|
115
|
+
<div id="d-attachments" class="attachments hidden"></div>
|
|
116
|
+
|
|
117
|
+
<div class="d-row" id="d-issue-row"></div>
|
|
118
|
+
|
|
119
|
+
<div id="d-timeline" class="timeline hidden"></div>
|
|
120
|
+
|
|
121
|
+
<div id="d-return" class="return-block hidden">
|
|
122
|
+
<button id="d-accept-btn" class="btn-accept hidden">✓ Accept task</button>
|
|
123
|
+
</div>
|
|
124
|
+
|
|
125
|
+
<div class="comments" id="comments-block">
|
|
126
|
+
<div id="comments"></div>
|
|
127
|
+
<div class="comment-form">
|
|
128
|
+
<textarea id="c-input" placeholder="Comment…" rows="1" autocomplete="off"></textarea>
|
|
129
|
+
<button id="c-send" class="btn-primary">↑</button>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</aside>
|
|
134
|
+
</div>
|
|
135
|
+
<script src="/drawer-sync.js"></script>
|
|
136
|
+
<script type="module" src="/app.js"></script>
|
|
137
|
+
</body>
|
|
138
|
+
</html>
|