clickup-cli 1.6.0__tar.gz → 1.7.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.
- clickup_cli-1.7.0/.claude/agents/test-writer.md +44 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.claude/skills/add-command.md +14 -8
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.claude/skills/clickup-cli.md +4 -12
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/CHANGELOG.md +7 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/CLAUDE.md +27 -16
- clickup_cli-1.7.0/CODE_OF_CONDUCT.md +27 -0
- clickup_cli-1.7.0/CONTRIBUTING.md +74 -0
- clickup_cli-1.7.0/FEATURE-GAP-ANALYSIS.md +281 -0
- clickup_cli-1.7.0/INTEGRATION.md +35 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/PKG-INFO +33 -16
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/README.md +32 -15
- clickup_cli-1.7.0/RELEASE.md +17 -0
- clickup_cli-1.7.0/SECURITY.md +26 -0
- clickup_cli-1.7.0/TROUBLESHOOTING.md +29 -0
- clickup_cli-1.7.0/docs/superpowers/README.md +18 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/docs/superpowers/plans/2026-04-18-gsd-public-repo-autonomous-rollout.md +14 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/docs/superpowers/specs/2026-04-18-gsd-public-repo-autonomous-design.md +18 -0
- clickup_cli-1.7.0/docs/superpowers/specs/2026-04-19-core-workflow-parity-design.md +113 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/__init__.py +1 -1
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/cli.py +7 -4
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/__init__.py +4 -0
- clickup_cli-1.7.0/src/clickup_cli/commands/fields.py +86 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/privacy.py +24 -3
- clickup_cli-1.7.0/src/clickup_cli/commands/spaces.py +377 -0
- clickup_cli-1.7.0/src/clickup_cli/commands/task_types.py +66 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/tasks.py +8 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/tasks_internal/__init__.py +4 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/tasks_internal/parser.py +214 -15
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/tasks_internal/read.py +24 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/tasks_internal/shared.py +32 -2
- clickup_cli-1.7.0/src/clickup_cli/commands/tasks_internal/write.py +457 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_cli.py +127 -1
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_command_manifest.py +14 -1
- clickup_cli-1.7.0/tests/test_commands_metadata.py +128 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_commands_misc.py +10 -5
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_commands_spaces_lists_folders.py +143 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_commands_tasks.py +381 -3
- clickup_cli-1.6.0/.claude/agents/test-writer.md +0 -39
- clickup_cli-1.6.0/CONTRIBUTING.md +0 -54
- clickup_cli-1.6.0/src/clickup_cli/commands/spaces.py +0 -194
- clickup_cli-1.6.0/src/clickup_cli/commands/tasks_internal/write.py +0 -209
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.claude/agents/api-compatibility-checker.md +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.claude/settings.json +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.claude/skills/changelog/SKILL.md +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.claude/skills/release/SKILL.md +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.claude/skills/validate-output/SKILL.md +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.github/workflows/ci.yml +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.gitignore +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/.mcp.json +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/LICENSE +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/clickup-config.example.json +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/pyproject.toml +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/scripts/validate-cli-output.sh +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/__main__.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/client.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/comments.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/docs.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/folders.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/init.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/lists.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/tags.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/commands/team.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/config.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/helpers.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/src/clickup_cli/runtime.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/command_fakes.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/conftest.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_client.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_commands_docs_comments.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_config.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_helpers.py +0 -0
- {clickup_cli-1.6.0 → clickup_cli-1.7.0}/tests/test_tasks_facade.py +0 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: test-writer
|
|
3
|
+
description: Generate tests for clickup-cli commands following the repo's current split test layout and command-fake patterns
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Test Writer Agent
|
|
7
|
+
|
|
8
|
+
You generate tests for the clickup-cli project.
|
|
9
|
+
|
|
10
|
+
## Before Writing Tests
|
|
11
|
+
|
|
12
|
+
1. Read `tests/conftest.py` for the test config setup pattern
|
|
13
|
+
2. Read the relevant split test files in `tests/` for the command family you are changing
|
|
14
|
+
3. Read `tests/command_fakes.py` for shared fake client helpers
|
|
15
|
+
4. Read the source file you're writing tests for
|
|
16
|
+
|
|
17
|
+
## Conventions
|
|
18
|
+
|
|
19
|
+
- Use `unittest.TestCase` classes (matching existing style)
|
|
20
|
+
- Use the fake client helpers from `tests/command_fakes.py` (for example `FlexClient`) — do NOT make real HTTP calls
|
|
21
|
+
- Use `unittest.mock.patch` and `MagicMock` for things FakeClient doesn't cover
|
|
22
|
+
- Use `argparse.Namespace` to construct fake args
|
|
23
|
+
- Test these for every command:
|
|
24
|
+
- Argument parsing (parser accepts the expected args)
|
|
25
|
+
- `--dry-run` behavior (mutating commands return preview, don't call API)
|
|
26
|
+
- Normal execution with mocked responses
|
|
27
|
+
- Error cases (missing required args, API errors)
|
|
28
|
+
- All output assertions should check JSON structure
|
|
29
|
+
- Put tests in the appropriate existing split test file when possible:
|
|
30
|
+
- `tests/test_cli.py` for parser/dispatch behavior
|
|
31
|
+
- `tests/test_command_manifest.py` for manifest wiring
|
|
32
|
+
- `tests/test_tasks_facade.py` for tasks facade/tasks_internal regressions
|
|
33
|
+
- `tests/test_commands_tasks.py`, `tests/test_commands_docs_comments.py`, `tests/test_commands_spaces_lists_folders.py`, or `tests/test_commands_misc.py` for handler coverage
|
|
34
|
+
|
|
35
|
+
## Example Pattern
|
|
36
|
+
|
|
37
|
+
```python
|
|
38
|
+
class TestTasksSearch(unittest.TestCase):
|
|
39
|
+
def test_search_dry_run(self):
|
|
40
|
+
client = FlexClient(dry_run=True)
|
|
41
|
+
args = Namespace(query="test", space="testspace", ...)
|
|
42
|
+
result = cmd_tasks_search(client, args)
|
|
43
|
+
self.assertIn("dry_run", result)
|
|
44
|
+
```
|
|
@@ -11,6 +11,7 @@ Follow these steps in order when adding a new command or subcommand.
|
|
|
11
11
|
|
|
12
12
|
- If this is a new command group, create `src/clickup_cli/commands/<group>.py`
|
|
13
13
|
- If extending an existing group, add the handler function to the existing file
|
|
14
|
+
- For `tasks`, keep `src/clickup_cli/commands/tasks.py` as the public facade and put new parser/read/write internals under `src/clickup_cli/commands/tasks_internal/` when appropriate
|
|
14
15
|
- Handler signature: `def cmd_<group>_<command>(client, args):`
|
|
15
16
|
- Return a dict (will be output as JSON)
|
|
16
17
|
- Mutating commands must check `client.dry_run` and return a dry-run preview instead of calling the API
|
|
@@ -19,7 +20,7 @@ Follow these steps in order when adding a new command or subcommand.
|
|
|
19
20
|
|
|
20
21
|
- Each command module owns its parser via `register_parser(subparsers, F)`
|
|
21
22
|
- If extending an existing group, add the new subparser inside the existing `register_parser()`
|
|
22
|
-
- If creating a new group,
|
|
23
|
+
- If creating a new group, expose a `COMMAND_MANIFEST` with `group`, `register_parser`, and `handlers`
|
|
23
24
|
- Add the subparser with:
|
|
24
25
|
- `description=` — what this command does
|
|
25
26
|
- `epilog=` — usage examples (at least 2)
|
|
@@ -30,14 +31,14 @@ Follow these steps in order when adding a new command or subcommand.
|
|
|
30
31
|
## 3. Register the handler
|
|
31
32
|
|
|
32
33
|
- Open `src/clickup_cli/commands/__init__.py`
|
|
33
|
-
-
|
|
34
|
-
-
|
|
34
|
+
- Update the owning module's `COMMAND_MANIFEST["handlers"]`
|
|
35
|
+
- For new command groups, import the group's `COMMAND_MANIFEST` and add it to `COMMAND_MANIFESTS`
|
|
36
|
+
- Do not hand-edit `HANDLERS`; it is derived from the manifests
|
|
35
37
|
|
|
36
|
-
## 3b.
|
|
38
|
+
## 3b. Root parser wiring
|
|
37
39
|
|
|
38
|
-
-
|
|
39
|
-
-
|
|
40
|
-
- Call it in `build_parser()` alongside the other `register_parser()` calls
|
|
40
|
+
- `cli.py` already iterates `COMMAND_MANIFESTS`
|
|
41
|
+
- New groups become available once their manifest is added to `src/clickup_cli/commands/__init__.py`
|
|
41
42
|
|
|
42
43
|
## 4. Write help text
|
|
43
44
|
|
|
@@ -47,7 +48,11 @@ Follow these steps in order when adding a new command or subcommand.
|
|
|
47
48
|
|
|
48
49
|
## 5. Add tests
|
|
49
50
|
|
|
50
|
-
-
|
|
51
|
+
- Update the relevant split test module in `tests/`:
|
|
52
|
+
- `tests/test_cli.py` for parser/dispatch behavior
|
|
53
|
+
- `tests/test_command_manifest.py` for manifest wiring changes
|
|
54
|
+
- `tests/test_tasks_facade.py` when changing the tasks facade/tasks_internal split
|
|
55
|
+
- `tests/test_commands_<group>.py` or the nearest shared command-family test file for handler coverage
|
|
51
56
|
- Test argument parsing (parser accepts the new args)
|
|
52
57
|
- Test dry-run behavior (mutating commands return dry-run preview)
|
|
53
58
|
- Test core logic with `FakeClient`
|
|
@@ -73,3 +78,4 @@ scripts/validate-cli-output.sh
|
|
|
73
78
|
## 7. Update the skill (if needed)
|
|
74
79
|
|
|
75
80
|
If the new command adds a new workflow pattern, update `.claude/skills/clickup-cli.md` with a usage example.
|
|
81
|
+
Prefer pointing contributors to `README.md` or `CONTRIBUTING.md` instead of duplicating general repo guidance here.
|
|
@@ -32,7 +32,7 @@ Global flags (`--pretty`, `--dry-run`, `--debug`) can appear before or after the
|
|
|
32
32
|
- Successful output is always JSON on stdout
|
|
33
33
|
- Errors go to stderr with non-zero exit code
|
|
34
34
|
- Use `--pretty` for indented JSON when reading output
|
|
35
|
-
-
|
|
35
|
+
- On `tasks list` and `tasks search`, default output is compact; `--full` returns full task objects, while `--fields` lets you request a smaller custom shape
|
|
36
36
|
|
|
37
37
|
## Common Workflows
|
|
38
38
|
|
|
@@ -46,6 +46,7 @@ clickup tasks get <task_id>
|
|
|
46
46
|
```bash
|
|
47
47
|
clickup --dry-run tasks create --space <space_name> --name "Fix auth" --desc "Details"
|
|
48
48
|
clickup tasks create --space <space_name> --name "Fix auth" --desc "Details"
|
|
49
|
+
clickup tasks create --list <list_id> --name "Fix auth" --desc "Details"
|
|
49
50
|
```
|
|
50
51
|
|
|
51
52
|
### Update a task (including tags, assignees, custom fields)
|
|
@@ -107,21 +108,12 @@ the ClickUp UI. Hits the v3 ACLs endpoint.
|
|
|
107
108
|
|
|
108
109
|
## Configuration
|
|
109
110
|
|
|
110
|
-
|
|
111
|
-
1. `CLICKUP_CONFIG_PATH` env var
|
|
112
|
-
2. `~/.config/clickup-cli/config.json`
|
|
113
|
-
3. `clickup-config.json` in current directory
|
|
114
|
-
|
|
115
|
-
Or use environment variables only:
|
|
116
|
-
- `CLICKUP_API_TOKEN` (required)
|
|
117
|
-
- `CLICKUP_WORKSPACE_ID` (auto-detected for single-workspace accounts)
|
|
118
|
-
|
|
119
|
-
Run `clickup init` for interactive setup.
|
|
111
|
+
Use `clickup init` for interactive setup. For config file shape, resolution order, and contributor-facing setup notes, prefer `README.md` and `CONTRIBUTING.md` over this repo-local skill.
|
|
120
112
|
|
|
121
113
|
## Key Behaviors
|
|
122
114
|
|
|
123
115
|
- `tasks get` auto-fetches comments (use `--no-comments` to skip)
|
|
124
116
|
- `tasks search` auto-detects task ID patterns (e.g. "PROJ-39") and applies prefix filtering
|
|
125
|
-
- `tasks create`
|
|
117
|
+
- `tasks create` accepts `--space` or `--list`; when only `--list` is provided, the CLI auto-infers the matching configured space alias before resolving the target list
|
|
126
118
|
- Tag names are auto-lowercased (ClickUp API requirement)
|
|
127
119
|
- Doc ID ≠ page ID — always use `docs pages` to find page IDs first
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.7.0 (2026-04-20)
|
|
4
|
+
|
|
5
|
+
- **Metadata discovery and custom-field lookup are easier to drive from the CLI.** New discovery flows cover field and task-type metadata, and task search can now target custom fields directly instead of forcing clients to pre-resolve everything out of band.
|
|
6
|
+
- **Task creation and task membership operations now match more of ClickUp's native surface area.** `tasks create` gained richer payload parity, task link operations are exposed directly, and multi-list task flows support adding and removing list memberships without leaving the CLI.
|
|
7
|
+
- **Space management reached CRUD parity.** Spaces now support the same create, read, update, and delete coverage already available on other container types, keeping workspace-level automation inside one tool.
|
|
8
|
+
- **Docs and help text were refreshed for agent-first discoverability.** Command help and supporting documentation were tightened so `--help` remains enough to discover the newer workflows without external context.
|
|
9
|
+
|
|
3
10
|
## 1.6.0 (2026-04-18)
|
|
4
11
|
|
|
5
12
|
- **Space-scoped task search and docs filtering now match the requested scope.** `tasks search --space <alias-or-id>` expands to every list in the resolved space, preserves explicit `--list` / `--folder` overrides, handles archived-only and empty-space edge cases without widening scope, and keeps the existing dry-run envelope intact. `docs list` and `docs create` now resolve `--space` through the shared alias-or-raw-ID path and fail fast on bad non-numeric space names.
|
|
@@ -11,10 +11,15 @@ src/clickup_cli/
|
|
|
11
11
|
├── cli.py # root parser, dispatch, main() — delegates to command modules
|
|
12
12
|
├── client.py # ClickUpClient API wrapper (rate limiting, dry-run, debug)
|
|
13
13
|
├── config.py # Config loader (lazy, fallback chain, workspace auto-detect)
|
|
14
|
-
├── helpers.py # output(), error(), compact_task(), etc.
|
|
14
|
+
├── helpers.py # output(), error(), compact_task(), add_id_argument(), etc.
|
|
15
15
|
└── commands/
|
|
16
|
-
├── __init__.py # HANDLERS
|
|
17
|
-
├── tasks.py #
|
|
16
|
+
├── __init__.py # COMMAND_MANIFESTS registry + derived HANDLERS map
|
|
17
|
+
├── tasks.py # compatibility facade for tasks entrypoints
|
|
18
|
+
├── tasks_internal/
|
|
19
|
+
│ ├── parser.py # tasks parser registration
|
|
20
|
+
│ ├── read.py # list/get/search handlers
|
|
21
|
+
│ ├── write.py # create/update/delete/move/merge/depend handlers
|
|
22
|
+
│ └── shared.py # task-scoped resolution helpers
|
|
18
23
|
├── comments.py # comments parser + handlers (list/add/update/delete/thread/reply)
|
|
19
24
|
├── docs.py # docs parser + handlers (list/get/create/pages/get-page/edit-page/create-page)
|
|
20
25
|
├── folders.py # folders parser + handlers (list/get/create/update/delete/privacy)
|
|
@@ -25,7 +30,7 @@ src/clickup_cli/
|
|
|
25
30
|
└── init.py # clickup init setup command
|
|
26
31
|
```
|
|
27
32
|
|
|
28
|
-
Each command
|
|
33
|
+
Each command group exposes a `COMMAND_MANIFEST` with `group`, `register_parser`, and `handlers`. `cli.py` builds the root parser by iterating `COMMAND_MANIFESTS`, and `commands/__init__.py` derives the dispatch map from those manifests.
|
|
29
34
|
|
|
30
35
|
## Argument Pattern: Positional + Flag Aliases
|
|
31
36
|
|
|
@@ -46,7 +51,7 @@ When adding new commands with ID arguments, always use `add_id_argument()` inste
|
|
|
46
51
|
|
|
47
52
|
## Space Inference
|
|
48
53
|
|
|
49
|
-
`tasks create`
|
|
54
|
+
`tasks create` accepts either `--space` or `--list`. If only `--list` is provided, it lazily infers the matching configured space alias from `GET /v2/list/{id}` before resolving the target list.
|
|
50
55
|
|
|
51
56
|
## Development Setup
|
|
52
57
|
|
|
@@ -61,15 +66,21 @@ scripts/validate-cli-output.sh # verify JSON stdout contract
|
|
|
61
66
|
|
|
62
67
|
```
|
|
63
68
|
tests/
|
|
64
|
-
├── conftest.py
|
|
65
|
-
├──
|
|
66
|
-
├──
|
|
67
|
-
├──
|
|
68
|
-
├──
|
|
69
|
-
|
|
69
|
+
├── conftest.py # test config setup before clickup_cli loads
|
|
70
|
+
├── command_fakes.py # shared fake client helpers for command tests
|
|
71
|
+
├── test_cli.py # parser, dispatch, global flags, resolve_id_args
|
|
72
|
+
├── test_client.py # ClickUpClient behavior
|
|
73
|
+
├── test_command_manifest.py # manifest registry + derived handlers
|
|
74
|
+
├── test_commands_tasks.py # task command handlers
|
|
75
|
+
├── test_commands_docs_comments.py # docs/comments handlers
|
|
76
|
+
├── test_commands_spaces_lists_folders.py # spaces/lists/folders handlers
|
|
77
|
+
├── test_commands_misc.py # tags/team/init coverage
|
|
78
|
+
├── test_tasks_facade.py # tasks facade -> tasks_internal regression coverage
|
|
79
|
+
├── test_config.py # config loading
|
|
80
|
+
└── test_helpers.py # helpers and pagination utilities
|
|
70
81
|
```
|
|
71
82
|
|
|
72
|
-
|
|
83
|
+
See `README.md` and `CONTRIBUTING.md` for contributor-facing usage and workflow details; keep this file focused on repo-local development conventions.
|
|
73
84
|
|
|
74
85
|
## CI
|
|
75
86
|
|
|
@@ -78,13 +89,13 @@ GitHub Actions (`ci.yml`): lint + test on Python 3.9, 3.11, 3.13. Runs on push t
|
|
|
78
89
|
## Adding a New Command
|
|
79
90
|
|
|
80
91
|
1. Create or extend a file in `src/clickup_cli/commands/`
|
|
81
|
-
2. Add
|
|
82
|
-
3.
|
|
83
|
-
4.
|
|
92
|
+
2. Add or update that group's `COMMAND_MANIFEST` (`group`, `register_parser`, `handlers`)
|
|
93
|
+
3. If it's a new command group, import its manifest in `commands/__init__.py` and add it to `COMMAND_MANIFESTS`
|
|
94
|
+
4. For `tasks`, keep the public facade in `commands/tasks.py` and put parser/read/write internals in `commands/tasks_internal/` when extending the split structure
|
|
84
95
|
5. Add detailed `--help` text (description + epilog with examples)
|
|
85
96
|
6. Mutating commands must support `--dry-run`
|
|
86
97
|
7. All output goes to stdout as JSON, errors to stderr
|
|
87
|
-
8. Add tests in `tests/`
|
|
98
|
+
8. Add tests in the relevant split test module under `tests/`
|
|
88
99
|
|
|
89
100
|
## Rules
|
|
90
101
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Code of Conduct
|
|
2
|
+
|
|
3
|
+
## Our Standard
|
|
4
|
+
|
|
5
|
+
Participation in this project should stay respectful, constructive, and focused on improving the software.
|
|
6
|
+
|
|
7
|
+
Examples of expected behavior:
|
|
8
|
+
|
|
9
|
+
- Be respectful in issues, pull requests, and reviews
|
|
10
|
+
- Assume good intent and discuss technical disagreements directly
|
|
11
|
+
- Share actionable feedback instead of personal attacks
|
|
12
|
+
- Respect privacy and avoid posting secrets or private workspace data
|
|
13
|
+
|
|
14
|
+
Examples of unacceptable behavior:
|
|
15
|
+
|
|
16
|
+
- Harassment, discrimination, or intimidation
|
|
17
|
+
- Personal insults or bad-faith escalation
|
|
18
|
+
- Publishing someone else's private information without permission
|
|
19
|
+
- Spamming, trolling, or deliberately derailing project discussions
|
|
20
|
+
|
|
21
|
+
## Enforcement
|
|
22
|
+
|
|
23
|
+
Project maintainers may remove, edit, or reject contributions and discussions that do not meet these standards.
|
|
24
|
+
|
|
25
|
+
## Reporting
|
|
26
|
+
|
|
27
|
+
If you experience or observe unacceptable behavior, contact the maintainers through the repository's available contact channels.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Contributing
|
|
2
|
+
|
|
3
|
+
Thanks for your interest in clickup-cli.
|
|
4
|
+
|
|
5
|
+
## Getting Started
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
git clone https://github.com/efetoker/clickup-cli.git
|
|
9
|
+
cd clickup-cli
|
|
10
|
+
pip install -e ".[dev]"
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Running Tests
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pytest -v
|
|
17
|
+
scripts/validate-cli-output.sh
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Current suite shape:
|
|
21
|
+
|
|
22
|
+
- `tests/test_cli.py` — parser, dispatch, global flags, ID alias resolution
|
|
23
|
+
- `tests/test_client.py` — API wrapper behavior, dry-run, debug, retries
|
|
24
|
+
- `tests/test_command_manifest.py` — manifest-derived registration and handlers
|
|
25
|
+
- `tests/test_commands_tasks.py` — task commands and task-specific behavior
|
|
26
|
+
- `tests/test_commands_docs_comments.py` — docs and comments commands
|
|
27
|
+
- `tests/test_commands_spaces_lists_folders.py` — spaces, lists, folders, privacy
|
|
28
|
+
- `tests/test_commands_misc.py` — tags, team, init, misc dispatch coverage
|
|
29
|
+
- `tests/test_config.py` — config loading and fallback rules
|
|
30
|
+
- `tests/test_helpers.py` — stdout/stderr helpers, task formatting, pagination helpers
|
|
31
|
+
- `tests/test_tasks_facade.py` — task facade exports
|
|
32
|
+
|
|
33
|
+
At the time of writing, `pytest --collect-only -q` collects 397 tests.
|
|
34
|
+
|
|
35
|
+
## Linting
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
ruff check src/ tests/
|
|
39
|
+
ruff format src/ tests/
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Guidelines
|
|
43
|
+
|
|
44
|
+
- **JSON stdout, errors to stderr** — all commands follow this convention
|
|
45
|
+
- **Dry-run on mutations** — every mutating command must support `--dry-run`
|
|
46
|
+
- **Help text is documentation** — `--help` should be self-sufficient for discovering usage
|
|
47
|
+
- **No workspace-specific values** — help text and source must not contain hardcoded workspace IDs, space names, or user data
|
|
48
|
+
- **Tests required** — new commands need test coverage in `tests/`
|
|
49
|
+
|
|
50
|
+
## Adding a New Command
|
|
51
|
+
|
|
52
|
+
1. Create or extend a file in `src/clickup_cli/commands/`
|
|
53
|
+
2. Keep parser registration and handlers in the same command module, or behind the existing task facade/internal split when working on tasks
|
|
54
|
+
3. Expose a `COMMAND_MANIFEST` from that module and add it to `COMMAND_MANIFESTS` in `src/clickup_cli/commands/__init__.py`
|
|
55
|
+
4. Let the derived `HANDLERS` map pick up handlers from the manifest instead of maintaining a separate manual registry
|
|
56
|
+
5. Use `add_id_argument()` from `helpers.py` for positional ID arguments so both positional and `--flag` forms work
|
|
57
|
+
6. Add self-sufficient `--help` text with examples, return-shape notes, and `--dry-run` guidance for mutating commands
|
|
58
|
+
7. Add or update focused tests in the relevant `tests/test_*.py` file
|
|
59
|
+
|
|
60
|
+
## Submitting Changes
|
|
61
|
+
|
|
62
|
+
1. Fork the repo and create a feature branch
|
|
63
|
+
2. Make your changes with tests
|
|
64
|
+
3. Run `pytest -v`, `ruff check src/ tests/`, and `scripts/validate-cli-output.sh`
|
|
65
|
+
4. Open a PR with a clear description of what changed and why
|
|
66
|
+
|
|
67
|
+
## Maintainer Workflows
|
|
68
|
+
|
|
69
|
+
- Maintainer release steps live in [RELEASE.md](RELEASE.md)
|
|
70
|
+
- Public support and disclosure docs live in `README.md`, `SECURITY.md`, `CODE_OF_CONDUCT.md`, `INTEGRATION.md`, and `TROUBLESHOOTING.md`
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
By contributing, you agree that your contributions will be licensed under the MIT License.
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
# ClickUp CLI Feature Gap Analysis
|
|
2
|
+
|
|
3
|
+
> Historical backlog inventory for public repo readers. This file tracks candidate future work and gap sizing; it is not the active implementation spec for the current selected milestone slice.
|
|
4
|
+
|
|
5
|
+
> Authority note: use this file for backlog-level gap context. For the currently chosen design slice, see `docs/superpowers/README.md` and the linked spec there.
|
|
6
|
+
|
|
7
|
+
## Contents
|
|
8
|
+
|
|
9
|
+
- [Purpose](#purpose)
|
|
10
|
+
- [Current repo coverage snapshot](#current-repo-coverage-snapshot)
|
|
11
|
+
- [Method / sources](#method--sources)
|
|
12
|
+
- [Gaps by area](#gaps-by-area)
|
|
13
|
+
- [Final priority summary](#final-priority-summary)
|
|
14
|
+
- [Recommended sequencing principles](#recommended-sequencing-principles)
|
|
15
|
+
- [Appendix: concise source list](#appendix-concise-source-list)
|
|
16
|
+
|
|
17
|
+
## Purpose
|
|
18
|
+
|
|
19
|
+
This document identifies the largest feature gaps between the current `clickup-cli` repository and ClickUp's public API and broader product surface. It is intended to answer one question clearly: what should this repo add next, and which missing areas are confirmed, uncertain, or lower-value right now.
|
|
20
|
+
|
|
21
|
+
## Current repo coverage snapshot
|
|
22
|
+
|
|
23
|
+
The repo already covers a solid core developer workflow surface:
|
|
24
|
+
|
|
25
|
+
- Tasks: `list`, `get`, `create`, `update`, `search`, `delete`, `move`, `merge`, `depend`, linked-task management, multi-list operations
|
|
26
|
+
- Comments: task comments only via `list`, `add`, `update`, `delete`, `thread`, `reply`
|
|
27
|
+
- Docs/pages: doc list/get/create, page list/get/create/edit
|
|
28
|
+
- Hierarchy: spaces/folders/lists CRUD, statuses, privacy toggles
|
|
29
|
+
- Metadata/admin-lite: fields, task types, tags, `whoami`, workspace members, bootstrap/init
|
|
30
|
+
|
|
31
|
+
Depth is strongest in tasks and docs/pages. The CLI already mixes v2 and v3 pragmatically, which is a good foundation for further expansion.
|
|
32
|
+
|
|
33
|
+
## Method / sources
|
|
34
|
+
|
|
35
|
+
This assessment combines:
|
|
36
|
+
|
|
37
|
+
- Local repo command inventory and manifest review
|
|
38
|
+
- ClickUp v2 public API coverage review
|
|
39
|
+
- ClickUp v3 public API coverage review
|
|
40
|
+
- Broader ClickUp product-surface review for areas where user expectations may exceed public API coverage
|
|
41
|
+
|
|
42
|
+
Priority in this document is a blended judgment based on four factors:
|
|
43
|
+
|
|
44
|
+
1. User value for a terminal workflow
|
|
45
|
+
2. Public API certainty
|
|
46
|
+
3. Fit with the current CLI shape
|
|
47
|
+
4. Likely implementation complexity and risk
|
|
48
|
+
|
|
49
|
+
Priority labels should be read this way:
|
|
50
|
+
|
|
51
|
+
- `High`: high value, high API confidence, strong fit with existing commands
|
|
52
|
+
- `Medium`: valuable and likely worth doing, but broader in scope or a bit less certain
|
|
53
|
+
- `Low`: niche, admin-heavy, experimental, enterprise-oriented, or not clearly public yet
|
|
54
|
+
|
|
55
|
+
## Gaps by area
|
|
56
|
+
|
|
57
|
+
### Task workflows and task-adjacent operations
|
|
58
|
+
|
|
59
|
+
#### [High] Checklists (`v2`)
|
|
60
|
+
|
|
61
|
+
Missing today: no checklist or checklist-item commands exist.
|
|
62
|
+
|
|
63
|
+
Why it matters: this is one of the most CLI-natural task-adjacent features. It adds lightweight decomposition without forcing full subtask workflows.
|
|
64
|
+
|
|
65
|
+
Suggested surface: `tasks checklist list/create/rename/delete` and `tasks checklist item add/toggle/update/delete`.
|
|
66
|
+
|
|
67
|
+
Why this is high priority: it is a clean public API surface, highly compatible with existing task commands, and useful immediately.
|
|
68
|
+
|
|
69
|
+
#### [Medium] Remaining task-create follow-through (`v2`)
|
|
70
|
+
|
|
71
|
+
Missing today: the main `v1.2` create-parity work shipped, including dates, estimates, points, inline custom fields, and task-type selection. The remaining gap is adjacent create-time setup such as checklist bootstrapping and attachment upload, which still requires follow-up commands or is unsupported.
|
|
72
|
+
|
|
73
|
+
Why it matters: task creation is one of the CLI's most visible workflows, so the remaining rough edges still show up quickly in real use.
|
|
74
|
+
|
|
75
|
+
Suggested surface: keep `tasks create` focused, but consider bounded follow-through helpers for checklist setup and attachments where the API shape is clean.
|
|
76
|
+
|
|
77
|
+
Why this is medium priority: the core parity gap is closed, but there is still room to smooth the create flow around nearby task setup.
|
|
78
|
+
|
|
79
|
+
#### [Medium] Task attachment upload (`v2`, bounded)
|
|
80
|
+
|
|
81
|
+
Missing today: no attachment upload support exists.
|
|
82
|
+
|
|
83
|
+
Why it matters: file upload is a practical workflow for bug reports, exports, screenshots, and logs.
|
|
84
|
+
|
|
85
|
+
Suggested surface: a narrow first slice such as `tasks attachments upload <task> --file <path>`.
|
|
86
|
+
|
|
87
|
+
Why this is medium priority: confirmed task upload support appears real and valuable, but broader attachment semantics should not be assumed yet.
|
|
88
|
+
|
|
89
|
+
#### [Low] Attachment listing and broader attachment coverage (`v3`, validate first)
|
|
90
|
+
|
|
91
|
+
Missing today: no attachment listing or broader cross-entity attachment support exists.
|
|
92
|
+
|
|
93
|
+
Why it matters: these could become useful later, especially if docs or other entities are brought deeper into the CLI.
|
|
94
|
+
|
|
95
|
+
Suggested surface: validate task-level listing first, then only expand if the v3 entity semantics are clean enough to justify it.
|
|
96
|
+
|
|
97
|
+
Why this is low priority: public support exists in a less settled shape, and this should not be mistaken for a clean v2 parity task.
|
|
98
|
+
|
|
99
|
+
### Collaboration and discussion
|
|
100
|
+
|
|
101
|
+
#### [Medium] Comments beyond tasks (`v2`)
|
|
102
|
+
|
|
103
|
+
Missing today: current comment support is task-only, while v2 also exposes list comments and view/chat-view comments.
|
|
104
|
+
|
|
105
|
+
Why it matters: this is another asymmetry inside an already-supported domain. It matters for shared list workflows and operational views.
|
|
106
|
+
|
|
107
|
+
Suggested surface: extend `comments list/add` with entity-explicit options such as `--task`, `--list`, and `--view`, while preserving edit/reply/thread behavior where supported.
|
|
108
|
+
|
|
109
|
+
Why this is medium priority: it expands an existing command group without introducing a new top-level product area.
|
|
110
|
+
|
|
111
|
+
#### [Low] Chat (`v3`, experimental)
|
|
112
|
+
|
|
113
|
+
Missing today: no chat-channel, DM, or chat-message support exists.
|
|
114
|
+
|
|
115
|
+
Why it matters: the v3 surface is broader than expected and could matter if the CLI evolves into a wider ClickUp power-user tool.
|
|
116
|
+
|
|
117
|
+
Suggested surface: only consider after the core task/reporting/admin gaps are better covered.
|
|
118
|
+
|
|
119
|
+
Why this is low priority: the official API is experimental, which makes it a risky foundation for near-term roadmap work.
|
|
120
|
+
|
|
121
|
+
### Time tracking and execution
|
|
122
|
+
|
|
123
|
+
#### [High] Time tracking and timers (`v2`, with selective `v3` estimate helpers later)
|
|
124
|
+
|
|
125
|
+
Missing today: no time-entry, timer, or time-report commands exist.
|
|
126
|
+
|
|
127
|
+
Why it matters: time tracking is one of ClickUp's most substantial CLI-compatible workflows. It fits developer usage especially well: start/stop timers, add retroactive work, inspect running timers, and export recent entries.
|
|
128
|
+
|
|
129
|
+
Suggested surface: a top-level `time` command group with `current`, `start`, `stop`, `list`, `add`, `edit`, `delete`, and tag helpers. Later, selectively add v3 task time-estimate helpers if they improve the UX.
|
|
130
|
+
|
|
131
|
+
Why this is high priority: it is a large but very high-value public API surface with strong CLI ergonomics.
|
|
132
|
+
|
|
133
|
+
### Hierarchy, planning, and reporting
|
|
134
|
+
|
|
135
|
+
#### [Medium] Views and saved-query workflows (`v2`)
|
|
136
|
+
|
|
137
|
+
Missing today: no command group exists for views, despite public list/board/calendar/gantt view support and view-task retrieval.
|
|
138
|
+
|
|
139
|
+
Why it matters: views are probably the public API's strongest reporting/query surface and the best CLI substitute for some dashboard-like needs.
|
|
140
|
+
|
|
141
|
+
Suggested surface: `views list/get/create/update/delete` and `views tasks <view>`.
|
|
142
|
+
|
|
143
|
+
Why this is medium priority: valuable and public, but broad enough that it deserves a deliberate command design rather than a quick parity patch.
|
|
144
|
+
|
|
145
|
+
#### [Medium] Goals and key results (`v2`)
|
|
146
|
+
|
|
147
|
+
Missing today: no goals or key-result support exists.
|
|
148
|
+
|
|
149
|
+
Why it matters: goals are a real ClickUp planning surface and appear in event/webhook concepts as well.
|
|
150
|
+
|
|
151
|
+
Suggested surface: `goals list/get/create/update/delete`, key-result commands, and compact progress summaries.
|
|
152
|
+
|
|
153
|
+
Why this is medium priority: useful, but slightly less foundational than task, time, and view workflows.
|
|
154
|
+
|
|
155
|
+
#### [Medium] Template discovery and application (`v2`)
|
|
156
|
+
|
|
157
|
+
Missing today: no first-class template workflows exist.
|
|
158
|
+
|
|
159
|
+
Why it matters: templates are a natural planning and bootstrap surface, especially once the CLI supports richer task, list, or workflow setup.
|
|
160
|
+
|
|
161
|
+
Suggested surface: start with read-only discovery and application flows before attempting broader template lifecycle management.
|
|
162
|
+
|
|
163
|
+
Why this is medium priority: important, but likely easier to justify after the primary task workflow gaps are closed.
|
|
164
|
+
|
|
165
|
+
### Automation and integrations
|
|
166
|
+
|
|
167
|
+
#### [Medium] Webhooks (`v2`)
|
|
168
|
+
|
|
169
|
+
Missing today: no webhook management support exists.
|
|
170
|
+
|
|
171
|
+
Why it matters: webhooks are the clearest public automation surface in ClickUp and unlock event-driven integrations even if full automation-rule CRUD remains unavailable.
|
|
172
|
+
|
|
173
|
+
Suggested surface: `webhooks list/create/update/delete`, with scope and event-selection helpers.
|
|
174
|
+
|
|
175
|
+
Why this is medium priority: high leverage for automation users, but slightly more specialized than core task and time parity work.
|
|
176
|
+
|
|
177
|
+
#### [Low] Full automation-rule management (`non-public/unclear`)
|
|
178
|
+
|
|
179
|
+
Missing today: no automation management support exists.
|
|
180
|
+
|
|
181
|
+
Why it matters: users may expect it because ClickUp markets automations heavily.
|
|
182
|
+
|
|
183
|
+
Suggested surface: do not plan this as a confirmed feature yet. Treat webhooks as the public-API automation proxy unless official automation CRUD becomes clearly available.
|
|
184
|
+
|
|
185
|
+
Why this is low priority: public API coverage was not clearly confirmed.
|
|
186
|
+
|
|
187
|
+
### Admin, identity, and governance
|
|
188
|
+
|
|
189
|
+
#### [Low] Broader identity/admin surface (`v2`)
|
|
190
|
+
|
|
191
|
+
Missing today: current support stops at `whoami` and workspace members. There is no groups, guests, roles, shared hierarchy, plan, or seats coverage.
|
|
192
|
+
|
|
193
|
+
Why it matters: these are real public API capabilities for admin-heavy environments.
|
|
194
|
+
|
|
195
|
+
Suggested surface: `team plan`, `team seats`, `groups ...`, `guests ...`, and related sharing inspection commands.
|
|
196
|
+
|
|
197
|
+
Why this is low priority: real surface area, but not the highest day-to-day value for the repo's current direction.
|
|
198
|
+
|
|
199
|
+
#### [Low] Granular ACL/share management (`v3`, partially understood)
|
|
200
|
+
|
|
201
|
+
Missing today: the CLI exposes boolean privacy toggles only.
|
|
202
|
+
|
|
203
|
+
Why it matters: the v3 ACL endpoint appears much broader and may eventually enable richer sharing workflows.
|
|
204
|
+
|
|
205
|
+
Suggested surface: validate semantics and billing/plan behavior before planning user/group grant commands.
|
|
206
|
+
|
|
207
|
+
Why this is low priority: the surface is promising but still not well understood enough for early roadmap commitment.
|
|
208
|
+
|
|
209
|
+
#### [Low] Audit logs (`v3`, enterprise/admin)
|
|
210
|
+
|
|
211
|
+
Missing today: no audit-log support exists.
|
|
212
|
+
|
|
213
|
+
Why it matters: useful for enterprise/admin inspection workflows.
|
|
214
|
+
|
|
215
|
+
Suggested surface: treat as a later admin-oriented reporting feature.
|
|
216
|
+
|
|
217
|
+
Why this is low priority: it is narrow, enterprise-facing, and not central to general CLI adoption.
|
|
218
|
+
|
|
219
|
+
## Product areas that are real, but not strong roadmap bets yet
|
|
220
|
+
|
|
221
|
+
### [Low] Dashboards (`non-public/unclear`)
|
|
222
|
+
|
|
223
|
+
Dashboards are clearly important in the product, but public dashboard object management was not confirmed in the API materials reviewed. Do not plan dashboard CRUD until public coverage is verified.
|
|
224
|
+
|
|
225
|
+
### [Low] Forms (`non-public/unclear`)
|
|
226
|
+
|
|
227
|
+
Forms matter in real ClickUp workflows, but public forms CRUD was not confirmed. Downstream support through tasks, views, and automation-style workflows is a better near-term bet.
|
|
228
|
+
|
|
229
|
+
### [Low] Whiteboards (`non-public/likely unsupported publicly`)
|
|
230
|
+
|
|
231
|
+
Whiteboards exist as a product area, but the docs reviewed indicate page views such as whiteboards are not part of the public API surface. This should stay out of active planning unless the API changes.
|
|
232
|
+
|
|
233
|
+
### [Low] Docs/page parity limitations (`v3`, public but incomplete)
|
|
234
|
+
|
|
235
|
+
The repo already covers most of the public docs/page surface. Remaining gaps such as doc rename/delete and page delete appear to be public API limitations rather than repo omissions.
|
|
236
|
+
|
|
237
|
+
## Final priority summary
|
|
238
|
+
|
|
239
|
+
### High priority
|
|
240
|
+
|
|
241
|
+
1. Checklists
|
|
242
|
+
2. Time tracking and timers
|
|
243
|
+
|
|
244
|
+
### Medium priority
|
|
245
|
+
|
|
246
|
+
1. Remaining task-create follow-through
|
|
247
|
+
2. Task attachment upload
|
|
248
|
+
3. Comments beyond tasks
|
|
249
|
+
4. Views and saved-query workflows
|
|
250
|
+
5. Goals and key results
|
|
251
|
+
6. Template discovery and application
|
|
252
|
+
7. Webhooks
|
|
253
|
+
|
|
254
|
+
### Low priority or validate-first
|
|
255
|
+
|
|
256
|
+
1. Attachment listing and broader attachment coverage
|
|
257
|
+
2. Chat
|
|
258
|
+
3. Full automation-rule management
|
|
259
|
+
4. Broader identity/admin surface
|
|
260
|
+
5. Granular ACL/share management
|
|
261
|
+
6. Audit logs
|
|
262
|
+
7. Dashboards
|
|
263
|
+
8. Forms
|
|
264
|
+
9. Whiteboards
|
|
265
|
+
10. Docs/page delete or rename parity that appears limited by the public API itself
|
|
266
|
+
|
|
267
|
+
## Recommended sequencing principles
|
|
268
|
+
|
|
269
|
+
1. Finish the biggest task-surface asymmetries before expanding into unrelated top-level domains.
|
|
270
|
+
2. Prefer public-API certainty over product-surface temptation.
|
|
271
|
+
3. Bias toward features that improve daily CLI workflows first: task creation, task decomposition, search/filtering, time, and saved-query/reporting.
|
|
272
|
+
4. Keep early expansions bounded. A narrow upload command or read-only template discovery is better than an oversized first cut.
|
|
273
|
+
5. Treat experimental or enterprise-heavy surfaces as explicit later-phase work, not hidden scope creep.
|
|
274
|
+
6. Where v2 and v3 overlap, prefer the narrower and better-documented path unless v3 clearly unlocks better behavior.
|
|
275
|
+
|
|
276
|
+
## Appendix: concise source list
|
|
277
|
+
|
|
278
|
+
- Local repo inventory: `README.md`, `CLAUDE.md`, `src/clickup_cli/commands/*.py`, `src/clickup_cli/commands/__init__.py`
|
|
279
|
+
- ClickUp developer docs: `developer.clickup.com/docs/tasks`, `docs/comments`, `docs/customfields`, `docs/views`, `docs/webhooks`, `docs/chat`, `docs/general-v2-v3-api`, `docs/move-a-task-to-a-new-list`, `docs/docsimportexportlimitations`
|
|
280
|
+
- ClickUp OpenAPI specs: `developer.clickup.com/openapi/clickup-api-v2-reference.json`, `developer.clickup.com/openapi/ClickUp_PUBLIC_API_V3.yaml`
|
|
281
|
+
- ClickUp product pages reviewed for expectation-setting: automations, dashboards, goals, forms, project time tracking, chat, whiteboards
|