crowdtime-cli 0.8.0__tar.gz → 0.8.2__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.
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/PKG-INFO +1 -1
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/pyproject.toml +1 -1
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/__init__.py +1 -1
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/log_cmd.py +6 -6
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/timesheet_cmd.py +24 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/skills/crowdtime/SKILL.md +1 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/skills/crowdtime/references/commands.md +8 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/skills/crowdtime/references/workflows.md +7 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/.gitignore +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/LICENSE +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/README.md +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/auth.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/client.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/__init__.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/ai_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/auth_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/billing_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/clients_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/config_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/expense_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/favorites_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/invoice_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/org_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/payroll_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/projects_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/report_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/skill_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/tasks_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/commands/timer_cmd.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/config.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/formatters.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/main.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/models.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/oauth.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/resolvers.py +0 -0
- {crowdtime_cli-0.8.0 → crowdtime_cli-0.8.2}/src/crowdtime_cli/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: crowdtime-cli
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2
|
|
4
4
|
Summary: AI-powered time tracking CLI — a modern, developer-friendly alternative to Harvest
|
|
5
5
|
Project-URL: Homepage, https://crowdtime.lat
|
|
6
6
|
Project-URL: Documentation, https://crowdtime.lat/docs
|
|
@@ -246,23 +246,23 @@ def _list_entries(
|
|
|
246
246
|
elif week:
|
|
247
247
|
today = date_type.today()
|
|
248
248
|
start = today - timedelta(days=today.weekday())
|
|
249
|
-
params["
|
|
250
|
-
params["
|
|
249
|
+
params["date_from"] = format_date(start)
|
|
250
|
+
params["date_to"] = format_date(today)
|
|
251
251
|
elif month:
|
|
252
252
|
today = date_type.today()
|
|
253
253
|
start = today.replace(day=1)
|
|
254
|
-
params["
|
|
255
|
-
params["
|
|
254
|
+
params["date_from"] = format_date(start)
|
|
255
|
+
params["date_to"] = format_date(today)
|
|
256
256
|
|
|
257
257
|
if from_date:
|
|
258
258
|
try:
|
|
259
|
-
params["
|
|
259
|
+
params["date_from"] = format_date(parse_date(from_date))
|
|
260
260
|
except ValueError as e:
|
|
261
261
|
format_error(str(e))
|
|
262
262
|
raise typer.Exit(1)
|
|
263
263
|
if to_date:
|
|
264
264
|
try:
|
|
265
|
-
params["
|
|
265
|
+
params["date_to"] = format_date(parse_date(to_date))
|
|
266
266
|
except ValueError as e:
|
|
267
267
|
format_error(str(e))
|
|
268
268
|
raise typer.Exit(1)
|
|
@@ -260,6 +260,30 @@ def reject_timesheet(
|
|
|
260
260
|
raise typer.Exit(1)
|
|
261
261
|
|
|
262
262
|
|
|
263
|
+
@app.command("recall")
|
|
264
|
+
def recall_timesheet(
|
|
265
|
+
timesheet_id: str = typer.Argument(..., help="Timesheet ID to recall."),
|
|
266
|
+
output_json: bool = typer.Option(False, "--json", help="Output as JSON."),
|
|
267
|
+
) -> None:
|
|
268
|
+
"""Recall a submitted timesheet back to draft (owner only, before approval).
|
|
269
|
+
|
|
270
|
+
Examples:
|
|
271
|
+
ct timesheet recall <timesheet-id>
|
|
272
|
+
"""
|
|
273
|
+
client = CrowdTimeClient(require_auth=True, require_org=True)
|
|
274
|
+
|
|
275
|
+
try:
|
|
276
|
+
result = client.post(f"/timesheets/{timesheet_id}/recall/")
|
|
277
|
+
|
|
278
|
+
if output_json:
|
|
279
|
+
print_json(result)
|
|
280
|
+
else:
|
|
281
|
+
format_success("Timesheet recalled to draft. You can now edit and resubmit.")
|
|
282
|
+
except APIError as e:
|
|
283
|
+
format_error(e.message)
|
|
284
|
+
raise typer.Exit(1)
|
|
285
|
+
|
|
286
|
+
|
|
263
287
|
@app.command("team")
|
|
264
288
|
def team_overview(
|
|
265
289
|
period_start: Optional[str] = typer.Option(
|
|
@@ -177,6 +177,7 @@ ct favorites delete <id>
|
|
|
177
177
|
ct timesheet list # List your timesheets
|
|
178
178
|
ct timesheet list --status submitted # Filter by status
|
|
179
179
|
ct timesheet submit --from 2026-03-10 --to 2026-03-16 # Submit for a period
|
|
180
|
+
ct timesheet recall <id> # Recall submitted timesheet back to draft
|
|
180
181
|
ct timesheet approve <id> # Approve a submitted timesheet (manager+)
|
|
181
182
|
ct timesheet reject <id> --notes "Missing entries for Wednesday" # Reject with notes
|
|
182
183
|
ct timesheet team # Team overview for this week (manager+)
|
|
@@ -1151,6 +1151,14 @@ ct timesheet reject TIMESHEET_ID --notes NOTES [--json]
|
|
|
1151
1151
|
|
|
1152
1152
|
Rejects a submitted timesheet with notes (requires manager+ role). Endpoint: `POST /timesheets/{id}/reject/`
|
|
1153
1153
|
|
|
1154
|
+
### ct timesheet recall
|
|
1155
|
+
|
|
1156
|
+
```
|
|
1157
|
+
ct timesheet recall TIMESHEET_ID [--json]
|
|
1158
|
+
```
|
|
1159
|
+
|
|
1160
|
+
Recalls a submitted timesheet back to draft so you can edit and resubmit. Only the timesheet owner can recall, and only before it's been approved or rejected. Endpoint: `POST /timesheets/{id}/recall/`
|
|
1161
|
+
|
|
1154
1162
|
### ct timesheet team
|
|
1155
1163
|
|
|
1156
1164
|
```
|
|
@@ -286,6 +286,13 @@ ct timesheet submit --from 2026-03-09 --to 2026-03-15
|
|
|
286
286
|
|
|
287
287
|
# Check submission status
|
|
288
288
|
ct timesheet list
|
|
289
|
+
|
|
290
|
+
# Made a mistake? Recall it back to draft (before approval)
|
|
291
|
+
ct timesheet recall <timesheet-id>
|
|
292
|
+
|
|
293
|
+
# Fix and resubmit
|
|
294
|
+
ct l -p project-alpha -d friday 2h "missed entry"
|
|
295
|
+
ct timesheet submit --from 2026-03-09 --to 2026-03-15
|
|
289
296
|
```
|
|
290
297
|
|
|
291
298
|
### Manager: Review Team Timesheets
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|