@floomhq/floom-mcp-sync 1.0.37 → 1.0.38
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/auto-sync.js +7 -3
- package/dist/lib/manifest.js +4 -1
- package/dist/server.js +5 -5
- package/package.json +1 -1
package/dist/auto-sync.js
CHANGED
|
@@ -346,7 +346,7 @@ async function manifestHasMissingTrackedFile(manifest, root) {
|
|
|
346
346
|
}
|
|
347
347
|
return false;
|
|
348
348
|
}
|
|
349
|
-
export async function autoSync(log = (message) => process.stderr.write(`${message}\n`), signal) {
|
|
349
|
+
export async function autoSync(log = (message) => process.stderr.write(`${message}\n`), signal, opts = {}) {
|
|
350
350
|
const initialCfg = await readConfig();
|
|
351
351
|
if (!initialCfg) {
|
|
352
352
|
maybeAuthWarning(log, "[floom] not signed in; skipping sync (run `npx -y @floomhq/floom login`)");
|
|
@@ -354,7 +354,7 @@ export async function autoSync(log = (message) => process.stderr.write(`${messag
|
|
|
354
354
|
}
|
|
355
355
|
let cfg = initialCfg;
|
|
356
356
|
await ensureSyncManifestDir();
|
|
357
|
-
|
|
357
|
+
const result = await withSyncLock(async () => {
|
|
358
358
|
const manifest = await readSyncManifest();
|
|
359
359
|
const root = skillsDir();
|
|
360
360
|
const apiUrl = apiUrlFromConfig(cfg);
|
|
@@ -527,7 +527,11 @@ export async function autoSync(log = (message) => process.stderr.write(`${messag
|
|
|
527
527
|
maybeHeartbeat(log, () => `[floom] heartbeat: ${total} skills tracked, all up-to-date`);
|
|
528
528
|
}
|
|
529
529
|
return { synced: total, unchanged, updated, conflicts };
|
|
530
|
-
});
|
|
530
|
+
}, { wait: !opts.skipIfLocked });
|
|
531
|
+
if (result)
|
|
532
|
+
return result;
|
|
533
|
+
log("[floom] sync already running; skipping background poll");
|
|
534
|
+
return { synced: 0, unchanged: 0, updated: 0, conflicts: 0 };
|
|
531
535
|
}
|
|
532
536
|
async function loadSyncPayload(apiUrl, token, signal) {
|
|
533
537
|
const all = [];
|
package/dist/lib/manifest.js
CHANGED
|
@@ -225,10 +225,11 @@ export async function ensureSyncManifestDir() {
|
|
|
225
225
|
throw err;
|
|
226
226
|
}
|
|
227
227
|
}
|
|
228
|
-
export async function withSyncLock(fn) {
|
|
228
|
+
export async function withSyncLock(fn, opts = {}) {
|
|
229
229
|
await ensureSyncManifestDir();
|
|
230
230
|
const lockPath = join(dirname(syncManifestPath()), "sync.lock");
|
|
231
231
|
const startedAt = Date.now();
|
|
232
|
+
const wait = opts.wait !== false;
|
|
232
233
|
for (;;) {
|
|
233
234
|
try {
|
|
234
235
|
await mkdir(lockPath, { mode: 0o700 });
|
|
@@ -249,6 +250,8 @@ export async function withSyncLock(fn) {
|
|
|
249
250
|
continue;
|
|
250
251
|
throw statErr;
|
|
251
252
|
}
|
|
253
|
+
if (!wait)
|
|
254
|
+
return null;
|
|
252
255
|
if (Date.now() - startedAt > LOCK_TIMEOUT_MS) {
|
|
253
256
|
throw new Error("Timed out waiting for Floom sync lock.");
|
|
254
257
|
}
|
package/dist/server.js
CHANGED
|
@@ -6,19 +6,19 @@ import { clearSyncLock } from "./lib/manifest.js";
|
|
|
6
6
|
import { getSkill } from "./tools/get.js";
|
|
7
7
|
import { searchSkills } from "./tools/search.js";
|
|
8
8
|
import { syncStatus } from "./tools/status.js";
|
|
9
|
-
const SERVER_VERSION = "1.0.
|
|
9
|
+
const SERVER_VERSION = "1.0.38";
|
|
10
10
|
const DEFAULT_INTERVAL_MS = 60_000;
|
|
11
11
|
const MIN_INTERVAL_MS = 10_000;
|
|
12
12
|
const SEARCH_TYPES = new Set(["knowledge", "instruction", "workflow", "skill"]);
|
|
13
13
|
let syncInFlight = null;
|
|
14
14
|
let syncAbortController = null;
|
|
15
15
|
let shuttingDown = false;
|
|
16
|
-
function runAutoSync() {
|
|
16
|
+
function runAutoSync(opts = {}) {
|
|
17
17
|
if (syncInFlight)
|
|
18
18
|
return syncInFlight;
|
|
19
19
|
const controller = new AbortController();
|
|
20
20
|
syncAbortController = controller;
|
|
21
|
-
syncInFlight = autoSync(undefined, controller.signal).finally(() => {
|
|
21
|
+
syncInFlight = autoSync(undefined, controller.signal, opts).finally(() => {
|
|
22
22
|
if (syncAbortController === controller)
|
|
23
23
|
syncAbortController = null;
|
|
24
24
|
syncInFlight = null;
|
|
@@ -114,7 +114,7 @@ function startPolling(intervalMs, state) {
|
|
|
114
114
|
return;
|
|
115
115
|
}
|
|
116
116
|
state.inFlight = true;
|
|
117
|
-
runAutoSync().catch((err) => {
|
|
117
|
+
runAutoSync({ skipIfLocked: true }).catch((err) => {
|
|
118
118
|
process.stderr.write(`[floom] poll failed: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
119
119
|
}).finally(() => {
|
|
120
120
|
state.inFlight = false;
|
|
@@ -293,7 +293,7 @@ async function main() {
|
|
|
293
293
|
const intervalMs = resolvePollIntervalMs();
|
|
294
294
|
process.stderr.write(`[floom] starting sync poller (interval ${intervalMs}ms)\n`);
|
|
295
295
|
const syncState = { inFlight: true };
|
|
296
|
-
void runAutoSync().catch((err) => {
|
|
296
|
+
void runAutoSync({ skipIfLocked: true }).catch((err) => {
|
|
297
297
|
process.stderr.write(`[floom] initial sync failed: ${err instanceof Error ? err.message : String(err)}\n`);
|
|
298
298
|
}).finally(() => {
|
|
299
299
|
syncState.inFlight = false;
|