@agentuity/core 2.0.7 → 2.0.8

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 (106) hide show
  1. package/dist/services/coder/api-reference.d.ts +4 -0
  2. package/dist/services/coder/api-reference.d.ts.map +1 -0
  3. package/dist/services/coder/api-reference.js +199 -0
  4. package/dist/services/coder/api-reference.js.map +1 -0
  5. package/dist/services/coder/client.d.ts +128 -0
  6. package/dist/services/coder/client.d.ts.map +1 -0
  7. package/dist/services/coder/client.js +265 -0
  8. package/dist/services/coder/client.js.map +1 -0
  9. package/dist/services/coder/discover.d.ts +13 -0
  10. package/dist/services/coder/discover.d.ts.map +1 -0
  11. package/dist/services/coder/discover.js +18 -0
  12. package/dist/services/coder/discover.js.map +1 -0
  13. package/dist/services/coder/github.d.ts +13 -0
  14. package/dist/services/coder/github.d.ts.map +1 -0
  15. package/dist/services/coder/github.js +15 -0
  16. package/dist/services/coder/github.js.map +1 -0
  17. package/dist/services/coder/index.d.ts +19 -0
  18. package/dist/services/coder/index.d.ts.map +1 -0
  19. package/dist/services/coder/index.js +13 -0
  20. package/dist/services/coder/index.js.map +1 -0
  21. package/dist/services/coder/loop-state.d.ts +10 -0
  22. package/dist/services/coder/loop-state.d.ts.map +1 -0
  23. package/dist/services/coder/loop-state.js +13 -0
  24. package/dist/services/coder/loop-state.js.map +1 -0
  25. package/dist/services/coder/session-data.d.ts +28 -0
  26. package/dist/services/coder/session-data.d.ts.map +1 -0
  27. package/dist/services/coder/session-data.js +28 -0
  28. package/dist/services/coder/session-data.js.map +1 -0
  29. package/dist/services/coder/sessions.d.ts +155 -0
  30. package/dist/services/coder/sessions.d.ts.map +1 -0
  31. package/dist/services/coder/sessions.js +125 -0
  32. package/dist/services/coder/sessions.js.map +1 -0
  33. package/dist/services/coder/skills.d.ts +17 -0
  34. package/dist/services/coder/skills.d.ts.map +1 -0
  35. package/dist/services/coder/skills.js +43 -0
  36. package/dist/services/coder/skills.js.map +1 -0
  37. package/dist/services/coder/types.d.ts +1066 -0
  38. package/dist/services/coder/types.d.ts.map +1 -0
  39. package/dist/services/coder/types.js +573 -0
  40. package/dist/services/coder/types.js.map +1 -0
  41. package/dist/services/coder/users.d.ts +12 -0
  42. package/dist/services/coder/users.d.ts.map +1 -0
  43. package/dist/services/coder/users.js +35 -0
  44. package/dist/services/coder/users.js.map +1 -0
  45. package/dist/services/coder/util.d.ts +82 -0
  46. package/dist/services/coder/util.d.ts.map +1 -0
  47. package/dist/services/coder/util.js +60 -0
  48. package/dist/services/coder/util.js.map +1 -0
  49. package/dist/services/coder/workspaces.d.ts +13 -0
  50. package/dist/services/coder/workspaces.d.ts.map +1 -0
  51. package/dist/services/coder/workspaces.js +37 -0
  52. package/dist/services/coder/workspaces.js.map +1 -0
  53. package/dist/services/index.d.ts +1 -0
  54. package/dist/services/index.d.ts.map +1 -1
  55. package/dist/services/index.js +1 -0
  56. package/dist/services/index.js.map +1 -1
  57. package/dist/services/oauth/types.d.ts +1 -0
  58. package/dist/services/oauth/types.d.ts.map +1 -1
  59. package/dist/services/oauth/types.js +1 -0
  60. package/dist/services/oauth/types.js.map +1 -1
  61. package/dist/services/project/deploy.d.ts +1 -1
  62. package/dist/services/queue/service.d.ts +28 -0
  63. package/dist/services/queue/service.d.ts.map +1 -1
  64. package/dist/services/queue/service.js +54 -9
  65. package/dist/services/queue/service.js.map +1 -1
  66. package/dist/services/sandbox/cli-list.d.ts +1 -1
  67. package/dist/services/sandbox/client.d.ts +10 -4
  68. package/dist/services/sandbox/client.d.ts.map +1 -1
  69. package/dist/services/sandbox/client.js +2 -2
  70. package/dist/services/sandbox/client.js.map +1 -1
  71. package/dist/services/sandbox/create.d.ts +2 -2
  72. package/dist/services/sandbox/execute.d.ts +2 -2
  73. package/dist/services/sandbox/execution.d.ts +4 -4
  74. package/dist/services/sandbox/files.d.ts +10 -2
  75. package/dist/services/sandbox/files.d.ts.map +1 -1
  76. package/dist/services/sandbox/files.js +14 -0
  77. package/dist/services/sandbox/files.js.map +1 -1
  78. package/dist/services/sandbox/get.d.ts +2 -2
  79. package/dist/services/sandbox/list.d.ts +4 -4
  80. package/dist/services/sandbox/run.d.ts +1 -1
  81. package/dist/services/sandbox/types.d.ts +18 -10
  82. package/dist/services/sandbox/types.d.ts.map +1 -1
  83. package/dist/services/sandbox/types.js +4 -4
  84. package/dist/services/sandbox/types.js.map +1 -1
  85. package/dist/services/session/events.d.ts +2 -2
  86. package/dist/services/workflow/types.d.ts +8 -8
  87. package/package.json +2 -2
  88. package/src/services/coder/api-reference.ts +207 -0
  89. package/src/services/coder/client.ts +378 -0
  90. package/src/services/coder/discover.ts +23 -0
  91. package/src/services/coder/github.ts +33 -0
  92. package/src/services/coder/index.ts +72 -0
  93. package/src/services/coder/loop-state.ts +19 -0
  94. package/src/services/coder/session-data.ts +63 -0
  95. package/src/services/coder/sessions.ts +237 -0
  96. package/src/services/coder/skills.ts +102 -0
  97. package/src/services/coder/types.ts +670 -0
  98. package/src/services/coder/users.ts +59 -0
  99. package/src/services/coder/util.ts +87 -0
  100. package/src/services/coder/workspaces.ts +77 -0
  101. package/src/services/index.ts +1 -0
  102. package/src/services/oauth/types.ts +1 -0
  103. package/src/services/queue/service.ts +56 -13
  104. package/src/services/sandbox/client.ts +10 -8
  105. package/src/services/sandbox/files.ts +28 -2
  106. package/src/services/sandbox/types.ts +8 -6
