@kb-labs/clickup-entry 2.96.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.
Files changed (122) hide show
  1. package/README.md +69 -0
  2. package/dist/commands/folder-create.d.ts +13 -0
  3. package/dist/commands/folder-create.js +94 -0
  4. package/dist/commands/folder-create.js.map +1 -0
  5. package/dist/commands/folder-delete.d.ts +14 -0
  6. package/dist/commands/folder-delete.js +92 -0
  7. package/dist/commands/folder-delete.js.map +1 -0
  8. package/dist/commands/folder-update.d.ts +13 -0
  9. package/dist/commands/folder-update.js +94 -0
  10. package/dist/commands/folder-update.js.map +1 -0
  11. package/dist/commands/list-create.d.ts +15 -0
  12. package/dist/commands/list-create.js +96 -0
  13. package/dist/commands/list-create.js.map +1 -0
  14. package/dist/commands/list-delete.d.ts +14 -0
  15. package/dist/commands/list-delete.js +92 -0
  16. package/dist/commands/list-delete.js.map +1 -0
  17. package/dist/commands/list-statuses.d.ts +11 -0
  18. package/dist/commands/list-statuses.js +88 -0
  19. package/dist/commands/list-statuses.js.map +1 -0
  20. package/dist/commands/list-tasks.d.ts +16 -0
  21. package/dist/commands/list-tasks.js +118 -0
  22. package/dist/commands/list-tasks.js.map +1 -0
  23. package/dist/commands/list-update.d.ts +13 -0
  24. package/dist/commands/list-update.js +92 -0
  25. package/dist/commands/list-update.js.map +1 -0
  26. package/dist/commands/space-create.d.ts +15 -0
  27. package/dist/commands/space-create.js +94 -0
  28. package/dist/commands/space-create.js.map +1 -0
  29. package/dist/commands/space-delete.d.ts +14 -0
  30. package/dist/commands/space-delete.js +92 -0
  31. package/dist/commands/space-delete.js.map +1 -0
  32. package/dist/commands/space-update.d.ts +14 -0
  33. package/dist/commands/space-update.js +93 -0
  34. package/dist/commands/space-update.js.map +1 -0
  35. package/dist/commands/task-comment-add.d.ts +15 -0
  36. package/dist/commands/task-comment-add.js +95 -0
  37. package/dist/commands/task-comment-add.js.map +1 -0
  38. package/dist/commands/task-comment-list.d.ts +11 -0
  39. package/dist/commands/task-comment-list.js +91 -0
  40. package/dist/commands/task-comment-list.js.map +1 -0
  41. package/dist/commands/task-create.d.ts +20 -0
  42. package/dist/commands/task-create.js +116 -0
  43. package/dist/commands/task-create.js.map +1 -0
  44. package/dist/commands/task-delete.d.ts +14 -0
  45. package/dist/commands/task-delete.js +92 -0
  46. package/dist/commands/task-delete.js.map +1 -0
  47. package/dist/commands/task-get.d.ts +14 -0
  48. package/dist/commands/task-get.js +128 -0
  49. package/dist/commands/task-get.js.map +1 -0
  50. package/dist/commands/task-search.d.ts +16 -0
  51. package/dist/commands/task-search.js +112 -0
  52. package/dist/commands/task-search.js.map +1 -0
  53. package/dist/commands/task-update.d.ts +19 -0
  54. package/dist/commands/task-update.js +124 -0
  55. package/dist/commands/task-update.js.map +1 -0
  56. package/dist/commands/workspace.d.ts +11 -0
  57. package/dist/commands/workspace.js +102 -0
  58. package/dist/commands/workspace.js.map +1 -0
  59. package/dist/index.d.ts +2 -0
  60. package/dist/index.js +474 -0
  61. package/dist/index.js.map +1 -0
  62. package/dist/manifest.d.ts +171 -0
  63. package/dist/manifest.js +474 -0
  64. package/dist/manifest.js.map +1 -0
  65. package/dist/rest/handlers/folder-create-handler.d.ts +11 -0
  66. package/dist/rest/handlers/folder-create-handler.js +57 -0
  67. package/dist/rest/handlers/folder-create-handler.js.map +1 -0
  68. package/dist/rest/handlers/folder-delete-handler.d.ts +11 -0
  69. package/dist/rest/handlers/folder-delete-handler.js +57 -0
  70. package/dist/rest/handlers/folder-delete-handler.js.map +1 -0
  71. package/dist/rest/handlers/folder-update-handler.d.ts +11 -0
  72. package/dist/rest/handlers/folder-update-handler.js +57 -0
  73. package/dist/rest/handlers/folder-update-handler.js.map +1 -0
  74. package/dist/rest/handlers/list-create-handler.d.ts +17 -0
  75. package/dist/rest/handlers/list-create-handler.js +59 -0
  76. package/dist/rest/handlers/list-create-handler.js.map +1 -0
  77. package/dist/rest/handlers/list-delete-handler.d.ts +11 -0
  78. package/dist/rest/handlers/list-delete-handler.js +57 -0
  79. package/dist/rest/handlers/list-delete-handler.js.map +1 -0
  80. package/dist/rest/handlers/list-statuses-handler.d.ts +9 -0
  81. package/dist/rest/handlers/list-statuses-handler.js +57 -0
  82. package/dist/rest/handlers/list-statuses-handler.js.map +1 -0
  83. package/dist/rest/handlers/list-tasks-handler.d.ts +16 -0
  84. package/dist/rest/handlers/list-tasks-handler.js +64 -0
  85. package/dist/rest/handlers/list-tasks-handler.js.map +1 -0
  86. package/dist/rest/handlers/list-update-handler.d.ts +15 -0
  87. package/dist/rest/handlers/list-update-handler.js +57 -0
  88. package/dist/rest/handlers/list-update-handler.js.map +1 -0
  89. package/dist/rest/handlers/search-handler.d.ts +16 -0
  90. package/dist/rest/handlers/search-handler.js +65 -0
  91. package/dist/rest/handlers/search-handler.js.map +1 -0
  92. package/dist/rest/handlers/space-create-handler.d.ts +11 -0
  93. package/dist/rest/handlers/space-create-handler.js +55 -0
  94. package/dist/rest/handlers/space-create-handler.js.map +1 -0
  95. package/dist/rest/handlers/space-delete-handler.d.ts +11 -0
  96. package/dist/rest/handlers/space-delete-handler.js +57 -0
  97. package/dist/rest/handlers/space-delete-handler.js.map +1 -0
  98. package/dist/rest/handlers/space-update-handler.d.ts +13 -0
  99. package/dist/rest/handlers/space-update-handler.js +57 -0
  100. package/dist/rest/handlers/space-update-handler.js.map +1 -0
  101. package/dist/rest/handlers/task-comment-add-handler.d.ts +13 -0
  102. package/dist/rest/handlers/task-comment-add-handler.js +61 -0
  103. package/dist/rest/handlers/task-comment-add-handler.js.map +1 -0
  104. package/dist/rest/handlers/task-comments-handler.d.ts +9 -0
  105. package/dist/rest/handlers/task-comments-handler.js +57 -0
  106. package/dist/rest/handlers/task-comments-handler.js.map +1 -0
  107. package/dist/rest/handlers/task-create-handler.d.ts +18 -0
  108. package/dist/rest/handlers/task-create-handler.js +58 -0
  109. package/dist/rest/handlers/task-create-handler.js.map +1 -0
  110. package/dist/rest/handlers/task-delete-handler.d.ts +11 -0
  111. package/dist/rest/handlers/task-delete-handler.js +58 -0
  112. package/dist/rest/handlers/task-delete-handler.js.map +1 -0
  113. package/dist/rest/handlers/task-get-handler.d.ts +12 -0
  114. package/dist/rest/handlers/task-get-handler.js +61 -0
  115. package/dist/rest/handlers/task-get-handler.js.map +1 -0
  116. package/dist/rest/handlers/task-update-handler.d.ts +19 -0
  117. package/dist/rest/handlers/task-update-handler.js +58 -0
  118. package/dist/rest/handlers/task-update-handler.js.map +1 -0
  119. package/dist/rest/handlers/workspace-handler.d.ts +6 -0
  120. package/dist/rest/handlers/workspace-handler.js +56 -0
  121. package/dist/rest/handlers/workspace-handler.js.map +1 -0
  122. package/package.json +54 -0
