agent-tool-openproject-cli 0.2.1__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.
@@ -0,0 +1,457 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-tool-openproject-cli
3
+ Version: 0.2.1
4
+ Summary: Agent-ready command-line interface for OpenProject (work packages, projects, time, costs, search, and more). Installs the `openproject` command.
5
+ Author: Zierhut IT, Alexander Zierhut
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/alexander-zierhut/agent-tool-openproject-cli
8
+ Project-URL: Repository, https://github.com/alexander-zierhut/agent-tool-openproject-cli
9
+ Project-URL: Issues, https://github.com/alexander-zierhut/agent-tool-openproject-cli/issues
10
+ Project-URL: Changelog, https://github.com/alexander-zierhut/agent-tool-openproject-cli/releases
11
+ Keywords: openproject,cli,command-line,openproject-api,work-packages,time-tracking,project-management,ai-agent,llm,automation,invoicing
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: License :: OSI Approved :: MIT License
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Topic :: Software Development :: Bug Tracking
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: typer>=0.12
23
+ Requires-Dist: httpx>=0.27
24
+ Requires-Dist: keyring>=25
25
+ Requires-Dist: rich>=13
26
+ Requires-Dist: python-dateutil>=2.9
27
+ Provides-Extra: test
28
+ Requires-Dist: pytest>=8; extra == "test"
29
+ Requires-Dist: pytest-timeout>=2.3; extra == "test"
30
+ Provides-Extra: build
31
+ Requires-Dist: pyinstaller>=6; extra == "build"
32
+ Dynamic: license-file
33
+
34
+ # openproject-cli โ€” the agent-ready OpenProject command-line interface
35
+
36
+ > A fast, scriptable **OpenProject CLI** for managing work packages, projects,
37
+ > time tracking, comments, and per-person cost reports from your terminal โ€” and
38
+ > the first OpenProject command-line tool designed to be driven by **AI agents**
39
+ > (Claude, Cursor, LLM tool-loops) as well as humans.
40
+
41
+ [![CI](https://github.com/alexander-zierhut/agent-tool-openproject-cli/actions/workflows/ci.yml/badge.svg)](https://github.com/alexander-zierhut/agent-tool-openproject-cli/actions/workflows/ci.yml)
42
+ ![Python](https://img.shields.io/badge/python-3.10%2B-blue)
43
+ ![License: MIT](https://img.shields.io/badge/license-MIT-green)
44
+ ![Agent ready](https://img.shields.io/badge/agent-ready-8A2BE2)
45
+
46
+ `openproject-cli` is a Python command-line interface for the
47
+ [OpenProject](https://www.openproject.org/) REST API v3. It covers the whole
48
+ day-to-day workflow โ€” **work packages** (create/update/delete/move), assignees,
49
+ custom fields, projects, comments, **time entries**, a genuinely good
50
+ **work-package search**, notifications, wiki, attachments with **Nextcloud** file
51
+ links, and **per-person time & cost reporting for monthly invoicing** โ€” all with
52
+ first-class JSON output so it slots straight into automation and AI agents.
53
+
54
+ ### Why this OpenProject CLI?
55
+
56
+ - ๐Ÿค– **Agent-ready** โ€” structured JSON on stdout, structured errors on stderr, and
57
+ stable exit codes. Plus a built-in **`openproject guide`** playbook so an agent
58
+ can learn the tool from the tool itself. See [AGENTS.md](AGENTS.md).
59
+ - ๐Ÿ”Ž **Discoverable search** โ€” filter with plain flags (`--mine`, `--overdue`,
60
+ `--updated-since 7d`), one-word presets (`search mine`), or `--where` expressions.
61
+ Never memorise filter JSON: `search fields`, `search operators`, `search values`.
62
+ - ๐Ÿ–‡๏ธ **Three output formats** โ€” `json` (default), `table`, and `markdown`; pick per
63
+ command with `-f`, set a default, or select exact `--fields`.
64
+ - ๐Ÿ” **Safe credentials** โ€” API token stored in the OS keyring (Secret Service /
65
+ macOS Keychain / Windows Credential Locker), with a `0600` file fallback.
66
+ - ๐Ÿงฐ **Escape hatch** โ€” `openproject raw` calls any endpoint the typed commands
67
+ don't wrap.
68
+ - ๐Ÿ“ฆ **Install anywhere** โ€” pipx, pip, or a single self-contained binary (no Python
69
+ required on the target).
70
+
71
+ **Docs:** [Usage guide](docs/USAGE.md) ยท [Full command reference](docs/COMMANDS.md) ยท [Agent guide](AGENTS.md)
72
+
73
+ **Keywords:** OpenProject CLI, OpenProject command line, OpenProject API client,
74
+ work package automation, time tracking CLI, project management CLI, AI agent tool,
75
+ LLM tooling, Claude, DevOps automation, invoicing.
76
+
77
+ ---
78
+
79
+ ## Quick start
80
+
81
+ ### 1. Install
82
+
83
+ Pick whichever fits your target:
84
+
85
+ **a) `pipx` (recommended โ€” isolated, `openproject` on PATH, needs Python 3.10+)**
86
+ ```bash
87
+ pipx install agent-tool-openproject-cli # from PyPI (installs the `openproject` command)
88
+ pipx install git+https://github.com/alexander-zierhut/agent-tool-openproject-cli.git # or straight from git
89
+ ```
90
+
91
+ **b) `pip` into a venv (for development)**
92
+ ```bash
93
+ python3 -m venv .venv && . .venv/bin/activate
94
+ pip install -e . # from this directory
95
+ ```
96
+
97
+ **c) Single self-contained binary (no Python on the target)**
98
+
99
+ Download the prebuilt binary for your OS from the GitHub Releases page, then:
100
+ ```bash
101
+ chmod +x openproject-linux-x86_64 && mv openproject-linux-x86_64 /usr/local/bin/openproject
102
+ openproject --help
103
+ ```
104
+ Or build one yourself โ€” produces a single `dist/openproject` (~16 MB) that
105
+ bundles the interpreter and all deps, including the OS keyring backends:
106
+ ```bash
107
+ pip install -e '.[build]'
108
+ ./scripts/build_binary.sh # -> dist/openproject (.exe on Windows)
109
+ ```
110
+ CI (`.github/workflows/release.yml`) builds Linux/macOS/Windows binaries on
111
+ every `v*` tag and attaches them to the release.
112
+
113
+ > The command is `openproject`. The short name `op` is intentionally **not**
114
+ > claimed, to avoid clobbering another tool of that name (this machine already
115
+ > has an OpenProject CLI at `/usr/local/bin/op`). Add your own alias if you want
116
+ > a shorter command, e.g. `alias opr=openproject`.
117
+
118
+ ### 2. Bring up a local OpenProject (for development/testing)
119
+
120
+ ```bash
121
+ docker compose up -d # boots the all-in-one image on :8090
122
+ docker compose logs -f openproject # watch until "seeding" finishes (~5 min)
123
+ eval "$(./scripts/get_admin_token.sh)" # mints & exports APITOKEN
124
+ ```
125
+
126
+ Web UI: http://localhost:8090 โ€” admin / `AdminPassw0rd!`
127
+
128
+ ### 3. Log in
129
+
130
+ ```bash
131
+ openproject auth login --url http://localhost:8090 --token "$APITOKEN"
132
+ openproject auth whoami
133
+ ```
134
+
135
+ `login` verifies the token against `/users/me`, saves the connection profile to
136
+ `~/.config/op-cli/config.json`, and stores the token in your keyring. Thereafter
137
+ just run `openproject ...`.
138
+
139
+ For headless/CI use you can skip the keyring entirely and pass everything via
140
+ environment variables:
141
+
142
+ ```bash
143
+ export OPCLI_BASE_URL=http://localhost:8090
144
+ export OPCLI_TOKEN=opapi-xxxxxxxx
145
+ openproject wp list
146
+ ```
147
+
148
+ ---
149
+
150
+ ## Command reference
151
+
152
+ Run `openproject <group> --help` for full options. Highlights:
153
+
154
+ ### Work packages โ€” `openproject wp`
155
+
156
+ ```bash
157
+ openproject wp create "Fix login bug" --project my-proj --type Bug \
158
+ --assignee me --priority High --due-date 2026-08-01 --estimated 4
159
+ openproject wp get 42
160
+ openproject wp list --project my-proj --status open --assignee me
161
+ openproject wp update 42 --status "In progress" --done-ratio 50
162
+ openproject wp move 42 other-project
163
+ openproject wp assign 42 jane.doe # or `openproject wp assign 42 none` to clear
164
+ openproject wp watch 42 me
165
+ openproject wp schema --project my-proj --type Task # discover fields + custom fields
166
+ openproject wp delete 42 -y
167
+ ```
168
+
169
+ ### Search โ€” `openproject search`
170
+
171
+ The star feature, designed to be usable **without memorising the JSON filter
172
+ language**. Three ways to search, easiest first:
173
+
174
+ **1. Plain-language flags** on `search wp`:
175
+
176
+ ```bash
177
+ openproject search wp "payment timeout" # full text
178
+ openproject search wp --mine --overdue # my past-due items
179
+ openproject search wp --project my-proj --status open --assignee jane.doe
180
+ openproject search wp --type Bug --priority High --updated-since 7d
181
+ openproject search wp --unassigned --project my-proj
182
+ openproject search wp --version "Sprint 12" --all
183
+ openproject search wp --id 42,57,103 # specific ids
184
+ openproject search wp --due-before 2026-08-01 # or --due-before +14d
185
+ openproject search wp "invoice" --count # just the total
186
+ openproject search wp --group-by status --project my-proj
187
+ ```
188
+
189
+ Dates accept ISO (`2026-08-01`) or relative specs: `7d`, `2w`, `1m`, `+30d`,
190
+ `today`, `yesterday`.
191
+
192
+ **2. Presets** โ€” common searches as one word:
193
+
194
+ ```bash
195
+ openproject search mine # open, assigned to me
196
+ openproject search overdue # past due & still open
197
+ openproject search unassigned # open with no assignee
198
+ openproject search reported # I created them
199
+ openproject search watching # I'm watching
200
+ openproject search recent --days 3
201
+ ```
202
+
203
+ **3. `--where` expressions** โ€” compact, no JSON, repeatable (AND-ed):
204
+
205
+ ```bash
206
+ openproject search wp --where "status = open" --where "assignee = me"
207
+ openproject search wp --where "assignee:none" # unassigned
208
+ openproject search wp --where "updated > 7d" --where "priority = High"
209
+ openproject search wp --where "subject ~ timeout"
210
+ ```
211
+
212
+ And when you don't remember what's available, **ask the CLI**:
213
+
214
+ ```bash
215
+ openproject search fields # what you can filter on (live)
216
+ openproject search fields --project x # incl. that project's custom fields
217
+ openproject search operators # what =, o, !*, <>d, ~ โ€ฆ mean
218
+ openproject search values status # allowed values for a field
219
+ openproject search values type
220
+ openproject search values version --project x
221
+ ```
222
+
223
+ The raw JSON filter escape hatch is still there when you need it:
224
+
225
+ ```bash
226
+ openproject search wp --filters '[{"customField1":{"operator":"~","values":["INV-2026"]}}]'
227
+ ```
228
+
229
+ ### Projects โ€” `openproject project`
230
+
231
+ ```bash
232
+ openproject project create "Client X" --identifier client-x --description "..."
233
+ openproject project list # add --archived for archived ones
234
+ openproject project archive client-x # PATCH active=false
235
+ openproject project unarchive client-x
236
+ openproject project delete client-x -y
237
+ ```
238
+
239
+ ### Assignees & members โ€” `openproject wp assign`, `openproject member`, `openproject user`
240
+
241
+ ```bash
242
+ openproject user available my-proj # who can be assigned in a project
243
+ openproject member add --project my-proj --user jane.doe --role Member
244
+ openproject member list --project my-proj
245
+ openproject member update 12 --role "Project admin" # replaces the role set
246
+ openproject member remove 12 -y
247
+ ```
248
+
249
+ ### Comments โ€” `openproject comment`
250
+
251
+ ```bash
252
+ openproject comment add 42 "Deployed to staging."
253
+ openproject comment list 42
254
+ openproject comment edit 137 "Deployed to staging (corrected)." # 137 = activity id
255
+ ```
256
+
257
+ ### Time entries โ€” `openproject time`
258
+
259
+ ```bash
260
+ openproject time add 2.5 --work-package 42 --activity Development --comment "debugging"
261
+ openproject time add 1 --project my-proj --date 2026-07-10 # log against a project
262
+ openproject time list --user me --month 2026-07
263
+ openproject time edit 88 --hours 3
264
+ openproject time activities --project my-proj
265
+ openproject time delete 88 -y
266
+ ```
267
+
268
+ Hours accept decimals (`2.5`) or ISO-8601 (`PT2H30M`) โ€” they're converted for you.
269
+
270
+ ### Custom fields โ€” `openproject cf`
271
+
272
+ Custom fields can't be *created* via the API (admin/Rails only), but you can
273
+ discover them and set values:
274
+
275
+ ```bash
276
+ openproject cf wp --project my-proj --type Task # lists customFieldN + allowed values
277
+ openproject wp create "Task" --project my-proj \
278
+ --custom-fields '{"customField1":"INV-2026-007","customField2":{"href":"/api/v3/custom_options/3"}}'
279
+ ```
280
+
281
+ Value-type fields (string/int/date/bool) take a scalar; list/user/version fields
282
+ take `{"href": "..."}` (use the ids from `openproject cf wp`).
283
+
284
+ ### Time & cost reporting (invoicing) โ€” `openproject cost`
285
+
286
+ OpenProject's API exposes **no** hourly rates or cost reports, so this report
287
+ sums time entries per person and applies a **rate table you supply**:
288
+
289
+ ```bash
290
+ openproject cost report --month 2026-07 --rates rates.json
291
+ openproject cost report --from 2026-07-01 --to 2026-07-31 --user jane.doe --rates rates.json
292
+ ```
293
+
294
+ `rates.json` (see `rates.example.json`):
295
+
296
+ ```json
297
+ {
298
+ "currency": "EUR",
299
+ "default": 90,
300
+ "users": { "admin": 120, "jane.doe": 100 },
301
+ "projects": { "client-x": { "default": 100, "admin": 110 } }
302
+ }
303
+ ```
304
+
305
+ Without `--rates` it reports hours only. Most specific rate wins:
306
+ project+user โ†’ project default โ†’ user โ†’ global default.
307
+
308
+ ### Notifications โ€” `openproject notify`
309
+
310
+ ```bash
311
+ openproject notify list # unread by default; --state read|all
312
+ openproject notify list --today # only today's
313
+ openproject notify count # {"total": N, "unread": M}
314
+ openproject notify count --today # adds today / todayUnread
315
+ openproject notify read 5
316
+ openproject notify unread 5
317
+ openproject notify read-all
318
+ ```
319
+
320
+ ### Attachments โ€” `openproject attach`
321
+
322
+ ```bash
323
+ openproject attach upload 42 ./report.pdf --description "Q3 report"
324
+ openproject attach list 42
325
+ openproject attach download 7 -O ./out.pdf
326
+ openproject attach delete 7 -y
327
+ ```
328
+
329
+ ### Nextcloud / file storages โ€” `openproject filelink`
330
+
331
+ Links an existing file in a configured storage (e.g. your Nextcloud) to a work
332
+ package. The storage must be set up in OpenProject admin first.
333
+
334
+ ```bash
335
+ openproject filelink storages
336
+ openproject filelink add 42 --storage 1 --file-id 123 --file-name "Contract.pdf"
337
+ openproject filelink list 42
338
+ openproject filelink delete 9 -y
339
+ ```
340
+
341
+ ### Wiki โ€” `openproject wiki`
342
+
343
+ > **Limitation:** OpenProject API v3 only exposes wiki *metadata* (id + title)
344
+ > and page attachments โ€” there is no API to read or write the wiki body text.
345
+
346
+ ```bash
347
+ openproject wiki get 3
348
+ openproject wiki attachments 3
349
+ ```
350
+
351
+ ### Raw escape hatch โ€” `openproject raw`
352
+
353
+ ```bash
354
+ openproject raw get work_packages/42
355
+ openproject raw get work_packages -p 'filters=[{"status":{"operator":"o","values":null}}]'
356
+ openproject raw post work_packages -d '{"subject":"x","_links":{"project":{"href":"/api/v3/projects/1"},"type":{"href":"/api/v3/types/1"}}}'
357
+ openproject raw patch work_packages/42 -d '{"lockVersion":3,"subject":"y"}'
358
+ openproject raw delete work_packages/42
359
+ ```
360
+
361
+ ### Auth & profiles โ€” `openproject auth`
362
+
363
+ ```bash
364
+ openproject auth login --url https://op.example.com --token opapi-xxxx --name prod
365
+ openproject auth status
366
+ openproject -p prod wp list # use a specific profile per-invocation
367
+ openproject auth logout --name prod
368
+ ```
369
+
370
+ ### Output format & settings โ€” `openproject settings`
371
+
372
+ Three output formats: **`json`** (default, best for scripts/agents),
373
+ **`table`** (human-readable terminal tables), and **`markdown`** (paste into
374
+ docs/PRs). Choose per command, or set a persistent default.
375
+
376
+ ```bash
377
+ openproject wp list -o table # global flag (before the command)
378
+ openproject wp list --format markdown # --format/-f works AFTER any command too
379
+ openproject wp get 42 -f md
380
+
381
+ openproject settings set-format table # persist a default
382
+ openproject settings show # current default, config path, profiles
383
+ ```
384
+
385
+ On the **first interactive run** the CLI asks which default format you'd like and
386
+ saves your choice. Non-interactive runs (pipes, CI, agents) never prompt โ€” they
387
+ default to `json`. Precedence: `--format`/`-f` โ†’ `-o/--output` โ†’ `$OPCLI_FORMAT`
388
+ โ†’ saved default โ†’ `json`.
389
+
390
+ ---
391
+
392
+ ## Output for agents
393
+
394
+ - Default output is pretty JSON on **stdout**. Errors are structured JSON on
395
+ **stderr** with a non-zero exit code (`{"error": "...", "status": 404}`).
396
+ - Exit codes: `0` ok, `4` auth, `5` not found, `6` conflict, `7` validation,
397
+ `1`/`3` general/config.
398
+ - Reference-by-name works everywhere sensible: `--status "In progress"`,
399
+ `--assignee jane.doe`, `--project client-x`, `--activity Development`,
400
+ `--type Bug` are resolved to ids for you. `me` resolves to the current user.
401
+ - Discover filters at runtime with `openproject search fields`,
402
+ `search operators`, and `search values <field>` โ€” no need to memorise the
403
+ filter JSON.
404
+
405
+ ---
406
+
407
+ ## Testing
408
+
409
+ A full integration suite drives the real CLI against the live instance.
410
+
411
+ ```bash
412
+ docker compose up -d
413
+ eval "$(./scripts/get_admin_token.sh)"
414
+ export OPCLI_BASE_URL=http://localhost:8090 OPCLI_TOKEN="$APITOKEN"
415
+ ./scripts/seed_test_data.sh # modules + custom fields + a 2nd user
416
+ pip install -e '.[test]'
417
+ pytest # 56 tests
418
+ ```
419
+
420
+ A few tests need a second, non-admin actor (to generate a notification). Set
421
+ `OPCLI_SECOND_TOKEN` to `jane.doe`'s token to enable them:
422
+
423
+ ```bash
424
+ export OPCLI_SECOND_TOKEN=$(./scripts/get_admin_token.sh jane.doe | grep APITOKEN | cut -d= -f2)
425
+ ```
426
+
427
+ Without `OPCLI_BASE_URL`/`OPCLI_TOKEN` the integration tests skip and only the
428
+ pure-unit tests run โ€” handy for CI. See `docs/API_NOTES.md` for the researched
429
+ API details behind the implementation.
430
+
431
+ Or just use the Makefile:
432
+
433
+ ```bash
434
+ make up # docker compose up + wait for health
435
+ make seed # mint token, seed test data, write .env
436
+ make test # run the suite
437
+ make down # tear down
438
+ ```
439
+
440
+ ---
441
+
442
+ ## Security notes
443
+
444
+ - The API token is the only secret persisted, and it goes to the OS keyring by
445
+ default. `openproject auth status` shows which backend is in use.
446
+ - On a headless box with no Secret Service, the token falls back to a `0600`
447
+ file at `~/.config/op-cli/credentials.json` and the CLI warns you.
448
+ - `OPCLI_TOKEN` in the environment always takes precedence (nothing is written
449
+ to disk in that mode).
450
+
451
+ ## Known limitations (API v3, not the CLI)
452
+
453
+ - **Wiki** is read-only metadata (no body text over the API).
454
+ - **Costs**: no hourly rates or cost-report endpoints exist โ€” hence the
455
+ client-side rate table for invoicing.
456
+ - **Custom fields** can't be created via the API (admin UI / Rails only); the
457
+ CLI discovers and sets them.
@@ -0,0 +1,40 @@
1
+ agent_tool_openproject_cli-0.2.1.dist-info/licenses/LICENSE,sha256=pnlo9A2Num7hCAJ7Aqhnezlvnc9pdRwpH_VUnjb5UTU,1087
2
+ opcli/__init__.py,sha256=DTLLI1iFU02KQjg8SpPd1BUW0VbSWm663W31HNCQl70,97
3
+ opcli/__main__.py,sha256=kGmhT06GyrqVC0YYH2pEefIhMdjUmJUmGTlVBqoiBEg,96
4
+ opcli/cli.py,sha256=orZIUEIZ4LpDFHvjCC1cbLSSn5e93Sfzbd_8HW4CCvU,6506
5
+ opcli/client.py,sha256=ZcOxQL49_MQ3CxlzcgqK4i44Oh6PwFI4gQ3mA6Uru8w,9170
6
+ opcli/config.py,sha256=iMQAGERtIPG2pfYPKLQ86DRtvWjYW-qGrG0BV7bAWas,4533
7
+ opcli/context.py,sha256=-WlR3IMfTWAUZ_k-NI3FKLcUhmFmXWd9RsL6OC6azLw,4222
8
+ opcli/credentials.py,sha256=9TudckGqDN9nt_CLL92H6ue1GTmkJgy43C4XsNPAqVk,4186
9
+ opcli/duration.py,sha256=Sz-w7DINxvUMlPUoc-s7fjFpYYwcydaKDlzDZi4Alx0,1742
10
+ opcli/errors.py,sha256=Evc_NRNS8-oZOtg0vXOWKKnlheNcgI3-pBmwcYeK4JI,2137
11
+ opcli/hal.py,sha256=an4fwopEKFyPT3nGhi0Zp2axnUHTCBvorXJGqy2ozuw,2093
12
+ opcli/output.py,sha256=nMfYBuLHDWZjQn15NkfzMeOmgsRY6bLWpIIQMq-0rdY,8223
13
+ opcli/resolve.py,sha256=izFd-jfKNnYjWlefMmvGy__yrZu3tMXl6LJFTs2IOo8,6741
14
+ opcli/searchspec.py,sha256=kzsWje90p_XG1YGwkd0gjzLgglOfw-q5A7TRCHUAASI,11348
15
+ opcli/serialize.py,sha256=Filznqv6jpdkZk2TlNHCSWiyxNs3eWaZ9lf-0rxK7FY,7441
16
+ opcli/wpfilters.py,sha256=K_77KKyD_1WkmwdMnVasNCjYCkNKnwlLZHVOY7sWmBg,6190
17
+ opcli/commands/__init__.py,sha256=7cNktBGdDU8aFHU4Om0Fts6bzE3e1c4C88cETaoxp2A,46
18
+ opcli/commands/_shared.py,sha256=4cPWx_yg2uNscTUwmbu-zegqlv8RF3hjJEEUaeG4-7s,1612
19
+ opcli/commands/attachments.py,sha256=XsLl6IJXvzOy5-UwLvOYSz7kZ3xnkwP4gQQrB40K1po,3752
20
+ opcli/commands/auth.py,sha256=tIsyS6ezMm88JBSK6K7lXW6_PV9FY43db9R6zd6id34,3632
21
+ opcli/commands/comments.py,sha256=HnYMwbJrBHBLdPeBKkRaQtcqQSzSYjy24y3sqvZCTb0,3188
22
+ opcli/commands/costs.py,sha256=YnUtvyC_7JCWdfK6M476F5B_9JZFxd7k1Xc3tOiHOK0,7953
23
+ opcli/commands/custom_fields.py,sha256=IRSYPfASG1ggace8CpHa_zrSLmIJELmTcn0aCq6V3PM,3094
24
+ opcli/commands/filelinks.py,sha256=BRt46o6KNLxYSu4XqHtTWKn9B9HwVfPGEg8lwDkpARQ,3461
25
+ opcli/commands/guide.py,sha256=7KkMEFxydpnG61o5RMbOfZV552-auYL-Q2x3hhsCtUM,10221
26
+ opcli/commands/memberships.py,sha256=ro3wPdqfCRTd8JX3icmR51CILMoUheNS2bKuGvrETJg,3982
27
+ opcli/commands/notifications.py,sha256=6Mk6ehJqiz6Rx6Vr4a8FwDNPvGXCts0UefHQ-nUnkj4,4889
28
+ opcli/commands/projects.py,sha256=8SLrCYvMpda4mQjsrbmRZBdOVmc7z92oSBZl9msa-I0,5796
29
+ opcli/commands/raw.py,sha256=PP-OueRwF_QxteR94PWJXU7Gu9Co92v_HCc1NwGq9BY,2911
30
+ opcli/commands/search.py,sha256=U9fJBQfZdg6TD_ZNrS9HGI0Uh9Mmhb9xq5hg3Z1ONwQ,11742
31
+ opcli/commands/settings.py,sha256=w54GfpYyv0whZiybCRfMNCkM2uDTLdT2YUVDCpESJ9o,1842
32
+ opcli/commands/time_entries.py,sha256=0fD12KQp7rW4FSzy15XrK0kx5OvtuBh8ZFg7sSBW2d8,9341
33
+ opcli/commands/users.py,sha256=8F3LYIbU36p-L88o021oSL_Ls7KI8v_Wp9rDXqkDaUk,3668
34
+ opcli/commands/wiki.py,sha256=arpAHrsD7Z4L_kgjbQQu4Ubf7ZraEQiHZDXUO0QWzkQ,1642
35
+ opcli/commands/workpackages.py,sha256=Vn_3-a9yuE3uZYrwNQW57v_CLL0kNQnGz3FjkBGtj-A,15872
36
+ agent_tool_openproject_cli-0.2.1.dist-info/METADATA,sha256=G7ZiC7GzOXal1ZZm1puACC3yYnkqEgA8FWqxn0-yiro,17683
37
+ agent_tool_openproject_cli-0.2.1.dist-info/WHEEL,sha256=K260EYznzXsJYBQGqmI8VTxEdiZYNvDZwW9cBh9-_MA,91
38
+ agent_tool_openproject_cli-0.2.1.dist-info/entry_points.txt,sha256=0-5cDe9xaftl2T8cMBTr3gwcsYEPmQaPbIH5HQACeWI,47
39
+ agent_tool_openproject_cli-0.2.1.dist-info/top_level.txt,sha256=9bigM7AKOqVoQF5dvbcRRsYwx0I1I38qgKeHlLdiWDQ,6
40
+ agent_tool_openproject_cli-0.2.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (83.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ openproject = opcli.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zierhut IT / Alexander Zierhut
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.
opcli/__init__.py ADDED
@@ -0,0 +1,3 @@
1
+ """opcli โ€” an agent-friendly command-line interface for OpenProject."""
2
+
3
+ __version__ = "0.2.1"
opcli/__main__.py ADDED
@@ -0,0 +1,6 @@
1
+ """Enable ``python -m opcli``."""
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ main()