@@ -0,0 +1,59 @@
1
+ import { z } from 'zod/v4';
2
+ import { type APIClient } from '../api.ts';
3
+ import {
4
+ CoderListUsersParamsSchema,
5
+ CoderListUsersResponseSchema,
6
+ CoderUserSchema,
7
+ type CoderListUsersParams,
8
+ type CoderListUsersResponse,
9
+ } from './types.ts';
10
+
11
+ const CoderListUsersPayloadSchema = z
12
+ .union([
13
+ z.array(CoderUserSchema).describe('Array-only users payload from service'),
14
+ CoderListUsersResponseSchema.describe('Object users payload from service'),
15
+ ])
16
+ .describe('Raw users list payload shape returned by service');
17
+
18
+ export const CoderListUsersParamsWithOrgSchema = CoderListUsersParamsSchema.describe(
19
+ 'Parameters for listing coder users'
20
+ );
21
+ export type CoderListUsersParamsWithOrg = z.infer<typeof CoderListUsersParamsWithOrgSchema>;
22
+
23
+ function normalizeUsers(
24
+ payload: z.infer<typeof CoderListUsersPayloadSchema>
25
+ ): CoderListUsersResponse {
26
+ if (Array.isArray(payload)) {
27
+ return {
28
+ users: payload,
29
+ total: payload.length,
30
+ };
31
+ }
32
+
33
+ return CoderListUsersResponseSchema.parse(payload);
34
+ }
35
+
36
+ export async function coderListUsers(
37
+ client: APIClient,
38
+ params?: CoderListUsersParams
39
+ ): Promise<CoderListUsersResponse> {
40
+ const query = new URLSearchParams();
41
+ if (params?.search) {
42
+ query.set('search', params.search);
43
+ }
44
+ if (params?.limit !== undefined) {
45
+ query.set('limit', String(params.limit));
46
+ }
47
+ if (params?.offset !== undefined) {
48
+ query.set('offset', String(params.offset));
49
+ }
50
+
51
+ const queryString = query.toString();
52
+ const path = `/hub/users${queryString ? `?${queryString}` : ''}`;
53
+ const payload = await client.get<z.infer<typeof CoderListUsersPayloadSchema>>(
54
+ path,
55
+ CoderListUsersPayloadSchema
56
+ );
57
+
58
+ return normalizeUsers(payload);
59
+ }
@@ -0,0 +1,87 @@
1
+ import { StructuredError } from '../../error.ts';
2
+ import { z } from 'zod/v4';
3
+
4
+ export const CoderErrorCodeSchema = z
5
+ .enum([
6
+ 'CODER_SESSION_NOT_FOUND',
7
+ 'CODER_SESSION_ARCHIVED',
8
+ 'CODER_SESSION_CONFLICT',
9
+ 'CODER_INVALID_REQUEST',
10
+ ])
11
+ .describe('Machine-readable error codes returned by coder APIs');
12
+ export type CoderErrorCode = z.infer<typeof CoderErrorCodeSchema>;
13
+
14
+ export const CoderResponseError = StructuredError('CoderResponseError')<{
15
+ /** Coder session id involved in the failed operation */
16
+ coderSessionId?: string;
17
+ /** x-session-id header value used for trace correlation */
18
+ requestSessionId?: string | null;
19
+ /** Backend machine-readable error code, if provided */
20
+ code?: CoderErrorCode;
21
+ }>();
22
+
23
+ export const CoderSessionNotFoundError = StructuredError('CoderSessionNotFoundError')<{
24
+ coderSessionId: string;
25
+ }>();
26
+
27
+ export const CoderSessionArchivedError = StructuredError('CoderSessionArchivedError')<{
28
+ coderSessionId?: string;
29
+ }>();
30
+
31
+ export const CoderSessionConflictError = StructuredError('CoderSessionConflictError')<{
32
+ coderSessionId?: string;
33
+ }>();
34
+
35
+ export const CoderErrorContextSchema = z
36
+ .object({
37
+ sessionId: z.string().optional().describe('Coder session id involved in the operation'),
38
+ requestSessionId: z
39
+ .string()
40
+ .nullish()
41
+ .describe('Request trace session id from x-session-id header'),
42
+ })
43
+ .describe('Context used when mapping coder API errors');
44
+ export type CoderErrorContext = z.infer<typeof CoderErrorContextSchema>;
45
+
46
+ export function throwCoderError(
47
+ resp: { message?: string; code?: string },
48
+ context: CoderErrorContext
49
+ ): never {
50
+ const code = resp.code as CoderErrorCode | undefined;
51
+
52
+ switch (code) {
53
+ case 'CODER_SESSION_NOT_FOUND':
54
+ throw new CoderSessionNotFoundError({
55
+ message: resp.message,
56
+ coderSessionId: context.sessionId ?? '',
57
+ });
58
+ case 'CODER_SESSION_ARCHIVED':
59
+ throw new CoderSessionArchivedError({
60
+ message: resp.message,
61
+ coderSessionId: context.sessionId,
62
+ });
63
+ case 'CODER_SESSION_CONFLICT':
64
+ throw new CoderSessionConflictError({
65
+ message: resp.message,
66
+ coderSessionId: context.sessionId,
67
+ });
68
+ default:
69
+ throw new CoderResponseError({
70
+ message: resp.message,
71
+ coderSessionId: context.sessionId,
72
+ requestSessionId: context.requestSessionId,
73
+ code,
74
+ });
75
+ }
76
+ }
77
+
78
+ export function normalizeCoderUrl(url: string): string {
79
+ return url.replace(/\/$/, '');
80
+ }
81
+
82
+ export function withOrgId(params: URLSearchParams, orgId?: string): URLSearchParams {
83
+ if (orgId) {
84
+ params.set('orgId', orgId);
85
+ }
86
+ return params;
87
+ }
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod/v4';
2
+ import { type APIClient } from '../api.ts';
3
+ import {
4
+ CoderCreateWorkspaceRequestSchema,
5
+ CoderWorkspaceDetailSchema,
6
+ CoderWorkspaceListResponseSchema,
7
+ type CoderCreateWorkspaceRequest,
8
+ type CoderWorkspaceDetail,
9
+ type CoderWorkspaceListResponse,
10
+ } from './types.ts';
11
+
12
+ const WorkspaceGetResponseSchema = z
13
+ .object({
14
+ workspace: CoderWorkspaceDetailSchema.describe('Workspace payload returned by coder hub'),
15
+ })
16
+ .passthrough()
17
+ .describe('Wrapped workspace response from coder hub');
18
+
19
+ const WorkspaceCreateResponseSchema = z
20
+ .object({
21
+ workspace: CoderWorkspaceDetailSchema.describe(
22
+ 'Created workspace payload returned by coder hub'
23
+ ),
24
+ })
25
+ .passthrough()
26
+ .describe('Wrapped workspace create response from coder hub');
27
+
28
+ const OkResponseSchema = z
29
+ .object({
30
+ ok: z.boolean().describe('Operation success indicator'),
31
+ })
32
+ .passthrough()
33
+ .describe('Generic ok response from coder hub');
34
+
35
+ export async function coderListWorkspaces(client: APIClient): Promise<CoderWorkspaceListResponse> {
36
+ return client.get<CoderWorkspaceListResponse>(
37
+ '/hub/workspaces',
38
+ CoderWorkspaceListResponseSchema
39
+ );
40
+ }
41
+
42
+ export async function coderGetWorkspace(
43
+ client: APIClient,
44
+ params: { workspaceId: string }
45
+ ): Promise<CoderWorkspaceDetail> {
46
+ const path = `/hub/workspaces/${encodeURIComponent(params.workspaceId)}`;
47
+ const resp = await client.get<z.infer<typeof WorkspaceGetResponseSchema>>(
48
+ path,
49
+ WorkspaceGetResponseSchema
50
+ );
51
+ return resp.workspace;
52
+ }
53
+
54
+ export async function coderCreateWorkspace(
55
+ client: APIClient,
56
+ params: { body: CoderCreateWorkspaceRequest }
57
+ ): Promise<CoderWorkspaceDetail> {
58
+ const resp = await client.post<
59
+ z.infer<typeof WorkspaceCreateResponseSchema>,
60
+ CoderCreateWorkspaceRequest
61
+ >(
62
+ '/hub/workspaces',
63
+ params.body,
64
+ WorkspaceCreateResponseSchema,
65
+ CoderCreateWorkspaceRequestSchema
66
+ );
67
+
68
+ return resp.workspace;
69
+ }
70
+
71
+ export async function coderDeleteWorkspace(
72
+ client: APIClient,
73
+ params: { workspaceId: string }
74
+ ): Promise<void> {
75
+ const path = `/hub/workspaces/${encodeURIComponent(params.workspaceId)}`;
76
+ await client.delete(path, OkResponseSchema);
77
+ }
@@ -9,6 +9,7 @@ export * from './task/index.ts';
9
9
  export * from './vector/index.ts';
