@novateva/teurtask-cli 0.1.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 (126) hide show
  1. package/README.md +263 -0
  2. package/dist/bin/teurtask-prod.d.ts +3 -0
  3. package/dist/bin/teurtask-prod.d.ts.map +1 -0
  4. package/dist/bin/teurtask-prod.js +6 -0
  5. package/dist/bin/teurtask-prod.js.map +1 -0
  6. package/dist/bin/teurtask.d.ts +3 -0
  7. package/dist/bin/teurtask.d.ts.map +1 -0
  8. package/dist/bin/teurtask.js +5 -0
  9. package/dist/bin/teurtask.js.map +1 -0
  10. package/dist/src/auth/index.d.ts +13 -0
  11. package/dist/src/auth/index.d.ts.map +1 -0
  12. package/dist/src/auth/index.js +44 -0
  13. package/dist/src/auth/index.js.map +1 -0
  14. package/dist/src/auth/login-server.d.ts +14 -0
  15. package/dist/src/auth/login-server.d.ts.map +1 -0
  16. package/dist/src/auth/login-server.js +84 -0
  17. package/dist/src/auth/login-server.js.map +1 -0
  18. package/dist/src/commands/auth.d.ts +3 -0
  19. package/dist/src/commands/auth.d.ts.map +1 -0
  20. package/dist/src/commands/auth.js +83 -0
  21. package/dist/src/commands/auth.js.map +1 -0
  22. package/dist/src/commands/comments.d.ts +3 -0
  23. package/dist/src/commands/comments.d.ts.map +1 -0
  24. package/dist/src/commands/comments.js +81 -0
  25. package/dist/src/commands/comments.js.map +1 -0
  26. package/dist/src/commands/documents.d.ts +3 -0
  27. package/dist/src/commands/documents.d.ts.map +1 -0
  28. package/dist/src/commands/documents.js +26 -0
  29. package/dist/src/commands/documents.js.map +1 -0
  30. package/dist/src/commands/env.d.ts +3 -0
  31. package/dist/src/commands/env.d.ts.map +1 -0
  32. package/dist/src/commands/env.js +71 -0
  33. package/dist/src/commands/env.js.map +1 -0
  34. package/dist/src/commands/goals.d.ts +3 -0
  35. package/dist/src/commands/goals.d.ts.map +1 -0
  36. package/dist/src/commands/goals.js +109 -0
  37. package/dist/src/commands/goals.js.map +1 -0
  38. package/dist/src/commands/notifications.d.ts +3 -0
  39. package/dist/src/commands/notifications.d.ts.map +1 -0
  40. package/dist/src/commands/notifications.js +77 -0
  41. package/dist/src/commands/notifications.js.map +1 -0
  42. package/dist/src/commands/phases.d.ts +3 -0
  43. package/dist/src/commands/phases.d.ts.map +1 -0
  44. package/dist/src/commands/phases.js +207 -0
  45. package/dist/src/commands/phases.js.map +1 -0
  46. package/dist/src/commands/projects.d.ts +3 -0
  47. package/dist/src/commands/projects.d.ts.map +1 -0
  48. package/dist/src/commands/projects.js +192 -0
  49. package/dist/src/commands/projects.js.map +1 -0
  50. package/dist/src/commands/schedules.d.ts +3 -0
  51. package/dist/src/commands/schedules.d.ts.map +1 -0
  52. package/dist/src/commands/schedules.js +155 -0
  53. package/dist/src/commands/schedules.js.map +1 -0
  54. package/dist/src/commands/scores.d.ts +3 -0
  55. package/dist/src/commands/scores.d.ts.map +1 -0
  56. package/dist/src/commands/scores.js +136 -0
  57. package/dist/src/commands/scores.js.map +1 -0
  58. package/dist/src/commands/sprints.d.ts +3 -0
  59. package/dist/src/commands/sprints.d.ts.map +1 -0
  60. package/dist/src/commands/sprints.js +218 -0
  61. package/dist/src/commands/sprints.js.map +1 -0
  62. package/dist/src/commands/tags.d.ts +3 -0
  63. package/dist/src/commands/tags.d.ts.map +1 -0
  64. package/dist/src/commands/tags.js +99 -0
  65. package/dist/src/commands/tags.js.map +1 -0
  66. package/dist/src/commands/tasks.d.ts +3 -0
  67. package/dist/src/commands/tasks.d.ts.map +1 -0
  68. package/dist/src/commands/tasks.js +355 -0
  69. package/dist/src/commands/tasks.js.map +1 -0
  70. package/dist/src/commands/users.d.ts +3 -0
  71. package/dist/src/commands/users.d.ts.map +1 -0
  72. package/dist/src/commands/users.js +172 -0
  73. package/dist/src/commands/users.js.map +1 -0
  74. package/dist/src/config/environments.d.ts +3 -0
  75. package/dist/src/config/environments.d.ts.map +1 -0
  76. package/dist/src/config/environments.js +18 -0
  77. package/dist/src/config/environments.js.map +1 -0
  78. package/dist/src/config/index.d.ts +7 -0
  79. package/dist/src/config/index.d.ts.map +1 -0
  80. package/dist/src/config/index.js +67 -0
  81. package/dist/src/config/index.js.map +1 -0
  82. package/dist/src/config/paths.d.ts +6 -0
  83. package/dist/src/config/paths.d.ts.map +1 -0
  84. package/dist/src/config/paths.js +9 -0
  85. package/dist/src/config/paths.js.map +1 -0
  86. package/dist/src/http/client.d.ts +8 -0
  87. package/dist/src/http/client.d.ts.map +1 -0
  88. package/dist/src/http/client.js +68 -0
  89. package/dist/src/http/client.js.map +1 -0
  90. package/dist/src/http/errors.d.ts +7 -0
  91. package/dist/src/http/errors.d.ts.map +1 -0
  92. package/dist/src/http/errors.js +34 -0
  93. package/dist/src/http/errors.js.map +1 -0
  94. package/dist/src/index.d.ts +3 -0
  95. package/dist/src/index.d.ts.map +1 -0
  96. package/dist/src/index.js +76 -0
  97. package/dist/src/index.js.map +1 -0
  98. package/dist/src/output/formatter.d.ts +10 -0
  99. package/dist/src/output/formatter.d.ts.map +1 -0
  100. package/dist/src/output/formatter.js +57 -0
  101. package/dist/src/output/formatter.js.map +1 -0
  102. package/dist/src/output/json.d.ts +6 -0
  103. package/dist/src/output/json.d.ts.map +1 -0
  104. package/dist/src/output/json.js +16 -0
  105. package/dist/src/output/json.js.map +1 -0
  106. package/dist/src/output/table.d.ts +9 -0
  107. package/dist/src/output/table.d.ts.map +1 -0
  108. package/dist/src/output/table.js +32 -0
  109. package/dist/src/output/table.js.map +1 -0
  110. package/dist/src/types/api.d.ts +172 -0
  111. package/dist/src/types/api.d.ts.map +1 -0
  112. package/dist/src/types/api.js +2 -0
  113. package/dist/src/types/api.js.map +1 -0
  114. package/dist/src/types/common.d.ts +18 -0
  115. package/dist/src/types/common.d.ts.map +1 -0
  116. package/dist/src/types/common.js +2 -0
  117. package/dist/src/types/common.js.map +1 -0
  118. package/dist/src/types/config.d.ts +22 -0
  119. package/dist/src/types/config.d.ts.map +1 -0
  120. package/dist/src/types/config.js +2 -0
  121. package/dist/src/types/config.js.map +1 -0
  122. package/dist/src/utils/spinner.d.ts +6 -0
  123. package/dist/src/utils/spinner.d.ts.map +1 -0
  124. package/dist/src/utils/spinner.js +35 -0
  125. package/dist/src/utils/spinner.js.map +1 -0
  126. package/package.json +32 -0
