common-qa-mcp 0.2.0 → 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.
Files changed (86) hide show
  1. package/README.md +6 -0
  2. package/dist/adapters/factory.d.ts +17 -7
  3. package/dist/adapters/factory.d.ts.map +1 -1
  4. package/dist/adapters/factory.js +61 -7
  5. package/dist/adapters/factory.js.map +1 -1
  6. package/dist/adapters/http.d.ts +50 -0
  7. package/dist/adapters/http.d.ts.map +1 -0
  8. package/dist/adapters/http.js +109 -0
  9. package/dist/adapters/http.js.map +1 -0
  10. package/dist/adapters/remoteMcp/adapter.d.ts +10 -1
  11. package/dist/adapters/remoteMcp/adapter.d.ts.map +1 -1
  12. package/dist/adapters/remoteMcp/adapter.js +26 -3
  13. package/dist/adapters/remoteMcp/adapter.js.map +1 -1
  14. package/dist/adapters/simplifyqa/adapter.d.ts +154 -0
  15. package/dist/adapters/simplifyqa/adapter.d.ts.map +1 -0
  16. package/dist/adapters/simplifyqa/adapter.js +1150 -0
  17. package/dist/adapters/simplifyqa/adapter.js.map +1 -0
  18. package/dist/adapters/simplifyqa/mapper.d.ts +63 -0
  19. package/dist/adapters/simplifyqa/mapper.d.ts.map +1 -0
  20. package/dist/adapters/simplifyqa/mapper.js +409 -0
  21. package/dist/adapters/simplifyqa/mapper.js.map +1 -0
  22. package/dist/adapters/types.d.ts +48 -1
  23. package/dist/adapters/types.d.ts.map +1 -1
  24. package/dist/adapters/walnut/adapter.d.ts +231 -0
  25. package/dist/adapters/walnut/adapter.d.ts.map +1 -0
  26. package/dist/adapters/walnut/adapter.js +1083 -0
  27. package/dist/adapters/walnut/adapter.js.map +1 -0
  28. package/dist/adapters/walnut/mapper.d.ts +29 -9
  29. package/dist/adapters/walnut/mapper.d.ts.map +1 -1
  30. package/dist/adapters/walnut/mapper.js +136 -24
  31. package/dist/adapters/walnut/mapper.js.map +1 -1
  32. package/dist/config.d.ts +28 -14
  33. package/dist/config.d.ts.map +1 -1
  34. package/dist/config.js +37 -19
  35. package/dist/config.js.map +1 -1
  36. package/dist/connection.d.ts +3 -2
  37. package/dist/connection.d.ts.map +1 -1
  38. package/dist/connection.js +36 -15
  39. package/dist/connection.js.map +1 -1
  40. package/dist/domain/types.d.ts +195 -1
  41. package/dist/domain/types.d.ts.map +1 -1
  42. package/dist/drafts/store.d.ts +4 -1
  43. package/dist/drafts/store.d.ts.map +1 -1
  44. package/dist/drafts/store.js +7 -2
  45. package/dist/drafts/store.js.map +1 -1
  46. package/dist/initAgents.d.ts.map +1 -1
  47. package/dist/initAgents.js +29 -12
  48. package/dist/initAgents.js.map +1 -1
  49. package/dist/requestConnection.d.ts +5 -3
  50. package/dist/requestConnection.d.ts.map +1 -1
  51. package/dist/requestConnection.js +11 -5
  52. package/dist/requestConnection.js.map +1 -1
  53. package/dist/server.d.ts.map +1 -1
  54. package/dist/server.js +25 -1
  55. package/dist/server.js.map +1 -1
  56. package/dist/tools/connection.tools.js +5 -5
  57. package/dist/tools/connection.tools.js.map +1 -1
  58. package/dist/tools/discovery.tools.d.ts.map +1 -1
  59. package/dist/tools/discovery.tools.js +93 -1
  60. package/dist/tools/discovery.tools.js.map +1 -1
  61. package/dist/tools/formulas.tools.d.ts +7 -0
  62. package/dist/tools/formulas.tools.d.ts.map +1 -0
  63. package/dist/tools/formulas.tools.js +56 -0
  64. package/dist/tools/formulas.tools.js.map +1 -0
  65. package/dist/tools/heal.tools.d.ts +17 -0
  66. package/dist/tools/heal.tools.d.ts.map +1 -0
  67. package/dist/tools/heal.tools.js +76 -0
  68. package/dist/tools/heal.tools.js.map +1 -0
  69. package/dist/tools/recording.tools.d.ts.map +1 -1
  70. package/dist/tools/recording.tools.js +28 -7
  71. package/dist/tools/recording.tools.js.map +1 -1
  72. package/dist/tools/run.tools.d.ts.map +1 -1
  73. package/dist/tools/run.tools.js +378 -37
  74. package/dist/tools/run.tools.js.map +1 -1
  75. package/dist/tools/storySync.tools.d.ts +66 -0
  76. package/dist/tools/storySync.tools.d.ts.map +1 -0
  77. package/dist/tools/storySync.tools.js +213 -0
  78. package/dist/tools/storySync.tools.js.map +1 -0
  79. package/dist/tools/testcase.tools.d.ts.map +1 -1
  80. package/dist/tools/testcase.tools.js +17 -2
  81. package/dist/tools/testcase.tools.js.map +1 -1
  82. package/dist/tools/testdata.tools.d.ts +7 -0
  83. package/dist/tools/testdata.tools.d.ts.map +1 -0
  84. package/dist/tools/testdata.tools.js +161 -0
  85. package/dist/tools/testdata.tools.js.map +1 -0
  86. package/package.json +1 -1
