ado-sync 0.1.47 → 0.1.48

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.
@@ -9,54 +9,94 @@ Using the MCP server instead of spawning the CLI gives agents:
9
9
 
10
10
  ---
11
11
 
12
- ## Start the server
12
+ ## Installation
13
13
 
14
+ No separate install needed. `ado-sync-mcp` ships inside the `ado-sync` npm package.
15
+
16
+ **Option A — Global install (recommended, fastest startup)**
14
17
  ```bash
15
- # stdio transport (standard for IDE integrations)
16
- ado-sync-mcp
18
+ npm install -g ado-sync
17
19
  ```
18
20
 
19
- The server reads your `ado-sync.json` (or the path in `ADO_SYNC_CONFIG` env var) automatically.
21
+ **Option B npx (no install, always latest)**
22
+
23
+ Use `npx --yes --package=ado-sync ado-sync-mcp` as the command in all configs below.
24
+ npx downloads and runs the package automatically on first use.
25
+
26
+ ---
27
+
28
+ ## Claude Code — one-liner registration
20
29
 
21
30
  ```bash
22
- # Point at a specific config
23
- ADO_SYNC_CONFIG=/path/to/ado-sync.json ado-sync-mcp
31
+ # With global install
32
+ claude mcp add ado-sync \
33
+ --env AZURE_DEVOPS_TOKEN="$AZURE_DEVOPS_TOKEN" \
34
+ --env ADO_SYNC_CONFIG="$(pwd)/ado-sync.json" \
35
+ -- ado-sync-mcp
36
+
37
+ # With npx (no global install required)
38
+ claude mcp add ado-sync \
39
+ --env AZURE_DEVOPS_TOKEN="$AZURE_DEVOPS_TOKEN" \
40
+ --env ADO_SYNC_CONFIG="$(pwd)/ado-sync.json" \
41
+ -- npx --yes --package=ado-sync ado-sync-mcp
42
+ ```
43
+
44
+ Verify it registered: run `/mcp` in Claude Code — `ado-sync` should appear in the list.
45
+
46
+ **Manual config** — `~/.claude/claude_desktop_config.json`:
47
+ ```json
48
+ {
49
+ "mcpServers": {
50
+ "ado-sync": {
51
+ "command": "npx",
52
+ "args": ["--yes", "--package=ado-sync", "ado-sync-mcp"],
53
+ "env": {
54
+ "AZURE_DEVOPS_TOKEN": "<your-pat>",
55
+ "ADO_SYNC_CONFIG": "/absolute/path/to/ado-sync.json"
56
+ }
57
+ }
58
+ }
59
+ }
24
60
  ```
25
61
 
26
62
  ---
27
63
 
28
- ## Register in Claude Code
64
+ ## Claude Desktop
29
65
 
30
- Add to `~/.claude/claude_desktop_config.json` (or the path shown in Claude Code → Settings → MCP):
66
+ Config file location:
67
+ - macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`
68
+ - Windows: `%APPDATA%\Claude\claude_desktop_config.json`
31
69
 
32
70
  ```json
33
71
  {
34
72
  "mcpServers": {
35
73
  "ado-sync": {
36
- "command": "ado-sync-mcp",
74
+ "command": "npx",
75
+ "args": ["--yes", "--package=ado-sync", "ado-sync-mcp"],
37
76
  "env": {
38
- "AZURE_DEVOPS_TOKEN": "<your-token>",
39
- "ADO_SYNC_CONFIG": "/path/to/ado-sync.json"
77
+ "AZURE_DEVOPS_TOKEN": "<your-pat>",
78
+ "ADO_SYNC_CONFIG": "/absolute/path/to/ado-sync.json"
40
79
  }
41
80
  }
42
81
  }
43
82
  }
44
83
  ```
45
84
 
46
- Restart Claude Code. The tools appear automatically under the `ado-sync` server namespace.
85
+ Restart Claude Desktop after saving.
47
86
 
48
87
  ---
49
88
 
50
- ## Register in VS Code (GitHub Copilot)
89
+ ## VS Code (GitHub Copilot agent mode)
51
90
 
52
- Add to `.vscode/mcp.json` in your workspace (or user settings):
91
+ Create `.vscode/mcp.json` in your workspace root:
53
92
 
54
93
  ```json
