memory-journal-mcp 7.5.0 → 7.6.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/README.md +85 -74
- package/dist/{chunk-XNOUTCRV.js → chunk-DFQG7UR5.js} +3273 -1305
- package/dist/{chunk-VHA46GLM.js → chunk-SYTB5YNH.js} +10047 -8082
- package/dist/cli.js +227 -51
- package/dist/index.d.ts +267 -162
- package/dist/index.js +2 -4
- package/dist/tools-JQPK5JFS.js +1 -0
- package/dist/worker-script.js +113 -23
- package/package.json +4 -2
- package/skills/github-commander/workflows/copilot-audit.md +3 -1
- package/skills/package.json +1 -1
- package/dist/chunk-OKOVZ5QE.js +0 -28
- package/dist/chunk-WXDEVIFL.js +0 -1745
- package/dist/github-integration-YODGZH3K.js +0 -1
- package/dist/tools-HTE4YXMW.js +0 -3
package/dist/worker-script.js
CHANGED
|
@@ -1,8 +1,36 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { workerData, parentPort } from 'worker_threads';
|
|
1
|
+
import { parentPort } from 'worker_threads';
|
|
3
2
|
import * as vm from 'vm';
|
|
4
3
|
|
|
5
|
-
|
|
4
|
+
// src/codemode/worker-script.ts
|
|
5
|
+
|
|
6
|
+
// src/codemode/auto-return.ts
|
|
7
|
+
var NON_RETURNABLE = /^\s*(return|throw|const |let |var |if\b|else\b|for\b|while\b|do\b|switch\b|try\b|catch\b|finally\b|class |function |\/\/|\/\*|\{|\})/;
|
|
8
|
+
function transformAutoReturn(code) {
|
|
9
|
+
const trimmed = code.trimEnd();
|
|
10
|
+
if (!trimmed) return code;
|
|
11
|
+
let depth = 0;
|
|
12
|
+
let splitIndex = -1;
|
|
13
|
+
for (let i = trimmed.length - 1; i >= 0; i--) {
|
|
14
|
+
const ch = trimmed.charAt(i);
|
|
15
|
+
if (ch === "}" || ch === "]" || ch === ")") depth++;
|
|
16
|
+
else if (ch === "{" || ch === "[" || ch === "(") depth--;
|
|
17
|
+
if (depth === 0 && (ch === ";" || ch === "\n")) {
|
|
18
|
+
splitIndex = i;
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
const lastStmt = (splitIndex >= 0 ? trimmed.slice(splitIndex + 1) : trimmed).trim();
|
|
23
|
+
if (!lastStmt) return code;
|
|
24
|
+
if (NON_RETURNABLE.test(lastStmt)) return code;
|
|
25
|
+
if (splitIndex >= 0) {
|
|
26
|
+
const before = trimmed.slice(0, splitIndex + 1);
|
|
27
|
+
return `${before}
|
|
28
|
+
return ${lastStmt}`;
|
|
29
|
+
}
|
|
30
|
+
return `return ${trimmed}`;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// src/codemode/worker-script.ts
|
|
6
34
|
var rpcPort = null;
|
|
7
35
|
var rpcIdCounter = 0;
|
|
8
36
|
var pendingRpcRequests = /* @__PURE__ */ new Map();
|
|
@@ -62,7 +90,7 @@ function buildApiProxy(methods) {
|
|
|
62
90
|
};
|
|
63
91
|
return api;
|
|
64
92
|
}
|
|
65
|
-
async function executeCode() {
|
|
93
|
+
async function executeCode(code, methodList, timeoutMs) {
|
|
66
94
|
const startCpu = process.cpuUsage();
|
|
67
95
|
const startTime = performance.now();
|
|
68
96
|
try {
|
|
@@ -76,7 +104,6 @@ async function executeCode() {
|
|
|
76
104
|
info: (...args) => args,
|
|
77
105
|
debug: (...args) => args
|
|
78
106
|
},
|
|
79
|
-
// Nulled globals
|
|
80
107
|
setTimeout: void 0,
|
|
81
108
|
setInterval: void 0,
|
|
82
109
|
setImmediate: void 0,
|
|
@@ -88,7 +115,11 @@ async function executeCode() {
|
|
|
88
115
|
globalThis: void 0
|
|
89
116
|
};
|
|
90
117
|
const context = vm.createContext(sandbox, {
|
|
91
|
-
name: "codemode-worker-sandbox"
|
|
118
|
+
name: "codemode-worker-sandbox",
|
|
119
|
+
codeGeneration: {
|
|
120
|
+
strings: false,
|
|
121
|
+
wasm: false
|
|
122
|
+
}
|
|
92
123
|
});
|
|
93
124
|
const wrappedCode = `(async () => { ${transformAutoReturn(code)} })()`;
|
|
94
125
|
const script = new vm.Script(wrappedCode, {
|
|
@@ -104,7 +135,6 @@ async function executeCode() {
|
|
|
104
135
|
wallTimeMs: Math.round(endTime - startTime),
|
|
105
136
|
cpuTimeMs: Math.round((endCpu.user + endCpu.system) / 1e3),
|
|
106
137
|
memoryUsedMb: 0
|
|
107
|
-
// Measured on host side via RSS delta
|
|
108
138
|
};
|
|
109
139
|
return { success: true, result, metrics };
|
|
110
140
|
} catch (err) {
|
|
@@ -124,21 +154,81 @@ async function executeCode() {
|
|
|
124
154
|
};
|
|
125
155
|
}
|
|
126
156
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
157
|
+
parentPort?.on("message", (msg) => {
|
|
158
|
+
void (async () => {
|
|
159
|
+
if (msg !== null && msg !== void 0 && typeof msg === "object" && "type" in msg && msg.type === "EXECUTE") {
|
|
160
|
+
const executeMsg = msg;
|
|
161
|
+
const {
|
|
162
|
+
id,
|
|
163
|
+
code,
|
|
164
|
+
methodList,
|
|
165
|
+
timeoutMs,
|
|
166
|
+
maxResultSize,
|
|
167
|
+
rpcPort: newRpcPort
|
|
168
|
+
} = executeMsg;
|
|
169
|
+
rpcPort = newRpcPort;
|
|
170
|
+
rpcIdCounter = 0;
|
|
171
|
+
pendingRpcRequests.clear();
|
|
172
|
+
rpcPort?.on("message", (response) => {
|
|
173
|
+
const pending = pendingRpcRequests.get(response.id);
|
|
174
|
+
if (pending) {
|
|
175
|
+
pendingRpcRequests.delete(response.id);
|
|
176
|
+
if (response.error) {
|
|
177
|
+
pending.reject(new Error(response.error));
|
|
178
|
+
} else {
|
|
179
|
+
pending.resolve(response.result);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
const result = await executeCode(code, methodList, timeoutMs ?? 3e4);
|
|
184
|
+
if (result.success) {
|
|
185
|
+
try {
|
|
186
|
+
const egressLimit = maxResultSize ?? 100 * 1024;
|
|
187
|
+
let bytes = 0;
|
|
188
|
+
const cache = /* @__PURE__ */ new Set();
|
|
189
|
+
const resultJson = JSON.stringify(
|
|
190
|
+
result.result,
|
|
191
|
+
(_key, value) => {
|
|
192
|
+
if (typeof value === "object" && value !== null) {
|
|
193
|
+
if (cache.has(value)) return "[Circular]";
|
|
194
|
+
cache.add(value);
|
|
195
|
+
}
|
|
196
|
+
if (typeof value === "string") {
|
|
197
|
+
bytes += Buffer.byteLength(value, "utf8") + 2;
|
|
198
|
+
} else if (typeof value === "number" || typeof value === "boolean") {
|
|
199
|
+
bytes += Buffer.byteLength(String(value), "utf8");
|
|
200
|
+
} else {
|
|
201
|
+
bytes += 5;
|
|
202
|
+
}
|
|
203
|
+
if (bytes > egressLimit) {
|
|
204
|
+
throw new Error(`EgressLimitExceeded:${bytes}`);
|
|
205
|
+
}
|
|
206
|
+
return value;
|
|
207
|
+
}
|
|
208
|
+
);
|
|
209
|
+
if (resultJson !== void 0) {
|
|
210
|
+
const byteLength = Buffer.byteLength(resultJson, "utf8");
|
|
211
|
+
if (byteLength > egressLimit) {
|
|
212
|
+
throw new Error(`EgressLimitExceeded:${byteLength}`);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
} catch (err) {
|
|
216
|
+
result.success = false;
|
|
217
|
+
const egressLimit = maxResultSize ?? 100 * 1024;
|
|
218
|
+
if (err instanceof Error && err.message.startsWith("EgressLimitExceeded:")) {
|
|
219
|
+
const actualBytesStr = err.message.split(":")[1];
|
|
220
|
+
const actualBytes = actualBytesStr !== void 0 ? Number(actualBytesStr) : egressLimit + 1;
|
|
221
|
+
const actualKb = (actualBytes / 1024).toFixed(1);
|
|
222
|
+
result.error = `Output limit exceeded: Result serialization exceeded the ${Math.round(egressLimit / 1024)}KB boundary (Actual size: >${actualKb}KB). Please aggregate or filter your results to reduce the payload size.`;
|
|
223
|
+
} else {
|
|
224
|
+
result.error = `Result could not be serialized or exceeded memory limits: ${err instanceof Error ? err.message : String(err)}`;
|
|
225
|
+
}
|
|
226
|
+
result.result = void 0;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
rpcPort?.close();
|
|
230
|
+
rpcPort = null;
|
|
231
|
+
parentPort?.postMessage({ type: "RESULT", id, result });
|
|
137
232
|
}
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
void executeCode().then((result) => {
|
|
141
|
-
rpcPort?.unref();
|
|
142
|
-
rpcPort?.close();
|
|
143
|
-
parentPort?.postMessage(result);
|
|
233
|
+
})();
|
|
144
234
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memory-journal-mcp",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.6.1",
|
|
4
4
|
"description": "Project context management for AI-assisted development - Persistent knowledge graphs and intelligent context recall across fragmented AI threads",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,8 +25,10 @@
|
|
|
25
25
|
"test:watch": "vitest",
|
|
26
26
|
"test:coverage": "vitest run --coverage && npx tsx scripts/update-badges.ts",
|
|
27
27
|
"bench": "vitest bench --run",
|
|
28
|
+
"pretest:e2e": "node -e \"fs.rmSync('.test-output/e2e', { recursive: true, force: true })\"",
|
|
28
29
|
"test:e2e": "playwright test",
|
|
29
|
-
"generate:instructions": "node scripts/generate-server-instructions.ts"
|
|
30
|
+
"generate:instructions": "node scripts/generate-server-instructions.ts",
|
|
31
|
+
"prepublishOnly": "npm run check && npm run test && npm run build"
|
|
30
32
|
},
|
|
31
33
|
"keywords": [
|
|
32
34
|
"mcp",
|
|
@@ -5,7 +5,7 @@ This workflow orchestrates an AI-driven adversarial review using the GitHub Copi
|
|
|
5
5
|
## Phase 1: Environment Readiness & Authentication
|
|
6
6
|
|
|
7
7
|
1. **Verify Copilot CLI Presence**:
|
|
8
|
-
Run `npm list -g @github/copilot`.
|
|
8
|
+
Run `npm list -g @github/copilot`.
|
|
9
9
|
If missing, install it automatically: `npm i -g @github/copilot`.
|
|
10
10
|
|
|
11
11
|
2. **Verify Authentication**:
|
|
@@ -16,6 +16,7 @@ This workflow orchestrates an AI-driven adversarial review using the GitHub Copi
|
|
|
16
16
|
Determine whether this is a localized Feature Branch (Pre-Push PR) review or a whole Codebase Audit.
|
|
17
17
|
|
|
18
18
|
### Path A: Pre-Push PR Review
|
|
19
|
+
|
|
19
20
|
1. Diff the current working branch against the primary target (e.g., `main` or `master`).
|
|
20
21
|
2. **Execute Single-Shot Evaluation Buffer**:
|
|
21
22
|
```bash
|
|
@@ -23,6 +24,7 @@ Determine whether this is a localized Feature Branch (Pre-Push PR) review or a w
|
|
|
23
24
|
```
|
|
24
25
|
|
|
25
26
|
### Path B: Comprehensive Codebase Review
|
|
27
|
+
|
|
26
28
|
1. **Execute Single-Shot Codebase Buffer**:
|
|
27
29
|
```bash
|
|
28
30
|
echo "Act as an adversarial security and performance auditor. Perform a comprehensive analysis of all files in this repository. Point out bad architectural couplings, injection vectors, unhandled error flows, and data boundaries that are not explicit. Output as a detailed Markdown report." | copilot
|
package/skills/package.json
CHANGED
package/dist/chunk-OKOVZ5QE.js
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
// src/codemode/auto-return.ts
|
|
2
|
-
var NON_RETURNABLE = /^\s*(return|throw|const |let |var |if\b|else\b|for\b|while\b|do\b|switch\b|try\b|catch\b|finally\b|class |function |\/\/|\/\*|\{|\})/;
|
|
3
|
-
function transformAutoReturn(code) {
|
|
4
|
-
const trimmed = code.trimEnd();
|
|
5
|
-
if (!trimmed) return code;
|
|
6
|
-
let depth = 0;
|
|
7
|
-
let splitIndex = -1;
|
|
8
|
-
for (let i = trimmed.length - 1; i >= 0; i--) {
|
|
9
|
-
const ch = trimmed.charAt(i);
|
|
10
|
-
if (ch === "}" || ch === "]" || ch === ")") depth++;
|
|
11
|
-
else if (ch === "{" || ch === "[" || ch === "(") depth--;
|
|
12
|
-
if (depth === 0 && (ch === ";" || ch === "\n")) {
|
|
13
|
-
splitIndex = i;
|
|
14
|
-
break;
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
const lastStmt = (splitIndex >= 0 ? trimmed.slice(splitIndex + 1) : trimmed).trim();
|
|
18
|
-
if (!lastStmt) return code;
|
|
19
|
-
if (NON_RETURNABLE.test(lastStmt)) return code;
|
|
20
|
-
if (splitIndex >= 0) {
|
|
21
|
-
const before = trimmed.slice(0, splitIndex + 1);
|
|
22
|
-
return `${before}
|
|
23
|
-
return ${lastStmt}`;
|
|
24
|
-
}
|
|
25
|
-
return `return ${trimmed}`;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export { transformAutoReturn };
|