@togglhq/cli 1.5.19
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.
- package/README.md +299 -0
- package/build/index.d.ts +1 -0
- package/build/index.js +13 -0
- package/build/program-BwnVUFVS.js +26083 -0
- package/build/program.d.ts +982 -0
- package/build/program.js +2 -0
- package/package.json +65 -0
- package/skills/toggl-cli/INTERNAL.md +51 -0
- package/skills/toggl-cli/SKILL.md +68 -0
- package/skills/toggl-cli/reference/auth-environments-workspaces.md +141 -0
- package/skills/toggl-cli/reference/command-contract.md +159 -0
- package/skills/toggl-cli/reference/focus-concepts.md +81 -0
- package/skills/toggl-cli/reference/projects.md +51 -0
- package/skills/toggl-cli/reference/rates-and-billables.md +13 -0
- package/skills/toggl-cli/reference/reports.md +18 -0
- package/skills/toggl-cli/reference/statuses-users.md +33 -0
- package/skills/toggl-cli/reference/tasks.md +57 -0
- package/skills/toggl-cli/reference/time-blocks.md +43 -0
- package/skills/toggl-cli/reference/time-entries.md +42 -0
- package/skills/toggl-cli/reference/troubleshooting.md +100 -0
- package/skills/toggl-cli/workflows/common-workflows.md +104 -0
package/build/program.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@togglhq/cli",
|
|
3
|
+
"version": "1.5.19",
|
|
4
|
+
"description": "Toggl CLI for Focus API operations.",
|
|
5
|
+
"license": "UNLICENSED",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/toggl/toggl-mcp.git"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"publishConfig": {
|
|
12
|
+
"registry": "https://registry.npmjs.org",
|
|
13
|
+
"access": "public"
|
|
14
|
+
},
|
|
15
|
+
"bin": {
|
|
16
|
+
"toggl": "./build/index.js"
|
|
17
|
+
},
|
|
18
|
+
"exports": {
|
|
19
|
+
".": {
|
|
20
|
+
"types": "./build/index.d.ts",
|
|
21
|
+
"import": "./build/index.js",
|
|
22
|
+
"default": "./build/index.js"
|
|
23
|
+
},
|
|
24
|
+
"./program": {
|
|
25
|
+
"types": "./build/program.d.ts",
|
|
26
|
+
"import": "./build/program.js",
|
|
27
|
+
"default": "./build/program.js"
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
"files": [
|
|
31
|
+
"build/**/*.js",
|
|
32
|
+
"build/**/*.d.ts",
|
|
33
|
+
"skills/**",
|
|
34
|
+
"README.md"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "tsdown",
|
|
38
|
+
"build:public": "tsdown",
|
|
39
|
+
"build:internal": "tsdown --config tsdown.config.internal.ts",
|
|
40
|
+
"build:watch": "tsdown --watch",
|
|
41
|
+
"typecheck": "tsgo -p tsconfig.json --noEmit",
|
|
42
|
+
"lint": "oxlint --deny-warnings src/**/*.ts tsdown.config.ts tsdown.config.internal.ts",
|
|
43
|
+
"lint:fix": "oxlint --deny-warnings --fix src/**/*.ts tsdown.config.ts tsdown.config.internal.ts",
|
|
44
|
+
"format": "oxfmt --write src skills package.json tsconfig.json tsdown.config.ts tsdown.config.internal.ts README.md",
|
|
45
|
+
"format:check": "oxfmt --check src skills package.json tsconfig.json tsdown.config.ts tsdown.config.internal.ts README.md",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"link:global": "pnpm link --global",
|
|
48
|
+
"unlink:global": "pnpm unlink --global"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=20"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"skills": "1.5.2"
|
|
55
|
+
},
|
|
56
|
+
"devDependencies": {
|
|
57
|
+
"@toggl/cli-core": "workspace:^",
|
|
58
|
+
"@toggl/operations": "workspace:^",
|
|
59
|
+
"@toggl/queries": "0.15.17",
|
|
60
|
+
"@types/node": "22.19.11",
|
|
61
|
+
"tsdown": "0.21.8",
|
|
62
|
+
"typescript": "5.9.3",
|
|
63
|
+
"vitest": "3.2.4"
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Internal Toggl CLI Workflows
|
|
2
|
+
|
|
3
|
+
Install `@toggl/cli-internal` from **GitHub Packages** for internal builds that include staging and MS environment helpers (`toggl-internal` bin).
|
|
4
|
+
|
|
5
|
+
## Environments
|
|
6
|
+
|
|
7
|
+
Use production by default. Use these flags only when a Toggl engineer asks for staging or a named MS environment.
|
|
8
|
+
|
|
9
|
+
Authenticate against staging:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
toggl-internal auth --staging
|
|
13
|
+
toggl-internal --json profile list
|
|
14
|
+
toggl-internal --json workspace list
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Authenticate against a named MS environment:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
toggl-internal auth --ms <name>
|
|
21
|
+
toggl-internal --json profile list
|
|
22
|
+
toggl-internal --json workspace list
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Generated non-production profiles keep the environment prefix, for example `staging-hazem-12345` or `ms-foo-hazem-12345`.
|
|
26
|
+
|
|
27
|
+
## Environment Variables
|
|
28
|
+
|
|
29
|
+
The internal build also recognizes shorthand environment variables:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
ENV=staging toggl-internal auth
|
|
33
|
+
MS=<name> toggl-internal auth
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Explicit URL overrides still take precedence:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
TOGGL_FOCUS_API_URL=<url> TOGGL_ACCOUNTS_API_URL=<url> toggl-internal auth
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Troubleshooting
|
|
43
|
+
|
|
44
|
+
When data appears missing in an internal environment, verify profile and workspace before assuming the resource does not exist:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
toggl-internal --json profile list
|
|
48
|
+
toggl-internal --json profile current
|
|
49
|
+
toggl-internal --json workspace list --refresh
|
|
50
|
+
toggl-internal --json workspace switch <workspace-id>
|
|
51
|
+
```
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: toggl-cli
|
|
3
|
+
description: Use the Toggl CLI to work with Toggl Focus tasks, projects, time entries, time blocks, workspaces, authentication, and CLI maintenance from an agent-friendly terminal workflow. Trigger when the user asks to inspect or modify Focus data through the terminal, authenticate Toggl, switch workspaces, install or refresh the Toggl agent skill, update the CLI, or automate Focus workflows.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Toggl CLI
|
|
7
|
+
|
|
8
|
+
Use the `toggl` command when the user wants to inspect or modify Toggl Focus data from the terminal. The CLI is designed for agents: commands are non-interactive when flags are supplied, `--json` gives compact machine-readable responses, validation errors are explicit, and destructive operations require confirmation flags.
|
|
9
|
+
|
|
10
|
+
## When to Use
|
|
11
|
+
|
|
12
|
+
Use this skill when the task involves:
|
|
13
|
+
|
|
14
|
+
- Listing, reading, creating, updating, or deleting Toggl Focus tasks, projects, time blocks, or time entries.
|
|
15
|
+
- Managing saved views, custom fields (admin), and task/project attachments (including file upload and download).
|
|
16
|
+
- Finding workspace metadata such as statuses, users, and workspace IDs.
|
|
17
|
+
- Authenticating the Toggl CLI, switching saved profiles, or switching the active workspace.
|
|
18
|
+
- Installing or refreshing the CLI's agent skill (`toggl skill setup`, or `toggl skill sync` after upgrading `@toggl/cli`).
|
|
19
|
+
- Updating a globally installed `@toggl/cli`.
|
|
20
|
+
- Automating a Focus workflow from shell commands.
|
|
21
|
+
|
|
22
|
+
Do not use this skill for Toggl Track APIs, raw Focus API calls, or MCP server implementation work unless the user specifically asks to operate through the CLI.
|
|
23
|
+
|
|
24
|
+
## Operating Rules
|
|
25
|
+
|
|
26
|
+
- Prefer `toggl --json ...` for any command whose output you will parse.
|
|
27
|
+
- Without `--json`, successful responses are formatted for human reading; do not parse that output in scripts.
|
|
28
|
+
- Run list/get commands first when the target ID is unclear.
|
|
29
|
+
- Use scalar flags for simple inputs: `--task-id`, `--project-id`, `--payload-status-id`.
|
|
30
|
+
- Use `--data -` or `--data-file <path>` for nested payloads or fragile shell quoting.
|
|
31
|
+
- Use `--dry-run` before mutations when you need to validate input.
|
|
32
|
+
- On a TTY, mutations that omit `--data` / `--data-file` / complete scalar flags may open interactive prompts by default; optional reads only prompt when the operation allows it and you pass **`--interactive`**. The **`--interactive`** / **`--no-interactive`** flags exist only on commands where the catalog enables prompting (not on read-only commands that are `interactive: hidden`). Agents and scripts should pass explicit `--*-id` flags or `--data` instead of relying on prompts.
|
|
33
|
+
- Never pass `--yes` unless the user explicitly requested a destructive delete.
|
|
34
|
+
- Use `toggl profile current` / `toggl profile list` when the active account may be wrong.
|
|
35
|
+
- Use `toggl profile switch [<profile>]` to change the default account (omit the name in a TTY to pick interactively), or `--profile <name>` / `--workspace-id <id>` for one command. Use `toggl profile remove [<profile>]` to delete a saved profile (omit the name in a TTY to pick interactively).
|
|
36
|
+
- Use `toggl workspace switch [<id>]` to set the active workspace (omit the id in a TTY to pick interactively from cached workspaces; use `toggl workspace list --refresh` if the list is stale).
|
|
37
|
+
- When changing a time entry’s start time or duration together, use `time-entries update` with required `type` (`activity` or `break`), not `partial-update`; details are in `reference/time-entries.md`.
|
|
38
|
+
- Inspect command help when unsure: `toggl <group> … <command> --help`. Use **`--dry-run`** to print `{ dry_run, operation, input }` (operation id plus validated body) without calling the API.
|
|
39
|
+
- Use the curated command groups: organization commands live under **`toggl organization …`** (not `toggl org …`), shared-data CLI routes sit under **`toggl shared …`**, search is `toggl search`, workspace settings are not nested under `users`, and advanced composite creation is under `projects create-advanced` / `tasks create-with-children`. Attachments nest under their parent: `toggl tasks attachments …` / `toggl projects attachments …`.
|
|
40
|
+
- Attachment files use local paths: upload with `attachments create --file-path <path>` (mime inferred from extension, 20 MB cap), bulk-upload with `--data '{"file_paths":[…]}'`, download with `attachments view --save-to <path>` (refuses to replace an existing file unless `--overwrite true`).
|
|
41
|
+
- custom-fields mutations need workspace admin and 403 otherwise.
|
|
42
|
+
- After the user upgrades `@toggl/cli`, suggest `toggl skill sync` if they use `--copy` installs; symlink installs usually track the package without an extra step.
|
|
43
|
+
|
|
44
|
+
## Read Next
|
|
45
|
+
|
|
46
|
+
- Focus concepts, entity hierarchy, and resource relationships: `reference/focus-concepts.md`
|
|
47
|
+
- Auth, profiles, and workspaces: `reference/auth-environments-workspaces.md`
|
|
48
|
+
- Command shape, JSON input, output, dates, and safety flags: `reference/command-contract.md`
|
|
49
|
+
- Tasks: `reference/tasks.md`
|
|
50
|
+
- Projects: `reference/projects.md`
|
|
51
|
+
- Time entries: `reference/time-entries.md`
|
|
52
|
+
- Time blocks: `reference/time-blocks.md`
|
|
53
|
+
- Rates and billables (Focus API vs Track): `reference/rates-and-billables.md`
|
|
54
|
+
- Statuses and users: `reference/statuses-users.md`
|
|
55
|
+
- Reports (`get-workload` vs `get-flexq-data`): `reference/reports.md`
|
|
56
|
+
- Common multi-step flows: `workflows/common-workflows.md`
|
|
57
|
+
- Errors and recovery: `reference/troubleshooting.md`
|
|
58
|
+
|
|
59
|
+
## Quick Start
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
toggl auth
|
|
63
|
+
toggl --json profile list
|
|
64
|
+
toggl --json workspace list
|
|
65
|
+
toggl --json tasks list --project-id <project-id>
|
|
66
|
+
toggl tasks update --task-id <task-id> --payload-status-id <status-id> --dry-run
|
|
67
|
+
toggl --json tasks update --task-id <task-id> --payload-status-id <status-id>
|
|
68
|
+
```
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Auth, Environments, and Workspaces
|
|
2
|
+
|
|
3
|
+
## Authentication
|
|
4
|
+
|
|
5
|
+
Authenticate before making API calls:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
toggl auth
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
On a machine without a usable browser (SSH, VM, remote CI shell), use the manual flow. The printed login URL redirects to **`accounts.toggl.com/focus/cli/auth-code`** (not localhost) and shows a copyable authorization code:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
toggl auth --manual
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Non-interactive environments can pass the code directly (must be from the same shell session’s printed login link—PKCE requires matching verifier). Use **`--manual`** so token exchange uses the accounts callback redirect:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
toggl auth --manual --code 'YOUR_CODE'
|
|
21
|
+
toggl auth --code 'https://accounts.toggl.com/focus/cli/auth-code?code=YOUR_CODE'
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
The default `toggl auth` flow still uses `http://localhost:8716/callback` on the same machine and shows a branded success page in the browser tab.
|
|
25
|
+
|
|
26
|
+
The same flags work for `npx @toggl/mcp auth` when running the MCP package entrypoint outside the MCP host.
|
|
27
|
+
|
|
28
|
+
If the account has multiple workspaces, pass the workspace explicitly:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
toggl auth --workspace-id <workspace-id>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
When `--profile` is omitted, the CLI saves the account under an account-based profile name such as `hazem-12345` and makes it active. Use an explicit profile name only when the user asks for a specific name:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
toggl auth --profile <name>
|
|
38
|
+
toggl --profile <name> --json tasks list --project-id <project-id>
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Credentials are stored in `~/.toggl/focus-tools.json`. Sessions refresh automatically; re-run `toggl auth` to switch workspaces or after long inactivity.
|
|
42
|
+
|
|
43
|
+
## Profiles
|
|
44
|
+
|
|
45
|
+
List saved profiles:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
toggl --json profile list
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Show the active profile:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
toggl --json profile current
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Switch the default account and environment:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
toggl --json profile switch <profile>
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Remove a saved profile. With `--json` or when stdin/stdout is not a TTY, pass the profile name; in an interactive terminal you can omit it to pick from the list.
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
toggl --json profile remove <profile>
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## Workspaces
|
|
70
|
+
|
|
71
|
+
List cached workspaces:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
toggl --json workspace list
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Refresh workspace metadata from the account:
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
toggl --json workspace list --refresh
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
Switch the active workspace for the current profile. With `--json` or when not a TTY, pass the workspace id; in an interactive terminal you can omit it to pick from cached workspaces (refresh with `toggl workspace list --refresh` if needed).
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
toggl --json workspace switch <workspace-id>
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Override workspace for one call without changing the active profile:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
toggl --workspace-id <workspace-id> --json tasks list --project-id <project-id>
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
When a command returns unexpected missing data, verify the active profile, environment, and workspace before assuming the resource does not exist.
|
|
96
|
+
|
|
97
|
+
## Workspace settings
|
|
98
|
+
|
|
99
|
+
`workspace-settings update` expects `--data` with a top-level `payload` object whose **only** mutable workspace fields live under **`payload.settings`** (not alongside `payload` at the root). Discover keys and value shapes from `workspace-settings list` on the same workspace before patching.
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
toggl workspace-settings update --dry-run --data '{"payload":{"settings":{}}}'
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Skill and CLI Maintenance
|
|
106
|
+
|
|
107
|
+
Install or refresh the agent skill (delegates to the `skills` CLI installed with `@toggl/cli`):
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
toggl skill setup
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
After upgrading the CLI, run the same flow again so agents pick up skill changes:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
toggl skill sync
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Non-interactive setup can pass target agents and confirmations to the `skills` installer:
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
toggl skill setup --agent cursor --global --copy --yes
|
|
123
|
+
toggl skill setup --agent cursor codex --copy --yes
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Prefer the default symlink install over `--copy` so skill content stays aligned when you upgrade `@toggl/cli` without re-running setup.
|
|
127
|
+
|
|
128
|
+
Update a globally installed CLI:
|
|
129
|
+
|
|
130
|
+
```bash
|
|
131
|
+
toggl update
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Preview the update command without running it:
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
toggl update --dry-run
|
|
138
|
+
toggl --json update --dry-run
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
`toggl update` updates the CLI package only. Run `toggl skill setup` again to refresh the installed agent skill after updating.
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
# Command Contract
|
|
2
|
+
|
|
3
|
+
## Shape
|
|
4
|
+
|
|
5
|
+
Commands follow:
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
toggl [global flags] <group> … <subcommand> [flags]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Put global flags before the first group:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
toggl --json tasks list --project-id 436195
|
|
15
|
+
toggl --profile hazem-12345 projects list
|
|
16
|
+
toggl --workspace-id 356965 tasks list --project-id 436195
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
**Organization and shared data** use multi-segment paths (no top-level `org` command):
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
toggl organization invitations list
|
|
23
|
+
toggl organization workspaces list
|
|
24
|
+
toggl shared status get
|
|
25
|
+
toggl shared holidays list
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Core resources and actions:
|
|
29
|
+
|
|
30
|
+
| Resource | Actions |
|
|
31
|
+
| -------------- | ----------------------------------------------------------------------------------- |
|
|
32
|
+
| `tasks` | `list`, `get`, `create`, `update`, `delete`, and **`bulk`** subcommands (see below) |
|
|
33
|
+
| `projects` | `list`, `get`, `create`, `update`, `delete`, and **`bulk`** subcommands |
|
|
34
|
+
| `time-blocks` | `list`, `get`, `create`, `update`, `delete`, and **`bulk`** subcommands |
|
|
35
|
+
| `time-entries` | `list`, `start`, `stop`, and **`bulk`** subcommands |
|
|
36
|
+
| `statuses` | `list` |
|
|
37
|
+
| `users` | `list` |
|
|
38
|
+
|
|
39
|
+
Operations marked **`hidden: true`** in `@toggl/operations` (notably generated **calendar** and **scheduler** endpoints today) are skipped by `visibleOperations()` and do not register CLI/MCP commands.
|
|
40
|
+
|
|
41
|
+
Bulk mutations use a nested command: **`toggl <resource> bulk <verb>`** (for example `toggl tasks bulk patch`). MCP entity tools still use hyphenated `action` values such as `bulk-patch` — only the CLI path uses the nested form.
|
|
42
|
+
|
|
43
|
+
| Resource | `toggl <resource> bulk …` |
|
|
44
|
+
| -------------- | --------------------------------------------------------------------------- |
|
|
45
|
+
| `tasks` | `create`, `patch`, `delete`, `archive`, `restore`, `unarchive`, `duplicate` |
|
|
46
|
+
| `projects` | `patch`, `delete`, `archive`, `restore`, `unarchive` |
|
|
47
|
+
| `time-blocks` | `create`, `patch`, `delete` |
|
|
48
|
+
| `time-entries` | `create`, `patch`, `delete`, `restore` |
|
|
49
|
+
|
|
50
|
+
`list` commands also have the `ls` alias.
|
|
51
|
+
|
|
52
|
+
## Output
|
|
53
|
+
|
|
54
|
+
Successful responses go to stdout as JSON. Use `--json` for compact single-line JSON that is easy to parse:
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
toggl --json tasks list --project-id 436195
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Without `--json`, successful output is still JSON, but pretty-printed.
|
|
61
|
+
|
|
62
|
+
Validation errors, API errors, install failures, and update failures go to stderr. The process exits with `0` on success and `1` on error.
|
|
63
|
+
|
|
64
|
+
## Input
|
|
65
|
+
|
|
66
|
+
Prefer scalar flags for simple calls. Input field names map to kebab-case flags:
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
toggl --json tasks get --task-id 12345
|
|
70
|
+
toggl --json tasks list --project-id 436195 --status-id 243956
|
|
71
|
+
toggl --json time-entries list --date-from 2026-04-01 --date-to 2026-04-07
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
For `update` commands, payload fields use `--payload-<field>`:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
toggl --json tasks update --task-id 12345 --payload-name "New task name"
|
|
78
|
+
toggl --json tasks update --task-id 12345 --payload-status-id 270002
|
|
79
|
+
toggl --json projects update --project-id 436195 --payload-name "Renamed project"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Use `--data` for a full JSON body:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
toggl --json tasks create --data '{"name":"Write release notes","project_id":436195}'
|
|
86
|
+
toggl --json tasks update --data '{"task_id":12345,"payload":{"status_id":270002}}'
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Use `--data -` when shell quoting is fragile:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
printf '%s\n' '{"task_id":12345,"payload":{"name":"Renamed task"}}' | toggl --json tasks update --data -
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Use `--data-file <path>` when a payload already lives in a file:
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
toggl --json tasks create --data-file ./new-task.json
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Bulk endpoints expect JSON via `--data` or `--data-file` (arrays for patch-style bulk; objects with `ids` or `task_ids` for deletes/archives). Examples:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
toggl --json tasks bulk patch --dry-run --data '[{"id":111,"status_id":270002},{"id":222,"status_id":270002}]'
|
|
105
|
+
toggl --json projects bulk patch --data-file ./project-updates.json
|
|
106
|
+
toggl --json time-blocks bulk create --data '{"time_blocks":[{"task_id":12345,"start":"2026-04-01T09:00:00Z","duration":60}]}'
|
|
107
|
+
toggl --json time-entries bulk patch --data '[{"id":9001,"description":"Updated"}]'
|
|
108
|
+
toggl --json tasks bulk delete --data '{"ids":[111,222]}' --yes
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Interactive prompting
|
|
112
|
+
|
|
113
|
+
**`--interactive`** and **`--no-interactive`** are registered only when the operation’s catalog `cli.interactive` mode is not `hidden` (read-only operations default to `hidden`, so most lists do not expose the flag). On a TTY, **mutations** with `interactive: default` prompt for missing fields when you did not pass `--data`, `--data-file`, or scalar flags that satisfy the schema; **`--interactive`** opts into prompts for operations marked `interactive: available` (optional reads). Prompting is suppressed when you use `--json`, `--data`, or `--data-file`, when stdin/stdout is not a TTY, or when `CI` / `TOGGL_NON_INTERACTIVE` is set. **Bulk** commands whose payloads are arrays of objects (for example `tasks bulk create` with a `tasks` array, or `tasks bulk patch` whose body is an array of `{ id, … }`) walk **one object at a time**: you fill that entry’s fields (including optional details via the usual checkbox), then answer whether to add another—comma-separated text is not used for those structures (use `--data` / `--data-file` for batch JSON). Typed dates and colors show inline validation before the prompt accepts input; ISO calendar dates accept `YYYY-MM-DD` or slash-separated forms (normalized); datetimes must parse as ISO-like strings; hex colors accept `#RGB`, `#RRGGBB`, or bare hex digits. For many Focus ID fields (for example `project_id`, `task_id`, `client_id`, `tag_id`, `status_id`, `user_id`, `assignee_user_id`), interactive prompts use a searchable list backed by the Focus API (type to narrow results; optional IDs can often be skipped with "— Skip —"). Arrays of those IDs (for example `tag_ids`, `assignee_user_ids`, `org_user_ids`, `workspaces`, `roles`, `groups` on `users list`) load the first API page straight into a multi-select checklist; when the page may be truncated (or a filter is already active), an extra row offers **Filter list by name** to narrow results before selecting again. Required fields (or failed list calls) still fall back to comma-separated IDs; **optional** arrays auto-skip when the API returns nothing to pick—pass flags or `--data` if you need explicit IDs anyway. Workspace and role lists are filtered client-side when the org APIs do not accept a search string; groups use organization teams with server-side `filter` scoped to your active workspace when applicable. Comma-separated flags and `--data` still accept raw IDs for scripts and agents.
|
|
114
|
+
|
|
115
|
+
## Safety Flags
|
|
116
|
+
|
|
117
|
+
Use `--dry-run` to validate resolved input without making an API call:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
toggl tasks update --task-id 12345 --payload-status-id 270002 --dry-run
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Delete commands require `--yes`. Never add `--yes` unless the user clearly requested the destructive delete:
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
toggl --json tasks delete --task-id 12345 --yes
|
|
127
|
+
toggl --json projects delete --project-id 436195 --yes
|
|
128
|
+
toggl --json time-blocks delete --task-id 12345 --time-block-id 67890 --yes
|
|
129
|
+
toggl --json tasks bulk delete --data '{"ids":[111,222]}' --yes
|
|
130
|
+
toggl --json projects bulk delete --data '{"ids":[436195,436196]}' --yes
|
|
131
|
+
toggl --json time-blocks bulk delete --data '{"ids":[101,102]}' --yes
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Dates
|
|
135
|
+
|
|
136
|
+
Date range flags accept:
|
|
137
|
+
|
|
138
|
+
- `YYYY-MM-DD`, expanded by the CLI to full UTC-day boundaries.
|
|
139
|
+
- RFC 3339 datetimes, used as provided.
|
|
140
|
+
|
|
141
|
+
Examples:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
toggl --json time-entries list --date-from 2026-04-01 --date-to 2026-04-07
|
|
145
|
+
toggl --json time-blocks list --date-from 2026-04-01T08:00:00+03:00 --date-to 2026-04-01T17:00:00+03:00
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Discovery
|
|
149
|
+
|
|
150
|
+
When a command shape is unclear, open help on each segment:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
toggl --help
|
|
154
|
+
toggl tasks --help
|
|
155
|
+
toggl tasks bulk --help
|
|
156
|
+
toggl tasks update --help
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Use **`--dry-run`** on a generated command to print `operation` (catalog id) and validated `input` without calling the API.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Focus Concepts
|
|
2
|
+
|
|
3
|
+
Use this file to understand how Toggl Focus entities relate to each other before choosing CLI commands.
|
|
4
|
+
|
|
5
|
+
## Mental Model
|
|
6
|
+
|
|
7
|
+
Toggl Focus is organized around work that happens inside a workspace:
|
|
8
|
+
|
|
9
|
+
```text
|
|
10
|
+
Environment/Profile
|
|
11
|
+
-> Workspace
|
|
12
|
+
-> Projects
|
|
13
|
+
-> Tasks
|
|
14
|
+
-> Time blocks
|
|
15
|
+
-> Time entries
|
|
16
|
+
-> Statuses
|
|
17
|
+
-> Users
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The active auth profile, environment, and workspace determine which data every command can see. If a project, task, status, or user appears missing, verify the profile and workspace before assuming the resource does not exist.
|
|
21
|
+
|
|
22
|
+
## Entities
|
|
23
|
+
|
|
24
|
+
### Profile
|
|
25
|
+
|
|
26
|
+
A profile stores credentials and the selected workspace. Use profiles when the user needs separate accounts or workspace contexts.
|
|
27
|
+
|
|
28
|
+
### Workspace
|
|
29
|
+
|
|
30
|
+
A workspace is the top-level Focus context for projects, tasks, statuses, users, time entries, and time blocks. Most IDs only make sense inside the active workspace.
|
|
31
|
+
|
|
32
|
+
Use workspace commands when the agent needs to list available workspaces, refresh workspace metadata, switch the default workspace, or override the workspace for one command.
|
|
33
|
+
|
|
34
|
+
### Project
|
|
35
|
+
|
|
36
|
+
A project groups related tasks. When a user mentions a project by name, list projects first to resolve the project ID before listing or creating tasks.
|
|
37
|
+
|
|
38
|
+
### Task
|
|
39
|
+
|
|
40
|
+
A task is the main work item. Tasks belong to projects and can move through statuses. Most agent workflows start by resolving a task ID from a project and task name.
|
|
41
|
+
|
|
42
|
+
Use task commands for creating work items, checking details, renaming tasks, changing status, and deleting tasks after explicit confirmation.
|
|
43
|
+
|
|
44
|
+
### Status
|
|
45
|
+
|
|
46
|
+
A status represents a task workflow state, such as todo, in progress, review, blocked, or done. Status IDs are workspace-specific.
|
|
47
|
+
|
|
48
|
+
When the user asks to move a task to a named status, list statuses first and use the matching status ID in the task update.
|
|
49
|
+
|
|
50
|
+
### User
|
|
51
|
+
|
|
52
|
+
A user is a workspace member. Use user commands to resolve member IDs when a workflow needs a person, assignee, owner, or reviewer.
|
|
53
|
+
|
|
54
|
+
Do not guess user IDs from names or emails. List users and confirm ambiguous matches.
|
|
55
|
+
|
|
56
|
+
### Time Entry
|
|
57
|
+
|
|
58
|
+
A time entry represents actual tracked time. Starting a time entry begins the running timer; stopping it ends the current timer.
|
|
59
|
+
|
|
60
|
+
Use time entries when the user wants to track work, start a break, stop tracking, or inspect actual logged time.
|
|
61
|
+
|
|
62
|
+
### Time Block
|
|
63
|
+
|
|
64
|
+
A time block represents scheduled or planned work. Time blocks usually belong to a task and have explicit start/end times.
|
|
65
|
+
|
|
66
|
+
Use time blocks when the user wants to schedule, plan, move, inspect, or delete calendar-like Focus blocks.
|
|
67
|
+
|
|
68
|
+
## Choosing the Right Command
|
|
69
|
+
|
|
70
|
+
If the user wants to:
|
|
71
|
+
|
|
72
|
+
- Find work: list projects, then list tasks for the project.
|
|
73
|
+
- Create work: resolve the project ID, then create a task.
|
|
74
|
+
- Move work through a workflow: resolve the task ID and status ID, then update the task.
|
|
75
|
+
- Track actual time: resolve the task ID, then start a time entry.
|
|
76
|
+
- Stop tracking: stop the current time entry.
|
|
77
|
+
- Schedule planned work: resolve the task ID, then create a time block.
|
|
78
|
+
- Find people: list users.
|
|
79
|
+
- Change workspace context: list or switch workspaces, or pass `--workspace-id`.
|
|
80
|
+
|
|
81
|
+
When intent is ambiguous, prefer lookup commands and ask before mutating.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Projects
|
|
2
|
+
|
|
3
|
+
Use project commands to list Focus projects, resolve project IDs, create projects, rename projects, and delete projects.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
List projects:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
toggl --json projects list
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
Get one project:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
toggl --json projects get --project-id <project-id>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Create a project:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
toggl --json projects create --data '{"name":"Q3 Planning","workspace_id":356965}'
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Rename a project:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
toggl --json projects update --project-id <project-id> --payload-name "Q3 Planning"
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Delete a project only after explicit user confirmation:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
toggl --json projects delete --project-id <project-id> --yes
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
## Agent Workflow
|
|
38
|
+
|
|
39
|
+
When the user provides a project name, list projects and resolve the project ID before acting:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
toggl --json projects list
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
When creating tasks, pass the resolved project ID to `tasks create`:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
toggl --json tasks create --data '{"name":"Task name","project_id":436195}'
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Project deletion is destructive. Confirm the exact project ID and name before using `--yes`.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Rates and billables
|
|
2
|
+
|
|
3
|
+
There are **two different systems**. Pick the one that matches where the user is working.
|
|
4
|
+
|
|
5
|
+
## Focus billable / labor rate schedules (this CLI)
|
|
6
|
+
|
|
7
|
+
Workspace and project **billable rate schedules** live under `toggl rates billable …` (nested under `rates`; same endpoints as the former top-level `billable-rates` command). **Labor cost rate** schedules use `toggl rates labor …` when your generated catalog includes them. Typical verbs: upserts, ranged deletes, conflict checks, and reads for workspace/project and per-user overlays (`get-*`, `upsert-*`, `delete-*-range`, `check-*-conflicts`). Use these when the task is **Focus billing configuration** or **Focus API rate data**.
|
|
8
|
+
|
|
9
|
+
## Track workspace assignment / Members UI
|
|
10
|
+
|
|
11
|
+
**Track** exposes member and workspace defaults such as **`track_billable_rate`** (and related assignment flows in the **Members** area of the Track product). That path is **not** the Focus `rates billable` endpoints. If someone is changing rates **only in Track’s member/project assignment UI**, use Track’s APIs or the Track web app — do not assume the Focus CLI commands wrote the same field.
|
|
12
|
+
|
|
13
|
+
**Rule of thumb:** Focus CLI `rates billable` (and `rates labor` when present) ↔ Focus billing schedules. Track member default rate ↔ Track/Members and Track APIs.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# Reports (`reports`)
|
|
2
|
+
|
|
3
|
+
## `get-workload` vs `get-flexq-data`
|
|
4
|
+
|
|
5
|
+
- **`reports get-workload`** — built-in workload report. Use for utilization, capacity, or team workload views that match that report.
|
|
6
|
+
- **`reports get-flexq-data`** — flexible FlexQ query. Use when you need custom attributes, aggregations, groupings, filters, sorts, or transforms.
|
|
7
|
+
|
|
8
|
+
Both commands share the same JSON shape: a top-level `payload` whose body includes every required key (`aggregation_filters`, `aggregations`, `attributes`, `filters`, `groupings`, `limit`, `ordinations`, `pagination`, `period`, `transformations`). Arrays may be empty for a minimal valid body; real analysis needs a meaningful `period` and populated dimensions.
|
|
9
|
+
|
|
10
|
+
## Minimal `--data` (validate with `--dry-run`)
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
toggl reports get-workload --dry-run --data '{"payload":{"aggregation_filters":[],"aggregations":[],"attributes":[],"filters":[],"groupings":[],"limit":100,"ordinations":[],"pagination":{"page":1,"per_page":50},"period":{"from":"","preset":"","to":""},"transformations":[]}}'
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Use the same JSON for `reports get-flexq-data`, changing only the subcommand.
|
|
17
|
+
|
|
18
|
+
Prefer `--data-file` or `--data -` when editing larger FlexQ bodies to avoid shell quoting mistakes.
|