55
94
  {
56
95
  "servers": {
57
96
  "ado-sync": {
58
97
  "type": "stdio",
59
- "command": "ado-sync-mcp",
98
+ "command": "npx",
99
+ "args": ["--yes", "--package=ado-sync", "ado-sync-mcp"],
60
100
  "env": {
61
101
  "AZURE_DEVOPS_TOKEN": "${env:AZURE_DEVOPS_TOKEN}",
62
102
  "ADO_SYNC_CONFIG": "${workspaceFolder}/ado-sync.json"
@@ -66,20 +106,23 @@ Add to `.vscode/mcp.json` in your workspace (or user settings):
66
106
  }
67
107
  ```
68
108
 
109
+ `${env:AZURE_DEVOPS_TOKEN}` reads the variable from your shell environment — no hardcoded secrets.
110
+
69
111
  ---
70
112
 
71
- ## Register in Cursor
113
+ ## Cursor
72
114
 
73
- Add to `~/.cursor/mcp.json`:
115
+ `~/.cursor/mcp.json`:
74
116
 
75
117
  ```json
76
118
  {
77
119
  "mcpServers": {
78
120
  "ado-sync": {
79
- "command": "ado-sync-mcp",
121
+ "command": "npx",
122
+ "args": ["--yes", "--package=ado-sync", "ado-sync-mcp"],
80
123
  "env": {
81
- "AZURE_DEVOPS_TOKEN": "<your-token>",
82
- "ADO_SYNC_CONFIG": "/path/to/ado-sync.json"
124
+ "AZURE_DEVOPS_TOKEN": "<your-pat>",
125
+ "ADO_SYNC_CONFIG": "/absolute/path/to/ado-sync.json"
83
126
  }
84
127
  }
85
128
  }
@@ -88,6 +131,18 @@ Add to `~/.cursor/mcp.json`:
88
131
 
89
132
  ---
90
133
 
134
+ ## Verify it works
135
+
136
+ After registration, ask your AI assistant:
137
+
138
+ ```
139
+ "Call ado-sync validate_config and tell me what it returns"
140
+ ```
141
+
142
+ Expected response includes config validity, Azure connection status, and test plan confirmation.
143
+
144
+ ---
145
+
91
146
  ## Available tools
92
147
 
93
148
  | Tool | Description |
@@ -101,7 +156,10 @@ Add to `~/.cursor/mcp.json`:
101
156
  | `diff` | Show field-level diff (richer than status) |
102
157
  | `generate_specs` | Generate local spec files from ADO User Stories |
103
158
  | `get_work_items` | Fetch ADO User Stories / work items |
104
- | `publish_test_results` | Publish TRX / JUnit / Playwright JSON results |
159
+ | `publish_test_results` | Publish TRX / JUnit / Playwright JSON / CTRF results; optionally file issues for failures |
160
+ | `create_issue` | File a single GitHub Issue or ADO Bug for a test failure (for healer agents) |
161
+ | `get_story_context` | Planner-agent feed: AC items, suggested tags, actors, linked TC IDs |
162
+ | `generate_manifest` | Write `.ai-workflow-manifest-{id}.json` for the full Planner→CI cycle |
105
163
 
106
164
  ---
107
165
 
@@ -111,7 +169,7 @@ All tools accept these optional base parameters:
111
169
 
112
170
  | Parameter | Type | Description |
113
171
  |-----------|------|-------------|
114
- | `configPath` | string | Path to `ado-sync.json` (overrides `ADO_SYNC_CONFIG`) |
172
+ | `configPath` | string | Absolute path to `ado-sync.json` (overrides `ADO_SYNC_CONFIG`) |
115
173
  | `configOverrides` | string[] | Runtime overrides in `key=value` format (same as `--config-override`) |
116
174
 
117
175
  ### `push_specs`
@@ -141,10 +199,50 @@ All tools accept these optional base parameters:
141
199
  ```json
142
200
  {
143
201
  "testResult": "results/playwright.json",
144
- "attachmentsFolder": "test-results/"
202
+ "attachmentsFolder": "test-results/",
203
+ "createIssuesOnFailure": true,
204
+ "issueProvider": "github",
205
+ "githubRepo": "myorg/myrepo",
206
+ "githubToken": "$GITHUB_TOKEN",
207
+ "bugThreshold": 20,
208
+ "maxIssues": 50
209
+ }
210
+ ```
211
+
212
+ ### `create_issue`
213
+
214
+ ```json
215
+ {
216
+ "title": "[FAILED] Login with valid credentials",
217
+ "body": "Error: Expected 200 but got 401\n\nStack: ...",
218
+ "provider": "github",
219
+ "githubRepo": "myorg/myrepo",
220
+ "githubToken": "$GITHUB_TOKEN",
221
+ "testCaseId": 1234
145
222
  }
146
223
  ```
147
224
 
225
+ ### `get_story_context`
226
+
227
+ ```json
228
+ { "storyId": 1234 }
229
+ ```
230
+
231
+ Returns: AC items as a bullet list, inferred tags (`@smoke`, `@auth`, …), extracted actors, and IDs of any Test Cases already linked via TestedBy relation.
232
+
233
+ ### `generate_manifest`
234
+
235
+ ```json
236
+ {
237
+ "storyIds": [1234, 5678],
238
+ "outputFolder": "e2e/bdd",
239
+ "format": "gherkin",
240
+ "dryRun": false
241
+ }
242
+ ```
243
+
244
+ Writes `.ai-workflow-manifest-1234.json` in `outputFolder`. The manifest contains the ordered 8-step workflow, AC items, required documents checklist, and validation steps.
245
+
148
246
  ---
149
247
 
150
248
  ## Example agent workflow
@@ -152,15 +250,17 @@ All tools accept these optional base parameters:
152
250
  Once registered, an AI agent can orchestrate the full test lifecycle without any human CLI invocation:
153
251
 
154
252
  ```
155
- Agent: "Push my Playwright specs to Azure DevOps"
156
- → calls push_specs({ dryRun: true }) # preview
157
- → calls push_specs({}) # apply
253
+ Agent: "Set up ado-sync for this repo"
254
+ → calls validate_config to check connectivity
255
+ → calls push_specs({ dryRun: true }) to preview
256
+ → calls push_specs({}) to create Test Cases
158
257
 
159
258
  Agent: "Generate spec files for User Story 1234"
160
259
  → calls generate_specs({ storyIds: [1234], format: "gherkin" })
161
260
 
162
- Agent: "Publish the latest test results"
163
- → calls publish_test_results({ testResult: "results/playwright.json" })
261
+ Agent: "Publish the latest test results and file issues for failures"
262
+ → calls publish_test_results({ testResult: "results/playwright.json", createIssuesOnFailure: true, githubRepo: "myorg/myrepo", githubToken: "$GITHUB_TOKEN" })
263
+ → returns issue URLs for any failures → healer agent opens fix PRs
164
264
  ```
165
265
 
166
266
  ---
@@ -169,5 +269,7 @@ Agent: "Publish the latest test results"
169
269
 
170
270
  | Variable | Description |
171
271
  |----------|-------------|
172
- | `ADO_SYNC_CONFIG` | Path to config file (default: `ado-sync.json` in cwd) |
272
+ | `ADO_SYNC_CONFIG` | Absolute path to config file (default: `ado-sync.json` in cwd) |
173
273
  | `AZURE_DEVOPS_TOKEN` | PAT or access token (referenced by `auth.token` in config) |
274
+
275
+ > **Important:** `ADO_SYNC_CONFIG` must be an **absolute path**. The MCP server process does not inherit the shell's working directory the same way as a CLI call.
@@ -1,6 +1,6 @@
1
1
  # publish-test-results
2
2
 
3
- Parses test result files (TRX, NUnit XML, JUnit, Cucumber JSON, Playwright JSON) and publishes them to an Azure DevOps Test Run, linking results back to Test Cases either directly by TC ID (when available in the result file) or by `AutomatedTestName` matching.
3
+ Parses test result files (TRX, NUnit XML, JUnit, Cucumber JSON, Playwright JSON, CTRF JSON) and publishes them to an Azure DevOps Test Run, linking results back to Test Cases either directly by TC ID (when available in the result file) or by `AutomatedTestName` matching.
4
4
 
5
5
  ---
6
6
 
@@ -31,11 +31,17 @@ ado-sync publish-test-results \
31
31
  | Option | Description |
32
32
  |--------|-------------|
33
33
  | `--testResult <path>` | Path to a result file. Repeatable. |
34
- | `--testResultFormat <format>` | `trx` · `nunitXml` · `junit` · `cucumberJson` · `playwrightJson`. Auto-detected when omitted. |
34
+ | `--testResultFormat <format>` | `trx` · `nunitXml` · `junit` · `cucumberJson` · `playwrightJson` · `ctrfJson`. Auto-detected when omitted. |
35
35
  | `--attachmentsFolder <path>` | Folder to scan for screenshots/videos/logs to attach to test results. |
36
36
  | `--runName <name>` | Name for the Test Run in Azure DevOps. Defaults to `ado-sync <ISO timestamp>`. |
37
37
  | `--buildId <id>` | Build ID to associate with the Test Run. |
38
38
  | `--dry-run` | Parse results and print summary without creating a run in Azure. |
39
+ | `--create-issues-on-failure` | File GitHub Issues or ADO Bugs for each failed test after publishing. |
40
+ | `--issue-provider <github\|ado>` | Issue provider. Default: `github`. |
41
+ | `--github-repo <owner/repo>` | GitHub repository to file issues in. |
42
+ | `--github-token <token>` | GitHub token. Supports `$ENV_VAR` references. |
43
+ | `--bug-threshold <percent>` | If more than this % of tests fail, one environment-failure issue is filed instead of per-test issues. Default: `20`. |
44
+ | `--max-issues <n>` | Hard cap on issues filed per run. Default: `50`. |
39
45
  | `--config-override` | Override config values (repeatable, same as other commands). |
40
46
 
41
47
  ---
@@ -50,6 +56,7 @@ ado-sync publish-test-results \
50
56
  | Cucumber JSON | `.json` | Yes (JSON array, Cucumber format) | Yes — via `@tc:ID` tag on scenario | `step.embeddings[]` (base64 screenshots/video) |
51
57
  | Playwright JSON | `.json` | Yes (JSON object with `suites` key) | Yes — via `test.annotations[{ type: 'tc', description: 'ID' }]` (preferred) or `@tc:ID` in test title | `test.results[].attachments[]` (screenshots, videos, traces) |
52
58
  | Robot Framework XML | `output.xml` | Yes (`<robot>` root element) | Yes — via `<tags><tag>tc:ID</tag></tags>` | — |
59
+ | CTRF JSON | `.json` | Yes (`results.tests` array) | Yes — via `tags: ["@tc:ID"]` or `@tc:ID` in test name | `attachments[].path` files, `stdout`/`stderr` arrays |
53
60
 
54
61
  > **NUnit via TRX**: when NUnit tests are run through the VSTest adapter (`--logger trx`), `[Property]` values are **not** included in the TRX output. Use `--logger "nunit3;LogFileName=results.xml"` to get the native NUnit XML format, which does include property values.
55
62
 
@@ -441,6 +448,38 @@ Recommended config:
441
448
 
442
449
  ---
443
450
 
451
+ ### CTRF (Common Test Report Format)
452
+
453
+ [CTRF](https://ctrf.io) is a framework-agnostic JSON report format supported by reporters for Playwright, Cypress, Jest, k6, and many others. ado-sync auto-detects CTRF from the `results.tests` array structure.
454
+
455
+ ```bash
456
+ # Example: Playwright with CTRF reporter
457
+ npm install --save-dev playwright-ctrf-json-reporter
458
+
459
+ # playwright.config.ts:
460
+ # reporter: [['playwright-ctrf-json-reporter', { outputFile: 'results/ctrf.json' }]]
461
+
462
+ npx playwright test
463
+ ado-sync publish-test-results --testResult results/ctrf.json
464
+ ```
465
+
466
+ ```bash
467
+ # Example: Jest with CTRF reporter
468
+ npm install --save-dev jest-ctrf-json-reporter
469
+
470
+ # jest.config.ts:
471
+ # reporters: [['jest-ctrf-json-reporter', { outputFile: 'results/ctrf.json' }]]
472
+
473
+ npx jest
474
+ ado-sync publish-test-results --testResult results/ctrf.json
475
+ ```
476
+
477
+ TC IDs are extracted from the `tags` array (e.g. `["@tc:1234", "@smoke"]`) or, as a fallback, from `@tc:ID` in the test name. `stdout`/`stderr` arrays and `attachments[].path` files are uploaded automatically.
478
+
479
+ > **Status mapping**: CTRF `passed` → `Passed`, `failed` → `Failed`, `skipped`/`pending`/`other` → `NotExecuted`.
480
+
481
+ ---
482
+
444
483
  ### Flutter
445
484
 
446
485
  Flutter can produce JUnit XML via the `flutter_test_junit` package or by piping `--reporter junit`:
@@ -483,6 +522,7 @@ TC linking uses `AutomatedTestName` matching — set `sync.markAutomated: true`
483
522
  | Espresso | JUnit XML | ❌ AutomatedTestName matching only | `<system-out>`, `<system-err>` | |
484
523
  | Flutter | JUnit XML | ❌ AutomatedTestName matching only | `<system-out>`, `<system-err>` | |
485
524
  | Robot Framework | Robot XML (`output.xml`) | ✅ `tc:N` in `<tags>` | — | |
525
+ | CTRF (any framework) | CTRF JSON | ✅ `tags: ["@tc:ID"]` or `@tc:ID` in name | `attachments[].path` files + `stdout`/`stderr` | |
486
526
 
487
527
  ---
488
528
 
@@ -499,6 +539,7 @@ ado-sync uploads screenshots, videos, and logs from test results to the correspo
499
539
  | JUnit XML | `<system-out>` → log; `<system-err>` → log; `[[ATTACHMENT\|path]]` → Playwright files |
500
540
  | Cucumber JSON | `step.embeddings[]` → base64-encoded screenshots/video |
501
541
  | Playwright JSON | `results[].attachments[].path` → files on disk (screenshots, videos, traces) |
542
+ | CTRF JSON | `tests[].attachments[].path` → files on disk; `tests[].stdout[]` / `tests[].stderr[]` → console logs |
502
543
 
503
544
  > **Note**: All file paths are resolved relative to the result file's directory, not the process working directory. This matches how test runners (Playwright, MSTest, NUnit) write relative paths in their output.
504
545
 
@@ -670,6 +711,99 @@ Results can also be configured in the config file under `publishTestResults`:
670
711
 
671
712
  ---
672
713
 
714
+ ## Creating issues on failure
715
+
716
+ `--create-issues-on-failure` automatically files a GitHub Issue or ADO Bug for each failed test
717
+ after the run is published. Multiple guards prevent flooding your tracker when the environment is
718
+ the problem rather than individual tests.
719
+
720
+ ### Guard logic (applied in order)
721
+
722
+ ```
723
+ failures > threshold% of total?
724
+ └─ YES → 1 environment-failure issue, stop
725
+ └─ NO
726
+ └─ cluster by error signature
727
+ └─ cluster size > 1?
728
+ └─ YES → 1 issue per cluster (lists affected test names)
729
+ └─ NO → 1 issue per TC (up to maxIssues cap)
730
+ └─ cap hit? → 1 overflow summary issue
731
+ ```
732
+
733
+ | Guard | Default | Description |
734
+ |---|---|---|
735
+ | Failure-rate threshold | 20% | Above this, one env-failure issue is filed instead of per-test |
736
+ | Error clustering | enabled | Tests with the same error message are grouped into one issue |
737
+ | Hard cap | 50 | No more than this many issues per run; one overflow summary when exceeded |
738
+ | Dedup | enabled | Skip if an open issue already exists for the same TC (GitHub: by `tc:ID` label; ADO: by title) |
739
+
740
+ ### GitHub Issues (recommended)
741
+
742
+ ```bash
743
+ ado-sync publish-test-results \
744
+ --testResult results/ctrf.json \
745
+ --create-issues-on-failure \
746
+ --github-repo myorg/myrepo \
747
+ --github-token $GITHUB_TOKEN
748
+ ```
749
+
750
+ Each issue is labelled `test-failure` and `tc:{ID}` (when a TC ID is available). The issue body
751
+ contains the error message, stack trace, ADO TC link, and run URL — everything a healer agent
752
+ needs to propose a fix PR.
753
+
754
+ ### ADO Bugs
755
+
756
+ ```bash
757
+ ado-sync publish-test-results \
758
+ --testResult results/junit.xml \
759
+ --create-issues-on-failure \
760
+ --issue-provider ado
761
+ ```
762
+
763
+ ADO Bugs are created as Bug work items in the same project. The `Repro Steps` field is populated
764
+ with the error details. When a TC ID is known, a `TestedBy` relation is added linking the Bug to
765
+ the Test Case.
766
+
767
+ ### Config-based setup
768
+
769
+ ```json
770
+ {
771
+ "publishTestResults": {
772
+ "createIssuesOnFailure": {
773
+ "provider": "github",
774
+ "repo": "myorg/myrepo",
775
+ "token": "$GITHUB_TOKEN",
776
+ "labels": ["test-failure", "automated"],
777
+ "threshold": 20,
778
+ "maxIssues": 50,
779
+ "clusterByError": true,
780
+ "dedupByTestCase": true
781
+ }
782
+ }
783
+ }
784
+ ```
785
+
786
+ CLI flags override the config values when both are present.
787
+
788
+ ### MCP tool: `create_issue`
789
+
790
+ The `create_issue` MCP tool lets healer agents file a single issue directly:
791
+
792
+ ```
793
+ create_issue({
794
+ title: "[FAILED] Login with valid credentials",
795
+ body: "Error: Expected 200 but got 401\n\nStack: ...",
796
+ provider: "github",
797
+ githubRepo: "myorg/myrepo",
798
+ githubToken: "$GITHUB_TOKEN",
799
+ testCaseId: 1234
800
+ })
801
+ ```
802
+
803
+ Returns the issue URL immediately, which the agent can embed in its fix PR.
804
+
805
+ ---
806
+
673
807
  ## Output
674
808
 
675
809
  ```
package/llms.txt CHANGED
@@ -9,7 +9,7 @@ npm package: `ado-sync` | bin: `ado-sync` and `ado-sync-mcp`
9
9
  - `pull` — reads Test Cases from Azure DevOps and updates matching local files
10
10
  - `status` — dry-run diff: shows what would change without touching anything
11
11
  - `diff` — field-level diff showing exactly which fields (title, steps, description) differ
12
- - `publish-test-results` — publishes TRX / JUnit XML / NUnit XML / Cucumber JSON / Playwright JSON results to an Azure DevOps Test Run
12
+ - `publish-test-results` — publishes TRX / JUnit XML / NUnit XML / Cucumber JSON / Playwright JSON / CTRF JSON results to an Azure DevOps Test Run
13
13
  - `generate` — creates local spec files (.feature or .md) from Azure DevOps User Stories
14
14
  - `validate` — checks config validity and Azure connectivity
15
15
  - `init` — interactive wizard that generates ado-sync.json
@@ -133,9 +133,10 @@ A `.env` file in the working directory is loaded automatically.
133
133
 
134
134
  ## MCP server
135
135
 
136
- `ado-sync-mcp` starts an MCP stdio server exposing 10 tools:
136
+ `ado-sync-mcp` starts an MCP stdio server exposing 13 tools:
137
137
  `validate_config`, `get_test_cases`, `get_test_case`, `push_specs`, `pull_specs`,
138
- `status`, `diff`, `generate_specs`, `get_work_items`, `publish_test_results`
138
+ `status`, `diff`, `generate_specs`, `get_work_items`, `publish_test_results`,
139
+ `create_issue`, `get_story_context`, `generate_manifest`
139
140
 
140
141
  Register in Claude Code (`~/.claude/claude_desktop_config.json`):
141
142
  ```json
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ado-sync",
3
- "version": "0.1.47",
3
+ "version": "0.1.48",
4
4
  "description": "Bidirectional sync between local test specs (Cucumber/Markdown) and Azure DevOps Test Cases",
5
5
  "bin": {
6
6
  "ado-sync": "./dist/cli.js",