10
10
 
11
11
  export * from './config.ts';
12
+ export * from './coder/index.ts';
12
13
  export * from './env.ts';
13
14
  export * from './logger.ts';
14
15
  export * from './api.ts';
@@ -313,6 +313,7 @@ export const OAuthUserInfoSchema = z
313
313
  name: z.string().optional(),
314
314
  given_name: z.string().optional(),
315
315
  family_name: z.string().optional(),
316
+ picture: z.string().optional(),
316
317
  email: z.string().optional(),
317
318
  email_verified: z.boolean().optional(),
318
319
  })
@@ -308,6 +308,14 @@ export interface QueueService {
308
308
  */
309
309
  export const QueuePublishError = StructuredError('QueuePublishError');
310
310
 
311
+ /**
312
+ * Error thrown when a queue creation operation fails.
313
+ *
314
+ * This is a general error for create failures that aren't specifically
315
+ * validation, not-found, or conflict (409) errors.
316
+ */
317
+ export const QueueCreateError = StructuredError('QueueCreateError');
318
+
311
319
  /**
312
320
  * Error thrown when a queue is not found.
313
321
  *
@@ -389,6 +397,33 @@ function validatePayloadInternal(payload: string): void {
389
397
  }
390
398
  }
391
399
 
400
+ /**
401
+ * Unwraps the standard API response envelope.
402
+ *
403
+ * The queue server returns responses wrapped in:
404
+ * { success: true, data: { [key]: { ...actual data... } } }
405
+ *
406
+ * Since `fromResponse()` parses the raw JSON body, `res.data` from the
407
+ * adapter is the full envelope. This helper extracts the nested data by key.
408
+ *
409
+ * Falls back to treating the input as already-unwrapped data (e.g., in tests
410
+ * using mock adapters that provide flat data directly).
411
+ *
412
+ * @internal
413
+ */
414
+ function unwrapApiResponse<T>(data: unknown, key: string): T {
415
+ if (data !== null && typeof data === 'object') {
416
+ const body = data as Record<string, unknown>;
417
+ if (body.success === true && typeof body.data === 'object' && body.data !== null) {
418
+ const envelope = body.data as Record<string, unknown>;
419
+ if (key in envelope) {
420
+ return envelope[key] as T;
421
+ }
422
+ }
423
+ }
424
+ return data as T;
425
+ }
426
+
392
427
  // ============================================================================
393
428
  // QueueStorageService Implementation
394
429
  // ============================================================================
@@ -496,16 +531,18 @@ export class QueueStorageService implements QueueService {
496
531
  });
