@toolplex/client 0.1.6 → 0.1.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.
@@ -2,7 +2,71 @@ import { FileLogger } from "../../shared/fileLogger.js";
2
2
  import { ServerInstallResultSchema, ListToolsResultSchema, } from "../../shared/serverManagerTypes.js";
3
3
  import Registry from "../registry.js";
4
4
  import { RuntimeCheck } from "../utils/runtimeCheck.js";
5
+ import { isAbsolute, parse } from "path";
5
6
  const logger = FileLogger;
7
+ /**
8
+ * Sanitizes ServerConfig for telemetry logging by extracting aggregate patterns
9
+ * while avoiding PII exposure. This function extracts useful installation patterns
10
+ * without logging sensitive data like file paths, API keys, or user-specific values.
11
+ *
12
+ * SECURITY: This function only logs metadata patterns, never actual values:
13
+ * - Command names (not paths): "npx" vs "/Users/john/bin/tool"
14
+ * - Argument flags (not values): "--port" vs actual port numbers
15
+ * - Environment variable names (not values): "API_KEY" vs actual keys
16
+ * - Path types for portability analysis: "absolute" vs "package_manager"
17
+ */
18
+ function sanitizeServerConfig(config) {
19
+ // Extract command executable name without sensitive path information
20
+ const extractCommandType = (command) => {
21
+ if (!command)
22
+ return "none";
23
+ // For absolute paths, extract only the executable name (e.g., "/usr/bin/node" -> "node")
24
+ if (isAbsolute(command)) {
25
+ return parse(command).name;
26
+ }
27
+ // For relative commands, get the base command (e.g., "npx" from "npx --version")
28
+ return (command
29
+ .split(/[\s/\\]/)
30
+ .pop()
31
+ ?.split(".")[0] || "unknown");
32
+ };
33
+ // Categorize path types for portability analysis - helps identify installation reliability patterns
34
+ const detectPathType = (command, args) => {
35
+ if (!command)
36
+ return "system_command";
37
+ // Absolute paths indicate potential portability issues
38
+ if (isAbsolute(command) || args?.some((arg) => isAbsolute(arg))) {
39
+ return "absolute";
40
+ }
41
+ // Package managers are typically more reliable across systems
42
+ if (["npx", "uvx", "pip", "yarn", "pnpm"].includes(command)) {
43
+ return "package_manager";
44
+ }
45
+ return "system_command";
46
+ };
47
+ // Extract common argument flags and patterns (not values) for usage analysis
48
+ const extractArgPatterns = (args) => {
49
+ return (args?.filter((arg) => arg.startsWith("-") || // Command flags like --port, --config
50
+ ["stdio", "mcp", "start", "latest", "@latest"].includes(arg)) || []);
51
+ };
52
+ // Extract environment variable names (not values) to understand integration patterns
53
+ // SAFE: Only logs key names like "API_KEY", "DATABASE_URL" - never the actual values
54
+ const extractEnvKeys = (env) => {
55
+ if (!env)
56
+ return [];
57
+ return Object.keys(env).sort();
58
+ };
59
+ return {
60
+ runtime: config.runtime || "node",
61
+ transport: config.transport,
62
+ command_type: extractCommandType(config.command),
63
+ path_type: detectPathType(config.command, config.args),
64
+ arg_patterns: extractArgPatterns(config.args),
65
+ arg_count: config.args?.length || 0,
66
+ env_keys: extractEnvKeys(config.env),
67
+ env_count: config.env ? Object.keys(config.env).length : 0,
68
+ };
69
+ }
6
70
  async function installServer(serverId, serverName, description, serverManagerClient, serverConfig) {
7
71
  await logger.info(`Starting installation of tool ${serverId}: ${serverName}`);
8
72
  await logger.debug(`Server config: ${JSON.stringify(serverConfig)}, Server ID: ${serverId}`);
@@ -91,6 +155,7 @@ export async function handleInstallServer(params) {
91
155
  success: true,
92
156
  log_context: {
93
157
  server_id: installResult.server_id,
158
+ sanitized_config: sanitizeServerConfig(config),
94
159
  },
95
160
  latency_ms: Date.now() - startTime,
96
161
  });
