claude-code-session-manager 0.88.0 → 0.88.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/dist/assets/{AgentLibrary-BZ6IY2g1.js → AgentLibrary-kQF8_wAw.js} +1 -1
- package/dist/assets/{DataModel-dAoGAODX.js → DataModel-CY_mMnsr.js} +1 -1
- package/dist/assets/{History-CF157HyX.js → History-Sji2brb0.js} +1 -1
- package/dist/assets/{Hooks-CCPPipBk.js → Hooks-CtqpO-p5.js} +1 -1
- package/dist/assets/{HostBilko-Dlmz2m06.js → HostBilko-DN0ydOCr.js} +1 -1
- package/dist/assets/{Library-BaXcboWX.js → Library-CoiLZTKh.js} +1 -1
- package/dist/assets/{ListDetail-CoUCzG5S.js → ListDetail-CmqiQ_io.js} +1 -1
- package/dist/assets/{MarkdownEditor-DTg3JlOT.js → MarkdownEditor-HPoNeKhT.js} +1 -1
- package/dist/assets/{McpServers-DdjY1sA3.js → McpServers-Bj1X3_NT.js} +1 -1
- package/dist/assets/{Memory-BJ3Jlw0C.js → Memory-1PKjsM3b.js} +1 -1
- package/dist/assets/{Panel-ygRSgc41.js → Panel-I1s6ghPo.js} +1 -1
- package/dist/assets/{Permissions-m0KAnccF.js → Permissions-BhiiZjHQ.js} +1 -1
- package/dist/assets/{Plugins-CJRl6B3Q.js → Plugins-gv3_fkPX.js} +2 -2
- package/dist/assets/{ProvenanceBadge-w8cnlVvW.js → ProvenanceBadge-BGcgBd8V.js} +1 -1
- package/dist/assets/{SaveBar-BpyPcUIk.js → SaveBar-BGr9eZ4g.js} +1 -1
- package/dist/assets/{Scheduler-D2ppxSfy.js → Scheduler-Bdo_awPq.js} +1 -1
- package/dist/assets/{ScopeSwitcher-EyuIwt-j.js → ScopeSwitcher-ukl0qWaA.js} +1 -1
- package/dist/assets/{Settings-BHSGGFEc.js → Settings-DJkFj22G.js} +1 -1
- package/dist/assets/{SkillReferenceGraph-BNaZ2JCF.js → SkillReferenceGraph-0t1Qblp6.js} +1 -1
- package/dist/assets/{Skills-Dl3q75QV.js → Skills-CeVdBGE-.js} +1 -1
- package/dist/assets/{SystemPrompt-Bg6F-Cyp.js → SystemPrompt-CfKvNHi3.js} +1 -1
- package/dist/assets/{TagLibrary-BSutflCy.js → TagLibrary-DAzNaUPd.js} +1 -1
- package/dist/assets/{TiptapBody-CXih4xrc.js → TiptapBody--S_rGXoA.js} +1 -1
- package/dist/assets/{Toggle-2qtUHhA9.js → Toggle-Dszm0xnp.js} +1 -1
- package/dist/assets/{index-B3emy2oI.js → index-Dp4Rc--q.js} +3 -3
- package/dist/assets/{settingsSchema-CdzxaqwM.js → settingsSchema-BLbssMYo.js} +1 -1
- package/dist/index.html +1 -1
- package/package.json +1 -1
- package/src/main/__tests__/health-tick-liveness.test.cjs +16 -0
- package/src/main/__tests__/scheduler-stall-per-project.test.cjs +14 -0
- package/src/main/build-info.json +4 -4
- package/src/main/health.cjs +9 -1
- package/src/main/scheduler.cjs +9 -2
package/dist/index.html
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
|
8
8
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
|
9
9
|
<link href="https://fonts.googleapis.com/css2?family=Newsreader:ital,opsz,wght@0,6..72,400;0,6..72,500;0,6..72,600;0,6..72,700;1,6..72,400&family=Geist:wght@300;400;500;600;700&family=IBM+Plex+Mono:wght@400;500;600&display=swap" rel="stylesheet">
|
|
10
|
-
<script type="module" crossorigin src="./assets/index-
|
|
10
|
+
<script type="module" crossorigin src="./assets/index-Dp4Rc--q.js"></script>
|
|
11
11
|
<link rel="modulepreload" crossorigin href="./assets/monaco-editor-BW5C4Iv1.js">
|
|
12
12
|
<link rel="stylesheet" crossorigin href="./assets/monaco-editor-BTnBOi8r.css">
|
|
13
13
|
<link rel="stylesheet" crossorigin href="./assets/index-BHTX4OTc.css">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-code-session-manager",
|
|
3
|
-
"version": "0.88.
|
|
3
|
+
"version": "0.88.1",
|
|
4
4
|
"description": "Local cockpit for the Claude Code CLI — multi-tab terminal, full config surface, scheduler, voice dictation, and live observability.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "src/main/index.cjs",
|
|
@@ -149,3 +149,19 @@ test('readFreshHeartbeat: returns the parsed last line when fresh', () => {
|
|
|
149
149
|
fs.rmSync(dir, { recursive: true, force: true });
|
|
150
150
|
}
|
|
151
151
|
});
|
|
152
|
+
|
|
153
|
+
test('no false positive: pending rows blocked on an unfinished dependsOn are waiting on a job, not a tick', () => {
|
|
154
|
+
const result = evaluateTickLiveness(
|
|
155
|
+
baseQueue({
|
|
156
|
+
jobs: [
|
|
157
|
+
{ slug: '265-head', status: 'running' },
|
|
158
|
+
{ slug: '266-next', status: 'pending', dependsOn: ['265-head'] },
|
|
159
|
+
],
|
|
160
|
+
}),
|
|
161
|
+
{ ts: NOW - 30_000, utilization: 0 },
|
|
162
|
+
NOW,
|
|
163
|
+
1,
|
|
164
|
+
);
|
|
165
|
+
assert.strictEqual(result.stalled, false);
|
|
166
|
+
assert.strictEqual(result.reason, 'no-pending-jobs');
|
|
167
|
+
});
|
|
@@ -110,3 +110,17 @@ test('findStaleQuarantinedJobs: fires past threshold, not before', () => {
|
|
|
110
110
|
assert.deepStrictEqual(slugs, ['exactly-at-threshold', 'stale']);
|
|
111
111
|
assert.strictEqual(stale.find((s) => s.slug === 'stale').cwd, '/p1');
|
|
112
112
|
});
|
|
113
|
+
|
|
114
|
+
test('computeStallSummary: a fully drained project (all completed) is idle, not stalled', () => {
|
|
115
|
+
const state = {
|
|
116
|
+
paused: null,
|
|
117
|
+
jobs: [
|
|
118
|
+
{ slug: 'a', cwd: '/p1', status: 'completed' },
|
|
119
|
+
{ slug: 'b', cwd: '/p2', status: 'running' },
|
|
120
|
+
],
|
|
121
|
+
invalidJobs: [],
|
|
122
|
+
};
|
|
123
|
+
const summary = computeStallSummary(state);
|
|
124
|
+
assert.strictEqual(summary.byProject['/p1'].stalled, false);
|
|
125
|
+
assert.strictEqual(computeStallSummary({ paused: null, jobs: [{ slug: 'a', cwd: '/p1', status: 'completed' }], invalidJobs: [] }).stalled, false);
|
|
126
|
+
});
|
package/src/main/build-info.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "0.88.
|
|
3
|
-
"gitSha": "
|
|
4
|
-
"gitShortSha": "
|
|
2
|
+
"version": "0.88.1",
|
|
3
|
+
"gitSha": "03a101e69f411db8f3e5dfb465cb92a77365f32a",
|
|
4
|
+
"gitShortSha": "03a101e",
|
|
5
5
|
"gitBranch": "HEAD",
|
|
6
|
-
"builtAt": "2026-09-19T14:
|
|
6
|
+
"builtAt": "2026-09-19T14:48:43.339Z",
|
|
7
7
|
"dirty": false
|
|
8
8
|
}
|
package/src/main/health.cjs
CHANGED
|
@@ -88,7 +88,15 @@ function readFreshHeartbeat(heartbeatPath) {
|
|
|
88
88
|
// now) so it's testable without touching the filesystem.
|
|
89
89
|
function evaluateTickLiveness(queueState, heartbeat, now, runningCount) {
|
|
90
90
|
const jobs = queueState.jobs || [];
|
|
91
|
-
|
|
91
|
+
// A pending row whose dependsOn names a job that has not completed cannot be
|
|
92
|
+
// dispatched yet — it is waiting on that job, not on a tick. Counting it made
|
|
93
|
+
// a healthy dependsOn chain (one running, the rest waiting) read as a stall.
|
|
94
|
+
const statusBySlug = new Map(jobs.map((j) => [j.slug, j.status]));
|
|
95
|
+
const depsSatisfied = (j) => (j.dependsOn || []).every((d) => {
|
|
96
|
+
const st = statusBySlug.get(d);
|
|
97
|
+
return st === undefined || st === 'completed' || st === 'skipped';
|
|
98
|
+
});
|
|
99
|
+
const pending = jobs.filter((j) => j.status === 'pending' && depsSatisfied(j));
|
|
92
100
|
const running = runningCount ?? jobs.filter((j) => j.status === 'running').length;
|
|
93
101
|
const config = queueState.config || {};
|
|
94
102
|
// The scheduler's private concurrencyCap is retired — the machine-wide
|
package/src/main/scheduler.cjs
CHANGED
|
@@ -1865,7 +1865,12 @@ function computeStallSummary(state) {
|
|
|
1865
1865
|
byProject[key].invalid = (byProject[key].invalid || 0) + 1;
|
|
1866
1866
|
}
|
|
1867
1867
|
const total = jobs.length + invalidJobs.length;
|
|
1868
|
-
|
|
1868
|
+
// A drained queue (every row completed/skipped) is idle, not stalled — a
|
|
1869
|
+
// stall needs at least one parked problem row (failed/needs_review/
|
|
1870
|
+
// quarantined/invalid) that is waiting on someone.
|
|
1871
|
+
const isProblemStatus = (st) => st !== 'completed' && st !== 'skipped';
|
|
1872
|
+
const stalled = total > 0 && running === 0 && pending === 0 && !state?.paused
|
|
1873
|
+
&& (invalidJobs.length > 0 || jobs.some((j) => isProblemStatus(j.status)));
|
|
1869
1874
|
for (const key of Object.keys(byProject)) {
|
|
1870
1875
|
const counts = byProject[key];
|
|
1871
1876
|
const projRunning = counts.running || 0;
|
|
@@ -1873,7 +1878,9 @@ function computeStallSummary(state) {
|
|
|
1873
1878
|
const projTotal = Object.keys(counts)
|
|
1874
1879
|
.filter((k) => k !== 'stalled')
|
|
1875
1880
|
.reduce((sum, k) => sum + counts[k], 0);
|
|
1876
|
-
|
|
1881
|
+
const projProblem = Object.keys(counts)
|
|
1882
|
+
.some((k) => k !== 'stalled' && k !== 'completed' && k !== 'skipped' && counts[k] > 0);
|
|
1883
|
+
counts.stalled = projTotal > 0 && projRunning === 0 && projPending === 0 && !state?.paused && projProblem;
|
|
1877
1884
|
}
|
|
1878
1885
|
return { stalled, total, running, pending, byProject };
|
|
1879
1886
|
}
|