common-qa-mcp 0.8.0 → 0.8.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.
Files changed (36) hide show
  1. package/dist/adapters/remoteMcp/adapter.js +1 -1
  2. package/dist/adapters/simplifyqa/adapter.d.ts +24 -0
  3. package/dist/adapters/simplifyqa/adapter.d.ts.map +1 -1
  4. package/dist/adapters/simplifyqa/adapter.js +360 -25
  5. package/dist/adapters/simplifyqa/adapter.js.map +1 -1
  6. package/dist/adapters/simplifyqa/mapper.d.ts +2 -2
  7. package/dist/adapters/simplifyqa/mapper.d.ts.map +1 -1
  8. package/dist/adapters/simplifyqa/mapper.js +257 -64
  9. package/dist/adapters/simplifyqa/mapper.js.map +1 -1
  10. package/dist/domain/types.d.ts +31 -4
  11. package/dist/domain/types.d.ts.map +1 -1
  12. package/dist/domain/validate.d.ts.map +1 -1
  13. package/dist/domain/validate.js +5 -1
  14. package/dist/domain/validate.js.map +1 -1
  15. package/dist/initAgents.d.ts.map +1 -1
  16. package/dist/initAgents.js +18 -11
  17. package/dist/initAgents.js.map +1 -1
  18. package/dist/server.d.ts.map +1 -1
  19. package/dist/server.js +6 -1
  20. package/dist/server.js.map +1 -1
  21. package/dist/tools/run.tools.d.ts +4 -0
  22. package/dist/tools/run.tools.d.ts.map +1 -1
  23. package/dist/tools/run.tools.js +200 -105
  24. package/dist/tools/run.tools.js.map +1 -1
  25. package/dist/tools/schemas.d.ts +41 -49
  26. package/dist/tools/schemas.d.ts.map +1 -1
  27. package/dist/tools/schemas.js +19 -1
  28. package/dist/tools/schemas.js.map +1 -1
  29. package/dist/tools/tcEditPublisher.d.ts +20 -0
  30. package/dist/tools/tcEditPublisher.d.ts.map +1 -0
  31. package/dist/tools/tcEditPublisher.js +46 -0
  32. package/dist/tools/tcEditPublisher.js.map +1 -0
  33. package/dist/tools/testcase.tools.d.ts.map +1 -1
  34. package/dist/tools/testcase.tools.js +299 -3
  35. package/dist/tools/testcase.tools.js.map +1 -1
  36. package/package.json +1 -1
