common-qa-mcp 0.3.0 → 0.4.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 (83) hide show
  1. package/dist/adapters/factory.d.ts +1 -1
  2. package/dist/adapters/factory.d.ts.map +1 -1
  3. package/dist/adapters/factory.js +12 -29
  4. package/dist/adapters/factory.js.map +1 -1
  5. package/dist/adapters/http.js +2 -3
  6. package/dist/adapters/http.js.map +1 -1
  7. package/dist/adapters/remoteMcp/adapter.d.ts +7 -2
  8. package/dist/adapters/remoteMcp/adapter.d.ts.map +1 -1
  9. package/dist/adapters/remoteMcp/adapter.js +9 -3
  10. package/dist/adapters/remoteMcp/adapter.js.map +1 -1
  11. package/dist/adapters/simplifyqa/adapter.d.ts +309 -23
  12. package/dist/adapters/simplifyqa/adapter.d.ts.map +1 -1
  13. package/dist/adapters/simplifyqa/adapter.js +2042 -86
  14. package/dist/adapters/simplifyqa/adapter.js.map +1 -1
  15. package/dist/adapters/simplifyqa/mapper.d.ts +43 -11
  16. package/dist/adapters/simplifyqa/mapper.d.ts.map +1 -1
  17. package/dist/adapters/simplifyqa/mapper.js +470 -21
  18. package/dist/adapters/simplifyqa/mapper.js.map +1 -1
  19. package/dist/adapters/types.d.ts +126 -5
  20. package/dist/adapters/types.d.ts.map +1 -1
  21. package/dist/adapters/walnut/adapter.d.ts +6 -2
  22. package/dist/adapters/walnut/adapter.d.ts.map +1 -1
  23. package/dist/adapters/walnut/adapter.js +33 -2
  24. package/dist/adapters/walnut/adapter.js.map +1 -1
  25. package/dist/adapters/walnut/mapper.d.ts +2 -1
  26. package/dist/adapters/walnut/mapper.d.ts.map +1 -1
  27. package/dist/adapters/walnut/mapper.js +13 -0
  28. package/dist/adapters/walnut/mapper.js.map +1 -1
  29. package/dist/config.d.ts +10 -0
  30. package/dist/config.d.ts.map +1 -1
  31. package/dist/config.js +36 -0
  32. package/dist/config.js.map +1 -1
  33. package/dist/connection.d.ts.map +1 -1
  34. package/dist/connection.js +15 -7
  35. package/dist/connection.js.map +1 -1
  36. package/dist/domain/types.d.ts +485 -4
  37. package/dist/domain/types.d.ts.map +1 -1
  38. package/dist/initAgents.d.ts.map +1 -1
  39. package/dist/initAgents.js +22 -9
  40. package/dist/initAgents.js.map +1 -1
  41. package/dist/server.d.ts.map +1 -1
  42. package/dist/server.js +23 -1
  43. package/dist/server.js.map +1 -1
  44. package/dist/tools/backlog.tools.d.ts +13 -0
  45. package/dist/tools/backlog.tools.d.ts.map +1 -0
  46. package/dist/tools/backlog.tools.js +399 -0
  47. package/dist/tools/backlog.tools.js.map +1 -0
  48. package/dist/tools/defects.tools.d.ts +7 -0
  49. package/dist/tools/defects.tools.d.ts.map +1 -0
  50. package/dist/tools/defects.tools.js +82 -0
  51. package/dist/tools/defects.tools.js.map +1 -0
  52. package/dist/tools/discovery.tools.d.ts.map +1 -1
  53. package/dist/tools/discovery.tools.js +912 -55
  54. package/dist/tools/discovery.tools.js.map +1 -1
  55. package/dist/tools/markdown.d.ts +3 -3
  56. package/dist/tools/markdown.d.ts.map +1 -1
  57. package/dist/tools/markdown.js +89 -18
  58. package/dist/tools/markdown.js.map +1 -1
  59. package/dist/tools/objects.tools.d.ts +7 -0
  60. package/dist/tools/objects.tools.d.ts.map +1 -0
  61. package/dist/tools/objects.tools.js +201 -0
  62. package/dist/tools/objects.tools.js.map +1 -0
  63. package/dist/tools/recording.tools.d.ts.map +1 -1
  64. package/dist/tools/recording.tools.js +64 -5
  65. package/dist/tools/recording.tools.js.map +1 -1
  66. package/dist/tools/run.tools.d.ts.map +1 -1
  67. package/dist/tools/run.tools.js +102 -18
  68. package/dist/tools/run.tools.js.map +1 -1
  69. package/dist/tools/schemas.d.ts +21 -4
  70. package/dist/tools/schemas.d.ts.map +1 -1
  71. package/dist/tools/schemas.js +14 -1
  72. package/dist/tools/schemas.js.map +1 -1
  73. package/dist/tools/tasks.tools.d.ts +7 -0
  74. package/dist/tools/tasks.tools.d.ts.map +1 -0
  75. package/dist/tools/tasks.tools.js +75 -0
  76. package/dist/tools/tasks.tools.js.map +1 -0
  77. package/dist/tools/testcase.tools.d.ts.map +1 -1
  78. package/dist/tools/testcase.tools.js +146 -100
  79. package/dist/tools/testcase.tools.js.map +1 -1
  80. package/dist/tools/testdata.tools.d.ts.map +1 -1
  81. package/dist/tools/testdata.tools.js +99 -11
  82. package/dist/tools/testdata.tools.js.map +1 -1
  83. package/package.json +3 -3
