@toolplex/client 0.1.38 → 0.1.40

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.
@@ -14,6 +14,7 @@ export declare class ClientContext {
14
14
  private _flags;
15
15
  private _isOrgUser;
16
16
  private _clientName;
17
+ private _userId;
17
18
  get sessionId(): string;
18
19
  set sessionId(id: string);
19
20
  get dev(): boolean;
@@ -34,5 +35,12 @@ export declare class ClientContext {
34
35
  set flags(consts: ClientFlags);
35
36
  get isOrgUser(): boolean;
36
37
  set isOrgUser(isOrgUser: boolean);
38
+ /**
39
+ * Optional user ID for system API keys to specify user context.
40
+ * Used for per-user telemetry tracking in cloud sessions.
41
+ * Returns null if not set (which is fine for regular client usage).
42
+ */
43
+ get userId(): string | null;
44
+ set userId(id: string | null);
37
45
  isInitialized(): boolean;
38
46
  }
@@ -13,6 +13,7 @@ export class ClientContext {
13
13
  this._flags = null;
14
14
  this._isOrgUser = null;
15
15
  this._clientName = null;
16
+ this._userId = null; // For system keys to specify user context
16
17
  }
17
18
  get sessionId() {
18
19
  if (!this._sessionId) {
@@ -104,6 +105,17 @@ export class ClientContext {
104
105
  set isOrgUser(isOrgUser) {
105
106
  this._isOrgUser = isOrgUser;
106
107
  }
108
+ /**
109
+ * Optional user ID for system API keys to specify user context.
110
+ * Used for per-user telemetry tracking in cloud sessions.
111
+ * Returns null if not set (which is fine for regular client usage).
112
+ */
113
+ get userId() {
114
+ return this._userId;
115
+ }
116
+ set userId(id) {
117
+ this._userId = id;
118
+ }
107
119
  isInitialized() {
108
120
  return !!(this._sessionId &&
109
121
  this._apiKey &&
@@ -9,6 +9,8 @@ const apiKey = process.env.TOOLPLEX_API_KEY;
9
9
  const clientMode = process.env.TOOLPLEX_CLIENT_MODE || "standard";
10
10
  const clientName = process.env.CLIENT_NAME || "unknown";
11
11
  const logLevel = process.env.LOG_LEVEL || "info";
12
+ // Optional user ID for per-user telemetry (system API keys only)
13
+ const userId = process.env.TOOLPLEX_USER_ID;
12
14
  // Read bundled dependency paths from environment variables
13
15
  // These are provided by the host application (e.g., Electron desktop)
14
16
  const bundledDependencies = {
@@ -48,6 +50,7 @@ const config = {
48
50
  logLevel,
49
51
  bundledDependencies,
50
52
  sessionResumeHistory,
53
+ userId,
51
54
  };
52
55
  serve(config).catch(() => {
53
56
  process.exit(1);
@@ -30,7 +30,7 @@ export class ToolplexApiService {
30
30
  return response.json();
31
31
  }
32
32
  getBaseHeaders() {
33
- return {
33
+ const headers = {
34
34
  "Content-Type": "application/json",
35
35
  Accept: "application/json",
36
36
  "x-api-key": this.clientContext.apiKey,
@@ -40,6 +40,12 @@ export class ToolplexApiService {
40
40
  "x-client-platform": os.platform(),
41
41
  "x-client-arch": os.arch(),
42
42
  };
43
+ // For system API keys (cloud-agent), include user ID for per-user telemetry
44
+ const userId = this.clientContext.userId;
45
+ if (userId) {
46
+ headers["x-user-id"] = userId;
47
+ }
48
+ return headers;
43
49
  }
44
50
  getHeadersWithSession() {
45
51
  return {
@@ -33,6 +33,9 @@ export async function serve(config) {
33
33
  clientContext.clientMode = config.clientMode;
34
34
  clientContext.clientName = config.clientName;
35
35
  clientContext.clientVersion = clientVersion;
36
+ if (config.userId) {
37
+ clientContext.userId = config.userId;
38
+ }
36
39
  await Registry.init(clientContext);
37
40
  // Store bundled dependencies in Registry for use throughout the application
38
41
  if (config.bundledDependencies) {
@@ -50,6 +50,9 @@ function extractPrivateRegistryScope(args) {
50
50
  * - username: the scope without @ (e.g., "tp-user-abc123def45")
51
51
  * - password: the ToolPlex API key (tp_live_xxx or tp_test_xxx)
52
52
  *
53
+ * IMPORTANT: We also clear _authToken to override any expired tokens in the
54
+ * user's ~/.npmrc. This ensures our injected basic auth takes precedence.
55
+ *
53
56
  * @param scope - The scope without @ (e.g., "tp-user-abc123def45")
54
57
  * @param apiKey - The ToolPlex API key
55
58
  */
@@ -66,14 +69,24 @@ function getPrivateRegistryEnv(scope, apiKey) {
66
69
  // Set Basic auth for the registry
67
70
  // npm_config_//host/:_auth maps to //host/:_auth in .npmrc
68
71
  "npm_config_//registry.toolplex.ai/:_auth": auth,
72
+ // Clear any existing _authToken from user's ~/.npmrc to prevent expired tokens
73
+ // from taking precedence over our injected basic auth
74
+ "npm_config_//registry.toolplex.ai/:_authToken": "",
69
75
  };
70
76
  }
71
77
  /**
72
78
  * Get additional args to prepend for private registry packages.
73
79
  * Uses --registry flag which is more reliable than env vars with special chars.
80
+ *
81
+ * IMPORTANT: We use --userconfig=/dev/null to completely ignore the user's ~/.npmrc.
82
+ * This prevents expired tokens in ~/.npmrc from interfering with our injected basic auth.
74
83
  */
75
84
  function getPrivateRegistryArgs() {
76
- return [`--registry=${PRIVATE_REGISTRY_URL}`];
85
+ return [
86
+ `--registry=${PRIVATE_REGISTRY_URL}`,
87
+ // Ignore user's ~/.npmrc to prevent expired _authToken from taking precedence
88
+ `--userconfig=/dev/null`,
89
+ ];
77
90
  }
78
91
  export class ServerManager {
79
92
  constructor() {
@@ -38,6 +38,8 @@ export interface ToolplexServerConfig {
38
38
  server_id: string;
39
39
  }>;
40
40
  };
41
+ /** Optional user ID for system API keys to specify user context (per-user telemetry) */
42
+ userId?: string;
41
43
  }
42
44
  export declare const TransportTypeSchema: z.ZodEnum<["stdio", "sse"]>;
43
45
  export type TransportType = z.infer<typeof TransportTypeSchema>;
@@ -13,6 +13,7 @@ export class ClientContext {
13
13
  this._flags = null;
14
14
  this._isOrgUser = null;
15
15
  this._clientName = null;
16
+ this._userId = null; // For system keys to specify user context
16
17
  }
17
18
  get sessionId() {
18
19
  if (!this._sessionId) {
@@ -104,6 +105,17 @@ export class ClientContext {
104
105
  set isOrgUser(isOrgUser) {
105
106
  this._isOrgUser = isOrgUser;
106
107
  }
108
+ /**
109
+ * Optional user ID for system API keys to specify user context.
110
+ * Used for per-user telemetry tracking in cloud sessions.
111
+ * Returns null if not set (which is fine for regular client usage).
112
+ */
113
+ get userId() {
114
+ return this._userId;
115
+ }
116
+ set userId(id) {
117
+ this._userId = id;
118
+ }
107
119
  isInitialized() {
108
120
  return !!(this._sessionId &&
109
121
  this._apiKey &&
@@ -30,7 +30,7 @@ export class ToolplexApiService {
30
30
  return response.json();
31
31
  }
32
32
  getBaseHeaders() {
33
- return {
33
+ const headers = {
34
34
  "Content-Type": "application/json",
35
35
  Accept: "application/json",
36
36
  "x-api-key": this.clientContext.apiKey,
@@ -40,6 +40,12 @@ export class ToolplexApiService {
40
40
  "x-client-platform": os.platform(),
41
41
  "x-client-arch": os.arch(),
42
42
  };
43
+ // For system API keys (cloud-agent), include user ID for per-user telemetry
44
+ const userId = this.clientContext.userId;
45
+ if (userId) {
46
+ headers["x-user-id"] = userId;
47
+ }
48
+ return headers;
43
49
  }
44
50
  getHeadersWithSession() {
45
51
  return {
package/dist/version.d.ts CHANGED
@@ -1 +1 @@
1
- export declare const version = "0.1.38";
1
+ export declare const version = "0.1.40";
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const version = '0.1.38';
1
+ export const version = '0.1.40';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@toolplex/client",
3
- "version": "0.1.38",
3
+ "version": "0.1.40",
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",