@protoboxai/sdk 1.0.0 → 1.0.1

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.
package/README.md CHANGED
@@ -1,8 +1,6 @@
1
1
  # @protoboxai/sdk
2
2
 
3
- Public TypeScript SDK for [Protobox](https://protobox.app) — managed MCP servers, tools, agents, knowledge resources, prompts, and chat.
4
-
5
- Forked from [`@chanl/sdk`](https://www.npmjs.com/package/@chanl/sdk) (source: `../chanl-v2/chanl-sdk`). Same API surface; Protobox-branded package for npm publish.
3
+ Public TypeScript SDK for [Protobox](https://protobox.ai) — managed MCP servers: tools, toolsets, knowledge, prompts, workspaces, and chat.
6
4
 
7
5
  ## Install
8
6
 
@@ -1,13 +1,13 @@
1
1
  /**
2
- * OpenAI Adapter for @chanl/sdk
2
+ * OpenAI Adapter for @protoboxai/sdk
3
3
  *
4
4
  * TDD Phase: GREEN - Implementation to make tests pass
5
5
  *
6
6
  * Provides integration with OpenAI's function calling format:
7
- * 1. Convert Chanl tools to OpenAI ChatCompletionTool format
7
+ * 1. Convert Protobox tools to OpenAI ChatCompletionTool format
8
8
  * 2. Execute tool calls from OpenAI responses
9
9
  */
10
- import { ChanlSDK } from '../client';
10
+ import { ProtoboxSDK } from '../client';
11
11
  /**
12
12
  * OpenAI function definition
13
13
  */
@@ -51,7 +51,7 @@ export interface GetToolsOptions {
51
51
  tag?: string;
52
52
  }
53
53
  /**
54
- * Adapter to integrate Chanl tools with OpenAI's function calling
54
+ * Adapter to integrate Protobox tools with OpenAI's function calling
55
55
  *
56
56
  * @example
57
57
  * ```typescript
@@ -79,9 +79,9 @@ export declare class OpenAIAdapter {
79
79
  private sdk;
80
80
  /** Cached tools for lookup during execution */
81
81
  private toolsCache;
82
- constructor(sdk: ChanlSDK);
82
+ constructor(sdk: ProtoboxSDK);
83
83
  /**
84
- * Convert Chanl tools to OpenAI function calling format
84
+ * Convert Protobox tools to OpenAI function calling format
85
85
  *
86
86
  * @param options - Optional filters for which tools to include
87
87
  * @returns Array of OpenAI ChatCompletionTool objects
@@ -95,7 +95,7 @@ export declare class OpenAIAdapter {
95
95
  */
96
96
  executeToolCalls(toolCalls: OpenAIToolCall[]): Promise<ToolOutput[]>;
97
97
  /**
98
- * Convert a single Chanl tool to OpenAI function format
98
+ * Convert a single Protobox tool to OpenAI function format
99
99
  */
100
100
  private convertToolToOpenAI;
101
101
  /**
@@ -1,17 +1,17 @@
1
1
  "use strict";
2
2
  /**
3
- * OpenAI Adapter for @chanl/sdk
3
+ * OpenAI Adapter for @protoboxai/sdk
4
4
  *
5
5
  * TDD Phase: GREEN - Implementation to make tests pass
6
6
  *
7
7
  * Provides integration with OpenAI's function calling format:
8
- * 1. Convert Chanl tools to OpenAI ChatCompletionTool format
8
+ * 1. Convert Protobox tools to OpenAI ChatCompletionTool format
9
9
  * 2. Execute tool calls from OpenAI responses
10
10
  */
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.OpenAIAdapter = void 0;
13
13
  /**
14
- * Adapter to integrate Chanl tools with OpenAI's function calling
14
+ * Adapter to integrate Protobox tools with OpenAI's function calling
15
15
  *
16
16
  * @example
17
17
  * ```typescript
@@ -42,7 +42,7 @@ class OpenAIAdapter {
42
42
  this.toolsCache = new Map();
43
43
  }
44
44
  /**
45
- * Convert Chanl tools to OpenAI function calling format
45
+ * Convert Protobox tools to OpenAI function calling format
46
46
  *
47
47
  * @param options - Optional filters for which tools to include
48
48
  * @returns Array of OpenAI ChatCompletionTool objects
@@ -55,15 +55,15 @@ class OpenAIAdapter {
55
55
  filters.tag = options.tag;
56
56
  }
57
57
  const response = await this.sdk.tools.list(filters);
58
- if (!response.success || !response.data?.tools) {
58
+ if (!response.success || !response.data?.items) {
59
59
  return [];
60
60
  }
61
61
  // Cache tools for later execution
62
62
  this.toolsCache.clear();
63
- for (const tool of response.data.tools) {
63
+ for (const tool of response.data.items) {
64
64
  this.toolsCache.set(tool.name, tool);
65
65
  }
66
- return response.data.tools.map((tool) => this.convertToolToOpenAI(tool));
66
+ return response.data.items.map((tool) => this.convertToolToOpenAI(tool));
67
67
  }
68
68
  /**
69
69
  * Execute tool calls from an OpenAI response
@@ -87,7 +87,7 @@ class OpenAIAdapter {
87
87
  return results;
88
88
  }
89
89
  /**
90
- * Convert a single Chanl tool to OpenAI function format
90
+ * Convert a single Protobox tool to OpenAI function format
91
91
  */
92
92
  convertToolToOpenAI(tool) {
93
93
  return {
package/dist/client.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ChanlConfig, RequestConfig, ApiResponse } from "./types/config";
1
+ import { ProtoboxConfig, RequestConfig, ApiResponse } from "./types/config";
2
2
  import { WorkspaceModule } from "./modules/workspace";
3
3
  import { AuthModule } from "./modules/auth";
4
4
  import { HealthModule } from "./modules/health";
@@ -8,7 +8,7 @@ import { ToolsetsModule } from "./modules/toolsets";
8
8
  import { McpModule } from "./modules/mcp";
9
9
  import { KnowledgeModule } from "./modules/knowledge";
10
10
  import { ChatModule } from "./modules/chat";
11
- export declare class ChanlSDK {
11
+ export declare class ProtoboxSDK {
12
12
  private config;
13
13
  readonly workspace: WorkspaceModule;
14
14
  readonly auth: AuthModule;
@@ -19,7 +19,7 @@ export declare class ChanlSDK {
19
19
  readonly mcp: McpModule;
20
20
  readonly knowledge: KnowledgeModule;
21
21
  readonly chat: ChatModule;
22
- constructor(config: ChanlConfig);
22
+ constructor(config: ProtoboxConfig);
23
23
  /**
24
24
  * Make a request to the API
25
25
  */
@@ -41,6 +41,21 @@ export declare class ChanlSDK {
41
41
  * Skips if id already exists to avoid overwriting.
42
42
  */
43
43
  private normalizeIds;
44
+ /**
45
+ * Collapse any list-shaped response into the canonical { items, total, pagination }.
46
+ *
47
+ * The platform API is internally inconsistent about PAGINATED list envelopes
48
+ * (`/tools` → { tools, total }, `/toolsets` → { items, pagination },
49
+ * executions → { executions, total, pagination }). This collapses all of them
50
+ * to ONE shape so the CLI/SDK never branch per endpoint.
51
+ *
52
+ * SCOPE: only objects with a recognized collection array AND a `total`/`pagination`
53
+ * sibling qualify. Bare arrays (workspaces, api keys, prompt versions, kb chunks)
54
+ * are left as-is — those endpoints are already uniform and have consumers that
55
+ * iterate the array directly. Single entities that merely contain an array
56
+ * (e.g. a toolset's `tools`) lack the total/pagination sibling, so they pass through.
57
+ */
58
+ private canonicalizeListData;
44
59
  /**
45
60
  * Update authentication credentials
46
61
  */
@@ -51,7 +66,7 @@ export declare class ChanlSDK {
51
66
  /**
52
67
  * Get current configuration
53
68
  */
54
- getConfig(): ChanlConfig;
69
+ getConfig(): ProtoboxConfig;
55
70
  /**
56
71
  * Enable/disable debug logging
57
72
  */
package/dist/client.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ChanlSDK = void 0;
3
+ exports.ProtoboxSDK = void 0;
4
4
  const workspace_1 = require("./modules/workspace");
5
5
  const auth_1 = require("./modules/auth");
6
6
  const health_1 = require("./modules/health");
@@ -10,13 +10,13 @@ const toolsets_1 = require("./modules/toolsets");
10
10
  const mcp_1 = require("./modules/mcp");
11
11
  const knowledge_1 = require("./modules/knowledge");
12
12
  const chat_1 = require("./modules/chat");
13
- class ChanlSDK {
13
+ class ProtoboxSDK {
14
14
  constructor(config) {
15
15
  const server = config.server;
16
16
  const baseUrl = config.baseUrl ||
17
17
  (typeof server === 'string' && server.length > 0 ? server : '');
18
18
  if (!baseUrl) {
19
- throw new Error('ChanlSDK: baseUrl or server is required');
19
+ throw new Error('ProtoboxSDK: baseUrl or server is required');
20
20
  }
21
21
  this.config = {
22
22
  timeout: 30000,
@@ -189,6 +189,12 @@ class ChanlSDK {
189
189
  }
190
190
  }
191
191
  }
192
+ // Canonicalize list envelopes LAST so EVERY list endpoint returns the same
193
+ // { items, total, pagination } shape regardless of what the API called the
194
+ // collection ({ tools, total } / { items, pagination } / a bare array / …).
195
+ if (normalized.data !== undefined) {
196
+ normalized.data = this.canonicalizeListData(normalized.data);
197
+ }
192
198
  return normalized;
193
199
  }
194
200
  catch (error) {
@@ -277,6 +283,59 @@ class ChanlSDK {
277
283
  }
278
284
  return result;
279
285
  }
286
+ /**
287
+ * Collapse any list-shaped response into the canonical { items, total, pagination }.
288
+ *
289
+ * The platform API is internally inconsistent about PAGINATED list envelopes
290
+ * (`/tools` → { tools, total }, `/toolsets` → { items, pagination },
291
+ * executions → { executions, total, pagination }). This collapses all of them
292
+ * to ONE shape so the CLI/SDK never branch per endpoint.
293
+ *
294
+ * SCOPE: only objects with a recognized collection array AND a `total`/`pagination`
295
+ * sibling qualify. Bare arrays (workspaces, api keys, prompt versions, kb chunks)
296
+ * are left as-is — those endpoints are already uniform and have consumers that
297
+ * iterate the array directly. Single entities that merely contain an array
298
+ * (e.g. a toolset's `tools`) lack the total/pagination sibling, so they pass through.
299
+ */
300
+ canonicalizeListData(data) {
301
+ if (data === null || typeof data !== 'object' || Array.isArray(data))
302
+ return data;
303
+ const COLLECTION_KEYS = [
304
+ 'items', 'data', 'tools', 'toolsets', 'executions',
305
+ 'prompts', 'documents', 'workspaces', 'results', 'knowledge',
306
+ ];
307
+ const buildMeta = (total, page, limit) => {
308
+ const safeLimit = limit > 0 ? limit : (total || 1);
309
+ const totalPages = safeLimit > 0 ? Math.max(1, Math.ceil(total / safeLimit)) : 1;
310
+ return {
311
+ page,
312
+ limit: safeLimit,
313
+ total,
314
+ totalPages,
315
+ hasNext: page < totalPages,
316
+ hasPrev: page > 1,
317
+ };
318
+ };
319
+ const obj = data;
320
+ const arrayKey = COLLECTION_KEYS.find((k) => Array.isArray(obj[k]));
321
+ const pag = (obj['pagination'] && typeof obj['pagination'] === 'object')
322
+ ? obj['pagination']
323
+ : undefined;
324
+ const hasTotal = typeof obj['total'] === 'number';
325
+ // Require a collection array PLUS a total/pagination sibling to qualify as a list.
326
+ if (!arrayKey || (!hasTotal && !pag))
327
+ return data;
328
+ const items = obj[arrayKey];
329
+ const total = (hasTotal ? obj['total'] : undefined)
330
+ ?? (typeof pag?.['total'] === 'number' ? pag['total'] : undefined)
331
+ ?? items.length;
332
+ const page = typeof pag?.['page'] === 'number' ? pag['page'] : 1;
333
+ const limit = typeof pag?.['limit'] === 'number' ? pag['limit'] : (items.length || total || 1);
334
+ const base = buildMeta(total, page, limit);
335
+ // Keep any explicit pagination fields the API provided; force total consistent.
336
+ const pagination = pag ? { ...base, ...pag, total } : base;
337
+ return { items, total, pagination };
338
+ }
280
339
  /**
281
340
  * Update authentication credentials
282
341
  */
@@ -303,5 +362,5 @@ class ChanlSDK {
303
362
  this.config.debug = enabled;
304
363
  }
305
364
  }
306
- exports.ChanlSDK = ChanlSDK;
365
+ exports.ProtoboxSDK = ProtoboxSDK;
307
366
  //# sourceMappingURL=client.js.map
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Custom Error Classes for @chanl/sdk
2
+ * Custom Error Classes for @protoboxai/sdk
3
3
  *
4
4
  * TDD Phase: RED - These errors define the error handling contract
5
5
  *
@@ -9,10 +9,10 @@
9
9
  * - Serializable details: Allow JSON serialization for logging
10
10
  */
11
11
  /**
12
- * Options type for ChanlError constructor
12
+ * Options type for ProtoboxError constructor
13
13
  * Uses explicit `| undefined` to be compatible with exactOptionalPropertyTypes
14
14
  */
15
- interface ChanlErrorOptions {
15
+ interface ProtoboxErrorOptions {
16
16
  code?: string | undefined;
17
17
  statusCode?: number | undefined;
18
18
  details?: Record<string, unknown> | undefined;
@@ -20,9 +20,9 @@ interface ChanlErrorOptions {
20
20
  requestId?: string | undefined;
21
21
  }
22
22
  /**
23
- * Base error class for all Chanl SDK errors
23
+ * Base error class for all Protobox SDK errors
24
24
  */
25
- export declare class ChanlError extends Error {
25
+ export declare class ProtoboxError extends Error {
26
26
  /** Error code for programmatic handling */
27
27
  readonly code: string;
28
28
  /** HTTP status code if from API response */
@@ -33,7 +33,7 @@ export declare class ChanlError extends Error {
33
33
  readonly cause?: Error;
34
34
  /** Request ID from API for tracing */
35
35
  readonly requestId?: string;
36
- constructor(message: string, options?: ChanlErrorOptions);
36
+ constructor(message: string, options?: ProtoboxErrorOptions);
37
37
  /**
38
38
  * Convert error to JSON for logging/serialization
39
39
  */
@@ -42,7 +42,7 @@ export declare class ChanlError extends Error {
42
42
  /**
43
43
  * Error thrown when a requested resource is not found (404)
44
44
  */
45
- export declare class NotFoundError extends ChanlError {
45
+ export declare class NotFoundError extends ProtoboxError {
46
46
  /** The type of resource that was not found */
47
47
  readonly resourceType: string;
48
48
  /** The identifier that was used to look up the resource */
@@ -55,7 +55,7 @@ export declare class NotFoundError extends ChanlError {
55
55
  /**
56
56
  * Error thrown when input validation fails (400)
57
57
  */
58
- export declare class ValidationError extends ChanlError {
58
+ export declare class ValidationError extends ProtoboxError {
59
59
  /** Field-level validation errors */
60
60
  readonly fieldErrors?: Record<string, string[]>;
61
61
  constructor(message: string, options?: {
@@ -75,7 +75,7 @@ export declare class ValidationError extends ChanlError {
75
75
  /**
76
76
  * Error thrown when authentication fails (401)
77
77
  */
78
- export declare class AuthenticationError extends ChanlError {
78
+ export declare class AuthenticationError extends ProtoboxError {
79
79
  constructor(message?: string, options?: {
80
80
  details?: Record<string, unknown> | undefined;
81
81
  requestId?: string | undefined;
@@ -84,7 +84,7 @@ export declare class AuthenticationError extends ChanlError {
84
84
  /**
85
85
  * Error thrown when authorization fails (403)
86
86
  */
87
- export declare class AuthorizationError extends ChanlError {
87
+ export declare class AuthorizationError extends ProtoboxError {
88
88
  /** The action that was attempted */
89
89
  readonly action?: string;
90
90
  /** The resource that was being accessed */
@@ -99,7 +99,7 @@ export declare class AuthorizationError extends ChanlError {
99
99
  /**
100
100
  * Error thrown when there's a conflict (409)
101
101
  */
102
- export declare class ConflictError extends ChanlError {
102
+ export declare class ConflictError extends ProtoboxError {
103
103
  /** The conflicting resource identifier */
104
104
  readonly conflictingResource?: string;
105
105
  constructor(message: string, options?: {
@@ -111,7 +111,7 @@ export declare class ConflictError extends ChanlError {
111
111
  /**
112
112
  * Error thrown when rate limit is exceeded (429)
113
113
  */
114
- export declare class RateLimitError extends ChanlError {
114
+ export declare class RateLimitError extends ProtoboxError {
115
115
  /** When the rate limit resets (Unix timestamp) */
116
116
  readonly retryAfter?: number;
117
117
  constructor(message?: string, options?: {
@@ -123,7 +123,7 @@ export declare class RateLimitError extends ChanlError {
123
123
  /**
124
124
  * Error thrown when API server fails (5xx)
125
125
  */
126
- export declare class ServerError extends ChanlError {
126
+ export declare class ServerError extends ProtoboxError {
127
127
  constructor(message?: string, options?: {
128
128
  statusCode?: number | undefined;
129
129
  details?: Record<string, unknown> | undefined;
@@ -133,7 +133,7 @@ export declare class ServerError extends ChanlError {
133
133
  /**
134
134
  * Error thrown for network/connection issues
135
135
  */
136
- export declare class NetworkError extends ChanlError {
136
+ export declare class NetworkError extends ProtoboxError {
137
137
  constructor(message?: string, options?: {
138
138
  cause?: Error | undefined;
139
139
  details?: Record<string, unknown> | undefined;
@@ -142,7 +142,7 @@ export declare class NetworkError extends ChanlError {
142
142
  /**
143
143
  * Error thrown when request times out
144
144
  */
145
- export declare class TimeoutError extends ChanlError {
145
+ export declare class TimeoutError extends ProtoboxError {
146
146
  /** Timeout duration in milliseconds */
147
147
  readonly timeoutMs?: number;
148
148
  constructor(message?: string, options?: {
@@ -152,9 +152,9 @@ export declare class TimeoutError extends ChanlError {
152
152
  });
153
153
  }
154
154
  /**
155
- * Type guard to check if error is a ChanlError
155
+ * Type guard to check if error is a ProtoboxError
156
156
  */
157
- export declare function isChanlError(error: unknown): error is ChanlError;
157
+ export declare function isProtoboxError(error: unknown): error is ProtoboxError;
158
158
  /**
159
159
  * Type guard to check if error is a NotFoundError
160
160
  */
@@ -174,6 +174,6 @@ export declare function createErrorFromResponse(statusCode: number, message: str
174
174
  details?: Record<string, unknown> | undefined;
175
175
  requestId?: string | undefined;
176
176
  fieldErrors?: Record<string, string[]> | undefined;
177
- }): ChanlError;
177
+ }): ProtoboxError;
178
178
  export {};
179
179
  //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * Custom Error Classes for @chanl/sdk
3
+ * Custom Error Classes for @protoboxai/sdk
4
4
  *
5
5
  * TDD Phase: RED - These errors define the error handling contract
6
6
  *
@@ -10,20 +10,20 @@
10
10
  * - Serializable details: Allow JSON serialization for logging
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.TimeoutError = exports.NetworkError = exports.ServerError = exports.RateLimitError = exports.ConflictError = exports.AuthorizationError = exports.AuthenticationError = exports.ValidationError = exports.NotFoundError = exports.ChanlError = void 0;
14
- exports.isChanlError = isChanlError;
13
+ exports.TimeoutError = exports.NetworkError = exports.ServerError = exports.RateLimitError = exports.ConflictError = exports.AuthorizationError = exports.AuthenticationError = exports.ValidationError = exports.NotFoundError = exports.ProtoboxError = void 0;
14
+ exports.isProtoboxError = isProtoboxError;
15
15
  exports.isNotFoundError = isNotFoundError;
16
16
  exports.isValidationError = isValidationError;
17
17
  exports.isAuthenticationError = isAuthenticationError;
18
18
  exports.createErrorFromResponse = createErrorFromResponse;
19
19
  /**
20
- * Base error class for all Chanl SDK errors
20
+ * Base error class for all Protobox SDK errors
21
21
  */
22
- class ChanlError extends Error {
22
+ class ProtoboxError extends Error {
23
23
  constructor(message, options = {}) {
24
24
  super(message);
25
- this.name = 'ChanlError';
26
- this.code = options.code ?? 'CHANL_ERROR';
25
+ this.name = 'ProtoboxError';
26
+ this.code = options.code ?? 'PROTOBOX_ERROR';
27
27
  // Only assign optional properties when defined (exactOptionalPropertyTypes)
28
28
  if (options.statusCode !== undefined) {
29
29
  this.statusCode = options.statusCode;
@@ -57,11 +57,11 @@ class ChanlError extends Error {
57
57
  };
58
58
  }
59
59
  }
60
- exports.ChanlError = ChanlError;
60
+ exports.ProtoboxError = ProtoboxError;
61
61
  /**
62
62
  * Error thrown when a requested resource is not found (404)
63
63
  */
64
- class NotFoundError extends ChanlError {
64
+ class NotFoundError extends ProtoboxError {
65
65
  constructor(resourceType, resourceId, options = {}) {
66
66
  const details = {
67
67
  resourceType,
@@ -83,7 +83,7 @@ exports.NotFoundError = NotFoundError;
83
83
  /**
84
84
  * Error thrown when input validation fails (400)
85
85
  */
86
- class ValidationError extends ChanlError {
86
+ class ValidationError extends ProtoboxError {
87
87
  constructor(message, options = {}) {
88
88
  const details = {
89
89
  ...options.details,
@@ -119,7 +119,7 @@ exports.ValidationError = ValidationError;
119
119
  /**
120
120
  * Error thrown when authentication fails (401)
121
121
  */
122
- class AuthenticationError extends ChanlError {
122
+ class AuthenticationError extends ProtoboxError {
123
123
  constructor(message = 'Authentication required', options = {}) {
124
124
  super(message, {
125
125
  code: 'AUTHENTICATION_ERROR',
@@ -134,7 +134,7 @@ exports.AuthenticationError = AuthenticationError;
134
134
  /**
135
135
  * Error thrown when authorization fails (403)
136
136
  */
137
- class AuthorizationError extends ChanlError {
137
+ class AuthorizationError extends ProtoboxError {
138
138
  constructor(message = 'Permission denied', options = {}) {
139
139
  const details = {
140
140
  ...options.details,
@@ -164,7 +164,7 @@ exports.AuthorizationError = AuthorizationError;
164
164
  /**
165
165
  * Error thrown when there's a conflict (409)
166
166
  */
167
- class ConflictError extends ChanlError {
167
+ class ConflictError extends ProtoboxError {
168
168
  constructor(message, options = {}) {
169
169
  const details = {
170
170
  ...options.details,
@@ -188,7 +188,7 @@ exports.ConflictError = ConflictError;
188
188
  /**
189
189
  * Error thrown when rate limit is exceeded (429)
190
190
  */
191
- class RateLimitError extends ChanlError {
191
+ class RateLimitError extends ProtoboxError {
192
192
  constructor(message = 'Rate limit exceeded', options = {}) {
193
193
  const details = {
194
194
  ...options.details,
@@ -212,7 +212,7 @@ exports.RateLimitError = RateLimitError;
212
212
  /**
213
213
  * Error thrown when API server fails (5xx)
214
214
  */
215
- class ServerError extends ChanlError {
215
+ class ServerError extends ProtoboxError {
216
216
  constructor(message = 'Internal server error', options = {}) {
217
217
  super(message, {
218
218
  code: 'SERVER_ERROR',
@@ -227,7 +227,7 @@ exports.ServerError = ServerError;
227
227
  /**
228
228
  * Error thrown for network/connection issues
229
229
  */
230
- class NetworkError extends ChanlError {
230
+ class NetworkError extends ProtoboxError {
231
231
  constructor(message = 'Network error', options = {}) {
232
232
  super(message, {
233
233
  code: 'NETWORK_ERROR',
@@ -241,7 +241,7 @@ exports.NetworkError = NetworkError;
241
241
  /**
242
242
  * Error thrown when request times out
243
243
  */
244
- class TimeoutError extends ChanlError {
244
+ class TimeoutError extends ProtoboxError {
245
245
  constructor(message = 'Request timeout', options = {}) {
246
246
  const details = {
247
247
  ...options.details,
@@ -262,10 +262,10 @@ class TimeoutError extends ChanlError {
262
262
  }
263
263
  exports.TimeoutError = TimeoutError;
264
264
  /**
265
- * Type guard to check if error is a ChanlError
265
+ * Type guard to check if error is a ProtoboxError
266
266
  */
267
- function isChanlError(error) {
268
- return error instanceof ChanlError;
267
+ function isProtoboxError(error) {
268
+ return error instanceof ProtoboxError;
269
269
  }
270
270
  /**
271
271
  * Type guard to check if error is a NotFoundError
@@ -298,8 +298,8 @@ function createErrorFromResponse(statusCode, message, options = {}) {
298
298
  return new AuthorizationError(message, options);
299
299
  case 404:
300
300
  // For 404, we need resourceType and resourceId which aren't in options
301
- // Return a generic ChanlError instead
302
- return new ChanlError(message, {
301
+ // Return a generic ProtoboxError instead
302
+ return new ProtoboxError(message, {
303
303
  code: 'NOT_FOUND',
304
304
  statusCode: 404,
305
305
  details: options.details,
@@ -313,7 +313,7 @@ function createErrorFromResponse(statusCode, message, options = {}) {
313
313
  if (statusCode >= 500) {
314
314
  return new ServerError(message, { statusCode, ...options });
315
315
  }
316
- return new ChanlError(message, { statusCode, ...options });
316
+ return new ProtoboxError(message, { statusCode, ...options });
317
317
  }
318
318
  }
319
319
  //# sourceMappingURL=index.js.map
package/dist/index.d.ts CHANGED
@@ -1,5 +1,6 @@
1
- export { ChanlSDK, ChanlSDK as Chanl, ChanlSDK as ProtoboxSDK, ChanlSDK as Protobox } from './client';
2
- export { ChanlConfig, ChanlAuthConfig } from './types/config';
1
+ export { ProtoboxSDK, ProtoboxSDK as Protobox } from './client';
2
+ export { ProtoboxConfig, ProtoboxAuthConfig } from './types/config';
3
+ export type { ApiResponse, ListResult, PaginationMeta, PaginatedResponse } from './types/config';
3
4
  export { WorkspaceModule } from './modules/workspace';
4
5
  export { AuthModule } from './modules/auth';
5
6
  export { HealthModule } from './modules/health';
package/dist/index.js CHANGED
@@ -14,12 +14,10 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.ChatModule = exports.KnowledgeModule = exports.McpModule = exports.ToolsetsModule = exports.ToolsModule = exports.PromptsModule = exports.HealthModule = exports.AuthModule = exports.WorkspaceModule = exports.Protobox = exports.ProtoboxSDK = exports.Chanl = exports.ChanlSDK = void 0;
17
+ exports.ChatModule = exports.KnowledgeModule = exports.McpModule = exports.ToolsetsModule = exports.ToolsModule = exports.PromptsModule = exports.HealthModule = exports.AuthModule = exports.WorkspaceModule = exports.Protobox = exports.ProtoboxSDK = void 0;
18
18
  var client_1 = require("./client");
19
- Object.defineProperty(exports, "ChanlSDK", { enumerable: true, get: function () { return client_1.ChanlSDK; } });
20
- Object.defineProperty(exports, "Chanl", { enumerable: true, get: function () { return client_1.ChanlSDK; } });
21
- Object.defineProperty(exports, "ProtoboxSDK", { enumerable: true, get: function () { return client_1.ChanlSDK; } });
22
- Object.defineProperty(exports, "Protobox", { enumerable: true, get: function () { return client_1.ChanlSDK; } });
19
+ Object.defineProperty(exports, "ProtoboxSDK", { enumerable: true, get: function () { return client_1.ProtoboxSDK; } });
20
+ Object.defineProperty(exports, "Protobox", { enumerable: true, get: function () { return client_1.ProtoboxSDK; } });
23
21
  var workspace_1 = require("./modules/workspace");
24
22
  Object.defineProperty(exports, "WorkspaceModule", { enumerable: true, get: function () { return workspace_1.WorkspaceModule; } });
25
23
  var auth_1 = require("./modules/auth");
@@ -1,5 +1,5 @@
1
1
  import { TypedEventEmitter } from './typed-emitter';
2
- import type { ChanlSDK } from '../client';
2
+ import type { ProtoboxSDK } from '../client';
3
3
  import type { ChatSessionResponse, ChatMessageResponse } from '../modules/chat';
4
4
  export type LiveChatEvents = {
5
5
  'message': (message: ChatMessageResponse) => void;
@@ -50,7 +50,7 @@ export declare class LiveChat extends TypedEventEmitter<LiveChatEvents> {
50
50
  private sdk;
51
51
  readonly sessionId: string;
52
52
  readonly agentName: string | undefined;
53
- constructor(sdk: ChanlSDK, sessionData: ChatSessionResponse);
53
+ constructor(sdk: ProtoboxSDK, sessionData: ChatSessionResponse);
54
54
  /**
55
55
  * Send a message and receive the agent's response.
56
56
  *
@@ -1,4 +1,4 @@
1
- import { ChanlSDK } from '../client';
1
+ import { ProtoboxSDK } from '../client';
2
2
  import { ApiResponse } from '../types/config';
3
3
  export interface ApiKey {
4
4
  id: string;
@@ -34,7 +34,7 @@ export interface AuthTokenResponse {
34
34
  }
35
35
  export declare class AuthModule {
36
36
  private sdk;
37
- constructor(sdk: ChanlSDK);
37
+ constructor(sdk: ProtoboxSDK);
38
38
  /**
39
39
  * Exchange a Firebase ID token for platform JWT tokens.
40
40
  * Used by CLI browser login flow.
@@ -6,7 +6,7 @@
6
6
  * the platform owns the full lifecycle (interaction, transcript,
7
7
  * billing, evaluation) so the SDK only deals with sessions and messages.
8
8
  */
9
- import { ChanlSDK } from '../client';
9
+ import { ProtoboxSDK } from '../client';
10
10
  import { ApiResponse } from '../types/config';
11
11
  import { ToolCall } from '../types/tool-calls';
12
12
  export interface CreateChatSessionInput {
@@ -62,7 +62,7 @@ export interface DeleteChatResponse {
62
62
  import { LiveChat } from '../live/live-chat';
63
63
  export declare class ChatModule {
64
64
  private sdk;
65
- constructor(sdk: ChanlSDK);
65
+ constructor(sdk: ProtoboxSDK);
66
66
  /**
67
67
  * Create a new chat session with an agent
68
68
  *
@@ -1,4 +1,4 @@
1
- import { ChanlSDK } from '../client';
1
+ import { ProtoboxSDK } from '../client';
2
2
  import { ApiResponse } from '../types/config';
3
3
  export interface HealthStatus {
4
4
  status: 'healthy' | 'unhealthy' | 'ok';
@@ -32,7 +32,7 @@ export interface DetailedHealthStatus {
32
32
  }
33
33
  export declare class HealthModule {
34
34
  private sdk;
35
- constructor(sdk: ChanlSDK);
35
+ constructor(sdk: ProtoboxSDK);
36
36
  /**
37
37
  * Get basic health status
38
38
  */
@@ -1,4 +1,4 @@
1
- import { ChanlSDK } from "../client";
1
+ import { ProtoboxSDK } from "../client";
2
2
  import { ApiResponse } from "../types/config";
3
3
  export type KnowledgeSource = "text" | "url" | "file" | "manual" | "document" | "faq" | "api_docs" | "transcript";
4
4
  export type ProcessingStatus = "pending" | "processing" | "completed" | "failed";
@@ -150,7 +150,7 @@ export interface ProcessingTaskResponse {
150
150
  }
151
151
  export declare class KnowledgeModule {
152
152
  private sdk;
153
- constructor(sdk: ChanlSDK);
153
+ constructor(sdk: ProtoboxSDK);
154
154
  /**
155
155
  * List all knowledge entries with optional filters
156
156
  */
@@ -4,7 +4,7 @@
4
4
  * Provides access to MCP server configuration and health status.
5
5
  * Used by CLI and admin UI to get ready-to-use agent configurations.
6
6
  */
7
- import { ChanlSDK } from '../client';
7
+ import { ProtoboxSDK } from '../client';
8
8
  import { ApiResponse } from '../types/config';
9
9
  export interface AgentConfig {
10
10
  url: string;
@@ -14,12 +14,12 @@ export interface AgentConfig {
14
14
  export interface AgentConfigs {
15
15
  claude: {
16
16
  mcpServers: {
17
- chanl: AgentConfig;
17
+ protobox: AgentConfig;
18
18
  };
19
19
  };
20
20
  cursor: {
21
21
  mcpServers: {
22
- chanl: AgentConfig;
22
+ protobox: AgentConfig;
23
23
  };
24
24
  };
25
25
  generic: AgentConfig;
@@ -59,7 +59,7 @@ export interface McpToolCallResult {
59
59
  }
60
60
  export declare class McpModule {
61
61
  private sdk;
62
- constructor(sdk: ChanlSDK);
62
+ constructor(sdk: ProtoboxSDK);
63
63
  /**
64
64
  * Get MCP configuration for a workspace
65
65
  *
@@ -33,7 +33,20 @@ class McpModule {
33
33
  }
34
34
  const queryString = queryParams.toString();
35
35
  const url = '/api/v1/mcp/config' + (queryString ? '?' + queryString : '');
36
- return this.sdk.request('GET', url);
36
+ const res = await this.sdk.request('GET', url);
37
+ // The backend keys the MCP server entry as `chanl` (legacy contract). Present
38
+ // it as `protobox` so consumer configs (Claude/Cursor) aren't off-brand and
39
+ // the runtime matches the AgentConfigs type.
40
+ if (res.success && res.data?.agentConfigs) {
41
+ for (const client of ['claude', 'cursor']) {
42
+ const servers = res.data.agentConfigs[client]?.mcpServers;
43
+ if (servers && 'chanl' in servers && !('protobox' in servers)) {
44
+ servers['protobox'] = servers['chanl'];
45
+ delete servers['chanl'];
46
+ }
47
+ }
48
+ }
49
+ return res;
37
50
  }
38
51
  /**
39
52
  * Check MCP server health status
@@ -1,4 +1,4 @@
1
- import { ChanlSDK } from "../client";
1
+ import { ProtoboxSDK } from "../client";
2
2
  import { ApiResponse } from "../types/config";
3
3
  export interface PromptVariable {
4
4
  name: string;
@@ -37,7 +37,12 @@ export interface PromptVersion {
37
37
  content: string;
38
38
  variables?: PromptVariable[];
39
39
  notes?: string;
40
- isActive: boolean;
40
+ /**
41
+ * Whether this is the prompt's active version. Optional: the API tracks the
42
+ * active version via `Prompt.currentVersion`, so this may be absent — compare
43
+ * `version` to the prompt's `currentVersion` when it is not present.
44
+ */
45
+ isActive?: boolean;
41
46
  author?: string;
42
47
  createdAt: string;
43
48
  updatedAt?: string;
@@ -83,7 +88,7 @@ export interface PromptFilters {
83
88
  }
84
89
  export declare class PromptsModule {
85
90
  private sdk;
86
- constructor(sdk: ChanlSDK);
91
+ constructor(sdk: ProtoboxSDK);
87
92
  /**
88
93
  * List all prompts with optional filters
89
94
  */
@@ -6,12 +6,12 @@
6
6
  * Provides CRUD operations for tools and execution capabilities.
7
7
  * Supports both JWT auth (admin UI) and MCP API key auth.
8
8
  */
9
- import { ChanlSDK } from '../client';
9
+ import { ProtoboxSDK } from '../client';
10
10
  import { ApiResponse } from '../types/config';
11
11
  import type { Tool, ExecuteResult, CreateToolInput, UpdateToolInput, ToolFilters, ExecutionFilters, ToolListResponse, ToolDeleteResponse, ExecutionListResponse, ToolCategoriesResponse } from '../types/tools';
12
12
  export declare class ToolsModule {
13
13
  private sdk;
14
- constructor(sdk: ChanlSDK);
14
+ constructor(sdk: ProtoboxSDK);
15
15
  /**
16
16
  * List all tools with optional filters
17
17
  *
@@ -31,7 +31,7 @@ export declare class ToolsModule {
31
31
  * limit: 10
32
32
  * });
33
33
  *
34
- * // Exclude system tools (kb_search, chanl_reason, etc.)
34
+ * // Exclude system tools (e.g. kb_search)
35
35
  * const { data } = await sdk.tools.list({
36
36
  * includeSystem: false
37
37
  * });
@@ -35,7 +35,7 @@ class ToolsModule {
35
35
  * limit: 10
36
36
  * });
37
37
  *
38
- * // Exclude system tools (kb_search, chanl_reason, etc.)
38
+ * // Exclude system tools (e.g. kb_search)
39
39
  * const { data } = await sdk.tools.list({
40
40
  * includeSystem: false
41
41
  * });
@@ -4,12 +4,12 @@
4
4
  * Provides CRUD operations for toolsets (collections of tools).
5
5
  * Supports both JWT auth (admin UI) and API key auth.
6
6
  */
7
- import { ChanlSDK } from '../client';
7
+ import { ProtoboxSDK } from '../client';
8
8
  import { ApiResponse } from '../types/config';
9
9
  import type { CreateToolsetInput, UpdateToolsetInput, ToolsetFilters, ToolsetListResponse, ToolsetResponse, ToolsetDeleteResponse, ManageToolsInput, ToolOverride } from '../types/toolsets';
10
10
  export declare class ToolsetsModule {
11
11
  private sdk;
12
- constructor(sdk: ChanlSDK);
12
+ constructor(sdk: ProtoboxSDK);
13
13
  /**
14
14
  * List all toolsets with optional filters
15
15
  *
@@ -1,4 +1,4 @@
1
- import { ChanlSDK } from "../client";
1
+ import { ProtoboxSDK } from "../client";
2
2
  import { ApiResponse } from "../types/config";
3
3
  export type WorkspaceSettings = Record<string, unknown>;
4
4
  export interface Workspace {
@@ -11,7 +11,7 @@ export interface Workspace {
11
11
  }
12
12
  export declare class WorkspaceModule {
13
13
  private sdk;
14
- constructor(sdk: ChanlSDK);
14
+ constructor(sdk: ProtoboxSDK);
15
15
  /**
16
16
  * Create a new workspace
17
17
  */
@@ -1,5 +1,5 @@
1
- export interface ChanlConfig {
2
- /** API base URL (e.g., 'https://api.chanl.ai' or 'http://localhost:18005') */
1
+ export interface ProtoboxConfig {
2
+ /** API base URL (e.g., 'https://api.protobox.app' or 'http://localhost:18005') */
3
3
  baseUrl: string;
4
4
  /** Same as baseUrl — supported for tooling that uses `server` (e.g. local eval). */
5
5
  server?: string;
@@ -31,7 +31,7 @@ export interface ChanlConfig {
31
31
  backoffMultiplier: number;
32
32
  };
33
33
  }
34
- export interface ChanlAuthConfig {
34
+ export interface ProtoboxAuthConfig {
35
35
  /** API key for authentication */
36
36
  apiKey?: string;
37
37
  /** JWT token for authentication */
@@ -68,6 +68,31 @@ export interface PaginatedResponse<T = unknown> {
68
68
  message: string;
69
69
  timestamp: string;
70
70
  }
71
+ /** Pagination metadata attached to every list response. */
72
+ export interface PaginationMeta {
73
+ page: number;
74
+ limit: number;
75
+ total: number;
76
+ totalPages: number;
77
+ hasNext: boolean;
78
+ hasPrev: boolean;
79
+ }
80
+ /**
81
+ * Canonical shape of `response.data` for EVERY list endpoint.
82
+ *
83
+ * The platform API is internally inconsistent — `/tools` returns `{ tools, total }`
84
+ * (no pagination), `/toolsets` returns `{ items, pagination }` (no top-level total),
85
+ * executions return `{ executions, ... }`, etc. The SDK client normalizes all of
86
+ * them to this one shape so consumers (and the CLI) never special-case per endpoint.
87
+ */
88
+ export interface ListResult<T = unknown> {
89
+ /** The rows — always here regardless of what the API called the collection. */
90
+ items: T[];
91
+ /** Total matching rows across all pages. */
92
+ total: number;
93
+ /** Always present; synthesized when the API omits it. */
94
+ pagination: PaginationMeta;
95
+ }
71
96
  export interface ApiError {
72
97
  success: false;
73
98
  error: {
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Tool Call Types for @chanl/sdk
2
+ * Tool Call Types for @protoboxai/sdk
3
3
  *
4
4
  * Normalized tool call data returned by Chat, Scenarios, and Calls APIs.
5
5
  */
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * Tool Call Types for @chanl/sdk
3
+ * Tool Call Types for @protoboxai/sdk
4
4
  *
5
5
  * Normalized tool call data returned by Chat, Scenarios, and Calls APIs.
6
6
  */
@@ -1,9 +1,9 @@
1
1
  /**
2
- * Tool Types for @chanl/sdk
2
+ * Tool Types for @protoboxai/sdk
3
3
  *
4
- * TDD Phase: RED - These types define the contract for ToolsModule
5
- * Based on chanl-api/src/tools/ schemas and DTOs
4
+ * Based on the platform agent-service tools schemas and DTOs.
6
5
  */
6
+ import type { ListResult } from './config';
7
7
  export type ToolType = 'http' | 'javascript' | 'code';
8
8
  export type HttpMethod = 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
9
9
  export type ExecutionStatus = 'pending' | 'running' | 'completed' | 'failed' | 'corrected';
@@ -223,19 +223,11 @@ export interface ExecutionFilters {
223
223
  limit?: number;
224
224
  }
225
225
  /**
226
- * Response for listing tools
226
+ * Response for listing tools.
227
+ * Canonical list shape — see {@link ListResult}. The SDK client normalizes the
228
+ * API's `{ tools, total }` into `{ items, total, pagination }`.
227
229
  */
228
- export interface ToolListResponse {
229
- tools: Tool[];
230
- total: number;
231
- pagination: {
232
- page: number;
233
- limit: number;
234
- totalPages: number;
235
- hasNext: boolean;
236
- hasPrev: boolean;
237
- };
238
- }
230
+ export type ToolListResponse = ListResult<Tool>;
239
231
  /**
240
232
  * Response for single tool operations
241
233
  */
@@ -274,21 +266,10 @@ export interface ToolExecutionResponse {
274
266
  execution: ToolExecution;
275
267
  }
276
268
  /**
277
- * Response for listing executions
269
+ * Response for listing executions.
270
+ * Canonical list shape — see {@link ListResult}. `items` holds the executions.
278
271
  */
279
- export interface ExecutionListResponse {
280
- data: ToolExecution[];
281
- total: number;
282
- page: number;
283
- limit: number;
284
- pagination: {
285
- page: number;
286
- limit: number;
287
- totalPages: number;
288
- hasNext: boolean;
289
- hasPrev: boolean;
290
- };
291
- }
272
+ export type ExecutionListResponse = ListResult<ToolExecution>;
292
273
  /**
293
274
  * Tool category (tag) with counts
294
275
  */
@@ -1,9 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
- * Tool Types for @chanl/sdk
3
+ * Tool Types for @protoboxai/sdk
4
4
  *
5
- * TDD Phase: RED - These types define the contract for ToolsModule
6
- * Based on chanl-api/src/tools/ schemas and DTOs
5
+ * Based on the platform agent-service tools schemas and DTOs.
7
6
  */
8
7
  Object.defineProperty(exports, "__esModule", { value: true });
9
8
  //# sourceMappingURL=tools.js.map
@@ -1,8 +1,9 @@
1
1
  /**
2
- * Toolset Types for @chanl/sdk
2
+ * Toolset Types for @protoboxai/sdk
3
3
  *
4
- * Based on chanl-api/src/tools/dto/toolset-*.dto.ts and schemas/toolset.schema.ts
4
+ * Based on the platform agent-service toolset DTOs and schema.
5
5
  */
6
+ import type { ListResult } from './config';
6
7
  /**
7
8
  * Toolset entity representing a collection of MCP tools
8
9
  */
@@ -123,20 +124,11 @@ export interface ToolOverride {
123
124
  /**
124
125
  * Response for listing toolsets
125
126
  */
126
- export interface ToolsetListResponse {
127
- /** Array of toolsets (API may return as 'items' or 'data') */
128
- items?: Toolset[];
129
- data?: Toolset[];
130
- total: number;
131
- pagination?: {
132
- page: number;
133
- limit: number;
134
- total: number;
135
- totalPages: number;
136
- hasNext: boolean;
137
- hasPrev: boolean;
138
- };
139
- }
127
+ /**
128
+ * Canonical list shape see {@link ListResult}. The SDK client normalizes the
129
+ * API's `{ items, pagination }` into `{ items, total, pagination }`.
130
+ */
131
+ export type ToolsetListResponse = ListResult<Toolset>;
140
132
  /**
141
133
  * Response for single toolset operations
142
134
  * Note: API returns toolset directly in data, not nested as { toolset: ... }
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  /**
3
- * Toolset Types for @chanl/sdk
3
+ * Toolset Types for @protoboxai/sdk
4
4
  *
5
- * Based on chanl-api/src/tools/dto/toolset-*.dto.ts and schemas/toolset.schema.ts
5
+ * Based on the platform agent-service toolset DTOs and schema.
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  //# sourceMappingURL=toolsets.js.map
package/package.json CHANGED
@@ -1,20 +1,9 @@
1
1
  {
2
2
  "name": "@protoboxai/sdk",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "TypeScript SDK for Protobox — MCP servers, tools, agents, knowledge resources, prompts, and chat",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
7
- "scripts": {
8
- "build": "tsc",
9
- "dev": "tsc --watch",
10
- "clean": "rimraf dist",
11
- "prebuild": "npm run clean",
12
- "test": "vitest run",
13
- "test:watch": "vitest",
14
- "typecheck": "tsc --noEmit",
15
- "lint": "eslint src/**/*.ts",
16
- "format": "prettier --write src/**/*.ts"
17
- },
18
7
  "keywords": [
19
8
  "protobox",
20
9
  "mcp",
@@ -48,5 +37,16 @@
48
37
  "publishConfig": {
49
38
  "registry": "https://registry.npmjs.org",
50
39
  "access": "public"
40
+ },
41
+ "scripts": {
42
+ "build": "tsc",
43
+ "dev": "tsc --watch",
44
+ "clean": "rimraf dist",
45
+ "prebuild": "npm run clean",
46
+ "test": "vitest run",
47
+ "test:watch": "vitest",
48
+ "typecheck": "tsc --noEmit",
49
+ "lint": "eslint src/**/*.ts",
50
+ "format": "prettier --write src/**/*.ts"
51
51
  }
52
- }
52
+ }