composto-ai 0.7.0 → 0.7.1
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 +54 -24
- package/dist/mcp/server.js +58 -24
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -843,8 +843,9 @@ function emitTier1(node) {
|
|
|
843
843
|
const outPrefix = exported ? "OUT " : "";
|
|
844
844
|
switch (node.type) {
|
|
845
845
|
case "import_statement": {
|
|
846
|
-
const
|
|
847
|
-
return `USE:${
|
|
846
|
+
const source = node.childForFieldName("source")?.text;
|
|
847
|
+
if (source) return `USE:${source.slice(1, -1)}`;
|
|
848
|
+
return `USE:${collapseText(node.text, 80)}`;
|
|
848
849
|
}
|
|
849
850
|
case "function_declaration": {
|
|
850
851
|
const name = node.childForFieldName("name")?.text ?? "anonymous";
|
|
@@ -974,9 +975,30 @@ function emitTier3(node) {
|
|
|
974
975
|
}
|
|
975
976
|
if (node.parent?.type === "statement_block") return null;
|
|
976
977
|
const vt = value.type;
|
|
977
|
-
if (vt === "number" || vt === "true" || vt === "false")
|
|
978
|
-
|
|
979
|
-
|
|
978
|
+
if (vt === "number" || vt === "true" || vt === "false") {
|
|
979
|
+
return `VAR:${name} = ${value.text}`;
|
|
980
|
+
}
|
|
981
|
+
if (vt === "array") {
|
|
982
|
+
return `VAR:${name}[${value.namedChildCount}]`;
|
|
983
|
+
}
|
|
984
|
+
if (vt === "object") {
|
|
985
|
+
const keys = [];
|
|
986
|
+
for (let i = 0; i < value.namedChildCount; i++) {
|
|
987
|
+
const member = value.namedChild(i);
|
|
988
|
+
keys.push(member.childForFieldName("key")?.text ?? member.text);
|
|
989
|
+
if (keys.length >= 6) break;
|
|
990
|
+
}
|
|
991
|
+
const more = value.namedChildCount > keys.length ? ", ..." : "";
|
|
992
|
+
return `VAR:${name}{${collapseText(keys.join(", "), 50)}${more}}`;
|
|
993
|
+
}
|
|
994
|
+
if (vt === "new_expression") {
|
|
995
|
+
const ctor = value.childForFieldName("constructor")?.text ?? "?";
|
|
996
|
+
return `VAR:${name} = new ${ctor}(...)`;
|
|
997
|
+
}
|
|
998
|
+
if (vt === "call_expression") {
|
|
999
|
+
const callee = value.childForFieldName("function")?.text ?? "?";
|
|
1000
|
+
return `VAR:${name} = ${collapseText(callee, 40)}(...)`;
|
|
1001
|
+
}
|
|
980
1002
|
const valText = value.text.replace(/"[^"]*"/g, '""').replace(/'[^']*'/g, "''").replace(/`[^`]*`/g, "``");
|
|
981
1003
|
return `VAR:${name} = ${collapseText(valText, 50)}`;
|
|
982
1004
|
}
|
|
@@ -1137,29 +1159,27 @@ async function astWalkIR(code, filePath) {
|
|
|
1137
1159
|
}
|
|
1138
1160
|
const merged = [];
|
|
1139
1161
|
let guardBlock = [];
|
|
1162
|
+
const guardValue = (ret) => ret.replace(/^RET\s+/, "");
|
|
1163
|
+
const flushGuards = () => {
|
|
1164
|
+
if (guardBlock.length === 0) return;
|
|
1165
|
+
if (guardBlock.length < 3) {
|
|
1166
|
+
for (const g of guardBlock) merged.push(`${g.indent}IF:${g.cond} \u2192 ${g.ret}`);
|
|
1167
|
+
} else {
|
|
1168
|
+
const entries = guardBlock.map((g) => `${g.cond} \u2192 ${guardValue(g.ret)}`);
|
|
1169
|
+
merged.push(`${guardBlock[0].indent}GUARD:[${entries.join(", ")}]`);
|
|
1170
|
+
}
|
|
1171
|
+
guardBlock = [];
|
|
1172
|
+
};
|
|
1140
1173
|
for (const line of pass1) {
|
|
1141
|
-
const guardMatch = line.match(/^(\s*)IF:(.+?) \u2192
|
|
1174
|
+
const guardMatch = line.match(/^(\s*)IF:(.+?) \u2192 (.+)$/);
|
|
1142
1175
|
if (guardMatch) {
|
|
1143
|
-
guardBlock.push(guardMatch[2].trim());
|
|
1176
|
+
guardBlock.push({ indent: guardMatch[1], cond: guardMatch[2].trim(), ret: guardMatch[3].trim() });
|
|
1144
1177
|
continue;
|
|
1145
1178
|
}
|
|
1146
|
-
|
|
1147
|
-
if (guardBlock.length < 3) {
|
|
1148
|
-
for (const g of guardBlock) merged.push(` IF:${g} \u2192 RET`);
|
|
1149
|
-
} else {
|
|
1150
|
-
merged.push(` GUARD:[${guardBlock.join(", ")}]`);
|
|
1151
|
-
}
|
|
1152
|
-
guardBlock = [];
|
|
1153
|
-
}
|
|
1179
|
+
flushGuards();
|
|
1154
1180
|
merged.push(line);
|
|
1155
1181
|
}
|
|
1156
|
-
|
|
1157
|
-
if (guardBlock.length < 3) {
|
|
1158
|
-
for (const g of guardBlock) merged.push(` IF:${g} \u2192 RET`);
|
|
1159
|
-
} else {
|
|
1160
|
-
merged.push(` GUARD:[${guardBlock.join(", ")}]`);
|
|
1161
|
-
}
|
|
1162
|
-
}
|
|
1182
|
+
flushGuards();
|
|
1163
1183
|
return merged.join("\n");
|
|
1164
1184
|
}
|
|
1165
1185
|
|
|
@@ -3593,7 +3613,16 @@ function renderSummary(s) {
|
|
|
3593
3613
|
}
|
|
3594
3614
|
|
|
3595
3615
|
// src/index.ts
|
|
3616
|
+
import { createRequire } from "module";
|
|
3596
3617
|
import { join as join13, resolve as resolve2 } from "path";
|
|
3618
|
+
var PKG_VERSION = (() => {
|
|
3619
|
+
try {
|
|
3620
|
+
const req = createRequire(import.meta.url);
|
|
3621
|
+
return req("../package.json").version;
|
|
3622
|
+
} catch {
|
|
3623
|
+
return "0.0.0";
|
|
3624
|
+
}
|
|
3625
|
+
})();
|
|
3597
3626
|
async function readStdin() {
|
|
3598
3627
|
if (process.stdin.isTTY) return "";
|
|
3599
3628
|
const chunks = [];
|
|
@@ -3754,10 +3783,11 @@ switch (command) {
|
|
|
3754
3783
|
break;
|
|
3755
3784
|
}
|
|
3756
3785
|
case "version":
|
|
3757
|
-
console.log(
|
|
3786
|
+
console.log(`composto v${PKG_VERSION}`);
|
|
3758
3787
|
break;
|
|
3759
3788
|
default:
|
|
3760
|
-
console.log(
|
|
3789
|
+
console.log(`composto v${PKG_VERSION} \u2014 less tokens, more insight
|
|
3790
|
+
`);
|
|
3761
3791
|
console.log("Commands:");
|
|
3762
3792
|
console.log(" scan [path] Scan codebase for issues");
|
|
3763
3793
|
console.log(" trends [path] Analyze codebase health trends");
|
package/dist/mcp/server.js
CHANGED
|
@@ -5,7 +5,8 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
import { z } from "zod";
|
|
7
7
|
import { readFileSync as readFileSync4 } from "fs";
|
|
8
|
-
import {
|
|
8
|
+
import { fileURLToPath as fileURLToPath3 } from "url";
|
|
9
|
+
import { resolve as resolve2, relative as relative2, join as join6, dirname as dirname5 } from "path";
|
|
9
10
|
|
|
10
11
|
// src/ir/structure.ts
|
|
11
12
|
var CLASSIFIERS = [
|
|
@@ -650,8 +651,9 @@ function emitTier1(node) {
|
|
|
650
651
|
const outPrefix = exported ? "OUT " : "";
|
|
651
652
|
switch (node.type) {
|
|
652
653
|
case "import_statement": {
|
|
653
|
-
const
|
|
654
|
-
return `USE:${
|
|
654
|
+
const source = node.childForFieldName("source")?.text;
|
|
655
|
+
if (source) return `USE:${source.slice(1, -1)}`;
|
|
656
|
+
return `USE:${collapseText(node.text, 80)}`;
|
|
655
657
|
}
|
|
656
658
|
case "function_declaration": {
|
|
657
659
|
const name = node.childForFieldName("name")?.text ?? "anonymous";
|
|
@@ -781,9 +783,30 @@ function emitTier3(node) {
|
|
|
781
783
|
}
|
|
782
784
|
if (node.parent?.type === "statement_block") return null;
|
|
783
785
|
const vt = value.type;
|
|
784
|
-
if (vt === "number" || vt === "true" || vt === "false")
|
|
785
|
-
|
|
786
|
-
|
|
786
|
+
if (vt === "number" || vt === "true" || vt === "false") {
|
|
787
|
+
return `VAR:${name} = ${value.text}`;
|
|
788
|
+
}
|
|
789
|
+
if (vt === "array") {
|
|
790
|
+
return `VAR:${name}[${value.namedChildCount}]`;
|
|
791
|
+
}
|
|
792
|
+
if (vt === "object") {
|
|
793
|
+
const keys = [];
|
|
794
|
+
for (let i = 0; i < value.namedChildCount; i++) {
|
|
795
|
+
const member = value.namedChild(i);
|
|
796
|
+
keys.push(member.childForFieldName("key")?.text ?? member.text);
|
|
797
|
+
if (keys.length >= 6) break;
|
|
798
|
+
}
|
|
799
|
+
const more = value.namedChildCount > keys.length ? ", ..." : "";
|
|
800
|
+
return `VAR:${name}{${collapseText(keys.join(", "), 50)}${more}}`;
|
|
801
|
+
}
|
|
802
|
+
if (vt === "new_expression") {
|
|
803
|
+
const ctor = value.childForFieldName("constructor")?.text ?? "?";
|
|
804
|
+
return `VAR:${name} = new ${ctor}(...)`;
|
|
805
|
+
}
|
|
806
|
+
if (vt === "call_expression") {
|
|
807
|
+
const callee = value.childForFieldName("function")?.text ?? "?";
|
|
808
|
+
return `VAR:${name} = ${collapseText(callee, 40)}(...)`;
|
|
809
|
+
}
|
|
787
810
|
const valText = value.text.replace(/"[^"]*"/g, '""').replace(/'[^']*'/g, "''").replace(/`[^`]*`/g, "``");
|
|
788
811
|
return `VAR:${name} = ${collapseText(valText, 50)}`;
|
|
789
812
|
}
|
|
@@ -944,29 +967,27 @@ async function astWalkIR(code, filePath) {
|
|
|
944
967
|
}
|
|
945
968
|
const merged = [];
|
|
946
969
|
let guardBlock = [];
|
|
970
|
+
const guardValue = (ret) => ret.replace(/^RET\s+/, "");
|
|
971
|
+
const flushGuards = () => {
|
|
972
|
+
if (guardBlock.length === 0) return;
|
|
973
|
+
if (guardBlock.length < 3) {
|
|
974
|
+
for (const g of guardBlock) merged.push(`${g.indent}IF:${g.cond} \u2192 ${g.ret}`);
|
|
975
|
+
} else {
|
|
976
|
+
const entries = guardBlock.map((g) => `${g.cond} \u2192 ${guardValue(g.ret)}`);
|
|
977
|
+
merged.push(`${guardBlock[0].indent}GUARD:[${entries.join(", ")}]`);
|
|
978
|
+
}
|
|
979
|
+
guardBlock = [];
|
|
980
|
+
};
|
|
947
981
|
for (const line of pass1) {
|
|
948
|
-
const guardMatch = line.match(/^(\s*)IF:(.+?) \u2192
|
|
982
|
+
const guardMatch = line.match(/^(\s*)IF:(.+?) \u2192 (.+)$/);
|
|
949
983
|
if (guardMatch) {
|
|
950
|
-
guardBlock.push(guardMatch[2].trim());
|
|
984
|
+
guardBlock.push({ indent: guardMatch[1], cond: guardMatch[2].trim(), ret: guardMatch[3].trim() });
|
|
951
985
|
continue;
|
|
952
986
|
}
|
|
953
|
-
|
|
954
|
-
if (guardBlock.length < 3) {
|
|
955
|
-
for (const g of guardBlock) merged.push(` IF:${g} \u2192 RET`);
|
|
956
|
-
} else {
|
|
957
|
-
merged.push(` GUARD:[${guardBlock.join(", ")}]`);
|
|
958
|
-
}
|
|
959
|
-
guardBlock = [];
|
|
960
|
-
}
|
|
987
|
+
flushGuards();
|
|
961
988
|
merged.push(line);
|
|
962
989
|
}
|
|
963
|
-
|
|
964
|
-
if (guardBlock.length < 3) {
|
|
965
|
-
for (const g of guardBlock) merged.push(` IF:${g} \u2192 RET`);
|
|
966
|
-
} else {
|
|
967
|
-
merged.push(` GUARD:[${guardBlock.join(", ")}]`);
|
|
968
|
-
}
|
|
969
|
-
}
|
|
990
|
+
flushGuards();
|
|
970
991
|
return merged.join("\n");
|
|
971
992
|
}
|
|
972
993
|
|
|
@@ -2381,9 +2402,22 @@ var MemoryAPI = class {
|
|
|
2381
2402
|
|
|
2382
2403
|
// src/mcp/server.ts
|
|
2383
2404
|
var ALL_EXTENSIONS = [".ts", ".tsx", ".js", ".jsx", ".mjs", ".py", ".go", ".rs"];
|
|
2405
|
+
var PKG_VERSION = (() => {
|
|
2406
|
+
try {
|
|
2407
|
+
const pkgPath = join6(
|
|
2408
|
+
dirname5(fileURLToPath3(import.meta.url)),
|
|
2409
|
+
"..",
|
|
2410
|
+
"..",
|
|
2411
|
+
"package.json"
|
|
2412
|
+
);
|
|
2413
|
+
return JSON.parse(readFileSync4(pkgPath, "utf-8")).version;
|
|
2414
|
+
} catch {
|
|
2415
|
+
return "0.0.0";
|
|
2416
|
+
}
|
|
2417
|
+
})();
|
|
2384
2418
|
var server = new McpServer({
|
|
2385
2419
|
name: "composto",
|
|
2386
|
-
version:
|
|
2420
|
+
version: PKG_VERSION
|
|
2387
2421
|
});
|
|
2388
2422
|
server.tool(
|
|
2389
2423
|
"composto_ir",
|