oscar64-mcp-docs 1.0.4 → 1.0.6

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/dist/stdio.js +83 -11
  2. package/package.json +7 -4
package/dist/stdio.js CHANGED
@@ -1454,7 +1454,67 @@ var StateUnavailableError = class extends Error {
1454
1454
  }
1455
1455
  };
1456
1456
  function isStateUnavailableError(error) {
1457
- return error instanceof StateUnavailableError;
1457
+ if (error instanceof StateUnavailableError) return true;
1458
+ if (!error || typeof error !== "object") return false;
1459
+ const name = String(error.name ?? "");
1460
+ const message = String(error.message ?? "");
1461
+ return name === "StateUnavailableError" || /source state unavailable/i.test(message);
1462
+ }
1463
+ function unwrapCause(error) {
1464
+ if (!error || typeof error !== "object") return void 0;
1465
+ return error.cause;
1466
+ }
1467
+ function collectErrorSignals(error) {
1468
+ const messages = [];
1469
+ const codes = [];
1470
+ let current = error;
1471
+ for (let depth = 0; depth < 3 && current; depth += 1) {
1472
+ if (typeof current === "object") {
1473
+ const message = String(current.message ?? "").trim();
1474
+ const code = String(current.code ?? "").trim();
1475
+ if (message) messages.push(message);
1476
+ if (code) codes.push(code);
1477
+ current = unwrapCause(current);
1478
+ continue;
1479
+ }
1480
+ messages.push(String(current));
1481
+ break;
1482
+ }
1483
+ return { messages, codes };
1484
+ }
1485
+ function isOperationalOfflineError(error) {
1486
+ if (isStateUnavailableError(error)) return true;
1487
+ const { messages, codes } = collectErrorSignals(error);
1488
+ const joined = messages.join(" | ").toLowerCase();
1489
+ const upperCodes = codes.map((code) => code.toUpperCase());
1490
+ const networkOrFsCodes = /* @__PURE__ */ new Set([
1491
+ "EAI_AGAIN",
1492
+ "ENOTFOUND",
1493
+ "ENETUNREACH",
1494
+ "ECONNREFUSED",
1495
+ "ECONNRESET",
1496
+ "ETIMEDOUT",
1497
+ "ENOENT",
1498
+ "ENOTDIR",
1499
+ "EACCES",
1500
+ "EPERM"
1501
+ ]);
1502
+ if (upperCodes.some((code) => networkOrFsCodes.has(code))) return true;
1503
+ if (joined.includes("fetch failed")) return true;
1504
+ if (joined.includes("http 4") || joined.includes("http 5")) return true;
1505
+ if (joined.includes("timeout waiting for repo lock")) return true;
1506
+ if (joined.includes("source state unavailable")) return true;
1507
+ if (joined.includes("no such file or directory")) return true;
1508
+ if (joined.includes("permission denied")) return true;
1509
+ return false;
1510
+ }
1511
+ function toErrorHintSuffix(error) {
1512
+ const { messages, codes } = collectErrorSignals(error);
1513
+ const message = messages.find((value) => value.length > 0) ?? "";
1514
+ const code = codes.find((value) => value.length > 0) ?? "";
1515
+ const compact = [code, message].filter(Boolean).join(": ").slice(0, 220);
1516
+ if (!compact) return "";
1517
+ return ` Root cause: ${compact}`;
1458
1518
  }
