@kb-labs/clickup-entry 2.107.0 → 2.110.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 (77) hide show
  1. package/dist/commands/folder-create.d.ts +1 -1
  2. package/dist/commands/folder-create.js +4 -4
  3. package/dist/commands/folder-create.js.map +1 -1
  4. package/dist/commands/folder-delete.d.ts +1 -1
  5. package/dist/commands/folder-delete.js +4 -4
  6. package/dist/commands/folder-delete.js.map +1 -1
  7. package/dist/commands/folder-update.d.ts +1 -1
  8. package/dist/commands/folder-update.js +4 -4
  9. package/dist/commands/folder-update.js.map +1 -1
  10. package/dist/commands/list-create.d.ts +1 -1
  11. package/dist/commands/list-create.js +4 -4
  12. package/dist/commands/list-create.js.map +1 -1
  13. package/dist/commands/list-delete.d.ts +1 -1
  14. package/dist/commands/list-delete.js +4 -4
  15. package/dist/commands/list-delete.js.map +1 -1
  16. package/dist/commands/list-statuses.d.ts +1 -1
  17. package/dist/commands/list-statuses.js +4 -4
  18. package/dist/commands/list-statuses.js.map +1 -1
  19. package/dist/commands/list-tasks.d.ts +1 -1
  20. package/dist/commands/list-tasks.js +5 -5
  21. package/dist/commands/list-tasks.js.map +1 -1
  22. package/dist/commands/list-update.d.ts +1 -1
  23. package/dist/commands/list-update.js +3 -3
  24. package/dist/commands/list-update.js.map +1 -1
  25. package/dist/commands/space-create.d.ts +1 -1
  26. package/dist/commands/space-create.js +3 -3
  27. package/dist/commands/space-create.js.map +1 -1
  28. package/dist/commands/space-delete.d.ts +1 -1
  29. package/dist/commands/space-delete.js +4 -4
  30. package/dist/commands/space-delete.js.map +1 -1
  31. package/dist/commands/space-update.d.ts +1 -1
  32. package/dist/commands/space-update.js +3 -3
  33. package/dist/commands/space-update.js.map +1 -1
  34. package/dist/commands/task-comment-add.d.ts +1 -1
  35. package/dist/commands/task-comment-add.js +4 -4
  36. package/dist/commands/task-comment-add.js.map +1 -1
  37. package/dist/commands/task-comment-list.d.ts +1 -1
  38. package/dist/commands/task-comment-list.js +5 -5
  39. package/dist/commands/task-comment-list.js.map +1 -1
  40. package/dist/commands/task-create.d.ts +1 -1
  41. package/dist/commands/task-create.js +4 -4
  42. package/dist/commands/task-create.js.map +1 -1
  43. package/dist/commands/task-delete.d.ts +1 -1
  44. package/dist/commands/task-delete.js +4 -4
  45. package/dist/commands/task-delete.js.map +1 -1
  46. package/dist/commands/task-get.d.ts +1 -1
  47. package/dist/commands/task-get.js +4 -4
  48. package/dist/commands/task-get.js.map +1 -1
  49. package/dist/commands/task-search.d.ts +1 -1
  50. package/dist/commands/task-search.js +4 -4
  51. package/dist/commands/task-search.js.map +1 -1
  52. package/dist/commands/task-update.d.ts +1 -1
  53. package/dist/commands/task-update.js +3 -3
  54. package/dist/commands/task-update.js.map +1 -1
  55. package/dist/commands/workspace.d.ts +1 -1
  56. package/dist/commands/workspace.js +3 -3
  57. package/dist/commands/workspace.js.map +1 -1
  58. package/dist/rest/handlers/folder-create-handler.js.map +1 -1
  59. package/dist/rest/handlers/folder-delete-handler.js.map +1 -1
  60. package/dist/rest/handlers/folder-update-handler.js.map +1 -1
  61. package/dist/rest/handlers/list-create-handler.js.map +1 -1
  62. package/dist/rest/handlers/list-delete-handler.js.map +1 -1
  63. package/dist/rest/handlers/list-statuses-handler.js.map +1 -1
  64. package/dist/rest/handlers/list-tasks-handler.js.map +1 -1
  65. package/dist/rest/handlers/list-update-handler.js.map +1 -1
  66. package/dist/rest/handlers/search-handler.js.map +1 -1
  67. package/dist/rest/handlers/space-create-handler.js.map +1 -1
  68. package/dist/rest/handlers/space-delete-handler.js.map +1 -1
  69. package/dist/rest/handlers/space-update-handler.js.map +1 -1
  70. package/dist/rest/handlers/task-comment-add-handler.js.map +1 -1
  71. package/dist/rest/handlers/task-comments-handler.js.map +1 -1
  72. package/dist/rest/handlers/task-create-handler.js.map +1 -1
  73. package/dist/rest/handlers/task-delete-handler.js.map +1 -1
  74. package/dist/rest/handlers/task-get-handler.js.map +1 -1
  75. package/dist/rest/handlers/task-update-handler.js.map +1 -1
  76. package/dist/rest/handlers/workspace-handler.js.map +1 -1
  77. package/package.json +4 -4
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/task-delete.ts"],"names":[],"mappings":"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","file":"task-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, deleteTask } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype TaskDeleteFlags = { yes?: boolean; json?: boolean; 'dry-run'?: boolean };\n\nexport default defineCommand({\n id: 'clickup:task.delete',\n description: 'Delete a task',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<TaskDeleteFlags>) {\n const [taskId] = input.argv;\n return {\n summary: `Delete task ${taskId ?? '(unknown)'}`,\n operations: [{ type: 'delete' as const, resource: 'task', details: { taskId } }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<TaskDeleteFlags>) {\n const [taskId] = input.argv;\n if (!taskId) {\n validationError(ctx, 'Task ID is required', 'Usage: kb clickup task delete <taskId> --yes', input.flags.json);\n return { exitCode: 1, result: null };\n }\n\n if (!input.flags.yes) {\n validationError(ctx, `--yes is required to delete task ${taskId}`, 'Add --yes to confirm deletion', input.flags.json);\n return { exitCode: 1, result: null };\n }\n\n try {\n await deleteTask(requireApiKey(), taskId);\n\n if (input.flags.json) {\n ctx.ui?.json?.({ ok: true, deleted: true, taskId });\n } else {\n ctx.ui?.success?.(`Deleted task ${taskId}`);\n }\n\n return { exitCode: 0, result: { deleted: true, taskId } };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/task-delete.ts"],"names":[],"mappings":"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","file":"task-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 { ok: false, error: 'Command failed', 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, deleteTask } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype TaskDeleteFlags = { yes?: boolean; json?: boolean; 'dry-run'?: boolean };\n\nexport default defineCommand({\n id: 'clickup:task.delete',\n description: 'Delete a task',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<TaskDeleteFlags>) {\n const [taskId] = input.argv;\n return {\n summary: `Delete task ${taskId ?? '(unknown)'}`,\n operations: [{ type: 'delete' as const, resource: 'task', details: { taskId } }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<TaskDeleteFlags>) {\n const [taskId] = input.argv;\n if (!taskId) {\n validationError(ctx, 'Task ID is required', 'Usage: kb clickup task delete <taskId> --yes', input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n\n if (!input.flags.yes) {\n validationError(ctx, `--yes is required to delete task ${taskId}`, 'Add --yes to confirm deletion', input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n\n try {\n await deleteTask(requireApiKey(), taskId);\n\n if (input.flags.json) {\n ctx.ui?.json?.({ ok: true, deleted: true, taskId });\n } else {\n ctx.ui?.success?.(`Deleted task ${taskId}`);\n }\n\n return { ok: true, result: { deleted: true, taskId } };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n },\n },\n});\n"]}
@@ -9,6 +9,6 @@ type TaskGetFlags = {
9
9
  declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<TaskGetFlags>, {
10
10
  task: _kb_labs_clickup_contracts.ClickUpTask;
11
11
  comments: _kb_labs_clickup_contracts.ClickUpComment[];
12
- } | null>;
12
+ }>;
13
13
 
14
14
  export { _default as default };
@@ -73,7 +73,7 @@ var task_get_default = defineCommand({
73
73
  const [taskId] = input.argv;
74
74
  if (!taskId) {
75
75
  validationError(ctx, "Task ID is required", "Usage: kb clickup task get <taskId>", input.flags.json);
76
- return { exitCode: 1, result: null };
76
+ return { ok: false, error: "Command failed", result: null };
77
77
  }
78
78
  try {
79
79
  const apiKey = requireApiKey();
@@ -83,7 +83,7 @@ var task_get_default = defineCommand({
83
83
  ]);
84
84
  if (input.flags.json) {
85
85
  ctx.ui?.json?.(input.flags.full ? { task, comments } : slimTaskWithDesc(task));
86
- return { exitCode: 0, result: { task, comments } };
86
+ return { ok: true, result: { task, comments } };
87
87
  }
88
88
  const priority = task.priority?.priority ?? "\u2013";
89
89
  const assignees = task.assignees.map((a) => a.username).join(", ") || "\u2013";
@@ -114,10 +114,10 @@ var task_get_default = defineCommand({
114
114
  },
115
115
  sections
116
116
  });
117
- return { exitCode: 0, result: { task, comments } };
117
+ return { ok: true, result: { task, comments } };
118
118
  } catch (err) {
119
119
  handleError(ctx, err, input.flags.json);
120
- return { exitCode: 1, result: null };
120
+ return { ok: false, error: "Command failed", result: null };
121
121
  }
122
122
  }
123
123
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/error.ts","../../src/utils/slim.ts","../../src/commands/task-get.ts"],"names":[],"mappings":"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","file":"task-get.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 type { ClickUpTask } from '@kb-labs/clickup-contracts';\n\nexport function slimTask(task: ClickUpTask) {\n return {\n id: task.id,\n name: task.name,\n status: task.status.status,\n priority: task.priority?.id ? Number(task.priority.id) : null,\n due_date: task.due_date ? Number(task.due_date) : null,\n url: task.url,\n };\n}\n\nexport function slimTaskWithDesc(task: ClickUpTask) {\n return { ...slimTask(task), description: task.description ?? '' };\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, getTask, getTaskComments } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\nimport { slimTaskWithDesc } from '../utils/slim.js';\n\ntype TaskGetFlags = { json?: boolean; full?: boolean };\n\nexport default defineCommand({\n id: 'clickup:task.get',\n description: 'Get full task details including comments',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<TaskGetFlags>) {\n const [taskId] = input.argv;\n if (!taskId) {\n validationError(ctx, 'Task ID is required', 'Usage: kb clickup task get <taskId>', input.flags.json);\n return { exitCode: 1, result: null };\n }\n\n try {\n const apiKey = requireApiKey();\n const [task, comments] = await Promise.all([\n getTask(apiKey, taskId),\n getTaskComments(apiKey, taskId),\n ]);\n\n if (input.flags.json) {\n ctx.ui?.json?.(input.flags.full ? { task, comments } : slimTaskWithDesc(task));\n return { exitCode: 0, result: { task, comments } };\n }\n\n const priority = task.priority?.priority ?? '–';\n const assignees = task.assignees.map(a => a.username).join(', ') || '–';\n const due = task.due_date\n ? new Date(Number(task.due_date)).toLocaleDateString()\n : '–';\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n if (task.description) {\n sections.push({ header: 'Description', items: [task.description] });\n }\n\n if (comments.length) {\n sections.push({\n header: `Comments (${comments.length})`,\n items: comments.map(c => {\n const date = new Date(Number(c.date)).toLocaleString();\n return `[${c.user.username} @ ${date}] ${c.comment_text}`;\n }),\n });\n }\n\n ctx.ui?.sideBox?.({\n title: `[${task.id}] ${task.name}`,\n status: 'info',\n summary: {\n 'Status': task.status.status,\n 'Priority': priority,\n 'Assignees': assignees,\n 'Due': due,\n 'List': `${task.list.name} / ${task.folder.name}`,\n 'URL': task.url,\n },\n sections,\n });\n\n return { exitCode: 0, result: { task, comments } };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/utils/slim.ts","../../src/commands/task-get.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AAOO,SAAS,WAAA,CAAY,GAAA,EAAsB,GAAA,EAAc,MAAA,EAAwB;AACtF,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,GAAA,CAAI,IAAI,IAAA,GAAO,EAAE,IAAI,KAAA,EAAO,KAAA,EAAO,EAAE,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,OAAA,EAAS,IAAI,OAAA,EAAS,MAAA,EAAQ,IAAI,MAAA,EAAQ,IAAA,IAAQ,CAAA;AAAA,IACzG,CAAA,MAAO;AACL,MAAA,GAAA,CAAI,EAAA,EAAI,KAAA,GAAQ,GAAA,CAAI,OAAA,EAAS,EAAE,IAAA,EAAM,KAAA,EAAO,CAAA,YAAA,EAAe,GAAA,CAAI,MAAM,CAAA,EAAA,EAAK,GAAA,CAAI,IAAI,KAAK,CAAA;AAAA,IACzF;AACA,IAAA;AAAA,EACF;AAEA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AAEnE,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,GAAA,CAAI,IAAI,IAAA,GAAO;AAAA,MACb,EAAA,EAAI,KAAA;AAAA,MACJ,KAAA,EAAO;AAAA,QACL,IAAA,EAAM,eAAe,aAAA,GAAgB,gBAAA;AAAA,QACrC,OAAA;AAAA,QACA,GAAI,YAAA,IAAgB;AAAA,UAClB,IAAA,EAAM;AAAA;AACR;AACF,KACD,CAAA;AAAA,EACH,CAAA,MAAO;AACL,IAAA,GAAA,CAAI,EAAA,EAAI,QAAQ,OAAA,EAAS;AAAA,MACvB,GAAI,YAAA,IAAgB;AAAA,QAClB,IAAA,EAAM,2FAAA;AAAA,QACN,OAAA,EAAS;AAAA;AACX,KACD,CAAA;AAAA,EACH;AACF;;;ACnDO,SAAS,SAAS,IAAA,EAAmB;AAC1C,EAAA,OAAO;AAAA,IACL,IAAU,IAAA,CAAK,EAAA;AAAA,IACf,MAAU,IAAA,CAAK,IAAA;AAAA,IACf,MAAA,EAAU,KAAK,MAAA,CAAO,MAAA;AAAA,IACtB,QAAA,EAAU,KAAK,QAAA,EAAU,EAAA,GAAK,OAAO,IAAA,CAAK,QAAA,CAAS,EAAE,CAAA,GAAI,IAAA;AAAA,IACzD,UAAU,IAAA,CAAK,QAAA,GAAW,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAA,GAAI,IAAA;AAAA,IAClD,KAAU,IAAA,CAAK;AAAA,GACjB;AACF;AAEO,SAAS,iBAAiB,IAAA,EAAmB;AAClD,EAAA,OAAO,EAAE,GAAG,QAAA,CAAS,IAAI,GAAG,WAAA,EAAa,IAAA,CAAK,eAAe,EAAA,EAAG;AAClE;;;ACRA,IAAO,mBAAQ,aAAA,CAAc;AAAA,EAC3B,EAAA,EAAI,kBAAA;AAAA,EACJ,WAAA,EAAa,0CAAA;AAAA,EAEb,OAAA,EAAS;AAAA,IACP,MAAM,OAAA,CAAQ,GAAA,EAAsB,KAAA,EAA+B;AACjE,MAAA,MAAM,CAAC,MAAM,CAAA,GAAI,KAAA,CAAM,IAAA;AACvB,MAAA,IAAI,CAAC,MAAA,EAAQ;AACX,QAAA,eAAA,CAAgB,GAAA,EAAK,qBAAA,EAAuB,qCAAA,EAAuC,KAAA,CAAM,MAAM,IAAI,CAAA;AACnG,QAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,gBAAA,EAAkB,QAAQ,IAAA,EAAK;AAAA,MAC5D;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,QAAA,MAAM,CAAC,IAAA,EAAM,QAAQ,CAAA,GAAI,MAAM,QAAQ,GAAA,CAAI;AAAA,UACzC,OAAA,CAAQ,QAAQ,MAAM,CAAA;AAAA,UACtB,eAAA,CAAgB,QAAQ,MAAM;AAAA,SAC/B,CAAA;AAED,QAAA,IAAI,KAAA,CAAM,MAAM,IAAA,EAAM;AACpB,UAAA,GAAA,CAAI,EAAA,EAAI,IAAA,GAAO,KAAA,CAAM,KAAA,CAAM,IAAA,GAAO,EAAE,IAAA,EAAM,QAAA,EAAS,GAAI,gBAAA,CAAiB,IAAI,CAAC,CAAA;AAC7E,UAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,QAAQ,EAAE,IAAA,EAAM,UAAS,EAAE;AAAA,QAChD;AAEA,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,QAAA,EAAU,QAAA,IAAY,QAAA;AAC5C,QAAA,MAAM,SAAA,GAAY,IAAA,CAAK,SAAA,CAAU,GAAA,CAAI,CAAA,CAAA,KAAK,EAAE,QAAQ,CAAA,CAAE,IAAA,CAAK,IAAI,CAAA,IAAK,QAAA;AACpE,QAAA,MAAM,GAAA,GAAM,IAAA,CAAK,QAAA,GACb,IAAI,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,QAAQ,CAAC,CAAA,CAAE,kBAAA,EAAmB,GACnD,QAAA;AAEJ,QAAA,MAAM,WAAuD,EAAC;AAE9D,QAAA,IAAI,KAAK,WAAA,EAAa;AACpB,UAAA,QAAA,CAAS,IAAA,CAAK,EAAE,MAAA,EAAQ,aAAA,EAAe,OAAO,CAAC,IAAA,CAAK,WAAW,CAAA,EAAG,CAAA;AAAA,QACpE;AAEA,QAAA,IAAI,SAAS,MAAA,EAAQ;AACnB,UAAA,QAAA,CAAS,IAAA,CAAK;AAAA,YACZ,MAAA,EAAQ,CAAA,UAAA,EAAa,QAAA,CAAS,MAAM,CAAA,CAAA,CAAA;AAAA,YACpC,KAAA,EAAO,QAAA,CAAS,GAAA,CAAI,CAAA,CAAA,KAAK;AACvB,cAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,MAAA,CAAO,EAAE,IAAI,CAAC,EAAE,cAAA,EAAe;AACrD,cAAA,OAAO,CAAA,CAAA,EAAI,EAAE,IAAA,CAAK,QAAQ,MAAM,IAAI,CAAA,EAAA,EAAK,EAAE,YAAY,CAAA,CAAA;AAAA,YACzD,CAAC;AAAA,WACF,CAAA;AAAA,QACH;AAEA,QAAA,GAAA,CAAI,IAAI,OAAA,GAAU;AAAA,UAChB,OAAO,CAAA,CAAA,EAAI,IAAA,CAAK,EAAE,CAAA,EAAA,EAAK,KAAK,IAAI,CAAA,CAAA;AAAA,UAChC,MAAA,EAAQ,MAAA;AAAA,UACR,OAAA,EAAS;AAAA,YACP,QAAA,EAAa,KAAK,MAAA,CAAO,MAAA;AAAA,YACzB,UAAA,EAAa,QAAA;AAAA,YACb,WAAA,EAAa,SAAA;AAAA,YACb,KAAA,EAAa,GAAA;AAAA,YACb,MAAA,EAAa,GAAG,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA,GAAA,EAAM,IAAA,CAAK,OAAO,IAAI,CAAA,CAAA;AAAA,YACpD,OAAa,IAAA,CAAK;AAAA,WACpB;AAAA,UACA;AAAA,SACD,CAAA;AAED,QAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,QAAQ,EAAE,IAAA,EAAM,UAAS,EAAE;AAAA,MAChD,SAAS,GAAA,EAAK;AACZ,QAAA,WAAA,CAAY,GAAA,EAAK,GAAA,EAAK,KAAA,CAAM,KAAA,CAAM,IAAI,CAAA;AACtC,QAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,KAAA,EAAO,gBAAA,EAAkB,QAAQ,IAAA,EAAK;AAAA,MAC5D;AAAA,IACF;AAAA;AAEJ,CAAC","file":"task-get.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 { ok: false, error: 'Command failed', 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 type { ClickUpTask } from '@kb-labs/clickup-contracts';\n\nexport function slimTask(task: ClickUpTask) {\n return {\n id: task.id,\n name: task.name,\n status: task.status.status,\n priority: task.priority?.id ? Number(task.priority.id) : null,\n due_date: task.due_date ? Number(task.due_date) : null,\n url: task.url,\n };\n}\n\nexport function slimTaskWithDesc(task: ClickUpTask) {\n return { ...slimTask(task), description: task.description ?? '' };\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, getTask, getTaskComments } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\nimport { slimTaskWithDesc } from '../utils/slim.js';\n\ntype TaskGetFlags = { json?: boolean; full?: boolean };\n\nexport default defineCommand({\n id: 'clickup:task.get',\n description: 'Get full task details including comments',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<TaskGetFlags>) {\n const [taskId] = input.argv;\n if (!taskId) {\n validationError(ctx, 'Task ID is required', 'Usage: kb clickup task get <taskId>', input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n\n try {\n const apiKey = requireApiKey();\n const [task, comments] = await Promise.all([\n getTask(apiKey, taskId),\n getTaskComments(apiKey, taskId),\n ]);\n\n if (input.flags.json) {\n ctx.ui?.json?.(input.flags.full ? { task, comments } : slimTaskWithDesc(task));\n return { ok: true, result: { task, comments } };\n }\n\n const priority = task.priority?.priority ?? '–';\n const assignees = task.assignees.map(a => a.username).join(', ') || '–';\n const due = task.due_date\n ? new Date(Number(task.due_date)).toLocaleDateString()\n : '–';\n\n const sections: Array<{ header: string; items: string[] }> = [];\n\n if (task.description) {\n sections.push({ header: 'Description', items: [task.description] });\n }\n\n if (comments.length) {\n sections.push({\n header: `Comments (${comments.length})`,\n items: comments.map(c => {\n const date = new Date(Number(c.date)).toLocaleString();\n return `[${c.user.username} @ ${date}] ${c.comment_text}`;\n }),\n });\n }\n\n ctx.ui?.sideBox?.({\n title: `[${task.id}] ${task.name}`,\n status: 'info',\n summary: {\n 'Status': task.status.status,\n 'Priority': priority,\n 'Assignees': assignees,\n 'Due': due,\n 'List': `${task.list.name} / ${task.folder.name}`,\n 'URL': task.url,\n },\n sections,\n });\n\n return { ok: true, result: { task, comments } };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n },\n },\n});\n"]}
@@ -11,6 +11,6 @@ type TaskSearchFlags = {
11
11
  json?: boolean;
12
12
  full?: boolean;
13
13
  };
14
- declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<TaskSearchFlags>, _kb_labs_clickup_contracts.ClickUpTask[] | null>;
14
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<TaskSearchFlags>, _kb_labs_clickup_contracts.ClickUpTask[]>;
15
15
 
16
16
  export { _default as default };
@@ -79,11 +79,11 @@ var task_search_default = defineCommand({
79
79
  });
80
80
  if (input.flags.json) {
81
81
  ctx.ui?.json?.(input.flags.full ? tasks : tasks.map(slimTask));
82
- return { exitCode: 0, result: tasks };
82
+ return { ok: true, result: tasks };
83
83
  }
84
84
  if (!tasks.length) {
85
85
  ctx.ui?.info?.("No tasks found.");
86
- return { exitCode: 0, result: tasks };
86
+ return { ok: true, result: tasks };
87
87
  }
88
88
  ctx.ui?.chain?.(tasks.map((task) => {
89
89
  const priority = task.priority?.priority ?? "\u2013";
@@ -98,10 +98,10 @@ var task_search_default = defineCommand({
98
98
  }]
99
99
  };
100
100
  }));
101
- return { exitCode: 0, result: tasks };
101
+ return { ok: true, result: tasks };
102
102
  } catch (err) {
103
103
  handleError(ctx, err, input.flags.json);
104
- return { exitCode: 1, result: null };
104
+ return { ok: false, error: "Command failed", result: null };
105
105
  }
106
106
  }
107
107
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/error.ts","../../src/utils/slim.ts","../../src/commands/task-search.ts"],"names":[],"mappings":"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","file":"task-search.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 type { ClickUpTask } from '@kb-labs/clickup-contracts';\n\nexport function slimTask(task: ClickUpTask) {\n return {\n id: task.id,\n name: task.name,\n status: task.status.status,\n priority: task.priority?.id ? Number(task.priority.id) : null,\n due_date: task.due_date ? Number(task.due_date) : null,\n url: task.url,\n };\n}\n\nexport function slimTaskWithDesc(task: ClickUpTask) {\n return { ...slimTask(task), description: task.description ?? '' };\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, requireTeamId, searchTasks } from '@kb-labs/clickup-core';\nimport { handleError } from '../utils/error.js';\nimport { slimTask } from '../utils/slim.js';\n\ntype TaskSearchFlags = {\n list?: string;\n status?: string;\n assignee?: string;\n limit?: number;\n closed?: boolean;\n json?: boolean;\n full?: boolean;\n};\n\nexport default defineCommand({\n id: 'clickup:task.search',\n description: 'Search tasks across the workspace',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<TaskSearchFlags>) {\n try {\n const [query] = input.argv;\n\n const tasks = await searchTasks(requireApiKey(), requireTeamId(), {\n query,\n list_ids: input.flags.list ? [input.flags.list] : undefined,\n statuses: input.flags.status ? input.flags.status.split(',') : undefined,\n assignees: input.flags.assignee ? input.flags.assignee.split(',') : undefined,\n limit: input.flags.limit ?? 20,\n include_closed: input.flags.closed,\n });\n\n if (input.flags.json) {\n ctx.ui?.json?.(input.flags.full ? tasks : tasks.map(slimTask));\n return { exitCode: 0, result: tasks };\n }\n\n if (!tasks.length) {\n ctx.ui?.info?.('No tasks found.');\n return { exitCode: 0, result: tasks };\n }\n\n ctx.ui?.chain?.(tasks.map(task => {\n const priority = task.priority?.priority ?? '–';\n const assignees = task.assignees.map(a => a.username).join(', ') || '–';\n return {\n title: `[${task.id}] ${task.name}`,\n sections: [{\n items: [\n `status: ${task.status.status} priority: ${priority} assignees: ${assignees}`,\n `list: ${task.list.name} ${task.url}`,\n ],\n }],\n };\n }));\n\n return { exitCode: 0, result: tasks };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/utils/slim.ts","../../src/commands/task-search.ts"],"names":[],"mappings":"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","file":"task-search.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 { ok: false, error: 'Command failed', 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 type { ClickUpTask } from '@kb-labs/clickup-contracts';\n\nexport function slimTask(task: ClickUpTask) {\n return {\n id: task.id,\n name: task.name,\n status: task.status.status,\n priority: task.priority?.id ? Number(task.priority.id) : null,\n due_date: task.due_date ? Number(task.due_date) : null,\n url: task.url,\n };\n}\n\nexport function slimTaskWithDesc(task: ClickUpTask) {\n return { ...slimTask(task), description: task.description ?? '' };\n}\n","import { defineCommand, type CLIInput, type PluginContextV3 } from '@kb-labs/sdk';\nimport { requireApiKey, requireTeamId, searchTasks } from '@kb-labs/clickup-core';\nimport { handleError } from '../utils/error.js';\nimport { slimTask } from '../utils/slim.js';\n\ntype TaskSearchFlags = {\n list?: string;\n status?: string;\n assignee?: string;\n limit?: number;\n closed?: boolean;\n json?: boolean;\n full?: boolean;\n};\n\nexport default defineCommand({\n id: 'clickup:task.search',\n description: 'Search tasks across the workspace',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<TaskSearchFlags>) {\n try {\n const [query] = input.argv;\n\n const tasks = await searchTasks(requireApiKey(), requireTeamId(), {\n query,\n list_ids: input.flags.list ? [input.flags.list] : undefined,\n statuses: input.flags.status ? input.flags.status.split(',') : undefined,\n assignees: input.flags.assignee ? input.flags.assignee.split(',') : undefined,\n limit: input.flags.limit ?? 20,\n include_closed: input.flags.closed,\n });\n\n if (input.flags.json) {\n ctx.ui?.json?.(input.flags.full ? tasks : tasks.map(slimTask));\n return { ok: true, result: tasks };\n }\n\n if (!tasks.length) {\n ctx.ui?.info?.('No tasks found.');\n return { ok: true, result: tasks };\n }\n\n ctx.ui?.chain?.(tasks.map(task => {\n const priority = task.priority?.priority ?? '–';\n const assignees = task.assignees.map(a => a.username).join(', ') || '–';\n return {\n title: `[${task.id}] ${task.name}`,\n sections: [{\n items: [\n `status: ${task.status.status} priority: ${priority} assignees: ${assignees}`,\n `list: ${task.list.name} ${task.url}`,\n ],\n }],\n };\n }));\n\n return { ok: true, result: tasks };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n },\n },\n});\n"]}
@@ -14,6 +14,6 @@ type TaskUpdateFlags = {
14
14
  full?: boolean;
15
15
  'dry-run'?: boolean;
16
16
  };
17
- declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<TaskUpdateFlags>, _kb_labs_clickup_contracts.ClickUpTask | null>;
17
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<TaskUpdateFlags>, _kb_labs_clickup_contracts.ClickUpTask>;
18
18
 
19
19
  export { _default as default };
@@ -79,7 +79,7 @@ var task_update_default = defineCommand({
79
79
  const [taskId] = input.argv;
80
80
  if (!taskId) {
81
81
  validationError(ctx, "Task ID is required", "Usage: kb clickup task update <taskId> [--name ...] [--status ...]", input.flags.json);
82
- return { exitCode: 1, result: null };
82
+ return { ok: false, error: "Command failed", result: null };
83
83
  }
84
84
  const { name, desc, status, priority, assignee_add, assignee_rem, due, json, full } = input.flags;
85
85
  const body = {};
@@ -110,10 +110,10 @@ var task_update_default = defineCommand({
110
110
  }]
111
111
  });
112
112
  }
113
- return { exitCode: 0, result: task };
113
+ return { ok: true, result: task };
114
114
  } catch (err) {
115
115
  handleError(ctx, err, json);
116
- return { exitCode: 1, result: null };
116
+ return { ok: false, error: "Command failed", result: null };
117
117
  }
118
118
  }
119
119
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/task-update.ts"],"names":[],"mappings":"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","file":"task-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, updateTask } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype TaskUpdateFlags = {\n name?: string;\n desc?: string;\n status?: string;\n priority?: number;\n assignee_add?: string;\n assignee_rem?: string;\n due?: string;\n json?: boolean;\n full?: boolean;\n 'dry-run'?: boolean;\n};\n\nfunction parseDue(due: string): number | null {\n if (due === 'null' || due === 'none') return null;\n const n = Number(due);\n if (!isNaN(n) && n > 0) return n;\n const d = new Date(due);\n if (!isNaN(d.getTime())) return d.getTime();\n return null;\n}\n\nexport default defineCommand({\n id: 'clickup:task.update',\n description: 'Update an existing task',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<TaskUpdateFlags>) {\n const [taskId] = input.argv;\n const skipKeys = new Set(['json', 'full', 'dry-run', 'yes', 'output']);\n const changes = Object.entries(input.flags)\n .filter(([k, v]) => !skipKeys.has(k) && v !== undefined)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`);\n return {\n summary: `Update task ${taskId ?? '(unknown)'}`,\n operations: [{\n type: 'update' as const,\n resource: 'task',\n details: { taskId, changes },\n }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<TaskUpdateFlags>) {\n const [taskId] = input.argv;\n if (!taskId) {\n validationError(ctx, 'Task ID is required', 'Usage: kb clickup task update <taskId> [--name ...] [--status ...]', input.flags.json);\n return { exitCode: 1, result: null };\n }\n\n const { name, desc, status, priority, assignee_add, assignee_rem, due, json, full } = input.flags;\n\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (desc !== undefined) body.markdown_content = desc.replace(/\\\\n/g, '\\n');\n if (status !== undefined) body.status = status;\n if (priority !== undefined) body.priority = priority;\n if (due !== undefined) body.due_date = parseDue(due);\n if (assignee_add || assignee_rem) {\n body.assignees = {\n add: assignee_add ? assignee_add.split(',').map(Number) : [],\n rem: assignee_rem ? assignee_rem.split(',').map(Number) : [],\n };\n }\n\n try {\n const task = await updateTask(requireApiKey(), taskId, body);\n\n if (json) {\n ctx.ui?.json?.(full ? task : { id: task.id, name: task.name, status: task.status.status, url: task.url });\n } else {\n ctx.ui?.success?.('Task updated', {\n sections: [{\n items: [\n `id: ${task.id}`,\n `name: ${task.name}`,\n `status: ${task.status.status}`,\n `url: ${task.url}`,\n ],\n }],\n });\n }\n\n return { exitCode: 0, result: task };\n } catch (err) {\n handleError(ctx, err, json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/task-update.ts"],"names":[],"mappings":"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","file":"task-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 { ok: false, error: 'Command failed', 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, updateTask } from '@kb-labs/clickup-core';\nimport { handleError, validationError } from '../utils/error.js';\n\ntype TaskUpdateFlags = {\n name?: string;\n desc?: string;\n status?: string;\n priority?: number;\n assignee_add?: string;\n assignee_rem?: string;\n due?: string;\n json?: boolean;\n full?: boolean;\n 'dry-run'?: boolean;\n};\n\nfunction parseDue(due: string): number | null {\n if (due === 'null' || due === 'none') return null;\n const n = Number(due);\n if (!isNaN(n) && n > 0) return n;\n const d = new Date(due);\n if (!isNaN(d.getTime())) return d.getTime();\n return null;\n}\n\nexport default defineCommand({\n id: 'clickup:task.update',\n description: 'Update an existing task',\n\n handler: {\n async intent(_ctx: PluginContextV3, input: CLIInput<TaskUpdateFlags>) {\n const [taskId] = input.argv;\n const skipKeys = new Set(['json', 'full', 'dry-run', 'yes', 'output']);\n const changes = Object.entries(input.flags)\n .filter(([k, v]) => !skipKeys.has(k) && v !== undefined)\n .map(([k, v]) => `${k}=${JSON.stringify(v)}`);\n return {\n summary: `Update task ${taskId ?? '(unknown)'}`,\n operations: [{\n type: 'update' as const,\n resource: 'task',\n details: { taskId, changes },\n }],\n };\n },\n\n async execute(ctx: PluginContextV3, input: CLIInput<TaskUpdateFlags>) {\n const [taskId] = input.argv;\n if (!taskId) {\n validationError(ctx, 'Task ID is required', 'Usage: kb clickup task update <taskId> [--name ...] [--status ...]', input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n\n const { name, desc, status, priority, assignee_add, assignee_rem, due, json, full } = input.flags;\n\n const body: Record<string, unknown> = {};\n if (name !== undefined) body.name = name;\n if (desc !== undefined) body.markdown_content = desc.replace(/\\\\n/g, '\\n');\n if (status !== undefined) body.status = status;\n if (priority !== undefined) body.priority = priority;\n if (due !== undefined) body.due_date = parseDue(due);\n if (assignee_add || assignee_rem) {\n body.assignees = {\n add: assignee_add ? assignee_add.split(',').map(Number) : [],\n rem: assignee_rem ? assignee_rem.split(',').map(Number) : [],\n };\n }\n\n try {\n const task = await updateTask(requireApiKey(), taskId, body);\n\n if (json) {\n ctx.ui?.json?.(full ? task : { id: task.id, name: task.name, status: task.status.status, url: task.url });\n } else {\n ctx.ui?.success?.('Task updated', {\n sections: [{\n items: [\n `id: ${task.id}`,\n `name: ${task.name}`,\n `status: ${task.status.status}`,\n `url: ${task.url}`,\n ],\n }],\n });\n }\n\n return { ok: true, result: task };\n } catch (err) {\n handleError(ctx, err, json);\n return { ok: false, error: 'Command failed', result: null };\n }\n },\n },\n});\n"]}
@@ -6,6 +6,6 @@ type WorkspaceFlags = {
6
6
  json?: boolean;
7
7
  full?: boolean;
8
8
  };
9
- declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<WorkspaceFlags>, ClickUpWorkspace | null>;
9
+ declare const _default: _kb_labs_shared_command_kit.CommandHandlerV3<unknown, CLIInput<WorkspaceFlags>, ClickUpWorkspace>;
10
10
 
11
11
  export { _default as default };
@@ -75,7 +75,7 @@ var workspace_default = defineCommand({
75
75
  const workspace = await getWorkspaceHierarchy(requireApiKey(), requireTeamId());
76
76
  if (input.flags.json) {
77
77
  ctx.ui?.json?.(input.flags.full ? workspace : toCompact(workspace));
78
- return { exitCode: 0, result: workspace };
78
+ return { ok: true, result: workspace };
79
79
  }
80
80
  const sections = workspace.spaces.map((space) => ({
81
81
  header: `${space.name} (space:${space.id})`,
@@ -88,10 +88,10 @@ var workspace_default = defineCommand({
88
88
  ]
89
89
  }));
90
90
  ctx.ui?.info?.(workspace.name, { sections });
91
- return { exitCode: 0, result: workspace };
91
+ return { ok: true, result: workspace };
92
92
  } catch (err) {
93
93
  handleError(ctx, err, input.flags.json);
94
- return { exitCode: 1, result: null };
94
+ return { ok: false, error: "Command failed", result: null };
95
95
  }
96
96
  }
97
97
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/workspace.ts"],"names":[],"mappings":"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","file":"workspace.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, requireTeamId, getWorkspaceHierarchy } from '@kb-labs/clickup-core';\nimport type { ClickUpWorkspace } from '@kb-labs/clickup-contracts';\nimport { handleError } from '../utils/error.js';\n\ntype WorkspaceFlags = { json?: boolean; full?: boolean };\n\nfunction toCompact(workspace: ClickUpWorkspace) {\n return {\n id: workspace.id,\n name: workspace.name,\n spaces: workspace.spaces.map(s => ({\n id: s.id,\n name: s.name,\n folders: s.folders.map(f => ({\n id: f.id,\n name: f.name,\n lists: f.lists.map(l => ({ id: l.id, name: l.name })),\n })),\n lists: s.lists.map(l => ({ id: l.id, name: l.name })),\n })),\n };\n}\n\nexport default defineCommand({\n id: 'clickup:workspace',\n description: 'Show full workspace hierarchy (spaces → folders → lists)',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<WorkspaceFlags>) {\n try {\n const workspace = await getWorkspaceHierarchy(requireApiKey(), requireTeamId());\n\n if (input.flags.json) {\n ctx.ui?.json?.(input.flags.full ? workspace : toCompact(workspace));\n return { exitCode: 0, result: workspace };\n }\n\n const sections = workspace.spaces.map(space => ({\n header: `${space.name} (space:${space.id})`,\n items: [\n ...space.folders.flatMap(folder => [\n `${folder.name} (folder:${folder.id})`,\n ...folder.lists.map(l => ` └─ ${l.name} (list:${l.id})`),\n ]),\n ...space.lists.map(l => `${l.name} (list:${l.id})`),\n ],\n }));\n ctx.ui?.info?.(workspace.name, { sections });\n\n return { exitCode: 0, result: workspace };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { exitCode: 1, result: null };\n }\n },\n },\n});\n"]}
1
+ {"version":3,"sources":["../../src/utils/error.ts","../../src/commands/workspace.ts"],"names":[],"mappings":"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","file":"workspace.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 { ok: false, error: 'Command failed', 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, requireTeamId, getWorkspaceHierarchy } from '@kb-labs/clickup-core';\nimport type { ClickUpWorkspace } from '@kb-labs/clickup-contracts';\nimport { handleError } from '../utils/error.js';\n\ntype WorkspaceFlags = { json?: boolean; full?: boolean };\n\nfunction toCompact(workspace: ClickUpWorkspace) {\n return {\n id: workspace.id,\n name: workspace.name,\n spaces: workspace.spaces.map(s => ({\n id: s.id,\n name: s.name,\n folders: s.folders.map(f => ({\n id: f.id,\n name: f.name,\n lists: f.lists.map(l => ({ id: l.id, name: l.name })),\n })),\n lists: s.lists.map(l => ({ id: l.id, name: l.name })),\n })),\n };\n}\n\nexport default defineCommand({\n id: 'clickup:workspace',\n description: 'Show full workspace hierarchy (spaces → folders → lists)',\n\n handler: {\n async execute(ctx: PluginContextV3, input: CLIInput<WorkspaceFlags>) {\n try {\n const workspace = await getWorkspaceHierarchy(requireApiKey(), requireTeamId());\n\n if (input.flags.json) {\n ctx.ui?.json?.(input.flags.full ? workspace : toCompact(workspace));\n return { ok: true, result: workspace };\n }\n\n const sections = workspace.spaces.map(space => ({\n header: `${space.name} (space:${space.id})`,\n items: [\n ...space.folders.flatMap(folder => [\n `${folder.name} (folder:${folder.id})`,\n ...folder.lists.map(l => ` └─ ${l.name} (list:${l.id})`),\n ]),\n ...space.lists.map(l => `${l.name} (list:${l.id})`),\n ],\n }));\n ctx.ui?.info?.(workspace.name, { sections });\n\n return { ok: true, result: workspace };\n } catch (err) {\n handleError(ctx, err, input.flags.json);\n return { ok: false, error: 'Command failed', result: null };\n }\n },\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/folder-create-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC3EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,EAAQ,OAAA;AAC9B,MAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,MAAM,qBAAqB,CAAA;AACnD,MAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,kBAAkB,CAAA;AACnD,MAAA,OAAO,YAAA,CAAa,aAAA,EAAc,EAAG,OAAA,EAAS,MAAM,IAAI,CAAA;AAAA,IAC1D,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"folder-create-handler.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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, createFolder } from '@kb-labs/clickup-core';\nimport type { CreateFolderInput } from '@kb-labs/clickup-contracts';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, CreateFolderInput, { spaceId: string }>,\n ) {\n try {\n const spaceId = input.params?.spaceId;\n if (!spaceId) throw new Error('spaceId is required');\n if (!input.body) throw new Error('body is required');\n return createFolder(requireApiKey(), spaceId, input.body);\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/folder-create-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC3EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,MAAM,MAAA,EAAQ,OAAA;AAC9B,MAAA,IAAI,CAAC,OAAA,EAAS,MAAM,IAAI,MAAM,qBAAqB,CAAA;AACnD,MAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,kBAAkB,CAAA;AACnD,MAAA,OAAO,YAAA,CAAa,aAAA,EAAc,EAAG,OAAA,EAAS,MAAM,IAAI,CAAA;AAAA,IAC1D,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"folder-create-handler.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 { ok: false, error: 'Command failed', 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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, createFolder } from '@kb-labs/clickup-core';\nimport type { CreateFolderInput } from '@kb-labs/clickup-contracts';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, CreateFolderInput, { spaceId: string }>,\n ) {\n try {\n const spaceId = input.params?.spaceId;\n if (!spaceId) throw new Error('spaceId is required');\n if (!input.body) throw new Error('body is required');\n return createFolder(requireApiKey(), spaceId, input.body);\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/folder-delete-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC5EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,EAAQ,QAAA;AAC/B,MAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,MAAM,sBAAsB,CAAA;AACrD,MAAA,MAAM,YAAA,CAAa,aAAA,EAAc,EAAG,QAAQ,CAAA;AAC5C,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,QAAA,EAAS;AAAA,IACnC,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"folder-delete-handler.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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, deleteFolder } from '@kb-labs/clickup-core';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, never, { folderId: string }>,\n ) {\n try {\n const folderId = input.params?.folderId;\n if (!folderId) throw new Error('folderId is required');\n await deleteFolder(requireApiKey(), folderId);\n return { deleted: true, folderId };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/folder-delete-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC5EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,EAAQ,QAAA;AAC/B,MAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,MAAM,sBAAsB,CAAA;AACrD,MAAA,MAAM,YAAA,CAAa,aAAA,EAAc,EAAG,QAAQ,CAAA;AAC5C,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,QAAA,EAAS;AAAA,IACnC,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"folder-delete-handler.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 { ok: false, error: 'Command failed', 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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, deleteFolder } from '@kb-labs/clickup-core';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, never, { folderId: string }>,\n ) {\n try {\n const folderId = input.params?.folderId;\n if (!folderId) throw new Error('folderId is required');\n await deleteFolder(requireApiKey(), folderId);\n return { deleted: true, folderId };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/folder-update-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC3EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,EAAQ,QAAA;AAC/B,MAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,MAAM,sBAAsB,CAAA;AACrD,MAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,kBAAkB,CAAA;AACnD,MAAA,OAAO,YAAA,CAAa,aAAA,EAAc,EAAG,QAAA,EAAU,MAAM,IAAI,CAAA;AAAA,IAC3D,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"folder-update-handler.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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, updateFolder } from '@kb-labs/clickup-core';\nimport type { UpdateFolderInput } from '@kb-labs/clickup-contracts';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, UpdateFolderInput, { folderId: string }>,\n ) {\n try {\n const folderId = input.params?.folderId;\n if (!folderId) throw new Error('folderId is required');\n if (!input.body) throw new Error('body is required');\n return updateFolder(requireApiKey(), folderId, input.body);\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/folder-update-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC3EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAM,MAAA,EAAQ,QAAA;AAC/B,MAAA,IAAI,CAAC,QAAA,EAAU,MAAM,IAAI,MAAM,sBAAsB,CAAA;AACrD,MAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,kBAAkB,CAAA;AACnD,MAAA,OAAO,YAAA,CAAa,aAAA,EAAc,EAAG,QAAA,EAAU,MAAM,IAAI,CAAA;AAAA,IAC3D,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"folder-update-handler.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 { ok: false, error: 'Command failed', 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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, updateFolder } from '@kb-labs/clickup-core';\nimport type { UpdateFolderInput } from '@kb-labs/clickup-contracts';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, UpdateFolderInput, { folderId: string }>,\n ) {\n try {\n const folderId = input.params?.folderId;\n if (!folderId) throw new Error('folderId is required');\n if (!input.body) throw new Error('body is required');\n return updateFolder(requireApiKey(), folderId, input.body);\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/list-create-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC3EA,IAAO,8BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAQ,GAAI,KAAA,CAAM,UAAU,EAAC;AAC/C,MAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,kBAAkB,CAAA;AACnD,MAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,MAAA,IAAI,UAAU,OAAO,kBAAA,CAAmB,MAAA,EAAQ,QAAA,EAAU,MAAM,IAAI,CAAA;AACpE,MAAA,IAAI,SAAS,OAAO,iBAAA,CAAkB,MAAA,EAAQ,OAAA,EAAS,MAAM,IAAI,CAAA;AACjE,MAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,IACnD,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"list-create-handler.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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, createListInFolder, createListInSpace } from '@kb-labs/clickup-core';\nimport type { CreateListInput } from '@kb-labs/clickup-contracts';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, CreateListInput, { folderId?: string; spaceId?: string }>,\n ) {\n try {\n const { folderId, spaceId } = input.params ?? {};\n if (!input.body) throw new Error('body is required');\n const apiKey = requireApiKey();\n if (folderId) return createListInFolder(apiKey, folderId, input.body);\n if (spaceId) return createListInSpace(apiKey, spaceId, input.body);\n throw new Error('folderId or spaceId is required');\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/list-create-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC3EA,IAAO,8BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,QAAA,EAAU,OAAA,EAAQ,GAAI,KAAA,CAAM,UAAU,EAAC;AAC/C,MAAA,IAAI,CAAC,KAAA,CAAM,IAAA,EAAM,MAAM,IAAI,MAAM,kBAAkB,CAAA;AACnD,MAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,MAAA,IAAI,UAAU,OAAO,kBAAA,CAAmB,MAAA,EAAQ,QAAA,EAAU,MAAM,IAAI,CAAA;AACpE,MAAA,IAAI,SAAS,OAAO,iBAAA,CAAkB,MAAA,EAAQ,OAAA,EAAS,MAAM,IAAI,CAAA;AACjE,MAAA,MAAM,IAAI,MAAM,iCAAiC,CAAA;AAAA,IACnD,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"list-create-handler.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 { ok: false, error: 'Command failed', 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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, createListInFolder, createListInSpace } from '@kb-labs/clickup-core';\nimport type { CreateListInput } from '@kb-labs/clickup-contracts';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, CreateListInput, { folderId?: string; spaceId?: string }>,\n ) {\n try {\n const { folderId, spaceId } = input.params ?? {};\n if (!input.body) throw new Error('body is required');\n const apiKey = requireApiKey();\n if (folderId) return createListInFolder(apiKey, folderId, input.body);\n if (spaceId) return createListInSpace(apiKey, spaceId, input.body);\n throw new Error('folderId or spaceId is required');\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/list-delete-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC5EA,IAAO,8BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,EAAQ,MAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AACjD,MAAA,MAAM,UAAA,CAAW,aAAA,EAAc,EAAG,MAAM,CAAA;AACxC,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,MAAA,EAAO;AAAA,IACjC,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"list-delete-handler.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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, deleteList } from '@kb-labs/clickup-core';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, never, { listId: string }>,\n ) {\n try {\n const listId = input.params?.listId;\n if (!listId) throw new Error('listId is required');\n await deleteList(requireApiKey(), listId);\n return { deleted: true, listId };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/list-delete-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC5EA,IAAO,8BAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,EAAQ,MAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AACjD,MAAA,MAAM,UAAA,CAAW,aAAA,EAAc,EAAG,MAAM,CAAA;AACxC,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,MAAA,EAAO;AAAA,IACjC,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"list-delete-handler.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 { ok: false, error: 'Command failed', 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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, deleteList } from '@kb-labs/clickup-core';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, never, { listId: string }>,\n ) {\n try {\n const listId = input.params?.listId;\n if (!listId) throw new Error('listId is required');\n await deleteList(requireApiKey(), listId);\n return { deleted: true, listId };\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/list-statuses-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC5EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,EAAQ,MAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAEjD,MAAA,OAAO,eAAA,CAAgB,QAAQ,MAAM,CAAA;AAAA,IACvC,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"list-statuses-handler.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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, getListStatuses } from '@kb-labs/clickup-core';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, never, { listId: string }>,\n ) {\n try {\n const apiKey = requireApiKey();\n const listId = input.params?.listId;\n if (!listId) throw new Error('listId is required');\n\n return getListStatuses(apiKey, listId);\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}
1
+ {"version":3,"sources":["../../../src/utils/error.ts","../../../src/rest/handlers/list-statuses-handler.ts"],"names":[],"mappings":";;;;AAKA,SAAS,QAAQ,GAAA,EAA8B;AAC7C,EAAA,QAAQ,IAAI,MAAA;AAAQ,IAClB,KAAK,GAAA;AAAK,MAAA,OAAO,kFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,oFAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,+FAAA;AAAA,IACjB,KAAK,GAAA;AAAK,MAAA,OAAO,2DAAA;AAAA,IACjB;AAAU,MAAA,OAAO,8BAAA;AAAA;AAErB;AA+CO,SAAS,eAAe,GAAA,EAAqB;AAClD,EAAA,IAAI,eAAe,eAAA,EAAiB;AAClC,IAAA,MAAM,IAAA,GAAO,QAAQ,GAAG,CAAA;AACxB,IAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,GAAA,CAAI,OAAO,CAAA,EAAG;AAAA,MACpD,YAAY,GAAA,CAAI,MAAA;AAAA,MAChB,MAAM,GAAA,CAAI,IAAA;AAAA,MACV,OAAA,EAAS,EAAE,IAAA;AAAK,KACjB,CAAA;AACD,IAAA,MAAM,OAAA;AAAA,EACR;AACA,EAAA,MAAM,UAAU,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG,CAAA;AAC/D,EAAA,MAAM,YAAA,GAAe,iCAAA,CAAkC,IAAA,CAAK,OAAO,CAAA;AACnE,EAAA,IAAI,YAAA,EAAc;AAChB,IAAA,MAAM,MAAA,CAAO,MAAA,CAAO,IAAI,KAAA,CAAM,OAAO,CAAA,EAAG;AAAA,MACtC,UAAA,EAAY,GAAA;AAAA,MACZ,IAAA,EAAM,aAAA;AAAA,MACN,OAAA,EAAS,EAAE,IAAA,EAAM,2FAAA;AAA4F,KAC9G,CAAA;AAAA,EACH;AACA,EAAA,MAAM,GAAA;AACR;;;AC5EA,IAAO,gCAAQ,aAAA,CAAc;AAAA,EAC3B,MAAM,OAAA,CACJ,IAAA,EACA,KAAA,EACA;AACA,IAAA,IAAI;AACF,MAAA,MAAM,SAAS,aAAA,EAAc;AAC7B,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,EAAQ,MAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,EAAQ,MAAM,IAAI,MAAM,oBAAoB,CAAA;AAEjD,MAAA,OAAO,eAAA,CAAgB,QAAQ,MAAM,CAAA;AAAA,IACvC,SAAS,GAAA,EAAK;AACZ,MAAA,cAAA,CAAe,GAAG,CAAA;AAAA,IACpB;AAAA,EACF;AACF,CAAC","file":"list-statuses-handler.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 { ok: false, error: 'Command failed', 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 { defineHandler, type PluginContextV3, type RestInput } from '@kb-labs/sdk';\nimport { requireApiKey, getListStatuses } from '@kb-labs/clickup-core';\nimport { rethrowForRest } from '../../utils/error.js';\n\nexport default defineHandler({\n async execute(\n _ctx: PluginContextV3,\n input: RestInput<Record<string, never>, never, { listId: string }>,\n ) {\n try {\n const apiKey = requireApiKey();\n const listId = input.params?.listId;\n if (!listId) throw new Error('listId is required');\n\n return getListStatuses(apiKey, listId);\n } catch (err) {\n rethrowForRest(err);\n }\n },\n});\n"]}