@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.
- package/.github/workflows/test-action.yml +20 -0
- package/.github/workflows/verify.yml +43 -0
- package/README.md +265 -0
- package/action.yml +42 -0
- package/dist/ai/cache.js +42 -0
- package/dist/ai/prompt.js +483 -0
- package/dist/ai/repair.js +131 -0
- package/dist/auth.proto +54 -0
- package/dist/engine/mocks/network-shim.js +29 -0
- package/dist/engine/runner.js +15 -0
- package/dist/index.js +110198 -0
- package/dist/licenses.txt +4049 -0
- package/dist/pagent.exe +0 -0
- package/dist/parser/extracts.js +39 -0
- package/dist/proto/channelz.proto +564 -0
- package/dist/proto/protoc-gen-validate/LICENSE +202 -0
- package/dist/proto/protoc-gen-validate/validate/validate.proto +797 -0
- package/dist/proto/xds/LICENSE +201 -0
- package/dist/proto/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
- package/dist/proto/xds/xds/service/orca/v3/orca.proto +36 -0
- package/dist/protoc-gen-validate/LICENSE +202 -0
- package/dist/protoc-gen-validate/validate/validate.proto +797 -0
- package/dist/runners/base-runner.js +96 -0
- package/dist/runners/bash-runner.js +12 -0
- package/dist/runners/c-runner.js +12 -0
- package/dist/runners/cpp-runner.js +12 -0
- package/dist/runners/go-runner.js +12 -0
- package/dist/runners/index.js +96 -0
- package/dist/runners/java-runner.js +12 -0
- package/dist/runners/javascript-runner.js +16 -0
- package/dist/runners/lua-runner.js +12 -0
- package/dist/runners/perl-runner.js +12 -0
- package/dist/runners/php-runner.js +12 -0
- package/dist/runners/python-runner.js +12 -0
- package/dist/runners/ruby-runner.js +12 -0
- package/dist/runners/rust-runner.js +12 -0
- package/dist/runners/typescript-runner.js +16 -0
- package/dist/utils/badge.js +27 -0
- package/dist/utils/patcher.js +23 -0
- package/dist/xds/LICENSE +201 -0
- package/dist/xds/xds/data/orca/v3/orca_load_report.proto +58 -0
- package/dist/xds/xds/service/orca/v3/orca.proto +36 -0
- 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
|
+
[](https://www.npmjs.com/package/doc-verify)
|
|
6
|
+
[](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
|
package/dist/ai/cache.js
ADDED
|
@@ -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
|
+
}
|