d365fo-mcp 1.16.1 → 1.16.2

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,5 +1,5 @@
1
1
  import { execFile } from 'child_process';
2
- import { parseSysTestXml } from '../../eval/oracle/systest.js';
2
+ import { parseSysTestXml } from './sysTestXml.js';
3
3
  import util from 'util';
4
4
  import path from 'path';
5
5
  import os from 'os';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Reader for the `/xml:` result document SysTestConsole writes.
3
+ *
4
+ * This lives beside the runner rather than in `src/eval/` because it is loaded
5
+ * at runtime by `sysTestRunner.ts`, and `src/eval/**` is a dev-only tree that
6
+ * package.json's `files` list keeps out of the published tarball
7
+ * (`"!dist/eval/**"`). A shipped module importing across that boundary makes
8
+ * the installed server fail to start with ERR_MODULE_NOT_FOUND. The eval
9
+ * oracle re-exports this from `src/eval/oracle/systest.ts`; the dependency
10
+ * runs eval → tools, never the other way.
11
+ */
12
+ /** One test method's outcome, read from the runner's XML result document. */
13
+ export interface SysTestCaseOutcome {
14
+ name: string;
15
+ passed: boolean;
16
+ message?: string;
17
+ }
18
+ /**
19
+ * Per-method outcomes from the `/xml:` document SysTestConsole writes.
20
+ *
21
+ * The shape is the platform's own: SysTestListenerXML builds
22
+ * `<test-results><results><test-case name="…" success="true|false">` and adds a
23
+ * `<failure><message>…</message></failure>` child for a failing one (the element
24
+ * names are #define'd at the top of that class). Reading it beats the regex over
25
+ * combined stdout that the runner used to classify with: a class named
26
+ * …ErrorHandlingTest made "error" appear in the output of a passing run, and a
27
+ * green run was reported as failed.
28
+ *
29
+ * Returns [] when the text is not such a document, so callers can fall back.
30
+ */
31
+ export declare function parseSysTestXml(xml: string | null | undefined): SysTestCaseOutcome[];
32
+ //# sourceMappingURL=sysTestXml.d.ts.map
@@ -0,0 +1,54 @@
1
+ /**
2
+ * Reader for the `/xml:` result document SysTestConsole writes.
3
+ *
4
+ * This lives beside the runner rather than in `src/eval/` because it is loaded
5
+ * at runtime by `sysTestRunner.ts`, and `src/eval/**` is a dev-only tree that
6
+ * package.json's `files` list keeps out of the published tarball
7
+ * (`"!dist/eval/**"`). A shipped module importing across that boundary makes
8
+ * the installed server fail to start with ERR_MODULE_NOT_FOUND. The eval
9
+ * oracle re-exports this from `src/eval/oracle/systest.ts`; the dependency
10
+ * runs eval → tools, never the other way.
11
+ */
12
+ /**
13
+ * Per-method outcomes from the `/xml:` document SysTestConsole writes.
14
+ *
15
+ * The shape is the platform's own: SysTestListenerXML builds
16
+ * `<test-results><results><test-case name="…" success="true|false">` and adds a
17
+ * `<failure><message>…</message></failure>` child for a failing one (the element
18
+ * names are #define'd at the top of that class). Reading it beats the regex over
19
+ * combined stdout that the runner used to classify with: a class named
20
+ * …ErrorHandlingTest made "error" appear in the output of a passing run, and a
21
+ * green run was reported as failed.
22
+ *
23
+ * Returns [] when the text is not such a document, so callers can fall back.
24
+ */
25
+ export function parseSysTestXml(xml) {
26
+ if (!xml || !/<test-case\b/i.test(xml))
27
+ return [];
28
+ const outcomes = [];
29
+ // The SELF-CLOSING form has to be tried first. With the paired form leading, its
30
+ // `[^>]*` happily consumed the `/` of `<test-case … />` and the lazy body then ran
31
+ // on to the NEXT `</test-case>`, swallowing two results into one.
32
+ const caseRe = /<test-case\b([^>]*?)\/>|<test-case\b([^>]*)>([\s\S]*?)<\/test-case>/gi;
33
+ let m;
34
+ while ((m = caseRe.exec(xml)) !== null) {
35
+ const attrs = m[1] ?? m[2] ?? '';
36
+ const body = m[3] ?? '';
37
+ const name = /\bname\s*=\s*"([^"]*)"/i.exec(attrs)?.[1] ?? '';
38
+ const successAttr = /\bsuccess\s*=\s*"([^"]*)"/i.exec(attrs)?.[1];
39
+ const failure = /<failure\b[^>]*>([\s\S]*?)<\/failure>/i.exec(body)?.[1];
40
+ const message = failure
41
+ ? (/<message\b[^>]*>([\s\S]*?)<\/message>/i.exec(failure)?.[1] ?? failure)
42
+ .replace(/<[^>]+>/g, ' ')
43
+ .replace(/\s+/g, ' ')
44
+ .trim()
45
+ : undefined;
46
+ // `success` is authoritative when present; a <failure> child decides otherwise.
47
+ const passed = successAttr !== undefined
48
+ ? /^(true|1)$/i.test(successAttr)
49
+ : failure === undefined;
50
+ outcomes.push(message ? { name, passed, message } : { name, passed });
51
+ }
52
+ return outcomes;
53
+ }
54
+ //# sourceMappingURL=sysTestXml.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "d365fo-mcp",
3
- "version": "1.16.1",
3
+ "version": "1.16.2",
4
4
  "description": "MCP Server for X++ Code Completion in D365 Finance & Operations",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",