qdoc-agent 0.1.5

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ibrhr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,230 @@
1
+ # qdoc — Agent for Agents
2
+
3
+ Documentation research for AI coding agents. No trial-and-error. No wasted tokens. One call, one answer.
4
+
5
+ ```
6
+ $ qdoc go "how do generics work in Go"
7
+
8
+ ● Thinking ···
9
+ ● Calling gpt-5.5 on openai
10
+ ▶ READ: tutorial/generics
11
+ ▶ READ: effective_go
12
+ ▶ READ: go1.24
13
+
14
+ ## Generics in Go
15
+
16
+ Type parameters enable...
17
+ ```
18
+
19
+ ---
20
+
21
+ ## Why qdoc?
22
+
23
+ AI coding agents waste tokens when researching documentation. The typical agent loop:
24
+
25
+ ```
26
+ Agent: searches docs index → finds 200+ links
27
+ Agent: fetches 5 pages, none are right
28
+ Agent: tries 5 more, close but incomplete
29
+ Agent: one more round, finally gets it
30
+ Agent: synthesizes answer
31
+
32
+ Total: ~10 page fetches, ~40% irrelevant content, 3 LLM rounds
33
+ ```
34
+
35
+ **qdoc replaces this with a one-shot LLM call:**
36
+
37
+ ```
38
+ qdoc: fetches doc index (1 HTTP call)
39
+ qdoc: passes index → query to LLM (1 inference)
40
+ LLM: returns "read these 3 specific pages"
41
+ qdoc: fetches them in parallel (3 HTTP calls)
42
+ qdoc: if needed, asks LLM for one more round (up to 5 turns)
43
+ LLM: synthesizes final answer with citations
44
+
45
+ Total: 1-5 page fetches, 100% LLM-selected relevance, 1-2 LLM rounds
46
+ ```
47
+
48
+ The difference compounds: an agent making 10 doc queries per session saves 50+ unnecessary page fetches and 15-20 redundant LLM rounds.
49
+
50
+ ---
51
+
52
+ ## Quick start
53
+
54
+ ```bash
55
+ # Linux, macOS (shell)
56
+ curl -fsSL https://qdoc.ibrhr.dev/install.sh | bash
57
+
58
+ # Any platform (npm)
59
+ npm install -g qdoc-agent
60
+ ```
61
+
62
+ ```bash
63
+ qdoc set key openai # prompts for your API key (input hidden)
64
+ qdoc go "generics tutorial" # ask your first question
65
+ ```
66
+
67
+ ---
68
+
69
+ ## Usage
70
+
71
+ ### As a human (interactive TUI)
72
+
73
+ ```bash
74
+ qdoc go "how does context work?"
75
+ qdoc fastapi "dependency injection patterns"
76
+ qdoc ./my-docs "deployment guide"
77
+ ```
78
+
79
+ Built with Bubble Tea v2. Live streaming, scrollable output, interactive provider/model pickers.
80
+
81
+ ### As an agent (headless)
82
+
83
+ ```bash
84
+ # Markdown to stdout — agent parses directly
85
+ qdoc --no-tui go "error wrapping with fmt.Errorf"
86
+
87
+ # Structured JSON — for programmatic consumption
88
+ qdoc --json go "generics constraints" | jq '.answer'
89
+
90
+ # In CI pipelines
91
+ qdoc --no-tui --json go "release notes for Go 1.24" > result.json
92
+ ```
93
+
94
+ ### Integration
95
+
96
+ Copy [`skill.md`](skill.md) to your agent's skills directory:
97
+
98
+ | Agent | Path |
99
+ |-------|------|
100
+ | **opencode** | `~/.agents/skills/qdoc/SKILL.md` |
101
+ | **Claude Code** | `~/.claude/skills/qdoc.md` |
102
+ | **Cursor** | Add as custom instruction |
103
+
104
+ Or instruct any agent manually:
105
+
106
+ > When you need documentation about a framework or library, run `qdoc --no-tui <source> <query>`. Available sources: go, fastapi, or any local docs directory.
107
+
108
+ ---
109
+
110
+ ## Providers
111
+
112
+ qdoc uses any OpenAI-compatible API.
113
+
114
+ | Provider | Default Model | Models Available |
115
+ |----------|--------------|-----------------|
116
+ | `openai` | `gpt-5.5` | gpt-5.5, gpt-5.5-pro, gpt-5.4, gpt-5.4-pro, gpt-5.4-mini, gpt-5.4-nano |
117
+ | `deepseek` | `deepseek-v4-flash` | deepseek-v4-flash, deepseek-v4-pro |
118
+ | `opencode-zen` | `gpt-5.4-mini` | GPT 5.5/5.4, Claude Opus 4.x, Claude Sonnet 4.x, Claude Haiku 4.5, Gemini 3.x, Qwen, MiniMax, GLM, Kimi, DeepSeek, Nemotron |
119
+ | `opencode-go` | `deepseek-v4-flash` | Qwen, MiniMax, GLM, Kimi, DeepSeek, MiMo (low-cost coding models) |
120
+
121
+ Set a provider interactively (`qdoc provider`), via config, or with env vars: `OPENAI_API_KEY`, `DEEPSEEK_API_KEY`, `OPENCODE_ZEN_API_KEY`, `OPENCODE_GO_API_KEY`.
122
+
123
+ ---
124
+
125
+ ## Documentation sources
126
+
127
+ | Source | Description |
128
+ |--------|------------|
129
+ | `go` | Go standard library, toolchain, modules, tutorials — [go.dev/doc](https://go.dev/doc) |
130
+ | `fastapi` | FastAPI framework — [fastapi.tiangolo.com](https://fastapi.tiangolo.com) |
131
+ | `./path` | Any local directory of markdown, HTML, RST, or AsciiDoc files |
132
+
133
+ ```bash
134
+ qdoc sources # list all available sources
135
+ ```
136
+
137
+ ---
138
+
139
+ ## Configuration
140
+
141
+ ```json
142
+ // ~/.config/qdoc/config.json
143
+ {
144
+ "provider": "openai",
145
+ "keys": { "openai": "sk-..." },
146
+ "models": { "openai": "gpt-5.5" }
147
+ }
148
+ ```
149
+
150
+ Resolution order: `QDOC_*` environment variables → config file → built-in defaults.
151
+
152
+ | Variable | Overrides |
153
+ |----------|----------|
154
+ | `QDOC_PROVIDER` | Active provider |
155
+ | `QDOC_MODEL` | Active model |
156
+ | `QDOC_BASE_URL` | API base URL |
157
+
158
+ ---
159
+
160
+ ## Commands
161
+
162
+ ```bash
163
+ qdoc go "query" # query Go docs
164
+ qdoc fastapi "query" # query FastAPI docs
165
+ qdoc ./my-docs "query" # query local docs directory
166
+
167
+ qdoc provider # interactive provider picker (TUI)
168
+ qdoc model # interactive model picker (TUI)
169
+ qdoc set key openai # save an API key (prompts securely)
170
+ qdoc set key openai sk-... # save an API key (inline)
171
+ qdoc set provider openai # switch default provider
172
+ qdoc set model openai gpt-5.5 # set model for a provider
173
+
174
+ qdoc status # show current config
175
+ qdoc providers # list providers + key status
176
+ qdoc sources # list documentation sources
177
+ ```
178
+
179
+ ---
180
+
181
+ ## Install
182
+
183
+ ### Shell script (Linux, macOS)
184
+
185
+ ```bash
186
+ curl -fsSL https://qdoc.ibrhr.dev/install.sh | bash
187
+ ```
188
+
189
+ Installs to `~/.qdoc/bin` (no sudo). Adds itself to your shell config. Options:
190
+
191
+ ```bash
192
+ curl -fsSL ... | bash -s -- --version 0.1.2 # specific version
193
+ curl -fsSL ... | bash -s -- --no-modify-path # don't touch shell config
194
+ ```
195
+
196
+ ### npm (all platforms)
197
+
198
+ ```bash
199
+ npm install -g qdoc-agent
200
+ ```
201
+
202
+ ### Manual download
203
+
204
+ Binaries for every platform on [GitHub Releases](https://github.com/ibrhr/qdoc/releases/latest).
205
+
206
+ ### From source
207
+
208
+ ```bash
209
+ git clone https://github.com/ibrhr/qdoc.git
210
+ cd qdoc
211
+ go build -ldflags "-X main.version=$(git describe --tags) -X main.commit=$(git rev-parse --short HEAD)" -o qdoc .
212
+ mv qdoc ~/.local/bin/
213
+ ```
214
+
215
+ Requires Go 1.26+.
216
+
217
+ ---
218
+
219
+ ## Verify
220
+
221
+ ```bash
222
+ qdoc --version
223
+ # qdoc 0.1.2 (abc1234)
224
+ ```
225
+
226
+ ---
227
+
228
+ ## License
229
+
230
+ MIT
package/bin/qdoc.js ADDED
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ const { execFileSync } = require("child_process");
3
+ const { join } = require("path");
4
+
5
+ const ext = process.platform === "win32" ? ".exe" : "";
6
+ const bin = join(__dirname, "..", "qdoc_bin" + ext);
7
+
8
+ try {
9
+ execFileSync(bin, process.argv.slice(2), { stdio: "inherit" });
10
+ } catch (err) {
11
+ process.exit(err.status || 1);
12
+ }
package/install.js ADDED
@@ -0,0 +1,74 @@
1
+ const { execSync } = require("child_process");
2
+ const { existsSync, renameSync, mkdirSync, rmSync, writeFileSync } = require("fs");
3
+ const { join } = require("path");
4
+ const https = require("https");
5
+
6
+ const REPO = "ibrhr/qdoc";
7
+
8
+ function mapPlatform() {
9
+ const goos = { linux: "linux", darwin: "darwin", win32: "windows" }[process.platform];
10
+ const goarch = { x64: "amd64", arm64: "arm64" }[process.arch];
11
+ if (!goos || !goarch) throw new Error(`Unsupported: ${process.platform}/${process.arch}`);
12
+ return `${goos}_${goarch}`;
13
+ }
14
+
15
+ function fetch(url) {
16
+ return new Promise((resolve, reject) => {
17
+ https.get(url, (res) => {
18
+ if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
19
+ https.get(res.headers.location, (rr) => {
20
+ const c = []; rr.on("data", (d) => c.push(d));
21
+ rr.on("end", () => resolve(Buffer.concat(c)));
22
+ rr.on("error", reject);
23
+ });
24
+ return;
25
+ }
26
+ const c = []; res.on("data", (d) => c.push(d));
27
+ res.on("end", () => resolve(Buffer.concat(c)));
28
+ res.on("error", reject);
29
+ }).on("error", reject);
30
+ });
31
+ }
32
+
33
+ async function main() {
34
+ const pkgDir = join(__dirname);
35
+ const ext = process.platform === "win32" ? ".exe" : "";
36
+ const dest = join(pkgDir, "qdoc_bin" + ext);
37
+
38
+ if (existsSync(dest)) return;
39
+
40
+ const platform = mapPlatform();
41
+ const base = `https://github.com/${REPO}/releases/latest/download/qdoc_${platform}`;
42
+ const url = process.platform === "win32" ? `${base}.zip` : `${base}.tar.gz`;
43
+
44
+ process.stderr.write(`qdoc: downloading ${url}\n`);
45
+ const buf = await fetch(url);
46
+
47
+ const tmp = join(pkgDir, ".qdoc_tmp");
48
+ mkdirSync(tmp, { recursive: true });
49
+
50
+ try {
51
+ if (process.platform === "win32") {
52
+ writeFileSync(join(tmp, "qdoc.zip"), buf);
53
+ execSync(`tar -xf qdoc.zip`, { cwd: tmp, stdio: "ignore" });
54
+ } else {
55
+ writeFileSync(join(tmp, "qdoc.tar.gz"), buf);
56
+ execSync(`tar xzf qdoc.tar.gz`, { cwd: tmp, stdio: "ignore" });
57
+ }
58
+
59
+ const src = join(tmp, "qdoc" + ext);
60
+ if (!existsSync(src)) throw new Error("binary not found in archive");
61
+ renameSync(src, dest);
62
+ } finally {
63
+ rmSync(tmp, { recursive: true, force: true });
64
+ }
65
+
66
+ if (process.platform !== "win32") {
67
+ execSync(`chmod +x "${dest}"`, { stdio: "ignore" });
68
+ }
69
+ }
70
+
71
+ main().catch((err) => {
72
+ console.error("qdoc install failed:", err.message);
73
+ process.exit(1);
74
+ });
package/package.json ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "name": "qdoc-agent",
3
+ "version": "0.1.5",
4
+ "description": "Agent for Agents — documentation research for AI coding agents. One call, one answer. No trial-and-error. No wasted tokens.",
5
+ "license": "MIT",
6
+ "repository": "github:ibrhr/qdoc",
7
+ "bin": {
8
+ "qdoc": "bin/qdoc.js"
9
+ },
10
+ "scripts": {
11
+ "postinstall": "node install.js"
12
+ },
13
+ "files": [
14
+ "install.js",
15
+ "bin/qdoc.js"
16
+ ],
17
+ "os": [
18
+ "linux",
19
+ "darwin",
20
+ "win32"
21
+ ],
22
+ "cpu": [
23
+ "x64",
24
+ "arm64"
25
+ ]
26
+ }