common-qa-mcp 0.1.1 → 0.3.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.
- package/README.md +25 -70
- package/dist/adapters/factory.d.ts +17 -7
- package/dist/adapters/factory.d.ts.map +1 -1
- package/dist/adapters/factory.js +61 -7
- package/dist/adapters/factory.js.map +1 -1
- package/dist/adapters/http.d.ts +50 -0
- package/dist/adapters/http.d.ts.map +1 -0
- package/dist/adapters/http.js +109 -0
- package/dist/adapters/http.js.map +1 -0
- package/dist/adapters/remoteMcp/adapter.d.ts +10 -1
- package/dist/adapters/remoteMcp/adapter.d.ts.map +1 -1
- package/dist/adapters/remoteMcp/adapter.js +31 -3
- package/dist/adapters/remoteMcp/adapter.js.map +1 -1
- package/dist/adapters/simplifyqa/adapter.d.ts +154 -0
- package/dist/adapters/simplifyqa/adapter.d.ts.map +1 -0
- package/dist/adapters/simplifyqa/adapter.js +1150 -0
- package/dist/adapters/simplifyqa/adapter.js.map +1 -0
- package/dist/adapters/simplifyqa/mapper.d.ts +63 -0
- package/dist/adapters/simplifyqa/mapper.d.ts.map +1 -0
- package/dist/adapters/simplifyqa/mapper.js +409 -0
- package/dist/adapters/simplifyqa/mapper.js.map +1 -0
- package/dist/adapters/types.d.ts +48 -1
- package/dist/adapters/types.d.ts.map +1 -1
- package/dist/adapters/walnut/adapter.d.ts +231 -0
- package/dist/adapters/walnut/adapter.d.ts.map +1 -0
- package/dist/adapters/walnut/adapter.js +1083 -0
- package/dist/adapters/walnut/adapter.js.map +1 -0
- package/dist/adapters/walnut/mapper.d.ts +29 -9
- package/dist/adapters/walnut/mapper.d.ts.map +1 -1
- package/dist/adapters/walnut/mapper.js +136 -24
- package/dist/adapters/walnut/mapper.js.map +1 -1
- package/dist/cli.js +5 -3
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +32 -14
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +41 -19
- package/dist/config.js.map +1 -1
- package/dist/connection.d.ts +6 -2
- package/dist/connection.d.ts.map +1 -1
- package/dist/connection.js +37 -14
- package/dist/connection.js.map +1 -1
- package/dist/domain/types.d.ts +195 -1
- package/dist/domain/types.d.ts.map +1 -1
- package/dist/drafts/store.d.ts +4 -1
- package/dist/drafts/store.d.ts.map +1 -1
- package/dist/drafts/store.js +7 -2
- package/dist/drafts/store.js.map +1 -1
- package/dist/initAgents.d.ts.map +1 -1
- package/dist/initAgents.js +69 -21
- package/dist/initAgents.js.map +1 -1
- package/dist/requestConnection.d.ts +5 -3
- package/dist/requestConnection.d.ts.map +1 -1
- package/dist/requestConnection.js +11 -5
- package/dist/requestConnection.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.js +26 -2
- package/dist/server.js.map +1 -1
- package/dist/tools/connection.tools.d.ts.map +1 -1
- package/dist/tools/connection.tools.js +12 -10
- package/dist/tools/connection.tools.js.map +1 -1
- package/dist/tools/discovery.tools.d.ts.map +1 -1
- package/dist/tools/discovery.tools.js +94 -2
- package/dist/tools/discovery.tools.js.map +1 -1
- package/dist/tools/formulas.tools.d.ts +7 -0
- package/dist/tools/formulas.tools.d.ts.map +1 -0
- package/dist/tools/formulas.tools.js +56 -0
- package/dist/tools/formulas.tools.js.map +1 -0
- package/dist/tools/heal.tools.d.ts +17 -0
- package/dist/tools/heal.tools.d.ts.map +1 -0
- package/dist/tools/heal.tools.js +76 -0
- package/dist/tools/heal.tools.js.map +1 -0
- package/dist/tools/recording.tools.d.ts.map +1 -1
- package/dist/tools/recording.tools.js +34 -12
- package/dist/tools/recording.tools.js.map +1 -1
- package/dist/tools/run.tools.d.ts.map +1 -1
- package/dist/tools/run.tools.js +378 -37
- package/dist/tools/run.tools.js.map +1 -1
- package/dist/tools/storySync.tools.d.ts +66 -0
- package/dist/tools/storySync.tools.d.ts.map +1 -0
- package/dist/tools/storySync.tools.js +213 -0
- package/dist/tools/storySync.tools.js.map +1 -0
- package/dist/tools/testcase.tools.d.ts.map +1 -1
- package/dist/tools/testcase.tools.js +24 -9
- package/dist/tools/testcase.tools.js.map +1 -1
- package/dist/tools/testdata.tools.d.ts +7 -0
- package/dist/tools/testdata.tools.d.ts.map +1 -0
- package/dist/tools/testdata.tools.js +161 -0
- package/dist/tools/testdata.tools.js.map +1 -0
- package/package.json +1 -1
package/dist/drafts/store.js
CHANGED
|
@@ -30,9 +30,14 @@ export class DraftStore {
|
|
|
30
30
|
this.drafts = new Map();
|
|
31
31
|
this.counter = 0;
|
|
32
32
|
}
|
|
33
|
-
create(tc) {
|
|
33
|
+
create(tc, sessionId) {
|
|
34
34
|
const draftId = `draft_${Date.now().toString(36)}_${(++this.counter).toString(36)}`;
|
|
35
|
-
this.drafts.set(draftId, {
|
|
35
|
+
this.drafts.set(draftId, {
|
|
36
|
+
draftId,
|
|
37
|
+
tc: { ...tc, steps: renumber(tc.steps) },
|
|
38
|
+
updatedAt: Date.now(),
|
|
39
|
+
...(sessionId ? { sessionId } : {}),
|
|
40
|
+
});
|
|
36
41
|
return draftId;
|
|
37
42
|
}
|
|
38
43
|
get(draftId) {
|
package/dist/drafts/store.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/drafts/store.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/drafts/store.ts"],"names":[],"mappings":"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"}
|
package/dist/initAgents.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initAgents.d.ts","sourceRoot":"","sources":["../src/initAgents.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"initAgents.d.ts","sourceRoot":"","sources":["../src/initAgents.ts"],"names":[],"mappings":"AAkNA,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAiDjE"}
|
package/dist/initAgents.js
CHANGED
|
@@ -23,10 +23,13 @@ const COMMON_QA_AGENT = {
|
|
|
23
23
|
// Lifecycle (product-neutral, flat)
|
|
24
24
|
'common-qa-mcp/list_projects', 'common-qa-mcp/qa_switch_project', 'common-qa-mcp/project_info',
|
|
25
25
|
'common-qa-mcp/tc_list', 'common-qa-mcp/tc_get', 'common-qa-mcp/tc_save', 'common-qa-mcp/tc_delete',
|
|
26
|
-
'common-qa-mcp/tc_run', 'common-qa-mcp/run_status', 'common-qa-mcp/run_stop',
|
|
26
|
+
'common-qa-mcp/tc_run', 'common-qa-mcp/run_status', 'common-qa-mcp/run_stop',
|
|
27
|
+
'common-qa-mcp/cloud_runners', 'common-qa-mcp/local_agents',
|
|
28
|
+
// Manage existing schedules — list / edit / pause-resume-cancel / delete
|
|
29
|
+
'common-qa-mcp/schedule_list', 'common-qa-mcp/schedule_update', 'common-qa-mcp/schedule_control', 'common-qa-mcp/schedule_delete',
|
|
27
30
|
// User stories → manual test cases → automate. story_list/get pull up stories; tc_draft_create/update
|
|
28
31
|
// author MANUAL test cases (then tc_save); tc_automate promotes a manual test case to automated in place.
|
|
29
|
-
'common-qa-mcp/story_list', 'common-qa-mcp/story_get',
|
|
32
|
+
'common-qa-mcp/story_list', 'common-qa-mcp/story_get', 'common-qa-mcp/list_modules',
|
|
30
33
|
'common-qa-mcp/tc_draft_create', 'common-qa-mcp/tc_draft_update', 'common-qa-mcp/tc_automate',
|
|
31
34
|
// Test suites — list / read / edit membership / execute (execute reuses run_status + run_stop)
|
|
32
35
|
'common-qa-mcp/suite_list', 'common-qa-mcp/suite_get', 'common-qa-mcp/suite_run',
|
|
@@ -62,7 +65,7 @@ Hand the whole recording to the sub-agent for the target technology; it opens a
|
|
|
62
65
|
- **\`web({ task, url?, profile?, nestStart?, nestEnd? })\`** — \`task\` is the COMPLETE goal for the part you are RECORDING: the app URL, the credentials/data, and what to assert, e.g. *"Sign in at <url> as Admin / admin123, then verify the Dashboard heading is visible."* \`nestStart\`/\`nestEnd\` are arrays of EXISTING test-case ids reused as nested steps around the recording, so the produced draft is composed as **[nestStart…] → recorded activity → [nestEnd…]**. **\`web\` returns immediately with \`{ sessionId, status: "recording" }\` and opens a live browser window** — it does NOT block or return a draft. **Call it ONCE; never retry it** (a browser is already recording).
|
|
63
66
|
- **Then POLL \`web_status({ sessionId })\`** every ~15–20 s until \`status\` is \`"done"\` (or \`"error"\`). While it says \`"recording"\`, wait and poll again — do NOT call \`web\` again. On \`"done"\` it returns the assembled draft (\`{ draftId, tc, stepCount }\`), an UNSAVED draft.
|
|
64
67
|
- **When you reuse a Login via \`nestStart\`, record only what happens AFTER sign-in** — don't record the login again (the nested one does it at run time). Reuse a signed-in \`profile\` so the recording browser starts already authenticated and the recorded steps are pure activity. Same idea for a Logout via \`nestEnd\`: don't record the sign-out.
|
|
65
|
-
- **REVIEW BEFORE SAVING — never auto-save. This applies to EVERY technology.** When the poll tool (\`web_status\`, \`mainframe_status\`, …) reports \`"done"\`, show the user the recorded steps in plain language (including the nested Login/Logout wrappers) and ask them to confirm or request changes. A finished recording is an UNSAVED draft and nothing is persisted until they approve. Call **\`tc_save({ draftId })\`** ONLY when the user EXPLICITLY tells you to (e.g. "save it", "save this one", "persist it", "okay save"). Finishing a recording is NOT permission to save, and neither is the user saying the draft "looks good" / "nice" / "that's right" — those are approval of the CONTENT, not an instruction to persist it; if you are unsure whether a reply was a save instruction, ASK. The user may instead save it themselves in the Walnut UI — that's fine; do NOT also \`tc_save\` (it would duplicate). \`tc_save\` persists it as a DRAFT test case and opens it in the real Walnut UI for review / edit / run.
|
|
68
|
+
- **REVIEW BEFORE SAVING — never auto-save. This applies to EVERY technology.** When the poll tool (\`web_status\`, \`mainframe_status\`, …) reports \`"done"\`, show the user the recorded steps in plain language (including the nested Login/Logout wrappers) and ask them to confirm or request changes. A finished recording is an UNSAVED draft and nothing is persisted until they approve. **Being asked to "record a test case" / "create this test" is an instruction to RECORD (produce this draft) — it is NOT an instruction to save; recording and saving are SEPARATE steps, so STOP at the draft and ask.** Call **\`tc_save({ draftId })\`** ONLY when the user EXPLICITLY tells you to (e.g. "save it", "save this one", "persist it", "okay save"). Finishing a recording is NOT permission to save, and neither is the user saying the draft "looks good" / "nice" / "that's right" — those are approval of the CONTENT, not an instruction to persist it; if you are unsure whether a reply was a save instruction, ASK. The user may instead save it themselves in the Walnut UI — that's fine; do NOT also \`tc_save\` (it would duplicate). \`tc_save\` persists it as a DRAFT test case and opens it in the real Walnut UI for review / edit / run.
|
|
66
69
|
- **\`mainframe({ task, appPath?, attachOnly?, nestStart?, nestEnd? })\`** — the SAME two-step shape for TN3270 terminals: it launches the emulator, attaches over HLLAPI, drives the screens (reading, sending text/AID keys, capturing each field by label + row/col), then you **poll \`mainframe_status({ sessionId })\`** until \`"done"\`. Pass \`appPath\` (the emulator SESSION FILE) so the emulator gets launched and step 1 records as "Launch \${app_path}" — omit it only to attach to an already-open emulator. The extension identifies the emulator: **\`.ecf\` = Quick3270, \`.ws\` = IBM Personal Communications, \`.rd3x\`/\`.rd5x\` = Micro Focus Reflection**. **If you do not know the path, ASK THE USER for it — do NOT go searching the filesystem**, and do NOT assume an extension (guessing \`.ws\` on a Quick3270 machine finds nothing and wastes the turn). Two constraints worth stating up front: it needs the agent on **Windows with WINDOWS_MCP_ENABLED**; and mainframe recordings **cannot overlap** (one HLLAPI session admits one attachment, so a second call is refused, not queued). Mainframe DOES record assertions — \`mf_verify_screen\` / \`mf_verify_field\` run against the live terminal — so include what to verify in the \`task\`, exactly as you would for web.
|
|
67
70
|
- **\`android({ task })\` / \`db({ task })\`** — same shape for their technologies; declared but not built yet (they reply "not available yet").
|
|
68
71
|
- Write ONE self-contained \`task\`: include the URL, the REAL values (passwords too — sensitive fields are parameterized to \`\${...}\` automatically), and the assertion. If a step needs a human (OTP / CAPTCHA / first login), say so in the task so the sub-agent pauses for it.
|
|
@@ -70,39 +73,57 @@ Hand the whole recording to the sub-agent for the target technology; it opens a
|
|
|
70
73
|
## Stories → manual test cases → automate
|
|
71
74
|
Pull up user stories, draft MANUAL test cases for them, and later promote those to automated.
|
|
72
75
|
- **Discover stories** — **\`story_list({ search? })\`** finds stories by keyword (key / title / description / acceptance criteria); **\`story_get({ id })\`** reads ONE (id or business key like \`US_12\`) with its **acceptance criteria**. When the user asks about stories ("show me the login stories", "what's US_12"), start here.
|
|
73
|
-
- **Create MANUAL test cases for a story (YOU draft them).** Read the story's acceptance criteria with \`story_get\`, then author manual test cases that COVER them — a happy-path case plus the negative / edge cases the criteria imply. Draft each with **\`tc_draft_create({ title, category: "manual", storyRef: "<story id or US_ key>", steps: [...] })\`**. Each manual step is PLAIN PROSE — a clear \`description\` and a non-empty \`expectedResult\`, \`actionType: "manual"\`, \`stepType: "web"\`; **no locators** (manual tests aren't executable until automated). \`storyRef\` links every case back to the story. Show the drafted cases in plain language; revise with \`tc_draft_update\` on request.
|
|
76
|
+
- **Create MANUAL test cases for a story (YOU draft them).** Read the story's acceptance criteria with \`story_get\`, then author manual test cases that COVER them — a happy-path case plus the negative / edge cases the criteria imply (unless the user asks for a specific count, then draft exactly that). Draft each with **\`tc_draft_create({ title, category: "manual", storyRef: "<story id or US_ key>", folderOrModule?: "<module id>", steps: [...] })\`**. Each manual step is PLAIN PROSE — a clear \`description\` and a non-empty \`expectedResult\`, \`actionType: "manual"\`, \`stepType: "web"\`; **no locators** (manual tests aren't executable until automated). \`storyRef\` links every case back to the story. **On SimplifyQA, call \`list_modules\` and ASK the user which module to file the test case(s) under, then pass its id as \`folderOrModule\`; Walnut has no modules — skip this step.** Show the drafted cases in plain language; revise with \`tc_draft_update\` on request.
|
|
74
77
|
- **SAVING IS ALWAYS AN EXPLICIT USER ACTION — never save on your own.** A drafted manual test case stays an UNSAVED draft. Call **\`tc_save({ draftId })\`** ONLY when the user EXPLICITLY tells you to (e.g. "save it", "save these", "persist it", "okay save"). Do NOT save just because you finished drafting or the user said the draft "looks good" — wait for an explicit save instruction. The user may instead review and **save it themselves in the Walnut UI** — that's fine; do NOT also \`tc_save\` (it would duplicate). Until an explicit save (in a prompt, or done in the UI), leave every drafted test case unsaved.
|
|
75
|
-
- **Automate a manual test case
|
|
78
|
+
- **Automate a manual test case** — **\`tc_automate({ tcId, url, extra? })\`** returns a recording guide built from the manual steps. First ASK the user for the app **URL** and any **credentials / data / assertions** (pass them as \`url\` + \`extra\`). \`profile\` reuses a signed-in browser profile. **Behavior depends on the connected product — the tool result tells you which path:**
|
|
79
|
+
- **Walnut (promote IN PLACE):** the tool drives a REAL browser recording, then REPLACES that test case's steps with the recorded ones (real locators) and flips it to \`automated\`, keeping the story link. The manual steps are **superseded** — confirm with the user before automating, since it overwrites them.
|
|
80
|
+
- **SimplifyQA (new automated TC via recorder UI):** no server-side recorder loop — the tool returns a GUIDE and you drive the recording yourself. Start by calling **\`core_activate_technology({ technology: 'WEB', testcaseName, userstoryId?, moduleId? })\`** where \`testcaseName\` is the source TC title, and \`userstoryId\` / \`moduleId\` are the **numeric suffixes** of the source TC's \`storyRef\` / \`folderOrModule\` (strip the business-key prefix — \`US_7\` → \`7\`, \`MOD_12\` → \`12\`). Then \`web_launch_application(url)\` and walk the manual steps with the granular verbs (\`web_snapshot\`, \`web_click\`, \`web_enter_text\`, …). When done, STOP and ask the user to Save in the recorder UI — that creates a **NEW automated TC** with the story link already selected; the source manual TC (\`tcId\`) stays untouched. Do NOT call \`tc_save\` / \`update_testcase\` / \`journal_modify\` on this path — the UI Save is the persist step.
|
|
76
81
|
|
|
77
82
|
## Run — execute & triage
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
+
Runs are AUTOMATED-only — a MANUAL test case can't be run or scheduled by an agent (the backend refuses it). **NEVER assume anything** — walk the user through these IN ORDER, asking each and WAITING for the answer before the next (this mirrors the product UI exactly):
|
|
84
|
+
1. **Local or cloud?** — ASK; never guess.
|
|
85
|
+
2. **Now or scheduled?** — ASK; never guess.
|
|
86
|
+
3. **If scheduled** — BEFORE offering any agent, ASK the START time (\`scheduledFor\`, ISO), the RECURRENCE (\`scheduleType\`: once / hourly / daily / weekdays / weekly / monthly — default once; hourly/daily/weekdays need an \`endDate\`) and the TIMEZONE.
|
|
87
|
+
4. **Browser?** — OFFER a choice for EVERY run (test case OR suite, local OR cloud, now OR scheduled): **chromium** (default), **chrome**, **msedge**, **firefox**, **webkit** → pass as \`browser\`. A SCHEDULE accepts only chromium / msedge / firefox / webkit (NOT chrome). If the user has no preference, default chromium — but always let them choose.
|
|
88
|
+
5. **THEN offer the agent/runner** — the AVAILABLE list depends on where AND when:
|
|
89
|
+
- **local + now** → call **\`local_agents\`** and offer ONLY the **ONLINE** agents (a run-now can't target an offline agent). Pass the chosen one as **\`agentId\`** (or omit to auto-pick the user's own online agent).
|
|
90
|
+
- **local + scheduled** → call **\`local_agents\`** and offer **ALL** agents — **ONLINE and OFFLINE** (a schedule can target an agent that's offline now; it runs when it fires). **\`agentId\` is REQUIRED** here — a schedule has no live session to fall back to.
|
|
91
|
+
- **cloud (now OR scheduled)** → call **\`cloud_runners\`** and offer ONLY the **ONLINE** runners; if none are online, say *"there are no active cloud runners in your project"* and STOP (never silently fall back to local). Pass the chosen one as **\`cloudRunnerId\`** (for a schedule, omit it to let the backend auto-pick a live VM at fire time).
|
|
92
|
+
- Agents/runners read as **owner · hostname** (e.g. *rishi · SIMLAP24*) — present them that way so the user recognizes their machine; the credential id is only for the tool call.
|
|
93
|
+
6. **Execute:**
|
|
94
|
+
- **now** → **\`tc_run({ tcId, mode, when: "immediate", browser?, agentId? | cloudRunnerId? })\`** → a run id; then **poll \`run_status\`** until terminal (passed / failed / stopped / error). Don't call a still-\`queued\`/\`running\` run a result; if it stayed \`queued\` and never started, the agent likely didn't pick it up — say that, not "pass". **\`run_stop\`** cancels a run.
|
|
95
|
+
- **scheduled** → **\`tc_run({ tcId, mode, when: "schedule", scheduledFor, scheduleType?, endDate?, timezone?, browser?, agentId (local) | cloudRunnerId? (cloud) })\`** → a schedule id (there's no run to poll).
|
|
96
|
+
7. **Report** plainly: pass / fail, step counts, the FAILING step + its error, the report link. **Triage, don't fix** — a broken locator or changed app → offer to re-delegate that flow to the sub-agent.
|
|
97
|
+
- **Suites:** **\`suite_run\`** follows the SAME ordered flow (local/cloud → now/scheduled → time-if-scheduled → browser → offer the right agent/runner list), plus cloud-only \`strategy\` / \`maxConcurrent\` / \`terminateOnFailure\` for an IMMEDIATE run. An immediate suite run returns a suite-run id you poll with the SAME **\`run_status\`** (it lists each test case's pass/fail) and cancel with **\`run_stop\`**.
|
|
98
|
+
- **Suite membership:** **\`suite_add_testcases({ suiteId, tcIds })\`** and **\`suite_remove_testcases({ suiteId, tcIds })\`** add / remove test cases (find ids via \`suite_list\` + \`tc_list\`; confirm the target suite when the user names it loosely). A suite holds ONE category — all manual OR all automated; the product rejects a mix.
|
|
99
|
+
- **Manage schedules:** **\`schedule_list\`** shows every schedule (what it runs, cadence, next run, status, pinned agent, browser) — start there to find the one the user means. Then **\`schedule_update\`** edits it (time / recurrence / end date / timezone / browser / environment, or RE-PIN via \`mode\` + \`agentId\` (local) / \`cloudRunnerCredentialId\` (cloud) — the same eligibility rules as a new run), **\`schedule_control({ scheduleId, action })\`** pauses / resumes / cancels it, and **\`schedule_delete\`** removes it PERMANENTLY. Confirm before deleting — it's irreversible; suggest pause/cancel when the user only wants to stop it for now.
|
|
83
100
|
|
|
84
101
|
## Modify a test case
|
|
85
102
|
Edit an EXISTING test case's steps from here — no re-recording needed for structure.
|
|
86
103
|
- **\`journal_grep({ tcId, pattern? })\`** FIRST — shows the NUMBERED steps (the numbers the edit ops use); \`pattern\` filters to locate a range.
|
|
87
|
-
- **\`journal_modify({ tcId, ops })\`** — apply edits, opens the result in the editor. Ops: \`wrap_in_loop { from, to }\` / \`wrap_in_if { from, to }\` (wrap that step range), \`insert_nested { at, tcId }\` (reuse an existing TC as a nested step), \`add_step\` / \`update_step\` / \`remove_step\` / \`move_step\`, and \`set_meta { patch: { title?, description?, priority?, … } }\` to RENAME / edit test-case metadata.
|
|
104
|
+
- **\`journal_modify({ tcId, ops })\`** — apply edits, opens the result in the editor. Ops: \`wrap_in_loop { from, to }\` / \`wrap_in_if { from, to }\` (wrap that step range), \`insert_nested { at, tcId }\` (reuse an existing TC as a nested step), \`add_step\` / \`update_step\` / \`remove_step\` / \`move_step\`, and \`set_meta { patch: { title?, description?, priority?, … } }\` to RENAME / edit test-case metadata. **On SimplifyQA, only \`update_step\` / \`remove_step\` / \`move_step\` are supported** — its journal mutates captured entries only, so \`add_step\` / wraps / nested inserts / \`set_meta\` are not available there.
|
|
88
105
|
- **\`tc_delete({ tcId })\`** — delete a test case (recoverable from the product recycle bin).
|
|
89
106
|
- Loop / if-else / nested / remove / move / edit-existing all persist cleanly. Adding a brand-new INTERACTION step (click/type a NEW element) has no captured locator → it's a manual, non-executable step; to add a real interaction, RECORD it instead.
|
|
90
107
|
|
|
91
108
|
## Always
|
|
92
|
-
- **NEVER save on your own — \`tc_save\` is an EXPLICIT user action ONLY.** A test case (recorded draft OR manual draft) is persisted only when the user EXPLICITLY says so (e.g. "save this test case", "save it", "persist it", "okay save"). Finishing a recording, or the user approving the CONTENT ("looks good", "nice", "correct"), is NOT a save instruction — if unsure whether a reply meant save, ASK rather than saving. The user may instead save it themselves in the Walnut UI; then do NOT also \`tc_save\` (it would duplicate).
|
|
109
|
+
- **NEVER save on your own — \`tc_save\` is an EXPLICIT user action ONLY.** A test case (recorded draft OR manual draft) is persisted only when the user EXPLICITLY says so (e.g. "save this test case", "save it", "persist it", "okay save"). **An instruction to RECORD / CREATE / AUTOMATE a test case is an instruction to produce the DRAFT — NOT to save it; recording/drafting and saving are SEPARATE steps.** After a recording finishes or a draft is authored, STOP at the draft, show it, and ask — do not chain into \`tc_save\`. Finishing a recording, or the user approving the CONTENT ("looks good", "nice", "correct"), is NOT a save instruction — if unsure whether a reply meant save, ASK rather than saving. The user may instead save it themselves in the Walnut UI; then do NOT also \`tc_save\` (it would duplicate).
|
|
93
110
|
- One door: you call the lifecycle tools + the technology sub-agents; the product and which technology are resolved downstream. Delegate with a complete, self-contained task. Never fabricate — read every result from the tools. Show steps in plain language, not code.`,
|
|
94
111
|
};
|
|
95
112
|
const AGENTS = [COMMON_QA_AGENT];
|
|
96
|
-
const ALL_LOOPS = ['claude', 'cursor', 'windsurf', 'vscode', 'codex'];
|
|
97
|
-
const yamlList = (items) => items.map((t) => ` - ${t}`).join('\n');
|
|
113
|
+
const ALL_LOOPS = ['claude', 'cursor', 'windsurf', 'vscode', 'codex', 'devin'];
|
|
98
114
|
const toolsNote = (a) => `\n\n## Allowed QA tools\nUse only these:\n${a.tools.map((t) => `- \`${t}\``).join('\n')}\n`;
|
|
99
|
-
/**
|
|
100
|
-
|
|
115
|
+
/** Default MCP server name (also the npm package name). The scoped tool-wildcards reference the NAME
|
|
116
|
+
* the user gave this server in their editor's mcp config — Claude/Devin `mcp__<server>__*`, VS Code
|
|
117
|
+
* `<server>/*` — so it must match. Resolved as: `--server-name` flag > this default. */
|
|
118
|
+
const DEFAULT_MCP = 'common-qa-mcp';
|
|
119
|
+
/** One agent → { path, content } for a per-file client. (codex uses the AGENTS.md writer.) */
|
|
120
|
+
function fileFor(loop, a, mcp) {
|
|
101
121
|
switch (loop) {
|
|
102
|
-
case 'claude': // Claude Code subagent —
|
|
122
|
+
case 'claude': // Claude Code subagent — name/model/color + a SCOPED MCP wildcard (mcp__<server>__*)
|
|
123
|
+
// grants every common-qa-mcp tool (none drop) and nothing else (the editor's own tools stay out).
|
|
103
124
|
return {
|
|
104
125
|
path: `.claude/agents/${a.slug}.md`,
|
|
105
|
-
content: `---\nname: ${a.slug}\ndescription: ${a.description}\nmodel: ${a.model}\ncolor: ${a.color}\ntools:\n${
|
|
126
|
+
content: `---\nname: ${a.slug}\ndescription: ${a.description}\nmodel: ${a.model}\ncolor: ${a.color}\ntools:\n - mcp__${mcp}__*\n---\n\n${a.body}${toolsNote(a)}`,
|
|
106
127
|
};
|
|
107
128
|
case 'cursor': // Cursor project rule (.mdc)
|
|
108
129
|
return {
|
|
@@ -114,10 +135,18 @@ function fileFor(loop, a) {
|
|
|
114
135
|
path: `.windsurf/rules/${a.slug}.md`,
|
|
115
136
|
content: `---\ntrigger: model_decision\ndescription: ${a.description}\n---\n\n${a.body}${toolsNote(a)}`,
|
|
116
137
|
};
|
|
117
|
-
case 'vscode': // VS Code custom
|
|
138
|
+
case 'vscode': // VS Code custom agent (.agent.md, current format) — SCOPED MCP wildcard <server>/*
|
|
139
|
+
// grants every common-qa-mcp tool (none drop) and nothing else (the editor's own tools stay out).
|
|
118
140
|
return {
|
|
119
141
|
path: `.github/agents/${a.slug}.agent.md`,
|
|
120
|
-
content: `---\
|
|
142
|
+
content: `---\nname: ${a.slug}\ndescription: ${a.description}\ntools: ['${mcp}/*']\n---\n\n${a.body}${toolsNote(a)}`,
|
|
143
|
+
};
|
|
144
|
+
case 'devin': // Devin custom SUBAGENT — .devin/agents/<name>.md. Devin imports Claude Code's agent
|
|
145
|
+
// format, so this mirrors the claude case: a SCOPED mcp__<server>__* allowlist (every common-qa-mcp
|
|
146
|
+
// tool, none drop; the editor's own tools stay out) + the persona body.
|
|
147
|
+
return {
|
|
148
|
+
path: `.devin/agents/${a.slug}.md`,
|
|
149
|
+
content: `---\nname: ${a.slug}\ndescription: ${a.description}\ntools:\n - mcp__${mcp}__*\n---\n\n${a.body}${toolsNote(a)}`,
|
|
121
150
|
};
|
|
122
151
|
}
|
|
123
152
|
}
|
|
@@ -131,6 +160,18 @@ function parseLoop(args) {
|
|
|
131
160
|
}
|
|
132
161
|
return null;
|
|
133
162
|
}
|
|
163
|
+
/** Parse `--server-name=<name>` / `--server-name <name>` — the MCP server name baked into the scoped
|
|
164
|
+
* tool-wildcards (must match the mcpServers key in the user's mcp.json). */
|
|
165
|
+
function parseServerName(args) {
|
|
166
|
+
for (let i = 0; i < args.length; i++) {
|
|
167
|
+
const a = args[i];
|
|
168
|
+
if (a.startsWith('--server-name='))
|
|
169
|
+
return a.slice('--server-name='.length);
|
|
170
|
+
if (a === '--server-name')
|
|
171
|
+
return args[i + 1] ?? null;
|
|
172
|
+
}
|
|
173
|
+
return null;
|
|
174
|
+
}
|
|
134
175
|
function writeFile(cwd, rel, content, loop) {
|
|
135
176
|
const target = join(cwd, rel);
|
|
136
177
|
mkdirSync(dirname(target), { recursive: true });
|
|
@@ -147,6 +188,13 @@ export async function runInitAgents(args) {
|
|
|
147
188
|
}
|
|
148
189
|
const loops = loopArg === 'all' ? [...ALL_LOOPS] : [loopArg];
|
|
149
190
|
const cwd = process.cwd();
|
|
191
|
+
// MCP server NAME for the scoped tool-wildcards. Each editor stores its MCP config in a different
|
|
192
|
+
// file/format (Claude .mcp.json, Cursor .cursor/mcp.json, Devin .devin/mcp_config.json, VS Code
|
|
193
|
+
// .vscode/mcp.json `servers`, Codex .codex/config.toml), so there's no single file to auto-detect
|
|
194
|
+
// from — the name comes from an explicit --server-name flag, else the package-name default. Name the
|
|
195
|
+
// server this in each editor's config (or pass --server-name) so the wildcard resolves. Logged below.
|
|
196
|
+
const serverName = parseServerName(args) ?? DEFAULT_MCP;
|
|
197
|
+
process.stderr.write(`init-agents: scoping tool wildcards to MCP server "${serverName}" (override with --server-name)\n`);
|
|
150
198
|
for (const loop of loops) {
|
|
151
199
|
if (loop === 'codex') {
|
|
152
200
|
// Codex / generic AGENTS.md — one repo-wide file holding the single Common QA agent.
|
|
@@ -167,7 +215,7 @@ export async function runInitAgents(args) {
|
|
|
167
215
|
continue;
|
|
168
216
|
}
|
|
169
217
|
for (const a of AGENTS) {
|
|
170
|
-
const { path, content } = fileFor(loop, a);
|
|
218
|
+
const { path, content } = fileFor(loop, a, serverName);
|
|
171
219
|
writeFile(cwd, path, content, loop);
|
|
172
220
|
}
|
|
173
221
|
}
|
package/dist/initAgents.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"initAgents.js","sourceRoot":"","sources":["../src/initAgents.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAuB1C;6EAC6E;AAC7E,MAAM,YAAY,GAAG;;;;;;0DAMqC,CAAC;AAE3D;gGACgG;AAChG,MAAM,eAAe,GAAa;IAChC,IAAI,EAAE,iBAAiB;IACvB,WAAW,EACT,kGAAkG;QAClG,qGAAqG;QACrG,6FAA6F;QAC7F,qEAAqE;IACvE,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE;QACL,oCAAoC;QACpC,6BAA6B,EAAE,iCAAiC,EAAE,4BAA4B;QAC9F,uBAAuB,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,yBAAyB;QACnG,sBAAsB,EAAE,0BAA0B,EAAE,wBAAwB,EAAE,6BAA6B;
|
|
1
|
+
{"version":3,"file":"initAgents.js","sourceRoot":"","sources":["../src/initAgents.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,13 +8,15 @@ import type { ConnectRequest } from './connection.js';
|
|
|
8
8
|
* "x-qa-url": "http://localhost:8080", "x-project-id": "<id>" } }
|
|
9
9
|
*
|
|
10
10
|
* - token <- `Authorization: Bearer …` (scheme stripped; `x-qa-token` also accepted)
|
|
11
|
-
* - url <- `?url=` | `x-qa-url`
|
|
12
|
-
*
|
|
11
|
+
* - url <- `?url=` | `x-qa-url` | QA_MCP_URL (the MCP endpoint to hop to: agent /mcp for
|
|
12
|
+
* walnut recording, or the SQA /mcp)
|
|
13
|
+
* - baseUrl <- `?baseUrl=` | `x-qa-base-url` | QA_BASE_URL (the Walnut BACKEND REST base, for
|
|
14
|
+
* DIRECT data ops; a walnut session can connect with baseUrl alone)
|
|
13
15
|
* - product <- `?product=` | `x-qa-product` | QA_MCP_PROVIDER (default 'walnut')
|
|
14
16
|
* - projectId<- `?projectId=` | `x-project-id` | QA_MCP_PROJECT_ID
|
|
15
17
|
* - auth <- `?auth=` | `x-qa-auth` ('jwt' | 'key')
|
|
16
18
|
*
|
|
17
|
-
* Returns null when there is no usable token+url, so the offline authoring path is untouched.
|
|
19
|
+
* Returns null when there is no usable token + (url|baseUrl), so the offline authoring path is untouched.
|
|
18
20
|
*/
|
|
19
21
|
export declare function connectionFromRequest(req: Request): ConnectRequest | null;
|
|
20
22
|
//# sourceMappingURL=requestConnection.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestConnection.d.ts","sourceRoot":"","sources":["../src/requestConnection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAetD
|
|
1
|
+
{"version":3,"file":"requestConnection.d.ts","sourceRoot":"","sources":["../src/requestConnection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAetD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,GAAG,IAAI,CAgBzE"}
|
|
@@ -18,27 +18,33 @@ function firstQuery(req, name) {
|
|
|
18
18
|
* "x-qa-url": "http://localhost:8080", "x-project-id": "<id>" } }
|
|
19
19
|
*
|
|
20
20
|
* - token <- `Authorization: Bearer …` (scheme stripped; `x-qa-token` also accepted)
|
|
21
|
-
* - url <- `?url=` | `x-qa-url`
|
|
22
|
-
*
|
|
21
|
+
* - url <- `?url=` | `x-qa-url` | QA_MCP_URL (the MCP endpoint to hop to: agent /mcp for
|
|
22
|
+
* walnut recording, or the SQA /mcp)
|
|
23
|
+
* - baseUrl <- `?baseUrl=` | `x-qa-base-url` | QA_BASE_URL (the Walnut BACKEND REST base, for
|
|
24
|
+
* DIRECT data ops; a walnut session can connect with baseUrl alone)
|
|
23
25
|
* - product <- `?product=` | `x-qa-product` | QA_MCP_PROVIDER (default 'walnut')
|
|
24
26
|
* - projectId<- `?projectId=` | `x-project-id` | QA_MCP_PROJECT_ID
|
|
25
27
|
* - auth <- `?auth=` | `x-qa-auth` ('jwt' | 'key')
|
|
26
28
|
*
|
|
27
|
-
* Returns null when there is no usable token+url, so the offline authoring path is untouched.
|
|
29
|
+
* Returns null when there is no usable token + (url|baseUrl), so the offline authoring path is untouched.
|
|
28
30
|
*/
|
|
29
31
|
export function connectionFromRequest(req) {
|
|
30
32
|
const authz = firstHeader(req, 'authorization') ?? '';
|
|
31
33
|
const token = ((authz.replace(/^Bearer\s+/i, '')) || firstHeader(req, 'x-qa-token') || '').trim();
|
|
32
34
|
if (!token)
|
|
33
35
|
return null;
|
|
36
|
+
// `url` = the MCP endpoint to hop to (agent /mcp for walnut recording, or the SQA /mcp).
|
|
37
|
+
// `baseUrl` = the Walnut BACKEND REST base for DIRECT data ops (QA_BASE_URL). Either one (with a
|
|
38
|
+
// token) is a usable connection; a walnut direct session needs only baseUrl.
|
|
34
39
|
const url = (firstQuery(req, 'url') ?? firstHeader(req, 'x-qa-url') ?? process.env['QA_MCP_URL'] ?? '').trim();
|
|
35
|
-
|
|
40
|
+
const baseUrl = (firstQuery(req, 'baseUrl') ?? firstHeader(req, 'x-qa-base-url') ?? process.env['QA_BASE_URL'] ?? '').trim();
|
|
41
|
+
if (!url && !baseUrl)
|
|
36
42
|
return null;
|
|
37
43
|
const productRaw = firstQuery(req, 'product') ?? firstHeader(req, 'x-qa-product') ?? process.env['QA_MCP_PROVIDER'] ?? '';
|
|
38
44
|
const product = productRaw === 'simplifyqa' ? 'simplifyqa' : 'walnut';
|
|
39
45
|
const projectId = (firstQuery(req, 'projectId') ?? firstHeader(req, 'x-project-id') ?? process.env['QA_MCP_PROJECT_ID'] ?? '').trim();
|
|
40
46
|
const authRaw = firstQuery(req, 'auth') ?? firstHeader(req, 'x-qa-auth') ?? '';
|
|
41
47
|
const auth = authRaw === 'key' ? 'key' : authRaw === 'jwt' ? 'jwt' : undefined;
|
|
42
|
-
return {
|
|
48
|
+
return { token, product, ...(url ? { url } : {}), ...(baseUrl ? { baseUrl } : {}), ...(projectId ? { projectId } : {}), ...(auth ? { auth } : {}) };
|
|
43
49
|
}
|
|
44
50
|
//# sourceMappingURL=requestConnection.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"requestConnection.js","sourceRoot":"","sources":["../src/requestConnection.ts"],"names":[],"mappings":"AAGA,iGAAiG;AACjG,iGAAiG;AAEjG,SAAS,WAAW,CAAC,GAAY,EAAE,IAAY;IAC7C,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,OAAO,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACrC,CAAC;AACD,SAAS,UAAU,CAAC,GAAY,EAAE,IAAY;IAC5C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC1B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3C,CAAC;AAED
|
|
1
|
+
{"version":3,"file":"requestConnection.js","sourceRoot":"","sources":["../src/requestConnection.ts"],"names":[],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAU/C,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;AAEnB;;;;;;;;;GASG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,OAAO,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC;kEAC8D;IAC9D,UAAU,CAAC,EAAE,YAAY,GAAG,SAAS,CAAC;IACtC,IAAI,CAAC,EAAE,WAAW,GAAG,SAAS,GAAG,SAAS,CAAC;IAC3C,MAAM,CAAC,EAAE,UAAU,GAAG,SAAS,CAAC;IAChC,cAAc,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,gBAAgB,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,SAAS,CAAC;CACnF,CAAC;AAIF,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,SAAS,CAoGvD"}
|
package/dist/server.js
CHANGED
|
@@ -3,13 +3,17 @@ import { DraftStore } from './drafts/store.js';
|
|
|
3
3
|
import { registerTestcaseTools } from './tools/testcase.tools.js';
|
|
4
4
|
import { registerConnectionTools } from './tools/connection.tools.js';
|
|
5
5
|
import { registerDiscoveryTools } from './tools/discovery.tools.js';
|
|
6
|
+
import { registerStorySyncTools } from './tools/storySync.tools.js';
|
|
6
7
|
import { registerRunTools } from './tools/run.tools.js';
|
|
8
|
+
import { registerTestdataTools } from './tools/testdata.tools.js';
|
|
9
|
+
import { registerFormulaTools } from './tools/formulas.tools.js';
|
|
7
10
|
import { registerRecordingPassthrough } from './tools/recording.tools.js';
|
|
11
|
+
import { registerHealTools } from './tools/heal.tools.js';
|
|
8
12
|
import { ok, err } from './mcpResult.js';
|
|
9
13
|
export { ok, err };
|
|
10
14
|
const OFFLINE_TOOLS = ['actions_catalog', 'tc_draft_create', 'tc_draft_update', 'tc_draft_get', 'tc_draft_discard', 'tc_draft_open'];
|
|
11
15
|
export function buildServer(deps) {
|
|
12
|
-
const server = new McpServer({ name: 'common-qa-mcp', version: '0.
|
|
16
|
+
const server = new McpServer({ name: 'common-qa-mcp', version: '0.3.0' });
|
|
13
17
|
const drafts = deps.drafts ?? new DraftStore();
|
|
14
18
|
server.registerTool('project_info', {
|
|
15
19
|
description: 'Validate the configured connection and return provider, org/project and entity counts.',
|
|
@@ -25,7 +29,7 @@ export function buildServer(deps) {
|
|
|
25
29
|
`Available offline: ${OFFLINE_TOOLS.join(', ')}.\n` +
|
|
26
30
|
'Author a draft with tc_draft_create / tc_draft_update and open it with tc_draft_open.\n\n' +
|
|
27
31
|
'To work with EXISTING test cases (list, read, modify, run), connect first:\n' +
|
|
28
|
-
' qa_connect({ url: "https://<your-product>", token: "<token>", projectId: "<id>"
|
|
32
|
+
' qa_connect({ url: "https://<your-product>", token: "<token>", projectId: "<id>" })', { mode: 'offline', availableTools: OFFLINE_TOOLS, ...(live ? { connection: live } : {}) });
|
|
29
33
|
}
|
|
30
34
|
if (!adapter)
|
|
31
35
|
return err('No provider configured. Use qa_connect, or set QA_MCP_URL/TOKEN/PROJECT_ID.');
|
|
@@ -55,11 +59,31 @@ export function buildServer(deps) {
|
|
|
55
59
|
registerDiscoveryTools(server, {
|
|
56
60
|
getAdapter: () => (deps.connection ? deps.connection.adapter() : deps.adapter),
|
|
57
61
|
});
|
|
62
|
+
// Story ↔ manual-testcase drift detection (report-only; agent applies via tc_draft_*).
|
|
63
|
+
registerStorySyncTools(server, {
|
|
64
|
+
getAdapter: () => (deps.connection ? deps.connection.adapter() : deps.adapter),
|
|
65
|
+
});
|
|
58
66
|
// Run surface (cloud_runners / tc_run / run_status / run_stop) -- same live-connection-wins rule;
|
|
59
67
|
// the run is forwarded to the product MCP (local dispatches to the agent, cloud to a runner VM).
|
|
60
68
|
registerRunTools(server, {
|
|
61
69
|
getAdapter: () => (deps.connection ? deps.connection.adapter() : deps.adapter),
|
|
62
70
|
});
|
|
71
|
+
// Testdata generation (tc_generate_testdata) -- fetches the default iteration template from the
|
|
72
|
+
// product MCP, generates N rows client-side, and posts them back via save_generated_iterations.
|
|
73
|
+
registerTestdataTools(server, {
|
|
74
|
+
getAdapter: () => (deps.connection ? deps.connection.adapter() : deps.adapter),
|
|
75
|
+
});
|
|
76
|
+
// Formula discovery (tc_list_formulas) — companion to tc_generate_testdata's `formulas` option, so
|
|
77
|
+
// the model can enumerate DEFAULT prefabs + CUSTOM formulas before picking one.
|
|
78
|
+
registerFormulaTools(server, {
|
|
79
|
+
getAdapter: () => (deps.connection ? deps.connection.adapter() : deps.adapter),
|
|
80
|
+
});
|
|
81
|
+
// Heal surface (tc_heal) — product-neutral proxy. The real loop (replay + snapshot + propose +
|
|
82
|
+
// verify) lives in the product agent and is invoked via adapter.callRaw. Same live-connection-
|
|
83
|
+
// wins rule as run/discovery tools.
|
|
84
|
+
registerHealTools(server, {
|
|
85
|
+
getAdapter: () => (deps.connection ? deps.connection.adapter() : deps.adapter),
|
|
86
|
+
});
|
|
63
87
|
// Recording passthrough: mirror the product agent's browser-recording tools onto this server so
|
|
64
88
|
// the client records through the one door. Agent-bound + forwarded (see recording.tools.ts).
|
|
65
89
|
// Async + fire-and-forget: it waits for the connection, then registerTool emits list_changed.
|
package/dist/server.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAGpE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,2BAA2B,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,6BAA6B,CAAC;AACtE,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,4BAA4B,EAAE,MAAM,4BAA4B,CAAC;AAC1E,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AAEzC,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC;AAwBnB,MAAM,aAAa,GAAG,CAAC,iBAAiB,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC;AAErI,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;IAE/C,MAAM,CAAC,YAAY,CAAC,cAAc,EAAE;QAClC,WAAW,EAAE,wFAAwF;QACrG,WAAW,EAAE,EAAE,EAAE,WAAW,EAAE,EAAE,YAAY,EAAE,IAAI,EAAE;KACrD,EAAE,KAAK,IAAI,EAAE;QACZ,8FAA8F;QAC9F,uFAAuF;QACvF,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;QAC3E,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;QAE1C,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;YACvB,OAAO,EAAE,CACP,uEAAuE;gBACrE,sBAAsB,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK;gBACnD,2FAA2F;gBAC3F,8EAA8E;gBAC9E,
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.tools.d.ts","sourceRoot":"","sources":["../../src/tools/connection.tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"connection.tools.d.ts","sourceRoot":"","sources":["../../src/tools/connection.tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAGrD,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,GAAG,IAAI,CAoIzF"}
|
|
@@ -14,10 +14,10 @@ import { z } from 'zod';
|
|
|
14
14
|
import { ok, err } from '../mcpResult.js';
|
|
15
15
|
export function registerConnectionTools(server, connection) {
|
|
16
16
|
server.registerTool('qa_connect', {
|
|
17
|
-
title: 'Connect to a
|
|
18
|
-
description: 'Point this MCP at
|
|
17
|
+
title: 'Connect to a QA product',
|
|
18
|
+
description: 'Point this MCP at your QA product so it can work with EXISTING test cases -- list them, read ' +
|
|
19
19
|
'their steps, modify them, and run them. Ask the user for their app URL and a token; do not ' +
|
|
20
|
-
'guess either. The token is a
|
|
20
|
+
'guess either. The token is a product session JWT (then `projectId` is required, because the ' +
|
|
21
21
|
'token alone carries no project context) or an MCP API key (then pass auth:"key" and ' +
|
|
22
22
|
'projectId is optional -- a key is already project-scoped).\n\n' +
|
|
23
23
|
'The connection is VALIDATED before it is accepted (it fetches the project), so a wrong URL, ' +
|
|
@@ -27,20 +27,22 @@ export function registerConnectionTools(server, connection) {
|
|
|
27
27
|
'NOT needed to record a new test case: recording, the live editor and drafts work offline ' +
|
|
28
28
|
'with nothing configured.',
|
|
29
29
|
inputSchema: {
|
|
30
|
-
url: z.string().
|
|
31
|
-
token: z.string().min(1).describe('Bearer token: a
|
|
30
|
+
url: z.string().optional().describe('MCP endpoint to hop to — the product agent /mcp, used for recording and save-with-editor. OPTIONAL for a DIRECT (backend-REST) connection: pass `baseUrl` instead. Required when connecting through a remote product MCP. Must start with http:// or https://.'),
|
|
31
|
+
token: z.string().min(1).describe('Bearer token: a product session JWT, or an MCP API key.'),
|
|
32
32
|
projectId: z.string().optional().describe('Project id. REQUIRED with a JWT; optional with an API key.'),
|
|
33
|
-
auth: z.enum(['jwt', 'key']).optional().describe('Token kind.
|
|
34
|
-
product: z.enum(['walnut', 'simplifyqa']).optional().describe('Which product to
|
|
33
|
+
auth: z.enum(['jwt', 'key']).optional().describe('Token kind. Omit to AUTO-DETECT from the token (JWT-shaped → "jwt"). "jwt" sends Authorization + x-project-id; "key" sends Authorization only.'),
|
|
34
|
+
product: z.enum(['walnut', 'simplifyqa']).optional().describe('Which product to route this connection to (the product selector; defaults to the primary product). For a remote product, also pass its agent MCP `/mcp` endpoint as `url`.'),
|
|
35
|
+
baseUrl: z.string().optional().describe('The product BACKEND REST base (QA_BASE_URL) for DIRECT data ops (list/read/save/run). Provide this for a direct connection; `url` is only needed for recording / save-with-editor.'),
|
|
35
36
|
},
|
|
36
37
|
annotations: { readOnlyHint: false },
|
|
37
|
-
}, async ({ url, token, projectId, auth, product }) => {
|
|
38
|
+
}, async ({ url, token, projectId, auth, product, baseUrl }) => {
|
|
38
39
|
const result = await connection.connect({
|
|
39
|
-
url,
|
|
40
40
|
token,
|
|
41
|
+
...(url !== undefined ? { url } : {}),
|
|
41
42
|
...(projectId !== undefined ? { projectId } : {}),
|
|
42
43
|
...(auth !== undefined ? { auth } : {}),
|
|
43
44
|
...(product !== undefined ? { product } : {}),
|
|
45
|
+
...(baseUrl !== undefined ? { baseUrl } : {}),
|
|
44
46
|
});
|
|
45
47
|
if (!result.ok) {
|
|
46
48
|
return err(`Could not connect: ${result.error}\n\n` +
|
|
@@ -74,7 +76,7 @@ export function registerConnectionTools(server, connection) {
|
|
|
74
76
|
});
|
|
75
77
|
server.registerTool('qa_connection_status', {
|
|
76
78
|
title: 'Show the current connection',
|
|
77
|
-
description: 'Report whether this MCP is connected to a
|
|
79
|
+
description: 'Report whether this MCP is connected to a QA product, which URL and project, how the ' +
|
|
78
80
|
'credentials arrived (startup config vs qa_connect), and whether a token is present. The ' +
|
|
79
81
|
'token value itself is never returned.',
|
|
80
82
|
inputSchema: {},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"connection.tools.js","sourceRoot":"","sources":["../../src/tools/connection.tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,EAAE,EAAE,EAAE,GAAG,EAAE,MAAM,iBAAiB,CAAC;AAE1C,MAAM,UAAU,uBAAuB,CAAC,MAAiB,EAAE,UAAwB;IACjF,MAAM,CAAC,YAAY,CACjB,YAAY,EACZ;QACE,KAAK,EAAE,yBAAyB;QAChC,WAAW,EACT
|
|
1
|
+
{"version":3,"file":"connection.tools.js","sourceRoot":"","sources":["../../src/tools/connection.tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"discovery.tools.d.ts","sourceRoot":"","sources":["../../src/tools/discovery.tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAK5D;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kFAAkF;IAClF,UAAU,EAAE,MAAM,eAAe,GAAG,IAAI,CAAC;CAC1C,CAAC;AAeF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"discovery.tools.d.ts","sourceRoot":"","sources":["../../src/tools/discovery.tools.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAEzE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAK5D;;;;;;;GAOG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,kFAAkF;IAClF,UAAU,EAAE,MAAM,eAAe,GAAG,IAAI,CAAC;CAC1C,CAAC;AAeF,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAygBxF"}
|