@shuffleio/shuffle-mcps 0.0.46 → 0.0.47

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/dist/index.js CHANGED
@@ -14782,14 +14782,6 @@ var getDiagnosableScope = (parsed) => {
14782
14782
  (d) => d && typeof d === "object" && d.run_details ? d.run_details : null
14783
14783
  );
14784
14784
  if (runDetails.some((rd) => rd !== null)) scope.run_details = runDetails;
14785
- const finalDecisions = parsed.decisions.map((d) => {
14786
- if (!d || typeof d !== "object") return null;
14787
- const action = String(d.action || d.details?.action || "").toLowerCase();
14788
- const category = String(d.category || "").toLowerCase();
14789
- if (!["finish", "finalise"].includes(action) && !["finish", "finalise"].includes(category)) return null;
14790
- return { reason: d.reason };
14791
- });
14792
- if (finalDecisions.some((d) => d !== null)) scope.decisions = finalDecisions;
14793
14785
  }
14794
14786
  if (parsed.decision_string !== void 0) scope.decision_string = parsed.decision_string;
14795
14787
  return Object.keys(scope).length > 0 ? scope : null;
@@ -14804,11 +14796,11 @@ var extractDecisionIndex = (path) => {
14804
14796
  var isAiAuthText = (text) => {
14805
14797
  if (!text || typeof text !== "string") return false;
14806
14798
  const lower = text.toLowerCase();
14807
- const hasAuthSignal = /\b(401|unauthori[sz]ed|invalid[_\s-]*(api[_\s-]*key|credentials?)|incorrect\s+api\s+key|missing[_\s-]*(api[_\s-]*key|authorization)|authentication[_\s-]*(failed|required|error))\b/.test(
14799
+ const hasAuthSignal = /\b(401|unauthori[sz]ed|invalid[_\s-]*(api[_\s-]*key|credentials?|token|auth|key)|incorrect\s+api\s+key|missing[_\s-]*(api[_\s-]*key|authorization|credentials?)|authentication[_\s-]*(failed|required|error)|ai\s+credentials)\b/.test(
14808
14800
  lower
14809
- );
14801
+ ) || /check\s+your\s+ai\s+credentials/.test(lower);
14810
14802
  if (!hasAuthSignal) return false;
14811
- const hasAiSignal = /\b(failed\s+to\s+start\s+ai\s+agent|failed\s+to\s+run\s+ai\s+agent|ai\s+agent\s+(failed|error|crash)|runactionai|llm\s+request|failed\s+to\s+run\s+llm|no\s+llm|openai|anthropic|mistral|groq|deepseek|together\.ai|together\.xyz|openrouter|gemini|googleapis\.com|ollama|lm\s*studio|platform\.openai\.com|api\.openai\.com|local\s*llm)\b/.test(
14803
+ const hasAiSignal = /\b(failed\s+to\s+start\s+ai\s+agent|failed\s+to\s+run\s+ai(\s+(agent|query))?|failed\s+to\s+run\s+ai|ai\s+agent\s+(failed|error|crash|aborted)|ai\s+query|ai\s+credentials|shuffler\.io\/agents|runactionai|llm\s+request|failed\s+to\s+run\s+llm|no\s+llm|openai|anthropic|mistral|groq|deepseek|together\.ai|together\.xyz|openrouter|gemini|googleapis\.com|ollama|lm\s*studio|platform\.openai\.com|api\.openai\.com|local\s*llm)\b/.test(
14812
14804
  lower
14813
14805
  ) || /error\s+from\s+['"][^'"]*(openai|anthropic|mistral|groq|deepseek|together|openrouter|googleapis|ollama|lmstudio)/.test(
14814
14806
  lower
@@ -14874,13 +14866,19 @@ var diagnoseOutputWarning = (run) => {
14874
14866
  const isFinished = (run.status || "").toUpperCase() === "FINISHED";
14875
14867
  const hasSuccessfulFinish = (() => {
14876
14868
  if (!parsed || typeof parsed !== "object") return false;
14869
+ if (parsed.error && String(parsed.error).trim().length > 0) return false;
14870
+ if (parsed.success === false) return false;
14877
14871
  if (Array.isArray(parsed.decisions) && parsed.decisions.length > 0) {
14878
14872
  const last = parsed.decisions[parsed.decisions.length - 1];
14879
14873
  if (last && typeof last === "object") {
14880
14874
  const action = String(last.action || last.details?.action || "").toLowerCase();
14881
14875
  const category = String(last.category || "").toLowerCase();
14882
14876
  if (["finish", "finalise"].includes(action) || ["finish", "finalise"].includes(category)) {
14883
- return last.success !== false;
14877
+ if (last.success === false || last.status === "FAILED") return false;
14878
+ if (isAiAuthText(last.reason) || isAiAuthText(last.output) || isAiAuthText(last.details?.output)) return false;
14879
+ const reasonStr = String(last.reason || "").toLowerCase();
14880
+ if (reasonStr.startsWith("failed to") || reasonStr.includes("error,")) return false;
14881
+ return true;
14884
14882
  }
14885
14883
  }
14886
14884
  }
@@ -14893,17 +14891,22 @@ var diagnoseOutputWarning = (run) => {
14893
14891
  if (typeof parsed.error === "string") candidates.push(parsed.error);
14894
14892
  if (typeof parsed.reason === "string") candidates.push(parsed.reason);
14895
14893
  if (typeof parsed.message === "string") candidates.push(parsed.message);
14894
+ if (typeof parsed.output === "string") candidates.push(parsed.output);
14896
14895
  if (Array.isArray(parsed.decisions)) {
14897
14896
  for (const d of parsed.decisions) {
14898
14897
  if (typeof d?.run_details?.error === "string") candidates.push(d.run_details.error);
14899
- if (d?.success === false || d?.status === "FAILED") {
14900
- if (typeof d?.reason === "string") candidates.push(d.reason);
14901
- if (typeof d?.run_details?.result === "string") candidates.push(d.run_details.result);
14898
+ if (typeof d?.reason === "string") candidates.push(d.reason);
14899
+ if (typeof d?.run_details?.result === "string") candidates.push(d.run_details.result);
14900
+ if (typeof d?.output === "string") candidates.push(d.output);
14901
+ if (Array.isArray(d?.fields)) {
14902
+ for (const f of d.fields) {
14903
+ if (typeof f?.value === "string") candidates.push(f.value);
14904
+ }
14902
14905
  }
14903
14906
  }
14904
14907
  }
14905
14908
  }
14906
- if (raw && (!parsed || !Array.isArray(parsed.decisions) || parsed.decisions.length === 0)) {
14909
+ if (raw) {
14907
14910
  candidates.push(raw);
14908
14911
  }
14909
14912
  return candidates.find((v) => isAiAuthText(v)) || null;
@@ -15159,23 +15162,37 @@ var diagnoseOutputWarning = (run) => {
15159
15162
  var isAiAuthFailure = (run, extraText) => {
15160
15163
  if (isAiAuthText(extraText)) return true;
15161
15164
  if (!run) return false;
15162
- const status = (run.status || "").toUpperCase();
15163
- const isFinished = status === "FINISHED";
15164
- const fail = getFailureInfo(run);
15165
- if (fail && isAiAuthText(fail.reason)) return true;
15166
15165
  const diagnosis = diagnoseOutputWarning(run);
15167
15166
  if (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth) return true;
15168
- if (isFinished) return false;
15169
- const decisions = run?.decisions;
15167
+ const fail = getFailureInfo(run);
15168
+ if (fail && isAiAuthText(fail.reason)) return true;
15169
+ const anyRun = run;
15170
+ if (typeof anyRun.result === "string" && isAiAuthText(anyRun.result)) return true;
15171
+ if (typeof anyRun.output === "string" && isAiAuthText(anyRun.output)) return true;
15172
+ if (typeof anyRun.error === "string" && isAiAuthText(anyRun.error)) return true;
15173
+ if (Array.isArray(run.results)) {
15174
+ for (const r of run.results) {
15175
+ if (typeof r?.result === "string" && isAiAuthText(r.result)) return true;
15176
+ if (typeof r?.error === "string" && isAiAuthText(r.error)) return true;
15177
+ }
15178
+ }
15179
+ const decisions = anyRun?.decisions;
15170
15180
  if (Array.isArray(decisions)) {
15171
15181
  for (const d of decisions) {
15182
+ if (isAiAuthText(d?.reason)) return true;
15183
+ if (typeof d?.output === "string" && isAiAuthText(d.output)) return true;
15172
15184
  if (typeof d?.run_details?.error === "string" && isAiAuthText(d.run_details.error)) return true;
15173
- if (d?.success === false || d?.status === "FAILED") {
15174
- if (isAiAuthText(d?.reason)) return true;
15175
- if (typeof d?.run_details?.result === "string" && isAiAuthText(d.run_details.result)) return true;
15185
+ if (typeof d?.run_details?.result === "string" && isAiAuthText(d.run_details.result)) return true;
15186
+ if (Array.isArray(d?.fields)) {
15187
+ for (const f of d.fields) {
15188
+ if (isAiAuthText(f?.value)) return true;
15189
+ }
15176
15190
  }
15177
15191
  }
15178
15192
  }
15193
+ const status = (run.status || "").toUpperCase();
15194
+ const isFinished = status === "FINISHED";
15195
+ if (isFinished) return false;
15179
15196
  return false;
15180
15197
  };
15181
15198
 
@@ -15307,6 +15324,21 @@ var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, onFocusContinue, exe
15307
15324
  if (status === "FINISHED" && (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth)) {
15308
15325
  return null;
15309
15326
  }
15327
+ if (status === "FINISHED" && diagnosis?.kind === "auth") {
15328
+ const firstEvidence2 = diagnosis?.evidence?.[0] || null;
15329
+ const jumpDecisionIndex2 = firstEvidence2 ? extractDecisionIndex(firstEvidence2.path) : null;
15330
+ if (jumpDecisionIndex2 === null) return null;
15331
+ const { parsed } = parseRunResult(run);
15332
+ const decs = parsed?.decisions || run?.decisions;
15333
+ if (Array.isArray(decs) && decs[jumpDecisionIndex2]) {
15334
+ const d = decs[jumpDecisionIndex2];
15335
+ const action = String(d?.action || d?.details?.action || "").toLowerCase();
15336
+ const category = String(d?.category || "").toLowerCase();
15337
+ if (["finish", "finalise"].includes(action) || ["finish", "finalise"].includes(category)) {
15338
+ return null;
15339
+ }
15340
+ }
15341
+ }
15310
15342
  const isCritical = !!failureInfo || diagnosis?.kind === "token_limit" || diagnosis?.kind === "ai_auth" || Boolean(diagnosis?.isAiAuth);
15311
15343
  const tone = isCritical ? "critical" : "medium";
15312
15344
  const Icon = isCritical ? import_lucide_react13.AlertTriangle : import_lucide_react13.HelpCircle;
@@ -20145,9 +20177,12 @@ var AgentUI = ({
20145
20177
  }
20146
20178
  }, [onChooseLLM]);
20147
20179
  const isAiAuthIssue = (0, import_react23.useMemo)(() => {
20148
- if (finishAnswer && finishAnswer.trim().length > 0) return false;
20180
+ if (finishAnswer && finishAnswer.trim().length > 0 && !isAiAuthText(finishAnswer)) {
20181
+ const diagnosable2 = execution?.results?.length ? execution : agentData;
20182
+ if (!isAiAuthFailure(diagnosable2, error || "")) return false;
20183
+ }
20149
20184
  const diagnosable = execution?.results?.length ? execution : agentData;
20150
- return isAiAuthFailure(diagnosable, error || "");
20185
+ return isAiAuthFailure(diagnosable, error || finishAnswer || "");
20151
20186
  }, [execution, agentData, finishAnswer, error]);
20152
20187
  const aiAuthSuggestionNode = isAiAuthIssue ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_material26.Box, { sx: { mt: 1.5 }, children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(AiAuthSuggestion_default, { onOpenLocalLlm: openLocalLlmArea }) }) : null;
20153
20188
  (0, import_react23.useEffect)(() => {
package/dist/index.mjs CHANGED
@@ -13703,14 +13703,6 @@ var getDiagnosableScope = (parsed) => {
13703
13703
  (d) => d && typeof d === "object" && d.run_details ? d.run_details : null
13704
13704
  );
13705
13705
  if (runDetails.some((rd) => rd !== null)) scope.run_details = runDetails;
13706
- const finalDecisions = parsed.decisions.map((d) => {
13707
- if (!d || typeof d !== "object") return null;
13708
- const action = String(d.action || d.details?.action || "").toLowerCase();
13709
- const category = String(d.category || "").toLowerCase();
13710
- if (!["finish", "finalise"].includes(action) && !["finish", "finalise"].includes(category)) return null;
13711
- return { reason: d.reason };
13712
- });
13713
- if (finalDecisions.some((d) => d !== null)) scope.decisions = finalDecisions;
13714
13706
  }
13715
13707
  if (parsed.decision_string !== void 0) scope.decision_string = parsed.decision_string;
13716
13708
  return Object.keys(scope).length > 0 ? scope : null;
@@ -13725,11 +13717,11 @@ var extractDecisionIndex = (path) => {
13725
13717
  var isAiAuthText = (text) => {
13726
13718
  if (!text || typeof text !== "string") return false;
13727
13719
  const lower = text.toLowerCase();
13728
- const hasAuthSignal = /\b(401|unauthori[sz]ed|invalid[_\s-]*(api[_\s-]*key|credentials?)|incorrect\s+api\s+key|missing[_\s-]*(api[_\s-]*key|authorization)|authentication[_\s-]*(failed|required|error))\b/.test(
13720
+ const hasAuthSignal = /\b(401|unauthori[sz]ed|invalid[_\s-]*(api[_\s-]*key|credentials?|token|auth|key)|incorrect\s+api\s+key|missing[_\s-]*(api[_\s-]*key|authorization|credentials?)|authentication[_\s-]*(failed|required|error)|ai\s+credentials)\b/.test(
13729
13721
  lower
13730
- );
13722
+ ) || /check\s+your\s+ai\s+credentials/.test(lower);
13731
13723
  if (!hasAuthSignal) return false;
13732
- const hasAiSignal = /\b(failed\s+to\s+start\s+ai\s+agent|failed\s+to\s+run\s+ai\s+agent|ai\s+agent\s+(failed|error|crash)|runactionai|llm\s+request|failed\s+to\s+run\s+llm|no\s+llm|openai|anthropic|mistral|groq|deepseek|together\.ai|together\.xyz|openrouter|gemini|googleapis\.com|ollama|lm\s*studio|platform\.openai\.com|api\.openai\.com|local\s*llm)\b/.test(
13724
+ const hasAiSignal = /\b(failed\s+to\s+start\s+ai\s+agent|failed\s+to\s+run\s+ai(\s+(agent|query))?|failed\s+to\s+run\s+ai|ai\s+agent\s+(failed|error|crash|aborted)|ai\s+query|ai\s+credentials|shuffler\.io\/agents|runactionai|llm\s+request|failed\s+to\s+run\s+llm|no\s+llm|openai|anthropic|mistral|groq|deepseek|together\.ai|together\.xyz|openrouter|gemini|googleapis\.com|ollama|lm\s*studio|platform\.openai\.com|api\.openai\.com|local\s*llm)\b/.test(
13733
13725
  lower
13734
13726
  ) || /error\s+from\s+['"][^'"]*(openai|anthropic|mistral|groq|deepseek|together|openrouter|googleapis|ollama|lmstudio)/.test(
13735
13727
  lower
@@ -13795,13 +13787,19 @@ var diagnoseOutputWarning = (run) => {
13795
13787
  const isFinished = (run.status || "").toUpperCase() === "FINISHED";
13796
13788
  const hasSuccessfulFinish = (() => {
13797
13789
  if (!parsed || typeof parsed !== "object") return false;
13790
+ if (parsed.error && String(parsed.error).trim().length > 0) return false;
13791
+ if (parsed.success === false) return false;
13798
13792
  if (Array.isArray(parsed.decisions) && parsed.decisions.length > 0) {
13799
13793
  const last = parsed.decisions[parsed.decisions.length - 1];
13800
13794
  if (last && typeof last === "object") {
13801
13795
  const action = String(last.action || last.details?.action || "").toLowerCase();
13802
13796
  const category = String(last.category || "").toLowerCase();
13803
13797
  if (["finish", "finalise"].includes(action) || ["finish", "finalise"].includes(category)) {
13804
- return last.success !== false;
13798
+ if (last.success === false || last.status === "FAILED") return false;
13799
+ if (isAiAuthText(last.reason) || isAiAuthText(last.output) || isAiAuthText(last.details?.output)) return false;
13800
+ const reasonStr = String(last.reason || "").toLowerCase();
13801
+ if (reasonStr.startsWith("failed to") || reasonStr.includes("error,")) return false;
13802
+ return true;
13805
13803
  }
13806
13804
  }
13807
13805
  }
@@ -13814,17 +13812,22 @@ var diagnoseOutputWarning = (run) => {
13814
13812
  if (typeof parsed.error === "string") candidates.push(parsed.error);
13815
13813
  if (typeof parsed.reason === "string") candidates.push(parsed.reason);
13816
13814
  if (typeof parsed.message === "string") candidates.push(parsed.message);
13815
+ if (typeof parsed.output === "string") candidates.push(parsed.output);
13817
13816
  if (Array.isArray(parsed.decisions)) {
13818
13817
  for (const d of parsed.decisions) {
13819
13818
  if (typeof d?.run_details?.error === "string") candidates.push(d.run_details.error);
13820
- if (d?.success === false || d?.status === "FAILED") {
13821
- if (typeof d?.reason === "string") candidates.push(d.reason);
13822
- if (typeof d?.run_details?.result === "string") candidates.push(d.run_details.result);
13819
+ if (typeof d?.reason === "string") candidates.push(d.reason);
13820
+ if (typeof d?.run_details?.result === "string") candidates.push(d.run_details.result);
13821
+ if (typeof d?.output === "string") candidates.push(d.output);
13822
+ if (Array.isArray(d?.fields)) {
13823
+ for (const f of d.fields) {
13824
+ if (typeof f?.value === "string") candidates.push(f.value);
13825
+ }
13823
13826
  }
13824
13827
  }
13825
13828
  }
13826
13829
  }
13827
- if (raw && (!parsed || !Array.isArray(parsed.decisions) || parsed.decisions.length === 0)) {
13830
+ if (raw) {
13828
13831
  candidates.push(raw);
13829
13832
  }
13830
13833
  return candidates.find((v) => isAiAuthText(v)) || null;
@@ -14080,23 +14083,37 @@ var diagnoseOutputWarning = (run) => {
14080
14083
  var isAiAuthFailure = (run, extraText) => {
14081
14084
  if (isAiAuthText(extraText)) return true;
14082
14085
  if (!run) return false;
14083
- const status = (run.status || "").toUpperCase();
14084
- const isFinished = status === "FINISHED";
14085
- const fail = getFailureInfo(run);
14086
- if (fail && isAiAuthText(fail.reason)) return true;
14087
14086
  const diagnosis = diagnoseOutputWarning(run);
14088
14087
  if (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth) return true;
14089
- if (isFinished) return false;
14090
- const decisions = run?.decisions;
14088
+ const fail = getFailureInfo(run);
14089
+ if (fail && isAiAuthText(fail.reason)) return true;
14090
+ const anyRun = run;
14091
+ if (typeof anyRun.result === "string" && isAiAuthText(anyRun.result)) return true;
14092
+ if (typeof anyRun.output === "string" && isAiAuthText(anyRun.output)) return true;
14093
+ if (typeof anyRun.error === "string" && isAiAuthText(anyRun.error)) return true;
14094
+ if (Array.isArray(run.results)) {
14095
+ for (const r of run.results) {
14096
+ if (typeof r?.result === "string" && isAiAuthText(r.result)) return true;
14097
+ if (typeof r?.error === "string" && isAiAuthText(r.error)) return true;
14098
+ }
14099
+ }
14100
+ const decisions = anyRun?.decisions;
14091
14101
  if (Array.isArray(decisions)) {
14092
14102
  for (const d of decisions) {
14103
+ if (isAiAuthText(d?.reason)) return true;
14104
+ if (typeof d?.output === "string" && isAiAuthText(d.output)) return true;
14093
14105
  if (typeof d?.run_details?.error === "string" && isAiAuthText(d.run_details.error)) return true;
14094
- if (d?.success === false || d?.status === "FAILED") {
14095
- if (isAiAuthText(d?.reason)) return true;
14096
- if (typeof d?.run_details?.result === "string" && isAiAuthText(d.run_details.result)) return true;
14106
+ if (typeof d?.run_details?.result === "string" && isAiAuthText(d.run_details.result)) return true;
14107
+ if (Array.isArray(d?.fields)) {
14108
+ for (const f of d.fields) {
14109
+ if (isAiAuthText(f?.value)) return true;
14110
+ }
14097
14111
  }
14098
14112
  }
14099
14113
  }
14114
+ const status = (run.status || "").toUpperCase();
14115
+ const isFinished = status === "FINISHED";
14116
+ if (isFinished) return false;
14100
14117
  return false;
14101
14118
  };
14102
14119
 
@@ -14228,6 +14245,21 @@ var AgentRunDiagnosisBanner = ({ run, sx, onJumpToEvidence, onFocusContinue, exe
14228
14245
  if (status === "FINISHED" && (diagnosis?.kind === "ai_auth" || diagnosis?.isAiAuth)) {
14229
14246
  return null;
14230
14247
  }
14248
+ if (status === "FINISHED" && diagnosis?.kind === "auth") {
14249
+ const firstEvidence2 = diagnosis?.evidence?.[0] || null;
14250
+ const jumpDecisionIndex2 = firstEvidence2 ? extractDecisionIndex(firstEvidence2.path) : null;
14251
+ if (jumpDecisionIndex2 === null) return null;
14252
+ const { parsed } = parseRunResult(run);
14253
+ const decs = parsed?.decisions || run?.decisions;
14254
+ if (Array.isArray(decs) && decs[jumpDecisionIndex2]) {
14255
+ const d = decs[jumpDecisionIndex2];
14256
+ const action = String(d?.action || d?.details?.action || "").toLowerCase();
14257
+ const category = String(d?.category || "").toLowerCase();
14258
+ if (["finish", "finalise"].includes(action) || ["finish", "finalise"].includes(category)) {
14259
+ return null;
14260
+ }
14261
+ }
14262
+ }
14231
14263
  const isCritical = !!failureInfo || diagnosis?.kind === "token_limit" || diagnosis?.kind === "ai_auth" || Boolean(diagnosis?.isAiAuth);
14232
14264
  const tone = isCritical ? "critical" : "medium";
14233
14265
  const Icon = isCritical ? AlertTriangle2 : HelpCircle;
@@ -19066,9 +19098,12 @@ var AgentUI = ({
19066
19098
  }
19067
19099
  }, [onChooseLLM]);
19068
19100
  const isAiAuthIssue = useMemo10(() => {
19069
- if (finishAnswer && finishAnswer.trim().length > 0) return false;
19101
+ if (finishAnswer && finishAnswer.trim().length > 0 && !isAiAuthText(finishAnswer)) {
19102
+ const diagnosable2 = execution?.results?.length ? execution : agentData;
19103
+ if (!isAiAuthFailure(diagnosable2, error || "")) return false;
19104
+ }
19070
19105
  const diagnosable = execution?.results?.length ? execution : agentData;
19071
- return isAiAuthFailure(diagnosable, error || "");
19106
+ return isAiAuthFailure(diagnosable, error || finishAnswer || "");
19072
19107
  }, [execution, agentData, finishAnswer, error]);
19073
19108
  const aiAuthSuggestionNode = isAiAuthIssue ? /* @__PURE__ */ jsx31(Box22, { sx: { mt: 1.5 }, children: /* @__PURE__ */ jsx31(AiAuthSuggestion_default, { onOpenLocalLlm: openLocalLlmArea }) }) : null;
19074
19109
  useEffect17(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shuffleio/shuffle-mcps",
3
- "version": "0.0.46",
3
+ "version": "0.0.47",
4
4
  "description": "Turn 3,000+ SaaS tools into MCP servers your agents can use. Headless React component for search, selection, and OAuth handoff.",
5
5
  "license": "MIT",
6
6
  "repository": {