@customclaw/composio 0.0.9 → 0.0.10

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
@@ -96,7 +96,7 @@ may look disconnected.
96
96
  Tips:
97
97
 
98
98
  - Set `defaultUserId` in plugin config for your app's primary identity.
99
- - Use `--user-id` explicitly when checking status/connect/disconnect.
99
+ - Prefer passing `user_id`/`--user-id` explicitly when checking status, connecting, disconnecting, or executing tools.
100
100
  - Use `openclaw composio accounts <toolkit>` to discover which `user_id` owns active connections.
101
101
 
102
102
  ## Updating
package/dist/cli.js CHANGED
@@ -271,9 +271,11 @@ export function registerComposioCli({ program, getClient, config, logger }) {
271
271
  try {
272
272
  const toolkitSlug = toolkit ? normalizeToolkitSlug(toolkit) : undefined;
273
273
  const toolkits = toolkitSlug ? [toolkitSlug] : undefined;
274
+ const currentUserId = options.userId || config.defaultUserId || "default";
274
275
  const statuses = await composioClient.getConnectionStatus(toolkits, options.userId);
275
276
  console.log("\nComposio Connection Status:");
276
277
  console.log("─".repeat(40));
278
+ console.log(` Scope user_id: ${currentUserId}${options.userId ? " (explicit)" : " (default)"}`);
277
279
  if (statuses.length === 0) {
278
280
  console.log(" No connections found");
279
281
  }
@@ -285,7 +287,6 @@ export function registerComposioCli({ program, getClient, config, logger }) {
285
287
  }
286
288
  }
287
289
  if (toolkitSlug && statuses.length === 1 && !statuses[0]?.connected) {
288
- const currentUserId = options.userId || config.defaultUserId || "default";
289
290
  const activeUserIds = await composioClient.findActiveUserIdsForToolkit(toolkitSlug);
290
291
  const otherUserIds = activeUserIds.filter((uid) => uid !== currentUserId);
291
292
  if (otherUserIds.length > 0) {
@@ -87,7 +87,14 @@ export declare function createComposioConnectionsTool(client: ComposioClient, _c
87
87
  text: string;
88
88
  }[];
89
89
  details: {
90
+ hints?: {
91
+ toolkit: string;
92
+ connected_user_ids: string[];
93
+ message: string;
94
+ }[] | undefined;
90
95
  action: string;
96
+ checked_user_id: string | undefined;
97
+ user_id_explicit: boolean;
91
98
  count: number;
92
99
  connections: {
93
100
  toolkit: string;
@@ -13,7 +13,7 @@ export const ComposioManageConnectionsToolSchema = Type.Object({
13
13
  description: "Multiple toolkits to check status for",
14
14
  })),
15
15
  user_id: Type.Optional(Type.String({
16
- description: "User ID for session scoping (uses default if not provided)",
16
+ description: "User ID for session scoping. Strongly recommended to avoid checking the wrong scope.",
17
17
  })),
18
18
  statuses: Type.Optional(Type.Array(Type.String(), {
19
19
  description: "Optional connection statuses filter for 'accounts' (e.g., ['ACTIVE'])",
@@ -34,6 +34,7 @@ export function createComposioConnectionsTool(client, _config) {
34
34
  async execute(_toolCallId, params) {
35
35
  const action = String(params.action || "status");
36
36
  const userId = typeof params.user_id === "string" ? params.user_id : undefined;
37
+ const userIdWasExplicit = typeof params.user_id === "string" && params.user_id.trim().length > 0;
37
38
  try {
38
39
  switch (action) {
39
40
  case "list": {
@@ -119,13 +120,32 @@ export function createComposioConnectionsTool(client, _config) {
119
120
  toolkitsToCheck = params.toolkits.filter((t) => typeof t === "string" && t.trim() !== "");
120
121
  }
121
122
  const statuses = await client.getConnectionStatus(toolkitsToCheck, userId);
123
+ const disconnectedToolkits = statuses.filter((s) => !s.connected).map((s) => s.toolkit);
124
+ const hints = [];
125
+ if (!userIdWasExplicit) {
126
+ for (const toolkit of disconnectedToolkits) {
127
+ const activeUserIds = await client.findActiveUserIdsForToolkit(toolkit);
128
+ if (activeUserIds.length === 0)
129
+ continue;
130
+ hints.push({
131
+ toolkit,
132
+ connected_user_ids: activeUserIds,
133
+ message: `No user_id was provided, so status checked the default scope. ` +
134
+ `'${toolkit}' has ACTIVE accounts under: ${activeUserIds.join(", ")}. ` +
135
+ "Pass user_id explicitly for deterministic results.",
136
+ });
137
+ }
138
+ }
122
139
  const response = {
123
140
  action: "status",
141
+ checked_user_id: statuses[0]?.userId,
142
+ user_id_explicit: userIdWasExplicit,
124
143
  count: statuses.length,
125
144
  connections: statuses.map((s) => ({
126
145
  toolkit: s.toolkit,
127
146
  connected: s.connected,
128
147
  })),
148
+ ...(hints.length > 0 ? { hints } : {}),
129
149
  };
130
150
  return {
131
151
  content: [{ type: "text", text: JSON.stringify(response, null, 2) }],
@@ -10,7 +10,7 @@ export const ComposioExecuteToolSchema = Type.Object({
10
10
  description: "Tool arguments matching the tool's parameter schema",
11
11
  }),
12
12
  user_id: Type.Optional(Type.String({
13
- description: "User ID for session scoping (uses default if not provided)",
13
+ description: "User ID for session scoping. Strongly recommended to avoid executing in the wrong scope.",
14
14
  })),
15
15
  connected_account_id: Type.Optional(Type.String({
16
16
  description: "Optional connected account ID to pin execution to a specific account when multiple are connected",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@customclaw/composio",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "type": "module",
5
5
  "description": "Composio Tool Router plugin for OpenClaw — access 1000+ third-party integrations",
6
6
  "main": "dist/index.js",