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.
@@ -1,8 +1,36 @@
1
- import { transformAutoReturn } from './chunk-OKOVZ5QE.js';
2
- import { workerData, parentPort } from 'worker_threads';
1
+ import { parentPort } from 'worker_threads';
3
2
  import * as vm from 'vm';
4
3
 
5
- var { code, methodList, timeoutMs, rpcPort: workerRpcPort } = workerData;
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
- rpcPort = workerRpcPort;
128
- rpcPort.ref();
129
- rpcPort.on("message", (response) => {
130
- const pending = pendingRpcRequests.get(response.id);
131
- if (pending) {
132
- pendingRpcRequests.delete(response.id);
133
- if (response.error) {
134
- pending.reject(new Error(response.error));
135
- } else {
136
- pending.resolve(response.result);
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.5.0",
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neverinfamous-agent-skills",
3
- "version": "1.1.1",
3
+ "version": "1.1.2",
4
4
  "description": "Foundational AI agent metacognitive skills and workflows for the Adamic ecosystem.",
5
5
  "type": "module",
6
6
  "main": "README.md",
@@ -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 };