@ateam-ai/mcp 0.4.46 → 0.4.48

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 +59 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ateam-ai/mcp",
3
- "version": "0.4.46",
3
+ "version": "0.4.48",
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
@@ -795,7 +795,8 @@ export const tools = [
795
795
  "- Add a tool: updates: { \"tools_push\": [{ name: \"conn.tool\", description: \"...\", inputs: [...], output: {...} }] }\n" +
796
796
  "- Change intent: updates: { \"intents.supported_update\": [{ id: \"i1\", description: \"new desc\" }] }\n" +
797
797
  "- CREATE a new skill: target='skill', skill_id='my-new-skill', updates: { \"problem.statement\": \"...\", \"role.persona\": \"...\" } — auto-scaffolded and added to solution topology.\n\n" +
798
- "PREVIEW BEFORE WRITING: pass dry_run:true to see the diff (arrays_merged, arrays_replaced, dropped_ids, added_ids) without applying. Use this before any destructive-looking edit.",
798
+ "PREVIEW BEFORE WRITING: pass dry_run:true to see the diff (arrays_merged, arrays_replaced, dropped_ids, added_ids) without applying. Use this before any destructive-looking edit.\n\n" +
799
+ "VERDICT (skill target): the response carries a NON-BLOCKING `validation` block { skill_id, valid, ready_to_export, error_count, incomplete_sections[], unresolved_refs } — the patch always saves even if the def is now invalid, so CHECK valid: false and fix incomplete_sections before relying on it (build_and_run will refuse to deploy an invalid skill). error_count can include auto-import connector-tool artifacts, so act on incomplete_sections first.",
799
800
  inputSchema: {
800
801
  type: "object",
801
802
  properties: {
@@ -2168,6 +2169,20 @@ function _scaffoldConnectorFiles({ connectorId, displayName, uiCapable }) {
2168
2169
  //
2169
2170
  // Fill in your real tools below (see TOOLS + the tools/call dispatch). The
2170
2171
  // JSON-RPC framing, actor isolation, stdio loop${uiCapable ? ", and ui-dist plugin discovery" : ""} are template-provided.
2172
+ //
2173
+ // ⚠️ NEVER SWALLOW A FAILURE. If something this tool depends on fails — a fetch,
2174
+ // a platform call, a store read — RETURN THE ERROR. Do not catch it and answer
2175
+ // with empty data:
2176
+ //
2177
+ // BAD: try { rows = await load(); } catch { rows = []; } // renders 0.00 forever
2178
+ // GOOD: try { rows = await load(); }
2179
+ // catch (e) { return toText({ ok: false, error: String(e.message || e) }); }
2180
+ //
2181
+ // A tool that returns ok:true with an empty result when its dependency is broken
2182
+ // is INDISTINGUISHABLE from one that genuinely has no data — to the widget, to
2183
+ // the person reading the screen, and to the agent trying to fix it. That exact
2184
+ // shape cost a full day: a connector caught a 401, returned an empty ledger, and
2185
+ // the dashboard showed 0.00 while every check reported success.
2171
2186
  ${uiCapable ? `
2172
2187
  import { readdirSync, readFileSync, existsSync } from "node:fs";
2173
2188
  import { fileURLToPath } from "node:url";
@@ -3817,6 +3832,46 @@ const handlers = {
3817
3832
  } catch { /* advisory — never downgrade a successful patch on the health check */ }
3818
3833
  }
3819
3834
 
3835
+ // Phase 5: validation verdict (skill target only). NON-BLOCKING — "silent is
3836
+ // the bug": a patch that leaves the definition invalid used to return ok:true
3837
+ // with NO verdict, so an agent (or a persona routing here as the "cheapest
3838
+ // correct tool") never saw it went red, and an invalid def slipped toward
3839
+ // Core (build_and_run refuses on errors, but the patch path reported nothing).
3840
+ // Report the verdict keyed by skill_id; never block. error_count can be
3841
+ // inflated by auto-imported connector tools (INVALID_TOOL_INPUTS /
3842
+ // MISSING_TOOL_OUTPUT fire on every solution because Core resolves their
3843
+ // contract at deploy, not the author) — so lead with the author-facing
3844
+ // signal: which sections are still incomplete, plus any unresolved refs.
3845
+ let validation = null;
3846
+ if (target === "skill" && skill_id) {
3847
+ try {
3848
+ const vr = await get(`/deploy/solutions/${solution_id}/skills/${encodeURIComponent(skill_id)}/validation`, sid);
3849
+ const v = vr?.validation || vr || {};
3850
+ const incomplete_sections = Object.entries(v.sections || {})
3851
+ .filter(([, s]) => s && s.complete === false)
3852
+ .map(([name]) => name);
3853
+ const unresolved = Object.entries(v.unresolved_refs || {}).filter(([, n]) => Number(n) > 0);
3854
+ validation = {
3855
+ skill_id,
3856
+ valid: v.valid === true,
3857
+ ready_to_export: v.ready_to_export === true,
3858
+ error_count: v.error_count ?? null,
3859
+ warning_count: v.warning_count ?? null,
3860
+ ...(incomplete_sections.length && { incomplete_sections }),
3861
+ ...(unresolved.length && { unresolved_refs: Object.fromEntries(unresolved) }),
3862
+ ...(v.error_count > 0 && {
3863
+ _note: `error_count can include auto-import connector-tool artifacts — INVALID_TOOL_INPUTS / MISSING_TOOL_OUTPUT fire on every solution because Core resolves an auto-imported tool's contract at deploy, not the author. Act on incomplete_sections${unresolved.length ? " + unresolved_refs" : ""} first.`,
3864
+ }),
3865
+ ...(v.valid === false && {
3866
+ _verdict: `Skill "${skill_id}" is INVALID — the patch was still saved + redeployed (non-blocking), but build_and_run will REFUSE to deploy while errors stand. Fix the above, then re-check.`,
3867
+ }),
3868
+ };
3869
+ } catch { /* advisory — a validation hiccup never downgrades a saved patch */ }
3870
+ }
3871
+ const validationStatus = (validation && validation.valid === false)
3872
+ ? ` ⚠️ Skill "${skill_id}" is INVALID (${validation.error_count ?? "?"} error(s)) — see validation (non-blocking; build_and_run will refuse until fixed).`
3873
+ : "";
3874
+
3820
3875
  return {
3821
3876
  ok: true,
3822
3877
  solution_id,
@@ -3846,13 +3901,14 @@ const handlers = {
3846
3901
  }),
