wopee-mcp 1.29.0 → 1.30.0

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.
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Strip pretty-printing from `tests.json` before it enters the model's context.
3
+ *
4
+ * The api commits the USER_STORIES artifact indented so the diff of a test-case
5
+ * edit is reviewable in a GitHub PR (autonomous-testing/backlog#4252). That
6
+ * formatting is for humans reading a diff — `fetchArtifact` hands the file
7
+ * straight to the model, where the extra whitespace is pure token cost and buys
8
+ * nothing. `fetch_project_summary` pulls this artifact for every suite in a
9
+ * project, so the cost is multiplied.
10
+ *
11
+ * Fails open: content that does not parse is returned untouched. A broken
12
+ * artifact is still worth showing the model — it can say so.
13
+ *
14
+ * Kept free of enum imports so `node --test` (strip-only TS) can cover it; the
15
+ * artifact-type gate lives in `_compactArtifactContentForModel`.
16
+ */
17
+ export function compactUserStoriesContent(content) {
18
+ try {
19
+ return JSON.stringify(JSON.parse(content));
20
+ }
21
+ catch {
22
+ return content;
23
+ }
24
+ }
@@ -45,6 +45,7 @@ export const DispatchAgent = `
45
45
  analysisIdentifier
46
46
  userStoryId
47
47
  testCaseId
48
+ runName
48
49
  executionStatus
49
50
  agentReport
50
51
  agentReportStatus
@@ -2,7 +2,7 @@ import { FetchArtifactInputSchema, UpdateArtifactInputSchema, GenerateAIDataInpu
2
2
  import { FetchArtifact, UpdateArtifact } from "./gql-queries.js";
3
3
  import { createFetchArtifactInput, createUpdateArtifactInput, createGenerateAIDataInput, } from "./factories.js";
4
4
  import { requestClient } from "../../utils/requestClient.js";
5
- import { _convertToArtifactType, _parseError, _parseGenerateArtifactType, } from "./helpers.js";
5
+ import { _compactArtifactContentForModel, _convertToArtifactType, _parseError, _parseGenerateArtifactType, } from "./helpers.js";
6
6
  export async function fetchArtifact(input) {
7
7
  try {
8
8
  const { type, suiteUuid, identifier } = input;
@@ -28,7 +28,7 @@ export async function fetchArtifact(input) {
28
28
  content: [
29
29
  {
30
30
  type: "text",
31
- text: result.fetchArtifact.content,
31
+ text: _compactArtifactContentForModel(type, result.fetchArtifact.content),
32
32
  },
33
33
  ],
34
34
  };
@@ -2,6 +2,7 @@ import { z } from "zod";
2
2
  import { GenerateAppContext, GenerateGeneralUserStories, GenerateReusableTestCases, GenerateReusableTestCaseSteps, GenerateTestCases, GenerateTestCaseSteps, GenerateUserStoriesWithTestCases, } from "./gql-queries.js";
3
3
  import { ArtifactType, GenerateArtifactType } from "./types.js";
4
4
  import { RequestError } from "../../utils/requestClient.js";
5
+ import { compactUserStoriesContent } from "./artifactContent.js";
5
6
  export function _convertToArtifactType(type) {
6
7
  switch (type) {
7
8
  case GenerateArtifactType.APP_CONTEXT:
@@ -95,3 +96,13 @@ export function _parseError(error) {
95
96
  ],
96
97
  };
97
98
  }
99
+ /**
100
+ * Only USER_STORIES is JSON: APP_CONTEXT / GENERAL_USER_STORIES are markdown and
101
+ * PLAYWRIGHT_CODE is TypeScript, where collapsing whitespace would corrupt the
102
+ * file. See `compactUserStoriesContent` for why the artifact is compacted at all.
103
+ */
104
+ export function _compactArtifactContentForModel(type, content) {
105
+ if (type !== ArtifactType.USER_STORIES)
106
+ return content;
107
+ return compactUserStoriesContent(content);
108
+ }
@@ -0,0 +1,20 @@
1
+ export function formatDispatchSuccess(testCases, input) {
2
+ const lines = [
3
+ "DISPATCH SUCCESSFUL — tests are now RUNNING (not yet completed).",
4
+ "",
5
+ "Tracking:",
6
+ `- Suite UUID: ${testCases[0]?.suiteUuid ?? input.suiteUuid}`,
7
+ `- Analysis Suite UUID: ${testCases[0]?.analysisSuiteUuid ?? "N/A"}`,
8
+ `- Analysis Identifier: ${testCases[0]?.analysisIdentifier ?? input.analysisIdentifier}`,
9
+ "",
10
+ "Test cases dispatched:",
11
+ ];
12
+ // Each row's uuid and run name are the handles for tracking THIS dispatch (backlog#4382).
13
+ // The run name is the GitHub Actions title verbatim and is unique per dispatch, so a caller
14
+ // no longer has to guess which of several identically-named runs is its own.
15
+ for (const tc of testCases) {
16
+ lines.push(`- ${tc.userStoryId}:${tc.testCaseId} → executionStatus: ${tc.executionStatus}`, ` executedTestCaseUuid: ${tc.uuid}`, ...(tc.runName ? [` runName: ${tc.runName}`] : []));
17
+ }
18
+ lines.push("", "IMPORTANT: These tests are RUNNING asynchronously. Do NOT report them as passed or failed.", "Tell the user their tests are running and results will be available shortly (typically 1-3 minutes).", "You will receive a follow-up notification in chat when tests complete with full results.");
19
+ return lines.join("\n");
20
+ }
@@ -3,25 +3,9 @@ import { ToolName } from "../shared/types.js";
3
3
  import { _parseError } from "../shared/helpers.js";
4
4
  import { createDispatchAgentInput } from "./factory.js";
5
5
  import { DispatchAgent } from "../shared/gql-queries.js";
6
+ import { formatDispatchSuccess } from "./format.js";
6
7
  import { requestClient } from "../../utils/requestClient.js";
7
8
  import { withRetry } from "../../utils/withRetry.js";
8
- function formatDispatchSuccess(testCases, input) {
9
- const lines = [
10
- "DISPATCH SUCCESSFUL — tests are now RUNNING (not yet completed).",
11
- "",
12
- "Tracking:",
13
- `- Suite UUID: ${testCases[0]?.suiteUuid ?? input.suiteUuid}`,
14
- `- Analysis Suite UUID: ${testCases[0]?.analysisSuiteUuid ?? "N/A"}`,
15
- `- Analysis Identifier: ${testCases[0]?.analysisIdentifier ?? input.analysisIdentifier}`,
16
- "",
17
- "Test cases dispatched:",
18
- ];
19
- for (const tc of testCases) {
20
- lines.push(`- ${tc.userStoryId}:${tc.testCaseId} → executionStatus: ${tc.executionStatus}`);
21
- }
22
- lines.push("", "IMPORTANT: These tests are RUNNING asynchronously. Do NOT report them as passed or failed.", "Tell the user their tests are running and results will be available shortly (typically 1-3 minutes).", "You will receive a follow-up notification in chat when tests complete with full results.");
23
- return lines.join("\n");
24
- }
25
9
  export const wopeeDispatchAgent = {
26
10
  name: ToolName.WOPEE_DISPATCH_AGENT,
27
11
  config: {
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "bin": {
5
5
  "wopee-mcp": "./build/index.js"
6
6
  },
7
- "version": "1.29.0",
7
+ "version": "1.30.0",
8
8
  "mcpName": "io.github.Wopee-io/wopee-mcp",
9
9
  "description": "Wopee.io MCP server for autonomous testing platform",
10
10
  "main": "./build/index.js",