@agentuity/server 1.0.14 → 1.0.16

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 (60) hide show
  1. package/dist/api/api.d.ts +6 -0
  2. package/dist/api/api.d.ts.map +1 -1
  3. package/dist/api/api.js +27 -5
  4. package/dist/api/api.js.map +1 -1
  5. package/dist/api/queue/index.d.ts +2 -1
  6. package/dist/api/queue/index.d.ts.map +1 -1
  7. package/dist/api/queue/index.js +5 -1
  8. package/dist/api/queue/index.js.map +1 -1
  9. package/dist/api/queue/types.d.ts +61 -0
  10. package/dist/api/queue/types.d.ts.map +1 -1
  11. package/dist/api/queue/types.js +41 -0
  12. package/dist/api/queue/types.js.map +1 -1
  13. package/dist/api/queue/websocket.d.ts +144 -0
  14. package/dist/api/queue/websocket.d.ts.map +1 -0
  15. package/dist/api/queue/websocket.js +376 -0
  16. package/dist/api/queue/websocket.js.map +1 -0
  17. package/dist/api/region/create.d.ts.map +1 -1
  18. package/dist/api/region/create.js +7 -0
  19. package/dist/api/region/create.js.map +1 -1
  20. package/dist/api/sandbox/create.d.ts +1 -0
  21. package/dist/api/sandbox/create.d.ts.map +1 -1
  22. package/dist/api/sandbox/create.js +10 -0
  23. package/dist/api/sandbox/create.js.map +1 -1
  24. package/dist/api/sandbox/get.d.ts +2 -0
  25. package/dist/api/sandbox/get.d.ts.map +1 -1
  26. package/dist/api/sandbox/get.js +5 -0
  27. package/dist/api/sandbox/get.js.map +1 -1
  28. package/dist/api/sandbox/index.d.ts +1 -1
  29. package/dist/api/sandbox/index.d.ts.map +1 -1
  30. package/dist/api/sandbox/index.js +1 -1
  31. package/dist/api/sandbox/index.js.map +1 -1
  32. package/dist/api/sandbox/snapshot-build.d.ts +14 -1
  33. package/dist/api/sandbox/snapshot-build.d.ts.map +1 -1
  34. package/dist/api/sandbox/snapshot-build.js +21 -3
  35. package/dist/api/sandbox/snapshot-build.js.map +1 -1
  36. package/dist/api/sandbox/snapshot.d.ts +1 -0
  37. package/dist/api/sandbox/snapshot.d.ts.map +1 -1
  38. package/dist/api/sandbox/snapshot.js +10 -1
  39. package/dist/api/sandbox/snapshot.js.map +1 -1
  40. package/dist/index.d.ts +1 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +2 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/util/mime.d.ts +10 -0
  45. package/dist/util/mime.d.ts.map +1 -0
  46. package/dist/util/mime.js +102 -0
  47. package/dist/util/mime.js.map +1 -0
  48. package/package.json +4 -4
  49. package/src/api/api.ts +43 -7
  50. package/src/api/queue/index.ts +19 -0
  51. package/src/api/queue/types.ts +51 -0
  52. package/src/api/queue/websocket.ts +488 -0
  53. package/src/api/region/create.ts +7 -0
  54. package/src/api/sandbox/create.ts +15 -0
  55. package/src/api/sandbox/get.ts +5 -0
  56. package/src/api/sandbox/index.ts +1 -1
  57. package/src/api/sandbox/snapshot-build.ts +29 -3
  58. package/src/api/sandbox/snapshot.ts +15 -1
  59. package/src/index.ts +3 -0
  60. package/src/util/mime.ts +109 -0
@@ -103,6 +103,13 @@ export function validateBucketName(name: string): { valid: boolean; error?: stri
103
103
  if (isIPv4Address(name)) {
104
104
  return { valid: false, error: 'bucket name cannot be an IP address' };
105
105
  }
106
+ // Reserved prefixes (system-generated names)
107
+ if (name.startsWith('ag-') || name.startsWith('ago-')) {
108
+ return {
109
+ valid: false,
110
+ error: 'bucket names starting with "ag-" or "ago-" are reserved for system use',
111
+ };
112
+ }
106
113
  return { valid: true };
107
114
  }
108
115
 
@@ -1,6 +1,7 @@
1
1
  import type { SandboxCreateOptions, SandboxStatus } from '@agentuity/core';
