promptgraph-mcp 2.8.0 → 2.8.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/commands/marketplace.js +4 -1
- package/marketplace.js +14 -4
- package/package.json +1 -1
package/commands/marketplace.js
CHANGED
|
@@ -95,7 +95,10 @@ export default async function handler(args, bin) {
|
|
|
95
95
|
validateAndPruneMarketplace();
|
|
96
96
|
onStatus(true, `Installed ${item.name}`);
|
|
97
97
|
});
|
|
98
|
-
if (r?.error) {
|
|
98
|
+
if (r?.error) {
|
|
99
|
+
if (!r.dedup) onStatus(false, r.error.slice(0, 60));
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
99
102
|
onStatus(null, `Queued ${item.name}…`);
|
|
100
103
|
} else {
|
|
101
104
|
const r = await installSkill(item.code || item.id);
|
package/marketplace.js
CHANGED
|
@@ -425,12 +425,14 @@ export async function installBundle(bundleId) {
|
|
|
425
425
|
const _bgQueue = [];
|
|
426
426
|
let _bgRunning = false;
|
|
427
427
|
let _bgCurrentId = null;
|
|
428
|
+
const _bgPendingKeys = new Set();
|
|
428
429
|
|
|
429
430
|
async function _bgProcess() {
|
|
430
431
|
if (_bgRunning) return;
|
|
431
432
|
_bgRunning = true;
|
|
432
433
|
while (_bgQueue.length > 0) {
|
|
433
|
-
const { bundle, validSkills, onDone } = _bgQueue.shift();
|
|
434
|
+
const { bundle, validSkills, onDone, _dedupKey } = _bgQueue.shift();
|
|
435
|
+
if (_dedupKey) _bgPendingKeys.delete(_dedupKey);
|
|
434
436
|
_bgCurrentId = bundle.id;
|
|
435
437
|
try {
|
|
436
438
|
const result = bundle.repo_url
|
|
@@ -450,15 +452,23 @@ async function _bgProcess() {
|
|
|
450
452
|
// The actual work is serialized through an internal queue.
|
|
451
453
|
// onDone(err, result) is called when the queue finishes processing this bundle.
|
|
452
454
|
export async function installBundleBg(bundleId, onDone) {
|
|
455
|
+
const q = String(bundleId).trim().toLowerCase();
|
|
456
|
+
// Synchronous dedup check BEFORE any await — prevents race on double-Enter
|
|
457
|
+
if (_bgPendingKeys.has(q)) {
|
|
458
|
+
return { dedup: true, error: `"${bundleId}" is already queued or installing` };
|
|
459
|
+
}
|
|
460
|
+
_bgPendingKeys.add(q);
|
|
461
|
+
|
|
453
462
|
const found = await _findBundle(bundleId);
|
|
454
|
-
if (found.error)
|
|
463
|
+
if (found.error) { _bgPendingKeys.delete(q); return found; }
|
|
455
464
|
const { bundle, validSkills } = found;
|
|
456
465
|
|
|
457
466
|
if (_bgCurrentId === bundle.id || _bgQueue.some(e => e.bundle.id === bundle.id)) {
|
|
458
|
-
|
|
467
|
+
_bgPendingKeys.delete(q);
|
|
468
|
+
return { dedup: true, error: `"${bundle.name}" is already queued or installing` };
|
|
459
469
|
}
|
|
460
470
|
|
|
461
|
-
_bgQueue.push({ bundle, validSkills, onDone });
|
|
471
|
+
_bgQueue.push({ bundle, validSkills, onDone, _dedupKey: q });
|
|
462
472
|
_bgProcess();
|
|
463
473
|
return { queued: true, id: bundle.id, name: bundle.name };
|
|
464
474
|
}
|