@ateam-ai/mcp 0.4.36 → 0.4.37
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/package.json +1 -1
- package/src/api.js +6 -1
- package/src/tools.js +44 -4
package/package.json
CHANGED
package/src/api.js
CHANGED
|
@@ -520,7 +520,12 @@ async function request(method, path, body, sessionId, opts = {}) {
|
|
|
520
520
|
|
|
521
521
|
if (!res.ok) {
|
|
522
522
|
const text = await res.text().catch(() => "");
|
|
523
|
-
|
|
523
|
+
// Attach the HTTP status so callers can distinguish a genuine 404
|
|
524
|
+
// (resource absent) from a transient/5xx failure. ateam_patch relies
|
|
525
|
+
// on this to NOT scaffold-clobber an existing skill on a read error.
|
|
526
|
+
const e = new Error(formatError(method, path, res.status, text, baseUrl));
|
|
527
|
+
e.status = res.status;
|
|
528
|
+
throw e;
|
|
524
529
|
}
|
|
525
530
|
|
|
526
531
|
return res.json();
|
package/src/tools.js
CHANGED
|
@@ -3261,11 +3261,51 @@ const handlers = {
|
|
|
3261
3261
|
current = JSON.parse(readResult.content);
|
|
3262
3262
|
}
|
|
3263
3263
|
} catch (err) {
|
|
3264
|
-
//
|
|
3265
|
-
//
|
|
3266
|
-
//
|
|
3264
|
+
// OPEN-31 guard: only scaffold-create when the skill is GENUINELY ABSENT.
|
|
3265
|
+
// The old code scaffolded on ANY read error, so a transient github/read
|
|
3266
|
+
// failure (fetch failed, 5xx, parse error) silently OVERWROTE a full
|
|
3267
|
+
// deployed skill with a bare scaffold on the next write — total data loss.
|
|
3268
|
+
//
|
|
3269
|
+
// A genuine "doesn't exist" is a 404 (or the local empty-definition throw).
|
|
3270
|
+
// Anything else = the store is unreachable/broken → FAIL LOUD, never write.
|
|
3271
|
+
const notFound = err.status === 404 || /not found \(empty definition\)/i.test(err.message || "");
|
|
3272
|
+
if (target === "skill" && skill_id && !notFound) {
|
|
3273
|
+
return {
|
|
3274
|
+
ok: false, phase: "read",
|
|
3275
|
+
error: `Refusing to patch "${skill_id}": could not read its current definition from ${isLocal ? "the Builder store" : "GitHub"} (${err.message}). This is NOT a "skill doesn't exist" error (that would be a 404) — scaffolding now could DESTROY the existing definition. Retry once the store is reachable, or check ateam_get_solution(solution_id, skill_id).`,
|
|
3276
|
+
phases,
|
|
3277
|
+
};
|
|
3278
|
+
}
|
|
3279
|
+
// Even on a real 404, the skill may exist in the OTHER source (deployed to
|
|
3280
|
+
// the Builder store but not pushed to GitHub, or vice versa). Scaffolding
|
|
3281
|
+
// then would destroy/diverge that real def — cross-check before creating.
|
|
3282
|
+
if (target === "skill" && skill_id) {
|
|
3283
|
+
let otherDef = null;
|
|
3284
|
+
try {
|
|
3285
|
+
const other = isLocal
|
|
3286
|
+
? JSON.parse((await get(`/deploy/solutions/${solution_id}/github/read?path=${encodeURIComponent(filePath)}`, sid)).content)
|
|
3287
|
+
: await get(`/deploy/solutions/${solution_id}/skills/${encodeURIComponent(skill_id)}`, sid);
|
|
3288
|
+
otherDef = other?.skill || other?.definition || other;
|
|
3289
|
+
} catch { otherDef = null; /* absent in the other source too → truly new */ }
|
|
3290
|
+
const otherIsReal = otherDef && typeof otherDef === "object" && (
|
|
3291
|
+
(Array.isArray(otherDef.tools) && otherDef.tools.length > 0) ||
|
|
3292
|
+
(Array.isArray(otherDef.connectors) && otherDef.connectors.length > 0) ||
|
|
3293
|
+
otherDef.voice_native || otherDef.ui_plugins ||
|
|
3294
|
+
(otherDef.role && otherDef.role.persona)
|
|
3295
|
+
);
|
|
3296
|
+
if (otherIsReal) {
|
|
3297
|
+
return {
|
|
3298
|
+
ok: false, phase: "read",
|
|
3299
|
+
error: `Refusing to patch "${skill_id}": it was not found in ${isLocal ? "the Builder store" : "GitHub"}, but a full definition EXISTS in ${isLocal ? "GitHub" : "the Builder store"}. Scaffold-creating here would destroy/diverge it. Sync the two first (ateam_redeploy / ateam_verify_consistency), then retry — do NOT patch-create over an existing skill.`,
|
|
3300
|
+
phases,
|
|
3301
|
+
};
|
|
3302
|
+
}
|
|
3303
|
+
}
|
|
3304
|
+
// If it's a skill that GENUINELY doesn't exist (404 in the primary source
|
|
3305
|
+
// AND absent from the other), create a default scaffold. This lets agents
|
|
3306
|
+
// use ateam_patch to both CREATE and UPDATE skills — no separate step.
|
|
3267
3307
|
if (target === "skill" && skill_id) {
|
|
3268
|
-
console.log(`[ateam_patch] Skill "${skill_id}"
|
|
3308
|
+
console.log(`[ateam_patch] Skill "${skill_id}" genuinely absent (404, both sources) — creating new skill scaffold`);
|
|
3269
3309
|
isNewSkill = true;
|
|
3270
3310
|
current = {
|
|
3271
3311
|
id: skill_id,
|