@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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/tools.js +47 -4
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ateam-ai/mcp",
3
- "version": "0.4.40",
3
+ "version": "0.4.41",
4
4
  "mcpName": "io.github.ariekogan/ateam-mcp",
5
5
  "description": "A-Team MCP Server — build, validate, and deploy multi-agent solutions from any AI environment",
6
6
  "type": "module",
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. 'github' (DEFAULT) — read from and write to the tenant's GitHub repo (GitHub is master; the normal path). 'local' read from and write to the Builder FS store (no GitHub repo required). Use 'local' ONLY for a repo-less bootstrap tenant (e.g. freshly onboarded from a template, before GitHub is connected). This is a DEDICATED, EXPLICIT switch never a fallback. Redeploy is local in both modes.",
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
- const isLocal = source === "local";
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
- const readResult = await get(`/deploy/solutions/${solution_id}/github/read?path=${encodeURIComponent(filePath)}`, sid);
3267
- current = JSON.parse(readResult.content);
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