ado-sync 0.1.30 → 0.1.32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -12,6 +12,15 @@ Supports a wide range of test file formats and frameworks:
12
12
  | `java` | JUnit 4, JUnit 5, TestNG + Selenium | `.java` |
13
13
  | `python` | pytest + Selenium | `.py` |
14
14
  | `javascript` | Jest, Jasmine, WebdriverIO | `.js` / `.ts` |
15
+ | `playwright` | Playwright Test | `.js` / `.ts` |
16
+ | `puppeteer` | Puppeteer + Jest or Mocha | `.js` / `.ts` |
17
+ | `cypress` | Cypress | `.cy.js` / `.cy.ts` |
18
+ | `testcafe` | TestCafe | `.js` / `.ts` |
19
+ | `detox` | Detox (React Native E2E) | `.js` / `.ts` |
20
+ | `espresso` | Android Espresso (JUnit 4 / Kotlin) | `.java` / `.kt` |
21
+ | `xcuitest` | iOS / macOS XCUITest | `.swift` |
22
+ | `flutter` | Flutter widget & integration tests | `_test.dart` |
23
+ | Appium | Use `javascript` / `java` / `python` / `csharp` | depends on language binding |
15
24
  | `csv` | Azure DevOps tabular export | `.csv` |
16
25
  | `excel` | Azure DevOps tabular export | `.xlsx` |
17
26
 
@@ -51,50 +60,73 @@ On the **first push**, a new Test Case is created in Azure DevOps and its ID is
51
60
  | Java JUnit 5 | `@Tag("tc:12345")` above `@Test` |
52
61
  | Python pytest | `@pytest.mark.tc(12345)` above `def test_*` |
53
62
  | JavaScript/TS (Jest/Jasmine/WebdriverIO) | `// @tc:12345` comment above `it()`/`test()` |
63
+ | Playwright | `annotation: { type: 'tc', description: '12345' }` in test options *(preferred)*; or `// @tc:12345` comment fallback |
64
+ | Puppeteer | `// @tc:12345` comment above `it()`/`test()` |
65
+ | Cypress | `// @tc:12345` comment above `it()`/`specify()` |
66
+ | TestCafe | `test.meta('tc', '12345')('title', fn)` *(preferred)*; or `// @tc:12345` comment fallback |
67
+ | Detox | `// @tc:12345` comment above `it()`/`test()` |
68
+ | Espresso (Java/Kotlin) | `// @tc:12345` comment above `@Test` |
69
+ | XCUITest (Swift) | `// @tc:12345` comment above `func test*()` |
70
+ | Flutter (Dart) | `// @tc:12345` comment above `testWidgets()`/`test()` |
54
71
  | CSV | Numeric ID in column A |
55
72
  | Excel | Numeric ID in cell A |
56
73
 
57
74
  ---
58
75
 
59
- ## Installation
76
+ ## Quick start
77
+
78
+ **Step 1 — Install**
60
79
 
61
80
  ```bash
62
81
  npm install -g ado-sync
63
- # or run without installing
82
+ # or run once without installing
64
83
  npx ado-sync --help
65
84
  ```
66
85
 
67
- ---
68
-
69
- ## Quick start
86
+ **Step 2 — Generate a config file**
70
87
 
71
88
  ```bash
72
- # 1. Generate a config file
73
89
  ado-sync init # creates ado-sync.json
74
- ado-sync init ado-sync.yml # YAML format
75
-
76
- # 2. Edit the config with your org, project, plan ID, and token
77
- export AZURE_DEVOPS_TOKEN=your_personal_access_token
78
-
79
- # 3. Preview what will be created
80
- ado-sync push --dry-run
81
-
82
- # 4. Push to Azure DevOps
83
- ado-sync push
90
+ ado-sync init ado-sync.yml # YAML format if you prefer
84
91
  ```
85
92
 
86
- Minimal config:
93
+ **Step 3 — Fill in your details**
94
+
95
+ Open `ado-sync.json` and replace the placeholders:
87
96
 
