@lightcone-ai/daemon 0.9.5 → 0.9.7

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/chat-bridge.js +23 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lightcone-ai/daemon",
3
- "version": "0.9.5",
3
+ "version": "0.9.7",
4
4
  "type": "module",
5
5
  "main": "src/index.js",
6
6
  "bin": {
@@ -101,15 +101,16 @@ server.tool('read_history', 'Read message history from a team, DM, or thread. Su
101
101
  });
102
102
 
103
103
  // ── search_messages ──────────────────────────────────────────────────────────
104
- server.tool('search_messages', 'Search messages visible to you. Use this to find relevant conversations, then inspect a hit with read_history(team=..., around=messageId).', {
104
+ server.tool('search_messages', 'Search messages within a specific team. You must specify the team. Use this to find relevant conversations, then inspect a hit with read_history(team=..., around=messageId).', {
105
105
  query: z.string().describe('Search query'),
106
- team: z.string().optional().describe('Optional target to scope the search, e.g. "#general", "dm:@richard"'),
106
+ team: z.string().describe('Target team to search within, e.g. "#general", "dm:@richard". Required — you may only search teams you are a member of.'),
107
107
  limit: z.number().optional().describe('Max results (default 10, max 20)'),
108
108
  }, async ({ query, team, limit }) => {
109
109
  const trimmed = query.trim();
110
110
  if (!trimmed) return { content: [{ type: 'text', text: 'Search query cannot be empty.' }] };
111
+ if (!team?.trim()) return { content: [{ type: 'text', text: 'team is required. Specify which team to search, e.g. "#general".' }] };
111
112
  const params = new URLSearchParams({ q: trimmed, limit: String(Math.min(limit ?? 10, 20)) });
112
- if (team) params.set('team', team);
113
+ params.set('team', team);
113
114
  try {
114
115
  const data = await api('GET', `/search?${params}`);
115
116
  if (!data.results || data.results.length === 0)
@@ -293,6 +294,25 @@ server.tool('write_workspace', 'Write a file to the shared team workspace. Use t
293
294
  return { content: [{ type: 'text', text: `Saved to team workspace: ${path}` }] };
294
295
  });
295
296
 
297
+ // ── get_credential ───────────────────────────────────────────────────────────
298
+ server.tool('get_credential',
299
+ 'Retrieve decrypted credential fields for a platform granted to this agent (e.g. XHS_COOKIE for "xhs"). Use when you need to inject credentials into a browser session or external call.',
300
+ {
301
+ platform: z.string().describe('Platform key, e.g. "xhs", "x", "youtube"'),
302
+ },
303
+ async ({ platform }) => {
304
+ try {
305
+ const grants = await api('GET', '/credential-grants');
306
+ const match = grants.find(g => g.platform === platform);
307
+ if (!match) return { content: [{ type: 'text', text: `No credential found for platform "${platform}". Ask the human to connect the account via Settings → 连接外部账号.` }] };
308
+ const fields = Object.entries(match.envVars).map(([k, v]) => `${k}=${v}`).join('\n');
309
+ return { content: [{ type: 'text', text: fields }] };
310
+ } catch (err) {
311
+ return { isError: true, content: [{ type: 'text', text: `Error: ${err.message}` }] };
312
+ }
313
+ }
314
+ );
315
+
296
316
  // ── skill_list ───────────────────────────────────────────────────────────────
297
317
  server.tool('skill_list', 'List all skills available to you (platform + bound). Returns index only (name + description), not full content.', {}, async () => {
298
318
  const skills = await api('GET', `/skills`);