@ateam-ai/mcp 0.4.40 → 0.4.41
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/tools.js +47 -4
package/package.json
CHANGED
package/src/tools.js
CHANGED
|
@@ -773,7 +773,7 @@ export const tools = [
|
|
|
773
773
|
type: "string",
|
|
774
774
|
enum: ["github", "local"],
|
|
775
775
|
description:
|
|
776
|
-
"Where the solution/skill definition lives.
|
|
776
|
+
"Where the solution/skill definition lives. Omit (DEFAULT) — prefer the tenant's GitHub repo (GitHub is master), but AUTO-DEGRADE to the Builder FS store if the tenant hasn't connected a repo, so a simple def patch always succeeds (it's pushed to GitHub once connected). 'github' — force GitHub; fails loud if not connected (use when you specifically require the repo write). 'local' — force the Builder FS store, no GitHub (repo-less bootstrap tenant). Redeploy is local in all modes.",
|
|
777
777
|
},
|
|
778
778
|
include_definition: {
|
|
779
779
|
type: "boolean",
|
|
@@ -3240,7 +3240,15 @@ const handlers = {
|
|
|
3240
3240
|
// yet connected). GitHub is still master overall; local is a temporary
|
|
3241
3241
|
// bootstrap until the tenant connects a repo (then local is pushed → GitHub).
|
|
3242
3242
|
// Redeploy (Phase 4) is local (Builder FS → Core) in BOTH modes.
|
|
3243
|
-
|
|
3243
|
+
let isLocal = source === "local";
|
|
3244
|
+
// Was a source EXPLICITLY chosen? An unspecified source is the default ("github")
|
|
3245
|
+
// and MAY auto-degrade to local when the tenant hasn't connected a repo — a simple
|
|
3246
|
+
// def patch must work FS-only (Arie's rule: create/patch allowed offline; only
|
|
3247
|
+
// GitHub-native ops refuse). An explicit source:'github' is honored as-is (the
|
|
3248
|
+
// caller asked for GitHub → it fails loud if not connected), and explicit 'local'
|
|
3249
|
+
// stays local.
|
|
3250
|
+
const sourceExplicit = source === "github" || source === "local";
|
|
3251
|
+
let degradedToLocal = false;
|
|
3244
3252
|
|
|
3245
3253
|
// Phase 1: Read current state (or create scaffold if new skill)
|
|
3246
3254
|
let current;
|
|
@@ -3263,8 +3271,39 @@ const handlers = {
|
|
|
3263
3271
|
throw new Error(`Local ${filePath} not found (empty definition)`);
|
|
3264
3272
|
}
|
|
3265
3273
|
} else {
|
|
3266
|
-
|
|
3267
|
-
|
|
3274
|
+
try {
|
|
3275
|
+
const readResult = await get(`/deploy/solutions/${solution_id}/github/read?path=${encodeURIComponent(filePath)}`, sid);
|
|
3276
|
+
current = JSON.parse(readResult.content);
|
|
3277
|
+
} catch (ghErr) {
|
|
3278
|
+
// Auto-degrade a DEFAULT-source patch to the Builder FS when the tenant
|
|
3279
|
+
// hasn't connected GitHub. A github/read failure alone is ambiguous (could
|
|
3280
|
+
// be a wrong solution_id or a transient Core hiccup — both must still fail
|
|
3281
|
+
// loud), so disambiguate with the definitive /github/connected probe and
|
|
3282
|
+
// only degrade on a genuine "not connected". Explicit source:'github' never
|
|
3283
|
+
// degrades. The local write below reconciles to GitHub once connected.
|
|
3284
|
+
let connected = true;
|
|
3285
|
+
if (!sourceExplicit) {
|
|
3286
|
+
try {
|
|
3287
|
+
const probe = await get(`/deploy/solutions/${solution_id}/github/connected`, sid);
|
|
3288
|
+
connected = probe?.connected !== false && probe?.enabled !== false;
|
|
3289
|
+
} catch { connected = true; /* probe failed → don't mask the real read error */ }
|
|
3290
|
+
}
|
|
3291
|
+
if (!sourceExplicit && !connected) {
|
|
3292
|
+
isLocal = true;
|
|
3293
|
+
degradedToLocal = true;
|
|
3294
|
+
const r = target === "skill" && skill_id
|
|
3295
|
+
? await get(`/deploy/solutions/${solution_id}/skills/${encodeURIComponent(skill_id)}`, sid)
|
|
3296
|
+
: await get(`/deploy/solutions/${solution_id}/definition?raw=1`, sid);
|
|
3297
|
+
current = target === "skill" && skill_id
|
|
3298
|
+
? (r.skill || r.definition || r)
|
|
3299
|
+
: (r.solution || r);
|
|
3300
|
+
if (!current || typeof current !== "object") {
|
|
3301
|
+
throw new Error(`Local ${filePath} not found (empty definition)`);
|
|
3302
|
+
}
|
|
3303
|
+
} else {
|
|
3304
|
+
throw ghErr; // connected (real error) or explicit github → surface it
|
|
3305
|
+
}
|
|
3306
|
+
}
|
|
3268
3307
|
}
|
|
3269
3308
|
} catch (err) {
|
|
3270
3309
|
// OPEN-31 guard: only scaffold-create when the skill is GENUINELY ABSENT.
|
|
@@ -3646,6 +3685,10 @@ const handlers = {
|
|
|
3646
3685
|
ok: true,
|
|
3647
3686
|
solution_id,
|
|
3648
3687
|
source: isLocal ? "local" : "github",
|
|
3688
|
+
...(degradedToLocal && {
|
|
3689
|
+
degraded_to_local: true,
|
|
3690
|
+
_degrade_note: `GitHub isn't connected for this tenant, so this patch was saved to the Builder store only (the edit succeeded). It will be pushed to GitHub automatically once the tenant connects a repo (Tenant Admin → GitHub). GitHub-native actions (promote, connector-source patch, github-sourced deploy) will refuse until then.`,
|
|
3691
|
+
}),
|
|
3649
3692
|
...(isLocal ? {} : {
|
|
3650
3693
|
branch: writeBranch,
|
|
3651
3694
|
// Be explicit: a github write lands on `dev`, not prod. The change is
|