@axiomatic-labs/claudeflow 2.13.60 → 2.13.61
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/doctor.js +29 -6
- package/package.json +1 -1
package/lib/doctor.js
CHANGED
|
@@ -149,13 +149,36 @@ function checkStaleLockfiles(cwd) {
|
|
|
149
149
|
// the configured port, the daemon is up.
|
|
150
150
|
function readObserverState(cwd) {
|
|
151
151
|
const observerJsonPath = path.join(cwd, '.claudeflow', 'tmp', 'error-observer.json');
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
152
|
+
// Defense-in-depth retry: even though the daemon now writes atomically
|
|
153
|
+
// (rename-after-write), older daemon versions and any future non-atomic
|
|
154
|
+
// writer would expose a 0-byte window during overwrite. We retry up to
|
|
155
|
+
// 3 times with a tiny pause between attempts so a transient empty read
|
|
156
|
+
// doesn't flip the panel UI between running/stopped every refresh.
|
|
157
|
+
let meta = null;
|
|
158
|
+
let lastErr = null;
|
|
159
|
+
for (let attempt = 0; attempt < 3; attempt += 1) {
|
|
160
|
+
try {
|
|
161
|
+
const raw = fs.readFileSync(observerJsonPath, 'utf8');
|
|
162
|
+
if (raw.trim()) {
|
|
163
|
+
meta = JSON.parse(raw);
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
lastErr = new Error('empty file');
|
|
167
|
+
} catch (e) {
|
|
168
|
+
lastErr = e;
|
|
169
|
+
if (e.code === 'ENOENT') break; // file genuinely missing — no retry helps
|
|
170
|
+
}
|
|
171
|
+
if (attempt < 2) {
|
|
172
|
+
// Sync sleep (~30ms) via spawnSync — sufficient to outlast a writeFile race.
|
|
173
|
+
const { spawnSync } = require('child_process');
|
|
174
|
+
spawnSync('sleep', ['0.03']);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
if (!meta) {
|
|
178
|
+
const source = (lastErr && lastErr.code === 'ENOENT') ? 'no-observer-json' : 'observer-json-malformed';
|
|
179
|
+
return { running: false, pid: null, port: null, source, observerJsonPath };
|
|
157
180
|
}
|
|
158
|
-
if (
|
|
181
|
+
if (typeof meta.port !== 'number') {
|
|
159
182
|
return { running: false, pid: null, port: null, source: 'observer-json-malformed', observerJsonPath };
|
|
160
183
|
}
|
|
161
184
|
const port = meta.port;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@axiomatic-labs/claudeflow",
|
|
3
|
-
"version": "2.13.
|
|
3
|
+
"version": "2.13.61",
|
|
4
4
|
"description": "Claudeflow — AI-powered development toolkit for Claude Code. Skills, agents, hooks, and quality gates that ship production apps.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"claudeflow": "./bin/cli.js"
|