fullscout 0.1.0__tar.gz

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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 75waves
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.
@@ -0,0 +1,13 @@
1
+ include LICENSE
2
+ include README.md
3
+ include cli/fullscout/skill/SKILL.md
4
+
5
+ # The hosted backend is proprietary and must never be published to PyPI.
6
+ prune server
7
+ prune docs
8
+ prune scripts
9
+ prune dist
10
+ prune build
11
+ recursive-exclude * __pycache__
12
+ recursive-exclude * *.py[cod]
13
+ global-exclude .env .env.* *.sqlite3 .DS_Store
@@ -0,0 +1,357 @@
1
+ Metadata-Version: 2.4
2
+ Name: fullscout
3
+ Version: 0.1.0
4
+ Summary: Guided vendor discovery and quote/demo request automation, driven from your AI coding assistant.
5
+ Author: 75waves
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://www.75waves.com/products/fullscout
8
+ Keywords: procurement,vendor,cli,assistant,skill
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Environment :: Console
11
+ Classifier: Intended Audience :: End Users/Desktop
12
+ Classifier: Operating System :: OS Independent
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Classifier: Programming Language :: Python :: 3.13
18
+ Classifier: Topic :: Office/Business
19
+ Classifier: Topic :: Utilities
20
+ Requires-Python: >=3.10
21
+ Description-Content-Type: text/markdown
22
+ License-File: LICENSE
23
+ Provides-Extra: dev
24
+ Requires-Dist: pytest>=8; extra == "dev"
25
+ Requires-Dist: build>=1.2; extra == "dev"
26
+ Requires-Dist: twine>=5.1; extra == "dev"
27
+ Dynamic: license-file
28
+
29
+ # fullscout
30
+
31
+ **Turn your AI coding assistant into a procurement assistant.**
32
+
33
+ Describe what you want to buy in plain language. `fullscout` helps you turn that
34
+ into concrete requirements, researches the market with you, and then submits
35
+ demo and quote requests to the vendors you pick — filling out each vendor's own
36
+ public form and reporting back what happened, vendor by vendor.
37
+
38
+ Buying software normally means the same tedious loop a dozen times: find a
39
+ vendor, hunt for their contact page, retype your name and company, pick a
40
+ company-size band from a dropdown, submit, repeat. `fullscout` collapses that
41
+ loop. You stay in your assistant, describe the problem once, review a scored
42
+ shortlist with evidence links, choose who to contact, confirm exactly what will
43
+ be sent, and the hosted service does the typing.
44
+
45
+ Nothing is ever sent without two explicit confirmations from you, and every
46
+ attempt is reported honestly — including the ones that could not be completed.
47
+
48
+ ```bash
49
+ pip install fullscout
50
+ fullscout install
51
+ ```
52
+
53
+ - **Python:** 3.10, 3.11, 3.12, 3.13
54
+ - **Runtime dependencies:** none — the client uses only the standard library
55
+ - **Platforms:** macOS, Linux, Windows
56
+ - **License:** MIT (this client), see [Open core](#open-core)
57
+
58
+ ## Quick start
59
+
60
+ Install the package and register the skill with your assistant:
61
+
62
+ ```console
63
+ $ pip install fullscout
64
+ $ fullscout install
65
+ {
66
+ "installed": [
67
+ "/Users/you/.codex/AGENTS.md",
68
+ "/Users/you/.claude/skills/fullscout/SKILL.md",
69
+ "/Users/you/.claude/skills/helpme/SKILL.md",
70
+ "/Users/you/.claude/skills/musthave/SKILL.md",
71
+ "/Users/you/.claude/skills/nicetohave/SKILL.md",
72
+ "/Users/you/.gemini/GEMINI.md"
73
+ ],
74
+ "skill": [
75
+ "/Users/you/.fullscout/skill/SKILL.md"
76
+ ]
77
+ }
78
+ ```
79
+
80
+ With no `--platform`, every supported assistant is set up at once. Then just
81
+ say what you need:
82
+
83
+ ```text
84
+ We need a webinar platform for a 200-person marketing team
85
+ ```
86
+
87
+ The assistant recognises this as a purchase and takes it from there, asking
88
+ what your hard requirements are and what would merely be nice. On Claude you
89
+ can also steer the list directly:
90
+
91
+ ```text
92
+ /helpme I need a webinar platform for a 200-person marketing team
93
+ /musthave supports at least 1,000 registrants
94
+ /nicetohave automated reminder emails
95
+ ```
96
+
97
+ Your assistant handles the rest: it sharpens the requirements, researches
98
+ vendors, presents a shortlist, and asks you to confirm before anything is sent.
99
+ See [Assistant support](#assistant-support) for what differs between assistants.
100
+
101
+ ## How it works
102
+
103
+ 1. **Capture** — Vague requirements get sorted into must-haves, nice-to-haves,
104
+ deal-breakers, and open questions. Fuzzy words like "cheap" or "enterprise
105
+ grade" become numbers you confirm.
106
+ 2. **Research** — Your assistant searches the live web and returns a scored
107
+ vendor shortlist with evidence links, must-have gaps, and confidence ratings.
108
+ 3. **Select** — You choose which vendors to pursue. Never all of them by default.
109
+ 4. **Confirm** — You review the exact details that will be sent: name, email,
110
+ company, company size, and location where a form needs it.
111
+ 5. **Submit** — The hosted service opens each vendor's public demo or quote
112
+ form, maps your approved values onto it, submits, and reports the outcome.
113
+
114
+ Both the vendor selection and the detail confirmation are required. Nothing is
115
+ sent without them, and an approval older than 15 minutes is rejected — so a
116
+ stale conversation cannot quietly submit on your behalf.
117
+
118
+ ## Features
119
+
120
+ - **Requirement capture that pushes back**
121
+ - Sorts free-form description into must-haves, nice-to-haves, deal-breakers
122
+ - Proposes concrete thresholds for vague terms and asks you to confirm them
123
+ - Surfaces the questions you have not answered yet
124
+ - **Vendor research with evidence**
125
+ - Returns 4–8 candidates rather than an unfiltered list
126
+ - Each candidate carries a fit score, evidence URLs, and a confidence rating
127
+ - Names the must-haves a vendor does *not* meet, instead of hiding them
128
+ - **Explicit, two-step consent**
129
+ - Vendor selection and detail confirmation are separate, and both mandatory
130
+ - Authorizations expire after 15 minutes
131
+ - The server re-checks both before anything is submitted
132
+ - **Honest outcome reporting**
133
+ - Every vendor gets a status, not a summary
134
+ - Obstacles are named — captcha, login wall, missing form — never worked around
135
+ - Failed submissions are reported as failures, never as successes
136
+ - **Local-first identity**
137
+ - No signup, password, or API key
138
+ - A local install ID is exchanged for a service token on first use
139
+ - Your details live in `~/.fullscout/`, readable only by you
140
+ - **Works across assistants**
141
+ - Claude gets native skills and dedicated `/helpme`, `/musthave`, `/nicetohave`
142
+ - Codex and Gemini get a short block in the instruction file they already read
143
+ - One skill file behind both, so behaviour does not drift between assistants
144
+ - **No dependency footprint**
145
+ - Zero runtime dependencies; nothing to conflict with your project
146
+ - Talks to the service over standard-library HTTP
147
+
148
+ ## Assistant support
149
+
150
+ `fullscout install` registers the skill wherever your assistant will actually
151
+ find it. What that means differs by assistant, because their extension models
152
+ differ.
153
+
154
+ | Assistant | Installed to | How you invoke it |
155
+ | --- | --- | --- |
156
+ | Claude | `~/.claude/skills/{fullscout,helpme,musthave,nicetohave}/SKILL.md` | Dedicated `/helpme`, `/musthave`, `/nicetohave` commands, or just describe the purchase |
157
+ | Codex | `~/.codex/AGENTS.md` | Describe the purchase in plain language |
158
+ | Gemini | `~/.gemini/GEMINI.md` | Describe the purchase in plain language |
159
+
160
+ **On Claude**, the three commands are registered skills. `/musthave` always
161
+ writes to hard requirements and `/nicetohave` always writes to preferences, so
162
+ you can steer the requirement list precisely.
163
+
164
+ **On Codex and Gemini** there is no slash-command mechanism to register. Instead
165
+ the assistant is told to gather the same information by asking you: what the
166
+ purchase must do, what would merely be welcome, and what any vague term
167
+ actually means in numbers. You end up with the same must-have and nice-to-have
168
+ lists, built through conversation rather than commands.
169
+
170
+ Either way you can simply say what you need — "we need a webinar platform for
171
+ 200 people" — and the assistant picks it up from there. The slash commands are
172
+ a precision tool, not the entry point.
173
+
174
+ ### How the non-Claude install works
175
+
176
+ `AGENTS.md` and `GEMINI.md` are files you own and may already have written in,
177
+ and their contents are sent to the model with *every* prompt. So `fullscout`
178
+ does two things:
179
+
180
+ - It writes only a fenced block, leaving the rest of your file untouched:
181
+
182
+ ```markdown
183
+ <!-- BEGIN fullscout (installed by the fullscout CLI) -->
184
+ ...
185
+ <!-- END fullscout -->
186
+ ```
187
+
188
+ Reinstalling refreshes that block. `fullscout uninstall` removes it and
189
+ nothing else. Content you wrote is never rewritten or dropped.
190
+
191
+ - The block is a short pointer — roughly 300 tokens — not the whole workflow.
192
+ It describes when the skill applies and where the full instructions live
193
+ (`~/.fullscout/skill/SKILL.md`, written at install time). The full workflow is
194
+ read only when a query actually looks like procurement, so unrelated work
195
+ does not pay for it on every request.
196
+
197
+ ## Command reference
198
+
199
+ ```bash
200
+ fullscout install [--platform claude|codex|gemini]
201
+ fullscout uninstall [--platform claude|codex|gemini]
202
+ fullscout install-status
203
+
204
+ fullscout identity status
205
+ fullscout identity reset
206
+
207
+ fullscout config show
208
+ fullscout config set-api-url <url>
209
+
210
+ fullscout profile show
211
+ fullscout profile save --json '<profile-json>'
212
+ fullscout profile clear
213
+
214
+ fullscout outreach --run-json '<run-json>' [--no-wait] [--timeout 600]
215
+ fullscout outreach-status --job-id <job-id>
216
+ ```
217
+
218
+ Every command prints JSON, so output pipes cleanly into `jq` or a script.
219
+
220
+ ### Identity
221
+
222
+ There is no account to create. `fullscout install` generates a local install
223
+ ID; the first API call exchanges it for an opaque service token used for run
224
+ ownership, audit logs, and rate limits.
225
+
226
+ ```console
227
+ $ fullscout identity status
228
+ {
229
+ "api_base_url": "https://fullscout.75waves.com",
230
+ "config_dir": "/Users/you/.fullscout",
231
+ "config_path": "/Users/you/.fullscout/config.json",
232
+ "has_server_token": false,
233
+ "install_id": "ddfc4744-e420-49cc-a813-94cbcd06ad01"
234
+ }
235
+ ```
236
+
237
+ `fullscout identity reset` discards the local identity and starts fresh.
238
+
239
+ ### Profile
240
+
241
+ The contact details that get typed into vendor forms.
242
+
243
+ ```console
244
+ $ fullscout profile save --json '{"first_name":"Ada","last_name":"Lovelace","email":"ada@example.com","company":"Analytical Engines","company_size":"11-50","city":"London","state":"","zip":"NW1"}'
245
+ {
246
+ "city": "London",
247
+ "company": "Analytical Engines",
248
+ "company_size": "11-50",
249
+ "email": "ada@example.com",
250
+ "first_name": "Ada",
251
+ "last_name": "Lovelace",
252
+ "state": "",
253
+ "zip": "NW1"
254
+ }
255
+
256
+ $ fullscout profile clear
257
+ $ fullscout profile show
258
+ {}
259
+ ```
260
+
261
+ ### Outreach
262
+
263
+ `fullscout outreach` takes one JSON object. Your assistant normally builds it,
264
+ but the contract is public and validated client-side before any network call:
265
+
266
+ | Field | Required | Contents |
267
+ | --- | --- | --- |
268
+ | `criteria` | yes | `MustHaves`, `NiceToHaves`, `DealBreakers`, `Unknowns` |
269
+ | `selected_vendors` | yes | non-empty list; see below |
270
+ | `profile` | yes | the contact details you confirmed |
271
+ | `user_authorization` | yes | consent flags plus a fresh timestamp |
272
+ | `assistant_metadata` | no | which assistant produced the run |
273
+
274
+ Each vendor must carry `vendor_name`, `homepage_url`, `contact_url`,
275
+ `evidence_urls`, `score`, `fit_summary`, `must_have_gaps`, and `confidence`.
276
+
277
+ `user_authorization` must set `vendors_selected`,
278
+ `vendor_selection_next_clicked`, `profile_validated`, and
279
+ `submit_requests_clicked` all to `true`, plus a timezone-aware `authorized_at`
280
+ no older than 15 minutes.
281
+
282
+ Validation happens before anything leaves your machine:
283
+
284
+ ```console
285
+ $ fullscout outreach --run-json '{}'
286
+ error: Missing run payload field: criteria
287
+ ```
288
+
289
+ By default the command waits for results and returns them per vendor.
290
+ `--no-wait` returns as soon as the batch is queued; poll with
291
+ `fullscout outreach-status --job-id <id>`.
292
+
293
+ ## Configuration
294
+
295
+ | Variable | Default | Purpose |
296
+ | --- | --- | --- |
297
+ | `FULLSCOUT_CONFIG_DIR` | `~/.fullscout` | Where local state is written |
298
+ | `FULLSCOUT_API_BASE_URL` | the hosted service | Point the client elsewhere |
299
+
300
+ | File | Contents |
301
+ | --- | --- |
302
+ | `~/.fullscout/config.json` | install ID, service token, API base URL |
303
+ | `~/.fullscout/profile.json` | your saved contact details |
304
+ | `~/.fullscout/skill/SKILL.md` | the full workflow, loaded on demand |
305
+
306
+ Both files are written with `0600` permissions — readable only by your user.
307
+ `fullscout config set-api-url` persists an endpoint change, which is how you
308
+ point the client at your own deployment.
309
+
310
+ ## What it works with
311
+
312
+ `fullscout` submits public, unauthenticated demo, quote, and contact-sales
313
+ forms that ask for ordinary business contact details. It does not work with
314
+ every vendor site, and does not pretend to.
315
+
316
+ A vendor is reported as `submitted` only when the form was actually sent and
317
+ the vendor's page acknowledged it. Anything else names the obstacle:
318
+
319
+ | Result | Meaning |
320
+ | --- | --- |
321
+ | `submitted` | Sent and acknowledged. Expect a reply by email. |
322
+ | `captcha_required` | Bot challenge on the page. Submit this one yourself. |
323
+ | `login_required` | The form needs an account. |
324
+ | `form_not_found` | No usable form at that URL. |
325
+ | `unsupported_form` | A required field was sensitive or couldn't be matched. |
326
+ | `blocked_url` | The URL failed safety checks. |
327
+ | `failed` | Load error, or the site rejected the submission. |
328
+
329
+ Captcha, login walls, and anti-automation measures are treated as hard stops.
330
+ They are never worked around.
331
+
332
+ ## Your data
333
+
334
+ - Only the details you confirm on screen are ever sent to a vendor.
335
+ - Sensitive fields — passwords, payment details, government IDs — are never
336
+ filled. A form requiring one is refused rather than partially completed.
337
+ - Contact details held by the service are encrypted at rest with AES-256-GCM.
338
+ To request deletion, email privacy@75waves.com.
339
+ - Every submission attempt is logged so you can audit what was sent where.
340
+ - Page content and your own profile values are treated as data, never as
341
+ instructions to the assistant.
342
+
343
+ ## Open core
344
+
345
+ This package is the client, and it is open source under the MIT license. It is
346
+ a thin wrapper: it stores a local identity, validates your input, and calls the
347
+ hosted 75waves service that performs the outreach. That hosted service is a
348
+ separate, proprietary product and is not distributed here.
349
+
350
+ Practically, that means you can read every line of what runs on your machine,
351
+ fork it, or write your own client against the same endpoints. The client knows
352
+ how to call the service and nothing about how outreach is actually carried out.
353
+
354
+ ## License
355
+
356
+ MIT. The full text ships inside the package as `LICENSE`, and PyPI shows the
357
+ license in the sidebar of this page.