@shaik_munawar/doc-verify 1.0.2

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 (43) hide show
  1. package/.github/workflows/test-action.yml +20 -0
  2. package/.github/workflows/verify.yml +43 -0
  3. package/README.md +265 -0
  4. package/action.yml +42 -0
  5. package/dist/ai/cache.js +42 -0
  6. package/dist/ai/prompt.js +483 -0
  7. package/dist/ai/repair.js +131 -0
  8. package/dist/auth.proto +54 -0
  9. package/dist/engine/mocks/network-shim.js +29 -0
  10. package/dist/engine/runner.js +15 -0
  11. package/dist/index.js +110198 -0
  12. package/dist/licenses.txt +4049 -0
  13. package/dist/pagent.exe +0 -0
  14. package/dist/parser/extracts.js +39 -0
  15. package/dist/proto/channelz.proto +564 -0
  16. package/dist/proto/protoc-gen-validate/LICENSE +202 -0
  17. package/dist/proto/protoc-gen-validate/validate/validate.proto +797 -0
  18. package/dist/proto/xds/LICENSE +201 -0
  19. package/dist/proto/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
  20. package/dist/proto/xds/xds/service/orca/v3/orca.proto +36 -0
  21. package/dist/protoc-gen-validate/LICENSE +202 -0
  22. package/dist/protoc-gen-validate/validate/validate.proto +797 -0
  23. package/dist/runners/base-runner.js +96 -0
  24. package/dist/runners/bash-runner.js +12 -0
  25. package/dist/runners/c-runner.js +12 -0
  26. package/dist/runners/cpp-runner.js +12 -0
  27. package/dist/runners/go-runner.js +12 -0
  28. package/dist/runners/index.js +96 -0
  29. package/dist/runners/java-runner.js +12 -0
  30. package/dist/runners/javascript-runner.js +16 -0
  31. package/dist/runners/lua-runner.js +12 -0
  32. package/dist/runners/perl-runner.js +12 -0
  33. package/dist/runners/php-runner.js +12 -0
  34. package/dist/runners/python-runner.js +12 -0
  35. package/dist/runners/ruby-runner.js +12 -0
  36. package/dist/runners/rust-runner.js +12 -0
  37. package/dist/runners/typescript-runner.js +16 -0
  38. package/dist/utils/badge.js +27 -0
  39. package/dist/utils/patcher.js +23 -0
  40. package/dist/xds/LICENSE +201 -0
  41. package/dist/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
  42. package/dist/xds/xds/service/orca/v3/orca.proto +36 -0
  43. package/package.json +42 -0