88
97
  ```json
89
98
  {
90
- "orgUrl": "https://dev.azure.com/my-org",
91
- "project": "MyProject",
99
+ "orgUrl": "https://dev.azure.com/YOUR-ORG",
100
+ "project": "YOUR-PROJECT-NAME",
92
101
  "auth": { "type": "pat", "token": "$AZURE_DEVOPS_TOKEN" },
93
- "testPlan": { "id": 1234 },
102
+ "testPlan": { "id": 12345 },
94
103
  "local": { "type": "gherkin", "include": "specs/**/*.feature" }
95
104
  }
96
105
  ```
97
106
 
107
+ | Field | Where to find it |
108
+ |-------|-----------------|
109
+ | `orgUrl` | Azure DevOps → top-left org name → `https://dev.azure.com/<org>` |
110
+ | `project` | Azure DevOps → your project name (shown in the breadcrumb) |
111
+ | `testPlan.id` | Test Plans → click your plan → the number in the URL |
112
+ | `AZURE_DEVOPS_TOKEN` | Azure DevOps → User Settings → Personal Access Tokens → New Token (scope: Test Management read/write) |
113
+
114
+ **Step 4 — Set your token**
115
+
116
+ ```bash
117
+ export AZURE_DEVOPS_TOKEN=your_personal_access_token
118
+ # or add it to a .env file in this directory
119
+ ```
120
+
121
+ **Step 5 — Preview then push**
122
+
123
+ ```bash
124
+ ado-sync push --dry-run # preview — no changes made
125
+ ado-sync push # create / update Test Cases in Azure DevOps
126
+ ```
127
+
128
+ On the first push, new Test Cases are created and their IDs are written back into your local files (`@tc:12345`). Every subsequent push updates them.
129
+
98
130
  ---
99
131
 
100
132
  ## CLI reference
@@ -130,6 +162,13 @@ ado-sync push
130
162
  ado-sync push --dry-run
131
163
  ado-sync push --tags "@smoke and not @wip"
132
164
  ado-sync push --config-override testPlan.id=9999
165
+
166
+ # AI-generated test steps for code files (Java, C#, Python, JS/TS, Playwright)
167
+ ado-sync push --ai-provider heuristic # fast regex-based (no model needed)
168
+ ado-sync push --ai-provider local --ai-model ~/.cache/models/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf
169
+ ado-sync push --ai-provider ollama --ai-model qwen2.5-coder:7b
170
+ ado-sync push --ai-provider openai --ai-key $OPENAI_API_KEY
171
+ ado-sync push --ai-provider none # disable AI summary entirely
133
172
  ```
134
173
 
135
174
  | Scenario state | Action |
@@ -152,10 +191,99 @@ ado-sync pull --tags "@smoke"
152
191
  ```bash
153
192
  ado-sync status
154
193
  ado-sync status --tags "@smoke"