package/README.md ADDED
@@ -0,0 +1,69 @@
1
+ # ClickUp Plugin for KB Labs
2
+
3
+ Manage ClickUp workspaces, spaces, folders, lists, and tasks directly from your terminal.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ kb marketplace install kb:kirill/@kb-labs/clickup-entry
9
+ ```
10
+
11
+ ## Configuration
12
+
13
+ Set your ClickUp API token:
14
+
15
+ ```bash
16
+ export CLICKUP_API_TOKEN=your_token_here
17
+ export CLICKUP_TEAM_ID=your_team_id
18
+ ```
19
+
20
+ Get your API token from **ClickUp → Settings → Apps → API Token**.
21
+
22
+ ## Commands
23
+
24
+ ### Tasks
25
+
26
+ | Command | Description |
27
+ |---|---|
28
+ | `kb clickup:task-get` | Get task details by ID |
29
+ | `kb clickup:task-create` | Create a new task |
30
+ | `kb clickup:task-update` | Update task fields |
31
+ | `kb clickup:task-delete` | Delete a task |
32
+ | `kb clickup:task-search` | Search tasks by query |
33
+ | `kb clickup:task-comment-add` | Add a comment to a task |
34
+ | `kb clickup:task-comment-list` | List task comments |
35
+
36
+ ### Lists & Folders
37
+
38
+ | Command | Description |
39
+ |---|---|
40
+ | `kb clickup:list-tasks` | List tasks in a list |
41
+ | `kb clickup:list-create` | Create a new list |
42
+ | `kb clickup:list-update` | Update list settings |
43
+ | `kb clickup:list-delete` | Delete a list |
44
+ | `kb clickup:list-statuses` | Get statuses for a list |
45
+ | `kb clickup:folder-create` | Create a folder |
46
+ | `kb clickup:folder-update` | Update a folder |
47
+ | `kb clickup:folder-delete` | Delete a folder |
48
+
49
+ ### Spaces & Workspace
50
+
51
+ | Command | Description |
52
+ |---|---|
53
+ | `kb clickup:space-create` | Create a space |
54
+ | `kb clickup:space-update` | Update a space |
55
+ | `kb clickup:space-delete` | Delete a space |
56
+ | `kb clickup:workspace` | Show workspace info |
57
+
58
+ ## Example
59
+
60
+ ```bash
61
+ # List tasks in a list
62
+ kb clickup:list-tasks --list-id 123456
63
+
64
+ # Create a task
65
+ kb clickup:task-create --list-id 123456 --name "Fix login bug" --priority high
66
+
67
+ # Search tasks
68
+ kb clickup:task-search --query "login" --team-id $CLICKUP_TEAM_ID
69
+ ```
@@ -0,0 +1,13 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import * as _kb_labs_clickup_contracts from '@kb-labs/clickup-contracts';
3
+ import { CLIInput } from '@kb-labs/sdk';
4
+
5
+ type FolderCreateFlags = {
6
+ space: string;
7
+ name: string;
8
+ json?: boolean;
9
+ full?: boolean;
10
+ };
11
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<FolderCreateFlags>, _kb_labs_clickup_contracts.ClickUpFolder | null>;
12
+
13
+ export { _default as default };
@@ -0,0 +1,94 @@
1
+ import { defineCommand, validationError } from '@kb-labs/sdk';
2
+ import { createFolder, requireApiKey, ClickUpApiError } from '@kb-labs/clickup-core';
3
+
4
+ // src/commands/folder-create.ts
5
+ function apiHint(err) {
6
+ switch (err.status) {
7
+ case 401:
8
+ return "CLICKUP_API_KEY is invalid or expired \u2014 check the token in your environment";
9
+ case 403:
10
+ return "You don't have permission for this action in ClickUp \u2014 check workspace access";
11
+ case 404:
12
+ return "Resource not found \u2014 verify the ID is correct (use `kb clickup workspace` to browse IDs)";
13
+ case 429:
14
+ return "ClickUp rate limit reached \u2014 wait a moment and retry";
15
+ default:
16
+ return "Unexpected ClickUp API error";
17
+ }
18
+ }
19
+ function handleError(ctx, err, isJson) {
20
+ if (err instanceof ClickUpApiError) {
21
+ const hint = apiHint(err);
22
+ if (isJson) {
23
+ ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });
24
+ } else {
25
+ ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });
26
+ }
27
+ return;
28
+ }
29
+ const message = err instanceof Error ? err.message : String(err);
30
+ const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);
31
+ if (isJson) {
32
+ ctx.ui?.json?.({
33
+ ok: false,
34
+ error: {
35
+ code: isEnvMissing ? "ENV_MISSING" : "INTERNAL_ERROR",
36
+ message,
37
+ ...isEnvMissing && {
38
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables"
39
+ }
40
+ }
41
+ });
42
+ } else {
43
+ ctx.ui?.error?.(message, {
44
+ ...isEnvMissing && {
45
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables",
46
+ command: "export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy"
47
+ }
48
+ });
49
+ }
50
+ }
51
+
52
+ // src/commands/folder-create.ts
53
+ var folder_create_default = defineCommand({
54
+ id: "clickup:folder.create",
55
+ description: "Create a new folder in a space",
56
+ handler: {
57
+ async intent(_ctx, input) {
58
+ const { space, name } = input.flags;
59
+ return {
60
+ summary: `Create folder "${name ?? "(unnamed)"}" in space ${space ?? "(unknown)"}`,
61
+ operations: [{ type: "create", resource: "folder", details: { space, name } }]
62
+ };
63
+ },
64
+ async execute(ctx, input) {
65
+ const { space, name, json, full } = input.flags;
66
+ if (!space) {
67
+ validationError(ctx, "--space is required", "Use `kb clickup workspace` to find the space ID", json);
68
+ return { exitCode: 1, result: null };
69
+ }
70
+ if (!name) {
71
+ validationError(ctx, "--name is required", void 0, json);
72
+ return { exitCode: 1, result: null };
73
+ }
74
+ try {
75
+ const folder = await createFolder(requireApiKey(), space, { name });
76
+ if (json) {
77
+ ctx.ui?.json?.(full ? folder : { id: folder.id, name: folder.name });
78
+ } else {
79
+ ctx.ui?.success?.("Folder created", {
80
+ sections: [{ items: [`id: ${folder.id}`, `name: ${folder.name}`] }]
81
+ });
82
+ }
83
+ return { exitCode: 0, result: folder };
84
+ } catch (err) {
85
+ handleError(ctx, err, json);
86
+ return { exitCode: 1, result: null };
87
+ }
88
+ }
89
+ }
90
+ });
91
+
92
+ export { folder_create_default as default };
93
+ //# sourceMappingURL=folder-create.js.map
94
+ //# sourceMappingURL=folder-create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/folder-create.ts"],"names":[],"mappings":"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","file":"folder-create.js","sourcesContent":["import type { PluginContextV3 } from '@kb-labs/sdk';\nimport { ClickUpApiError } from '@kb-labs/clickup-core';\n\nexport { validationError } from '@kb-labs/sdk';\n\nfunction apiHint(err: ClickUpApiError): string {\n switch (err.status) {\n case 401: return 'CLICKUP_API_KEY is invalid or expired — check the token in your environment';\n case 403: return 'You don\\'t have permission for this action in ClickUp — check workspace access';\n case 404: return 'Resource not found — verify the ID is correct (use `kb clickup workspace` to browse IDs)';\n case 429: return 'ClickUp rate limit reached — wait a moment and retry';\n default: return 'Unexpected ClickUp API error';\n }\n}\n\n/**\n * Output a structured error and return — call right before `return { exitCode: 1, result: null }`.\n * In JSON mode emits `{ ok: false, error: { code, message, hint?, status? } }`.\n * In CLI mode uses ctx.ui.error() with hint and cause.\n */\nexport function handleError(ctx: PluginContextV3, err: unknown, isJson?: boolean): void {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n if (isJson) {\n ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });\n } else {\n ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });\n }\n return;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n\n if (isJson) {\n ctx.ui?.json?.({\n ok: false,\n error: {\n code: isEnvMissing ? 'ENV_MISSING' : 'INTERNAL_ERROR',\n message,\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n }),\n },\n });\n } else {\n ctx.ui?.error?.(message, {\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n command: 'export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy',\n }),\n });\n }\n}\n\n/**\n * Re-throws `err` as an HTTP-aware error for REST handlers.\n * `ClickUpApiError` → preserves HTTP status code; env errors → 400; others → 500.\n * The envelope middleware in rest-api reads `err.statusCode` to set the response status.\n */\nexport function rethrowForRest(err: unknown): never {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n const restErr = Object.assign(new Error(err.message), {\n statusCode: err.status,\n code: err.code,\n details: { hint },\n });\n throw restErr;\n }\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n if (isEnvMissing) {\n throw Object.assign(new Error(message), {\n statusCode: 400,\n code: 'ENV_MISSING',\n details: { hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables' },\n });\n }\n throw err;\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, createFolder } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype FolderCreateFlags = {\n space: string;\n name: string;\n json?: boolean;\n full?: boolean;\n};\n\nexport default defineCommand({\n id: 'clickup:folder.create',\n description: 'Create a new folder in a space',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<FolderCreateFlags>) {\n const { space, name } = input.flags;\n return {\n summary: `Create folder \"${name ?? '(unnamed)'}\" in space ${space ?? '(unknown)'}`,\n operations: [{ type: 'create' as const, resource: 'folder', details: { space, name } }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<FolderCreateFlags>) {\n const { space, name, json, full } = input.flags;\n if (!space) {\n validationError(ctx, '--space is required', 'Use `kb clickup workspace` to find the space ID', json);\n return { exitCode: 1, result: null };\n }\n if (!name) {\n validationError(ctx, '--name is required', undefined, json);\n return { exitCode: 1, result: null };\n }\n\n try {\n const folder = await createFolder(requireApiKey(), space, { name });\n\n if (json) {\n ctx.ui?.json?.(full ? folder : { id: folder.id, name: folder.name });\n } else {\n ctx.ui?.success?.('Folder created', {\n sections: [{ items: [`id: ${folder.id}`, `name: ${folder.name}`] }],\n });\n }\n\n return { exitCode: 0, result: folder };\n } catch (err) {\n handleError(ctx, err, json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
@@ -0,0 +1,14 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { CLIInput } from '@kb-labs/sdk';
3
+
4
+ type FolderDeleteFlags = {
5
+ force?: boolean;
6
+ json?: boolean;
7
+ 'dry-run'?: boolean;
8
+ };
9
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<FolderDeleteFlags>, {
10
+ deleted: boolean;
11
+ folderId: string;
12
+ } | null>;
13
+
14
+ export { _default as default };
@@ -0,0 +1,92 @@
1
+ import { defineCommand, validationError } from '@kb-labs/sdk';
2
+ import { deleteFolder, requireApiKey, ClickUpApiError } from '@kb-labs/clickup-core';
3
+
4
+ // src/commands/folder-delete.ts
5
+ function apiHint(err) {
6
+ switch (err.status) {
7
+ case 401:
8
+ return "CLICKUP_API_KEY is invalid or expired \u2014 check the token in your environment";
9
+ case 403:
10
+ return "You don't have permission for this action in ClickUp \u2014 check workspace access";
11
+ case 404:
12
+ return "Resource not found \u2014 verify the ID is correct (use `kb clickup workspace` to browse IDs)";
13
+ case 429:
14
+ return "ClickUp rate limit reached \u2014 wait a moment and retry";
15
+ default:
16
+ return "Unexpected ClickUp API error";
17
+ }
18
+ }
19
+ function handleError(ctx, err, isJson) {
20
+ if (err instanceof ClickUpApiError) {
21
+ const hint = apiHint(err);
22
+ if (isJson) {
23
+ ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });
24
+ } else {
25
+ ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });
26
+ }
27
+ return;
28
+ }
29
+ const message = err instanceof Error ? err.message : String(err);
30
+ const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);
31
+ if (isJson) {
32
+ ctx.ui?.json?.({
33
+ ok: false,
34
+ error: {
35
+ code: isEnvMissing ? "ENV_MISSING" : "INTERNAL_ERROR",
36
+ message,
37
+ ...isEnvMissing && {
38
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables"
39
+ }
40
+ }
41
+ });
42
+ } else {
43
+ ctx.ui?.error?.(message, {
44
+ ...isEnvMissing && {
45
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables",
46
+ command: "export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy"
47
+ }
48
+ });
49
+ }
50
+ }
51
+
52
+ // src/commands/folder-delete.ts
53
+ var folder_delete_default = defineCommand({
54
+ id: "clickup:folder.delete",
55
+ description: "Delete a folder",
56
+ handler: {
57
+ async intent(_ctx, input) {
58
+ const [folderId] = input.argv;
59
+ return {
60
+ summary: `Delete folder ${folderId ?? "(unknown)"}`,
61
+ operations: [{ type: "delete", resource: "folder", details: { folderId } }]
62
+ };
63
+ },
64
+ async execute(ctx, input) {
65
+ const folderId = input.argv[0];
66
+ if (!folderId) {
67
+ validationError(ctx, "folderId is required", "Usage: kb clickup folder delete <folderId> --force", input.flags.json);
68
+ return { exitCode: 1, result: null };
69
+ }
70
+ if (!input.flags.force) {
71
+ validationError(ctx, `--force is required to delete folder ${folderId}`, "Add --force to confirm deletion", input.flags.json);
72
+ return { exitCode: 1, result: null };
73
+ }
74
+ try {
75
+ await deleteFolder(requireApiKey(), folderId);
76
+ if (input.flags.json) {
77
+ ctx.ui?.json?.({ ok: true, deleted: true, folderId });
78
+ } else {
79
+ ctx.ui?.success?.(`Deleted folder ${folderId}`);
80
+ }
81
+ return { exitCode: 0, result: { deleted: true, folderId } };
82
+ } catch (err) {
83
+ handleError(ctx, err, input.flags.json);
84
+ return { exitCode: 1, result: null };
85
+ }
86
+ }
87
+ }
88
+ });
89
+
90
+ export { folder_delete_default as default };
91
+ //# sourceMappingURL=folder-delete.js.map
92
+ //# sourceMappingURL=folder-delete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/folder-delete.ts"],"names":[],"mappings":"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","file":"folder-delete.js","sourcesContent":["import type { PluginContextV3 } from '@kb-labs/sdk';\nimport { ClickUpApiError } from '@kb-labs/clickup-core';\n\nexport { validationError } from '@kb-labs/sdk';\n\nfunction apiHint(err: ClickUpApiError): string {\n switch (err.status) {\n case 401: return 'CLICKUP_API_KEY is invalid or expired — check the token in your environment';\n case 403: return 'You don\\'t have permission for this action in ClickUp — check workspace access';\n case 404: return 'Resource not found — verify the ID is correct (use `kb clickup workspace` to browse IDs)';\n case 429: return 'ClickUp rate limit reached — wait a moment and retry';\n default: return 'Unexpected ClickUp API error';\n }\n}\n\n/**\n * Output a structured error and return — call right before `return { exitCode: 1, result: null }`.\n * In JSON mode emits `{ ok: false, error: { code, message, hint?, status? } }`.\n * In CLI mode uses ctx.ui.error() with hint and cause.\n */\nexport function handleError(ctx: PluginContextV3, err: unknown, isJson?: boolean): void {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n if (isJson) {\n ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });\n } else {\n ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });\n }\n return;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n\n if (isJson) {\n ctx.ui?.json?.({\n ok: false,\n error: {\n code: isEnvMissing ? 'ENV_MISSING' : 'INTERNAL_ERROR',\n message,\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n }),\n },\n });\n } else {\n ctx.ui?.error?.(message, {\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n command: 'export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy',\n }),\n });\n }\n}\n\n/**\n * Re-throws `err` as an HTTP-aware error for REST handlers.\n * `ClickUpApiError` → preserves HTTP status code; env errors → 400; others → 500.\n * The envelope middleware in rest-api reads `err.statusCode` to set the response status.\n */\nexport function rethrowForRest(err: unknown): never {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n const restErr = Object.assign(new Error(err.message), {\n statusCode: err.status,\n code: err.code,\n details: { hint },\n });\n throw restErr;\n }\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n if (isEnvMissing) {\n throw Object.assign(new Error(message), {\n statusCode: 400,\n code: 'ENV_MISSING',\n details: { hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables' },\n });\n }\n throw err;\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, deleteFolder } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype FolderDeleteFlags = {\n force?: boolean;\n json?: boolean;\n 'dry-run'?: boolean;\n};\n\nexport default defineCommand({\n id: 'clickup:folder.delete',\n description: 'Delete a folder',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<FolderDeleteFlags>) {\n const [folderId] = input.argv;\n return {\n summary: `Delete folder ${folderId ?? '(unknown)'}`,\n operations: [{ type: 'delete' as const, resource: 'folder', details: { folderId } }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<FolderDeleteFlags>) {\n const folderId = input.argv[0] as string | undefined;\n if (!folderId) {\n validationError(ctx, 'folderId is required', 'Usage: kb clickup folder delete <folderId> --force', input.flags.json);\n return { exitCode: 1, result: null };\n }\n if (!input.flags.force) {\n validationError(ctx, `--force is required to delete folder ${folderId}`, 'Add --force to confirm deletion', input.flags.json);\n return { exitCode: 1, result: null };\n }\n\n try {\n await deleteFolder(requireApiKey(), folderId);\n\n if (input.flags.json) {\n ctx.ui?.json?.({ ok: true, deleted: true, folderId });\n } else {\n ctx.ui?.success?.(`Deleted folder ${folderId}`);\n }\n\n return { exitCode: 0, result: { deleted: true, folderId } };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
@@ -0,0 +1,13 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import * as _kb_labs_clickup_contracts from '@kb-labs/clickup-contracts';
3
+ import { CLIInput } from '@kb-labs/sdk';
4
+
5
+ type FolderUpdateFlags = {
6
+ name: string;
7
+ json?: boolean;
8
+ full?: boolean;
9
+ 'dry-run'?: boolean;
10
+ };
11
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<FolderUpdateFlags>, _kb_labs_clickup_contracts.ClickUpFolder | null>;
12
+
13
+ export { _default as default };
@@ -0,0 +1,94 @@
1
+ import { defineCommand, validationError } from '@kb-labs/sdk';
2
+ import { updateFolder, requireApiKey, ClickUpApiError } from '@kb-labs/clickup-core';
3
+
4
+ // src/commands/folder-update.ts
5
+ function apiHint(err) {
6
+ switch (err.status) {
7
+ case 401:
8
+ return "CLICKUP_API_KEY is invalid or expired \u2014 check the token in your environment";
9
+ case 403:
10
+ return "You don't have permission for this action in ClickUp \u2014 check workspace access";
11
+ case 404:
12
+ return "Resource not found \u2014 verify the ID is correct (use `kb clickup workspace` to browse IDs)";
13
+ case 429:
14
+ return "ClickUp rate limit reached \u2014 wait a moment and retry";
15
+ default:
16
+ return "Unexpected ClickUp API error";
17
+ }
18
+ }
19
+ function handleError(ctx, err, isJson) {
20
+ if (err instanceof ClickUpApiError) {
21
+ const hint = apiHint(err);
22
+ if (isJson) {
23
+ ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });
24
+ } else {
25
+ ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });
26
+ }
27
+ return;
28
+ }
29
+ const message = err instanceof Error ? err.message : String(err);
30
+ const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);
31
+ if (isJson) {
32
+ ctx.ui?.json?.({
33
+ ok: false,
34
+ error: {
35
+ code: isEnvMissing ? "ENV_MISSING" : "INTERNAL_ERROR",
36
+ message,
37
+ ...isEnvMissing && {
38
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables"
39
+ }
40
+ }
41
+ });
42
+ } else {
43
+ ctx.ui?.error?.(message, {
44
+ ...isEnvMissing && {
45
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables",
46
+ command: "export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy"
47
+ }
48
+ });
49
+ }
50
+ }
51
+
52
+ // src/commands/folder-update.ts
53
+ var folder_update_default = defineCommand({
54
+ id: "clickup:folder.update",
55
+ description: "Rename a folder",
56
+ handler: {
57
+ async intent(_ctx, input) {
58
+ const [folderId] = input.argv;
59
+ return {
60
+ summary: `Rename folder ${folderId ?? "(unknown)"} to "${input.flags.name ?? "(unnamed)"}"`,
61
+ operations: [{ type: "update", resource: "folder", details: { folderId, name: input.flags.name } }]
62
+ };
63
+ },
64
+ async execute(ctx, input) {
65
+ const folderId = input.argv[0];
66
+ if (!folderId) {
67
+ validationError(ctx, "folderId is required", 'Usage: kb clickup folder update <folderId> --name "new name"', input.flags.json);
68
+ return { exitCode: 1, result: null };
69
+ }
70
+ if (!input.flags.name) {
71
+ validationError(ctx, "--name is required", void 0, input.flags.json);
72
+ return { exitCode: 1, result: null };
73
+ }
74
+ try {
75
+ const folder = await updateFolder(requireApiKey(), folderId, { name: input.flags.name });
76
+ if (input.flags.json) {
77
+ ctx.ui?.json?.(input.flags.full ? folder : { id: folder.id, name: folder.name });
78
+ } else {
79
+ ctx.ui?.success?.("Folder updated", {
80
+ sections: [{ items: [`id: ${folder.id}`, `name: ${folder.name}`] }]
81
+ });
82
+ }
83
+ return { exitCode: 0, result: folder };
84
+ } catch (err) {
85
+ handleError(ctx, err, input.flags.json);
86
+ return { exitCode: 1, result: null };
87
+ }
88
+ }
89
+ }
90
+ });
91
+
92
+ export { folder_update_default as default };
93
+ //# sourceMappingURL=folder-update.js.map
94
+ //# sourceMappingURL=folder-update.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/folder-update.ts"],"names":[],"mappings":"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","file":"folder-update.js","sourcesContent":["import type { PluginContextV3 } from '@kb-labs/sdk';\nimport { ClickUpApiError } from '@kb-labs/clickup-core';\n\nexport { validationError } from '@kb-labs/sdk';\n\nfunction apiHint(err: ClickUpApiError): string {\n switch (err.status) {\n case 401: return 'CLICKUP_API_KEY is invalid or expired — check the token in your environment';\n case 403: return 'You don\\'t have permission for this action in ClickUp — check workspace access';\n case 404: return 'Resource not found — verify the ID is correct (use `kb clickup workspace` to browse IDs)';\n case 429: return 'ClickUp rate limit reached — wait a moment and retry';\n default: return 'Unexpected ClickUp API error';\n }\n}\n\n/**\n * Output a structured error and return — call right before `return { exitCode: 1, result: null }`.\n * In JSON mode emits `{ ok: false, error: { code, message, hint?, status? } }`.\n * In CLI mode uses ctx.ui.error() with hint and cause.\n */\nexport function handleError(ctx: PluginContextV3, err: unknown, isJson?: boolean): void {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n if (isJson) {\n ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });\n } else {\n ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });\n }\n return;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n\n if (isJson) {\n ctx.ui?.json?.({\n ok: false,\n error: {\n code: isEnvMissing ? 'ENV_MISSING' : 'INTERNAL_ERROR',\n message,\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n }),\n },\n });\n } else {\n ctx.ui?.error?.(message, {\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n command: 'export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy',\n }),\n });\n }\n}\n\n/**\n * Re-throws `err` as an HTTP-aware error for REST handlers.\n * `ClickUpApiError` → preserves HTTP status code; env errors → 400; others → 500.\n * The envelope middleware in rest-api reads `err.statusCode` to set the response status.\n */\nexport function rethrowForRest(err: unknown): never {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n const restErr = Object.assign(new Error(err.message), {\n statusCode: err.status,\n code: err.code,\n details: { hint },\n });\n throw restErr;\n }\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n if (isEnvMissing) {\n throw Object.assign(new Error(message), {\n statusCode: 400,\n code: 'ENV_MISSING',\n details: { hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables' },\n });\n }\n throw err;\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, updateFolder } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype FolderUpdateFlags = {\n name: string;\n json?: boolean;\n full?: boolean;\n 'dry-run'?: boolean;\n};\n\nexport default defineCommand({\n id: 'clickup:folder.update',\n description: 'Rename a folder',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<FolderUpdateFlags>) {\n const [folderId] = input.argv;\n return {\n summary: `Rename folder ${folderId ?? '(unknown)'} to \"${input.flags.name ?? '(unnamed)'}\"`,\n operations: [{ type: 'update' as const, resource: 'folder', details: { folderId, name: input.flags.name } }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<FolderUpdateFlags>) {\n const folderId = input.argv[0] as string | undefined;\n if (!folderId) {\n validationError(ctx, 'folderId is required', 'Usage: kb clickup folder update <folderId> --name \"new name\"', input.flags.json);\n return { exitCode: 1, result: null };\n }\n if (!input.flags.name) {\n validationError(ctx, '--name is required', undefined, input.flags.json);\n return { exitCode: 1, result: null };\n }\n\n try {\n const folder = await updateFolder(requireApiKey(), folderId, { name: input.flags.name });\n\n if (input.flags.json) {\n ctx.ui?.json?.(input.flags.full ? folder : { id: folder.id, name: folder.name });\n } else {\n ctx.ui?.success?.('Folder updated', {\n sections: [{ items: [`id: ${folder.id}`, `name: ${folder.name}`] }],\n });\n }\n\n return { exitCode: 0, result: folder };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
@@ -0,0 +1,15 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import * as _kb_labs_clickup_contracts from '@kb-labs/clickup-contracts';
3
+ import { CLIInput } from '@kb-labs/sdk';
4
+
5
+ type ListCreateFlags = {
6
+ folder?: string;
7
+ space?: string;
8
+ name: string;
9
+ json?: boolean;
10
+ full?: boolean;
11
+ 'dry-run'?: boolean;
12
+ };
13
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<ListCreateFlags>, _kb_labs_clickup_contracts.ClickUpList | null>;
14
+
15
+ export { _default as default };
@@ -0,0 +1,96 @@
1
+ import { defineCommand, validationError } from '@kb-labs/sdk';
2
+ import { requireApiKey, createListInFolder, createListInSpace, ClickUpApiError } from '@kb-labs/clickup-core';
3
+
4
+ // src/commands/list-create.ts
5
+ function apiHint(err) {
6
+ switch (err.status) {
7
+ case 401:
8
+ return "CLICKUP_API_KEY is invalid or expired \u2014 check the token in your environment";
9
+ case 403:
10
+ return "You don't have permission for this action in ClickUp \u2014 check workspace access";
11
+ case 404:
12
+ return "Resource not found \u2014 verify the ID is correct (use `kb clickup workspace` to browse IDs)";
13
+ case 429:
14
+ return "ClickUp rate limit reached \u2014 wait a moment and retry";
15
+ default:
16
+ return "Unexpected ClickUp API error";
17
+ }
18
+ }
19
+ function handleError(ctx, err, isJson) {
20
+ if (err instanceof ClickUpApiError) {
21
+ const hint = apiHint(err);
22
+ if (isJson) {
23
+ ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });
24
+ } else {
25
+ ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });
26
+ }
27
+ return;
28
+ }
29
+ const message = err instanceof Error ? err.message : String(err);
30
+ const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);
31
+ if (isJson) {
32
+ ctx.ui?.json?.({
33
+ ok: false,
34
+ error: {
35
+ code: isEnvMissing ? "ENV_MISSING" : "INTERNAL_ERROR",
36
+ message,
37
+ ...isEnvMissing && {
38
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables"
39
+ }
40
+ }
41
+ });
42
+ } else {
43
+ ctx.ui?.error?.(message, {
44
+ ...isEnvMissing && {
45
+ hint: "Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables",
46
+ command: "export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy"
47
+ }
48
+ });
49
+ }
50
+ }
51
+
52
+ // src/commands/list-create.ts
53
+ var list_create_default = defineCommand({
54
+ id: "clickup:list.create",
55
+ description: "Create a new list in a folder or space",
56
+ handler: {
57
+ async intent(_ctx, input) {
58
+ const { folder, space, name } = input.flags;
59
+ const parent = folder ? `folder ${folder}` : space ? `space ${space}` : "(unknown)";
60
+ return {
61
+ summary: `Create list "${name}" in ${parent}`,
62
+ operations: [{ type: "create", resource: "list", details: { folder, space, name } }]
63
+ };
64
+ },
65
+ async execute(ctx, input) {
66
+ const { folder, space, name, json, full } = input.flags;
67
+ if (!name) {
68
+ validationError(ctx, "--name is required", void 0, json);
69
+ return { exitCode: 1, result: null };
70
+ }
71
+ if (!folder && !space) {
72
+ validationError(ctx, "--folder or --space is required", "Use `kb clickup workspace` to find IDs", json);
73
+ return { exitCode: 1, result: null };
74
+ }
75
+ try {
76
+ const apiKey = requireApiKey();
77
+ const list = folder ? await createListInFolder(apiKey, folder, { name }) : await createListInSpace(apiKey, space, { name });
78
+ if (json) {
79
+ ctx.ui?.json?.(full ? list : { id: list.id, name: list.name });
80
+ } else {
81
+ ctx.ui?.success?.("List created", {
82
+ sections: [{ items: [`id: ${list.id}`, `name: ${list.name}`] }]
83
+ });
84
+ }
85
+ return { exitCode: 0, result: list };
86
+ } catch (err) {
87
+ handleError(ctx, err, json);
88
+ return { exitCode: 1, result: null };
89
+ }
90
+ }
91
+ }
92
+ });
93
+
94
+ export { list_create_default as default };
95
+ //# sourceMappingURL=list-create.js.map
96
+ //# sourceMappingURL=list-create.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/list-create.ts"],"names":[],"mappings":"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","file":"list-create.js","sourcesContent":["import type { PluginContextV3 } from '@kb-labs/sdk';\nimport { ClickUpApiError } from '@kb-labs/clickup-core';\n\nexport { validationError } from '@kb-labs/sdk';\n\nfunction apiHint(err: ClickUpApiError): string {\n switch (err.status) {\n case 401: return 'CLICKUP_API_KEY is invalid or expired — check the token in your environment';\n case 403: return 'You don\\'t have permission for this action in ClickUp — check workspace access';\n case 404: return 'Resource not found — verify the ID is correct (use `kb clickup workspace` to browse IDs)';\n case 429: return 'ClickUp rate limit reached — wait a moment and retry';\n default: return 'Unexpected ClickUp API error';\n }\n}\n\n/**\n * Output a structured error and return — call right before `return { exitCode: 1, result: null }`.\n * In JSON mode emits `{ ok: false, error: { code, message, hint?, status? } }`.\n * In CLI mode uses ctx.ui.error() with hint and cause.\n */\nexport function handleError(ctx: PluginContextV3, err: unknown, isJson?: boolean): void {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n if (isJson) {\n ctx.ui?.json?.({ ok: false, error: { code: err.code, message: err.message, status: err.status, hint } });\n } else {\n ctx.ui?.error?.(err.message, { hint, cause: `ClickUp API ${err.status} (${err.code})` });\n }\n return;\n }\n\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n\n if (isJson) {\n ctx.ui?.json?.({\n ok: false,\n error: {\n code: isEnvMissing ? 'ENV_MISSING' : 'INTERNAL_ERROR',\n message,\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n }),\n },\n });\n } else {\n ctx.ui?.error?.(message, {\n ...(isEnvMissing && {\n hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables',\n command: 'export CLICKUP_API_KEY=pk_xxx CLICKUP_TEAM_ID=yyy',\n }),\n });\n }\n}\n\n/**\n * Re-throws `err` as an HTTP-aware error for REST handlers.\n * `ClickUpApiError` → preserves HTTP status code; env errors → 400; others → 500.\n * The envelope middleware in rest-api reads `err.statusCode` to set the response status.\n */\nexport function rethrowForRest(err: unknown): never {\n if (err instanceof ClickUpApiError) {\n const hint = apiHint(err);\n const restErr = Object.assign(new Error(err.message), {\n statusCode: err.status,\n code: err.code,\n details: { hint },\n });\n throw restErr;\n }\n const message = err instanceof Error ? err.message : String(err);\n const isEnvMissing = /CLICKUP_API_KEY|CLICKUP_TEAM_ID/.test(message);\n if (isEnvMissing) {\n throw Object.assign(new Error(message), {\n statusCode: 400,\n code: 'ENV_MISSING',\n details: { hint: 'Set CLICKUP_API_KEY (and CLICKUP_TEAM_ID for workspace commands) as environment variables' },\n });\n }\n throw err;\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, createListInFolder, createListInSpace } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype ListCreateFlags = {\n folder?: string;\n space?: string;\n name: string;\n json?: boolean;\n full?: boolean;\n 'dry-run'?: boolean;\n};\n\nexport default defineCommand({\n id: 'clickup:list.create',\n description: 'Create a new list in a folder or space',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<ListCreateFlags>) {\n const { folder, space, name } = input.flags;\n const parent = folder ? `folder ${folder}` : space ? `space ${space}` : '(unknown)';\n return {\n summary: `Create list \"${name}\" in ${parent}`,\n operations: [{ type: 'create' as const, resource: 'list', details: { folder, space, name } }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<ListCreateFlags>) {\n const { folder, space, name, json, full } = input.flags;\n if (!name) {\n validationError(ctx, '--name is required', undefined, json);\n return { exitCode: 1, result: null };\n }\n if (!folder && !space) {\n validationError(ctx, '--folder or --space is required', 'Use `kb clickup workspace` to find IDs', json);\n return { exitCode: 1, result: null };\n }\n\n try {\n const apiKey = requireApiKey();\n const list = folder\n ? await createListInFolder(apiKey, folder, { name })\n : await createListInSpace(apiKey, space!, { name });\n\n if (json) {\n ctx.ui?.json?.(full ? list : { id: list.id, name: list.name });\n } else {\n ctx.ui?.success?.('List created', {\n sections: [{ items: [`id: ${list.id}`, `name: ${list.name}`] }],\n });\n }\n\n return { exitCode: 0, result: list };\n } catch (err) {\n handleError(ctx, err, json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
@@ -0,0 +1,14 @@
1
+ import * as _kb_labs_shared_command_kit from '@kb-labs/shared-command-kit';
2
+ import { CLIInput } from '@kb-labs/sdk';
3
+
4
+ type ListDeleteFlags = {
5
+ force?: boolean;
6
+ json?: boolean;
7
+ 'dry-run'?: boolean;
8
+ };
9
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<ListDeleteFlags>, {
10
+ deleted: boolean;
11
+ listId: string;
12
+ } | null>;
13
+
14
+ export { _default as default };