@krodak/clickup-cli 1.6.1 → 1.8.0

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.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "clickup-cli",
3
3
  "description": "ClickUp CLI skills for managing tasks, sprints, comments, checklists, custom fields, tags, and time tracking via the cup command",
4
- "version": "1.6.1",
4
+ "version": "1.8.0",
5
5
  "author": {
6
6
  "name": "Krzysztof Rodak"
7
7
  },
package/README.md CHANGED
@@ -150,11 +150,11 @@ Full CRUD for the core ClickUp workflow:
150
150
  | 📄 **Docs** | List, read, create, edit, delete (v3 API) |
151
151
  | ⏱️ **Time Tracking** | Start/stop timer, log entries, list/update/delete history |
152
152
  | ☑️ **Checklists** | View, create, delete, add/edit/delete items |
153
- | 🔧 **Custom Fields** | List, set, remove values (dropdown, date, checkbox, text, etc.) |
153
+ | 🔧 **Custom Fields** | List, create, set, remove values (dropdown, date, checkbox, text, etc.) |
154
154
  | 🏷️ **Tags** | Add/remove on tasks, space-level create/update/delete |
155
155
  | 🎯 **Goals & OKRs** | Goals CRUD, key results CRUD |
156
156
  | 🏃 **Sprints** | Auto-detect active sprint, flexible date parsing, config override |
157
- | 🏢 **Workspace** | Spaces, folders, lists, members, task types, templates |
157
+ | 🏢 **Workspace** | Spaces, folders, lists (read + create), members, task types, templates |
158
158
  | 📎 **Attachments** | Upload files to tasks, shown in detail views |
159
159
 
160
160
  [Full API coverage details](docs/api-coverage.md) | [Command reference](docs/commands.md)
package/dist/index.js CHANGED
@@ -224,6 +224,12 @@ var ClickUpClient = class {
224
224
  async getListWithStatuses(listId) {
225
225
  return this.request(`/list/${listId}`);
226
226
  }
227
+ async createSpace(teamId, name) {
228
+ return this.request(`/team/${teamId}/space`, {
229
+ method: "POST",
230
+ body: JSON.stringify({ name, multiple_assignees: true })
231
+ });
232
+ }
227
233
  async getSpaces(teamId) {
228
234
  const data = await this.request(`/team/${teamId}/space?archived=false`);
229
235
  return readCollectionField(data, "spaces", "spaces");
@@ -238,6 +244,24 @@ var ClickUpClient = class {
238
244
  "custom task types"
239
245
  );
240
246
  }
247
+ async createList(spaceId, name) {
248
+ return this.request(`/space/${spaceId}/list`, {
249
+ method: "POST",
250
+ body: JSON.stringify({ name })
251
+ });
252
+ }
253
+ async createFolderList(folderId, name) {
254
+ return this.request(`/folder/${folderId}/list`, {
255
+ method: "POST",
256
+ body: JSON.stringify({ name })
257
+ });
258
+ }
259
+ async createFolder(spaceId, name) {
260
+ return this.request(`/space/${spaceId}/folder`, {
261
+ method: "POST",
262
+ body: JSON.stringify({ name })
263
+ });
264
+ }
241
265
  async getLists(spaceId) {
242
266
  const data = await this.request(`/space/${spaceId}/list?archived=false`);
243
267
  return readCollectionField(data, "lists", "space lists");
@@ -673,6 +697,27 @@ var ClickUpClient = class {
673
697
  body: JSON.stringify({ name })
674
698
  });
675
699
  }
700
+ async createCustomField(teamId, name, type, opts) {
701
+ const body = {
702
+ name,
703
+ type,
704
+ type_config: {},
705
+ description: opts?.description ?? "",
706
+ required: opts?.required ?? false,
707
+ pinned: false,
708
+ hide_from_guests: false,
709
+ required_on_subtasks: false,
710
+ private: false,
711
+ permission_level: null,
712
+ members: [],
713
+ groups: []
714
+ };
715
+ const data = await this.request(
716
+ `/field?workspace_id=${teamId}`,
717
+ { method: "POST", body: JSON.stringify(body) }
718
+ );
719
+ return data.data;
720
+ }
676
721
  };
