flowcvcli 0.2.0__py3-none-any.whl
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.
- flowcvcli/__init__.py +8 -0
- flowcvcli/__main__.py +5 -0
- flowcvcli/api.py +29 -0
- flowcvcli/cli.py +335 -0
- flowcvcli/client.py +300 -0
- flowcvcli/config.py +87 -0
- flowcvcli/content.py +168 -0
- flowcvcli/customization.py +85 -0
- flowcvcli/markup.py +53 -0
- flowcvcli/personal.py +66 -0
- flowcvcli/photo.py +95 -0
- flowcvcli/resume.py +122 -0
- flowcvcli-0.2.0.dist-info/METADATA +213 -0
- flowcvcli-0.2.0.dist-info/RECORD +18 -0
- flowcvcli-0.2.0.dist-info/WHEEL +5 -0
- flowcvcli-0.2.0.dist-info/entry_points.txt +2 -0
- flowcvcli-0.2.0.dist-info/licenses/LICENSE +21 -0
- flowcvcli-0.2.0.dist-info/top_level.txt +1 -0
flowcvcli/resume.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""Resume-level operations: listing, create/duplicate/rename/delete, PDF
|
|
2
|
+
download, web-resume publish/status.
|
|
3
|
+
|
|
4
|
+
ResumeMixin is a pure mixin over Client (see client.py): no __init__, all
|
|
5
|
+
state lives on `self`. Write methods return the JSON envelope dict so callers
|
|
6
|
+
can check `env["success"]`.
|
|
7
|
+
"""
|
|
8
|
+
import json
|
|
9
|
+
import uuid
|
|
10
|
+
|
|
11
|
+
# Top-level resume fields that must NOT be copied into a new resume: server
|
|
12
|
+
# regenerates them (unique tokens / timestamps). `id` and `uuid` are reassigned.
|
|
13
|
+
_NEW_RESUME_DROP = ("webToken", "feedbackToken", "createdAt", "updatedAt", "lastChangeAt")
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class ResumeMixin:
|
|
17
|
+
# ---- listing ----------------------------------------------------------
|
|
18
|
+
def list_resumes(self):
|
|
19
|
+
"""GET /resumes/all -> the list of resume summaries. Raises on failure."""
|
|
20
|
+
env = self.request("resumes/all")
|
|
21
|
+
if not env.get("success"):
|
|
22
|
+
raise SystemExit(f"list resumes failed: {env}")
|
|
23
|
+
return env["data"]["resumes"]
|
|
24
|
+
|
|
25
|
+
# ---- create / duplicate / rename / delete -----------------------------
|
|
26
|
+
def _create_from(self, title, keep_content):
|
|
27
|
+
"""Create a new resume by cloning the current one's full object.
|
|
28
|
+
|
|
29
|
+
FlowCV's `create` needs a complete resume object (every NOT-NULL column),
|
|
30
|
+
so we clone the current resume — guaranteeing validity — then reassign a
|
|
31
|
+
fresh id/uuid, drop the unique tokens (server regenerates), and set the
|
|
32
|
+
title. `keep_content=False` makes a blank resume that keeps the same
|
|
33
|
+
identity (personalDetails) and design (customization); `keep_content=True`
|
|
34
|
+
is a full duplicate. Returns the new resume id.
|
|
35
|
+
"""
|
|
36
|
+
src = self.get_resume()
|
|
37
|
+
clone = json.loads(json.dumps(src)) # deep copy
|
|
38
|
+
new_id = str(uuid.uuid4())
|
|
39
|
+
clone["id"] = new_id
|
|
40
|
+
clone["uuid"] = str(uuid.uuid4())
|
|
41
|
+
clone["title"] = title
|
|
42
|
+
for k in _NEW_RESUME_DROP:
|
|
43
|
+
clone.pop(k, None)
|
|
44
|
+
if not keep_content:
|
|
45
|
+
clone["content"] = {}
|
|
46
|
+
env = self.request("resumes/create", method="POST", body={"clientResume": clone})
|
|
47
|
+
if not env.get("success"):
|
|
48
|
+
raise SystemExit(f"create resume failed: {json.dumps(env)[:200]}")
|
|
49
|
+
return new_id
|
|
50
|
+
|
|
51
|
+
def create_resume(self, title):
|
|
52
|
+
"""Create a new, empty resume (same contact details & styling, no content).
|
|
53
|
+
Returns the new resume id."""
|
|
54
|
+
return self._create_from(title, keep_content=False)
|
|
55
|
+
|
|
56
|
+
def duplicate_resume(self, title=None):
|
|
57
|
+
"""Duplicate the current resume (content and all). Returns the new id."""
|
|
58
|
+
if title is None:
|
|
59
|
+
title = (self.get_resume().get("title") or "Resume") + " (copy)"
|
|
60
|
+
return self._create_from(title, keep_content=True)
|
|
61
|
+
|
|
62
|
+
def rename_resume(self, title):
|
|
63
|
+
"""PATCH /resumes/rename_resume — set the resume's title."""
|
|
64
|
+
return self.request("resumes/rename_resume", method="PATCH",
|
|
65
|
+
body={"resumeId": self.resume_id, "resumeTitle": title})
|
|
66
|
+
|
|
67
|
+
def delete_resume(self, resume_id=None):
|
|
68
|
+
"""DELETE /resumes/delete_resume — permanently delete a resume.
|
|
69
|
+
|
|
70
|
+
Defaults to the configured resume; pass an explicit id to delete another.
|
|
71
|
+
Irreversible — the CLI guards this behind --yes.
|
|
72
|
+
"""
|
|
73
|
+
rid = resume_id or self.resume_id
|
|
74
|
+
return self.request("resumes/delete_resume", method="DELETE", query={"resumeId": rid})
|
|
75
|
+
|
|
76
|
+
# ---- PDF --------------------------------------------------------------
|
|
77
|
+
def download_pdf(self, pages=10):
|
|
78
|
+
"""GET /resumes/download -> PDF bytes. Raises unless a 200 + %PDF body."""
|
|
79
|
+
status, raw = self.request_raw(
|
|
80
|
+
"resumes/download",
|
|
81
|
+
query={"resumeId": self.resume_id, "previewPageCount": pages},
|
|
82
|
+
)
|
|
83
|
+
if status != 200 or not raw.startswith(b"%PDF"):
|
|
84
|
+
raise SystemExit(f"download failed: HTTP {status}, {raw[:80]!r}")
|
|
85
|
+
return raw
|
|
86
|
+
|
|
87
|
+
def save_pdf(self, path, pages=10):
|
|
88
|
+
"""Download the resume PDF and write it to `path`; return `path`."""
|
|
89
|
+
with open(path, "wb") as f:
|
|
90
|
+
f.write(self.download_pdf(pages))
|
|
91
|
+
return path
|
|
92
|
+
|
|
93
|
+
def download_public(self, token):
|
|
94
|
+
"""Download ANY public/shared resume's PDF by its web token (no ownership needed)."""
|
|
95
|
+
status, raw = self.request_raw("public/download_resume", query={"token": token})
|
|
96
|
+
if status != 200 or not raw.startswith(b"%PDF"):
|
|
97
|
+
raise SystemExit(f"public download failed: HTTP {status}, {raw[:80]!r}")
|
|
98
|
+
return raw
|
|
99
|
+
|
|
100
|
+
# ---- web resume -------------------------------------------------------
|
|
101
|
+
def publish(self):
|
|
102
|
+
"""PATCH /resumes/publish_web_resume to make the web resume public."""
|
|
103
|
+
return self.request("resumes/publish_web_resume", method="PATCH",
|
|
104
|
+
body={"publish": True, "resumeId": self.resume_id})
|
|
105
|
+
|
|
106
|
+
def unpublish(self):
|
|
107
|
+
"""PATCH /resumes/publish_web_resume to take the web resume offline."""
|
|
108
|
+
return self.request("resumes/publish_web_resume", method="PATCH",
|
|
109
|
+
body={"publish": False, "resumeId": self.resume_id})
|
|
110
|
+
|
|
111
|
+
def web_status(self):
|
|
112
|
+
"""Return {live, url} for the public web resume (url None if no token)."""
|
|
113
|
+
r = self.get_resume()
|
|
114
|
+
token = r.get("webToken")
|
|
115
|
+
return {
|
|
116
|
+
"live": r.get("webResumeLive"),
|
|
117
|
+
"url": "https://flowcv.com/resume/" + token if token else None,
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
def share_url(self):
|
|
121
|
+
"""Return the public web-resume URL (or None if no webToken)."""
|
|
122
|
+
return self.web_status()["url"]
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flowcvcli
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Control a FlowCV resume from the command line or Python — content, design, templates, photo, publish and PDF export — via FlowCV's private JSON API. Zero dependencies.
|
|
5
|
+
Author: dannyota
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/dannyota/flowcvcli
|
|
8
|
+
Project-URL: Repository, https://github.com/dannyota/flowcvcli
|
|
9
|
+
Project-URL: Documentation, https://github.com/dannyota/flowcvcli/blob/main/docs/API.md
|
|
10
|
+
Project-URL: Issues, https://github.com/dannyota/flowcvcli/issues
|
|
11
|
+
Keywords: flowcv,resume,cv,cli,resume-builder,json-api,automation
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Environment :: Console
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
24
|
+
Classifier: Topic :: Office/Business
|
|
25
|
+
Classifier: Topic :: Utilities
|
|
26
|
+
Requires-Python: >=3.8
|
|
27
|
+
Description-Content-Type: text/markdown
|
|
28
|
+
License-File: LICENSE
|
|
29
|
+
Dynamic: license-file
|
|
30
|
+
|
|
31
|
+
# flowcvcli
|
|
32
|
+
|
|
33
|
+
[](https://pypi.org/project/flowcvcli/)
|
|
34
|
+
[](https://pypi.org/project/flowcvcli/)
|
|
35
|
+
[](LICENSE)
|
|
36
|
+
|
|
37
|
+
Control a [FlowCV](https://flowcv.com) resume from the **command line** or from
|
|
38
|
+
**Python** — content, header & links, **customization**, **templates**,
|
|
39
|
+
**avatar**, reorder/hide, multi-resume management, publish, and **PDF export**.
|
|
40
|
+
It drives FlowCV's private JSON API (the same calls the web app makes), so it
|
|
41
|
+
works for any FlowCV resume with your own session. **Zero dependencies** (Python
|
|
42
|
+
standard library only), so it's easy to drop into scripts and LLM agents.
|
|
43
|
+
|
|
44
|
+
> Unofficial and not affiliated with FlowCV. It uses FlowCV's undocumented
|
|
45
|
+
> internal API and may break if that changes; use it with your own account and at
|
|
46
|
+
> your own risk (mind FlowCV's Terms of Service). See [`docs/API.md`](docs/API.md)
|
|
47
|
+
> for the reverse-engineered API and [`docs/RENDERING.md`](docs/RENDERING.md) for
|
|
48
|
+
> how the editor renders the live preview and persists edits.
|
|
49
|
+
|
|
50
|
+
## Install
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
pip install flowcvcli # installs the `flowcv` command
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Or run from source without installing:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
git clone https://github.com/dannyota/flowcvcli && cd flowcvcli
|
|
60
|
+
python3 flowcv.py --help # equivalent to the `flowcv` command
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configure
|
|
64
|
+
|
|
65
|
+
Put a `.env` in the directory you run `flowcv` from (or in
|
|
66
|
+
`~/.config/flowcvcli/.env`). Real environment variables override it.
|
|
67
|
+
|
|
68
|
+
```dotenv
|
|
69
|
+
# Auth — pick ONE:
|
|
70
|
+
FLOWCV_COOKIE=flowcvsidapp=s%3A... # your session cookie, OR
|
|
71
|
+
# FLOWCV_EMAIL=you@example.com # log in with credentials instead
|
|
72
|
+
# FLOWCV_PASSWORD=... # (session cached to ~/.config/flowcvcli/session)
|
|
73
|
+
|
|
74
|
+
# FLOWCV_RESUME_ID=... # optional; only if your account has several resumes
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
- **Cookie**: DevTools → Application → Cookies → `app.flowcv.com` → copy the
|
|
78
|
+
`flowcvsidapp` value. That single cookie is the auth.
|
|
79
|
+
- **Credentials**: with `FLOWCV_EMAIL` + `FLOWCV_PASSWORD` the tool logs in and
|
|
80
|
+
caches the session (re-login is automatic when the cookie expires). The cache
|
|
81
|
+
is written `0600` to `~/.config/flowcvcli/session` (override with
|
|
82
|
+
`$FLOWCV_SESSION_FILE`).
|
|
83
|
+
- **Resume id** is optional: with one resume it's auto-selected; with several,
|
|
84
|
+
set `FLOWCV_RESUME_ID` or pass `--resume-id <id>` (run `flowcv resumes` to list).
|
|
85
|
+
|
|
86
|
+
## CLI
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
flowcv resumes # list resumes (id, title, share token)
|
|
90
|
+
flowcv show [section] # sections + entries (ids, labels, dates)
|
|
91
|
+
flowcv dump <section> <id> # one entry, fields + rich text
|
|
92
|
+
|
|
93
|
+
# manage resumes (multi-resume / paid plans)
|
|
94
|
+
flowcv new "My Second Resume" # new resume (same details+style, no content) -> prints id
|
|
95
|
+
flowcv duplicate ["Copy title"] # full copy of the current resume
|
|
96
|
+
flowcv rename "New Title" # rename the current resume
|
|
97
|
+
flowcv delete-resume --yes # permanent (refuses without --yes)
|
|
98
|
+
|
|
99
|
+
# content (markdown mini-format below); `add` creates the section if needed
|
|
100
|
+
flowcv add work --set title="Engineer" --set company="Acme" \
|
|
101
|
+
--set start=01/2022 --set end=Present --text $'- Did a measurable thing.'
|
|
102
|
+
flowcv desc work <id> --file role.md
|
|
103
|
+
flowcv field work <id> employer --text "Acme Corp"
|
|
104
|
+
flowcv rm work <id>
|
|
105
|
+
|
|
106
|
+
# reorder / hide / sections
|
|
107
|
+
flowcv reorder work <id3> <id1> <id2> # set entry order (all of the section's ids)
|
|
108
|
+
flowcv hide work <id> ; flowcv show-entry work <id>
|
|
109
|
+
flowcv rename-section skill "Core Skills"
|
|
110
|
+
flowcv section-icon skill head-side-brain
|
|
111
|
+
flowcv rm-section custom1 --yes # delete a section + its entries
|
|
112
|
+
flowcv reorder-sections profile work skill education # one-column order
|
|
113
|
+
|
|
114
|
+
# header details & links (links are social entries: orcid, googlescholar, github…)
|
|
115
|
+
flowcv pd jobTitle --text "Security Leader"
|
|
116
|
+
flowcv link orcid ORCID https://orcid.org/0000-0000-0000-0000
|
|
117
|
+
flowcv unlink orcid ; flowcv links
|
|
118
|
+
|
|
119
|
+
# avatar
|
|
120
|
+
flowcv avatar set https://example.com/me.png # upload from URL or file
|
|
121
|
+
flowcv avatar on | off | remove
|
|
122
|
+
|
|
123
|
+
# styling (a delta into resume.customization) and templates
|
|
124
|
+
flowcv customize font.fontFamily "Source Sans Pro"
|
|
125
|
+
flowcv customize colors.basic.single '"#0e374e"'
|
|
126
|
+
flowcv templates # lists each as [free] / [PAID] (paid needs a subscription)
|
|
127
|
+
flowcv apply-template <templateId> # warns first if the template is paid
|
|
128
|
+
|
|
129
|
+
# render & share
|
|
130
|
+
flowcv download -o resume.pdf # the rendered PDF
|
|
131
|
+
flowcv download --token <webToken> -o out.pdf # any PUBLIC resume by its share token (no auth)
|
|
132
|
+
flowcv share | publish | unpublish
|
|
133
|
+
|
|
134
|
+
flowcv login # refresh the cached session
|
|
135
|
+
flowcv md2html --file role.md # preview HTML (offline)
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Any command takes `--resume-id <id>` to target a specific resume. (From source,
|
|
139
|
+
replace `flowcv` with `python3 flowcv.py`.)
|
|
140
|
+
|
|
141
|
+
## Library (for scripts & LLM agents)
|
|
142
|
+
|
|
143
|
+
```python
|
|
144
|
+
from flowcvcli import FlowCV
|
|
145
|
+
|
|
146
|
+
fc = FlowCV() # or FlowCV(resume_id="...")
|
|
147
|
+
fc.set_personal_field("fullName", "Jane Doe")
|
|
148
|
+
fc.add_entry("work", sets={"jobTitle": "Engineer", "employer": "Acme",
|
|
149
|
+
"startDateNew": "01/2022", "endDateNew": "Present"},
|
|
150
|
+
md="- Shipped a thing with **measurable** impact.")
|
|
151
|
+
fc.set("font.fontFamily", "Source Sans Pro") # a customization delta
|
|
152
|
+
fc.set_photo("https://example.com/me.png") # avatar from URL
|
|
153
|
+
fc.apply_template("a3fb6c37-...") # a design from list_templates()
|
|
154
|
+
fc.save_pdf("resume.pdf") # render to PDF
|
|
155
|
+
|
|
156
|
+
# structure & resume management
|
|
157
|
+
fc.reorder_entries("work", ["id3", "id1", "id2"]) # set entry order
|
|
158
|
+
fc.rename_section("skill", "Core Skills"); fc.delete_section("custom1")
|
|
159
|
+
fc.hide_entry("work", "id", hidden=True)
|
|
160
|
+
new_id = fc.create_resume("Second Resume") # or fc.duplicate_resume()
|
|
161
|
+
fc.rename_resume("New Title"); fc.delete_resume() # delete is permanent
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
### Build → render → check → improve
|
|
165
|
+
|
|
166
|
+
The PDF *is* the rendered output. An agent can write content, `save_pdf(...)`,
|
|
167
|
+
**open the PDF to see the actual layout**, then adjust and re-render — a closed
|
|
168
|
+
feedback loop for building a resume from raw info.
|
|
169
|
+
|
|
170
|
+
## Markdown mini-format (`desc` / `add`)
|
|
171
|
+
|
|
172
|
+
| You write | You get |
|
|
173
|
+
|---|---|
|
|
174
|
+
| blank line | block separator |
|
|
175
|
+
| `## Heading` / `**Whole line bold**` | bold subheader |
|
|
176
|
+
| `- item` | bullet (consecutive = one list) |
|
|
177
|
+
| anything else | justified paragraph |
|
|
178
|
+
| `**bold**` inline | `<strong>bold</strong>` |
|
|
179
|
+
|
|
180
|
+
## How it works
|
|
181
|
+
|
|
182
|
+
- **Read-modify-write**: edits fetch the resume, change one part, and send it
|
|
183
|
+
back — unrelated fields are never touched.
|
|
184
|
+
- New entries append to the bottom of their section; use `reorder` to change order.
|
|
185
|
+
- The on-screen preview is client-side HTML; the **PDF download is a separate
|
|
186
|
+
server render** of the same data (details in [`docs/RENDERING.md`](docs/RENDERING.md)).
|
|
187
|
+
|
|
188
|
+
> **Scope:** this tool covers **resumes**. The same FlowCV account also has Cover
|
|
189
|
+
> Letters, Job Tracker, Email Signatures and Personal Websites (separate APIs —
|
|
190
|
+
> see `docs/API.md` "Other FlowCV products"); documented but not implemented here.
|
|
191
|
+
|
|
192
|
+
## Project layout
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
flowcvcli/ # the package (import flowcvcli)
|
|
196
|
+
config.py # resolve resume id + auth from .env / env vars
|
|
197
|
+
client.py # HTTP, login, cookie-jar session, retry, get_resume
|
|
198
|
+
markup.py # markdown <-> FlowCV rich-text HTML
|
|
199
|
+
content.py # sections & entries (add/edit/reorder/hide/sections)
|
|
200
|
+
personal.py # header details & links
|
|
201
|
+
customization.py # styling deltas & templates
|
|
202
|
+
photo.py # avatar upload / toggle
|
|
203
|
+
resume.py # list, create/duplicate/rename/delete, download, publish
|
|
204
|
+
api.py # FlowCV = Client + all mixins
|
|
205
|
+
cli.py / __main__.py # the `flowcv` command
|
|
206
|
+
docs/API.md # reverse-engineered API reference
|
|
207
|
+
docs/RENDERING.md # how the editor renders the preview & debounces saves
|
|
208
|
+
flowcv.py # source-tree entry point (python3 flowcv.py …)
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
## License
|
|
212
|
+
|
|
213
|
+
[MIT](LICENSE) © dannyota
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
flowcvcli/__init__.py,sha256=x-8Y0Y2l1JAsBFthqIMytVGwTs40a2N5Hqtyk7cyJYA,329
|
|
2
|
+
flowcvcli/__main__.py,sha256=vswlkf5GlOpZWRnJCMyo3nxdNHjfpV64MfTlpoyqg6k,140
|
|
3
|
+
flowcvcli/api.py,sha256=fsTgehgjBJjLKVs4l3Ph21M8Yp8kA0-MZIdofv3M3Ho,1335
|
|
4
|
+
flowcvcli/cli.py,sha256=z1quLav3fBlzlQPcuG9udoq-KEcYzecet6QckMG1oaE,12541
|
|
5
|
+
flowcvcli/client.py,sha256=mK6Tn2axUaR2C07aoeSr6Qo5VGl8qB-aoY3h4csqD2g,13130
|
|
6
|
+
flowcvcli/config.py,sha256=EC-et6QjOVwDc7zGK6Dr50uNWJ27iOmqFKjF7_gyR3Q,3246
|
|
7
|
+
flowcvcli/content.py,sha256=hEJWM2OHVa74WBwuS5tYV1p7czEU0Tw0WEA0hBropuc,8123
|
|
8
|
+
flowcvcli/customization.py,sha256=Kz34TZnyzhVT9iN-neRf0I7UMdP4Q2QPOUBZceFvaRo,3869
|
|
9
|
+
flowcvcli/markup.py,sha256=AFGb7YI-kZ_KQgM7qxVHFZ_24dwzv7qZ8SYh3fxrFGU,1785
|
|
10
|
+
flowcvcli/personal.py,sha256=IjXGqOWt7K7ZVoqYZTupe5zhoeWo0La_YiDpQ9JXhJU,2755
|
|
11
|
+
flowcvcli/photo.py,sha256=PERJtjhNKFgYftBsGNBEcokq8yZ0mmVkDiw9AVHLVcs,4088
|
|
12
|
+
flowcvcli/resume.py,sha256=ZpI1gqwXE6y8WW0NVHm5l4cXj9fH2UTnxMqUOFXSg0Q,5564
|
|
13
|
+
flowcvcli-0.2.0.dist-info/licenses/LICENSE,sha256=23m7cKsJg9PqqLZ0wK5RbcEGNAFbSchahsBJ8LGvX0g,1065
|
|
14
|
+
flowcvcli-0.2.0.dist-info/METADATA,sha256=_yRE9G2QHWgy32PVmnSUjovBkYdsU2XGbRbJH0oU6js,9549
|
|
15
|
+
flowcvcli-0.2.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
16
|
+
flowcvcli-0.2.0.dist-info/entry_points.txt,sha256=rS7BgaYFbAad6mzLcqK62k4kMgZ4UeurHj5wT_rgCDk,46
|
|
17
|
+
flowcvcli-0.2.0.dist-info/top_level.txt,sha256=kvOYoW_loF42cvdHgkdKjyCQ-FiYDu1PLhAb40HkBaI,10
|
|
18
|
+
flowcvcli-0.2.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dannyota
|
|
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 @@
|
|
|
1
|
+
flowcvcli
|