@@ -0,0 +1,154 @@
1
+ import type { ConnectedQaConfig } from '../../config.js';
2
+ import type { MakeClientOptions } from '../http.js';
3
+ import type { ProjectInfo } from '../types.js';
4
+ import type { ActionDef, CloudRunner, DatasetInfo, DefaultIteration, EntityRef, EnvInfo, Formula, FormulaCall, JournalOp, JournalView, LocalAgent, MemberOp, ModuleSummary, ObjectQuery, ProjectSummary, QaObject, ReleaseQuery, ReleaseSummary, RunOptions, RunRef, RunStatus, RunTarget, SaveGeneratedIterations, SaveGeneratedIterationsResult, SavedRef, SprintQuery, SprintSummary, Story, StoryQuery, StorySummary, Suite, SuiteSummary, TcQuery, TcSummary, TestCase } from '../../domain/types.js';
5
+ /** Test seam identical to WalnutAdapter's — swap transport, keep real headers. */
6
+ export type SimplifyQaTransport = Pick<MakeClientOptions, 'fetchImpl' | 'FormDataImpl' | 'BlobImpl'>;
7
+ /**
8
+ * SimplifyQaAdapter — DIRECT-to-backend REST driver for SimplifyQA, mirroring WalnutAdapter's
9
+ * design. Reads (list/get for projects/testcases/suites/stories/modules/releases/sprints/objects)
10
+ * hit the SQA TM backend REST directly via a `QaHttp` bound to `cfg.baseUrl`. Anything not yet
11
+ * ported (writes, testdata, run dispatch, marketplace, and the recording surface) delegates to
12
+ * the LOCAL AGENT's `/mcp` (`cfg.url`) via a lazily-built RemoteMcpAdapter — same "graceful hop"
13
+ * pattern walnut uses for recording. When the hop is not configured, unported ops surface a clear
14
+ * error instead of failing silently.
15
+ *
16
+ * This class deliberately does not `implements ProviderAdapter` (walnut trick): the factory casts
17
+ * it, and tools that call ported methods get direct REST; tools that call unported methods get
18
+ * the hop (or a clear error). Each porting step replaces one more delegation with a direct call.
19
+ */
20
+ export declare class SimplifyQaAdapter {
21
+ private readonly cfg;
22
+ private readonly http;
23
+ private agentHop;
24
+ private formulaCache;
25
+ constructor(cfg: ConnectedQaConfig, transport?: SimplifyQaTransport);
26
+ private headers;
27
+ private requireProjectId;
28
+ private searchBody;
29
+ /** Validates baseUrl + token + (optional) project by running the same list_projects search the
30
+ * Java `infoResult` uses to resolve the project name — no separate /info endpoint on SQA. */
31
+ info(): Promise<ProjectInfo>;
32
+ /** `POST /pm/project/search` — projects the token can see. NOT project-scoped. */
33
+ listProjects(): Promise<ProjectSummary[]>;
34
+ listTestCases(q: TcQuery): Promise<TcSummary[]>;
35
+ /** Neutral test case, steps included. Accepts numeric id or business code (`TC_123`). */
36
+ getTestCase(id: string): Promise<TestCase>;
37
+ private fetchRawTestcase;
38
+ private fetchStepsCollection;
39
+ listSuites(): Promise<SuiteSummary[]>;
40
+ getSuite(id: string): Promise<Suite>;
41
+ listStories(q: StoryQuery): Promise<StorySummary[]>;
42
+ getStory(id: string): Promise<Story>;
43
+ /** A US_XXX business key → the numeric userstoryId via `/pm/userstory/search`. Numeric passes
44
+ * through. SQA's GET-by-id parseInts the path, so a raw key would 404. */
45
+ private resolveStoryNumericId;
46
+ listModules(): Promise<ModuleSummary[]>;
47
+ listReleases(q: ReleaseQuery): Promise<ReleaseSummary[]>;
48
+ listSprints(q: SprintQuery): Promise<SprintSummary[]>;
49
+ getObject(id: string): Promise<QaObject>;
50
+ productUrlFor(entity: EntityRef): string;
51
+ private hop;
52
+ private requireHop;
53
+ /** Recording tool schemas from the SQA agent — mirrored so the recording passthrough can register
54
+ * them. No agent configured → `[]`, so no recording tools get registered. */
55
+ listAgentTools(): Promise<Array<{
56
+ name: string;
57
+ description?: string;
58
+ inputSchema?: Record<string, unknown>;
59
+ }>>;
60
+ /** Forward a recording-tool call to the agent /mcp. Same behavior as walnut. */
61
+ callRaw(name: string, args: Record<string, unknown>): Promise<unknown>;
62
+ /** Two-step create: (1) resolve every `${name}` token in the steps to a project-scoped parameter id
63
+ * (get-or-create), (2) POST /tm/testcase multipart with the assembled `testcaseObj`. */
64
+ createTestCase(tc: TestCase): Promise<SavedRef>;
65
+ /** Same shape as create, but with `tcfnObj.id` set and operation:'UPDATE'. */
66
+ updateTestCase(id: string, tc: TestCase): Promise<SavedRef>;
67
+ /** Soft-delete (recoverable via recycle bin). `isDelete:true` = delete; `false` = restore. */
68
+ deleteTestCase(id: string): Promise<void>;
69
+ /** Never throw on unresolvable storyRef — the Java code logs and moves on so the save still lands. */
70
+ private resolveStoryNumericIdOrNull;
71
+ /** Resolve every `${name}` token across every step to a SQA parameter id via get-or-create.
72
+ * Name-uniqueness is project-wide on the backend; get-or-create means every TC using
73
+ * `${appUrl}` links to the same parameter row. */
74
+ private resolveParamIds;
75
+ /** Case-insensitive project-scoped exact-name lookup. Backend duplicate-name check uses Mongo
76
+ * collation strength:2, so a case-sensitive search here misses params stored under different
77
+ * casing — the next POST then trips "Duplicate Name Error". Returns null when not found. */
78
+ private findParameterId;
79
+ private getOrCreateParameter;
80
+ createSuite(s: Suite): Promise<SavedRef>;
81
+ /** Fetch raw suite, apply add/remove/reorder ops in memory, then PUT the whole doc back with a
82
+ * STRICT allow-listed payload (the SQA update validator rejects unknown keys on both suite-level
83
+ * and testCases[] entries). */
84
+ updateSuiteMembers(id: string, ops: MemberOp[]): Promise<Suite>;
85
+ /** Soft-delete via `isDelete:true`. `isDelete:false` restores. */
86
+ deleteSuite(id: string): Promise<void>;
87
+ private fetchRawSuite;
88
+ /** Assemble the strict allow-listed suite entry for an ADD op. Required fields per the SQA
89
+ * validator: testcaseId, code, seq (set by the caller), version, versionId, tcType. */
90
+ private buildSuiteEntryFromTestcase;
91
+ searchObjects(q: ObjectQuery): Promise<QaObject[]>;
92
+ createObject(o: QaObject): Promise<QaObject>;
93
+ actionsCatalog(platform?: string): Promise<ActionDef[]>;
94
+ /** Fetch the default (template) iteration row for a TC. Fills gaps from the raw TC:
95
+ * - versionId: falls back through versionId → selectedVersionId → versionsDetails.id → versions[0].id
96
+ * - executionType (required by the backend Mongo filter): read from raw TC, default AUTOMATION
97
+ * - environmentType: caller value wins; else /pm/fields/8 first configured env; else 'general' */
98
+ getDefaultIteration(q: {
99
+ tcId: string;
100
+ versionId?: string;
101
+ environmentType?: string;
102
+ }): Promise<DefaultIteration>;
103
+ /** Persist N generated iteration rows. Rebuilds the name → paramId map from a fresh template
104
+ * fetch — no cache, because a stale id would silently write to the wrong parameter. */
105
+ saveGeneratedIterations(payload: SaveGeneratedIterations): Promise<SaveGeneratedIterationsResult>;
106
+ /** Environment key: caller wins; else fetch the project's configured envs and pick the first;
107
+ * else 'general' (matches the SQA UI fallback). */
108
+ private resolveEnvironment;
109
+ /** Parameter name lookup for paramId → name enrichment. Null when the parameter is deleted or
110
+ * belongs to a different project. */
111
+ private fetchParameterName;
112
+ /** List every formula the current project can use — DEFAULT (customer-wide prefabs) unioned with
113
+ * CUSTOM entries scoped to the customer or this project. The backend endpoint already returns the
114
+ * union when called with `projectId`; we just normalise the doc shape and derive `scope` from
115
+ * (type + projectId). Cached per adapter instance. */
116
+ listFormulas(): Promise<Formula[]>;
117
+ /** Evaluate one formula call and return { value, expression }. Order args by the formula's declared
118
+ * parameter list so the stored `formulaValue` string is positional (`=NAME("a","b")`) — that's
119
+ * what the SQA UI writes, and the backend just reads it verbatim on save. */
120
+ evaluateFormula(call: FormulaCall): Promise<{
121
+ value: string;
122
+ expression: string;
123
+ }>;
124
+ /** Real status of a run — reads step-level results direct from SQA REST because the desktop agent's
125
+ * get_run only returns queue state (often stale). start/stop still hop for v1. */
126
+ getRun(runId: string): Promise<RunStatus>;
127
+ startRun(target: RunTarget, opts: RunOptions): Promise<RunRef>;
128
+ stopRun(runId: string): Promise<void>;
129
+ listCloudRunners(): Promise<CloudRunner[]>;
130
+ listLocalAgents(): Promise<LocalAgent[]>;
131
+ /**
132
+ * Pick THE ACTING USER'S OWN active agent — never row [0] of a shared-tenant roster (which
133
+ * would silently dispatch a local run to a teammate's box, and the run would sit queued until
134
+ * TTL because it lands in a Redis key that no local agent on the caller's machine polls).
135
+ *
136
+ * SQA's `machineRegistration` row carries no owner_user_id column (unlike walnut, which matches
137
+ * the JWT `id` claim to `owner_user_id`), so we identify "your" agent by hostname: common-mcp
138
+ * runs on the caller's own box in the typical MCP setup, and SQA `machineName` is either the
139
+ * bare OS hostname or a bracketed display form (`USER.NAME [ Hostname.local ]`) — both contain
140
+ * `os.hostname()`. Filter → active only → hostname substring match → return the single hit.
141
+ * Zero/many matches refuse honestly; a silent guess would just repeat the exact bug we're fixing.
142
+ *
143
+ * ponytail: hostname heuristic. Upgrade to owner-user-id match if the backend adds that column
144
+ * to machineRegistration (mirror walnut's `resolveLocalAgentCredential` at that point).
145
+ */
146
+ private resolveLocalAgentId;
147
+ private detectExecutionOS;
148
+ private buildRunPlatform;
149
+ listEnvironments(): Promise<EnvInfo[]>;
150
+ listDatasets(tcId?: string): Promise<DatasetInfo[]>;
151
+ readJournal(tcId: string): Promise<JournalView>;
152
+ editJournal(tcId: string, ops: JournalOp[]): Promise<JournalView>;
153
+ }
154
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/simplifyqa/adapter.ts"],"names":[],"mappings":"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"}