@uipath/tasks-tool 1.202.0-preview.140 → 1.202.0-preview.142

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 (41) hide show
  1. package/dist/index.js +1 -1
  2. package/dist/{tool-4er8cbf1.js → tool-315h4wtj.js} +5 -2
  3. package/dist/tool.js +1 -1
  4. package/package.json +5 -2
  5. package/browser.json +0 -4
  6. package/src/commands/_shared/catalog-options.spec.ts +0 -114
  7. package/src/commands/_shared/catalog-options.ts +0 -122
  8. package/src/commands/_shared/connect.spec.ts +0 -52
  9. package/src/commands/_shared/connect.ts +0 -31
  10. package/src/commands/_shared/constants.ts +0 -1
  11. package/src/commands/_shared/folder-picker-interactive.spec.ts +0 -92
  12. package/src/commands/_shared/folder-picker-interactive.ts +0 -76
  13. package/src/commands/_shared/folder-picker.spec.ts +0 -159
  14. package/src/commands/_shared/folder-picker.ts +0 -113
  15. package/src/commands/_shared/folder-resolver.spec.ts +0 -152
  16. package/src/commands/_shared/folder-resolver.ts +0 -113
  17. package/src/commands/_shared/parse.spec.ts +0 -69
  18. package/src/commands/_shared/parse.ts +0 -43
  19. package/src/commands/catalogs.ts +0 -281
  20. package/src/commands/comments.ts +0 -160
  21. package/src/commands/data.ts +0 -137
  22. package/src/commands/labels.ts +0 -93
  23. package/src/commands/metadata.ts +0 -139
  24. package/src/commands/tasks.spec.ts +0 -2449
  25. package/src/commands/tasks.ts +0 -631
  26. package/src/index.ts +0 -12
  27. package/src/tool.ts +0 -24
  28. package/src/utils/sdk-client.ts +0 -30
  29. package/tests/assign.e2e.test.ts +0 -166
  30. package/tests/assignable-users.e2e.test.ts +0 -167
  31. package/tests/catalogs.e2e.test.ts +0 -418
  32. package/tests/comments.e2e.test.ts +0 -223
  33. package/tests/complete.e2e.test.ts +0 -207
  34. package/tests/data.e2e.test.ts +0 -187
  35. package/tests/get.e2e.test.ts +0 -103
  36. package/tests/labels.e2e.test.ts +0 -184
  37. package/tests/list.e2e.test.ts +0 -234
  38. package/tests/metadata.e2e.test.ts +0 -186
  39. package/tests/performance.e2e.test.ts +0 -32
  40. package/tsconfig.json +0 -9
  41. package/vitest.config.ts +0 -1