497
532
 
498
533
  if (res.ok) {
499
- const data = res.data as unknown as {
500
- id: string;
501
- offset: number;
502
- published_at: string;
503
- };
504
- return {
534
+ const data = unwrapApiResponse<Record<string, unknown>>(res.data, 'message');
535
+ const result = QueuePublishResultSchema.safeParse({
505
536
  id: data.id,
506
537
  offset: data.offset,
507
538
  publishedAt: data.published_at,
508
- };
539
+ });
540
+ if (result.success) {
541
+ return result.data;
542
+ }
543
+ throw new QueuePublishError({
544
+ message: `Queue publish returned an unexpected response format: ${result.error.message}`,
545
+ });
509
546
  }
510
547
 
511
548
  if (res.response.status === 404) {
@@ -579,12 +616,18 @@ export class QueueStorageService implements QueueService {
579
616
  });
580
617
 
581
618
  if (res.ok) {
582
- const data = res.data as unknown as Record<string, unknown>;
583
- this.#knownQueues.add(queueName);
584
- return {
585
- name: (data.name as string) ?? queueName,
586
- queueType: (data.queue_type as string) ?? params?.queueType ?? 'worker',
587
- };
619
+ const data = unwrapApiResponse<Record<string, unknown>>(res.data, 'queue');
620
+ const result = QueueCreateResultSchema.safeParse({
621
+ name: data.name,
622
+ queueType: data.queue_type,
623
+ });
624
+ if (result.success) {
625
+ this.#knownQueues.add(queueName);
626
+ return result.data;
627
+ }
628
+ throw new QueueCreateError({
629
+ message: `Queue create returned an unexpected response format: ${result.error.message}`,
630
+ });
588
631
  }