@@ -19,7 +19,7 @@ export type Step = {
19
19
  * steps by identity (update in place) and correctly deletes the ones dropped — not fragile
20
20
  * slot-by-number matching. Absent on freshly-inserted steps (the backend then creates them). */
21
21
  sourceId?: string | undefined;
22
- stepType: 'web' | 'api' | 'control_flow' | 'function' | 'database' | 'android' | 'mainframe';
22
+ stepType: 'manual' | 'web' | 'api' | 'control_flow' | 'function' | 'function_end' | 'database' | 'android' | 'mainframe' | 'switch' | 'compare';
23
23
  objectRef?: {
24
24
  id?: string | undefined;
25
25
  name?: string | undefined;
@@ -27,9 +27,15 @@ export type Step = {
27
27
  } | undefined;
28
28
  value?: string | undefined;
29
29
  expectedResult?: string | undefined;
30
+ /** Control-flow marker. `kind` mirrors SQA's raw `stepType` for control rows (IF/ELSE/ELSE_IF/IF_END,
31
+ * WHILE_START/WHILE/WHILE_END, DO/DO_WHILE, FOR_START/FOR_END, LOOP, ITERATOR_START/END,
32
+ * LOOP_ITERATION_START/END, SWITCH_TO_*). Kept as a wide string so a future backend adds don't need
33
+ * a schema change here — the markdown renderer defaults unknown kinds to their raw uppercase name. */
30
34
  controlFlow?: {
31
- kind: 'if' | 'else' | 'if_end' | 'while' | 'while_end';
35
+ kind: string;
32
36
  condition?: Condition | undefined;
37
+ /** Raw ifstring from SQA's `conditions.ifstring` — the human-readable expression as shown in the UI. */
38
+ conditionText?: string | undefined;
33
39
  blockId?: string | undefined;
34
40
  maxIterations?: number | undefined;
35
41
  } | undefined;
@@ -41,6 +47,13 @@ export type Step = {
41
47
  functionCall?: {
42
48
  testCaseId: string;
43
49
  testCaseName?: string | undefined;
50
+ /** SQA function code (e.g. FN_12). Populated by the adapter's FN-name lookup so the
51
+ * markdown renderer can show a human ref instead of a bare numeric id. */
52
+ testCaseCode?: string | undefined;
53
+ /** SQA `fnVersionId` — the specific version of the referenced function pinned by this call. */
54
+ versionId?: string | undefined;
55
+ /** SQA `sharedFnProjectId` — non-null when the FN lives in a different project (shared functions). */
56
+ sharedProjectId?: string | undefined;
44
57
  inputParams?: Record<string, unknown> | undefined;
45
58
  continueOnFailure?: boolean | undefined;
46
59
  } | undefined;
@@ -50,6 +63,14 @@ export type Step = {
50
63
  continueOnFailure?: boolean | undefined;
51
64
  optional?: boolean | undefined;
52
65
  } | undefined;
66
+ /** WEB automation: browser to target for this step. Defaults to CHROME when absent. */
67
+ browserType?: string | undefined;
68
+ /** SQA automation: recorded values for this step, keyed by ACTION PARAMETER NAME (not id).
69
+ * Example: for a launch action, `{ packageName: 'us.zoom.videomeetings', activity: '...' }`.
70
+ * The mapper resolves each name → paramId via get-or-create, then emits SQA's
71
+ * `parameterIds: [<id>...]` + `recordedParam: { <id>: value }` on the step. Populates the
72
+ * default iteration on save. Manual TCs ignore this field. */
73
+ recordedParam?: Record<string, string> | undefined;
53
74
  };
54
75
  export type TestCase = {
55
76
  id?: string | undefined;
@@ -66,29 +87,82 @@ export type TestCase = {
66
87
  tags?: string[] | undefined;
67
88
  steps: Step[];
68
89
  version?: number | undefined;
90
+ /** All non-deleted versions of this TC — populated by adapters that support versioning (SQA).
91
+ * `id` is the version's opaque id (SQA `tcfn_version.id`, a uuid); `name` is the human label
92
+ * ("v1.0"). Walnut/manual-only adapters leave this undefined. */
93
+ versions?: TcVersion[] | undefined;
94
+ /** The version whose steps are surfaced on `steps[]`. Adapters resolve this: caller-provided
95
+ * `versionId` argument > TC's currently-selected version > first entry in `versions[]`. */
96
+ currentVersionId?: string | undefined;
69
97
  /** Default-row test data: param name -> value. Forwarded to the product on save to populate the
70
98
  * datarow of the dataset it auto-creates from the `${param}` tokens in step descriptions, so the
71
99
  * saved test case is executable with data. Optional -- the product also derives it from each
72
100
  * step's single `${param}` + its value. */
73
101
  data?: Record<string, string> | undefined;
102
+ /** SQA automation: execution target (device / browser) for the test case.
103
+ * - WEB: OPTIONAL — omit to let the SQA backend default to Chrome.
104
+ * - ANDROID / IOS: REQUIRED — the mapper refuses the save without one.
105
+ * Wire shape mirrors the SQA `executionPlatform` field on the tcfnObj:
106
+ * `{ id: <deviceSerial|'CHROME'>, name, technologyType: 'ANDROID'|'IOS'|'WEB', type:
107
+ * 'REAL_DEVICE'|'CLOUD_DEVICE'|'NONE', cloudDeviceType? }`. */
108
+ executionPlatform?: {
109
+ id: string;
110
+ name: string;
111
+ technologyType: string;
112
+ type: string;
113
+ cloudDeviceType?: string | undefined;
114
+ } | undefined;
115
+ };
116
+ /** One entry in `TestCase.versions[]`. Fields mirror what SQA's `/tm/testcase/getById` projects onto
117
+ * `versions[]` (tcfn.service.js:1489). `updateVersion` is the optimistic-lock counter, useful when
118
+ * the caller wants to display which version is newest. */
119
+ export type TcVersion = {
120
+ id: string;
121
+ name: string;
122
+ updateVersion?: number | undefined;
123
+ reviewApproveStatus?: string | undefined;
124
+ executionType?: string | undefined;
125
+ /** True when this is the TC's currently-selected version (the one the UI opens by default). */
126
+ isCurrent?: boolean | undefined;
74
127
  };
75
128
  export type TcSummary = {
76
129
  id: string;
130
+ code?: string;
77
131
  title: string;
78
132
  priority: string;
79
133
  status?: string;
80
134
  stepCount?: number;
135
+ technologyType?: string;
136
+ executionType?: string;
137
+ obsolete?: boolean;
81
138
  };
82
139
  export type ProjectSummary = {
83
140
  id: string;
141
+ code?: string;
84
142
  name: string;
85
143
  counts?: Record<string, number> | undefined;
86
144
  };
145
+ /** One raw backend column filter (searchFields protocol) — see `zRawFilter` in tools/schemas.ts. */
146
+ export type RawSearchFilter = {
147
+ column: string;
148
+ value: string | number | boolean | string[] | number[];
149
+ regEx?: boolean | undefined;
150
+ };
87
151
  export type TcQuery = {
88
152
  search?: string;
89
153
  status?: string;
90
154
  limit?: number;
91
155
  offset?: number;
156
+ /** Filter by numeric userId of the creator. Pass "me" and the adapter substitutes cfg.userId. */
157
+ createdBy?: string;
158
+ /** Filter by numeric userId of the last updater. Pass "me" and the adapter substitutes cfg.userId. */
159
+ updatedBy?: string;
160
+ storyId?: string;
161
+ /** Filter to test cases filed under this module (id or business key). SimplifyQA only; ignored on providers without a module tree. */
162
+ moduleId?: string;
163
+ /** True → only obsolete TCs; false → only non-obsolete. Omit to include both. SimplifyQA only. */
164
+ obsolete?: boolean;
165
+ filters?: RawSearchFilter[];
92
166
  };
93
167
  /** A USER STORY (Walnut `user_stories` doc, type 'story'). `key` = the human business key (walnut_key
94
168
  * like US_001, or an external Jira/ADO key). `id` = the Mongo _id (what test cases link to via story_id). */
@@ -117,6 +191,248 @@ export type StoryQuery = {
117
191
  sprintId?: string;
118
192
  /** Filter stories that belong to this release (SimplifyQA `userstory.releaseId`). */
119
193
  releaseId?: string;
194
+ /** Filter by numeric userId of the creator. Pass "me" and the adapter substitutes cfg.userId. */
195
+ createdBy?: string;
196
+ /** Filter by numeric userId of the last updater. Pass "me" and the adapter substitutes cfg.userId. */
197
+ updatedBy?: string;
198
+ /** Filter by numeric userId of the story owner (`userstory.ownerId`). Pass "me" and the adapter
199
+ * substitutes cfg.userId. Testcases have no owner field — this is story-only. */
200
+ ownerId?: string;
201
+ filters?: RawSearchFilter[];
202
+ };
203
+ export type DefectSummary = {
204
+ id: string;
205
+ code?: string | undefined;
206
+ title: string;
207
+ state?: string | undefined;
208
+ severity?: string | undefined;
209
+ priority?: string | undefined;
210
+ assignedTo?: string[] | undefined;
211
+ tcIds?: string[] | undefined;
212
+ };
213
+ export type DefectQuery = {
214
+ search?: string;
215
+ limit?: number;
216
+ offset?: number;
217
+ tcId?: string;
218
+ storyId?: string;
219
+ /** Exact workflow-state key (e.g. "new"), not the capitalized UI label. */
220
+ state?: string;
221
+ /** Numeric userId of the assignee (array field on the defect). Pass "me" for the caller. */
222
+ assignedTo?: string;
223
+ createdBy?: string;
224
+ filters?: RawSearchFilter[];
225
+ };
226
+ /** A TASK (SimplifyQA `pm.task`) — project-management work item, distinct from a test case or defect. */
227
+ export type TaskSummary = {
228
+ id: string;
229
+ code?: string | undefined;
230
+ title: string;
231
+ state?: string | undefined;
232
+ priority?: string | undefined;
233
+ assignedTo?: string[] | undefined;
234
+ /** Linked defect id, when raised against one. */
235
+ defectId?: string | undefined;
236
+ };
237
+ export type TaskQuery = {
238
+ search?: string;
239
+ limit?: number;
240
+ offset?: number;
241
+ /** Filter to tasks linked to this user story (`userstoryId`). */
242
+ storyId?: string;
243
+ state?: string;
244
+ assignedTo?: string;
245
+ createdBy?: string;
246
+ filters?: RawSearchFilter[];
247
+ };
248
+ /** Fields accepted when CREATING a user story (`POST /pm/userstory`). Neutral shape — the SQA adapter
249
+ * maps `moduleId`/`iterationId`/etc to the SQA payload as-is. `projectId` is filled from the connected
250
+ * project when omitted; `state` and `estimatedEffort` are backend-required. */
251
+ export type StoryInput = {
252
+ name: string;
253
+ state: string;
254
+ estimatedEffort: number;
255
+ projectId?: number | undefined;
256
+ epicId?: number | undefined;
257
+ featureId?: number | undefined;
258
+ moduleId?: number | undefined;
259
+ releaseId?: number | undefined;
260
+ /** SQA `iterationId` — the sprint. */
261
+ iterationId?: number | undefined;
262
+ acceptanceCriteria?: string | undefined;
263
+ description?: string | undefined;
264
+ priority?: string | undefined;
265
+ /** SQA accepts an array of userIds. */
266
+ ownerId?: number[] | undefined;
267
+ tags?: number[] | undefined;
268
+ teamId?: number[] | undefined;
269
+ type?: string | undefined;
270
+ plannedStartDate?: string | undefined;
271
+ plannedEndDate?: string | undefined;
272
+ customFields?: Record<string, unknown> | undefined;
273
+ };
274
+ /** Partial update body for `PUT /pm/userstory/:id`. `updateVersion` is optimistic-concurrency: the
275
+ * server bumps it on every write and rejects stale writes. Pass it back from the last `getStory`. */
276
+ export type StoryUpdate = {
277
+ name?: string | undefined;
278
+ state?: string | undefined;
279
+ estimatedEffort?: number | undefined;
280
+ projectId?: number | undefined;
281
+ epicId?: number | undefined;
282
+ featureId?: number | undefined;
283
+ moduleId?: number | undefined;
284
+ releaseId?: number | undefined;
285
+ iterationId?: number | undefined;
286
+ acceptanceCriteria?: string | undefined;
287
+ description?: string | undefined;
288
+ priority?: string | undefined;
289
+ ownerId?: number[] | undefined;
290
+ tags?: number[] | undefined;
291
+ teamId?: number[] | undefined;
292
+ type?: string | undefined;
293
+ plannedStartDate?: string | undefined;
294
+ plannedEndDate?: string | undefined;
295
+ customFields?: Record<string, unknown> | undefined;
296
+ updateVersion?: number | undefined;
297
+ };
298
+ /** An EPIC (SimplifyQA `pm.epic`). Top of the backlog hierarchy: epic → feature → story. `key` is the
299
+ * human business key (EP_XXX); `id` is the numeric doc id. */
300
+ export type EpicSummary = {
301
+ id: string;
302
+ key?: string | undefined;
303
+ name: string;
304
+ state?: string | undefined;
305
+ };
306
+ export type Epic = EpicSummary & {
307
+ description?: string | undefined;
308
+ estimatedEffort?: number | undefined;
309
+ ownerId?: number | undefined;
310
+ plannedStartDate?: string | undefined;
311
+ plannedEndDate?: string | undefined;
312
+ };
313
+ export type EpicQuery = {
314
+ search?: string;
315
+ state?: string;
316
+ limit?: number;
317
+ offset?: number;
318
+ /** Numeric userId of the creator. Pass "me" and the adapter substitutes cfg.userId. */
319
+ createdBy?: string;
320
+ /** Numeric userId of the last updater. Pass "me" and the adapter substitutes cfg.userId. */
321
+ updatedBy?: string;
322
+ /** Numeric userId of the epic owner. Pass "me" and the adapter substitutes cfg.userId. */
323
+ ownerId?: string;
324
+ };
325
+ /** Fields accepted when CREATING an epic (`POST /pm/epic`). `projectIds` is filled to `[currentProject]`
326
+ * when omitted; all six required fields (name/state/estimatedEffort/plannedStartDate/plannedEndDate/projectIds)
327
+ * must be present before hitting the backend. */
328
+ export type EpicInput = {
329
+ name: string;
330
+ state: string;
331
+ estimatedEffort: number;
332
+ plannedStartDate: string;
333
+ plannedEndDate: string;
334
+ projectIds?: number[] | undefined;
335
+ ownerId?: number | undefined;
336
+ description?: string | undefined;
337
+ tags?: string[] | undefined;
338
+ teamId?: number[] | undefined;
339
+ actualStartDate?: string | undefined;
340
+ actualEndDate?: string | undefined;
341
+ actualEffort?: number | undefined;
342
+ remainingEffort?: number | undefined;
343
+ plannedBudget?: number | undefined;
344
+ customFields?: Record<string, unknown> | undefined;
345
+ };
346
+ export type EpicUpdate = {
347
+ name?: string | undefined;
348
+ state?: string | undefined;
349
+ estimatedEffort?: number | undefined;
350
+ plannedStartDate?: string | undefined;
351
+ plannedEndDate?: string | undefined;
352
+ projectIds?: number[] | undefined;
353
+ ownerId?: number | undefined;
354
+ description?: string | undefined;
355
+ tags?: string[] | undefined;
356
+ teamId?: number[] | undefined;
357
+ actualStartDate?: string | undefined;
358
+ actualEndDate?: string | undefined;
359
+ actualEffort?: number | undefined;
360
+ remainingEffort?: number | undefined;
361
+ plannedBudget?: number | undefined;
362
+ customFields?: Record<string, unknown> | undefined;
363
+ updateVersion?: number | undefined;
364
+ };
365
+ /** A FEATURE (SimplifyQA `pm.feature`). Middle of the backlog hierarchy: epic → feature → story.
366
+ * `key` = business key (FT_XXX). `epicId` links to the parent epic. */
367
+ export type FeatureSummary = {
368
+ id: string;
369
+ key?: string | undefined;
370
+ name: string;
371
+ state?: string | undefined;
372
+ priority?: string | undefined;
373
+ epicId?: string | undefined;
374
+ };
375
+ export type Feature = FeatureSummary & {
376
+ description?: string | undefined;
377
+ estimatedEffort?: number | undefined;
378
+ ownerId?: number | undefined;
379
+ plannedStartDate?: string | undefined;
380
+ plannedEndDate?: string | undefined;
381
+ };
382
+ export type FeatureQuery = {
383
+ search?: string;
384
+ state?: string;
385
+ limit?: number;
386
+ offset?: number;
387
+ /** Filter features under a specific parent epic id. */
388
+ epicId?: string;
389
+ /** Numeric userId of the creator. Pass "me" and the adapter substitutes cfg.userId. */
390
+ createdBy?: string;
391
+ /** Numeric userId of the last updater. Pass "me" and the adapter substitutes cfg.userId. */
392
+ updatedBy?: string;
393
+ /** Numeric userId of the feature owner. Pass "me" and the adapter substitutes cfg.userId. */
394
+ ownerId?: string;
395
+ };
396
+ /** Fields accepted when CREATING a feature (`POST /pm/feature`). Same rules as EpicInput plus optional
397
+ * `epicId` (parent). `state` is optional on the backend for features (unlike epic/story). */
398
+ export type FeatureInput = {
399
+ name: string;
400
+ estimatedEffort: number;
401
+ plannedStartDate: string;
402
+ plannedEndDate: string;
403
+ projectIds?: number[] | undefined;
404
+ epicId?: number | undefined;
405
+ state?: string | undefined;
406
+ priority?: string | undefined;
407
+ ownerId?: number | undefined;
408
+ description?: string | undefined;
409
+ tags?: number[] | undefined;
410
+ teamId?: number[] | undefined;
411
+ actualStartDate?: string | undefined;
412
+ actualEndDate?: string | undefined;
413
+ actualEffort?: number | undefined;
414
+ remainingEffort?: number | undefined;
415
+ customFields?: Record<string, unknown> | undefined;
416
+ };
417
+ export type FeatureUpdate = {
418
+ name?: string | undefined;
419
+ estimatedEffort?: number | undefined;
420
+ plannedStartDate?: string | undefined;
421
+ plannedEndDate?: string | undefined;
422
+ projectIds?: number[] | undefined;
423
+ epicId?: number | undefined;
424
+ state?: string | undefined;
425
+ priority?: string | undefined;
426
+ ownerId?: number | undefined;
427
+ description?: string | undefined;
428
+ tags?: number[] | undefined;
429
+ teamId?: number[] | undefined;
430
+ actualStartDate?: string | undefined;
431
+ actualEndDate?: string | undefined;
432
+ actualEffort?: number | undefined;
433
+ remainingEffort?: number | undefined;
434
+ customFields?: Record<string, unknown> | undefined;
435
+ updateVersion?: number | undefined;
120
436
  };
121
437
  /** A RELEASE (SimplifyQA `pm.release`). `state` is the release state ("planned", "in-progress", ...). */
122
438
  export type ReleaseSummary = {
@@ -147,6 +463,145 @@ export type ModuleSummary = {
147
463
  name: string;
148
464
  parentId?: string | undefined;
149
465
  };
466
+ /** Full MODULE detail — `list_modules` returns only summary rows; `get_module` returns everything the
467
+ * server persists (description, human-readable code, immediate children, project). */
468
+ export type ModuleDetail = ModuleSummary & {
469
+ code?: string | undefined;
470
+ description?: string | undefined;
471
+ childIds?: number[] | undefined;
472
+ projectId?: string | undefined;
473
+ isRoot?: boolean | undefined;
474
+ };
475
+ /** Input to `createModule`. `isRoot:true` files under the project root (server strips `parentId`);
476
+ * otherwise `parentId` must resolve to an existing module in the same project. */
477
+ export type ModuleCreateInput = {
478
+ name: string;
479
+ projectId: string;
480
+ isRoot: boolean;
481
+ parentId?: string | undefined;
482
+ description?: string | undefined;
483
+ };
484
+ /** Per-id dependency footprint the PATCH /pm/module dry-run returns. Non-empty arrays block delete
485
+ * until the referring rows are moved or removed. */
486
+ export type ModuleDependency = {
487
+ id: number;
488
+ tcArr: number[];
489
+ fnArr: number[];
490
+ parameterArr: number[];
491
+ objArr: number[];
492
+ defectArr: number[];
493
+ usArr: number[];
494
+ };
495
+ /** Result of `deleteModule`. `dryRun:true` → nothing was deleted; `dependencies` names what still
496
+ * references each id. `dryRun:false` → server actually deleted the ids with empty dependencies and
497
+ * silently skipped the rest; `dependencies` still surfaces the skipped-with-refs list for the caller
498
+ * to act on. */
499
+ export type ModuleDeleteResult = {
500
+ dryRun: boolean;
501
+ dependencies: ModuleDependency[];
502
+ };
503
+ /** Input to `deleteVersion`. `kind` toggles the backend `parentType` ('TC'|'FN'); `versionId` is
504
+ * the tcfn_version uuid (from `TestCase.versions[]` / `QaFunction.versions[]`); `versionName` is
505
+ * required by the backend validator even though the delete match doesn't strictly need it. */
506
+ export type VersionDeleteInput = {
507
+ kind: 'tc' | 'fn';
508
+ parentId: string;
509
+ versionId: string;
510
+ versionName: string;
511
+ confirm?: boolean;
512
+ };
513
+ /** TC-version dependency row — matches the payload SQA's dry-run returns for `parentType==='TC'`
514
+ * (tcfnversion.service.js:219). Each `*Arr` maps projectId (as a string key) → array of referring
515
+ * entity ids in that project. Empty maps mean "no refs of this kind". */
516
+ export type TcVersionDep = {
517
+ id: number;
518
+ versionName?: string | undefined;
519
+ defectArr: Record<string, number[]>;
520
+ suiteArr: Record<string, number[]>;
521
+ epArr: Record<string, number[]>;
522
+ scenarioArr: Record<string, number[]>;
523
+ schedulerArr: Record<string, number[]>;
524
+ pipelineArr: Record<string, number[]>;
525
+ workflowArr: Record<string, number[]>;
526
+ };
527
+ /** FN-version dependency row — matches the payload SQA returns for `parentType==='FN'`
528
+ * (tcfnversion.service.js:267). Same {projectId → ids} shape, narrower key set. */
529
+ export type FnVersionDep = {
530
+ id: number;
531
+ tcArr: Record<string, number[]>;
532
+ fnArr: Record<string, number[]>;
533
+ wfArr: Record<string, number[]>;
534
+ };
535
+ /** Result of `deleteVersion`. Two-phase mirrors the backend contract (tcfnversion.service.js:30):
536
+ * - `confirm:false` → `dryRun:true`, `dependencies` non-empty either way (each ref-array in the
537
+ * dep row may be empty maps — a truly-safe delete is when EVERY *Arr is `{}`).
538
+ * - `confirm:true` with empty deps → `dryRun:false`, `deleted:true`, `dependencies` empty.
539
+ * - `confirm:true` with non-empty deps → SERVER REFUSED: `dryRun:false`, `deleted:false`,
540
+ * `dependencies` populated. Caller must inspect the shape, not assume success from confirm:true. */
541
+ export type VersionDeleteResult = {
542
+ dryRun: boolean;
543
+ deleted: boolean;
544
+ dependencies: Array<TcVersionDep | FnVersionDep>;
545
+ /** True when any dependency row still has a non-empty ref map. When `dryRun:true` this means
546
+ * "delete would be refused"; when `dryRun:false` this means "server refused the delete". */
547
+ hasBlockers: boolean;
548
+ };
549
+ /** A reusable FUNCTION (SimplifyQA `tcfnObj` with type='FN'). Distinct from a TC: intended to be
550
+ * called as a nested step from many test cases. `fnType` is the technology (WEB/API/ANDROID/IOS);
551
+ * `executionType` is MANUAL/AUTOMATION; `status` is the review/approve status. */
552
+ export type FunctionSummary = {
553
+ id: string;
554
+ code?: string;
555
+ name: string;
556
+ description?: string | undefined;
557
+ fnType?: string | undefined;
558
+ executionType?: string | undefined;
559
+ stepCount?: number | undefined;
560
+ status?: string | undefined;
561
+ };
562
+ export type QaFunction = {
563
+ id: string;
564
+ code?: string | undefined;
565
+ name: string;
566
+ description?: string | undefined;
567
+ fnType?: string | undefined;
568
+ executionType?: string | undefined;
569
+ status?: string | undefined;
570
+ stepCount?: number | undefined;
571
+ steps: Step[];
572
+ /** Present when the FN has versions (SQA always does). Newest first — same shape as `TestCase.versions`. */
573
+ versions?: TcVersion[] | undefined;
574
+ };
575
+ export type FunctionQuery = {
576
+ search?: string;
577
+ fnType?: string;
578
+ executionType?: string;
579
+ /** Filter to functions filed under this module (id or business key). */
580
+ moduleId?: string;
581
+ /** Numeric userId of the creator. Pass "me" and the adapter substitutes cfg.userId. */
582
+ createdBy?: string;
583
+ /** Numeric userId of the last updater. Pass "me" and the adapter substitutes cfg.userId. */
584
+ updatedBy?: string;
585
+ limit?: number;
586
+ offset?: number;
587
+ };
588
+ /** A USER row from `/pm/user/search` — the identity behind `createdBy` / `updatedBy` on stories &
589
+ * testcases. Use `list_users` to resolve a name → id, then pass that id to `tc_list({createdBy})`. */
590
+ export type UserSummary = {
591
+ id: string;
592
+ name?: string;
593
+ email?: string;
594
+ username?: string;
595
+ status?: string;
596
+ };
597
+ export type UserQuery = {
598
+ search?: string;
599
+ limit?: number;
600
+ offset?: number;
601
+ /** Restrict to users assigned to this project (via projectuserrole). Non-admin callers are
602
+ * already scoped server-side to their accessible projects. */
603
+ projectId?: string;
604
+ };
150
605
  export type QaObject = {
151
606
  id?: string;
152
607
  name: string;
@@ -155,8 +610,10 @@ export type QaObject = {
155
610
  locators: Locator[];
156
611
  };
157
612
  export type ObjectQuery = {
158
- query: string;
613
+ query?: string;
159
614
  pageName?: string;
615
+ limit?: number;
616
+ offset?: number;
160
617
  };
161
618
  export type Suite = {
162
619
  id?: string;
@@ -167,10 +624,12 @@ export type Suite = {
167
624
  order: number;
168
625
  }[];
169
626
  };
627
+ /** `suiteType` is SimplifyQA-only ("MANUAL" | "AUTOMATION"); absent on Walnut. */
170
628
  export type SuiteSummary = {
171
629
  id: string;
172
630
  name: string;
173
631
  memberCount?: number;
632
+ suiteType?: string | undefined;
174
633
  };
175
634
  export type MemberOp = {
176
635
  op: 'add' | 'remove' | 'reorder';
@@ -204,6 +663,16 @@ export type RunOptions = {
204
663
  maxConcurrent?: number;
205
664
  /** SUITE runs only — stop dispatching remaining test cases after the first failure. */
206
665
  terminateOnFailure?: boolean;
666
+ /** SimplifyQA project-management tag on the run. Optional — the UI's "Release" picker
667
+ * (from `list_releases`). Sent as numeric `releaseId` on the exec payload; default 0. */
668
+ releaseId?: string;
669
+ /** SimplifyQA project-management tag on the run. Optional — the UI's "Sprint" picker
670
+ * (from `list_sprints`). Sent as numeric `iterationId` on the exec payload; default 0. */
671
+ sprintId?: string;
672
+ /** Override the TC's currently-selected version for this run. Optional — the UI's
673
+ * "Version" chip defaults to the TC's current; pass an id from the TC's `versions[]` to run
674
+ * a different one. Omit to run the current version. */
675
+ versionId?: string;
207
676
  };
208
677
  export type RunRef = {
209
678
  runId: string;
@@ -253,6 +722,13 @@ export type ScheduleOptions = {
253
722
  browser?: string;
254
723
  /** Environment id (Mongo id); only forwarded when it is a 24-hex id, mirroring startRun. */
255
724
  environmentId?: string;
725
+ /** Tag the scheduled run with a RELEASE (from list_releases). REQUIRED for suite schedules on
726
+ * SimplifyQA — the UI marks Release with `*` when _parentComponent==='SU'. Sent as numeric
727
+ * releaseId on the schedule payload. */
728
+ releaseId?: string;
729
+ /** Tag the scheduled run with a SPRINT (from list_sprints). REQUIRED for suite schedules on
730
+ * SimplifyQA — mirrors the UI. SQA's underlying column is `iterationId`. */
731
+ sprintId?: string;
256
732
  /** REQUIRED — ISO datetime of the first (or only) run. */
257
733
  scheduledFor: string;
258
734
  /** Recurrence cadence. Default 'once'. */
@@ -339,6 +815,8 @@ export type ActionDef = {
339
815
  export type EnvInfo = {
340
816
  id: string;
341
817
  name: string;
818
+ key?: string;
819
+ isDefault?: boolean;
342
820
  };
343
821
  export type DatasetInfo = {
344
822
  id: string;
@@ -354,10 +832,13 @@ export type DefaultIteration = {
354
832
  tcId: string;
355
833
  versionId: string;
356
834
  environmentType: string;
835
+ /** `seed` is already masked for a protected parameter ("*****" / "(empty)") — the real value
836
+ * never leaves the adapter. */
357
837
  parameters: Array<{
358
838
  paramId: number;
359
839
  name: string;
360
840
  seed: string;
841
+ protected?: boolean | undefined;
361
842
  }>;
362
843
  };
363
844
  /** Request body for `saveGeneratedIterations`. `rows[i]` is a flat `{paramName: value}` map; the
@@ -414,7 +895,7 @@ export type SaveGeneratedIterationsResult = {
414
895
  datasetUrl?: string;
415
896
  };
416
897
  export type EntityRef = {
417
- kind: 'testcase' | 'suite' | 'run';
898
+ kind: 'testcase' | 'suite' | 'run' | 'function';
418
899
  id: string;
419
900
  };
420
901
  /** The recording-JOURNAL view of a test case, for journal-first editing. `source:'journal'` = steps