@@ -20,7 +20,7 @@ export async function handleLookupEntityTool(params) {
20
20
  if (params.entity_type === "server") {
21
21
  policyEnforcer.enforceUseServerPolicy(params.entity_id);
22
22
  }
23
- let lookupResponse = await apiService.lookupEntity(params.entity_type, params.entity_id);
23
+ const lookupResponse = await apiService.lookupEntity(params.entity_type, params.entity_id);
24
24
  // Annotate installed server using resultAnnotators
25
25
  if (params.entity_type === "server" &&
26
26
  lookupResponse &&
@@ -21,8 +21,8 @@ export async function handleSavePlaybook(params) {
21
21
  }
22
22
  // Enforce playbook policy before saving
23
23
  policyEnforcer.enforceSavePlaybookPolicy(params);
24
- const { description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason, } = params;
25
- const response = await apiService.createPlaybook(description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason);
24
+ const { playbook_name, description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason, } = params;
25
+ const response = await apiService.createPlaybook(playbook_name, description, actions, domain, keywords, requirements, privacy, source_playbook_id, fork_reason);
26
26
  await logger.info(`Playbook created successfully with ID: ${response.id}`);
27
27
  await telemetryLogger.log("client_save_playbook", {
28
28
  success: true,
@@ -25,7 +25,7 @@ export declare class ToolplexApiService {
25
25
  mcp_servers?: any[];
26
26
  playbooks?: any[];
27
27
  }>;
28
- createPlaybook(description: string, actions: Array<PlaybookAction>, domain?: string, keywords?: string[], requirements?: string[], privacy?: "public" | "private", sourcePlaybookId?: string, forkReason?: string): Promise<CreatePlaybookResponse>;
28
+ createPlaybook(playbook_name: string, description: string, actions: Array<PlaybookAction>, domain?: string, keywords?: string[], requirements?: string[], privacy?: "public" | "private", sourcePlaybookId?: string, forkReason?: string): Promise<CreatePlaybookResponse>;
29
29
  logPlaybookUsage(playbookId: string, success: boolean, errorMessage?: string): Promise<LogPlaybookUsageResponse>;
30
30
  submitFeedback(targetType: "server" | "playbook", targetId: string, vote: "up" | "down", message?: string, securityAssessment?: SecurityAssessment): Promise<SubmitFeedbackResponse>;
31
31
  getFeedbackSummary(): Promise<FeedbackSummaryResponse>;
@@ -136,8 +136,9 @@ export class ToolplexApiService {
136
136
  throw err;
137
137
  }
138
138
  }
139
- async createPlaybook(description, actions, domain, keywords, requirements, privacy, sourcePlaybookId, forkReason) {
139
+ async createPlaybook(playbook_name, description, actions, domain, keywords, requirements, privacy, sourcePlaybookId, forkReason) {
140
140
  const requestBody = {
141
+ playbook_name,
141
142
  description,
142
143
  actions,
143
144
  llm_context: this.clientContext.llmContext,
@@ -43,6 +43,7 @@ export interface LlmContext {
43
43
  chat_client?: string;
44
44
  }
45
45
  export interface CreatePlaybookRequest {
46
+ playbook_name: string;
46
47
  description: string;
47
48
  actions: Array<{
48
49
  do: string;
@@ -252,6 +252,7 @@ export declare const PlaybookActionSchema: z.ZodObject<{
252
252
  }>;
253
253
  export type PlaybookAction = z.infer<typeof PlaybookActionSchema>;
254
254
  export declare const SavePlaybookParamsSchema: z.ZodObject<{
255
+ playbook_name: z.ZodString;
255
256
  description: z.ZodString;
256
257
  actions: z.ZodEffects<z.ZodArray<z.ZodObject<{
257
258
  do: z.ZodString;
@@ -303,6 +304,7 @@ export declare const SavePlaybookParamsSchema: z.ZodObject<{
303
304
  fork_reason: z.ZodOptional<z.ZodString>;
304
305
  }, "strip", z.ZodTypeAny, {
305
306
  description: string;
307
+ playbook_name: string;
306
308
  actions: {
307
309
  do: string;
308
310
  args?: Record<string, {
@@ -319,6 +321,7 @@ export declare const SavePlaybookParamsSchema: z.ZodObject<{
319
321
  fork_reason?: string | undefined;
320
322
  }, {
321
323
  description: string;
324
+ playbook_name: string;
322
325
  actions: {
323
326
  do: string;
324
327
  args?: Record<string, {
@@ -111,6 +111,7 @@ export const PlaybookActionSchema = z.object({
111
111
  // SavePlaybookParams
112
112
  // --------------------
113
113
  export const SavePlaybookParamsSchema = z.object({
114
+ playbook_name: z.string(),
114
115
  description: z.string(),
115
116
  // Requires at least one action to have a "call" property
116
117
  actions: z
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.1.6";
1
+ export declare const version = "0.1.8";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '0.1.6';
1
+ export const version = '0.1.8';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolplex/client",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "author": "ToolPlex LLC",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "description": "The official ToolPlex client for AI agent tool discovery and execution",