@jefuriiij/synthra 0.1.5 → 0.1.7

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.
@@ -1013,7 +1013,7 @@ async function parseRust(f, source) {
1013
1013
  }
1014
1014
 
1015
1015
  // src/scanner/parsers/typescript.ts
1016
- var QUERY12 = `
1016
+ var TS_QUERY = `
1017
1017
  (function_declaration name: (identifier) @function.name) @function
1018
1018
  (class_declaration name: (type_identifier) @class.name) @class
1019
1019
  (interface_declaration name: (type_identifier) @interface.name) @interface
@@ -1023,11 +1023,22 @@ var QUERY12 = `
1023
1023
  (lexical_declaration (variable_declarator name: (identifier) @const-fn.name value: [(arrow_function) (function_expression)])) @const-fn
1024
1024
  (import_statement source: (string) @import)
1025
1025
  `;
1026
+ var JS_QUERY = `
1027
+ (function_declaration name: (identifier) @function.name) @function
1028
+ (class_declaration name: (identifier) @class.name) @class
1029
+ (method_definition name: (property_identifier) @method.name) @method
1030
+ (lexical_declaration (variable_declarator name: (identifier) @const-fn.name value: [(arrow_function) (function_expression)])) @const-fn
1031
+ (import_statement source: (string) @import)
1032
+ (call_expression function: (identifier) @_require_fn arguments: (arguments . (string) @require_source))
1033
+ `;
1026
1034
  function grammarFor(ext) {
1027
1035
  if (ext === ".tsx" || ext === ".jsx") return "tsx";
1028
1036
  if (ext === ".js" || ext === ".cjs" || ext === ".mjs") return "javascript";
1029
1037
  return "typescript";
1030
1038
  }
1039
+ function queryFor(grammar) {
1040
+ return grammar === "javascript" ? JS_QUERY : TS_QUERY;
1041
+ }
1031
1042
  function unquote(s) {
1032
1043
  return s.replace(/^["'`]|["'`]$/g, "");
1033
1044
  }
@@ -1051,7 +1062,7 @@ async function parseTypeScript(f, source) {
1051
1062
  const { parser, language } = await createParser(grammar);
1052
1063
  const tree = parser.parse(source);
1053
1064
  if (!tree) return { file: f, source, symbols, imports, calls: [] };
1054
- const query = language.query(QUERY12);
1065
+ const query = language.query(queryFor(grammar));
1055
1066
  const matches = query.matches(tree.rootNode);
1056
1067
  for (const match of matches) {
1057
1068
  const byName = /* @__PURE__ */ new Map();
@@ -1068,7 +1079,15 @@ async function parseTypeScript(f, source) {
1068
1079
  continue;
1069
1080
  }
1070
1081
  const importNode = byName.get("import");
1071
- if (importNode) imports.push(unquote(importNode.text));
1082
+ if (importNode) {
1083
+ imports.push(unquote(importNode.text));
1084
+ continue;
1085
+ }
1086
+ const requireFn = byName.get("_require_fn");
1087
+ const requireSource = byName.get("require_source");
1088
+ if (requireFn && requireSource && requireFn.text === "require") {
1089
+ imports.push(unquote(requireSource.text));
1090
+ }
1072
1091
  }
1073
1092
  const seen = /* @__PURE__ */ new Set();
1074
1093
  symbols = symbols.filter((s) => {
@@ -1457,6 +1476,12 @@ function policyBlock() {
1457
1476
  "Grep / Glob / Read** \u2014 they are faster, cheaper, and already filtered",
1458
1477
  "to relevant files.",
1459
1478
  "",
1479
+ "> **Tool namespace.** Synthra's MCP tools are exposed as",
1480
+ "> `mcp__synthra__graph_continue`, `mcp__synthra__graph_read`, and",
1481
+ "> `mcp__synthra__graph_register_edit`. Below they are referred to by",
1482
+ "> their short names (`graph_continue` etc.) for readability \u2014 use the",
1483
+ "> full namespaced form when actually invoking them.",
1484
+ "",
1460
1485
  "### Tools",
1461
1486
  "",
1462
1487
  "- **`graph_continue(query)`** \u2014 returns a `Confidence` label, the list",
@@ -1493,8 +1518,11 @@ function policyBlock() {
1493
1518
  "",
1494
1519
  "- **`Confidence: high`** \u2192 Stop. Do NOT Grep, Glob, or further explore",
1495
1520
  " for this query. The graph already has it.",
1496
- "- **`Confidence: medium`** or **`low`** \u2192 You may use Grep / Glob",
1497
- " sparingly, but the PreToolUse hook may still block redundant calls.",
1521
+ "- **`Confidence: medium`** \u2192 Read the listed `Files` directly via",
1522
+ ' `graph_read("file::symbol")` *before* trying Grep. The graph has',
1523
+ " narrowed the search space \u2014 use it, don't bypass it.",
1524
+ "- **`Confidence: low`** \u2192 You may use Grep / Glob, but the PreToolUse",
1525
+ " hook may still block redundant calls.",
1498
1526
  "",
1499
1527
  "### Reading code",
1500
1528
  "",
@@ -1551,8 +1579,16 @@ async function patchClaudeMd(path) {
1551
1579
  }
1552
1580
 
1553
1581
  // src/cli/bootstrap.ts
1554
- var GITIGNORE_MARKER = "# added by synthra";
1555
- var GITIGNORE_ENTRY = ".synthra-graph/";
1582
+ var GITIGNORE_ENTRIES = [
1583
+ {
1584
+ comment: "added by synthra (heavy generated state \u2014 gitignored by design)",
1585
+ entry: ".synthra-graph/"
1586
+ },
1587
+ {
1588
+ comment: "added by synthra \u2014 MCP registration. Remove this line if you want to share the synthra MCP entry with teammates via committed .mcp.json",
1589
+ entry: ".mcp.json"
1590
+ }
1591
+ ];
1556
1592
  async function exists(path) {
1557
1593
  try {
1558
1594
  await stat2(path);
@@ -1572,11 +1608,12 @@ async function patchGitignore(path) {
1572
1608
  existing = await readFile7(path, "utf8");
1573
1609
  } catch {
1574
1610
  }
1575
- const lines = existing.split(/\r?\n/);
1576
- if (lines.some((l) => l.trim() === GITIGNORE_ENTRY)) return false;
1577
- const appendix = (existing.length === 0 || existing.endsWith("\n") ? "" : "\n") + (existing.length ? "\n" : "") + `${GITIGNORE_MARKER}
1578
- ${GITIGNORE_ENTRY}
1579
- `;
1611
+ const trimmed = new Set(existing.split(/\r?\n/).map((l) => l.trim()));
1612
+ const missing = GITIGNORE_ENTRIES.filter((e) => !trimmed.has(e.entry));
1613
+ if (missing.length === 0) return false;
1614
+ const block = missing.map((m) => `# ${m.comment}
1615
+ ${m.entry}`).join("\n") + "\n";
1616
+ const appendix = (existing.length === 0 || existing.endsWith("\n") ? "" : "\n") + (existing.length ? "\n" : "") + block;
1580
1617
  await writeFile3(path, existing + appendix, "utf8");
1581
1618
  return true;
1582
1619
  }