194
+ ado-sync status --ai-provider heuristic
155
195
  ```
156
196
 
157
197
  Compares local specs against Azure DevOps and prints a diff — no changes made.
158
198
 
199
+ ### AI auto-summary
200
+
201
+ For code-based test types (`java`, `csharp`, `python`, `javascript`, `playwright`, `cypress`, `testcafe`, `detox`, `espresso`, `xcuitest`, `flutter`), ado-sync reads your test function bodies and automatically generates a TC **title**, **description**, and **steps** — so you don't need doc comments on every test.
202
+
203
+ > **No setup required to try it.** `ado-sync push` always works, even without a model — it falls back to fast regex-based analysis automatically.
204
+
205
+ #### Choose a provider
206
+
207
+ | Provider | Quality | Setup |
208
+ |---|---|---|
209
+ | `local` *(default)* | Good–Excellent | Download a GGUF model file (see below) |
210
+ | `heuristic` | Basic | None — works offline, zero dependencies |
211
+ | `ollama` | Good–Excellent | Install [Ollama](https://ollama.com) + `ollama pull qwen2.5-coder:7b` |
212
+ | `openai` | Excellent | `--ai-key $OPENAI_API_KEY` |
213
+ | `anthropic` | Excellent | `--ai-key $ANTHROPIC_API_KEY` |
214
+
215
+ #### Option A — No setup (heuristic, instant)
216
+
217
+ ```bash
218
+ ado-sync push --ai-provider heuristic
219
+ ```
220
+
221
+ Uses regex pattern matching. No model download, no internet required. Good for CI pipelines.
222
+
223
+ #### Option B — Local LLM (best privacy, no API cost)
224
+
225
+ `node-llama-cpp` is bundled — **no extra install needed**. You only need to download a model file once.
226
+
227
+ **1. Pick a model size**
228
+
229
+ | Model | RAM needed | Quality |
230
+ |-------|-----------|---------|
231
+ | 1.5B Q4_K_M *(start here)* | ~1.1 GB | Good |
232
+ | 7B Q4_K_M | ~4.5 GB | Better |
233
+ | 14B Q4_K_M | ~8.5 GB | Excellent |
234
+
235
+ **2. Download the model**
236
+
237
+ macOS / Linux:
238
+ ```bash
239
+ mkdir -p ~/.cache/ado-sync/models
240
+ curl -L -o ~/.cache/ado-sync/models/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf \
241
+ "https://huggingface.co/Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF/resolve/main/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf"
242
+ ```
243
+
244
+ Windows (PowerShell):
245
+ ```powershell
246
+ New-Item -ItemType Directory -Force "$env:LOCALAPPDATA\ado-sync\models"
247
+ Invoke-WebRequest `
248
+ -Uri "https://huggingface.co/Qwen/Qwen2.5-Coder-1.5B-Instruct-GGUF/resolve/main/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf" `
249
+ -OutFile "$env:LOCALAPPDATA\ado-sync\models\qwen2.5-coder-1.5b-instruct-q4_k_m.gguf"
250
+ ```
251
+
252
+ **3. Run push with the model**
253
+
254
+ ```bash
255
+ # macOS / Linux
256
+ ado-sync push --ai-model ~/.cache/ado-sync/models/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf
257
+
258
+ # Windows
259
+ ado-sync push --ai-model "$env:LOCALAPPDATA\ado-sync\models\qwen2.5-coder-1.5b-instruct-q4_k_m.gguf"
260
+ ```
261
+
262
+ #### Option C — Ollama (model management UI, easy upgrades)
263
+
264
+ ```bash
265
+ # 1. Install Ollama from https://ollama.com, then:
266
+ ollama pull qwen2.5-coder:7b
267
+
268
+ # 2. Push using Ollama
269
+ ado-sync push --ai-provider ollama --ai-model qwen2.5-coder:7b
270
+ ```
271
+
272
+ #### Option D — Cloud AI (OpenAI / Anthropic)
273
+
274
+ ```bash
275
+ ado-sync push --ai-provider openai --ai-key $OPENAI_API_KEY
276
+ ado-sync push --ai-provider anthropic --ai-key $ANTHROPIC_API_KEY
277
+ ```
278
+
279
+ #### Disable AI entirely
280
+
281
+ ```bash
282
+ ado-sync push --ai-provider none
283
+ ```
284
+
285
+ > Tests with existing doc comments (JSDoc / Javadoc / C# XML doc / Python docstring) that already have both steps and a description are **never overwritten**. Local source files are **never modified** by AI summary.
286
+
159
287
  ### `publish-test-results`
160
288
 
161
289
  ```bash
@@ -195,7 +323,8 @@ ado-sync push --config-override sync.disableLocalChanges=true
195
323
  | Topic | Link |
196
324
  |-------|------|
197
325
  | Full configuration reference | [docs/configuration.md](docs/configuration.md) |
