withfeedback 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,304 @@
1
+ local_password.txt
2
+ AGENTS-local.md
3
+ dev.sh
4
+ /media/*
5
+ ### VisualStudioCode template
6
+ .vscode/*
7
+
8
+
9
+ # Local History for Visual Studio Code
10
+ .history/
11
+
12
+ # Built Visual Studio Code Extensions
13
+ *.vsix
14
+
15
+ ### JetBrains template
16
+ # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
17
+ # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
18
+ .idea/*
19
+
20
+ # Gradle and Maven with auto-import
21
+ # When using Gradle or Maven with auto-import, you should exclude module files,
22
+ # since they will be recreated, and may cause churn. Uncomment if using
23
+ # auto-import.
24
+ # .idea/artifacts
25
+ # .idea/compiler.xml
26
+ # .idea/jarRepositories.xml
27
+ # .idea/modules.xml
28
+ # .idea/*.iml
29
+ # .idea/modules
30
+ # *.iml
31
+ # *.ipr
32
+
33
+ # CMake
34
+ cmake-build-*/
35
+
36
+ # Mongo Explorer plugin
37
+ .idea/**/mongoSettings.xml
38
+
39
+ # File-based project format
40
+ *.iws
41
+
42
+ # IntelliJ
43
+ out/
44
+
45
+ # mpeltonen/sbt-idea plugin
46
+ .idea_modules/
47
+
48
+ # JIRA plugin
49
+ atlassian-ide-plugin.xml
50
+
51
+ # Cursive Clojure plugin
52
+ .idea/replstate.xml
53
+
54
+ # SonarLint plugin
55
+ .idea/sonarlint/
56
+
57
+ # Crashlytics plugin (for Android Studio and IntelliJ)
58
+ com_crashlytics_export_strings.xml
59
+ crashlytics.properties
60
+ crashlytics-build.properties
61
+ fabric.properties
62
+
63
+ # Editor-based Rest Client
64
+ .idea/httpRequests
65
+
66
+ # Android studio 3.1+ serialized cache file
67
+ .idea/caches/build_file_checksums.ser
68
+
69
+ ### Linux template
70
+ *~
71
+
72
+ # temporary files which can be created if a process still has a handle open of a deleted file
73
+ .fuse_hidden*
74
+
75
+ # KDE directory preferences
76
+ .directory
77
+
78
+ # Linux trash folder which might appear on any partition or disk
79
+ .Trash-*
80
+
81
+ # .nfs files are created when an open file is removed but is still being accessed
82
+ .nfs*
83
+
84
+ ### Windows template
85
+ # Windows thumbnail cache files
86
+ Thumbs.db
87
+ Thumbs.db:encryptable
88
+ ehthumbs.db
89
+ ehthumbs_vista.db
90
+
91
+ # Dump file
92
+ *.stackdump
93
+
94
+ # Folder config file
95
+ [Dd]esktop.ini
96
+
97
+ # Recycle Bin used on file shares
98
+ $RECYCLE.BIN/
99
+
100
+ # Windows Installer files
101
+ *.cab
102
+ *.msi
103
+ *.msix
104
+ *.msm
105
+ *.msp
106
+
107
+ # Windows shortcuts
108
+ *.lnk
109
+
110
+ ### macOS template
111
+ # General
112
+ .DS_Store
113
+ .AppleDouble
114
+ .LSOverride
115
+
116
+ # Icon must end with two \r
117
+ Icon
118
+
119
+ # Thumbnails
120
+ ._*
121
+
122
+ # Files that might appear in the root of a volume
123
+ .DocumentRevisions-V100
124
+ .fseventsd
125
+ .Spotlight-V100
126
+ .TemporaryItems
127
+ .Trashes
128
+ .VolumeIcon.icns
129
+ .com.apple.timemachine.donotpresent
130
+
131
+ # Directories potentially created on remote AFP share
132
+ .AppleDB
133
+ .AppleDesktop
134
+ Network Trash Folder
135
+ Temporary Items
136
+ .apdisk
137
+
138
+ ### Python template
139
+ # Byte-compiled / optimized / DLL files
140
+ __pycache__/
141
+ *.py[cod]
142
+ *$py.class
143
+
144
+ # C extensions
145
+ *.so
146
+
147
+ # Distribution / packaging
148
+ .Python
149
+ build/
150
+ develop-eggs/
151
+ dist/
152
+ downloads/
153
+ eggs/
154
+ .eggs/
155
+ lib/
156
+ lib64/
157
+ parts/
158
+ sdist/
159
+ var/
160
+ wheels/
161
+ share/python-wheels/
162
+ *.egg-info/
163
+ .installed.cfg
164
+ *.egg
165
+ MANIFEST
166
+
167
+ # PyInstaller
168
+ # Usually these files are written by a python script from a template
169
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
170
+ *.manifest
171
+ *.spec
172
+
173
+ # Installer logs
174
+ pip-log.txt
175
+ pip-delete-this-directory.txt
176
+
177
+ # Unit test / coverage reports
178
+ htmlcov/
179
+ .tox/
180
+ .nox/
181
+ .coverage
182
+ .coverage.*
183
+ .cache
184
+ nosetests.xml
185
+ coverage.xml
186
+ *.cover
187
+ *.py,cover
188
+ .hypothesis/
189
+ .pytest_cache/
190
+ cover/
191
+
192
+ # Translations
193
+ *.mo
194
+ *.pot
195
+
196
+ # Django stuff:
197
+ *.log
198
+ local_settings.py
199
+ db.sqlite3
200
+ db.sqlite3-journal
201
+
202
+ # Flask stuff:
203
+ instance/
204
+ .webassets-cache
205
+
206
+ # Scrapy stuff:
207
+ .scrapy
208
+
209
+ # Sphinx documentation
210
+ docs/_build/
211
+
212
+ # PyBuilder
213
+ .pybuilder/
214
+ target/
215
+
216
+ # Jupyter Notebook
217
+ .ipynb_checkpoints
218
+
219
+ # IPython
220
+ profile_default/
221
+ ipython_config.py
222
+
223
+ # pyenv
224
+ # For a library or package, you might want to ignore these files since the code is
225
+ # intended to run in multiple environments; otherwise, check them in:
226
+ # .python-version
227
+
228
+ # pipenv
229
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
230
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
231
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
232
+ # install all needed dependencies.
233
+ #Pipfile.lock
234
+
235
+ # poetry
236
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
237
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
238
+ # commonly ignored for libraries.
239
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
240
+ #poetry.lock
241
+
242
+ # pdm
243
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
244
+ #pdm.lock
245
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
246
+ # in version control.
247
+ # https://pdm.fming.dev/#use-with-ide
248
+ .pdm.toml
249
+
250
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
251
+ __pypackages__/
252
+
253
+ # Celery stuff
254
+ celerybeat-schedule
255
+ celerybeat.pid
256
+
257
+ # SageMath parsed files
258
+ *.sage.py
259
+
260
+ # Environments
261
+ .env
262
+ .venv
263
+ env/
264
+ venv/
265
+ ENV/
266
+ env.bak/
267
+ venv.bak/
268
+
269
+ # Spyder project settings
270
+ .spyderproject
271
+ .spyproject
272
+
273
+ # Rope project settings
274
+ .ropeproject
275
+
276
+ # mkdocs documentation
277
+ /site
278
+
279
+ # mypy
280
+ .mypy_cache/
281
+ .dmypy.json
282
+ dmypy.json
283
+
284
+ # Pyre type checker
285
+ .pyre/
286
+
287
+ # pytype static type analyzer
288
+ .pytype/
289
+
290
+ # Cython debug symbols
291
+ cython_debug/
292
+
293
+ # PyCharm
294
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
295
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
296
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
297
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
298
+ #.idea/
299
+
300
+ /env/
301
+ /tailwindcss
302
+
303
+ node_modules/
304
+ /staticfiles/*
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.5
2
+ Name: withfeedback
3
+ Version: 0.1.0
4
+ Summary: Command-line client for withfeedback.com — testimonials, feedback moderation, imports, widgets, and NPS
5
+ Project-URL: Homepage, https://withfeedback.com
6
+ Project-URL: Documentation, https://withfeedback.com/api/docs/
7
+ License: MIT
8
+ Keywords: cli,feedback,testimonials,withfeedback
9
+ Requires-Python: >=3.10
10
+ Requires-Dist: click>=8.1
11
+ Requires-Dist: httpx>=0.27
12
+ Requires-Dist: keyring>=24
13
+ Description-Content-Type: text/markdown
14
+
15
+ # withfeedback CLI
16
+
17
+ Command-line client for [withfeedback.com](https://withfeedback.com):
18
+ testimonials, feedback moderation, CSV imports, surveys, NPS, widgets, and
19
+ quota usage — from your terminal or CI.
20
+
21
+ ## Install
22
+
23
+ ```bash
24
+ pip install withfeedback
25
+ # or run without installing:
26
+ uvx withfeedback --help
27
+ ```
28
+
29
+ The console command is `withfeedback`.
30
+
31
+ ## Quick start with a personal access token (PAT)
32
+
33
+ Good for CI and quick scripting:
34
+
35
+ 1. Log in at your withfeedback.com instance and open **Account → API Tokens**
36
+ (`/accounts/tokens/`).
37
+ 2. Create a token with the scopes you need (see the table below).
38
+ 3. Either export it per-shell:
39
+
40
+ ```bash
41
+ export WITHFEEDBACK_TOKEN=spd_abc123...
42
+ withfeedback testimonials list --team <TEAM_ID> --project <PROJECT_ID>
43
+ ```
44
+
45
+ or persist it in the OS keychain:
46
+
47
+ ```bash
48
+ withfeedback login --token spd_abc123...
49
+ ```
50
+
51
+ API access requires a plan that includes the API/CLI/MCP feature (Pro and
52
+ above).
53
+
54
+ ## Login via OAuth2 device flow (interactive)
55
+
56
+ ```bash
57
+ withfeedback login
58
+ ```
59
+
60
+ No flags needed against withfeedback.com — the CLI defaults to the official
61
+ public client id `7yQMsnY2Is2f5tCuwwgItoQu3fRkEX2wnzIRj0Vh` (public by
62
+ design — device-flow clients carry no secret). For a self-hosted instance
63
+ pass your own client:
64
+
65
+ ```bash
66
+ withfeedback login --client-id <CLIENT_ID> # or WITHFEEDBACK_CLIENT_ID
67
+ ```
68
+
69
+ What happens:
70
+
71
+ 1. The CLI calls `POST /o/device-authorization/` and prints a verification
72
+ URL plus a short code (it also tries to open your browser).
73
+ 2. You open the URL, enter the code, and approve the requested scopes.
74
+ 3. The CLI polls `POST /o/token/` until you approve, then stores the access
75
+ and refresh tokens in the **OS keychain** via `keyring` (macOS Keychain,
76
+ Windows Credential Locker, Secret Service/KWallet on Linux) — never in a
77
+ plaintext file.
78
+
79
+ When an access token expires, the CLI transparently refreshes it. Refresh
80
+ tokens rotate on every use; the rotated token replaces the stored one.
81
+ (Stored PATs are never "refreshed" — if a PAT is rejected, the CLI tells you
82
+ to create a new one and run `withfeedback login --token` again.)
83
+
84
+ ```bash
85
+ withfeedback logout # remove stored tokens from the keychain
86
+ ```
87
+
88
+ Token resolution precedence for every command:
89
+ `--token` flag > `WITHFEEDBACK_TOKEN` env var > OS keychain.
90
+
91
+ ## Commands
92
+
93
+ ```bash
94
+ withfeedback login [--client-id <ID> | --token <PAT>]
95
+ withfeedback logout
96
+
97
+ withfeedback testimonials list --team <ID> --project <ID> [--status pending|approved|rejected|spam] [--rating N] [--q text] [--json]
98
+ withfeedback testimonials approve <SUBMISSION_ID> --team <ID> [--json]
99
+ withfeedback testimonials reject <SUBMISSION_ID> --team <ID> [--json]
100
+ withfeedback testimonials create --team <ID> --project <ID> --text "..." [--rating N] [--name ..] [--email ..] [--title ..] [--company ..] [--consent] [--tag t]... [--json]
101
+
102
+ withfeedback import csv FILE --team <ID> --project <ID> --text-col COL [--rating-col COL] [--name-col COL] [--email-col COL] [--consent] [--json]
103
+
104
+ withfeedback surveys list --team <ID> --project <ID> [--json]
105
+ withfeedback nps summary --team <ID> --project <ID> [--json]
106
+ withfeedback widgets list --team <ID> --project <ID> [--json]
107
+ withfeedback usage --team <ID> [--json]
108
+ ```
109
+
110
+ Human output is plain text tables. Pass `--json` for machine-readable output
111
+ (raw API responses) — errors still go to stderr.
112
+
113
+ ### CSV import
114
+
115
+ `withfeedback import csv` validates the file locally (header columns, row
116
+ count), builds the column mapping from your `--*-col` options, and uploads
117
+ the file to the server's multipart import endpoint. Rows are processed
118
+ asynchronously and land as **pending** submissions; the command prints the
119
+ batch id and a status URL to poll.
120
+
121
+ ```bash
122
+ withfeedback import csv reviews.csv \
123
+ --team <TEAM_ID> --project <PROJECT_ID> \
124
+ --text-col "Testimonial" --rating-col "Stars" \
125
+ --name-col "Author" --email-col "Email" --consent
126
+ ```
127
+
128
+ Pass `--consent` only when display consent was actually collected for these
129
+ rows.
130
+
131
+ ## Required scopes per command
132
+
133
+ | Command | Required scope |
134
+ |---|---|
135
+ | `testimonials list` | `read:feedback` (or `read:testimonials`) |
136
+ | `testimonials approve` / `reject` | `moderate:submissions` (`write:*` cannot moderate) |
137
+ | `testimonials create` | `write:testimonials` (or `write:feedback`) |
138
+ | `import csv` | `write:feedback` |
139
+ | `surveys list`, `nps summary` | `read:surveys` |
140
+ | `widgets list` | `read:widgets` |
141
+ | `usage` | `read:feedback` |
142
+
143
+ ## Exit codes
144
+
145
+ | Code | Meaning |
146
+ |---|---|
147
+ | 0 | Success |
148
+ | 1 | General / unknown error |
149
+ | 2 | Usage / config error (bad flags, unreadable CSV, missing column) |
150
+ | 3 | Auth error (not logged in, invalid or expired token) |
151
+ | 4 | Forbidden or payment required (missing scope/role, plan without API access, quota exceeded, billing blocked) |
152
+ | 5 | Not found (unknown team/project/object or no access) |
153
+ | 6 | Validation error or invalid state transition |
154
+ | 7 | Network error (server unreachable) |
155
+
156
+ On API errors the API's error detail is printed to stderr.
157
+
158
+ ## Environment variables
159
+
160
+ | Variable | Default | Purpose |
161
+ |---|---|---|
162
+ | `WITHFEEDBACK_API_URL` | `https://withfeedback.com` | API base URL (self-hosted/staging override) |
163
+ | `WITHFEEDBACK_TOKEN` | — | PAT (beats the keychain, loses to `--token`) |
164
+ | `WITHFEEDBACK_CLIENT_ID` | official public client id | Client id for `login` (override for self-hosted) |
165
+ | `WITHFEEDBACK_SCOPES` | all CLI scopes | Scopes requested during device-flow login |
166
+
167
+ On the first request of a run the CLI checks `GET /.well-known/speedpy.json`
168
+ once and warns (never fails) when the manifest is unreachable or the API is
169
+ older than the minimum this client expects.
170
+
171
+ ## Development
172
+
173
+ ```bash
174
+ uv run --with pytest --with httpx --with click --with keyring pytest packages/withfeedback-cli/
175
+ ```
@@ -0,0 +1,161 @@
1
+ # withfeedback CLI
2
+
3
+ Command-line client for [withfeedback.com](https://withfeedback.com):
4
+ testimonials, feedback moderation, CSV imports, surveys, NPS, widgets, and
5
+ quota usage — from your terminal or CI.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ pip install withfeedback
11
+ # or run without installing:
12
+ uvx withfeedback --help
13
+ ```
14
+
15
+ The console command is `withfeedback`.
16
+
17
+ ## Quick start with a personal access token (PAT)
18
+
19
+ Good for CI and quick scripting:
20
+
21
+ 1. Log in at your withfeedback.com instance and open **Account → API Tokens**
22
+ (`/accounts/tokens/`).
23
+ 2. Create a token with the scopes you need (see the table below).
24
+ 3. Either export it per-shell:
25
+
26
+ ```bash
27
+ export WITHFEEDBACK_TOKEN=spd_abc123...
28
+ withfeedback testimonials list --team <TEAM_ID> --project <PROJECT_ID>
29
+ ```
30
+
31
+ or persist it in the OS keychain:
32
+
33
+ ```bash
34
+ withfeedback login --token spd_abc123...
35
+ ```
36
+
37
+ API access requires a plan that includes the API/CLI/MCP feature (Pro and
38
+ above).
39
+
40
+ ## Login via OAuth2 device flow (interactive)
41
+
42
+ ```bash
43
+ withfeedback login
44
+ ```
45
+
46
+ No flags needed against withfeedback.com — the CLI defaults to the official
47
+ public client id `7yQMsnY2Is2f5tCuwwgItoQu3fRkEX2wnzIRj0Vh` (public by
48
+ design — device-flow clients carry no secret). For a self-hosted instance
49
+ pass your own client:
50
+
51
+ ```bash
52
+ withfeedback login --client-id <CLIENT_ID> # or WITHFEEDBACK_CLIENT_ID
53
+ ```
54
+
55
+ What happens:
56
+
57
+ 1. The CLI calls `POST /o/device-authorization/` and prints a verification
58
+ URL plus a short code (it also tries to open your browser).
59
+ 2. You open the URL, enter the code, and approve the requested scopes.
60
+ 3. The CLI polls `POST /o/token/` until you approve, then stores the access
61
+ and refresh tokens in the **OS keychain** via `keyring` (macOS Keychain,
62
+ Windows Credential Locker, Secret Service/KWallet on Linux) — never in a
63
+ plaintext file.
64
+
65
+ When an access token expires, the CLI transparently refreshes it. Refresh
66
+ tokens rotate on every use; the rotated token replaces the stored one.
67
+ (Stored PATs are never "refreshed" — if a PAT is rejected, the CLI tells you
68
+ to create a new one and run `withfeedback login --token` again.)
69
+
70
+ ```bash
71
+ withfeedback logout # remove stored tokens from the keychain
72
+ ```
73
+
74
+ Token resolution precedence for every command:
75
+ `--token` flag > `WITHFEEDBACK_TOKEN` env var > OS keychain.
76
+
77
+ ## Commands
78
+
79
+ ```bash
80
+ withfeedback login [--client-id <ID> | --token <PAT>]
81
+ withfeedback logout
82
+
83
+ withfeedback testimonials list --team <ID> --project <ID> [--status pending|approved|rejected|spam] [--rating N] [--q text] [--json]
84
+ withfeedback testimonials approve <SUBMISSION_ID> --team <ID> [--json]
85
+ withfeedback testimonials reject <SUBMISSION_ID> --team <ID> [--json]
86
+ withfeedback testimonials create --team <ID> --project <ID> --text "..." [--rating N] [--name ..] [--email ..] [--title ..] [--company ..] [--consent] [--tag t]... [--json]
87
+
88
+ withfeedback import csv FILE --team <ID> --project <ID> --text-col COL [--rating-col COL] [--name-col COL] [--email-col COL] [--consent] [--json]
89
+
90
+ withfeedback surveys list --team <ID> --project <ID> [--json]
91
+ withfeedback nps summary --team <ID> --project <ID> [--json]
92
+ withfeedback widgets list --team <ID> --project <ID> [--json]
93
+ withfeedback usage --team <ID> [--json]
94
+ ```
95
+
96
+ Human output is plain text tables. Pass `--json` for machine-readable output
97
+ (raw API responses) — errors still go to stderr.
98
+
99
+ ### CSV import
100
+
101
+ `withfeedback import csv` validates the file locally (header columns, row
102
+ count), builds the column mapping from your `--*-col` options, and uploads
103
+ the file to the server's multipart import endpoint. Rows are processed
104
+ asynchronously and land as **pending** submissions; the command prints the
105
+ batch id and a status URL to poll.
106
+
107
+ ```bash
108
+ withfeedback import csv reviews.csv \
109
+ --team <TEAM_ID> --project <PROJECT_ID> \
110
+ --text-col "Testimonial" --rating-col "Stars" \
111
+ --name-col "Author" --email-col "Email" --consent
112
+ ```
113
+
114
+ Pass `--consent` only when display consent was actually collected for these
115
+ rows.
116
+
117
+ ## Required scopes per command
118
+
119
+ | Command | Required scope |
120
+ |---|---|
121
+ | `testimonials list` | `read:feedback` (or `read:testimonials`) |
122
+ | `testimonials approve` / `reject` | `moderate:submissions` (`write:*` cannot moderate) |
123
+ | `testimonials create` | `write:testimonials` (or `write:feedback`) |
124
+ | `import csv` | `write:feedback` |
125
+ | `surveys list`, `nps summary` | `read:surveys` |
126
+ | `widgets list` | `read:widgets` |
127
+ | `usage` | `read:feedback` |
128
+
129
+ ## Exit codes
130
+
131
+ | Code | Meaning |
132
+ |---|---|
133
+ | 0 | Success |
134
+ | 1 | General / unknown error |
135
+ | 2 | Usage / config error (bad flags, unreadable CSV, missing column) |
136
+ | 3 | Auth error (not logged in, invalid or expired token) |
137
+ | 4 | Forbidden or payment required (missing scope/role, plan without API access, quota exceeded, billing blocked) |
138
+ | 5 | Not found (unknown team/project/object or no access) |
139
+ | 6 | Validation error or invalid state transition |
140
+ | 7 | Network error (server unreachable) |
141
+
142
+ On API errors the API's error detail is printed to stderr.
143
+
144
+ ## Environment variables
145
+
146
+ | Variable | Default | Purpose |
147
+ |---|---|---|
148
+ | `WITHFEEDBACK_API_URL` | `https://withfeedback.com` | API base URL (self-hosted/staging override) |
149
+ | `WITHFEEDBACK_TOKEN` | — | PAT (beats the keychain, loses to `--token`) |
150
+ | `WITHFEEDBACK_CLIENT_ID` | official public client id | Client id for `login` (override for self-hosted) |
151
+ | `WITHFEEDBACK_SCOPES` | all CLI scopes | Scopes requested during device-flow login |
152
+
153
+ On the first request of a run the CLI checks `GET /.well-known/speedpy.json`
154
+ once and warns (never fails) when the manifest is unreachable or the API is
155
+ older than the minimum this client expects.
156
+
157
+ ## Development
158
+
159
+ ```bash
160
+ uv run --with pytest --with httpx --with click --with keyring pytest packages/withfeedback-cli/
161
+ ```
@@ -0,0 +1,27 @@
1
+ [project]
2
+ name = "withfeedback"
3
+ version = "0.1.0"
4
+ description = "Command-line client for withfeedback.com — testimonials, feedback moderation, imports, widgets, and NPS"
5
+ readme = "README.md"
6
+ requires-python = ">=3.10"
7
+ license = { text = "MIT" }
8
+ keywords = ["cli", "testimonials", "feedback", "withfeedback"]
9
+ dependencies = [
10
+ "click>=8.1",
11
+ "httpx>=0.27",
12
+ "keyring>=24",
13
+ ]
14
+
15
+ [project.urls]
16
+ Homepage = "https://withfeedback.com"
17
+ Documentation = "https://withfeedback.com/api/docs/"
18
+
19
+ [project.scripts]
20
+ withfeedback = "withfeedback_cli.main:cli"
21
+
22
+ [build-system]
23
+ requires = ["hatchling"]
24
+ build-backend = "hatchling.build"
25
+
26
+ [tool.hatch.build.targets.wheel]
27
+ packages = ["src/withfeedback_cli"]
@@ -0,0 +1,3 @@
1
+ """withfeedback.com CLI package."""
2
+
3
+ __version__ = "0.1.0"