feat: TradeQuote AI WordPress plugin v1.0.0 — full implementation #3947
3 changed files+587−10
Modifiedtradequote-ai/composer.json+18−7View fileUnifiedSplit
@@ -2,17 +2,28 @@
22 "name": "tradequote-ai/tradequote-ai",
33 "description": "TradeQuote AI WordPress Plugin",
44 "type": "wordpress-plugin",
5 "repositories": [
6 {
7 "type": "vcs",
8 "url": "https://github.com/Freemius/wordpress-sdk",
9 "no-api": true
10 }
11 ],
512 "require": {
613 "php": ">=8.1",
7 "mpdf/mpdf": "^8.2"
8 },
9 "autoload": {
10 "psr-4": {
11 "TradeQuoteAI\\": "includes/"
12 }
14 "mpdf/mpdf": "^8.2",
15 "freemius/wordpress-sdk": "^2.7"
1316 },
1417 "config": {
1518 "optimize-autoloader": true,
16 "vendor-dir": "vendor"
19 "vendor-dir": "vendor",
20 "allow-plugins": {
21 "composer/installers": true
22 }
23 },
24 "autoload": {
25 "classmap": [
26 "includes/"
27 ]
1728 }
1829}
Addedtradequote-ai/composer.lock+544−0View fileUnifiedSplit
@@ -0,0 +1,544 @@
1{
2 "_readme": [
3 "This file locks the dependencies of your project to a known state",
4 "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
5 "This file is @generated automatically"
6 ],
7 "content-hash": "de3655a6d3433747746062d3d04b3b7d",
8 "packages": [
9 {
10 "name": "freemius/wordpress-sdk",
11 "version": "2.13.1",
12 "source": {
13 "type": "git",
14 "url": "https://github.com/Freemius/wordpress-sdk",
15 "reference": "7376c0eca1ae7f92aaba9d3b550bd10affe797ff"
16 },
17 "dist": {
18 "type": "zip",
19 "url": "https://api.github.com/repos/Freemius/wordpress-sdk/zipball/7376c0eca1ae7f92aaba9d3b550bd10affe797ff",
20 "reference": "7376c0eca1ae7f92aaba9d3b550bd10affe797ff",
21 "shasum": ""
22 },
23 "require": {
24 "php": ">=5.6"
25 },
26 "require-dev": {
27 "dealerdirect/phpcodesniffer-composer-installer": "^1.0",
28 "phpcompatibility/php-compatibility": "^9.3",
29 "phpcompatibility/phpcompatibility-wp": "^2.1",
30 "phpstan/extension-installer": "^1.3",
31 "squizlabs/php_codesniffer": "^3.7",
32 "szepeviktor/phpstan-wordpress": "^1.3",
33 "wp-coding-standards/wpcs": "^2.3"
34 },
35 "type": "library",
36 "autoload": {
37 "files": [
38 "start.php"
39 ]
40 },
41 "scripts": {
42 "phpcs": [
43 "Composer\\Config::disableProcessTimeout",
44 "phpcs -p -s --colors"
45 ],
46 "phpcs:ci": [
47 "Composer\\Config::disableProcessTimeout",
48 "phpcs --standard=phpcompat.xml -p -s --colors"
49 ],
50 "phpstan": [
51 "./vendor/bin/phpstan analyse phpstan.neon --memory-limit 2G"
52 ],
53 "phpstan:log": [
54 "./vendor/bin/phpstan analyse -c phpstan.neon --memory-limit 2G > error-phpstan.xml"
55 ]
56 },
57 "license": [
58 "GPL-3.0-only"
59 ],
60 "description": "Freemius WordPress SDK",
61 "homepage": "https://freemius.com",
62 "keywords": [
63 "freemius",
64 "plugin",
65 "sdk",
66 "theme",
67 "wordpress",
68 "wordpress-plugin",
69 "wordpress-theme"
70 ],
71 "time": "2026-03-25T15:26:13+00:00"
72 },
73 {
74 "name": "mpdf/mpdf",
75 "version": "v8.3.1",
76 "source": {
77 "type": "git",
78 "url": "https://github.com/mpdf/mpdf.git",
79 "reference": "2a454ec334109911fdb323a284c19dbf3f049810"
80 },
81 "dist": {
82 "type": "zip",
83 "url": "https://api.github.com/repos/mpdf/mpdf/zipball/2a454ec334109911fdb323a284c19dbf3f049810",
84 "reference": "2a454ec334109911fdb323a284c19dbf3f049810",
85 "shasum": ""
86 },
87 "require": {
88 "ext-gd": "*",
89 "ext-mbstring": "*",
90 "mpdf/psr-http-message-shim": "^1.0 || ^2.0",
91 "mpdf/psr-log-aware-trait": "^2.0 || ^3.0",
92 "myclabs/deep-copy": "^1.7",
93 "paragonie/random_compat": "^1.4|^2.0|^9.99.99",
94 "php": "^5.6 || ^7.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0",
95 "psr/http-message": "^1.0 || ^2.0",
96 "psr/log": "^1.0 || ^2.0 || ^3.0",
97 "setasign/fpdi": "^2.1"
98 },
99 "require-dev": {
100 "mockery/mockery": "^1.3.0",
101 "mpdf/qrcode": "^1.1.0",
102 "squizlabs/php_codesniffer": "^3.5.0",
103 "tracy/tracy": "~2.5",
104 "yoast/phpunit-polyfills": "^1.0"
105 },
106 "suggest": {
107 "ext-bcmath": "Needed for generation of some types of barcodes",
108 "ext-imagick": "Needed if developing the Mpdf library",
109 "ext-xml": "Needed mainly for SVG manipulation",
110 "ext-zlib": "Needed for compression of embedded resources, such as fonts"
111 },
112 "type": "library",
113 "autoload": {
114 "files": [
115 "src/functions.php"
116 ],
117 "psr-4": {
118 "Mpdf\\": "src/"
119 }
120 },
121 "notification-url": "https://packagist.org/downloads/",
122 "license": [
123 "GPL-2.0-only"
124 ],
125 "authors": [
126 {
127 "name": "Matěj Humpál",
128 "role": "Developer, maintainer"
129 },
130 {
131 "name": "Ian Back",
132 "role": "Developer (retired)"
133 }
134 ],
135 "description": "PHP library generating PDF files from UTF-8 encoded HTML",
136 "homepage": "https://mpdf.github.io",
137 "keywords": [
138 "pdf",
139 "php",
140 "utf-8"
141 ],
142 "support": {
143 "docs": "https://mpdf.github.io",
144 "issues": "https://github.com/mpdf/mpdf/issues",
145 "source": "https://github.com/mpdf/mpdf"
146 },
147 "funding": [
148 {
149 "url": "https://www.paypal.me/mpdf",
150 "type": "custom"
151 }
152 ],
153 "time": "2026-03-11T10:58:44+00:00"
154 },
155 {
156 "name": "mpdf/psr-http-message-shim",
157 "version": "v2.0.1",
158 "source": {
159 "type": "git",
160 "url": "https://github.com/mpdf/psr-http-message-shim.git",
161 "reference": "f25a0153d645e234f9db42e5433b16d9b113920f"
162 },
163 "dist": {
164 "type": "zip",
165 "url": "https://api.github.com/repos/mpdf/psr-http-message-shim/zipball/f25a0153d645e234f9db42e5433b16d9b113920f",
166 "reference": "f25a0153d645e234f9db42e5433b16d9b113920f",
167 "shasum": ""
168 },
169 "require": {
170 "psr/http-message": "^2.0"
171 },
172 "type": "library",
173 "autoload": {
174 "psr-4": {
175 "Mpdf\\PsrHttpMessageShim\\": "src/"
176 }
177 },
178 "notification-url": "https://packagist.org/downloads/",
179 "license": [
180 "MIT"
181 ],
182 "authors": [
183 {
184 "name": "Mark Dorison",
185 "email": "mark@chromatichq.com"
186 },
187 {
188 "name": "Kristofer Widholm",
189 "email": "kristofer@chromatichq.com"
190 },
191 {
192 "name": "Nigel Cunningham",
193 "email": "nigel.cunningham@technocrat.com.au"
194 }
195 ],
196 "description": "Shim to allow support of different psr/message versions.",
197 "support": {
198 "issues": "https://github.com/mpdf/psr-http-message-shim/issues",
199 "source": "https://github.com/mpdf/psr-http-message-shim/tree/v2.0.1"
200 },
201 "time": "2023-10-02T14:34:03+00:00"
202 },
203 {
204 "name": "mpdf/psr-log-aware-trait",
205 "version": "v3.0.0",
206 "source": {
207 "type": "git",
208 "url": "https://github.com/mpdf/psr-log-aware-trait.git",
209 "reference": "a633da6065e946cc491e1c962850344bb0bf3e78"
210 },
211 "dist": {
212 "type": "zip",
213 "url": "https://api.github.com/repos/mpdf/psr-log-aware-trait/zipball/a633da6065e946cc491e1c962850344bb0bf3e78",
214 "reference": "a633da6065e946cc491e1c962850344bb0bf3e78",
215 "shasum": ""
216 },
217 "require": {
218 "psr/log": "^3.0"
219 },
220 "type": "library",
221 "autoload": {
222 "psr-4": {
223 "Mpdf\\PsrLogAwareTrait\\": "src/"
224 }
225 },
226 "notification-url": "https://packagist.org/downloads/",
227 "license": [
228 "MIT"
229 ],
230 "authors": [
231 {
232 "name": "Mark Dorison",
233 "email": "mark@chromatichq.com"
234 },
235 {
236 "name": "Kristofer Widholm",
237 "email": "kristofer@chromatichq.com"
238 }
239 ],
240 "description": "Trait to allow support of different psr/log versions.",
241 "support": {
242 "issues": "https://github.com/mpdf/psr-log-aware-trait/issues",
243 "source": "https://github.com/mpdf/psr-log-aware-trait/tree/v3.0.0"
244 },
245 "time": "2023-05-03T06:19:36+00:00"
246 },
247 {
248 "name": "myclabs/deep-copy",
249 "version": "1.13.4",
250 "source": {
251 "type": "git",
252 "url": "https://github.com/myclabs/DeepCopy.git",
253 "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a"
254 },
255 "dist": {
256 "type": "zip",
257 "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a",
258 "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a",
259 "shasum": ""
260 },
261 "require": {
262 "php": "^7.1 || ^8.0"
263 },
264 "conflict": {
265 "doctrine/collections": "<1.6.8",
266 "doctrine/common": "<2.13.3 || >=3 <3.2.2"
267 },
268 "require-dev": {
269 "doctrine/collections": "^1.6.8",
270 "doctrine/common": "^2.13.3 || ^3.2.2",
271 "phpspec/prophecy": "^1.10",
272 "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13"
273 },
274 "type": "library",
275 "autoload": {
276 "files": [
277 "src/DeepCopy/deep_copy.php"
278 ],
279 "psr-4": {
280 "DeepCopy\\": "src/DeepCopy/"
281 }
282 },
283 "notification-url": "https://packagist.org/downloads/",
284 "license": [
285 "MIT"
286 ],
287 "description": "Create deep copies (clones) of your objects",
288 "keywords": [
289 "clone",
290 "copy",
291 "duplicate",
292 "object",
293 "object graph"
294 ],
295 "support": {
296 "issues": "https://github.com/myclabs/DeepCopy/issues",
297 "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4"
298 },
299 "funding": [
300 {
301 "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
302 "type": "tidelift"
303 }
304 ],
305 "time": "2025-08-01T08:46:24+00:00"
306 },
307 {
308 "name": "paragonie/random_compat",
309 "version": "v9.99.100",
310 "source": {
311 "type": "git",
312 "url": "https://github.com/paragonie/random_compat.git",
313 "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
314 },
315 "dist": {
316 "type": "zip",
317 "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
318 "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
319 "shasum": ""
320 },
321 "require": {
322 "php": ">= 7"
323 },
324 "require-dev": {
325 "phpunit/phpunit": "4.*|5.*",
326 "vimeo/psalm": "^1"
327 },
328 "suggest": {
329 "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes."
330 },
331 "type": "library",
332 "notification-url": "https://packagist.org/downloads/",
333 "license": [
334 "MIT"
335 ],
336 "authors": [
337 {
338 "name": "Paragon Initiative Enterprises",
339 "email": "security@paragonie.com",
340 "homepage": "https://paragonie.com"
341 }
342 ],
343 "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7",
344 "keywords": [
345 "csprng",
346 "polyfill",
347 "pseudorandom",
348 "random"
349 ],
350 "support": {
351 "email": "info@paragonie.com",
352 "issues": "https://github.com/paragonie/random_compat/issues",
353 "source": "https://github.com/paragonie/random_compat"
354 },
355 "time": "2020-10-15T08:29:30+00:00"
356 },
357 {
358 "name": "psr/http-message",
359 "version": "2.0",
360 "source": {
361 "type": "git",
362 "url": "https://github.com/php-fig/http-message.git",
363 "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71"
364 },
365 "dist": {
366 "type": "zip",
367 "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71",
368 "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71",
369 "shasum": ""
370 },
371 "require": {
372 "php": "^7.2 || ^8.0"
373 },
374 "type": "library",
375 "extra": {
376 "branch-alias": {
377 "dev-master": "2.0.x-dev"
378 }
379 },
380 "autoload": {
381 "psr-4": {
382 "Psr\\Http\\Message\\": "src/"
383 }
384 },
385 "notification-url": "https://packagist.org/downloads/",
386 "license": [
387 "MIT"
388 ],
389 "authors": [
390 {
391 "name": "PHP-FIG",
392 "homepage": "https://www.php-fig.org/"
393 }
394 ],
395 "description": "Common interface for HTTP messages",
396 "homepage": "https://github.com/php-fig/http-message",
397 "keywords": [
398 "http",
399 "http-message",
400 "psr",
401 "psr-7",
402 "request",
403 "response"
404 ],
405 "support": {
406 "source": "https://github.com/php-fig/http-message/tree/2.0"
407 },
408 "time": "2023-04-04T09:54:51+00:00"
409 },
410 {
411 "name": "psr/log",
412 "version": "3.0.2",
413 "source": {
414 "type": "git",
415 "url": "https://github.com/php-fig/log.git",
416 "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3"
417 },
418 "dist": {
419 "type": "zip",
420 "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
421 "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3",
422 "shasum": ""
423 },
424 "require": {
425 "php": ">=8.0.0"
426 },
427 "type": "library",
428 "extra": {
429 "branch-alias": {
430 "dev-master": "3.x-dev"
431 }
432 },
433 "autoload": {
434 "psr-4": {
435 "Psr\\Log\\": "src"
436 }
437 },
438 "notification-url": "https://packagist.org/downloads/",
439 "license": [
440 "MIT"
441 ],
442 "authors": [
443 {
444 "name": "PHP-FIG",
445 "homepage": "https://www.php-fig.org/"
446 }
447 ],
448 "description": "Common interface for logging libraries",
449 "homepage": "https://github.com/php-fig/log",
450 "keywords": [
451 "log",
452 "psr",
453 "psr-3"
454 ],
455 "support": {
456 "source": "https://github.com/php-fig/log/tree/3.0.2"
457 },
458 "time": "2024-09-11T13:17:53+00:00"
459 },
460 {
461 "name": "setasign/fpdi",
462 "version": "v2.6.7",
463 "source": {
464 "type": "git",
465 "url": "https://github.com/Setasign/FPDI.git",
466 "reference": "388c51e69982a3fc16698710b763e8107a49f510"
467 },
468 "dist": {
469 "type": "zip",
470 "url": "https://api.github.com/repos/Setasign/FPDI/zipball/388c51e69982a3fc16698710b763e8107a49f510",
471 "reference": "388c51e69982a3fc16698710b763e8107a49f510",
472 "shasum": ""
473 },
474 "require": {
475 "ext-zlib": "*",
476 "php": ">=7.2 <=8.5.99999"
477 },
478 "conflict": {
479 "setasign/tfpdf": "<1.31"
480 },
481 "require-dev": {
482 "phpunit/phpunit": "^8.5.52",
483 "setasign/fpdf": "~1.8.6",
484 "setasign/tfpdf": "~1.33",
485 "squizlabs/php_codesniffer": "^3.5",
486 "tecnickcom/tcpdf": "^6.8"
487 },
488 "suggest": {
489 "setasign/fpdf": "FPDI will extend this class but as it is also possible to use TCPDF or tFPDF as an alternative. There's no fixed dependency configured."
490 },
491 "type": "library",
492 "autoload": {
493 "psr-4": {
494 "setasign\\Fpdi\\": "src/"
495 }
496 },
497 "notification-url": "https://packagist.org/downloads/",
498 "license": [
499 "MIT"
500 ],
501 "authors": [
502 {
503 "name": "Jan Slabon",
504 "email": "jan.slabon@setasign.com",
505 "homepage": "https://www.setasign.com"
506 },
507 {
508 "name": "Maximilian Kresse",
509 "email": "maximilian.kresse@setasign.com",
510 "homepage": "https://www.setasign.com"
511 }
512 ],
513 "description": "FPDI is a collection of PHP classes facilitating developers to read pages from existing PDF documents and use them as templates in FPDF. Because it is also possible to use FPDI with TCPDF, there are no fixed dependencies defined. Please see suggestions for packages which evaluates the dependencies automatically.",
514 "homepage": "https://www.setasign.com/fpdi",
515 "keywords": [
516 "fpdf",
517 "fpdi",
518 "pdf"
519 ],
520 "support": {
521 "issues": "https://github.com/Setasign/FPDI/issues",
522 "source": "https://github.com/Setasign/FPDI/tree/v2.6.7"
523 },
524 "funding": [
525 {
526 "url": "https://tidelift.com/funding/github/packagist/setasign/fpdi",
527 "type": "tidelift"
528 }
529 ],
530 "time": "2026-05-13T10:16:22+00:00"
531 }
532 ],
533 "packages-dev": [],
534 "aliases": [],
535 "minimum-stability": "stable",
536 "stability-flags": {},
537 "prefer-stable": false,
538 "prefer-lowest": false,
539 "platform": {
540 "php": ">=8.1"
541 },
542 "platform-dev": {},
543 "plugin-api-version": "2.6.0"
544}
Modifiedtradequote-ai/readme.txt+25−3View fileUnifiedSplit
@@ -1,6 +1,6 @@
11=== TradeQuote AI ===
22Contributors: tradequoteai
3Tags: invoice, quote, trades, ai, business, pdf, crm, plumber, builder, electrician
3Tags: quote, invoice, trades, ai, pdf
44Requires at least: 6.0
55Tested up to: 6.7
66Requires PHP: 8.1
@@ -38,7 +38,29 @@ Stop spending an hour on every quote. Describe the job in plain English, let AI
3838
3939* **Free** — 5 quotes/month, includes AI builder, PDF, email, customer DB
4040* **Pro** ($29/month) — Unlimited quotes, invoice conversion, job tracker, custom branding
41* **Business** (/month) — Everything Pro + multi-user, priority support
41* **Business** ($59/month) — Everything Pro + priority support
42
43== External Services ==
44
45This plugin connects to the following external services:
46
47= Anthropic Claude API =
48
49When you generate a quote, your job description is sent to the Anthropic Claude API to produce line items and pricing suggestions. This requires a Claude API key which you provide yourself in Settings (Bring Your Own Key — your key, your costs, your data).
50
51* Service: Anthropic Claude API
52* Data sent: The job description text you type into the quote builder
53* When: Only when you click "Generate Quote"
54* Privacy policy: https://www.anthropic.com/privacy
55* Terms of service: https://www.anthropic.com/legal/consumer-terms
56
57= Freemius =
58
59This plugin uses Freemius to manage optional paid plan upgrades. Freemius may collect basic site information (site URL, WordPress version, admin email) if you opt in to usage tracking during activation. Opting in is voluntary — the plugin operates fully in free mode without it.
60
61* Service: Freemius
62* Privacy policy: https://freemius.com/privacy/
63* Terms of service: https://freemius.com/terms/
4264
4365== Installation ==
4466
@@ -55,7 +77,7 @@ Yes. TradeQuote AI uses a Bring Your Own Key (BYOK) model so you control your AI
5577
5678= Is my data stored securely? =
5779
58All data is stored in your own WordPress database. Your API key is stored encrypted in WordPress options.
80All customer and quote data is stored in your own WordPress database. Your Claude API key is stored in WordPress options and is only ever transmitted to the Anthropic API.
5981
6082= What countries does it support? =
6183
6284
c comment · e edit title · m merge · a approve · r request changes · ? shortcuts