@@ -0,0 +1,20 @@
1
+ name: Test DocVerify Action
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ verify-docs:
7
+ runs-on: ubuntu-latest
8
+ steps:
9
+ - name: Checkout Code
10
+ uses: actions/checkout@v3
11
+
12
+ # This step runs the action we just created
13
+ - name: Run DocVerify
14
+ uses: ./ # Uses the action from the current root directory
15
+ with:
16
+ file: 'Readme.md'
17
+ language: 'javascript'
18
+ openai_api_key: ${{ secrets.OPENAI_API_KEY }}
19
+ openai_api_base_url: ${{ secrets.OPENAI_API_BASE_URL }}
20
+ openai_model_name: ${{ secrets.OPENAI_MODEL_NAME }}
@@ -0,0 +1,43 @@
1
+ name: Verify Docs
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+
8
+ jobs:
9
+ doc-verify:
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: write # <--- CRITICAL: Allows the bot to push changes
13
+
14
+ steps:
15
+ - uses: actions/checkout@v4
16
+
17
+ # Run your tool (assuming you published it, or use local path)
18
+ - name: Run DocVerify
19
+ uses: ./ # or your-username/doc-verify@v1
20
+ with:
21
+ file: 'README.md'
22
+ language: 'javascript'
23
+ openai_api_key: ${{ secrets.OPENAI_API_KEY }}
24
+ openai_api_base_url: ${{ secrets.OPENAI_BASE_URL }}
25
+ openai_model_name: ${{ secrets.OPENAI_MODEL_NAME }}
26
+ # You might need to add a 'badge: true' input to your action.yml
27
+
28
+ # COMMIT THE CHANGE BACK
29
+ - name: Commit Badge Update
30
+ # Only run if the previous step succeeded and modified the file
31
+ if: success()
32
+ run: |
33
+ git config --global user.name 'DocVerify Bot'
34
+ git config --global user.email 'bot@docverify.com'
35
+
36
+ # Check if README was actually modified
37
+ if [[ `git status --porcelain README.md` ]]; then
38
+ git add README.md
39
+ git commit -m "docs: update verification badge [skip ci]"
40
+ git push
41
+ else
42
+ echo "No changes to badge."
43
+ fi
package/README.md ADDED
@@ -0,0 +1,265 @@
1
+ # doc-verify
2
+
3
+ A CLI tool that extracts code snippets from markdown documentation and executes them in sandboxed Docker containers to verify they actually work.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/doc-verify.svg)](https://www.npmjs.com/package/doc-verify)
6
+ [![License: ISC](https://img.shields.io/badge/License-ISC-blue.svg)](https://opensource.org/licenses/ISC)
7
+
8
+ ## Why?
9
+
10
+ Documentation code examples often become outdated or contain bugs that slip through review. **doc-verify** ensures your code examples actually run by:
11
+
12
+ 1. **Extracting** code blocks from markdown files
13
+ 2. **Repairing** incomplete snippets using AI (mocks missing dependencies, completes partial code)
14
+ 3. **Executing** each snippet in an isolated Docker container
15
+ 4. **Reporting** pass/fail results with interactive debugging options
16
+
17
+ ## Features
18
+
19
+ - 🐳 **Sandboxed Execution** - Each snippet runs in an isolated Docker container with no network access
20
+ - 🤖 **AI-Powered Repair** - Automatically completes incomplete code and mocks missing dependencies
21
+ - 🌍 **13+ Languages** - JavaScript, TypeScript, Python, Go, Rust, Ruby, Java, C, C++, Bash, PHP, Perl, Lua
22
+ - 🔄 **Interactive Mode** - Retry, skip, auto-fix, or debug failed snippets
23
+ - ⚡ **Parallel Processing** - Repairs snippets concurrently for faster execution
24
+ - 📦 **Caching** - Caches AI repairs to avoid redundant API calls
25
+ - 🔧 **Auto-fix** - Apply AI-generated fixes directly to your markdown files
26
+ - 🏷️ **Badge Updates** - Automatically updates verification badges in your docs
27
+
28
+ ## Installation
29
+
30
+ ```bash
31
+ # Install globally
32
+ npm install -g doc-verify
33
+
34
+ # Or use with npx
35
+ npx doc-verify run README.md
36
+ ```
37
+
38
+ ### Prerequisites
39
+
40
+ - **Node.js** 18+
41
+ - **Docker** running locally
42
+ - **OpenAI-compatible API** (OpenAI, Ollama, etc.)
43
+
44
+ ## Quick Start
45
+
46
+ 1. Set up environment variables:
47
+
48
+ ```bash
49
+ # .env
50
+ OPENAI_API_KEY=your-api-key
51
+ OPENAI_BASE_URL=https://api.openai.com # or your Ollama endpoint
52
+ OPENAI_MODEL_NAME=gpt-4o-mini # or llama3:latest for Ollama
53
+ ```
54
+
55
+ 2. Run verification:
56
+
57
+ ```bash
58
+ dv run README.md
59
+ ```
60
+
61
+ ## Usage
62
+
63
+ ### Basic Commands
64
+
65
+ ```bash
66
+ # Verify all code snippets in a markdown file
67
+ dv run README.md
68
+
69
+ # Filter by language
70
+ dv run README.md --lang python
71
+
72
+ # Clear the AI repair cache
73
+ dv clear
74
+ ```
75
+
76
+ ### Interactive Mode
77
+
78
+ When a snippet fails, you get interactive options:
79
+
80
+ ```
81
+ 2. python FAIL
82
+ Exited with code 1
83
+ ? Action
84
+ › Auto-fix # Generate and apply AI fix to source file
85
+ Details # View original code, repaired code, and error
86
+ Retry # Re-run after clearing cache for this snippet
87
+ Clear cache # Clear entire cache and restart
88
+ Skip # Skip this snippet
89
+ Exit # Exit immediately
90
+ ```
91
+
92
+ ### CLI Options
93
+
94
+ ```
95
+ Usage: doc-verify [command] [options]
96
+
97
+ Commands:
98
+ run <file> Verify code snippets in a markdown file
99
+ clear Clear the AI repair cache
100
+
101
+ Options:
102
+ -l, --lang <language> Filter snippets by language
103
+ -V, --version Output version number
104
+ -h, --help Display help
105
+ ```
106
+
107
+ ## Supported Languages
108
+
109
+ | Language | Aliases | Docker Image |
110
+ |----------|---------|--------------|
111
+ | JavaScript | `js`, `javascript` | `node:18-alpine` |
112
+ | TypeScript | `ts`, `typescript` | `denoland/deno:latest` |
113
+ | Python | `py`, `python` | `python:3.11-alpine` |
114
+ | Go | `go`, `golang` | `golang:1.21-alpine` |
115
+ | Rust | `rs`, `rust` | `rust:1.74-alpine` |
116
+ | Ruby | `rb`, `ruby` | `ruby:3.2-alpine` |
117
+ | Java | `java` | `eclipse-temurin:17-alpine` |
118
+ | C | `c` | `gcc:13` |
119
+ | C++ | `cpp`, `c++` | `gcc:13` |
120
+ | Bash | `bash`, `sh`, `shell` | `alpine:latest` |
121
+ | PHP | `php` | `php:8.2-cli-alpine` |
122
+ | Perl | `perl` | `perl:5.38-slim` |
123
+ | Lua | `lua` | `nickblah/lua:5.4-alpine` |
124
+
125
+ ## GitHub Action
126
+
127
+ Use doc-verify in your CI/CD pipeline:
128
+
129
+ ```yaml
130
+ name: Verify Docs
131
+
132
+ on:
133
+ push:
134
+ paths:
135
+ - '**.md'
136
+ pull_request:
137
+ paths:
138
+ - '**.md'
139
+
140
+ jobs:
141
+ verify:
142
+ runs-on: ubuntu-latest
143
+ steps:
144
+ - uses: actions/checkout@v4
145
+
146
+ - name: Verify Documentation
147
+ uses: shaik-abdul-munawar/doc-verify@v1
148
+ with:
149
+ file: README.md
150
+ openai_api_key: ${{ secrets.OPENAI_API_KEY }}
151
+ openai_api_base_url: ${{ secrets.OPENAI_BASE_URL }}
152
+ openai_model_name: gpt-4o-mini
153
+ ```
154
+
155
+ ### Action Inputs
156
+
157
+ | Input | Required | Default | Description |
158
+ |-------|----------|---------|-------------|
159
+ | `file` | No | `README.md` | Markdown file to verify |
160
+ | `language` | No | - | Filter by language |
161
+ | `openai_api_key` | Yes | - | API key for AI repairs |
162
+ | `openai_api_base_url` | Yes | - | Base URL for OpenAI-compatible API |
163
+ | `openai_model_name` | Yes | - | Model name to use |
164
+
165
+ ## How It Works
166
+
167
+ ### 1. Extraction
168
+
169
+ Parses markdown files using `remark` and extracts all fenced code blocks with language identifiers.
170
+
171
+ ### 2. AI Repair
172
+
173
+ Documentation snippets are often incomplete (missing imports, undefined variables). The AI:
174
+ - Adds missing imports and dependencies
175
+ - Mocks external services (APIs, databases, etc.)
176
+ - Wraps code in async contexts if needed
177
+ - **Does NOT fix intentional bugs** - preserves the original logic
178
+
179
+ ### 3. Sandboxed Execution
180
+
181
+ Each snippet runs in a Docker container with:
182
+ - **No network access** (`NetworkMode: 'none'`)
183
+ - **Memory limit** (128MB)
184
+ - **Auto-cleanup** (containers removed after execution)
185
+ - **Timeout protection**
186
+
187
+ ### 4. Network Mocking (JS/TS)
188
+
189
+ For JavaScript/TypeScript, a network shim is injected that mocks:
190
+ - `fetch()` API calls
191
+ - Common HTTP libraries
192
+
193
+ This allows API examples to "work" without making real network requests.
194
+
195
+ ## Configuration
196
+
197
+ ### Environment Variables
198
+
199
+ | Variable | Description |
200
+ |----------|-------------|
201
+ | `OPENAI_API_KEY` | API key for the LLM provider |
202
+ | `OPENAI_BASE_URL` | Base URL (e.g., `https://api.openai.com` or Ollama endpoint) |
203
+ | `OPENAI_MODEL_NAME` | Model to use (e.g., `gpt-4o-mini`, `llama3:latest`) |
204
+
205
+ ### Using with Ollama
206
+
207
+ ```bash
208
+ # Start Ollama
209
+ ollama serve
210
+
211
+ # Set environment
212
+ OPENAI_API_KEY=ollama
213
+ OPENAI_BASE_URL=http://localhost:11434
214
+ OPENAI_MODEL_NAME=llama3:latest
215
+ ```
216
+
217
+ ## Architecture
218
+
219
+ ```
220
+ src/
221
+ ├── index.ts # CLI entry point
222
+ ├── parser/
223
+ │ └── extracts.ts # Markdown parsing & snippet extraction
224
+ ├── engine/
225
+ │ ├── runner.ts # Execution orchestration
226
+ │ └── mocks/
227
+ │ └── network-shim.ts # Network mocking for JS/TS
228
+ ├── runners/
229
+ │ ├── base-runner.ts # Abstract base class with Docker logic
230
+ │ ├── javascript-runner.ts
231
+ │ ├── typescript-runner.ts
232
+ │ ├── python-runner.ts
233
+ │ └── ... # Language-specific runners
234
+ ├── ai/
235
+ │ ├── repair.ts # AI-powered code completion
236
+ │ ├── prompt.ts # Language-specific prompts
237
+ │ └── cache.ts # SHA256-based caching
238
+ └── utils/
239
+ ├── badge.ts # Badge update utility
240
+ └── patcher.ts # File patching for auto-fix
241
+ ```
242
+
243
+ ## Development
244
+
245
+ ```bash
246
+ # Clone the repo
247
+ git clone https://github.com/shaik-abdul-munawar/doc-verify.git
248
+ cd doc-verify
249
+
250
+ # Install dependencies
251
+ pnpm install
252
+
253
+ # Run in development mode
254
+ pnpm run dev run README.md
255
+
256
+ # Build
257
+ pnpm run build
258
+
259
+ # Bundle for distribution
260
+ pnpm run bundle
261
+ ```
262
+
263
+ ## License
264
+
265
+ ISC © Shaik Abdul Munawar
package/action.yml ADDED
@@ -0,0 +1,42 @@
1
+ name: 'DocVerify'
2
+ description: 'Verifies documentation code snippets by running them in sandboxed containers.'
3
+ author: 'Shaik Abdul Munawar'
4
+ inputs:
5
+ file:
6
+ description: 'The markdown file to verify'
7
+ required: true
8
+ default: 'README.md'
9
+ language:
10
+ description: 'The language to filter (e.g., javascript)'
11
+ required: false
12
+ openai_api_key:
13
+ description: 'API Key for AI repairs'
14
+ required: true
15
+ openai_api_base_url:
16
+ description: 'Base URL for the OpenAI-compatible API endpoint'
17
+ required: true
18
+ openai_model_name:
19
+ description: 'Model name for the OpenAI-compatible API endpoint'
20
+ required: true
21
+
22
+ runs:
23
+ using: "composite"
24
+ steps:
25
+ - name: Setup Node.js
26
+ uses: actions/setup-node@v4
27
+ with:
28
+ node-version: 20
29
+
30
+ - name: Run DocVerify
31
+ shell: bash
32
+ env:
33
+ OPENAI_API_KEY: ${{ inputs.openai_api_key }}
34
+ OPENAI_BASE_URL: ${{ inputs.openai_api_base_url }}
35
+ OPENAI_MODEL_NAME: ${{ inputs.openai_model_name }}
36
+ run: |
37
+ cd ${{ github.action_path }}
38
+ if [ -n "${{ inputs.language }}" ]; then
39
+ node ./dist/index.js run ${{ inputs.file }} --lang ${{ inputs.language }}
40
+ else
41
+ node ./dist/index.js run ${{ inputs.file }}
42
+ fi
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getCachedRepair = getCachedRepair;
7
+ exports.saveCachedRepair = saveCachedRepair;
8
+ exports.clearCache = clearCache;
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const crypto_1 = __importDefault(require("crypto"));
11
+ const CACHE_FILE = '.docverify-cache.json';
12
+ function getCachedRepair(code) {
13
+ if (!fs_1.default.existsSync(CACHE_FILE))
14
+ return null;
15
+ const cache = JSON.parse(fs_1.default.readFileSync(CACHE_FILE, 'utf-8'));
16
+ const hash = crypto_1.default.createHash('sha256').update(code).digest('hex');
17
+ return cache[hash] || null;
18
+ }
19
+ function saveCachedRepair(code, repaired) {
20
+ const hash = crypto_1.default.createHash('sha256').update(code).digest('hex');
21
+ let cache = {};
22
+ if (fs_1.default.existsSync(CACHE_FILE)) {
23
+ cache = JSON.parse(fs_1.default.readFileSync(CACHE_FILE, 'utf-8'));
24
+ }
25
+ cache[hash] = repaired;
26
+ fs_1.default.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), { flag: 'w' });
27
+ }
28
+ function clearCache(code) {
29
+ if (!fs_1.default.existsSync(CACHE_FILE))
30
+ return;
31
+ if (code) {
32
+ const hash = crypto_1.default.createHash('sha256').update(code).digest('hex');
33
+ let cache = JSON.parse(fs_1.default.readFileSync(CACHE_FILE, 'utf-8'));
34
+ if (cache[hash]) {
35
+ delete cache[hash];
36
+ fs_1.default.writeFileSync(CACHE_FILE, JSON.stringify(cache, null, 2), { flag: 'w' });
37
+ }
38
+ }
39
+ else {
40
+ fs_1.default.unlinkSync(CACHE_FILE);
41
+ }
42
+ }