1459
1519
  function getStateSnapshotSync() {
1460
1520
  return latestState;
@@ -1561,17 +1621,21 @@ var listIndexesTool = createTool({
1561
1621
  description: "List topic/tutorial/sample entries with concrete docs:// or code:// URIs.",
1562
1622
  inputSchema: listIndexesInputSchema,
1563
1623
  outputSchema: listIndexesOutputSchema,
1564
- execute: async ({ context }) => {
1624
+ execute: async (input) => {
1625
+ const context = input?.context ?? input;
1565
1626
  try {
1566
1627
  return await executeListIndexes(context);
1567
1628
  } catch (error) {
1568
- if (isStateUnavailableError(error)) {
1629
+ if (process.env.OSCAR_MCP_DEBUG_ERRORS === "1") {
1630
+ console.error("[oscar64-mcp-docs] list_indexes error:", error);
1631
+ }
1632
+ if (isOperationalOfflineError(error)) {
1569
1633
  return {
1570
1634
  ok: false,
1571
1635
  error: {
1572
1636
  code: "OFFLINE",
1573
1637
  message: "list_indexes unavailable while sources are offline.",
1574
- hint: "Ensure network access to GitHub or warm cache under ~/.cache/oscar-mcp, then retry.",
1638
+ hint: `Ensure network access to GitHub or warm cache under ~/.cache/oscar-mcp, then retry.${toErrorHintSuffix(error)}`,
1575
1639
  recoverable: true
1576
1640
  }
1577
1641
  };
@@ -1595,7 +1659,7 @@ import { createTool as createTool2 } from "@mastra/core/tools";
1595
1659
  async function readResourceUriFromState(uri) {
1596
1660
  const state = await getStateSnapshot();
1597
1661
  const resources = makeResources(() => state);
1598
- const content = await resources.getResourceContent({ uri });
1662
+ const content = await resources.getResourceContent({ uri, extra: {} });
1599
1663
  const toText = (item) => {
1600
1664
  if (typeof item?.text === "string") return item.text;
1601
1665
  if (typeof item?.blob === "string") return item.blob;
@@ -1721,17 +1785,21 @@ var readUriTool = createTool2({
1721
1785
  description: "Read text or binary content for supported resource/file URIs (typically from search results).",
1722
1786
  inputSchema: readUriInputSchema,
1723
1787
  outputSchema: readUriOutputSchema,
1724
- execute: async ({ context }) => {
1788
+ execute: async (input) => {
1789
+ const context = input?.context ?? input;
1725
1790
  try {
1726
1791
  return await executeReadUri(context);
1727
1792
  } catch (error) {
1728
- if (isStateUnavailableError(error)) {
1793
+ if (process.env.OSCAR_MCP_DEBUG_ERRORS === "1") {
1794
+ console.error("[oscar64-mcp-docs] read_uri error:", error);
1795
+ }
1796
+ if (isOperationalOfflineError(error)) {
1729
1797
  return {
1730
1798
  ok: false,
1731
1799
  error: {
1732
1800
  code: "OFFLINE",
1733
1801
  message: "read_uri unavailable while sources are offline.",
1734
- hint: "Ensure network access to GitHub or warm cache under ~/.cache/oscar-mcp, then retry.",
1802
+ hint: `Ensure network access to GitHub or warm cache under ~/.cache/oscar-mcp, then retry.${toErrorHintSuffix(error)}`,
1735
1803
  recoverable: true
1736
1804
  }
1737
1805
  };
@@ -2137,17 +2205,21 @@ var searchTool = createTool3({
2137
2205
  description: "Unified search across manual and code sources with ranked results.",
2138
2206
  inputSchema: searchInputSchema,
2139
2207
  outputSchema: searchOutputSchema,
2140
- execute: async ({ context }) => {
2208
+ execute: async (input) => {
2209
+ const context = input?.context ?? input;
2141
2210
  try {
2142
2211
  return await executeSearch(context);
2143
2212
  } catch (error) {
2144
- if (isStateUnavailableError(error)) {
2213
+ if (process.env.OSCAR_MCP_DEBUG_ERRORS === "1") {
2214
+ console.error("[oscar64-mcp-docs] search error:", error);
2215
+ }
2216
+ if (isOperationalOfflineError(error)) {
2145
2217
  return {
2146
2218
  ok: false,
2147
2219
  error: {
2148
2220
  code: "OFFLINE",
2149
2221
  message: "Search unavailable while sources are offline.",
2150
- hint: "Ensure network access to GitHub or warm cache under ~/.cache/oscar-mcp, then retry.",
2222
+ hint: `Ensure network access to GitHub or warm cache under ~/.cache/oscar-mcp, then retry.${toErrorHintSuffix(error)}`,
2151
2223
  recoverable: true
2152
2224
  }
2153
2225
  };
package/package.json CHANGED
@@ -1,8 +1,11 @@
1
1
  {
2
2
  "name": "oscar64-mcp-docs",
3
- "version": "1.0.4",
3
+ "version": "1.0.6",
4
4
  "private": false,
5
5
  "type": "module",
6
+ "engines": {
7
+ "node": ">=22.13.0"
8
+ },
6
9
  "files": [
7
10
  "dist",
8
11
  "README.md"
@@ -26,15 +29,15 @@
26
29
  "test:watch": "vitest"
27
30
  },
28
31
  "dependencies": {
29
- "@mastra/core": "^1.9.0",
30
- "@mastra/mcp": "^1.0.3",
32
+ "@mastra/core": "^1.10.0",
33
+ "@mastra/mcp": "^1.1.0",
31
34
  "adm-zip": "^0.5.16",
32
35
  "minisearch": "^7.1.1",
33
36
  "zod": "^3.23.8"
34
37
  },
35
38
  "devDependencies": {
36
39
  "@types/adm-zip": "^0.5.5",
37
- "mastra": "^1.3.6",
40
+ "mastra": "^1.3.7",
38
41
  "tsup": "^8.3.5",
39
42
  "tsx": "^4.19.2",
40
43
  "typescript": "^5.6.3",