@@ -0,0 +1,67 @@
1
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'node:fs';
2
+ import { paths } from './paths.js';
3
+ import { defaultEnvironments } from './environments.js';
4
+ function ensureDir() {
5
+ if (!existsSync(paths.dir)) {
6
+ mkdirSync(paths.dir, { recursive: true });
7
+ }
8
+ }
9
+ function defaultConfig() {
10
+ return {
11
+ activeEnv: 'local',
12
+ environments: defaultEnvironments,
13
+ };
14
+ }
15
+ export function loadConfig() {
16
+ ensureDir();
17
+ if (!existsSync(paths.config)) {
18
+ const config = defaultConfig();
19
+ saveConfig(config);
20
+ return config;
21
+ }
22
+ const raw = readFileSync(paths.config, 'utf-8');
23
+ return JSON.parse(raw);
24
+ }
25
+ export function saveConfig(config) {
26
+ ensureDir();
27
+ writeFileSync(paths.config, JSON.stringify(config, null, 2), 'utf-8');
28
+ }
29
+ export function getActiveEnv() {
30
+ const lockedName = process.env.TEURTASK_LOCKED_ENV;
31
+ if (lockedName) {
32
+ const env = defaultEnvironments.find((e) => e.name === lockedName);
33
+ if (env) {
34
+ return env;
35
+ }
36
+ throw new Error(`Locked environment "${lockedName}" not found in defaults`);
37
+ }
38
+ const config = loadConfig();
39
+ const env = config.environments.find((e) => e.name === config.activeEnv);
40
+ if (!env) {
41
+ throw new Error(`Environment "${config.activeEnv}" not found. Run: teurtask env list`);
42
+ }
43
+ return env;
44
+ }
45
+ export function setActiveEnv(name) {
46
+ const config = loadConfig();
47
+ const env = config.environments.find((e) => e.name === name);
48
+ if (!env) {
49
+ const names = config.environments.map((e) => e.name).join(', ');
50
+ throw new Error(`Environment "${name}" not found. Available: ${names}`);
51
+ }
52
+ config.activeEnv = name;
53
+ saveConfig(config);
54
+ return env;
55
+ }
56
+ export function addEnvironment(env) {
57
+ const config = loadConfig();
58
+ const existing = config.environments.findIndex((e) => e.name === env.name);
59
+ if (existing >= 0) {
60
+ config.environments[existing] = env;
61
+ }
62
+ else {
63
+ config.environments.push(env);
64
+ }
65
+ saveConfig(config);
66
+ }
67
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/config/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ export declare const paths: {
2
+ dir: string;
3
+ config: string;
4
+ auth: string;
5
+ };
6
+ //# sourceMappingURL=paths.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../../src/config/paths.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,KAAK;;;;CAIjB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { join } from 'node:path';
2
+ import { homedir } from 'node:os';
3
+ const TEURTASK_DIR = join(homedir(), '.teurtask');
4
+ export const paths = {
5
+ dir: TEURTASK_DIR,
6
+ config: join(TEURTASK_DIR, 'config.json'),
7
+ auth: join(TEURTASK_DIR, 'auth.json'),
8
+ };
9
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../../../src/config/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAElC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAElD,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,GAAG,EAAE,YAAY;IACjB,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC;IACzC,IAAI,EAAE,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC;CACtC,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { type AxiosInstance, type AxiosRequestConfig } from 'axios';
2
+ export declare function getClient(envOverride?: string): AxiosInstance;
3
+ export declare function resetClient(): void;
4
+ export declare function apiGet<T = unknown>(url: string, params?: Record<string, unknown>): Promise<T>;
5
+ export declare function apiPost<T = unknown>(url: string, data?: unknown, config?: AxiosRequestConfig): Promise<T>;
6
+ export declare function apiPut<T = unknown>(url: string, data?: unknown): Promise<T>;
7
+ export declare function apiDelete<T = unknown>(url: string): Promise<T>;
8
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../../src/http/client.ts"],"names":[],"mappings":"AAAA,OAAc,EAAE,KAAK,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,OAAO,CAAC;AAM3E,wBAAgB,SAAS,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,CA4D7D;AAED,wBAAgB,WAAW,IAAI,IAAI,CAElC;AAED,wBAAsB,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAGnG;AAED,wBAAsB,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,kBAAkB,GAAG,OAAO,CAAC,CAAC,CAAC,CAG/G;AAED,wBAAsB,MAAM,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,CAGjF;AAED,wBAAsB,SAAS,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAGpE"}
@@ -0,0 +1,68 @@
1
+ import axios from 'axios';
2
+ import { getActiveEnv } from '../config/index.js';
3
+ import { getToken, updateToken, clearAuth } from '../auth/index.js';
4
+ let clientInstance = null;
5
+ export function getClient(envOverride) {
6
+ if (clientInstance)
7
+ return clientInstance;
8
+ const env = getActiveEnv();
9
+ const baseURL = env.apiBaseUrl;
10
+ const instance = axios.create({
11
+ baseURL,
12
+ timeout: 30000,
13
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
14
+ });
15
+ // Request interceptor: inject Bearer token
16
+ instance.interceptors.request.use((config) => {
17
+ const token = getToken(envOverride);
18
+ if (token) {
19
+ config.headers.Authorization = `Bearer ${token}`;
20
+ }
21
+ return config;
22
+ });
23
+ // Response interceptor: handle 401 -> refresh -> retry
24
+ instance.interceptors.response.use((response) => response, async (error) => {
25
+ const originalRequest = error.config;
26
+ if (error.response?.status === 401 &&
27
+ !originalRequest._retry &&
28
+ !originalRequest.url?.includes('/auth/refresh')) {
29
+ originalRequest._retry = true;
30
+ try {
31
+ const token = getToken(envOverride);
32
+ const refreshResponse = await axios.post(`${baseURL}/auth/refresh`, {}, { headers: { Authorization: `Bearer ${token}` } });
33
+ const newToken = refreshResponse.data.access_token;
34
+ updateToken(newToken, envOverride);
35
+ originalRequest.headers.Authorization = `Bearer ${newToken}`;
36
+ return instance(originalRequest);
37
+ }
38
+ catch {
39
+ clearAuth(envOverride);
40
+ console.error('Session expired. Please run: teurtask auth login');
41
+ process.exit(2);
42
+ }
43
+ }
44
+ return Promise.reject(error);
45
+ });
46
+ clientInstance = instance;
47
+ return instance;
48
+ }
49
+ export function resetClient() {
50
+ clientInstance = null;
51
+ }
52
+ export async function apiGet(url, params) {
53
+ const res = await getClient().get(url, { params });
54
+ return res.data;
55
+ }
56
+ export async function apiPost(url, data, config) {
57
+ const res = await getClient().post(url, data, config);
58
+ return res.data;
59
+ }
60
+ export async function apiPut(url, data) {
61
+ const res = await getClient().put(url, data);
62
+ return res.data;
63
+ }
64
+ export async function apiDelete(url) {
65
+ const res = await getClient().delete(url);
66
+ return res.data;
67
+ }
68
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../../../src/http/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export interface ApiError {
2
+ message: string;
3
+ status?: number;
4
+ errors?: Record<string, string[]>;
5
+ }
6
+ export declare function formatApiError(err: unknown): ApiError;
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/http/errors.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;CACnC;AAED,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,QAAQ,CAqCrD"}
@@ -0,0 +1,34 @@
1
+ export function formatApiError(err) {
2
+ if (isAxiosError(err)) {
3
+ const status = err.response?.status;
4
+ const data = err.response?.data;
5
+ if (status === 401) {
6
+ return { message: 'Authentication failed. Please run: teurtask auth login', status };
7
+ }
8
+ if (status === 403) {
9
+ return { message: 'Permission denied.', status };
10
+ }
11
+ if (status === 404) {
12
+ return { message: 'Resource not found.', status };
13
+ }
14
+ if (status === 422 && data?.errors) {
15
+ return {
16
+ message: data.message ?? 'Validation error',
17
+ status,
18
+ errors: data.errors,
19
+ };
20
+ }
21
+ if (data?.message) {
22
+ return { message: data.message, status };
23
+ }
24
+ return { message: err.message, status };
25
+ }
26
+ if (err instanceof Error) {
27
+ return { message: err.message };
28
+ }
29
+ return { message: String(err) };
30
+ }
31
+ function isAxiosError(err) {
32
+ return typeof err === 'object' && err !== null && 'isAxiosError' in err;
33
+ }
34
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/http/errors.ts"],"names":[],"mappings":"AAQA,MAAM,UAAU,cAAc,CAAC,GAAY;IACzC,IAAI,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;QACtB,MAAM,MAAM,GAAG,GAAG,CAAC,QAAQ,EAAE,MAAM,CAAC;QACpC,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,EAAE,IAA2C,CAAC;QAEvE,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,EAAE,OAAO,EAAE,wDAAwD,EAAE,MAAM,EAAE,CAAC;QACvF,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,EAAE,OAAO,EAAE,oBAAoB,EAAE,MAAM,EAAE,CAAC;QACnD,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;YACnB,OAAO,EAAE,OAAO,EAAE,qBAAqB,EAAE,MAAM,EAAE,CAAC;QACpD,CAAC;QAED,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,MAAM,EAAE,CAAC;YACnC,OAAO;gBACL,OAAO,EAAG,IAAI,CAAC,OAAkB,IAAI,kBAAkB;gBACvD,MAAM;gBACN,MAAM,EAAE,IAAI,CAAC,MAAkC;aAChD,CAAC;QACJ,CAAC;QAED,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC;YAClB,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,OAAiB,EAAE,MAAM,EAAE,CAAC;QACrD,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAC1C,CAAC;IAED,IAAI,GAAG,YAAY,KAAK,EAAE,CAAC;QACzB,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,CAAC;IAClC,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;AAClC,CAAC;AAED,SAAS,YAAY,CAAC,GAAY;IAChC,OAAO,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,IAAI,cAAc,IAAI,GAAG,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from 'commander';
2
+ export declare function createProgram(): Command;
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBpC,wBAAgB,aAAa,IAAI,OAAO,CAiEvC"}
@@ -0,0 +1,76 @@
1
+ import { Command } from 'commander';
2
+ import { registerEnvCommands } from './commands/env.js';
3
+ import { registerAuthCommands } from './commands/auth.js';
4
+ import { registerProjectCommands } from './commands/projects.js';
5
+ import { registerTaskCommands } from './commands/tasks.js';
6
+ import { registerSprintCommands } from './commands/sprints.js';
7
+ import { registerUserCommands } from './commands/users.js';
8
+ import { registerCommentCommands } from './commands/comments.js';
9
+ import { registerPhaseCommands } from './commands/phases.js';
10
+ import { registerNotificationCommands } from './commands/notifications.js';
11
+ import { registerScheduleCommands } from './commands/schedules.js';
12
+ import { registerGoalCommands } from './commands/goals.js';
13
+ import { registerTagCommands } from './commands/tags.js';
14
+ import { registerScoreCommands } from './commands/scores.js';
15
+ import { registerDocumentCommands } from './commands/documents.js';
16
+ export function createProgram() {
17
+ const locked = process.env.TEURTASK_LOCKED_ENV ?? null;
18
+ const program = new Command();
19
+ program
20
+ .name('teurtask')
21
+ .description('CLI for teurtask project management')
22
+ .version('0.1.0')
23
+ .option('--json', 'Output in JSON format')
24
+ .option('--verbose', 'Enable verbose output')
25
+ .addHelpText('after', `
26
+ Common Workflows:
27
+
28
+ Create a project and phase:
29
+ teurtask project create --name "My Project" --description "..."
30
+ teurtask phase create --name "Phase 1" --start-date 2026-03-01 --end-date 2026-05-30 \\
31
+ --project-id 3 --users "1:40,2:80" --responsible-ids "1"
32
+
33
+ List tasks:
34
+ teurtask task list --project-id 3
35
+ teurtask task list --sprint-id 7
36
+ teurtask task list --project-id 3 --start-date 2026-01-01 --end-date 2026-03-31
37
+ teurtask project backlog 3 --phase-ids "5,6" (filter by phase)
38
+
39
+ Create and edit a task:
40
+ teurtask task create --title "Fix bug" --state To_Do --sprint-id 7 --project-id 3
41
+ teurtask task update 42 --state Doing --priority high
42
+
43
+ Move a task:
44
+ teurtask task destinations --project-id 3 (list available sprints)
45
+ teurtask task move 42 --to-sprint 7
46
+ teurtask task move 42 --to-backlog
47
+
48
+ Add users to a phase:
49
+ teurtask phase update 5 --users "1:40,2:80" --responsible-ids "1"
50
+ teurtask sprint update 12 --user-ids "1,2,3" (add users to a sprint)
51
+
52
+ Track time:
53
+ teurtask task track 42 (toggle start/stop)
54
+ teurtask task active (show currently tracked tasks)
55
+
56
+ Append --json to any command for machine-readable output.`);
57
+ if (!locked) {
58
+ program.option('--env <name>', 'Override active environment');
59
+ registerEnvCommands(program);
60
+ }
61
+ registerAuthCommands(program);
62
+ registerProjectCommands(program);
63
+ registerTaskCommands(program);
64
+ registerSprintCommands(program);
65
+ registerUserCommands(program);
66
+ registerCommentCommands(program);
67
+ registerPhaseCommands(program);
68
+ registerNotificationCommands(program);
69
+ registerScheduleCommands(program);
70
+ registerGoalCommands(program);
71
+ registerTagCommands(program);
72
+ registerScoreCommands(program);
73
+ registerDocumentCommands(program);
74
+ return program;
75
+ }
76
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,4BAA4B,EAAE,MAAM,6BAA6B,CAAC;AAC3E,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,MAAM,UAAU,aAAa;IAC3B,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,IAAI,CAAC;IACvD,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,UAAU,CAAC;SAChB,WAAW,CAAC,qCAAqC,CAAC;SAClD,OAAO,CAAC,OAAO,CAAC;SAChB,MAAM,CAAC,QAAQ,EAAE,uBAAuB,CAAC;SACzC,MAAM,CAAC,WAAW,EAAE,uBAAuB,CAAC;SAC5C,WAAW,CACV,OAAO,EACP;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0DA+BoD,CACrD,CAAC;IAEJ,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,6BAA6B,CAAC,CAAC;QAC9D,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IACD,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,sBAAsB,CAAC,OAAO,CAAC,CAAC;IAChC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,uBAAuB,CAAC,OAAO,CAAC,CAAC;IACjC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,4BAA4B,CAAC,OAAO,CAAC,CAAC;IACtC,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAClC,oBAAoB,CAAC,OAAO,CAAC,CAAC;IAC9B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC7B,qBAAqB,CAAC,OAAO,CAAC,CAAC;IAC/B,wBAAwB,CAAC,OAAO,CAAC,CAAC;IAElC,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,10 @@
1
+ import { type Column } from './table.js';
2
+ export interface CommandContext {
3
+ json: boolean;
4
+ }
5
+ export declare function getContext(opts: Record<string, unknown>): CommandContext;
6
+ export declare function outputList(ctx: CommandContext, rows: Record<string, unknown>[], columns: Column[]): void;
7
+ export declare function outputDetail(ctx: CommandContext, data: Record<string, unknown>, labels?: Record<string, string>): void;
8
+ export declare function outputSuccess(ctx: CommandContext, message: string, data?: unknown): void;
9
+ export declare function outputError(ctx: CommandContext, err: unknown): void;
10
+ //# sourceMappingURL=formatter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.d.ts","sourceRoot":"","sources":["../../../src/output/formatter.ts"],"names":[],"mappings":"AACA,OAAO,EAA+B,KAAK,MAAM,EAAE,MAAM,YAAY,CAAC;AAItE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,cAAc,CAExE;AAED,wBAAgB,UAAU,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAWxG;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAMtH;AAED,wBAAgB,aAAa,CAAC,GAAG,EAAE,cAAc,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,IAAI,CAMxF;AAED,wBAAgB,WAAW,CAAC,GAAG,EAAE,cAAc,EAAE,GAAG,EAAE,OAAO,GAAG,IAAI,CAiBnE"}
@@ -0,0 +1,57 @@
1
+ import { printJson, printJsonError } from './json.js';
2
+ import { renderTable, renderKeyValue } from './table.js';
3
+ import { formatApiError } from '../http/errors.js';
4
+ import chalk from 'chalk';
5
+ export function getContext(opts) {
6
+ return { json: Boolean(opts.json) };
7
+ }
8
+ export function outputList(ctx, rows, columns) {
9
+ if (ctx.json) {
10
+ printJson(rows, rows.length);
11
+ }
12
+ else {
13
+ if (rows.length === 0) {
14
+ console.log(chalk.yellow('No results found.'));
15
+ }
16
+ else {
17
+ renderTable(rows, columns);
18
+ console.log(chalk.dim(`${rows.length} result(s)`));
19
+ }
20
+ }
21
+ }
22
+ export function outputDetail(ctx, data, labels) {
23
+ if (ctx.json) {
24
+ printJson(data);
25
+ }
26
+ else {
27
+ renderKeyValue(data, labels);
28
+ }
29
+ }
30
+ export function outputSuccess(ctx, message, data) {
31
+ if (ctx.json) {
32
+ printJson(data ?? { message });
33
+ }
34
+ else {
35
+ console.log(chalk.green(`✓ ${message}`));
36
+ }
37
+ }
38
+ export function outputError(ctx, err) {
39
+ const apiErr = formatApiError(err);
40
+ if (ctx.json) {
41
+ printJsonError(apiErr.message);
42
+ }
43
+ else {
44
+ console.error(chalk.red(`Error: ${apiErr.message}`));
45
+ if (apiErr.errors) {
46
+ for (const [field, messages] of Object.entries(apiErr.errors)) {
47
+ for (const msg of messages) {
48
+ console.error(chalk.red(` ${field}: ${msg}`));
49
+ }
50
+ }
51
+ }
52
+ }
53
+ if (apiErr.status === 401)
54
+ process.exit(2);
55
+ process.exit(1);
56
+ }
57
+ //# sourceMappingURL=formatter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"formatter.js","sourceRoot":"","sources":["../../../src/output/formatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAe,MAAM,YAAY,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,MAAM,UAAU,UAAU,CAAC,IAA6B;IACtD,OAAO,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,GAAmB,EAAE,IAA+B,EAAE,OAAiB;IAChG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACjD,CAAC;aAAM,CAAC;YACN,WAAW,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC;QACrD,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,GAAmB,EAAE,IAA6B,EAAE,MAA+B;IAC9G,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,SAAS,CAAC,IAAI,CAAC,CAAC;IAClB,CAAC;SAAM,CAAC;QACN,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC/B,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,GAAmB,EAAE,OAAe,EAAE,IAAc;IAChF,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,SAAS,CAAC,IAAI,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,GAAmB,EAAE,GAAY;IAC3D,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,CAAC;IACnC,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;QACb,cAAc,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,UAAU,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACrD,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAClB,KAAK,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC9D,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;oBAC3B,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;gBACjD,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,KAAK,GAAG;QAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC3C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { JsonEnvelope } from '../types/common.js';
2
+ export declare function jsonSuccess<T>(data: T, count?: number): JsonEnvelope<T>;
3
+ export declare function jsonError(error: string): JsonEnvelope<null>;
4
+ export declare function printJson<T>(data: T, count?: number): void;
5
+ export declare function printJsonError(error: string): void;
6
+ //# sourceMappingURL=json.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.d.ts","sourceRoot":"","sources":["../../../src/output/json.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,wBAAgB,WAAW,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,YAAY,CAAC,CAAC,CAAC,CAIvE;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAE3D;AAED,wBAAgB,SAAS,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAE1D;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAElD"}
@@ -0,0 +1,16 @@
1
+ export function jsonSuccess(data, count) {
2
+ const envelope = { success: true, data };
3
+ if (count !== undefined)
4
+ envelope.count = count;
5
+ return envelope;
6
+ }
7
+ export function jsonError(error) {
8
+ return { success: false, data: null, error };
9
+ }
10
+ export function printJson(data, count) {
11
+ console.log(JSON.stringify(jsonSuccess(data, count), null, 2));
12
+ }
13
+ export function printJsonError(error) {
14
+ console.error(JSON.stringify(jsonError(error), null, 2));
15
+ }
16
+ //# sourceMappingURL=json.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"json.js","sourceRoot":"","sources":["../../../src/output/json.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,WAAW,CAAI,IAAO,EAAE,KAAc;IACpD,MAAM,QAAQ,GAAoB,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC1D,IAAI,KAAK,KAAK,SAAS;QAAE,QAAQ,CAAC,KAAK,GAAG,KAAK,CAAC;IAChD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,SAAS,CAAI,IAAO,EAAE,KAAc;IAClD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa;IAC1C,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC3D,CAAC"}
@@ -0,0 +1,9 @@
1
+ export interface Column {
2
+ key: string;
3
+ header: string;
4
+ width?: number;
5
+ formatter?: (value: unknown, row: Record<string, unknown>) => string;
6
+ }
7
+ export declare function renderTable(rows: Record<string, unknown>[], columns: Column[]): void;
8
+ export declare function renderKeyValue(data: Record<string, unknown>, labels?: Record<string, string>): void;
9
+ //# sourceMappingURL=table.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.d.ts","sourceRoot":"","sources":["../../../src/output/table.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,MAAM,CAAC;CACtE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,IAAI,CAoBpF;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAWnG"}
@@ -0,0 +1,32 @@
1
+ import Table from 'cli-table3';
2
+ export function renderTable(rows, columns) {
3
+ const table = new Table({
4
+ head: columns.map((c) => c.header),
5
+ colWidths: columns.map((c) => c.width ?? null),
6
+ wordWrap: true,
7
+ style: { head: ['cyan'] },
8
+ });
9
+ for (const row of rows) {
10
+ table.push(columns.map((col) => {
11
+ const value = row[col.key];
12
+ if (col.formatter)
13
+ return col.formatter(value, row);
14
+ if (value === null || value === undefined)
15
+ return '';
16
+ return String(value);
17
+ }));
18
+ }
19
+ console.log(table.toString());
20
+ }
21
+ export function renderKeyValue(data, labels) {
22
+ const table = new Table({ style: { head: ['cyan'] } });
23
+ for (const [key, value] of Object.entries(data)) {
24
+ if (value === undefined)
25
+ continue;
26
+ const label = labels?.[key] ?? key;
27
+ const display = value === null ? '' : typeof value === 'object' ? JSON.stringify(value) : String(value);
28
+ table.push({ [label]: display });
29
+ }
30
+ console.log(table.toString());
31
+ }
32
+ //# sourceMappingURL=table.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"table.js","sourceRoot":"","sources":["../../../src/output/table.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,YAAY,CAAC;AAS/B,MAAM,UAAU,WAAW,CAAC,IAA+B,EAAE,OAAiB;IAC5E,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC;QAClC,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC;QAC9C,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE;KAC1B,CAAC,CAAC;IAEH,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,KAAK,CAAC,IAAI,CACR,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;YAClB,MAAM,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAC3B,IAAI,GAAG,CAAC,SAAS;gBAAE,OAAO,GAAG,CAAC,SAAS,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YACpD,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO,EAAE,CAAC;YACrD,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC;QACvB,CAAC,CAAC,CACH,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAA6B,EAAE,MAA+B;IAC3F,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,EAAE,KAAK,EAAE,EAAE,IAAI,EAAE,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAEvD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;QAChD,IAAI,KAAK,KAAK,SAAS;YAAE,SAAS;QAClC,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC;QACnC,MAAM,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACxG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,OAAO,EAAE,CAAC,CAAC;IACnC,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;AAChC,CAAC"}