3847
3902
  ...(isNewSkill && { created_skill: skill_id }),
3848
3903
  ...(redeployResult && { redeploy: redeployResult }),
3904
+ ...(validation && { validation }),
3849
3905
  ...(widget_health && { widget_health }),
3850
3906
  ...(test_result && { test_result }),
3851
- _status: redeployOk
3907
+ _status: (redeployOk
3852
3908
  ? (widget_health && !widget_health.ok
3853
3909
  ? `✅ Patched on ${store} + redeployed. ⚠️ ${widget_health.issues?.length || 0} widget(s) not rendering — see widget_health.`
3854
3910
  : `✅ Patched on ${store} + redeployed.`)
3855
- : `⚠️ Patched on ${store} ✅ but redeploy timed out. Run: ateam_redeploy(solution_id` + (skill_id ? `, skill_id: "${skill_id}"` : '') + ')',
3911
+ : `⚠️ Patched on ${store} ✅ but redeploy timed out. Run: ateam_redeploy(solution_id` + (skill_id ? `, skill_id: "${skill_id}"` : '') + ')') + validationStatus,
3856
3912
  _next: isLocal
3857
3913
  ? 'Local edit saved + redeployed. When the tenant connects a GitHub repo, the local state is pushed → GitHub (which then becomes master).'
3858
3914
  : 'Create a checkpoint before making more changes: ateam_github_promote(solution_id)',