198
- | Spec file formats (Gherkin, Markdown, C# MSTest, CSV, Excel) | [docs/spec-formats.md](docs/spec-formats.md) |
326
+ | Spec file formats (Gherkin, Markdown, C# MSTest, CSV, Excel, JS/TS) | [docs/spec-formats.md](docs/spec-formats.md) |
327
+ | Work Item Links (User Story, Bug, etc.) | [docs/spec-formats.md#work-item-links](docs/spec-formats.md#work-item-links) |
199
328
  | Advanced features (format, state, fieldUpdates, customizations, attachments, CI mode) | [docs/advanced.md](docs/advanced.md) |
200
329
  | Publishing test results | [docs/publish-test-results.md](docs/publish-test-results.md) |
201
330
 
@@ -325,6 +454,23 @@ pytest --junitxml=results/junit.xml
325
454
  ado-sync publish-test-results --testResult results/junit.xml --testResultFormat junit
326
455
  ```
327
456
 
457
+ By default, TC linking uses `AutomatedTestName` matching (requires `sync.markAutomated: true`).
458
+
459
+ **Optional — embed TC IDs into JUnit XML** for direct linking (more reliable, works even if the class/method is renamed):
460
+
461
+ Add this to `conftest.py`:
462
+
463
+ ```python
464
+ # conftest.py
465
+ def pytest_runtest_makereport(item, call):
466
+ """Write @pytest.mark.tc(N) as a JUnit XML property for ado-sync to pick up."""
467
+ for marker in item.iter_markers("tc"):
468
+ if marker.args:
469
+ item.user_properties.append(("tc", str(marker.args[0])))
470
+ ```
471
+
472
+ pytest will then write each TC ID into the JUnit XML as `<property name="tc" value="N"/>`, and ado-sync will link the result directly to that Test Case — no AutomatedTestName matching needed.
473
+
328
474
  Recommended `ado-sync.json` for Python:
329
475
 
330
476
  ```json
@@ -383,7 +529,7 @@ Recommended `ado-sync.json` for Playwright:
383
529
  "auth": { "type": "pat", "token": "$AZURE_DEVOPS_TOKEN" },
384
530
  "testPlan": { "id": 1234 },
385
531
  "local": {
386
- "type": "javascript",
532
+ "type": "playwright",
387
533
  "include": ["tests/**/*.spec.ts"],
388
534
  "exclude": ["**/*.helper.ts"]
389
535
  },
@@ -412,6 +558,138 @@ Recommended `ado-sync.json` for Jest/Jasmine/WebdriverIO:
412
558
  }
413
559
  ```
414
560
 
561
+ ### Detox (React Native): create TCs and push
562
+
563
+ ```bash
564
+ # 1. Create TCs and write IDs back into .ts files
565
+ ado-sync push --dry-run # preview
566
+ ado-sync push # writes // @tc:ID above each it() / test()
567
+
568
+ # 2. Run Detox tests (Jest runner)
569
+ npx detox test --configuration ios.sim.release
570
+
571
+ # 3. Publish results (Jest JUnit reporter)
572
+ ado-sync publish-test-results --testResult results/junit.xml --testResultFormat junit
573
+ ```
574
+
575
+ Recommended `ado-sync.json` for Detox:
576
+
577
+ ```json
578
+ {
579
+ "orgUrl": "https://dev.azure.com/my-org",
580
+ "project": "MyProject",
581
+ "auth": { "type": "pat", "token": "$AZURE_DEVOPS_TOKEN" },
582
+ "testPlan": { "id": 1234 },
583
+ "local": {
584
+ "type": "detox",
585
+ "include": ["e2e/**/*.test.ts"]
586
+ },
587
+ "sync": { "markAutomated": true }
588
+ }
589
+ ```
590
+
591
+ ### Espresso (Android): create TCs and push
592
+
593
+ ```bash
594
+ # 1. Create TCs and write IDs back into .java / .kt files
595
+ ado-sync push --dry-run # preview
596
+ ado-sync push # writes // @tc:ID above @Test
597
+
598
+ # 2. Run instrumented tests and generate JUnit XML
599
+ ./gradlew connectedAndroidTest
600
+ # XML output: app/build/outputs/androidTest-results/connected/TEST-*.xml
601
+
602
+ # 3. Publish results
603
+ ado-sync publish-test-results \
604
+ --testResult "app/build/outputs/androidTest-results/connected/TEST-*.xml" \
605
+ --testResultFormat junit
606
+ ```
607
+
608
+ Recommended `ado-sync.json` for Espresso:
609
+
610
+ ```json
611
+ {
612
+ "orgUrl": "https://dev.azure.com/my-org",
613
+ "project": "MyProject",
614
+ "auth": { "type": "pat", "token": "$AZURE_DEVOPS_TOKEN" },
615
+ "testPlan": { "id": 1234 },
616
+ "local": {
617
+ "type": "espresso",
618
+ "include": ["app/src/androidTest/**/*.java", "app/src/androidTest/**/*.kt"],
619
+ "exclude": ["**/*BaseTest.java"]
620
+ },
621
+ "sync": { "markAutomated": true }
622
+ }
623
+ ```
624
+
625
+ ### XCUITest (iOS): create TCs and push
626
+
627
+ ```bash
628
+ # 1. Create TCs and write IDs back into .swift files
629
+ ado-sync push --dry-run # preview
630
+ ado-sync push # writes // @tc:ID above func test*()
631
+
632
+ # 2. Run XCUITest and export JUnit XML
633
+ xcodebuild test \
634
+ -project MyApp.xcodeproj \
635
+ -scheme MyApp \
636
+ -destination 'platform=iOS Simulator,name=iPhone 15' \
637
+ -resultBundlePath TestResults.xcresult
638
+ xcrun xcresulttool get --path TestResults.xcresult --format junit > results/junit.xml
639
+
640
+ # 3. Publish results
641
+ ado-sync publish-test-results --testResult results/junit.xml --testResultFormat junit
642
+ ```
643
+
644
+ Recommended `ado-sync.json` for XCUITest:
645
+
646
+ ```json
647
+ {
648
+ "orgUrl": "https://dev.azure.com/my-org",
649
+ "project": "MyProject",
650
+ "auth": { "type": "pat", "token": "$AZURE_DEVOPS_TOKEN" },
651
+ "testPlan": { "id": 1234 },
652
+ "local": {
653
+ "type": "xcuitest",
654
+ "include": ["UITests/**/*.swift"],
655
+ "exclude": ["UITests/**/*Helper.swift", "UITests/**/*Base.swift"]
656
+ },
657
+ "sync": { "markAutomated": true }
658
+ }
659
+ ```
660
+
661
+ ### Flutter: create TCs and push
662
+
663
+ ```bash
664
+ # 1. Create TCs and write IDs back into _test.dart files
665
+ ado-sync push --dry-run # preview
666
+ ado-sync push # writes // @tc:ID above testWidgets() / test()
667
+
668
+ # 2. Run Flutter tests with machine-readable output
669
+ flutter test --machine > results/flutter_test.jsonl
670
+ # Or generate JUnit XML with the flutter_test_junit package:
671
+ flutter test --reporter junit > results/junit.xml
672
+
673
+ # 3. Publish results
674
+ ado-sync publish-test-results --testResult results/junit.xml --testResultFormat junit
675
+ ```
676
+
677
+ Recommended `ado-sync.json` for Flutter:
678
+
679
+ ```json
680
+ {
681
+ "orgUrl": "https://dev.azure.com/my-org",
682
+ "project": "MyProject",
683
+ "auth": { "type": "pat", "token": "$AZURE_DEVOPS_TOKEN" },
684
+ "testPlan": { "id": 1234 },
685
+ "local": {
686
+ "type": "flutter",
687
+ "include": ["test/**/*_test.dart", "integration_test/**/*_test.dart"]
688
+ },
689
+ "sync": { "markAutomated": true }
690
+ }
691
+ ```
692
+
415
693
  ### CI pipeline
416
694
 
417
695
  ```yaml
@@ -421,6 +699,11 @@ Recommended `ado-sync.json` for Jest/Jasmine/WebdriverIO:
421
699
  env:
422
700
  AZURE_DEVOPS_TOKEN: ${{ secrets.AZURE_DEVOPS_TOKEN }}
423
701
 
702
+ - name: Sync test cases to Azure DevOps (with AI summary)
703
+ run: ado-sync push --ai-provider heuristic --config-override sync.disableLocalChanges=true
704
+ env:
705
+ AZURE_DEVOPS_TOKEN: ${{ secrets.AZURE_DEVOPS_TOKEN }}
706
+
424
707
  - name: Publish test results
425
708
  run: ado-sync publish-test-results --testResult results/test.trx
426
709
  env:
@@ -435,6 +718,109 @@ ado-sync status
435
718
 
436
719
  ---
437
720
 
721
+ ## Work Item Links
722
+
723
+ Link each Test Case to related Azure DevOps work items (User Stories, Bugs, etc.) automatically on every push.
724
+
725
+ ### Configure `sync.links`
726
+
727
+ ```json
728
+ {
729
+ "sync": {
730
+ "links": [
731
+ {
732
+ "prefix": "story",
733
+ "relationship": "Microsoft.VSTS.Common.TestedBy-Reverse",
734
+ "workItemType": "User Story"
735
+ },
736
+ {
737
+ "prefix": "bug",
738
+ "relationship": "System.LinkTypes.Related",
739
+ "workItemType": "Bug"
740
+ }
741
+ ]
742
+ }
743
+ }
744
+ ```
745
+
746
+ | Field | Description |
747
+ |-------|-------------|
748
+ | `prefix` | The tag prefix used in your spec files (e.g. `story` → `@story:555`) |
749
+ | `relationship` | ADO relation type (see common values below) |
750
+ | `workItemType` | Optional — used in log output only |
751
+
752
+ **Common relationship values:**
753
+
754
+ | Relationship | Meaning |
755
+ |---|---|
756
+ | `Microsoft.VSTS.Common.TestedBy-Reverse` | Test Case "Tested By" ↔ User Story |
757
+ | `System.LinkTypes.Related` | Simple "Related" link |
758
+ | `System.LinkTypes.Dependency-Forward` | "Successor" (this item depends on) |
759
+ | `System.LinkTypes.Hierarchy-Reverse` | "Parent" link |
760
+
761
+ ### Tag your tests
762
+
763
+ **Gherkin (`.feature`):**
764
+ ```gherkin
765
+ # @story:555 @bug:789
766
+ Scenario: User can log in
767
+ Given I am on the login page
768
+ ```
769
+
770
+ **JavaScript / TypeScript (Jest, Playwright, Cypress, TestCafe, Puppeteer):**
771
+ ```typescript
772
+ // @story:555
773
+ // @bug:789
774
+ test('user can log in', async ({ page }) => { ... });
775
+ ```
776
+
777
+ **Markdown (`.md`):**
778
+ ```markdown
779
+ ### User can log in @story:555 @bug:789
780
+
781
+ 1. Navigate to the login page
782
+ 2. Check: Login form is visible
783
+ ```
784
+
785
+ **Python (pytest):**
786
+ ```python
787
+ # @story:555 @bug:789
788
+ def test_user_can_log_in():
789
+ ...
790
+ ```
791
+
792
+ **C# / Java / Espresso:** Add `// @story:555` in the comment block immediately above the `[TestMethod]` / `@Test` line.
793
+
794
+ **Swift (XCUITest):**
795
+ ```swift
796
+ // @story:555
797
+ // @bug:789
798
+ func testUserCanLogin() { ... }
799
+ ```
800
+
801
+ **Dart (Flutter):**
802
+ ```dart
803
+ // @story:555
804
+ // @bug:789
805
+ testWidgets('user can log in', (WidgetTester tester) async { ... });
806
+ ```
807
+
808
+ **Detox / React Native:**
809
+ ```typescript
810
+ // @story:555
811
+ // @bug:789
812
+ it('user can log in', async () => { ... });
813
+ ```
814
+
815
+ ### How it works
816
+
817
+ - On each `push`, ado-sync reads the `@story:N` / `@bug:N` tags from the spec file.
818
+ - **New links** found in the file are added to the Test Case in Azure DevOps.
819
+ - **Stale links** (present in Azure but no longer tagged locally) are removed automatically.
820
+ - The sync is non-destructive for links not covered by a configured prefix — only the prefixes listed in `sync.links` are managed.
821
+
822
+ ---
823
+
438
824
  ## Environment variables
439
825
 
440
826
  | Variable | Description |
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Auto-summary generator for test cases that have no doc comment.
3
+ *
4
+ * Providers:
5
+ *
6
+ * local — Node.js-native LLM via node-llama-cpp (bundled dependency).
7
+ * Runs GGUF models directly in-process; no external server.
8
+ * Requires a GGUF model file path supplied via `model`.
9
+ * Falls back to heuristic if no model path is provided.
10
+ * Recommended model: Qwen2.5-Coder-1.5B-Instruct-Q4_K_M.gguf
11
+ *
12
+ * heuristic — regex pattern matching against the test body; zero
13
+ * dependencies, works fully offline.
14
+ *
15
+ * ollama — local LLM via Ollama REST API (http://localhost:11434).
16
+ * Model suggestion: qwen2.5-coder:7b.
17
+ *
18
+ * openai — OpenAI Chat Completions API (requires API key).
19
+ *
20
+ * anthropic — Anthropic Messages API (requires API key).
21
+ *
22
+ * Usage (engine.ts / CLI):
23
+ * const { title, description, steps } = await summarizeTest(test, localType, {
24
+ * provider: 'local',
25
+ * model: '/path/to/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf',
26
+ * });
27
+ * test.title = title;
28
+ * test.description = description;
29
+ * test.steps = steps;
30
+ */
31
+ import { ParsedStep, ParsedTest } from '../types';
32
+ export type AiProvider = 'heuristic' | 'local' | 'ollama' | 'openai' | 'anthropic';
33
+ export interface AiSummaryOpts {
34
+ provider: AiProvider;
35
+ /**
36
+ * For `local`: absolute path to a GGUF model file, e.g.
37
+ * ~/.cache/ado-sync/models/qwen2.5-coder-1.5b-instruct-q4_k_m.gguf
38
+ * For `ollama`: model tag, e.g. qwen2.5-coder:7b
39
+ * For `openai`: model name, e.g. gpt-4o-mini
40
+ * For `anthropic`: model name, e.g. claude-haiku-4-5-20251001
41
+ */
42
+ model?: string;
43
+ /** Base URL for Ollama (default: http://localhost:11434) or OpenAI-compatible endpoint. */
44
+ baseUrl?: string;
45
+ /** API key for openai / anthropic — or $ENV_VAR reference. */
46
+ apiKey?: string;
47
+ /** Fall back to heuristic if the LLM call fails. Default: true. */
48
+ heuristicFallback?: boolean;
49
+ }
50
+ type LocalType = 'gherkin' | 'markdown' | 'csv' | 'excel' | 'csharp' | 'java' | 'python' | 'javascript' | 'playwright' | 'puppeteer' | 'cypress' | 'testcafe' | 'detox' | 'espresso' | 'xcuitest' | 'flutter';
51
+ /**
52
+ * Read the source file and return the raw text of the test function body,
53
+ * starting from the marker line (1-based).
54
+ *
55
+ * For Python: collects lines indented past the `def` line.
56
+ * For all others: collects until balanced braces close.
57
+ */
58
+ export declare function extractFunctionBody(filePath: string, markerLine: number, localType: LocalType): string;
59
+ export declare function heuristicSummary(body: string, fallbackTitle: string): {
60
+ title: string;
61
+ description: string;
62
+ steps: ParsedStep[];
63
+ };
64
+ /**
65
+ * Generate a title, description, and steps for a test that has no doc comment.
66
+ * Mutates nothing — returns new values; callers assign them.
67
+ */
68
+ export declare function summarizeTest(test: ParsedTest, localType: LocalType, opts: AiSummaryOpts): Promise<{
69
+ title: string;
70
+ description: string;
71
+ steps: ParsedStep[];
72
+ }>;
73
+ export {};