@@ -38,7 +38,7 @@ export class RemoteMcpAdapter {
38
38
  async client() {
39
39
  if (!this.clientPromise) {
40
40
  this.clientPromise = (async () => {
41
- const client = new Client({ name: 'common-qa-mcp', version: '0.8.0' });
41
+ const client = new Client({ name: 'common-qa-mcp', version: '0.8.1' });
42
42
  // The `as Transport` cast bridges exactOptionalPropertyTypes: StreamableHTTPClientTransport
43
43
  // implements Transport, but the SDK's own .d.ts (built without EOPT) leaves its optional
44
44
  // callbacks (onclose?/onerror?/onmessage?) without `| undefined`, which this project's EOPT
@@ -25,6 +25,15 @@ export declare class SimplifyQaAdapter {
25
25
  private backlogDefaultsCache;
26
26
  constructor(cfg: ConnectedQaConfig, transport?: SimplifyQaTransport);
27
27
  private headers;
28
+ /** Public session context for MCP viewer/recorder windows that need to authenticate the sqa-ui
29
+ * they load. cfg itself stays private; this getter is the one seam through which tc_edit_open
30
+ * and record tools can forward token + baseUrl + projectId to Electron without asking the LLM. */
31
+ getSessionContext(): {
32
+ token: string;
33
+ baseUrl: string;
34
+ projectId?: string;
35
+ userId?: string;
36
+ };
28
37
  private requireProjectId;
29
38
  private searchBody;
30
39
  /** Validates baseUrl + token + (optional) project by running the same list_projects search the
@@ -320,6 +329,9 @@ export declare class SimplifyQaAdapter {
320
329
  * Keyed by `${technologyType}::${lowerCaseName}` so the same action name across two techs
321
330
  * (e.g. "click" for WEB + ANDROID) resolves to the right numeric id. */
322
331
  private actionCatalogCache;
332
+ /** Populated by actionCatalog() on each fetch. Surfaced in resolveAutomationSteps error messages
333
+ * so a user hitting "no SQA action named X" can see what the fetch actually returned. */
334
+ private actionCatalogFetchDiag;
323
335
  private actionCatalog;
324
336
  private resolveObjectId;
325
337
  /** For every automation step, resolve `actionId` (from action name + technology) and
@@ -330,6 +342,10 @@ export declare class SimplifyQaAdapter {
330
342
  * collation strength:2, so a case-sensitive search here misses params stored under different
331
343
  * casing — the next POST then trips "Duplicate Name Error". Returns null when not found. */
332
344
  private findParameterId;
345
+ /** Case-insensitive project-scoped lookup of an existing object by `disname` (the UI's Name).
346
+ * Lets tc_draft_update pass `objectRef:{name}` for an already-defined object without also
347
+ * supplying locators — mirrors what a user picking from the Object Repository dropdown does. */
348
+ private findObjectIdByName;
333
349
  private getOrCreateParameter;
334
350
  createSuite(s: Suite): Promise<SavedRef>;
335
351
  /** Fetch raw suite, apply add/remove/reorder ops in memory, then PUT the whole doc back with a
@@ -469,6 +485,14 @@ export declare class SimplifyQaAdapter {
469
485
  private lookupProjectName;
470
486
  startRun(target: RunTarget, opts: RunOptions): Promise<RunRef>;
471
487
  stopRun(runId: string): Promise<void>;
488
+ /** SUITE dispatch. Mirrors `startRun` above (which handles TC) — same `/exec/execution` endpoint,
489
+ * same LOCAL-agent fast-fail, same project-name / environment resolution. What differs is on the
490
+ * wire: `type: 'SUITE'`, `executionType` sourced from `suite.suiteType`, `mode` defaulting to
491
+ * `suite.executionType`, a populated `globalConfiguration` block, and one `executionItems` entry
492
+ * PER member — each carrying the suite row's persisted `versionId` / `stepId` / `platform` / `seq`
493
+ * (NOT a re-derived random step id). See sqa-ui execution-popup-modal.component.ts:621-1105 SU
494
+ * branch for the authoritative UI builder; every field below traces back to a line there. */
495
+ private startSuiteRun;
472
496
  /** GET the agent /mcp with a 1s timeout. Any HTTP response (incl. 4xx from an MCP server rejecting
473
497
  * a naked GET) proves the process is up; connect/DNS/timeout errors mean it is down. Replaces
474
498
  * the customer-wide `machineRegistration` round trip when all we needed was "is LOCAL possible?". */
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/simplifyqa/adapter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/simplifyqa/adapter.ts"],"names":[],"mappings":"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"}
@@ -227,6 +227,9 @@ export class SimplifyQaAdapter {
227
227
  * Keyed by `${technologyType}::${lowerCaseName}` so the same action name across two techs
228
228
  * (e.g. "click" for WEB + ANDROID) resolves to the right numeric id. */
229
229
  this.actionCatalogCache = null;
230
+ /** Populated by actionCatalog() on each fetch. Surfaced in resolveAutomationSteps error messages
231
+ * so a user hitting "no SQA action named X" can see what the fetch actually returned. */
232
+ this.actionCatalogFetchDiag = 'never fetched';
230
233
  // ---------------------------------------------------------------------- Objects (read + delete)
231
234
  // list/create/delete now go direct REST (same /tm/object base getObject already uses), mirroring
232
235
  // the testcase/suite search + soft-delete convention.
@@ -254,6 +257,18 @@ export class SimplifyQaAdapter {
254
257
  ...(this.cfg.projectId ? { 'x-project-id': this.cfg.projectId } : {}),
255
258
  };
256
259
  }
260
+ /** Public session context for MCP viewer/recorder windows that need to authenticate the sqa-ui
261
+ * they load. cfg itself stays private; this getter is the one seam through which tc_edit_open
262
+ * and record tools can forward token + baseUrl + projectId to Electron without asking the LLM. */
263
+ getSessionContext() {
264
+ // Constructor already rejected missing baseUrl (~line 265), so `!` is safe here.
265
+ return {
266
+ token: this.cfg.token,
267
+ baseUrl: this.cfg.baseUrl,
268
+ ...(this.cfg.projectId ? { projectId: this.cfg.projectId } : {}),
269
+ ...(this.cfg.userId ? { userId: this.cfg.userId } : {}),
270
+ };
271
+ }
257
272
  requireProjectId() {
258
273
  if (!this.cfg.projectId)
259
274
  throw new Error(NEEDS_PROJECT);
@@ -470,7 +485,11 @@ export class SimplifyQaAdapter {
470
485
  // Overlay currentVersionId to the resolved one and flip isCurrent flags on versions[]. Apply
471
486
  // even when rows are empty — a caller who pinned versionId still expects the header + versions[]
472
487
  // to reflect that choice (a legitimately-empty version shouldn't fall back to the TC's default).
473
- const resolvedVer = versionId ?? tc.currentVersionId;
488
+ // ponytail: mirror fetchStepsCollection's resolution ladder — the raw doc from /tm/testcase/getById
489
+ // does NOT include a top-level versionId, only a `versions[]` array. Without the versions[0] fallback,
490
+ // tc.currentVersionId stays undefined → tc_save emits versionsDetails.id:"" → backend mints a
491
+ // phantom version and orphans the saved steps.
492
+ const resolvedVer = versionId ?? tc.currentVersionId ?? (Array.isArray(tc.versions) ? tc.versions[0]?.id : undefined);
474
493
  const patched = { ...withSteps, ...(resolvedVer ? { currentVersionId: resolvedVer } : {}) };
475
494
  if (resolvedVer && patched.versions?.length) {
476
495
  patched.versions = patched.versions.map((v) => ({ ...v, isCurrent: v.id === resolvedVer }));
@@ -2317,8 +2336,10 @@ export class SimplifyQaAdapter {
2317
2336
  return this.actionCatalogCache;
2318
2337
  const projectId = this.requireProjectId();
2319
2338
  this.actionCatalogCache = (async () => {
2320
- // `projectId in [0, projectId]` — 0 is the customer-wide default catalog, projectId is the
2321
- // per-project overrides layered on top. Same filter the SQA UI uses (steps.model.ts:59).
2339
+ // Use the SAME filter the SQA UI uses (mobile-app/angular/.../steps.model.ts:59):
2340
+ // {projectId: {$in:[0, projectId]}}. Removing it caused /tm/action/search to return 0 rows in
2341
+ // practice — the backend endpoint apparently requires it as-is despite server-side resolvers
2342
+ // using only {customerId, deleted:false}. Keep the UI's filter to stay compatible.
2322
2343
  const body = {
2323
2344
  searchFields: [
2324
2345
  { column: 'deleted', value: false },
@@ -2330,12 +2351,25 @@ export class SimplifyQaAdapter {
2330
2351
  };
2331
2352
  const raw = await this.http.postJson('/tm/action/search', body);
2332
2353
  const rows = pickArray(raw, 'data', 'content', 'actions');
2354
+ // Capture diagnostic snapshot so downstream errors can surface WHY the fetch returned 0 rows.
2355
+ try {
2356
+ const topKeys = raw && typeof raw === 'object' ? Object.keys(raw).slice(0, 10).join(',') : typeof raw;
2357
+ const totalCount = raw?.totalCount ?? raw?.total ?? 'n/a';
2358
+ const firstRowKeys = rows[0] && typeof rows[0] === 'object' ? Object.keys(rows[0]).slice(0, 12).join(',') : 'no-rows';
2359
+ this.actionCatalogFetchDiag = `rows.length=${rows.length} totalCount=${totalCount} raw.keys=[${topKeys}] firstRowKeys=[${firstRowKeys}] projectId=${projectId}`;
2360
+ }
2361
+ catch { /* diagnostic must not throw */ }
2333
2362
  const map = new Map();
2334
2363
  for (const row of rows) {
2335
2364
  const idStr = str(row, 'id', '_id', 'actionId');
2336
2365
  const name = str(row, 'name');
2337
- const tech = str(row, 'technology');
2338
- if (!idStr || !name || !tech)
2366
+ // Diagnostic proved action rows have NO top-level `technology` field
2367
+ // (firstRowKeys=[id,name,objectRequired,objectTemplate]). SQA UI derives tech by looking up
2368
+ // objectTemplate → object_templates.name — we don't (would need a second fetch). Just require
2369
+ // id; drop the tech-in-key and let names collide across techs. Round-trip lookups (by numeric
2370
+ // id) are unaffected. Model-authored by-name lookups get whichever action registered last for
2371
+ // that name — good enough until cross-tech name collisions actually bite.
2372
+ if (!idStr)
2339
2373
  continue;
2340
2374
  const id = Number.parseInt(idStr, 10);
2341
2375
  if (!Number.isFinite(id))
@@ -2345,14 +2379,17 @@ export class SimplifyQaAdapter {
2345
2379
  const objectTemplate = typeof otRaw === 'number' ? otRaw
2346
2380
  : typeof otRaw === 'string' && /^\d+$/.test(otRaw) ? Number.parseInt(otRaw, 10)
2347
2381
  : undefined;
2348
- // Prefer the higher-priority project override when the same (tech, name) has both a
2349
- // default and a project row: last write wins if we sort defaults first. Backend returns
2350
- // whichever ordering; we resolve determinism by preferring a non-zero projectId row.
2351
- const key = `${tech.toUpperCase()}::${name.toLowerCase()}`;
2352
- const prev = map.get(key);
2353
- const isProjectOverride = typeof row?.projectId === 'number' && row.projectId !== 0;
2354
- if (!prev || isProjectOverride)
2355
- map.set(key, { id, objectRequired, objectTemplate });
2382
+ const entry = { id, objectRequired, ...(objectTemplate !== undefined ? { objectTemplate } : {}) };
2383
+ // Name-only key for by-name lookups (may collide across techs — see comment above).
2384
+ if (name) {
2385
+ const key = name.toLowerCase();
2386
+ const prev = map.get(key);
2387
+ const isProjectOverride = typeof row?.projectId === 'number' && row.projectId !== 0;
2388
+ if (!prev || isProjectOverride)
2389
+ map.set(key, entry);
2390
+ }
2391
+ // Id-keyed entry so numeric-actionType round-trip lookups are O(1) instead of a scan.
2392
+ map.set(`id::${id}`, entry);
2356
2393
  }
2357
2394
  return map;
2358
2395
  })().catch((e) => { this.actionCatalogCache = null; throw e; });
@@ -2409,27 +2446,106 @@ export class SimplifyQaAdapter {
2409
2446
  async resolveAutomationSteps(projectId, moduleId, tc) {
2410
2447
  const catalog = await this.actionCatalog();
2411
2448
  const steps = Array.isArray(tc.steps) ? tc.steps : [];
2449
+ // ponytail: objectId can be `undefined` here to mean "don't emit — preserve the backend value".
2450
+ // Used when an existing step (sourceId set) has no round-trip objectRef.id, e.g. because it was
2451
+ // recorded before objectRequired was flipped on the action. Emitting null would $set-clobber the DB.
2452
+ // actionId also nullable for control-flow / function / switch / function_end — those steps don't
2453
+ // have an action; buildAutomationPayload omits action/object emit when actionId is null.
2412
2454
  const out = [];
2413
2455
  for (let i = 0; i < steps.length; i++) {
2414
2456
  const s = steps[i];
2457
+ // ponytail: control-flow / function / switch / function_end steps have no action to resolve.
2458
+ // Push a null-actionId slot so index alignment survives; mapper checks and skips action/object
2459
+ // emit for these. Without this, IF/FOR/WHILE/FUNCTION steps throw "missing actionType" on save.
2460
+ if (s.stepType === 'control_flow' || s.stepType === 'function' || s.stepType === 'function_end' || s.stepType === 'switch' || s.stepType === 'manual') {
2461
+ out.push({ actionId: null, objectId: null });
2462
+ continue;
2463
+ }
2415
2464
  const tech = (TECH_BY_STEPTYPE[s.stepType] ?? deriveTcType(tc)).toUpperCase();
2416
2465
  const name = (s.actionType ?? '').trim();
2417
2466
  if (!name) {
2418
2467
  throw new Error(`Automation step ${i + 1} ("${s.description}"): missing actionType — the neutral Step.actionType must name an SQA action (e.g. "Click", "Type Text", "Launch Application").`);
2419
2468
  }
2420
- const meta = catalog.get(`${tech}::${name.toLowerCase()}`);
2469
+ // Round-trip support: a TC hydrated via getTestCase carries actionType = String(actionId), so
2470
+ // on save we may see a numeric string here. Catalog is dual-keyed: `id::N` for round-trip,
2471
+ // `<lowercase name>` for model-authored by-name lookups. Tech is not in the key because
2472
+ // action rows have no top-level `technology` field (SQA UI resolves via objectTemplate lookup).
2473
+ const isNumericId = /^\d+$/.test(name);
2474
+ let meta = isNumericId
2475
+ ? catalog.get(`id::${Number.parseInt(name, 10)}`)
2476
+ : catalog.get(name.toLowerCase());
2477
+ // Fallback: if the by-id scan misses (action created in a different project and thus not in
2478
+ // the UI's projectId-filtered catalog), fetch it directly via GET /tm/action/:id. Only tries
2479
+ // for numeric-id lookups — model-authored name lookups have no id to fetch.
2480
+ let fallbackDiag = '';
2481
+ if (!meta && isNumericId) {
2482
+ try {
2483
+ const raw = await this.http.getJson(`/tm/action/${Number.parseInt(name, 10)}`);
2484
+ const row = raw?.data && typeof raw.data === 'object' ? raw.data
2485
+ : Array.isArray(raw?.data) ? raw.data[0]
2486
+ : Array.isArray(raw) ? raw[0]
2487
+ : raw;
2488
+ const idStr = str(row, 'id', '_id', 'actionId');
2489
+ // ponytail: no `technology` gate. Catalog builder proved action rows have no top-level
2490
+ // technology field (see comment at ~line 2357); requiring it here made the fallback
2491
+ // never succeed — every cross-project action id threw "no SQA action named X".
2492
+ if (idStr) {
2493
+ const otRaw = row?.objectTemplate;
2494
+ const objectTemplate = typeof otRaw === 'number' ? otRaw
2495
+ : typeof otRaw === 'string' && /^\d+$/.test(otRaw) ? Number.parseInt(otRaw, 10)
2496
+ : undefined;
2497
+ meta = {
2498
+ id: Number.parseInt(idStr, 10),
2499
+ objectRequired: row?.objectRequired === true,
2500
+ ...(objectTemplate !== undefined ? { objectTemplate } : {}),
2501
+ };
2502
+ }
2503
+ else {
2504
+ fallbackDiag = ` [GET /tm/action/${name} returned no usable row (idStr=null). Raw keys: ${row && typeof row === 'object' ? Object.keys(row).join(',') : typeof row}]`;
2505
+ }
2506
+ }
2507
+ catch (e) {
2508
+ fallbackDiag = ` [GET /tm/action/${name} failed: ${e.message}]`;
2509
+ }
2510
+ }
2421
2511
  if (!meta) {
2422
- throw new Error(`Automation step ${i + 1}: no SQA action named "${name}" for technology ${tech}. Check the action catalog in the SQA UI.`);
2512
+ throw new Error(`Automation step ${i + 1}: no SQA action named "${name}" for technology ${tech}. Catalog size=${catalog.size}, numericId=${isNumericId}. FetchDiag: ${this.actionCatalogFetchDiag}.${fallbackDiag}`);
2423
2513
  }
2424
2514
  let objectId = null;
2425
2515
  if (meta.objectRequired) {
2426
- if (!s.objectRef || !s.objectRef.name || !(s.objectRef.locators?.length)) {
2427
- throw new Error(`Automation step ${i + 1} ("${name}"): action requires an object but Step.objectRef is missing name/locators. Provide objectRef:{name, locators:[{name, value}]}.`);
2516
+ // Resolution ladder (first match wins):
2517
+ // 1. objectRef.id set → use directly (round-trip OR LLM referencing a known object)
2518
+ // 2. sourceId set but no objectRef.id → preserve DB value (existing step, backend may
2519
+ // have null historically; emitting anything would $set-clobber)
2520
+ // 3. objectRef.name only (no locators) → project-scoped name lookup (LLM added a step
2521
+ // referencing an existing Object Repository entry by name — mirrors UI dropdown)
2522
+ // 4. objectRef.name + locators → get-or-create via createObjectSeq (recorder path)
2523
+ // 5. nothing usable → throw with the three-option error so the caller can pick
2524
+ const roundTripId = s.objectRef?.id ? Number.parseInt(String(s.objectRef.id), 10) : NaN;
2525
+ if (Number.isFinite(roundTripId)) {
2526
+ objectId = roundTripId;
2527
+ }
2528
+ else if (s.sourceId) {
2529
+ objectId = undefined;
2530
+ }
2531
+ else if (s.objectRef?.name && !(s.objectRef.locators?.length)) {
2532
+ const found = await this.findObjectIdByName(projectId, s.objectRef.name);
2533
+ if (found != null) {
2534
+ objectId = found;
2535
+ }
2536
+ else {
2537
+ throw new Error(`Automation step ${i + 1} ("${name}"): no object named "${s.objectRef.name}" found in this project. Either pass objectRef.id to reuse an existing one, or add objectRef.locators:[{name, value}, ...] to create a new object with that name.`);
2538
+ }
2539
+ }
2540
+ else if (s.objectRef?.name && s.objectRef.locators?.length) {
2541
+ if (meta.objectTemplate == null) {
2542
+ throw new Error(`Automation step ${i + 1} ("${name}"): action ${meta.id} has no objectTemplate — cannot create/reuse an object without knowing which template it belongs to.`);
2543
+ }
2544
+ objectId = await this.resolveObjectId(s.objectRef, projectId, moduleId, tech, meta.objectTemplate);
2428
2545
  }
2429
- if (meta.objectTemplate == null) {
2430
- throw new Error(`Automation step ${i + 1} ("${name}"): action ${meta.id} has no objectTemplate — cannot create/reuse an object without knowing which template it belongs to.`);
2546
+ else {
2547
+ throw new Error(`Automation step ${i + 1} ("${name}"): action requires an object but Step.objectRef is missing. Provide objectRef:{id} to reuse a known one, objectRef:{name} to look one up by name in the project, or objectRef:{name, locators:[{name, value}]} to create a new one.`);
2431
2548
  }
2432
- objectId = await this.resolveObjectId(s.objectRef, projectId, moduleId, tech, meta.objectTemplate);
2433
2549
  }
2434
2550
  out.push({ actionId: meta.id, objectId });
2435
2551
  }
@@ -2458,6 +2574,28 @@ export class SimplifyQaAdapter {
2458
2574
  }
2459
2575
  return null;
2460
2576
  }
2577
+ /** Case-insensitive project-scoped lookup of an existing object by `disname` (the UI's Name).
2578
+ * Lets tc_draft_update pass `objectRef:{name}` for an already-defined object without also
2579
+ * supplying locators — mirrors what a user picking from the Object Repository dropdown does. */
2580
+ async findObjectIdByName(projectId, name) {
2581
+ const body = this.searchBody([
2582
+ { column: 'disname', value: name },
2583
+ { column: 'projectId', value: projectId },
2584
+ { column: 'deleted', value: false },
2585
+ ], { startIndex: 0, limit: 10 });
2586
+ body['searchFields'][0]['ignorecase'] = true;
2587
+ const raw = await this.http.postJson('/tm/object/search', body);
2588
+ const rows = pickArray(raw, 'data', 'content', 'objects');
2589
+ for (const row of rows) {
2590
+ const rowName = str(row, 'disname');
2591
+ if (rowName?.toLowerCase() === name.toLowerCase()) {
2592
+ const id = str(row, 'id', '_id');
2593
+ if (id)
2594
+ return Number.parseInt(id, 10);
2595
+ }
2596
+ }
2597
+ return null;
2598
+ }
2461
2599
  async getOrCreateParameter(projectId, moduleId, name, defaultValue) {
2462
2600
  const existing = await this.findParameterId(projectId, name);
2463
2601
  if (existing != null)
@@ -2888,7 +3026,19 @@ export class SimplifyQaAdapter {
2888
3026
  }
2889
3027
  // ---------------------------------------------------------------------- Actions catalog
2890
3028
  async actionsCatalog(platform) {
2891
- return this.requireHop('actions_catalog').actionsCatalog(platform);
3029
+ // Build from the live backend catalog (already cached per-connection). Each entry gets its
3030
+ // numeric id + objectRequired flag so callers can round-trip actionType ↔ actionId. Ignores
3031
+ // `platform` — action rows carry no top-level technology; tech disambiguation is a follow-up
3032
+ // (would need an object_templates lookup). Skips the `id::N` reverse-lookup keys.
3033
+ void platform;
3034
+ const catalog = await this.actionCatalog();
3035
+ const defs = [];
3036
+ for (const [key, meta] of catalog) {
3037
+ if (key.startsWith('id::'))
3038
+ continue; // reverse-lookup entry — already covered by name key
3039
+ defs.push({ actionType: key, platform: 'unknown', id: meta.id, objectRequired: meta.objectRequired });
3040
+ }
3041
+ return defs;
2892
3042
  }
2893
3043
  // ---------------------------------------------------------------------- Testdata generation [Step 3]
2894
3044
  /** Fetch the default (template) iteration row for a TC. Fills gaps from the raw TC:
@@ -3314,11 +3464,10 @@ export class SimplifyQaAdapter {
3314
3464
  // SUITE runs are not yet ported and still hop (or error clearly).
3315
3465
  async startRun(target, opts) {
3316
3466
  const projectId = this.requireProjectId();
3467
+ if (target.suiteId && !target.tcId) {
3468
+ return this.startSuiteRun(target.suiteId, opts);
3469
+ }
3317
3470
  if (!target.tcId) {
3318
- if (target.suiteId) {
3319
- throw new Error('startRun: SUITE runs are not yet ported to direct REST — set QA_MCP_URL so common-mcp ' +
3320
- 'can hop to the SimplifyQA agent for suite dispatch, or run a single TC.');
3321
- }
3322
3471
  throw new Error('startRun: target.tcId (or target.suiteId) is required.');
3323
3472
  }
3324
3473
  const tcId = target.tcId;
@@ -3492,6 +3641,192 @@ export class SimplifyQaAdapter {
3492
3641
  killType: 'STOP_EXECUTION',
3493
3642
  });
3494
3643
  }
3644
+ /** SUITE dispatch. Mirrors `startRun` above (which handles TC) — same `/exec/execution` endpoint,
3645
+ * same LOCAL-agent fast-fail, same project-name / environment resolution. What differs is on the
3646
+ * wire: `type: 'SUITE'`, `executionType` sourced from `suite.suiteType`, `mode` defaulting to
3647
+ * `suite.executionType`, a populated `globalConfiguration` block, and one `executionItems` entry
3648
+ * PER member — each carrying the suite row's persisted `versionId` / `stepId` / `platform` / `seq`
3649
+ * (NOT a re-derived random step id). See sqa-ui execution-popup-modal.component.ts:621-1105 SU
3650
+ * branch for the authoritative UI builder; every field below traces back to a line there. */
3651
+ async startSuiteRun(suiteId, opts) {
3652
+ const projectId = this.requireProjectId();
3653
+ const suiteNum = Number.parseInt(numericId(suiteId), 10);
3654
+ if (!Number.isFinite(suiteNum))
3655
+ throw new Error(`startRun: could not resolve numeric id for ${suiteId}.`);
3656
+ const rawSuite = await this.fetchRawSuite(suiteId);
3657
+ if (!rawSuite || Object.keys(rawSuite).length === 0) {
3658
+ throw new Error(`startRun: suite ${suiteId} not found.`);
3659
+ }
3660
+ // Effective mode: caller pick wins (matches our tool's cascade UX); fall back to the suite doc's
3661
+ // stored `executionType`, which the UI reads unconditionally (execution-popup-modal.ts:668).
3662
+ const mode = (opts.mode ?? String(rawSuite.executionType ?? 'LOCAL')).toUpperCase();
3663
+ if (mode === 'LOCAL' && !(await this.probeLocalAgent())) {
3664
+ throw new Error(`startRun (LOCAL): SimplifyQA desktop agent is not reachable at ` +
3665
+ `${this.cfg.url ?? '(no agent URL configured — set QA_MCP_URL)'}. Start the desktop ` +
3666
+ `agent, then try again. Use mode:'cloud' to run on a cloud runner instead — it does not ` +
3667
+ `need the desktop agent.`);
3668
+ }
3669
+ const projectName = await this.lookupProjectName(projectId);
3670
+ if (!projectName) {
3671
+ throw new Error(`startRun: could not resolve project name for projectId=${projectId}. ` +
3672
+ `The token may not have read access to this project.`);
3673
+ }
3674
+ const env = await this.resolveEnvironment(projectId, opts.environment);
3675
+ const suiteType = String(rawSuite.suiteType ?? 'AUTOMATION').toUpperCase();
3676
+ // Build one executionItems entry per suite row, in suite order. Silently skip rows whose TC no
3677
+ // longer exists (matches UI :880 `if (!data) return;`). Every item uses the suite row's stored
3678
+ // versionId + stepId + per-mode platform — regenerating any of those splits step correlation
3679
+ // and breaks the agent's iteration join. Missing platform for a row is not an error here (UI
3680
+ // sends `[]`) — the agent tolerates it for MANUAL suites; AUTOMATION suites without a saved
3681
+ // platform were misconfigured upstream and would fail regardless.
3682
+ const members = Array.isArray(rawSuite.testCases) ? rawSuite.testCases : [];
3683
+ const executionItems = [];
3684
+ let seqCounter = 0;
3685
+ for (const row of members) {
3686
+ seqCounter++;
3687
+ const memberTcId = row?.testcaseId;
3688
+ if (memberTcId === undefined || memberTcId === null)
3689
+ continue;
3690
+ let rawTc;
3691
+ try {
3692
+ rawTc = await this.fetchRawTestcase(String(memberTcId));
3693
+ }
3694
+ catch {
3695
+ continue;
3696
+ }
3697
+ if (!rawTc || Object.keys(rawTc).length === 0)
3698
+ continue;
3699
+ const tcType = String(str(rawTc, 'tcType') ?? 'WEB').toUpperCase();
3700
+ const versions = Array.isArray(rawTc?.versions) ? rawTc.versions : [];
3701
+ const rowVersionId = row?.versionId ?? row?.version;
3702
+ const versionMatch = rowVersionId
3703
+ ? versions.find((v) => str(v, 'id', '_id') === String(rowVersionId) || str(v, 'name') === String(rowVersionId))
3704
+ : undefined;
3705
+ const versionId = str(versionMatch, 'id', '_id') ?? (rowVersionId !== undefined ? String(rowVersionId) : '');
3706
+ const versionName = str(versionMatch, 'name') ?? str(rawTc, 'versionName', 'selectedVersionName') ?? 'v1.0';
3707
+ // Per-mode platform from the suite row. UI reads `data1.executionPlatform[mode]` (:882-965);
3708
+ // when saved, it's a single object → wrap in `[obj]`; if the row didn't save one for this
3709
+ // mode, send `[]` and let the backend reject/accept per its own rules.
3710
+ const savedPlatform = row?.executionPlatform?.[mode];
3711
+ let platform = [];
3712
+ if (savedPlatform && typeof savedPlatform === 'object') {
3713
+ const p = {
3714
+ name: savedPlatform.name,
3715
+ id: savedPlatform.id ?? savedPlatform.name,
3716
+ technologyType: String(savedPlatform.technologyType ?? tcType).toUpperCase(),
3717
+ type: savedPlatform.type ?? 'NONE',
3718
+ };
3719
+ if (savedPlatform.cloudDeviceType)
3720
+ p['cloudDeviceType'] = savedPlatform.cloudDeviceType;
3721
+ if (savedPlatform.osVersion)
3722
+ p['osVersion'] = savedPlatform.osVersion;
3723
+ platform = [p];
3724
+ }
3725
+ else if (['API', 'MAINFRAME', 'SAP', 'DESKTOP', 'DATABASE'].includes(tcType)) {
3726
+ platform = [{ name: tcType, id: tcType, technologyType: tcType, type: 'NONE' }];
3727
+ }
3728
+ const moduleIdNum = typeof rawTc?.moduleId === 'number' ? rawTc.moduleId : 0;
3729
+ let moduleName = '';
3730
+ if (moduleIdNum > 0) {
3731
+ try {
3732
+ const body = this.searchBody([{ column: 'id', value: moduleIdNum }, { column: 'deleted', value: false }], { selectFields: ['id', 'name'], limit: 1 });
3733
+ const raw = await this.http.postJson('/pm/module/search', body);
3734
+ const rows = pickArray(raw, 'data', 'content', 'modules');
3735
+ moduleName = str(rows[0], 'name') ?? '';
3736
+ }
3737
+ catch { /* leave empty */ }
3738
+ }
3739
+ executionItems.push({
3740
+ id: typeof rawTc?.id === 'number' ? rawTc.id : Number.parseInt(numericId(String(memberTcId)), 10),
3741
+ name: str(rawTc, 'name', 'title') ?? '',
3742
+ description: str(rawTc, 'description') ?? '',
3743
+ versionId,
3744
+ versionName,
3745
+ seq: typeof row?.seq === 'number' ? row.seq : seqCounter,
3746
+ stepId: row?.stepId ?? '', // MUST come from the suite row, never regenerated
3747
+ stepCount: -1, // suite items send -1 (TC sends 0)
3748
+ technologyType: tcType,
3749
+ type: 'TC', // every item is 'TC'; suite-ness lives at top-level type
3750
+ platform,
3751
+ projectId,
3752
+ projectName,
3753
+ configuration: {},
3754
+ iterationsSelected: [],
3755
+ moduleId: moduleIdNum,
3756
+ userstoryId: typeof rawTc?.userstoryId === 'number' ? rawTc.userstoryId : 0,
3757
+ tags: Array.isArray(rawTc?.tags) ? rawTc.tags : [],
3758
+ code: str(rawTc, 'code') ?? '',
3759
+ prerequisite: str(rawTc, 'prerequisite', 'preconditions') ?? '',
3760
+ moduleName,
3761
+ userstoryName: '',
3762
+ });
3763
+ }
3764
+ if (executionItems.length === 0) {
3765
+ throw new Error(`startRun: suite ${suiteId} has no runnable test cases (all members were deleted, ` +
3766
+ `unreadable, or filtered out).`);
3767
+ }
3768
+ // agentId derivation (mirrors UI :677). LOCAL always uses this machine's agent; REMOTE/CLOUD
3769
+ // pin the suite doc's saved `agentId` (or null when the suite wasn't pinned). CLOUD_AGENT
3770
+ // fallback (:771-774) promotes `cloudType` to 'SQA'.
3771
+ let agentId;
3772
+ if (mode === 'LOCAL') {
3773
+ agentId = await this.resolveLocalAgentId(opts.agentId);
3774
+ }
3775
+ else if (mode === 'REMOTE') {
3776
+ const preferred = opts.agentId ?? (typeof rawSuite.agentId === 'string' ? rawSuite.agentId : undefined);
3777
+ agentId = preferred ? await this.resolveRemoteAgentId(preferred) : null;
3778
+ }
3779
+ else {
3780
+ agentId = typeof rawSuite.agentId === 'string' && rawSuite.agentId.length > 0 ? rawSuite.agentId : null;
3781
+ }
3782
+ let cloudType = mode === 'CLOUD' ? 'VM' : 'NONE';
3783
+ if (!agentId && typeof rawSuite.cloudAgentId === 'string' && rawSuite.cloudAgentId.length > 0) {
3784
+ agentId = rawSuite.cloudAgentId;
3785
+ cloudType = 'SQA';
3786
+ }
3787
+ const gc = rawSuite.globalConfiguration ?? {};
3788
+ const body = {
3789
+ projectId,
3790
+ environmentType: env,
3791
+ executionStyle: (opts.strategy ?? 'serial').toUpperCase(),
3792
+ executionOS: this.detectExecutionOS(),
3793
+ executionTypeId: suiteNum,
3794
+ executionTypeName: str(rawSuite, 'name') ?? '',
3795
+ executionTypeCode: str(rawSuite, 'code') ?? '',
3796
+ mailersList: rawSuite.mailersList ?? {},
3797
+ cloudType,
3798
+ mode,
3799
+ executionCategory: 'EXECUTION',
3800
+ releaseId: opts.releaseId ? Number.parseInt(opts.releaseId, 10) || 0 : 0,
3801
+ iterationId: opts.sprintId ? Number.parseInt(opts.sprintId, 10) || 0 : 0,
3802
+ executionTime: '',
3803
+ status: 'INPROGRESS',
3804
+ iterationsSelected: [],
3805
+ result: '',
3806
+ globalConfiguration: {
3807
+ TERMINATE_ON_FAIL: opts.terminateOnFailure ?? gc.TERMINATE_ON_FAIL ?? false,
3808
+ NEW_BROWSER_SESSION: gc.NEW_BROWSER_SESSION ?? false,
3809
+ RE_EXECUTION_COUNT: gc.RE_EXECUTION_COUNT ?? 0,
3810
+ RE_EXECUTION_TYPE: gc.RE_EXECUTION_TYPE ?? 'AFTER_TESTCASE',
3811
+ MINIMUM_CONTAINER_COUNT: gc.MINIMUM_CONTAINER_COUNT ?? 1,
3812
+ MAXIMUM_CONTAINER_COUNT: opts.maxConcurrent ?? gc.MAXIMUM_CONTAINER_COUNT ?? 5,
3813
+ },
3814
+ isRecordingEnabled: false,
3815
+ offset: -(new Date().getTimezoneOffset()),
3816
+ type: 'SUITE',
3817
+ executionType: suiteType,
3818
+ agentId,
3819
+ executionItems,
3820
+ };
3821
+ const resp = await this.http.postJson('/exec/execution', body);
3822
+ const d = resp?.data ?? resp;
3823
+ const runId = str(d, 'id', 'executionId', '_id') ??
3824
+ (typeof d?.id === 'number' ? String(d.id) : undefined) ??
3825
+ (typeof d?.executionId === 'number' ? String(d.executionId) : undefined);
3826
+ if (!runId)
3827
+ throw new Error('startRun: backend accepted suite trigger but returned no run id.');
3828
+ return { runId };
3829
+ }
3495
3830
  /** GET the agent /mcp with a 1s timeout. Any HTTP response (incl. 4xx from an MCP server rejecting
3496
3831
  * a naked GET) proves the process is up; connect/DNS/timeout errors mean it is down. Replaces
3497
3832
  * the customer-wide `machineRegistration` round trip when all we needed was "is LOCAL possible?". */