677
722
 
678
723
  // src/config.ts
@@ -3024,6 +3069,38 @@ var commandMetadata = [
3024
3069
  { section: "read", usage: "folders <spaceId>", description: "List folders in a space" }
3025
3070
  ]
3026
3071
  },
3072
+ {
3073
+ name: "space-create",
3074
+ description: "Create a new space in your workspace",
3075
+ flags: ["--json"],
3076
+ quickReference: [
3077
+ { section: "write", usage: "space-create <name>", description: "Create a space" }
3078
+ ]
3079
+ },
3080
+ {
3081
+ name: "list-create",
3082
+ description: "Create a new list in a space",
3083
+ flags: ["--folder", "--json"],
3084
+ quickReference: [
3085
+ {
3086
+ section: "write",
3087
+ usage: "list-create <spaceId> <name>",
3088
+ description: "Create a list in a space"
3089
+ }
3090
+ ]
3091
+ },
3092
+ {
3093
+ name: "folder-create",
3094
+ description: "Create a new folder in a space",
3095
+ flags: ["--json"],
3096
+ quickReference: [
3097
+ {
3098
+ section: "write",
3099
+ usage: "folder-create <spaceId> <name>",
3100
+ description: "Create a folder in a space"
3101
+ }
3102
+ ]
3103
+ },
3027
3104
  {
3028
3105
  name: "members",
3029
3106
  description: "List workspace members",
@@ -3038,6 +3115,18 @@ var commandMetadata = [
3038
3115
  { section: "read", usage: "fields <listId>", description: "List custom fields for a list" }
3039
3116
  ]
3040
3117
  },
3118
+ {
3119
+ name: "field-create",
3120
+ description: "Create a custom field in your workspace",
3121
+ flags: ["-t", "--type", "-d", "--description", "--required", "--json"],
3122
+ quickReference: [
3123
+ {
3124
+ section: "write",
3125
+ usage: "field-create <name>",
3126
+ description: "Create a custom field in your workspace"
3127
+ }
3128
+ ]
3129
+ },
3041
3130
  {
3042
3131
  name: "duplicate",
3043
3132
  description: "Duplicate a task",
@@ -3725,6 +3814,14 @@ ${renderZshTopLevelCommands(name)}
3725
3814
  '1:list_id:' \\
3726
3815
  '--json[Force JSON output]'
3727
3816
  ;;
3817
+ field-create)
3818
+ _arguments \\
3819
+ '1:name:' \\
3820
+ '(-t --type)'{-t,--type}'[Field type]:type:(text short_text number date checkbox drop_down labels email phone url currency)' \\
3821
+ '(-d --description)'{-d,--description}'[Field description]:text:' \\
3822
+ '--required[Make the field required]' \\
3823
+ '--json[Force JSON output]'
3824
+ ;;
3728
3825
  duplicate)
3729
3826
  _arguments \\
3730
3827
  '1:task_id:' \\
@@ -3834,6 +3931,24 @@ ${renderZshTopLevelCommands(name)}
3834
3931
  '--name[Filter by folder name]:text:' \\
3835
3932
  '--json[Force JSON output]'
3836
3933
  ;;
3934
+ space-create)
3935
+ _arguments \\
3936
+ '1:name:' \\
3937
+ '--json[Force JSON output]'
3938
+ ;;
3939
+ list-create)
3940
+ _arguments \\
3941
+ '1:space_id:' \\
3942
+ '2:name:' \\
3943
+ '--folder[Create inside a folder]:folder_id:' \\
3944
+ '--json[Force JSON output]'
3945
+ ;;
3946
+ folder-create)
3947
+ _arguments \\
3948
+ '1:space_id:' \\
3949
+ '2:name:' \\
3950
+ '--json[Force JSON output]'
3951
+ ;;
3837
3952
  doc-create)