2
2
  import { z } from 'zod';
3
3
  import { type APIClient, APIResponseSchema } from '../api';
4
+ import { NPM_PACKAGE_NAME_PATTERN } from './snapshot-build';
4
5
  import { API_VERSION, throwSandboxError } from './util';
5
6
 
6
7
  export const SandboxCreateRequestSchema = z
@@ -86,6 +87,17 @@ export const SandboxCreateRequestSchema = z
86
87
  .array(z.string())
87
88
  .optional()
88
89
  .describe('Apt packages to install when creating the sandbox'),
90
+ packages: z
91
+ .array(
92
+ z
93
+ .string()
94
+ .regex(
95
+ NPM_PACKAGE_NAME_PATTERN,
96
+ 'Invalid npm/bun package specifier: must not contain whitespace, semicolons, backticks, pipes, or dollar signs'
97
+ )
98
+ )
99
+ .optional()
100
+ .describe('npm/bun packages to install globally when creating the sandbox'),
89
101
  metadata: z
90
102
  .record(z.string(), z.unknown())
91
103
  .optional()
@@ -202,6 +214,9 @@ export async function sandboxCreate(
202
214
  if (options.dependencies && options.dependencies.length > 0) {
203
215
  body.dependencies = options.dependencies;
204
216
  }
217
+ if (options.packages && options.packages.length > 0) {
218
+ body.packages = options.packages;
219
+ }
205
220
  if (options.metadata) {
206
221
  body.metadata = options.metadata;
207
222
  }
@@ -123,6 +123,10 @@ export const SandboxInfoDataSchema = z
123
123
  .array(z.string())
124
124
  .optional()
125
125
  .describe('Apt packages installed in the sandbox'),
126
+ packages: z
127
+ .array(z.string())
128
+ .optional()
129
+ .describe('npm/bun packages installed globally in the sandbox'),
126
130
  metadata: z
127
131
  .record(z.string(), z.unknown())
128
132
  .optional()
@@ -209,6 +213,7 @@ export async function sandboxGet(
209
213
  stdoutStreamUrl: resp.data.stdoutStreamUrl,
210
214
  stderrStreamUrl: resp.data.stderrStreamUrl,
211
215
  dependencies: resp.data.dependencies,
216
+ packages: resp.data.packages,
212
217
  metadata: resp.data.metadata as Record<string, unknown> | undefined,
213
218
  resources: resp.data.resources,
214
219
  cpuTimeMs: resp.data.cpuTimeMs,
@@ -171,7 +171,7 @@ export {
171
171
  snapshotUpload,
172
172
  } from './snapshot';
173
173
  export type { SnapshotBuildFile } from './snapshot-build';
174
- export { SnapshotBuildFileSchema } from './snapshot-build';
174
+ export { SnapshotBuildFileSchema, NPM_PACKAGE_NAME_PATTERN } from './snapshot-build';
175
175
  export type { SandboxErrorCode, SandboxErrorContext } from './util';
176
176
  export {
177
177
  ExecutionCancelledError,
@@ -1,5 +1,17 @@
1
1
  import { z } from 'zod';
2
2
 
3
+ /**
4
+ * Regex pattern for validating npm/bun package specifiers.
5
+ * Uses a blocklist approach: rejects shell injection characters while allowing
6
+ * all legitimate specifier formats (names, scoped packages, URLs, git refs, etc.).
7
+ *
8
+ * Valid examples: "typescript", "@types/node", "opencode-ai@1.2.3",
9
+ * "https://github.com/user/repo", "git+https://github.com/user/repo.git",
10
+ * "github:user/repo", "file:../local-pkg"
11
+ * Invalid examples: "foo bar", "pkg;rm -rf", "pkg|cat /etc/passwd", "$(evil)"
12
+ */
13
+ export const NPM_PACKAGE_NAME_PATTERN = /^[^\s;`|$]+$/;
14
+
3
15
  /**
4
16
  * Base schema for snapshot build configuration file (agentuity-snapshot.yaml)
5
17
  * This is the canonical schema - used for JSON Schema generation.
@@ -22,6 +34,19 @@ export const SnapshotBuildFileBaseSchema = z
22
34
  .describe(
23
35
  'List of apt packages to install. Supports version pinning: package=version or package=version* for prefix matching'
24
36
  ),
37
+ packages: z
38
+ .array(
39
+ z
40
+ .string()
41
+ .regex(
42
+ NPM_PACKAGE_NAME_PATTERN,
43
+ 'Invalid npm/bun package specifier: must not contain whitespace, semicolons, backticks, pipes, or dollar signs'
44
+ )
45
+ )
46
+ .optional()
47
+ .describe(
48
+ 'List of npm/bun packages to install globally via bun install -g. Example: opencode-ai, typescript'
49
+ ),
25
50
  files: z
26
51
  .array(z.string())
27
52
  .optional()
@@ -49,17 +74,18 @@ export const SnapshotBuildFileBaseSchema = z
49
74
 
50
75
  /**
51
76
  * Schema with validation refinement - use this for parsing/validation.
52
- * Ensures at least one of dependencies, files, or env is specified.
77
+ * Ensures at least one of dependencies, files, env, or packages is specified.
53
78
  */
54
79
  export const SnapshotBuildFileSchema = SnapshotBuildFileBaseSchema.refine(
55
80
  (data) => {
56
81
  const hasDependencies = data.dependencies && data.dependencies.length > 0;
57
82
  const hasFiles = data.files && data.files.length > 0;
58
83
  const hasEnv = data.env && Object.keys(data.env).length > 0;
59
- return hasDependencies || hasFiles || hasEnv;
84
+ const hasPackages = data.packages && data.packages.length > 0;
85
+ return hasDependencies || hasFiles || hasEnv || hasPackages;
60
86
  },
61
87
  {
62
- message: 'At least one of dependencies, files, or env must be specified',
88
+ message: 'At least one of dependencies, files, env, or packages must be specified',
63
89
  }
64
90
  );
65
91
 
@@ -1,5 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  import { type APIClient, APIResponseSchema, APIResponseSchemaNoData } from '../api';
3
+ import { NPM_PACKAGE_NAME_PATTERN } from './snapshot-build';
3
4
  import { API_VERSION, SandboxResponseError, throwSandboxError } from './util';
4
5
 
5
6
  export const SnapshotFileInfoSchema = z
@@ -594,6 +595,17 @@ const _SnapshotBuildFinalizeParamsSchema = z
594
595
  fileCount: z.number().describe('Number of files in the snapshot'),
595
596
  files: z.array(SnapshotFileInfoSchema).describe('List of files with path and size'),
596
597
  dependencies: z.array(z.string()).optional().describe('List of apt packages to install'),
598
+ packages: z
599
+ .array(
600
+ z
601
+ .string()
602
+ .regex(
603
+ NPM_PACKAGE_NAME_PATTERN,
604
+ 'Invalid npm/bun package specifier: must not contain whitespace, semicolons, backticks, pipes, or dollar signs'
605
+ )
606
+ )
607
+ .optional()
608
+ .describe('List of npm/bun packages to install globally'),
597
609
  env: z.record(z.string(), z.string()).optional().describe('Environment variables to set'),
598
610
  metadata: z
599
611
  .record(z.string(), z.string())
@@ -671,7 +683,8 @@ export async function snapshotBuildFinalize(
671
683
  client: APIClient,
672
684
  params: SnapshotBuildFinalizeParams
673
685
  ): Promise<SnapshotInfo> {
674
- const { snapshotId, sizeBytes, fileCount, files, dependencies, env, metadata, orgId } = params;
686
+ const { snapshotId, sizeBytes, fileCount, files, dependencies, packages, env, metadata, orgId } =
687
+ params;
675
688
  const queryString = buildQueryString({ orgId });
676
689
  const url = `/sandbox/${API_VERSION}/snapshots/${snapshotId}/finalize${queryString}`;
677
690
 
@@ -681,6 +694,7 @@ export async function snapshotBuildFinalize(
681
694
  files,
682
695
  };
683
696
  if (dependencies) body.dependencies = dependencies;
697
+ if (packages) body.packages = packages;
684
698
  if (env) body.env = env;
685
699
  if (metadata) body.metadata = metadata;
686
700
 
package/src/index.ts CHANGED
@@ -13,6 +13,9 @@ export { createServerFetchAdapter } from './server';
13
13
  // schema.ts exports
14
14
  export { toJSONSchema } from './schema';
15
15
 
16
+ // util/mime.ts exports
17
+ export { getContentType, mimeTypes } from './util/mime';
18
+
16
19
  // util/resources.ts exports
17
20
  export {
18
21
  validateCPUSpec,
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Canonical MIME type map and content-type lookup.
3
+ *
4
+ * This is the single source of truth for extension → MIME type mappings
5
+ * used across the CLI (build metadata, generated entry code) and runtime
6
+ * (serveStatic).
7
+ */
8
+
9
+ export const mimeTypes: Record<string, string> = {
10
+ // Text and code
11
+ css: 'text/css',
12
+ csv: 'text/csv',
13
+ htm: 'text/html',
14
+ html: 'text/html',
15
+ ics: 'text/calendar',
16
+ js: 'application/javascript',
17
+ mjs: 'application/javascript',
18
+ cjs: 'application/javascript',
19
+ json: 'application/json',
20
+ jsonld: 'application/ld+json',
21
+ map: 'application/json',
22
+ md: 'text/markdown',
23
+ markdown: 'text/markdown',
24
+ txt: 'text/plain',
25
+ text: 'text/plain',
26
+ vcf: 'text/vcard',
27
+ xml: 'application/xml',
28
+ yaml: 'text/yaml',
29
+ yml: 'text/yaml',
30
+
31
+ // Images
32
+ apng: 'image/apng',
33
+ avif: 'image/avif',
34
+ bmp: 'image/bmp',
35
+ gif: 'image/gif',
36
+ ico: 'image/x-icon',
37
+ jpeg: 'image/jpeg',
38
+ jpg: 'image/jpeg',
39
+ jxl: 'image/jxl',
40
+ png: 'image/png',
41
+ svg: 'image/svg+xml',
42
+ tif: 'image/tiff',
43
+ tiff: 'image/tiff',
44
+ webp: 'image/webp',
45
+
46
+ // Fonts
47
+ eot: 'application/vnd.ms-fontobject',
48
+ otf: 'font/otf',
49
+ ttf: 'font/ttf',
50
+ woff: 'font/woff',
51
+ woff2: 'font/woff2',
52
+
53
+ // Audio
54
+ aac: 'audio/aac',
55
+ flac: 'audio/flac',
56
+ m4a: 'audio/mp4',
57
+ mid: 'audio/midi',
58
+ midi: 'audio/midi',
59
+ mp3: 'audio/mpeg',
60
+ ogg: 'audio/ogg',
61
+ oga: 'audio/ogg',
62
+ opus: 'audio/opus',
63
+ wav: 'audio/wav',
64
+ weba: 'audio/webm',
65
+
66
+ // Video
67
+ avi: 'video/x-msvideo',
68
+ m4v: 'video/mp4',
69
+ mkv: 'video/x-matroska',
70
+ mov: 'video/quicktime',
71
+ mp4: 'video/mp4',
72
+ ogv: 'video/ogg',
73
+ webm: 'video/webm',
74
+
75
+ // Documents and archives
76
+ doc: 'application/msword',
77
+ docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
78
+ gz: 'application/gzip',
79
+ odp: 'application/vnd.oasis.opendocument.presentation',
80
+ ods: 'application/vnd.oasis.opendocument.spreadsheet',
81
+ odt: 'application/vnd.oasis.opendocument.text',
82
+ pdf: 'application/pdf',
83
+ ppt: 'application/vnd.ms-powerpoint',
84
+ pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
85
+ rtf: 'application/rtf',
86
+ tar: 'application/x-tar',
87
+ xls: 'application/vnd.ms-excel',
88
+ xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
89
+ zip: 'application/zip',
90
+ '7z': 'application/x-7z-compressed',
91
+
92
+ // Web and application
93
+ atom: 'application/atom+xml',
94
+ glb: 'model/gltf-binary',
95
+ gltf: 'model/gltf+json',
96
+ rss: 'application/rss+xml',
97
+ wasm: 'application/wasm',
98
+ webmanifest: 'application/manifest+json',
99
+ xsl: 'application/xslt+xml',
100
+ xslt: 'application/xslt+xml',
101
+ };
102
+
103
+ export function getContentType(filename: string): string {
104
+ const ext = filename.split('.').pop()?.toLowerCase();
105
+ if (ext && ext in mimeTypes) {
106
+ return mimeTypes[ext]!;
107
+ }
108
+ return 'application/octet-stream';
109
+ }