docworks 0.11.0-next.1
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 +200 -0
- package/dist/commands/check.d.ts +7 -0
- package/dist/commands/check.d.ts.map +1 -0
- package/dist/commands/check.js +61 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/init.d.ts +5 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +165 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/test.d.ts +5 -0
- package/dist/commands/test.d.ts.map +1 -0
- package/dist/commands/test.js +45 -0
- package/dist/commands/test.js.map +1 -0
- package/dist/core/ai.d.ts +2 -0
- package/dist/core/ai.d.ts.map +1 -0
- package/dist/core/ai.js +29 -0
- package/dist/core/ai.js.map +1 -0
- package/dist/core/cache.d.ts +3 -0
- package/dist/core/cache.d.ts.map +1 -0
- package/dist/core/cache.js +31 -0
- package/dist/core/cache.js.map +1 -0
- package/dist/core/validator.d.ts +4 -0
- package/dist/core/validator.d.ts.map +1 -0
- package/dist/core/validator.js +47 -0
- package/dist/core/validator.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +32 -0
- package/dist/index.js.map +1 -0
- package/dist/providers/anthropic.d.ts +10 -0
- package/dist/providers/anthropic.d.ts.map +1 -0
- package/dist/providers/anthropic.js +51 -0
- package/dist/providers/anthropic.js.map +1 -0
- package/dist/providers/base.d.ts +12 -0
- package/dist/providers/base.d.ts.map +1 -0
- package/dist/providers/base.js +14 -0
- package/dist/providers/base.js.map +1 -0
- package/dist/providers/openai.d.ts +10 -0
- package/dist/providers/openai.d.ts.map +1 -0
- package/dist/providers/openai.js +42 -0
- package/dist/providers/openai.js.map +1 -0
- package/dist/sources/base.d.ts +3 -0
- package/dist/sources/base.d.ts.map +1 -0
- package/dist/sources/base.js +17 -0
- package/dist/sources/base.js.map +1 -0
- package/dist/sources/llms-txt.d.ts +7 -0
- package/dist/sources/llms-txt.d.ts.map +1 -0
- package/dist/sources/llms-txt.js +43 -0
- package/dist/sources/llms-txt.js.map +1 -0
- package/dist/sources/mcp.d.ts +9 -0
- package/dist/sources/mcp.d.ts.map +1 -0
- package/dist/sources/mcp.js +33 -0
- package/dist/sources/mcp.js.map +1 -0
- package/dist/types/config.d.ts +26 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +2 -0
- package/dist/types/config.js.map +1 -0
- package/dist/utils/config.d.ts +3 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +18 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/reporter.d.ts +4 -0
- package/dist/utils/reporter.d.ts.map +1 -0
- package/dist/utils/reporter.js +111 -0
- package/dist/utils/reporter.js.map +1 -0
- package/package.json +84 -0
- package/templates/api.yml +21 -0
- package/templates/default.yml +19 -0
- package/templates/gitbook.yml +13 -0
- package/templates/library.yml +21 -0
- package/templates/mintlify.yml +18 -0
- package/templates/readme.yml +13 -0
package/README.md
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
<img width="250" height="70" alt="logo-light" src="https://github.com/user-attachments/assets/ab45ecc7-adad-42e2-84bd-a87145fbc01b" />
|
|
2
|
+
<br/><br/>
|
|
3
|
+
|
|
4
|
+
Ensure your docs answer critical questions. AI-powered validation that checks if developers can actually find what they need.
|
|
5
|
+
|
|
6
|
+
## The Problem
|
|
7
|
+
|
|
8
|
+
Your docs mention "authentication" 50 times, but developers still can't figure out HOW to authenticate. Keywords exist, but answers are fragmented across pages. Support tickets spike.
|
|
9
|
+
|
|
10
|
+
## How It Works
|
|
11
|
+
|
|
12
|
+
Define what questions your docs must answer. DocWorks uses AI to verify they remain answerable after every change.
|
|
13
|
+
|
|
14
|
+
```yaml
|
|
15
|
+
# docworks.yml
|
|
16
|
+
questions:
|
|
17
|
+
critical:
|
|
18
|
+
- How do I authenticate?
|
|
19
|
+
- What are the rate limits?
|
|
20
|
+
- How do I handle errors?
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Install
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
npm install -g docworks
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## Quick Start
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 1. Initialize with smart defaults
|
|
33
|
+
docworks init
|
|
34
|
+
|
|
35
|
+
# 2. Check your docs (with your OpenAI key)
|
|
36
|
+
OPENAI_API_KEY=sk-... docworks check
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Output:
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
✅ How do I authenticate?
|
|
43
|
+
✅ What are the rate limits?
|
|
44
|
+
❌ How do I handle errors?
|
|
45
|
+
|
|
46
|
+
Documentation check failed:
|
|
47
|
+
Critical questions cannot be answered from current docs
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## CI/CD Integration
|
|
51
|
+
|
|
52
|
+
```yaml
|
|
53
|
+
# .github/workflows/docs.yml
|
|
54
|
+
name: Documentation Check
|
|
55
|
+
on: [pull_request]
|
|
56
|
+
|
|
57
|
+
jobs:
|
|
58
|
+
check:
|
|
59
|
+
runs-on: ubuntu-latest
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v3
|
|
62
|
+
- run: npx docworks check
|
|
63
|
+
env:
|
|
64
|
+
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Configuration
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
# docworks.yml
|
|
71
|
+
questions:
|
|
72
|
+
critical: # These block PRs if unanswerable
|
|
73
|
+
- How do I install this?
|
|
74
|
+
- How do I authenticate?
|
|
75
|
+
|
|
76
|
+
important: # These warn but don't block
|
|
77
|
+
- How do I debug issues?
|
|
78
|
+
- What are the rate limits?
|
|
79
|
+
|
|
80
|
+
nice_to_have: # Informational only
|
|
81
|
+
- Are there TypeScript types?
|
|
82
|
+
|
|
83
|
+
# Optional: Use your preferred AI provider
|
|
84
|
+
provider: openai # or anthropic, azure
|
|
85
|
+
model: gpt-4o-mini
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Templates
|
|
89
|
+
|
|
90
|
+
Start quickly with pre-built templates:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# API documentation
|
|
94
|
+
docworks init --template api
|
|
95
|
+
|
|
96
|
+
# NPM package
|
|
97
|
+
docworks init --template library
|
|
98
|
+
|
|
99
|
+
# Internal platform
|
|
100
|
+
docworks init --template internal
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Why DocWorks?
|
|
104
|
+
|
|
105
|
+
- **Explicit control** - You define what matters, not magic patterns
|
|
106
|
+
- **AI-powered** - Understands context, not just keywords
|
|
107
|
+
- **Progressive adoption** - Start advisory, enable blocking when ready
|
|
108
|
+
- **Provider flexible** - OpenAI, Anthropic, Azure (BYO keys)
|
|
109
|
+
- **Fast** - Cached responses, parallel validation
|
|
110
|
+
|
|
111
|
+
## Examples
|
|
112
|
+
|
|
113
|
+
### API Documentation
|
|
114
|
+
|
|
115
|
+
```yaml
|
|
116
|
+
questions:
|
|
117
|
+
critical:
|
|
118
|
+
- How do I authenticate with the API?
|
|
119
|
+
- What are the API endpoints?
|
|
120
|
+
- How do I handle errors?
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Library/Package
|
|
124
|
+
|
|
125
|
+
```yaml
|
|
126
|
+
questions:
|
|
127
|
+
critical:
|
|
128
|
+
- How do I install this package?
|
|
129
|
+
- How do I import and use it?
|
|
130
|
+
- What's a basic example?
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Internal Docs
|
|
134
|
+
|
|
135
|
+
```yaml
|
|
136
|
+
questions:
|
|
137
|
+
critical:
|
|
138
|
+
- How do I get access?
|
|
139
|
+
- Who do I contact for help?
|
|
140
|
+
- Where are the runbooks?
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## How It Really Works
|
|
144
|
+
|
|
145
|
+
1. **You define questions** your docs must answer
|
|
146
|
+
2. **DocWorks reads** all your documentation
|
|
147
|
+
3. **AI validates** each question is answerable
|
|
148
|
+
4. **CI/CD enforces** on every PR
|
|
149
|
+
|
|
150
|
+
No keyword matching. No regex patterns. Just: "Can a developer find this answer?"
|
|
151
|
+
|
|
152
|
+
## Requirements
|
|
153
|
+
|
|
154
|
+
- Node.js 16+
|
|
155
|
+
- OpenAI API key (or Anthropic, Azure)
|
|
156
|
+
- Documentation in Markdown
|
|
157
|
+
|
|
158
|
+
## Pricing
|
|
159
|
+
|
|
160
|
+
- **DocWorks**: Free, open source, MIT licensed
|
|
161
|
+
- **AI costs**: ~$0.01 per check with caching (you pay provider directly)
|
|
162
|
+
|
|
163
|
+
## Development
|
|
164
|
+
|
|
165
|
+
```bash
|
|
166
|
+
# Clone and install
|
|
167
|
+
git clone https://github.com/caiopizzol/docworks
|
|
168
|
+
cd docworks
|
|
169
|
+
npm install
|
|
170
|
+
|
|
171
|
+
# Run locally
|
|
172
|
+
npm run dev
|
|
173
|
+
|
|
174
|
+
# Run tests
|
|
175
|
+
npm test
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
## FAQ
|
|
179
|
+
|
|
180
|
+
**Q: Will this block my PRs?**
|
|
181
|
+
A: Not by default. Starts in advisory mode. Enable blocking when ready.
|
|
182
|
+
|
|
183
|
+
**Q: What if the AI is wrong?**
|
|
184
|
+
A: Adjust confidence thresholds, use advisory mode, or override specific questions.
|
|
185
|
+
|
|
186
|
+
**Q: Can I use this with private docs?**
|
|
187
|
+
A: Yes. Runs in your CI with your API keys. Docs never leave your infrastructure.
|
|
188
|
+
|
|
189
|
+
**Q: Does it support other languages?**
|
|
190
|
+
A: Currently Markdown/MDX. More formats coming soon.
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT
|
|
195
|
+
|
|
196
|
+
## Links
|
|
197
|
+
|
|
198
|
+
- [Documentation](https://docworks.dev)
|
|
199
|
+
- [GitHub](https://github.com/caiopizzol/docworks)
|
|
200
|
+
- [NPM](https://npmjs.com/package/docworks)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"AAMA,wBAAsB,KAAK,CAAC,OAAO,EAAE;IACnC,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,MAAM,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAA;CACxC,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EhB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { loadConfig } from '../utils/config.js';
|
|
2
|
+
import { createSource } from '../sources/base.js';
|
|
3
|
+
import { validateJourneys, validateQuestions } from '../core/validator.js';
|
|
4
|
+
import { formatReport, formatJSON } from '../utils/reporter.js';
|
|
5
|
+
export async function check(options) {
|
|
6
|
+
try {
|
|
7
|
+
// Load config
|
|
8
|
+
const config = await loadConfig(options.config || 'docworks.yml');
|
|
9
|
+
// Validate API key
|
|
10
|
+
const apiKey = process.env.OPENAI_API_KEY ||
|
|
11
|
+
process.env.ANTHROPIC_API_KEY ||
|
|
12
|
+
config.api_key;
|
|
13
|
+
if (!apiKey) {
|
|
14
|
+
console.error('❌ No API key found\n');
|
|
15
|
+
console.error('Set one of:');
|
|
16
|
+
console.error(' export OPENAI_API_KEY=sk-...');
|
|
17
|
+
console.error(' export ANTHROPIC_API_KEY=sk-ant-...');
|
|
18
|
+
process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
// Load documentation
|
|
21
|
+
console.log('📚 Loading documentation...');
|
|
22
|
+
const source = await createSource(config);
|
|
23
|
+
console.log(`Source: ${source.name}\n`);
|
|
24
|
+
const docs = await source.fetch();
|
|
25
|
+
// Validate journeys
|
|
26
|
+
console.log('🔍 Validating journeys...\n');
|
|
27
|
+
let results;
|
|
28
|
+
if (options.journey) {
|
|
29
|
+
// Validate single journey
|
|
30
|
+
const questions = config.journeys[options.journey];
|
|
31
|
+
if (!questions) {
|
|
32
|
+
console.error(`Journey "${options.journey}" not found`);
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
console.log(`Journey: ${options.journey}`);
|
|
36
|
+
console.log('─'.repeat(40));
|
|
37
|
+
results = {
|
|
38
|
+
[options.journey]: await validateQuestions(questions, docs, apiKey, options.cache !== false),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
// Validate all journeys
|
|
43
|
+
results = await validateJourneys(config.journeys, docs, apiKey, options.cache !== false);
|
|
44
|
+
}
|
|
45
|
+
// Format output
|
|
46
|
+
if (options.format === 'json') {
|
|
47
|
+
console.log(formatJSON(results, source.name));
|
|
48
|
+
const hasFailures = Object.values(results).some((questions) => questions.some((q) => q.answerable === 'NO'));
|
|
49
|
+
process.exit(hasFailures ? 1 : 0);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const exitCode = formatReport(results, options.format === 'github');
|
|
53
|
+
process.exit(exitCode);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error('❌ Error:', error.message);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.js","sourceRoot":"","sources":["../../src/commands/check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAkHA,wBAAsB,IAAI,CAAC,OAAO,EAAE;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,GAAG,OAAO,CAAC,IAAI,CAAC,CAqChB"}
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import { glob } from 'glob';
|
|
3
|
+
const TEMPLATES = {
|
|
4
|
+
default: `# DocWorks Configuration
|
|
5
|
+
source: ./llms.txt
|
|
6
|
+
|
|
7
|
+
journeys:
|
|
8
|
+
getting_started:
|
|
9
|
+
- How do I install this?
|
|
10
|
+
- How do I get started?
|
|
11
|
+
- Where are examples?
|
|
12
|
+
|
|
13
|
+
development:
|
|
14
|
+
- How do I run tests?
|
|
15
|
+
- How do I debug issues?
|
|
16
|
+
- Where can I get help?
|
|
17
|
+
|
|
18
|
+
provider: openai
|
|
19
|
+
model: gpt-4o-mini`,
|
|
20
|
+
api: `# DocWorks Configuration - API Documentation
|
|
21
|
+
source: ./llms.txt
|
|
22
|
+
|
|
23
|
+
journeys:
|
|
24
|
+
authentication:
|
|
25
|
+
- How do I authenticate?
|
|
26
|
+
- Where do I get API keys?
|
|
27
|
+
- What auth methods are supported?
|
|
28
|
+
|
|
29
|
+
integration:
|
|
30
|
+
- What are the endpoints?
|
|
31
|
+
- How do I handle errors?
|
|
32
|
+
- What are the rate limits?
|
|
33
|
+
|
|
34
|
+
production:
|
|
35
|
+
- How do I monitor usage?
|
|
36
|
+
- Where are status pages?
|
|
37
|
+
- How do I get support?
|
|
38
|
+
|
|
39
|
+
provider: openai
|
|
40
|
+
model: gpt-4o-mini`,
|
|
41
|
+
library: `# DocWorks Configuration - Library/Package
|
|
42
|
+
source: ./llms.txt
|
|
43
|
+
|
|
44
|
+
journeys:
|
|
45
|
+
setup:
|
|
46
|
+
- How do I install this package?
|
|
47
|
+
- How do I import it?
|
|
48
|
+
- What are the requirements?
|
|
49
|
+
|
|
50
|
+
basic_usage:
|
|
51
|
+
- What's a hello world example?
|
|
52
|
+
- What are the main functions?
|
|
53
|
+
- How do I configure options?
|
|
54
|
+
|
|
55
|
+
typescript:
|
|
56
|
+
- Does it have TypeScript support?
|
|
57
|
+
- Where are the type definitions?
|
|
58
|
+
- How do I use with TypeScript?
|
|
59
|
+
|
|
60
|
+
provider: openai
|
|
61
|
+
model: gpt-4o-mini`,
|
|
62
|
+
mintlify: `# DocWorks Configuration - Mintlify
|
|
63
|
+
source:
|
|
64
|
+
type: mcp
|
|
65
|
+
server: "@mintlify/mcp-server"
|
|
66
|
+
|
|
67
|
+
journeys:
|
|
68
|
+
api_reference:
|
|
69
|
+
- Where is the API reference?
|
|
70
|
+
- Are all endpoints documented?
|
|
71
|
+
- Do examples work?
|
|
72
|
+
|
|
73
|
+
getting_started:
|
|
74
|
+
- Is there a quickstart guide?
|
|
75
|
+
- How do I authenticate?
|
|
76
|
+
- What SDKs are available?
|
|
77
|
+
|
|
78
|
+
provider: openai
|
|
79
|
+
model: gpt-4o-mini`,
|
|
80
|
+
readme: `# DocWorks Configuration - ReadMe
|
|
81
|
+
source:
|
|
82
|
+
type: mcp
|
|
83
|
+
server: "@readme/mcp-server"
|
|
84
|
+
|
|
85
|
+
journeys:
|
|
86
|
+
developer_experience:
|
|
87
|
+
- Can I try the API interactively?
|
|
88
|
+
- Are there code examples?
|
|
89
|
+
- Is versioning documented?
|
|
90
|
+
|
|
91
|
+
provider: openai
|
|
92
|
+
model: gpt-4o-mini`,
|
|
93
|
+
gitbook: `# DocWorks Configuration - GitBook
|
|
94
|
+
source:
|
|
95
|
+
type: mcp
|
|
96
|
+
server: "@gitbook/mcp-server"
|
|
97
|
+
|
|
98
|
+
journeys:
|
|
99
|
+
knowledge_base:
|
|
100
|
+
- Is content organized logically?
|
|
101
|
+
- Can I search effectively?
|
|
102
|
+
- Are guides comprehensive?
|
|
103
|
+
|
|
104
|
+
provider: openai
|
|
105
|
+
model: gpt-4o-mini`,
|
|
106
|
+
};
|
|
107
|
+
export async function init(options) {
|
|
108
|
+
console.log('🚀 Initializing DocWorks...\n');
|
|
109
|
+
// Check existing config
|
|
110
|
+
if (fs.existsSync('docworks.yml')) {
|
|
111
|
+
console.log('⚠️ docworks.yml already exists');
|
|
112
|
+
process.exit(1);
|
|
113
|
+
}
|
|
114
|
+
// Select template
|
|
115
|
+
const templateName = options.platform || options.template || 'default';
|
|
116
|
+
const template = TEMPLATES[templateName];
|
|
117
|
+
if (!template) {
|
|
118
|
+
console.error(`Unknown template: ${templateName}`);
|
|
119
|
+
console.log('Available: default, api, library, mintlify, readme, gitbook');
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
// Create llms.txt if needed (not for MCP platforms)
|
|
123
|
+
if (!options.platform && !fs.existsSync('llms.txt')) {
|
|
124
|
+
await createLLMSTxt();
|
|
125
|
+
}
|
|
126
|
+
// Write config
|
|
127
|
+
fs.writeFileSync('docworks.yml', template);
|
|
128
|
+
console.log('✅ Created docworks.yml\n');
|
|
129
|
+
// Next steps
|
|
130
|
+
console.log('Next steps:');
|
|
131
|
+
if (!options.platform) {
|
|
132
|
+
console.log('1. Review llms.txt - ensure all docs are listed');
|
|
133
|
+
}
|
|
134
|
+
console.log('2. Set your API key:');
|
|
135
|
+
console.log(' export OPENAI_API_KEY=sk-...');
|
|
136
|
+
console.log('3. Run validation:');
|
|
137
|
+
console.log(' docworks check');
|
|
138
|
+
}
|
|
139
|
+
async function createLLMSTxt() {
|
|
140
|
+
console.log('📝 Creating llms.txt...');
|
|
141
|
+
// Find common documentation files
|
|
142
|
+
const patterns = ['README.md', 'readme.md', 'docs/**/*.md', '*.md'];
|
|
143
|
+
const files = new Set();
|
|
144
|
+
for (const pattern of patterns) {
|
|
145
|
+
const matches = await glob(pattern, {
|
|
146
|
+
ignore: ['node_modules/**', '.git/**', 'CHANGELOG.md'],
|
|
147
|
+
});
|
|
148
|
+
matches.forEach((file) => files.add(file));
|
|
149
|
+
}
|
|
150
|
+
const content = [
|
|
151
|
+
'# Documentation sources for DocWorks',
|
|
152
|
+
'# Add your documentation files below, one per line',
|
|
153
|
+
'# Lines starting with # are comments',
|
|
154
|
+
'',
|
|
155
|
+
...Array.from(files).slice(0, 20), // Limit initial list
|
|
156
|
+
'',
|
|
157
|
+
'# Add more files as needed:',
|
|
158
|
+
'# docs/api/authentication.md',
|
|
159
|
+
'# examples/quickstart.js',
|
|
160
|
+
'# https://api.example.com/openapi.json',
|
|
161
|
+
].join('\n');
|
|
162
|
+
fs.writeFileSync('llms.txt', content);
|
|
163
|
+
console.log(`✅ Created llms.txt with ${files.size} documentation files\n`);
|
|
164
|
+
}
|
|
165
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAIA,wBAAsB,IAAI,CAAC,OAAO,EAAE;IAClC,MAAM,EAAE,MAAM,CAAA;IACd,EAAE,CAAC,EAAE,MAAM,CAAA;CACZ,GAAG,OAAO,CAAC,IAAI,CAAC,CA+ChB"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { loadConfig } from '../utils/config.js';
|
|
2
|
+
import { createSource } from '../sources/base.js';
|
|
3
|
+
import { createProvider } from '../providers/base.js';
|
|
4
|
+
export async function test(options) {
|
|
5
|
+
if (!options.ai) {
|
|
6
|
+
console.error('Specify a task: docworks test --ai "build hello world"');
|
|
7
|
+
process.exit(1);
|
|
8
|
+
}
|
|
9
|
+
try {
|
|
10
|
+
const config = await loadConfig(options.config || 'docworks.yml');
|
|
11
|
+
const apiKey = process.env.OPENAI_API_KEY || config.api_key;
|
|
12
|
+
if (!apiKey) {
|
|
13
|
+
console.error('❌ No API key found');
|
|
14
|
+
process.exit(1);
|
|
15
|
+
}
|
|
16
|
+
// Load docs
|
|
17
|
+
console.log('📚 Loading documentation...');
|
|
18
|
+
const source = await createSource(config);
|
|
19
|
+
const docs = await source.fetch();
|
|
20
|
+
// Ask AI to complete task
|
|
21
|
+
console.log(`\n🤖 Testing: "${options.ai}"\n`);
|
|
22
|
+
const provider = createProvider(config.provider || 'openai', apiKey);
|
|
23
|
+
const prompt = `
|
|
24
|
+
Using ONLY this documentation, ${options.ai}.
|
|
25
|
+
Provide working code.
|
|
26
|
+
|
|
27
|
+
Documentation:
|
|
28
|
+
${docs.substring(0, 30000)}
|
|
29
|
+
|
|
30
|
+
Provide ONLY the code, no explanation.`;
|
|
31
|
+
const response = await provider.complete(prompt);
|
|
32
|
+
console.log('Generated code:');
|
|
33
|
+
console.log('─'.repeat(40));
|
|
34
|
+
console.log(response);
|
|
35
|
+
console.log('─'.repeat(40));
|
|
36
|
+
// Future: Actually execute and validate the code
|
|
37
|
+
console.log('\n✅ AI successfully generated code from documentation');
|
|
38
|
+
console.log('⚠️ Code execution validation coming soon');
|
|
39
|
+
}
|
|
40
|
+
catch (error) {
|
|
41
|
+
console.error('❌ Error:', error.message);
|
|
42
|
+
process.exit(1);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
//# sourceMappingURL=test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test.js","sourceRoot":"","sources":["../../src/commands/test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACjD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,OAG1B;IACC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAA;QACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,CAAA;QACjE,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,MAAM,CAAC,OAAO,CAAA;QAE3D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAA;YACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACjB,CAAC;QAED,YAAY;QACZ,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAA;QAC1C,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,MAAM,CAAC,CAAA;QACzC,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAA;QAEjC,0BAA0B;QAC1B,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,EAAE,KAAK,CAAC,CAAA;QAE9C,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,CAAC,QAAQ,IAAI,QAAQ,EAAE,MAAM,CAAC,CAAA;QACpE,MAAM,MAAM,GAAG;iCACc,OAAO,CAAC,EAAE;;;;EAIzC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,KAAK,CAAC;;uCAEa,CAAA;QAEnC,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QAEhD,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;QAC9B,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QAC3B,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACrB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAA;QAE3B,iDAAiD;QACjD,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAA;QACpE,OAAO,CAAC,GAAG,CAAC,2CAA2C,CAAC,CAAA;IAC1D,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,UAAU,EAAG,KAAe,CAAC,OAAO,CAAC,CAAA;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IACjB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/core/ai.ts"],"names":[],"mappings":"AAEA,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,SAAW,EACnB,KAAK,CAAC,EAAE,MAAM,4DA8Bf"}
|
package/dist/core/ai.js
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { createProvider } from '../providers/base.js';
|
|
2
|
+
export async function checkAnswerability(question, docs, apiKey, provider = 'openai', model) {
|
|
3
|
+
const maxRetries = 3;
|
|
4
|
+
let lastError = null;
|
|
5
|
+
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
|
6
|
+
try {
|
|
7
|
+
const aiProvider = createProvider(provider, apiKey, model);
|
|
8
|
+
return await aiProvider.checkAnswerability(question, docs);
|
|
9
|
+
}
|
|
10
|
+
catch (error) {
|
|
11
|
+
lastError = error;
|
|
12
|
+
// Retry on rate limits with exponential backoff
|
|
13
|
+
if (error.status === 429 && attempt < maxRetries) {
|
|
14
|
+
const delay = Math.pow(2, attempt) * 1000;
|
|
15
|
+
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
16
|
+
continue;
|
|
17
|
+
}
|
|
18
|
+
// Don't retry on other errors
|
|
19
|
+
break;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
// Return error state instead of throwing
|
|
23
|
+
return {
|
|
24
|
+
answerable: 'NO',
|
|
25
|
+
reason: lastError?.message || 'Unknown error',
|
|
26
|
+
location: 'N/A',
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=ai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai.js","sourceRoot":"","sources":["../../src/core/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AAErD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAAgB,EAChB,IAAY,EACZ,MAAc,EACd,QAAQ,GAAG,QAAQ,EACnB,KAAc;IAEd,MAAM,UAAU,GAAG,CAAC,CAAA;IACpB,IAAI,SAAS,GAAiB,IAAI,CAAA;IAElC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QACvD,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,CAAC,CAAA;YAC1D,OAAO,MAAM,UAAU,CAAC,kBAAkB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC5D,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,SAAS,GAAG,KAAK,CAAA;YAEjB,gDAAgD;YAChD,IAAI,KAAK,CAAC,MAAM,KAAK,GAAG,IAAI,OAAO,GAAG,UAAU,EAAE,CAAC;gBACjD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,IAAI,CAAA;gBACzC,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC,CAAA;gBAC1D,SAAQ;YACV,CAAC;YAED,8BAA8B;YAC9B,MAAK;QACP,CAAC;IACH,CAAC;IAED,yCAAyC;IACzC,OAAO;QACL,UAAU,EAAE,IAAa;QACzB,MAAM,EAAE,SAAS,EAAE,OAAO,IAAI,eAAe;QAC7C,QAAQ,EAAE,KAAK;KAChB,CAAA;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AAYA,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAgB1C;AAED,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,IAAI,CAUtD"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import os from 'os';
|
|
4
|
+
const CACHE_DIR = path.join(os.homedir(), '.docworks', 'cache');
|
|
5
|
+
const CACHE_TTL = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
6
|
+
// Ensure cache directory exists
|
|
7
|
+
if (!fs.existsSync(CACHE_DIR)) {
|
|
8
|
+
fs.mkdirSync(CACHE_DIR, { recursive: true });
|
|
9
|
+
}
|
|
10
|
+
export function getCached(key) {
|
|
11
|
+
const cachePath = path.join(CACHE_DIR, `${key}.json`);
|
|
12
|
+
if (!fs.existsSync(cachePath)) {
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
const cached = JSON.parse(fs.readFileSync(cachePath, 'utf-8'));
|
|
16
|
+
// Check if expired
|
|
17
|
+
if (Date.now() - cached.timestamp > CACHE_TTL) {
|
|
18
|
+
fs.unlinkSync(cachePath);
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
return cached.data;
|
|
22
|
+
}
|
|
23
|
+
export function setCached(key, data) {
|
|
24
|
+
const cachePath = path.join(CACHE_DIR, `${key}.json`);
|
|
25
|
+
fs.writeFileSync(cachePath, JSON.stringify({
|
|
26
|
+
timestamp: Date.now(),
|
|
27
|
+
data,
|
|
28
|
+
}));
|
|
29
|
+
}
|
|
30
|
+
//** */
|
|
31
|
+
//# sourceMappingURL=cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/core/cache.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,CAAA;AAEnB,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,CAAA;AAC/D,MAAM,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA,CAAC,SAAS;AAEnD,gCAAgC;AAChC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;IAC9B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAA;AAC9C,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,CAAA;IAErD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9B,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAA;IAE9D,mBAAmB;IACnB,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,SAAS,GAAG,SAAS,EAAE,CAAC;QAC9C,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAA;QACxB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAA;AACpB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,GAAW,EAAE,IAAS;IAC9C,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,GAAG,OAAO,CAAC,CAAA;IAErD,EAAE,CAAC,aAAa,CACd,SAAS,EACT,IAAI,CAAC,SAAS,CAAC;QACb,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;QACrB,IAAI;KACL,CAAC,CACH,CAAA;AACH,CAAC;AACD,OAAO"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { ValidationResult, JourneyResults } from '../types/config.js';
|
|
2
|
+
export declare function validateJourneys(journeys: Record<string, string[]>, docs: string, apiKey: string, useCache?: boolean): Promise<JourneyResults>;
|
|
3
|
+
export declare function validateQuestions(questions: string[], docs: string, apiKey: string, useCache?: boolean): Promise<ValidationResult[]>;
|
|
4
|
+
//# sourceMappingURL=validator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/core/validator.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AAIrE,wBAAsB,gBAAgB,CACpC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EAClC,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,UAAO,GACd,OAAO,CAAC,cAAc,CAAC,CAazB;AAED,wBAAsB,iBAAiB,CACrC,SAAS,EAAE,MAAM,EAAE,EACnB,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,MAAM,EACd,QAAQ,UAAO,GACd,OAAO,CAAC,gBAAgB,EAAE,CAAC,CA4C7B"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import { checkAnswerability } from './ai.js';
|
|
3
|
+
import { getCached, setCached } from './cache.js';
|
|
4
|
+
export async function validateJourneys(journeys, docs, apiKey, useCache = true) {
|
|
5
|
+
const results = {};
|
|
6
|
+
for (const [journey, questions] of Object.entries(journeys)) {
|
|
7
|
+
results[journey] = await validateQuestions(questions, docs, apiKey, useCache);
|
|
8
|
+
}
|
|
9
|
+
return results;
|
|
10
|
+
}
|
|
11
|
+
export async function validateQuestions(questions, docs, apiKey, useCache = true) {
|
|
12
|
+
const results = [];
|
|
13
|
+
for (const question of questions) {
|
|
14
|
+
// Generate cache key
|
|
15
|
+
const cacheKey = crypto
|
|
16
|
+
.createHash('md5')
|
|
17
|
+
.update(question + docs.substring(0, 1000)) // Use first 1KB for cache key
|
|
18
|
+
.digest('hex');
|
|
19
|
+
let result = null;
|
|
20
|
+
// Try cache first
|
|
21
|
+
if (useCache) {
|
|
22
|
+
result = getCached(cacheKey);
|
|
23
|
+
}
|
|
24
|
+
// If not cached, check with AI
|
|
25
|
+
if (!result) {
|
|
26
|
+
const validation = await checkAnswerability(question, docs, apiKey);
|
|
27
|
+
result = {
|
|
28
|
+
question,
|
|
29
|
+
...validation,
|
|
30
|
+
};
|
|
31
|
+
// Cache the result
|
|
32
|
+
if (useCache) {
|
|
33
|
+
setCached(cacheKey, result);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
results.push(result);
|
|
37
|
+
// Show progress
|
|
38
|
+
const icon = result.answerable === 'YES'
|
|
39
|
+
? '✅'
|
|
40
|
+
: result.answerable === 'PARTIAL'
|
|
41
|
+
? '⚠️'
|
|
42
|
+
: '❌';
|
|
43
|
+
console.log(` ${icon} ${question}`);
|
|
44
|
+
}
|
|
45
|
+
return results;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=validator.js.map
|