3838
3953
  _arguments \\
3839
3954
  '1:title:' \\
@@ -5423,6 +5538,45 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
5423
5538
  }
5424
5539
  })
5425
5540
  );
5541
+ program.command("field-create <name>").description("Create a custom field in your workspace").requiredOption(
5542
+ "-t, --type <type>",
5543
+ "Field type (text, number, date, checkbox, drop_down, labels, email, phone, url, currency, short_text)"
5544
+ ).option("-d, --description <text>", "Field description").option("--required", "Make the field required").option("--json", "Force JSON output even in terminal").action(
5545
+ wrapAction(
5546
+ async (name, opts) => {
5547
+ if (!name.trim()) throw new Error("Field name cannot be empty");
5548
+ const validTypes = [
5549
+ "text",
5550
+ "short_text",
5551
+ "number",
5552
+ "date",
5553
+ "checkbox",
5554
+ "drop_down",
5555
+ "labels",
5556
+ "email",
5557
+ "phone",
5558
+ "url",
5559
+ "currency"
5560
+ ];
5561
+ if (!validTypes.includes(opts.type)) {
5562
+ throw new Error(
5563
+ `Invalid field type "${opts.type}". Valid types: ${validTypes.join(", ")}`
5564
+ );
5565
+ }
5566
+ const config = loadConfig(getProfileName());
5567
+ const client = new ClickUpClient(config);
5568
+ const field = await client.createCustomField(config.teamId, name, opts.type, {
5569
+ description: opts.description,
5570
+ required: opts.required
5571
+ });
5572
+ if (shouldOutputJson(opts.json ?? false)) {
5573
+ console.log(JSON.stringify(field, null, 2));
5574
+ } else {
5575
+ console.log(`Created field "${field.name}" (${field.id}) type: ${field.type}`);
5576
+ }
5577
+ }
5578
+ )
5579
+ );
5426
5580
  program.command("duplicate <taskId>").description("Duplicate a task").option("--json", "Force JSON output even in terminal").action(
5427
5581
  wrapAction(async (taskId, opts) => {
5428
5582
  const config = loadConfig(getProfileName());
@@ -5632,6 +5786,47 @@ function buildProgram(programName = basename(process.argv[1] ?? "cup")) {
5632
5786
  }
5633
5787
  })
5634
5788
  );
