@jefuriiij/synthra 0.1.23 → 0.1.25
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/CHANGELOG.md +53 -0
- package/LICENSE +21 -21
- package/README.md +222 -222
- package/dist/cli/index.js +434 -225
- package/dist/cli/index.js.map +1 -1
- package/dist/dashboard/index.js +56 -8
- package/dist/dashboard/index.js.map +1 -1
- package/dist/server/index.js +32 -9
- package/dist/server/index.js.map +1 -1
- package/package.json +66 -66
package/dist/server/index.js
CHANGED
|
@@ -1596,6 +1596,7 @@ function resolvePaths(projectRoot) {
|
|
|
1596
1596
|
activityLog: join5(graphDir, "activity.jsonl"),
|
|
1597
1597
|
tokenLog: join5(graphDir, "token_log.jsonl"),
|
|
1598
1598
|
gateLog: join5(graphDir, "gate_log.jsonl"),
|
|
1599
|
+
toolLog: join5(graphDir, "tool_log.jsonl"),
|
|
1599
1600
|
mcpPort: join5(graphDir, "mcp_port"),
|
|
1600
1601
|
mcpServerLog: join5(graphDir, "mcp_server.log"),
|
|
1601
1602
|
mcpServerErrLog: join5(graphDir, "mcp_server.err.log"),
|
|
@@ -1931,6 +1932,10 @@ async function scanProject(projectRootRaw, opts = {}) {
|
|
|
1931
1932
|
};
|
|
1932
1933
|
}
|
|
1933
1934
|
|
|
1935
|
+
// src/server/mcp.ts
|
|
1936
|
+
import { appendFile as appendFile2, mkdir as mkdir6 } from "fs/promises";
|
|
1937
|
+
import { dirname as dirname7 } from "path";
|
|
1938
|
+
|
|
1934
1939
|
// src/graph/rank.ts
|
|
1935
1940
|
var STOPWORDS2 = /* @__PURE__ */ new Set([
|
|
1936
1941
|
"a",
|
|
@@ -2780,7 +2785,10 @@ _(no file is unreferenced \u2014 every file is either imported by another, has a
|
|
|
2780
2785
|
async function graphContinue(args, ctx) {
|
|
2781
2786
|
const query = typeof args?.query === "string" ? args.query : "";
|
|
2782
2787
|
if (!query) return errorContent("graph_continue: 'query' (string) is required");
|
|
2783
|
-
const retrieval = await retrieve(ctx.graph, query
|
|
2788
|
+
const retrieval = await retrieve(ctx.graph, query, {
|
|
2789
|
+
recentlyEditedPaths: ctx.activity.recentFilePaths(15 * 60 * 1e3),
|
|
2790
|
+
sessionKnownPaths: getRegisteredEdits()
|
|
2791
|
+
});
|
|
2784
2792
|
const packed = await pack(retrieval.files, { query, graph: ctx.graph });
|
|
2785
2793
|
const header = `Confidence: ${retrieval.confidence}
|
|
2786
2794
|
Files: ${retrieval.files.map((f) => f.path).join(", ") || "(none)"}
|
|
@@ -2842,6 +2850,9 @@ function graphRegisterEdit(args, _ctx) {
|
|
|
2842
2850
|
for (const f of files) editedFiles.add(f);
|
|
2843
2851
|
return textContent(`Registered ${files.length} edited file(s). Total tracked this session: ${editedFiles.size}.`);
|
|
2844
2852
|
}
|
|
2853
|
+
function getRegisteredEdits() {
|
|
2854
|
+
return Array.from(editedFiles);
|
|
2855
|
+
}
|
|
2845
2856
|
var VALID_KINDS = /* @__PURE__ */ new Set(["decision", "task", "next", "fact", "blocker"]);
|
|
2846
2857
|
async function contextRemember(args, ctx) {
|
|
2847
2858
|
const text = typeof args?.text === "string" ? args.text.trim() : "";
|
|
@@ -2905,6 +2916,17 @@ async function contextRecall(args, ctx) {
|
|
|
2905
2916
|
}
|
|
2906
2917
|
return textContent(lines.join("\n"));
|
|
2907
2918
|
}
|
|
2919
|
+
async function logToolCall(ctx, tool) {
|
|
2920
|
+
try {
|
|
2921
|
+
await mkdir6(dirname7(ctx.paths.toolLog), { recursive: true });
|
|
2922
|
+
await appendFile2(
|
|
2923
|
+
ctx.paths.toolLog,
|
|
2924
|
+
JSON.stringify({ ts: (/* @__PURE__ */ new Date()).toISOString(), tool }) + "\n",
|
|
2925
|
+
"utf8"
|
|
2926
|
+
);
|
|
2927
|
+
} catch {
|
|
2928
|
+
}
|
|
2929
|
+
}
|
|
2908
2930
|
async function handleMcpRequest(body, ctx) {
|
|
2909
2931
|
if (!body || typeof body !== "object") {
|
|
2910
2932
|
return err(null, ERR.invalidRequest, "Request body must be a JSON-RPC 2.0 object.");
|
|
@@ -2931,6 +2953,7 @@ async function handleMcpRequest(body, ctx) {
|
|
|
2931
2953
|
const toolName = typeof params.name === "string" ? params.name : "";
|
|
2932
2954
|
if (!toolName) return err(id, ERR.invalidParams, "'name' is required for tools/call.");
|
|
2933
2955
|
const args = params.arguments && typeof params.arguments === "object" ? params.arguments : {};
|
|
2956
|
+
void logToolCall(ctx, toolName);
|
|
2934
2957
|
const result = await callTool(toolName, args, ctx);
|
|
2935
2958
|
return ok(id, result);
|
|
2936
2959
|
}
|
|
@@ -2985,8 +3008,8 @@ async function handleContextUpdate(req, ctx) {
|
|
|
2985
3008
|
}
|
|
2986
3009
|
|
|
2987
3010
|
// src/server/routes/gate.ts
|
|
2988
|
-
import { appendFile as
|
|
2989
|
-
import { dirname as
|
|
3011
|
+
import { appendFile as appendFile3, mkdir as mkdir7 } from "fs/promises";
|
|
3012
|
+
import { dirname as dirname8 } from "path";
|
|
2990
3013
|
var BLOCKABLE_TOOLS = /* @__PURE__ */ new Set(["Grep", "Glob"]);
|
|
2991
3014
|
var RECENT_ACTIVITY_WINDOW_MS = 5 * 60 * 1e3;
|
|
2992
3015
|
function extractQuery(toolName, input) {
|
|
@@ -3042,7 +3065,7 @@ function recentlyTouchedMatchesQuery(recentPaths, queryTokens, graph) {
|
|
|
3042
3065
|
}
|
|
3043
3066
|
async function logDecision(ctx, toolName, query, decision, reason) {
|
|
3044
3067
|
try {
|
|
3045
|
-
await
|
|
3068
|
+
await mkdir7(dirname8(ctx.paths.gateLog), { recursive: true });
|
|
3046
3069
|
const entry = {
|
|
3047
3070
|
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
3048
3071
|
tool: toolName,
|
|
@@ -3050,7 +3073,7 @@ async function logDecision(ctx, toolName, query, decision, reason) {
|
|
|
3050
3073
|
query,
|
|
3051
3074
|
reason
|
|
3052
3075
|
};
|
|
3053
|
-
await
|
|
3076
|
+
await appendFile3(ctx.paths.gateLog, JSON.stringify(entry) + "\n", "utf8");
|
|
3054
3077
|
} catch {
|
|
3055
3078
|
}
|
|
3056
3079
|
}
|
|
@@ -3114,16 +3137,16 @@ async function handleGate(req, ctx) {
|
|
|
3114
3137
|
}
|
|
3115
3138
|
|
|
3116
3139
|
// src/server/routes/log.ts
|
|
3117
|
-
import { appendFile as
|
|
3118
|
-
import { dirname as
|
|
3140
|
+
import { appendFile as appendFile4, mkdir as mkdir8 } from "fs/promises";
|
|
3141
|
+
import { dirname as dirname9 } from "path";
|
|
3119
3142
|
async function handleLog(entry, ctx) {
|
|
3120
3143
|
if (!entry || typeof entry.input_tokens !== "number" || typeof entry.output_tokens !== "number") {
|
|
3121
3144
|
throw new Error("log: input_tokens and output_tokens (number) are required");
|
|
3122
3145
|
}
|
|
3123
3146
|
const written_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
3124
3147
|
const record = { ...entry, written_at };
|
|
3125
|
-
await
|
|
3126
|
-
await
|
|
3148
|
+
await mkdir8(dirname9(ctx.paths.tokenLog), { recursive: true });
|
|
3149
|
+
await appendFile4(ctx.paths.tokenLog, JSON.stringify(record) + "\n", "utf8");
|
|
3127
3150
|
return { ok: true, written_at };
|
|
3128
3151
|
}
|
|
3129
3152
|
|