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.
- fullscout-0.1.0/LICENSE +21 -0
- fullscout-0.1.0/MANIFEST.in +13 -0
- fullscout-0.1.0/PKG-INFO +357 -0
- fullscout-0.1.0/README.md +329 -0
- fullscout-0.1.0/cli/fullscout/__init__.py +2 -0
- fullscout-0.1.0/cli/fullscout/__main__.py +122 -0
- fullscout-0.1.0/cli/fullscout/http_client.py +66 -0
- fullscout-0.1.0/cli/fullscout/identity.py +88 -0
- fullscout-0.1.0/cli/fullscout/install.py +281 -0
- fullscout-0.1.0/cli/fullscout/outreach.py +67 -0
- fullscout-0.1.0/cli/fullscout/paths.py +31 -0
- fullscout-0.1.0/cli/fullscout/profile.py +58 -0
- fullscout-0.1.0/cli/fullscout/research_contract.py +51 -0
- fullscout-0.1.0/cli/fullscout/skill/SKILL.md +188 -0
- fullscout-0.1.0/cli/fullscout.egg-info/PKG-INFO +357 -0
- fullscout-0.1.0/cli/fullscout.egg-info/SOURCES.txt +20 -0
- fullscout-0.1.0/cli/fullscout.egg-info/dependency_links.txt +1 -0
- fullscout-0.1.0/cli/fullscout.egg-info/entry_points.txt +2 -0
- fullscout-0.1.0/cli/fullscout.egg-info/requires.txt +5 -0
- fullscout-0.1.0/cli/fullscout.egg-info/top_level.txt +1 -0
- fullscout-0.1.0/pyproject.toml +63 -0
- fullscout-0.1.0/setup.cfg +4 -0
fullscout-0.1.0/LICENSE
ADDED
|
@@ -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
|
fullscout-0.1.0/PKG-INFO
ADDED
|
@@ -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.
|