@@ -1,418 +0,0 @@
1
- import { RESULTS } from "@uipath/common";
2
- import { describe, expect, it } from "vitest";
3
- import {
4
- type E2EManifest,
5
- MANIFEST_PATH,
6
- } from "../../../tests/e2e-shared/global-setup";
7
- import {
8
- EXEC_TIMEOUT,
9
- localCliRaw,
10
- localCliRawWithArgs,
11
- parseOutput,
12
- readManifest,
13
- } from "../../../tests/e2e-shared/helpers";
14
-
15
- interface Envelope {
16
- Result: string;
17
- Code?: string;
18
- Data?: unknown;
19
- Message?: string;
20
- Instructions?: string;
21
- ErrorCode?: string;
22
- Retry?: string;
23
- Context?: { httpStatus?: number };
24
- }
25
-
26
- interface Catalog {
27
- Id?: number;
28
- Name?: string;
29
- Encrypted?: boolean;
30
- RetentionAction?: string;
31
- RetentionPeriod?: number;
32
- }
33
-
34
- interface TaskRow {
35
- IsDeleted?: boolean;
36
- Status?: string;
37
- FolderId?: number;
38
- }
39
-
40
- const { tempDir } = readManifest<E2EManifest>(MANIFEST_PATH).sharedInstall;
41
-
42
- function listTasks(asAdmin: boolean): TaskRow[] {
43
- const flag = asAdmin ? "--as-admin " : "";
44
- const raw = localCliRaw(
45
- tempDir,
46
- `tasks list ${flag}--limit 200 --output json`,
47
- );
48
- if (raw.exitCode !== 0) return [];
49
- return (parseOutput(raw.stdout, "json") as { Data?: TaskRow[] }).Data ?? [];
50
- }
51
-
52
- function discoverFolderId(): string {
53
- if (process.env.TASKS_TOOL_E2E_FOLDER_ID) {
54
- return process.env.TASKS_TOOL_E2E_FOLDER_ID;
55
- }
56
- for (const asAdmin of [false, true]) {
57
- const task = listTasks(asAdmin).find(
58
- (t) => !t.IsDeleted && typeof t.FolderId === "number",
59
- );
60
- if (typeof task?.FolderId === "number") {
61
- return String(task.FolderId);
62
- }
63
- }
64
- throw new Error(
65
- "No live task found to derive a folder for catalogs e2e. Set TASKS_TOOL_E2E_FOLDER_ID or seed a task.",
66
- );
67
- }
68
-
69
- const folderId = discoverFolderId();
70
- let createdCatalogId: number | undefined;
71
-
72
- function createCatalog(name: string, extra: string[] = []): Envelope {
73
- const raw = localCliRawWithArgs(tempDir, [
74
- "tasks",
75
- "catalogs",
76
- "create",
77
- "--folder-id",
78
- folderId,
79
- "--name",
80
- name,
81
- ...extra,
82
- "--output",
83
- "json",
84
- ]);
85
- return parseOutput(raw.stdout, "json") as Envelope;
86
- }
87
-
88
- function getCatalog(id: number): Envelope {
89
- const raw = localCliRaw(
90
- tempDir,
91
- `tasks catalogs get ${id} --folder-id ${folderId} --output json`,
92
- );
93
- return parseOutput(raw.stdout, "json") as Envelope;
94
- }
95
-
96
- /**
97
- * A failure envelope built by `classifiedFailure()` carries the backend status
98
- * through, so the error code comes from that status instead of falling back to
99
- * the `unknown_error` default. The code is only asserted when the failure
100
- * actually had an HTTP status — a network blip on the way to the tenant has
101
- * none, and that is not what these scenarios pin.
102
- */
103
- function expectClassified(res: Envelope): void {
104
- expect(res.Retry).toBeDefined();
105
- if (res.Context?.httpStatus !== undefined) {
106
- expect(res.ErrorCode).not.toBe("unknown_error");
107
- }
108
- }
109
-
110
- describe("tasks catalogs e2e", () => {
111
- it(
112
- "S1: list catalogs in a folder",
113
- () => {
114
- const raw = localCliRaw(
115
- tempDir,
116
- `tasks catalogs list --folder-id ${folderId} --output json`,
117
- );
118
- const res = parseOutput(raw.stdout, "json") as Envelope;
119
- expect(raw.exitCode, JSON.stringify(res)).toBe(0);
120
- expect(res.Result).toBe(RESULTS.Success);
121
- expect(res.Code).toBe("TaskCatalogList");
122
- expect(Array.isArray(res.Data)).toBe(true);
123
- },
124
- EXEC_TIMEOUT,
125
- );
126
-
127
- it(
128
- "S2: list caps results with --limit",
129
- () => {
130
- const raw = localCliRaw(
131
- tempDir,
132
- `tasks catalogs list --folder-id ${folderId} --limit 1 --output json`,
133
- );
134
- const res = parseOutput(raw.stdout, "json") as Envelope;
135
- expect(raw.exitCode, JSON.stringify(res)).toBe(0);
136
- expect(res.Code).toBe("TaskCatalogList");
137
- expect((res.Data as unknown[]).length).toBeLessThanOrEqual(1);
138
- },
139
- EXEC_TIMEOUT,
140
- );
141
-
142
- it(
143
- "S3: get a catalog by id",
144
- () => {
145
- const listRaw = localCliRaw(
146
- tempDir,
147
- `tasks catalogs list --folder-id ${folderId} --limit 1 --output json`,
148
- );
149
- const list = parseOutput(listRaw.stdout, "json") as {
150
- Data?: Catalog[];
151
- };
152
- const id = list.Data?.[0]?.Id;
153
- if (typeof id !== "number") {
154
- throw new Error(
155
- "No catalog in the folder for getCatalogById. Seed a catalog first.",
156
- );
157
- }
158
-
159
- const res = getCatalog(id);
160
- expect(res.Result).toBe(RESULTS.Success);
161
- expect(res.Code).toBe("TaskCatalogDetails");
162
- expect((res.Data as Catalog).Id).toBe(id);
163
- expect(typeof (res.Data as Catalog).Name).toBe("string");
164
- },
165
- EXEC_TIMEOUT,
166
- );
167
-
168
- it(
169
- "S4: get a non-existent catalog reports a failure",
170
- () => {
171
- const raw = localCliRaw(
172
- tempDir,
173
- `tasks catalogs get 999999999 --folder-id ${folderId} --output json`,
174
- );
175
- const res = parseOutput(raw.stdout, "json") as Envelope;
176
- expect(raw.exitCode).not.toBe(0);
177
- expect(res.Result).toBe(RESULTS.Failure);
178
- expect(res.Message).toMatch(/^Error getting task catalog/);
179
- expectClassified(res);
180
- },
181
- EXEC_TIMEOUT,
182
- );
183
-
184
- it(
185
- "S5: invalid catalog id reports a validation error",
186
- () => {
187
- const raw = localCliRaw(
188
- tempDir,
189
- `tasks catalogs get not-a-number --folder-id ${folderId} --output json`,
190
- );
191
- const res = parseOutput(raw.stdout, "json") as Envelope;
192
- expect(raw.exitCode).not.toBe(0);
193
- expect(res.Result).toBe(RESULTS.Failure);
194
- expect(res.Message).toMatch(/^Invalid <id>/);
195
- expect(res.Instructions).toBe("Must be a positive integer.");
196
- },
197
- EXEC_TIMEOUT,
198
- );
199
-
200
- it(
201
- "S6: create a minimal catalog (name only)",
202
- () => {
203
- const name = `sdk-cli-e2e-${Date.now()}`;
204
- const res = createCatalog(name);
205
- expect(res.Result).toBe(RESULTS.Success);
206
- expect(res.Code).toBe("TaskCatalogCreated");
207
- const created = res.Data as Catalog;
208
- expect(created.Name).toBe(name);
209
- expect(typeof created.Id).toBe("number");
210
- createdCatalogId = created.Id;
211
- },
212
- EXEC_TIMEOUT,
213
- );
214
-
215
- it(
216
- "S7: create a catalog with description, encryption, and a retention policy",
217
- () => {
218
- const name = `sdk-cli-e2e-ret-${Date.now()}`;
219
- const res = createCatalog(name, [
220
- "--description",
221
- "Invoice approvals",
222
- "--encrypted",
223
- "--retention-action",
224
- "Delete",
225
- "--retention-period",
226
- "30",
227
- ]);
228
- expect(res.Result).toBe(RESULTS.Success);
229
- expect(res.Code).toBe("TaskCatalogCreated");
230
- const created = res.Data as Catalog;
231
- expect(created.Encrypted).toBe(true);
232
- expect(created.RetentionAction).toBe("Delete");
233
- expect(created.RetentionPeriod).toBe(30);
234
- },
235
- EXEC_TIMEOUT,
236
- );
237
-
238
- it(
239
- "S8: create without --name fails",
240
- () => {
241
- const raw = localCliRaw(
242
- tempDir,
243
- `tasks catalogs create --folder-id ${folderId} --output json`,
244
- );
245
- expect(raw.exitCode).not.toBe(0);
246
- },
247
- EXEC_TIMEOUT,
248
- );
249
-
250
- it(
251
- "S9: create with an invalid --retention-action is rejected before the API call",
252
- () => {
253
- const res = createCatalog(`sdk-cli-e2e-bad-${Date.now()}`, [
254
- "--retention-action",
255
- "Purge",
256
- ]);
257
- expect(res.Result).toBe(RESULTS.Failure);
258
- expect(res.Message).toBe("Invalid --retention-action 'Purge'");
259
- expect(res.Instructions).toContain("Delete");
260
- },
261
- EXEC_TIMEOUT,
262
- );
263
-
264
- it(
265
- "S10: update a catalog's name and description",
266
- () => {
267
- if (typeof createdCatalogId !== "number") {
268
- throw new Error(
269
- "S6 must create a catalog before S10 updates it.",
270
- );
271
- }
272
- const raw = localCliRawWithArgs(tempDir, [
273
- "tasks",
274
- "catalogs",
275
- "update",
276
- String(createdCatalogId),
277
- "--folder-id",
278
- folderId,
279
- "--name",
280
- `sdk-cli-e2e-renamed-${Date.now()}`,
281
- "--description",
282
- "Updated",
283
- "--output",
284
- "json",
285
- ]);
286
- const res = parseOutput(raw.stdout, "json") as Envelope;
287
- expect(raw.exitCode, JSON.stringify(res)).toBe(0);
288
- expect(res.Result).toBe(RESULTS.Success);
289
- expect(res.Code).toBe("TaskCatalogUpdated");
290
- },
291
- EXEC_TIMEOUT,
292
- );
293
-
294
- it(
295
- "S11: retention round-trips through create, update, and get",
296
- () => {
297
- const name = `sdk-cli-e2e-rt-${Date.now()}`;
298
- const created = createCatalog(name, [
299
- "--retention-action",
300
- "Delete",
301
- "--retention-period",
302
- "30",
303
- ]);
304
- const id = (created.Data as Catalog).Id;
305
- expect(typeof id).toBe("number");
306
-
307
- const afterCreate = getCatalog(id as number);
308
- expect((afterCreate.Data as Catalog).RetentionPeriod).toBe(30);
309
-
310
- const upd = localCliRawWithArgs(tempDir, [
311
- "tasks",
312
- "catalogs",
313
- "update",
314
- String(id),
315
- "--folder-id",
316
- folderId,
317
- "--name",
318
- name,
319
- "--retention-action",
320
- "Delete",
321
- "--retention-period",
322
- "60",
323
- "--output",
324
- "json",
325
- ]);
326
- expect(upd.exitCode, upd.stdout).toBe(0);
327
-
328
- const afterUpdate = getCatalog(id as number);
329
- expect((afterUpdate.Data as Catalog).RetentionPeriod).toBe(60);
330
- },
331
- EXEC_TIMEOUT,
332
- );
333
-
334
- it(
335
- "S12: update a non-existent catalog reports a failure",
336
- () => {
337
- const raw = localCliRaw(
338
- tempDir,
339
- `tasks catalogs update 999999999 --folder-id ${folderId} --name whatever --output json`,
340
- );
341
- const res = parseOutput(raw.stdout, "json") as Envelope;
342
- expect(raw.exitCode).not.toBe(0);
343
- expect(res.Result).toBe(RESULTS.Failure);
344
- expect(res.Message).toMatch(/^Error updating task catalog/);
345
- expectClassified(res);
346
- },
347
- EXEC_TIMEOUT,
348
- );
349
-
350
- it(
351
- "S13: update with only --description preserves the other fields",
352
- () => {
353
- const name = `sdk-cli-e2e-merge-${Date.now()}`;
354
- const created = createCatalog(name, [
355
- "--retention-action",
356
- "Delete",
357
- "--retention-period",
358
- "30",
359
- ]);
360
- const id = (created.Data as Catalog).Id;
361
- expect(typeof id).toBe("number");
362
-
363
- // Update only the description; leave name and retention unset.
364
- const upd = localCliRawWithArgs(tempDir, [
365
- "tasks",
366
- "catalogs",
367
- "update",
368
- String(id),
369
- "--folder-id",
370
- folderId,
371
- "--description",
372
- "Only this changed",
373
- "--output",
374
- "json",
375
- ]);
376
- expect(upd.exitCode, upd.stdout).toBe(0);
377
-
378
- // Read-modify-write: name and retention must survive the update.
379
- const after = getCatalog(id as number).Data as Catalog;
380
- expect(after.Name).toBe(name);
381
- expect(after.RetentionPeriod).toBe(30);
382
- },
383
- EXEC_TIMEOUT,
384
- );
385
-
386
- it(
387
- "S14: list catalogs scoped by folder key",
388
- () => {
389
- const foldersRaw = localCliRaw(
390
- tempDir,
391
- "or folders list --output json",
392
- );
393
- if (foldersRaw.exitCode !== 0) return;
394
- const foldersRes = parseOutput(foldersRaw.stdout, "json") as {
395
- Data?: { Key?: string }[];
396
- };
397
- const key = foldersRes.Data?.[0]?.Key;
398
- if (!key) return;
399
-
400
- const raw = localCliRaw(
401
- tempDir,
402
- `tasks catalogs list --folder-key ${key} --output json`,
403
- );
404
- const res = parseOutput(raw.stdout, "json") as Envelope;
405
- expect(raw.exitCode, JSON.stringify(res)).toBe(0);
406
- expect(res.Result).toBe(RESULTS.Success);
407
- expect(res.Code).toBe("TaskCatalogList");
408
- expect(Array.isArray(res.Data)).toBe(true);
409
- },
410
- EXEC_TIMEOUT,
411
- );
412
-
413
- // A 5xx from the catalogs endpoint cannot be induced against a live tenant,
414
- // so the RetryLater classification is unit-covered in tasks.spec.ts instead.
415
- // Expected envelope on an HTTP 5xx from any catalogs call: Result: Failure,
416
- // ErrorCode: server_error, Retry: RetryLater, Context.httpStatus: 5xx.
417
- it.skip("S15: a transient catalogs failure is reported as retryable", () => {});
418
- });
@@ -1,223 +0,0 @@
1
- import { RESULTS } from "@uipath/common";
2
- import { describe, expect, it } from "vitest";
3
- import {
4
- type E2EManifest,
5
- MANIFEST_PATH,
6
- } from "../../../tests/e2e-shared/global-setup";
7
- import {
8
- EXEC_TIMEOUT,
9
- localCliRaw,
10
- localCliRawWithArgs,
11
- parseOutput,
12
- readManifest,
13
- } from "../../../tests/e2e-shared/helpers";
14
-
15
- interface Envelope {
16
- Result: string;
17
- Code?: string;
18
- Data?: unknown;
19
- Message?: string;
20
- Instructions?: string;
21
- }
22
-
23
- interface TaskRow {
24
- Id?: number;
25
- IsDeleted?: boolean;
26
- Status?: string;
27
- Type?: string;
28
- FolderId?: number;
29
- }
30
-
31
- const { tempDir } = readManifest<E2EManifest>(MANIFEST_PATH).sharedInstall;
32
-
33
- function listTasks(asAdmin: boolean): TaskRow[] {
34
- const flag = asAdmin ? "--as-admin " : "";
35
- const raw = localCliRaw(
36
- tempDir,
37
- `tasks list ${flag}--limit 200 --output json`,
38
- );
39
- if (raw.exitCode !== 0) return [];
40
- return (parseOutput(raw.stdout, "json") as { Data?: TaskRow[] }).Data ?? [];
41
- }
42
-
43
- function discoverTask(): { taskId: string; folderId: string } | null {
44
- const envFolder = process.env.TASKS_TOOL_E2E_FOLDER_ID;
45
- const envTask =
46
- process.env.TASKS_TOOL_E2E_TASK_ID_COMMENTS ??
47
- process.env.TASKS_TOOL_E2E_TASK_ID;
48
- if (envFolder && envTask) {
49
- return { taskId: envTask, folderId: envFolder };
50
- }
51
- for (const asAdmin of [false, true]) {
52
- const task = listTasks(asAdmin).find(
53
- (t) =>
54
- !t.IsDeleted &&
55
- t.Status !== "Completed" &&
56
- t.Type === "ExternalTask" &&
57
- typeof t.Id === "number" &&
58
- typeof t.FolderId === "number",
59
- );
60
- if (task) {
61
- return {
62
- taskId: String(task.Id),
63
- folderId: String(envFolder ?? task.FolderId),
64
- };
65
- }
66
- }
67
- // No actionable ExternalTask on this tenant; skip the live suite (guarded by describe.skipIf below).
68
- return null;
69
- }
70
-
71
- const discovered = discoverTask();
72
- const taskId = discovered?.taskId ?? "";
73
- const folderId = discovered?.folderId ?? "";
74
-
75
- describe.skipIf(!discovered)("tasks comments e2e", () => {
76
- it(
77
- "S1: list comments for a task",
78
- () => {
79
- const raw = localCliRaw(
80
- tempDir,
81
- `tasks comments list ${taskId} --folder-id ${folderId} --output json`,
82
- );
83
- const res = parseOutput(raw.stdout, "json") as Envelope;
84
- expect(raw.exitCode, JSON.stringify(res)).toBe(0);
85
- expect(res.Result).toBe(RESULTS.Success);
86
- expect(res.Code).toBe("TaskCommentList");
87
- expect(Array.isArray(res.Data)).toBe(true);
88
- },
89
- EXEC_TIMEOUT,
90
- );
91
-
92
- it(
93
- "S2: list caps results with --limit",
94
- () => {
95
- const raw = localCliRaw(
96
- tempDir,
97
- `tasks comments list ${taskId} --folder-id ${folderId} --limit 1 --output json`,
98
- );
99
- const res = parseOutput(raw.stdout, "json") as Envelope;
100
- expect(raw.exitCode, JSON.stringify(res)).toBe(0);
101
- expect(res.Code).toBe("TaskCommentList");
102
- expect((res.Data as unknown[]).length).toBeLessThanOrEqual(1);
103
- },
104
- EXEC_TIMEOUT,
105
- );
106
-
107
- it(
108
- "S3: invalid task id reports a validation error",
109
- () => {
110
- const raw = localCliRaw(
111
- tempDir,
112
- `tasks comments list not-a-number --folder-id ${folderId} --output json`,
113
- );
114
- const res = parseOutput(raw.stdout, "json") as Envelope;
115
- expect(raw.exitCode).not.toBe(0);
116
- expect(res.Result).toBe(RESULTS.Failure);
117
- expect(res.Message).toMatch(/^Invalid <task-id>/);
118
- expect(res.Instructions).toBe("Must be a positive integer.");
119
- },
120
- EXEC_TIMEOUT,
121
- );
122
-
123
- it(
124
- "S4: add a comment",
125
- () => {
126
- const text = `sdk-cli-e2e comment ${Date.now()}`;
127
- const raw = localCliRawWithArgs(tempDir, [
128
- "tasks",
129
- "comments",
130
- "add",
131
- taskId,
132
- "--folder-id",
133
- folderId,
134
- "--text",
135
- text,
136
- "--output",
137
- "json",
138
- ]);
139
- const res = parseOutput(raw.stdout, "json") as Envelope;
140
- expect(raw.exitCode, JSON.stringify(res)).toBe(0);
141
- expect(res.Result).toBe(RESULTS.Success);
142
- expect(res.Code).toBe("TaskCommentCreated");
143
- expect((res.Data as { Text?: string }).Text).toBe(text);
144
- },
145
- EXEC_TIMEOUT,
146
- );
147
-
148
- it(
149
- "S5: empty text reports a validation error",
150
- () => {
151
- const raw = localCliRawWithArgs(tempDir, [
152
- "tasks",
153
- "comments",
154
- "add",
155
- taskId,
156
- "--folder-id",
157
- folderId,
158
- "--text",
159
- "",
160
- "--output",
161
- "json",
162
- ]);
163
- const res = parseOutput(raw.stdout, "json") as Envelope;
164
- expect(raw.exitCode).not.toBe(0);
165
- expect(res.Result).toBe(RESULTS.Failure);
166
- expect(res.Message).toBe("--text cannot be empty");
167
- },
168
- EXEC_TIMEOUT,
169
- );
170
-
171
- it(
172
- "S6: add a comment to a non-existent task reports a failure",
173
- () => {
174
- const raw = localCliRawWithArgs(tempDir, [
175
- "tasks",
176
- "comments",
177
- "add",
178
- "999999999",
179
- "--folder-id",
180
- folderId,
181
- "--text",
182
- "Escalated",
183
- "--output",
184
- "json",
185
- ]);
186
- const res = parseOutput(raw.stdout, "json") as Envelope;
187
- expect(raw.exitCode).not.toBe(0);
188
- expect(res.Result).toBe(RESULTS.Failure);
189
- expect(res.Message).toMatch(/^Error adding comment to task/);
190
- },
191
- EXEC_TIMEOUT,
192
- );
193
-
194
- it(
195
- "S7: a created comment appears in the list",
196
- () => {
197
- const marker = `sdk-cli-e2e-marker-${Date.now()}`;
198
- const create = localCliRawWithArgs(tempDir, [
199
- "tasks",
200
- "comments",
201
- "add",
202
- taskId,
203
- "--folder-id",
204
- folderId,
205
- "--text",
206
- marker,
207
- "--output",
208
- "json",
209
- ]);
210
- expect(create.exitCode, create.stdout).toBe(0);
211
-
212
- const listRaw = localCliRaw(
213
- tempDir,
214
- `tasks comments list ${taskId} --folder-id ${folderId} --limit 100 --output json`,
215
- );
216
- const list = parseOutput(listRaw.stdout, "json") as {
217
- Data?: { Text?: string }[];
218
- };
219
- expect((list.Data ?? []).some((n) => n.Text === marker)).toBe(true);
220
- },
221
- EXEC_TIMEOUT,
222
- );
223
- });