claude-code-kanban 2.3.1 → 2.4.0
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/lib/parsers.js +9 -2
- package/package.json +1 -1
- package/public/app.js +7 -0
- package/server.js +34 -26
package/lib/parsers.js
CHANGED
|
@@ -172,7 +172,7 @@ function readCustomTitle(jsonlPath, existingStat) {
|
|
|
172
172
|
}
|
|
173
173
|
|
|
174
174
|
function readSessionInfoFromJsonl(jsonlPath) {
|
|
175
|
-
const result = { slug: null, projectPath: null, gitBranch: null, customTitle: null };
|
|
175
|
+
const result = { slug: null, projectPath: null, cwd: null, gitBranch: null, customTitle: null };
|
|
176
176
|
let stat;
|
|
177
177
|
try {
|
|
178
178
|
stat = statSync(jsonlPath);
|
|
@@ -182,16 +182,22 @@ function readSessionInfoFromJsonl(jsonlPath) {
|
|
|
182
182
|
|
|
183
183
|
const headBuf = Buffer.alloc(Math.min(HEAD_SIZE, stat.size));
|
|
184
184
|
const hn = fs.readSync(fd, headBuf, 0, headBuf.length, 0);
|
|
185
|
+
let lastCwdFromHead = null;
|
|
185
186
|
for (const line of headBuf.toString('utf8', 0, hn).split('\n')) {
|
|
186
187
|
try {
|
|
187
188
|
const data = JSON.parse(line);
|
|
188
189
|
if (data.slug) result.slug = data.slug;
|
|
189
|
-
if (data.cwd)
|
|
190
|
+
if (data.cwd) {
|
|
191
|
+
if (!result.projectPath) result.projectPath = data.cwd;
|
|
192
|
+
lastCwdFromHead = data.cwd;
|
|
193
|
+
}
|
|
190
194
|
if (data.gitBranch) result.gitBranch = data.gitBranch;
|
|
191
195
|
if (result.slug && result.projectPath && result.gitBranch) break;
|
|
192
196
|
} catch (e) {}
|
|
193
197
|
}
|
|
194
198
|
|
|
199
|
+
result.cwd = lastCwdFromHead;
|
|
200
|
+
|
|
195
201
|
if ((!result.slug || !result.projectPath || !result.gitBranch) && stat.size > HEAD_SIZE) {
|
|
196
202
|
const tailStart = stat.size - TAIL_SIZE;
|
|
197
203
|
const tailBuf = Buffer.alloc(TAIL_SIZE);
|
|
@@ -203,6 +209,7 @@ function readSessionInfoFromJsonl(jsonlPath) {
|
|
|
203
209
|
if (!result.slug && data.slug) result.slug = data.slug;
|
|
204
210
|
if (!result.projectPath && data.cwd) result.projectPath = data.cwd;
|
|
205
211
|
if (!result.gitBranch && data.gitBranch) result.gitBranch = data.gitBranch;
|
|
212
|
+
if (!result.cwd && data.cwd) result.cwd = data.cwd;
|
|
206
213
|
if (result.slug && result.projectPath && result.gitBranch) break;
|
|
207
214
|
} catch (e) {}
|
|
208
215
|
}
|
package/package.json
CHANGED
package/public/app.js
CHANGED
|
@@ -4825,6 +4825,9 @@ function showInfoModal(session, teamConfig, tasks, planContent) {
|
|
|
4825
4825
|
const projectName = session.project.split(/[/\\]/).pop();
|
|
4826
4826
|
infoRows.push(['Project', projectName, { openPath: session.projectDir }]);
|
|
4827
4827
|
infoRows.push(['Path', session.project, { openPath: session.project }]);
|
|
4828
|
+
if (session.cwd && session.cwd !== session.project) {
|
|
4829
|
+
infoRows.push(['CWD', session.cwd, { openPath: session.cwd }]);
|
|
4830
|
+
}
|
|
4828
4831
|
if (session.gitBranch) {
|
|
4829
4832
|
infoRows.push(['Branch', session.gitBranch]);
|
|
4830
4833
|
}
|
|
@@ -5290,6 +5293,10 @@ window.addEventListener('popstate', () => {
|
|
|
5290
5293
|
e.preventDefault();
|
|
5291
5294
|
window.parent?.postMessage({ type: 'hub:keydown', key: e.key }, '*');
|
|
5292
5295
|
}
|
|
5296
|
+
if (e.altKey && !e.ctrlKey && !e.shiftKey && !e.metaKey && /^[1-9]$/.test(e.key)) {
|
|
5297
|
+
e.preventDefault();
|
|
5298
|
+
window.parent?.postMessage({ type: 'hub:keydown', key: e.key }, '*');
|
|
5299
|
+
}
|
|
5293
5300
|
});
|
|
5294
5301
|
})();
|
|
5295
5302
|
|
package/server.js
CHANGED
|
@@ -359,6 +359,20 @@ function loadSessionMetadata() {
|
|
|
359
359
|
const files = readdirSync(projectPath).filter(f => f.endsWith('.jsonl'));
|
|
360
360
|
const sessionIds = [];
|
|
361
361
|
|
|
362
|
+
// Read sessions-index.json first for canonical projectPath
|
|
363
|
+
let indexProjectPath = null;
|
|
364
|
+
const indexPath = path.join(projectPath, 'sessions-index.json');
|
|
365
|
+
let indexEntries = [];
|
|
366
|
+
if (existsSync(indexPath)) {
|
|
367
|
+
try {
|
|
368
|
+
const indexData = JSON.parse(readFileSync(indexPath, 'utf8'));
|
|
369
|
+
indexEntries = indexData.entries || [];
|
|
370
|
+
for (const entry of indexEntries) {
|
|
371
|
+
if (entry.projectPath) { indexProjectPath = entry.projectPath; break; }
|
|
372
|
+
}
|
|
373
|
+
} catch (e) {}
|
|
374
|
+
}
|
|
375
|
+
|
|
362
376
|
// First pass: read all JSONL files
|
|
363
377
|
let resolvedProjectPath = null;
|
|
364
378
|
for (const file of files) {
|
|
@@ -372,7 +386,8 @@ function loadSessionMetadata() {
|
|
|
372
386
|
|
|
373
387
|
metadata[sessionId] = {
|
|
374
388
|
slug: sessionInfo.slug,
|
|
375
|
-
project: sessionInfo.projectPath || null,
|
|
389
|
+
project: indexProjectPath || sessionInfo.projectPath || null,
|
|
390
|
+
cwd: sessionInfo.cwd || null,
|
|
376
391
|
gitBranch: sessionInfo.gitBranch || null,
|
|
377
392
|
customTitle: sessionInfo.customTitle || null,
|
|
378
393
|
jsonlPath: jsonlPath
|
|
@@ -381,38 +396,30 @@ function loadSessionMetadata() {
|
|
|
381
396
|
}
|
|
382
397
|
|
|
383
398
|
// Second pass: fill in missing project paths from siblings
|
|
384
|
-
|
|
399
|
+
const canonicalProject = indexProjectPath || resolvedProjectPath;
|
|
400
|
+
if (canonicalProject) {
|
|
385
401
|
for (const sid of sessionIds) {
|
|
386
402
|
if (!metadata[sid].project) {
|
|
387
|
-
metadata[sid].project =
|
|
403
|
+
metadata[sid].project = canonicalProject;
|
|
388
404
|
}
|
|
389
405
|
}
|
|
390
406
|
}
|
|
391
407
|
|
|
392
|
-
//
|
|
393
|
-
const
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
metadata[entry.sessionId] = {
|
|
403
|
-
slug: null,
|
|
404
|
-
project: entry.projectPath || null,
|
|
405
|
-
jsonlPath: null
|
|
406
|
-
};
|
|
407
|
-
}
|
|
408
|
-
metadata[entry.sessionId].description = entry.description || null;
|
|
409
|
-
if (entry.gitBranch) metadata[entry.sessionId].gitBranch = entry.gitBranch;
|
|
410
|
-
if (entry.customTitle) metadata[entry.sessionId].customTitle = entry.customTitle;
|
|
411
|
-
metadata[entry.sessionId].created = entry.created || null;
|
|
412
|
-
}
|
|
408
|
+
// Apply index metadata (descriptions, custom titles, etc.)
|
|
409
|
+
for (const entry of indexEntries) {
|
|
410
|
+
if (entry.sessionId) {
|
|
411
|
+
if (!metadata[entry.sessionId]) {
|
|
412
|
+
metadata[entry.sessionId] = {
|
|
413
|
+
slug: null,
|
|
414
|
+
project: indexProjectPath || entry.projectPath || null,
|
|
415
|
+
cwd: null,
|
|
416
|
+
jsonlPath: null
|
|
417
|
+
};
|
|
413
418
|
}
|
|
414
|
-
|
|
415
|
-
|
|
419
|
+
metadata[entry.sessionId].description = entry.description || null;
|
|
420
|
+
if (entry.gitBranch) metadata[entry.sessionId].gitBranch = entry.gitBranch;
|
|
421
|
+
if (entry.customTitle) metadata[entry.sessionId].customTitle = entry.customTitle;
|
|
422
|
+
metadata[entry.sessionId].created = entry.created || null;
|
|
416
423
|
}
|
|
417
424
|
}
|
|
418
425
|
}
|
|
@@ -480,6 +487,7 @@ function buildSessionObject(id, meta, overrides = {}) {
|
|
|
480
487
|
name: getSessionDisplayName(id, meta),
|
|
481
488
|
slug: meta.slug || null,
|
|
482
489
|
project: meta.project || null,
|
|
490
|
+
cwd: meta.cwd || null,
|
|
483
491
|
description: meta.description || null,
|
|
484
492
|
gitBranch: meta.gitBranch || null,
|
|
485
493
|
customTitle: meta.customTitle || null,
|