5789
+ program.command("space-create <name>").description("Create a new space in your workspace").option("--json", "Force JSON output even in terminal").action(
5790
+ wrapAction(async (name, opts) => {
5791
+ if (!name.trim()) throw new Error("Space name cannot be empty");
5792
+ const config = loadConfig(getProfileName());
5793
+ const client = new ClickUpClient(config);
5794
+ const space = await client.createSpace(config.teamId, name);
5795
+ if (shouldOutputJson(opts.json ?? false)) {
5796
+ console.log(JSON.stringify(space, null, 2));
5797
+ } else {
5798
+ console.log(`Created space "${space.name}" (${space.id})`);
5799
+ }
5800
+ })
5801
+ );
5802
+ program.command("list-create <spaceId> <name>").description("Create a new list in a space").option("--folder <folderId>", "Create the list inside a folder").option("--json", "Force JSON output even in terminal").action(
5803
+ wrapAction(
5804
+ async (spaceId, name, opts) => {
5805
+ if (!name.trim()) throw new Error("List name cannot be empty");
5806
+ const config = loadConfig(getProfileName());
5807
+ const client = new ClickUpClient(config);
5808
+ const list = opts.folder ? await client.createFolderList(opts.folder, name) : await client.createList(spaceId, name);
5809
+ if (shouldOutputJson(opts.json ?? false)) {
5810
+ console.log(JSON.stringify(list, null, 2));
5811
+ } else {
5812
+ console.log(`Created list "${list.name}" (${list.id})`);
5813
+ }
5814
+ }
5815
+ )
5816
+ );
5817
+ program.command("folder-create <spaceId> <name>").description("Create a new folder in a space").option("--json", "Force JSON output even in terminal").action(
5818
+ wrapAction(async (spaceId, name, opts) => {
5819
+ if (!name.trim()) throw new Error("Folder name cannot be empty");
5820
+ const config = loadConfig(getProfileName());
5821
+ const client = new ClickUpClient(config);
5822
+ const folder = await client.createFolder(spaceId, name);
5823
+ if (shouldOutputJson(opts.json ?? false)) {
5824
+ console.log(JSON.stringify(folder, null, 2));
5825
+ } else {
5826
+ console.log(`Created folder "${folder.name}" (${folder.id})`);
5827
+ }
5828
+ })
5829
+ );
5635
5830
  program.command("doc-create <title>").description("Create a new doc").option("-c, --content <text>", "Initial content (markdown)").option("--json", "Force JSON output even in terminal").action(
5636
5831
  wrapAction(async (title, opts) => {
5637
5832
  const config = loadConfig(getProfileName());
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@krodak/clickup-cli",
3
- "version": "1.6.1",
3
+ "version": "1.8.0",
4
4
  "description": "ClickUp CLI for AI agents and humans",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -78,6 +78,7 @@ All commands support `--help` for full flag details. All commands support `--jso
78
78
  | `cup depend <id> [--on taskId] [--blocks taskId] [--remove]` | Add/remove dependencies |
79
79
  | `cup move <id> [--to listId] [--remove listId]` | Add/remove task from lists |
80
80
  | `cup field <id> [--set "Name" value] [--remove "Name"]` | Set/remove custom field values |
81
+ | `cup field-create <name> -t <type> [-d desc] [--required]` | Create a custom field |
81
82
  | `cup tag <id> [--add tags] [--remove tags]` | Add/remove tags on a task |
82
83
  | `cup link <taskId> <linksTo> [--remove]` | Link/unlink tasks |
83
84
  | `cup attach <taskId> <filePath>` | Upload file attachment |
@@ -108,6 +109,9 @@ All commands support `--help` for full flag details. All commands support `--jso
108
109
  | `cup doc-page-edit <docId> <pageId> [--name text] [-c content]` | Edit doc page |
109
110
  | `cup doc-delete <docId>` | Delete a doc |
110
111
  | `cup doc-page-delete <docId> <pageId>` | Delete doc page |
112
+ | `cup space-create <name>` | Create a space |
113
+ | `cup list-create <spaceId> <name> [--folder folderId]` | Create a list in a space or folder |
114
+ | `cup folder-create <spaceId> <name>` | Create a folder in a space |
111
115
  | `cup tag-create <spaceId> <name> [--fg color] [--bg color]` | Create space tag |
112
116
  | `cup tag-update <spaceId> <tagName> --name <newName> [--fg c] [--bg c]` | Update space tag |
113
117
  | `cup tag-delete <spaceId> <name>` | Delete space tag |
@@ -215,6 +219,10 @@ cup doc-page-edit <docId> <pageId> -c "# Updated"
215
219
  cup spaces --name "Engineering" # find space ID
216
220
  cup folders <spaceId> # folders with their lists
217
221
  cup lists <spaceId> # lists in a space
222
+ cup space-create "New Space" # create a space
223
+ cup folder-create <spaceId> "Q2" # create a folder
224
+ cup list-create <spaceId> "Backlog" # create a list
225
+ cup list-create <spaceId> "Sprint" --folder <folderId>
218
226
  cup members # workspace members
219
227
  cup fields <listId> # custom fields on a list
220
228
  cup task-types # custom task types