pikiclaw 0.2.67 → 0.2.69

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
@@ -22,7 +22,7 @@ npx pikiclaw@latest
22
22
 
23
23
  > Real task: ask pikiclaw to gather and summarize today's AI news — the agent reads, writes, and sends results back through Telegram, all from your phone.
24
24
 
25
- <video src="docs/promo-demo.mp4" width="700" controls muted></video>
25
+ <img src="docs/promo-demo.gif" alt="Demo" width="700">
26
26
 
27
27
  > Basic operations: send a message, watch the agent stream, receive files back.
28
28
 
@@ -222,6 +222,7 @@ Relevant environment variables:
222
222
 
223
223
  ## Roadmap
224
224
 
225
+ - **ACP (Agent Client Protocol) adoption** — unified driver for any ACP-compatible agent, replacing per-agent CLI output parsing. See [ACP Migration Plan](docs/acp-migration.md)
225
226
  - Expand session-scoped MCP bridge into a more complete top-level tool layer
226
227
  - Improve GUI automation, especially browser + desktop tool coordination
227
228
  - More IM channels (WhatsApp, etc.)
@@ -249,25 +249,16 @@ export function resolveSkillPrompt(bot, chatId, cmd, args) {
249
249
  const cs = bot.chat(chatId);
250
250
  const extra = args.trim();
251
251
  const suffix = extra ? ` Additional context: ${extra}` : '';
252
+ const workdirHint = `[Project directory: ${bot.workdir}]\n\n`;
252
253
  let prompt;
253
- if (skill.source === 'commands') {
254
- prompt = `In this project's .claude/commands/${skill.name}.md file, there is a custom command definition. Please read and execute the instructions defined there.${suffix}`;
255
- return { prompt, skillName: skill.name };
256
- }
257
254
  const paths = getProjectSkillPaths(bot.workdir, skill.name);
258
- if (cs.agent === 'claude' && paths.claudeSkillFile) {
259
- prompt = `Please execute the /${skill.name} skill defined in this project.${suffix}`;
255
+ const skillFile = paths.claudeSkillFile || paths.sharedSkillFile || paths.agentsSkillFile;
256
+ if (skillFile) {
257
+ prompt = `${workdirHint}Read the skill definition at \`${skillFile}\` and execute the instructions defined there.${suffix}`;
260
258
  }
261
259
  else {
262
- const canonicalPath = paths.sharedSkillFile
263
- ? `\`${relSkillPath(bot.workdir, paths.sharedSkillFile)}\``
264
- : `\`.pikiclaw/skills/${skill.name}/SKILL.md\``;
265
- const locationText = paths.sharedSkillFile
266
- ? canonicalPath
267
- : paths.agentsSkillFile || paths.claudeSkillFile
268
- ? canonicalPath
269
- : `\`${skill.name}/SKILL.md\``;
270
- prompt = `In this project, the ${skill.name} skill is defined in ${locationText}. Please read that SKILL.md file and execute the instructions.${suffix}`;
260
+ const fallbackPath = `${bot.workdir}/.pikiclaw/skills/${skill.name}/SKILL.md`;
261
+ prompt = `${workdirHint}Read the skill definition at \`${fallbackPath}\` and execute the instructions defined there.${suffix}`;
271
262
  }
272
263
  return { prompt, skillName: skill.name };
273
264
  }
@@ -121,14 +121,17 @@ export function ensureManagedBrowserProfileDir() {
121
121
  return profileDir;
122
122
  }
123
123
  export function getManagedBrowserMcpArgs(profileDir = getManagedBrowserProfileDir(), options = {}) {
124
+ const outputDir = path.dirname(profileDir);
124
125
  if (options.cdpEndpoint) {
125
- return ['--cdp-endpoint', options.cdpEndpoint];
126
+ return ['--cdp-endpoint', options.cdpEndpoint, '--output-dir', outputDir];
126
127
  }
127
128
  return [
128
129
  ...PLAYWRIGHT_MCP_BROWSER_ARGS,
129
130
  ...(options.headless ? ['--headless'] : []),
130
131
  '--user-data-dir',
131
132
  profileDir,
133
+ '--output-dir',
134
+ outputDir,
132
135
  ];
133
136
  }
134
137
  export function resolveManagedBrowserMcpCliPath() {
@@ -1209,32 +1209,15 @@ export function getProjectSkillPaths(workdir, skillName) {
1209
1209
  const sharedSkillFile = path.join(workdir, '.pikiclaw', 'skills', skillName, 'SKILL.md');
1210
1210
  const agentsSkillFile = path.join(workdir, '.agents', 'skills', skillName, 'SKILL.md');
1211
1211
  const claudeSkillFile = path.join(workdir, '.claude', 'skills', skillName, 'SKILL.md');
1212
- const claudeCommandFile = path.join(workdir, '.claude', 'commands', `${skillName}.md`);
1213
1212
  return {
1214
1213
  sharedSkillFile: hasFile(sharedSkillFile) ? sharedSkillFile : null,
1215
1214
  agentsSkillFile: hasFile(agentsSkillFile) ? agentsSkillFile : null,
1216
1215
  claudeSkillFile: hasFile(claudeSkillFile) ? claudeSkillFile : null,
1217
- claudeCommandFile: hasFile(claudeCommandFile) ? claudeCommandFile : null,
1218
1216
  };
1219
1217
  }
1220
1218
  export function listSkills(workdir) {
1221
1219
  const skills = [];
1222
1220
  const seen = new Set();
1223
- const commandsDir = path.join(workdir, '.claude', 'commands');
1224
- for (const entry of readSortedDir(commandsDir)) {
1225
- if (!entry.endsWith('.md'))
1226
- continue;
1227
- const name = entry.replace(/\.md$/, '');
1228
- if (!name || seen.has(name))
1229
- continue;
1230
- let meta = { label: null, description: null };
1231
- try {
1232
- meta = parseSkillMeta(fs.readFileSync(path.join(commandsDir, entry), 'utf-8'));
1233
- }
1234
- catch { }
1235
- skills.push({ name, label: meta.label, description: meta.description, source: 'commands' });
1236
- seen.add(name);
1237
- }
1238
1221
  const skillRoots = [
1239
1222
  path.join(workdir, '.pikiclaw', 'skills'),
1240
1223
  ];
package/dist/run.js CHANGED
@@ -112,14 +112,13 @@ async function main() {
112
112
  case 'skills': {
113
113
  const result = listSkills(workdir);
114
114
  if (!result.skills.length) {
115
- process.stdout.write(`No custom skills found in ${workdir} (.pikiclaw/skills, .claude/commands)\n`);
115
+ process.stdout.write(`No custom skills found in ${workdir} (.pikiclaw/skills)\n`);
116
116
  break;
117
117
  }
118
118
  process.stdout.write(`Project skills (${result.skills.length}):\n\n`);
119
119
  for (const sk of result.skills) {
120
- const src = sk.source === 'skills' ? 'skill' : 'command';
121
120
  const desc = sk.description ? ` ${sk.description}` : '';
122
- process.stdout.write(` ${sk.name} [${src}]${desc}\n`);
121
+ process.stdout.write(` ${sk.name}${desc}\n`);
123
122
  }
124
123
  break;
125
124
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pikiclaw",
3
- "version": "0.2.67",
3
+ "version": "0.2.69",
4
4
  "description": "Put the world's smartest AI agents in your pocket. Command local Claude & Gemini via IM. | 让最好用的 IM 变成你电脑上的顶级 Agent 控制台",
5
5
  "type": "module",
6
6
  "bin": {