589
632
 
590
633
  if (res.response.status === 409) {
@@ -257,14 +257,16 @@ export interface SandboxInstance {
257
257
  mkDir(path: string, recursive?: boolean): Promise<void>;
258
258
 
259
259
  /**
260
- * Remove a file from the sandbox workspace
260
+ * Remove a file from the sandbox workspace.
261
+ * @returns Object with `found` indicating whether the file existed before removal
261
262
  */
262
- rmFile(path: string): Promise<void>;
263
+ rmFile(path: string): Promise<{ found: boolean }>;
263
264
 
264
265
  /**
265
- * Remove a directory from the sandbox workspace
266
+ * Remove a directory from the sandbox workspace.
267
+ * @returns Object with `found` indicating whether the directory existed before removal
266
268
  */
267
- rmDir(path: string, recursive?: boolean): Promise<void>;
269
+ rmDir(path: string, recursive?: boolean): Promise<{ found: boolean }>;
268
270
 
269
271
  /**
270
272
  * Set environment variables on the sandbox. Pass null to delete a variable.
@@ -380,12 +382,12 @@ function createSandboxInstanceMethods(
380
382
  await sandboxMkDir(client, { sandboxId, path, recursive, orgId });
381
383
  },
382
384
 
383
- async rmFile(path: string): Promise<void> {
384
- await sandboxRmFile(client, { sandboxId, path, orgId });
385
+ async rmFile(path: string): Promise<{ found: boolean }> {
386
+ return sandboxRmFile(client, { sandboxId, path, orgId });
385
387
  },
386
388
 
387
- async rmDir(path: string, recursive?: boolean): Promise<void> {
388
- await sandboxRmDir(client, { sandboxId, path, recursive, orgId });
389
+ async rmDir(path: string, recursive?: boolean): Promise<{ found: boolean }> {
390
+ return sandboxRmDir(client, { sandboxId, path, recursive, orgId });
389
391
  },
390
392
 
391
393
  async setEnv(env: Record<string, string | null>): Promise<Record<string, string>> {
@@ -217,6 +217,13 @@ export const RmDirResponseSchema = z.discriminatedUnion('success', [
217
217
  }),
218
218
  z.object({
219
219
  success: z.literal<true>(true),
220
+ found: z
221
+ .boolean()
222
+ .optional()
223
+ .default(true)
224
+ .describe(
225
+ 'Whether the directory existed before removal. False when already removed (idempotent).'
226
+ ),
220
227
  }),
221
228
  ]);
222
229
 
@@ -235,9 +242,13 @@ export type RmDirParams = z.infer<typeof RmDirParamsSchema>;
235
242
  *
236
243
  * @param client - The API client to use for the request
237
244
  * @param params - Parameters including sandbox ID, path, and recursive flag
245
+ * @returns Object with `found` indicating whether the directory existed before removal
238
246
  * @throws {SandboxResponseError} If the rmdir request fails
239
247
  */
240
- export async function sandboxRmDir(client: APIClient, params: RmDirParams): Promise<void> {
248
+ export async function sandboxRmDir(
249
+ client: APIClient,
250
+ params: RmDirParams
251
+ ): Promise<{ found: boolean }> {
241
252
  const { sandboxId, path, recursive, orgId, signal } = params;
242
253
 
243
254
  const body: z.infer<typeof RmDirRequestSchema> = {
@@ -263,6 +274,8 @@ export async function sandboxRmDir(client: APIClient, params: RmDirParams): Prom
263
274
  if (!resp.success) {
264
275
  throwSandboxError(resp, { sandboxId });
265
276
  }
277
+
278
+ return { found: resp.found };
266
279
  }
267
280
 
268
281
  export const RmFileRequestSchema = z
@@ -278,6 +291,13 @@ export const RmFileResponseSchema = z.discriminatedUnion('success', [
278
291
  }),
279
292
  z.object({
280
293
  success: z.literal<true>(true),
294
+ found: z
295
+ .boolean()
296
+ .optional()
297
+ .default(true)
298
+ .describe(
299
+ 'Whether the file existed before removal. False when already removed (idempotent).'
300
+ ),
281
301
  }),
282
302
  ]);
283
303
 
@@ -295,9 +315,13 @@ export type RmFileParams = z.infer<typeof RmFileParamsSchema>;
295
315
  *
296
316
  * @param client - The API client to use for the request
297
317
  * @param params - Parameters including sandbox ID and path
318
+ * @returns Object with `found` indicating whether the file existed before removal
298
319
  * @throws {SandboxResponseError} If the rm request fails
299
320
  */
300
- export async function sandboxRmFile(client: APIClient, params: RmFileParams): Promise<void> {
321
+ export async function sandboxRmFile(
322
+ client: APIClient,
323
+ params: RmFileParams
324
+ ): Promise<{ found: boolean }> {
301
325
  const { sandboxId, path, orgId, signal } = params;
302
326
 
303
327
  const body: z.infer<typeof RmFileRequestSchema> = {
@@ -322,6 +346,8 @@ export async function sandboxRmFile(client: APIClient, params: RmFileParams): Pr
322
346
  if (!resp.success) {
323
347
  throwSandboxError(resp, { sandboxId });
324
348
  }
349
+
350
+ return { found: resp.found };
325
351
  }
326
352
 
327
353
  export const FileInfoSchema = z.object({
@@ -383,14 +383,16 @@ export const SandboxSchema = z.object({
383
383
  mkDir: z
384
384
  .custom<(path: string, recursive?: boolean) => Promise<void>>()
385
385
  .describe('Create a directory in the sandbox workspace.'),
386
- /** Remove a file from the sandbox workspace. */
386
+ /** Remove a file from the sandbox workspace. Returns whether the file was found. */
387
387
  rmFile: z
388
- .custom<(path: string) => Promise<void>>()
389
- .describe('Remove a file from the sandbox workspace.'),
390
- /** Remove a directory from the sandbox workspace. */
388
+ .custom<(path: string) => Promise<{ found: boolean }>>()
389
+ .describe('Remove a file from the sandbox workspace. Returns whether the file was found.'),
390
+ /** Remove a directory from the sandbox workspace. Returns whether the directory was found. */
391
391
  rmDir: z
392
- .custom<(path: string, recursive?: boolean) => Promise<void>>()
393
- .describe('Remove a directory from the sandbox workspace.'),
392
+ .custom<(path: string, recursive?: boolean) => Promise<{ found: boolean }>>()
393
+ .describe(
394
+ 'Remove a directory from the sandbox workspace. Returns whether the directory was found.'
395
+ ),
394
396
  /** Set environment variables on the sandbox. Pass null to delete a variable. */
395
397
  setEnv: z
396
398
  .custom<(env: Record<string, string | null>) => Promise<Record<string, string>>>()