0agent 1.0.12 → 1.0.13

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/bin/0agent.js CHANGED
@@ -535,11 +535,16 @@ async function runSkillCommand(skillArgs) {
535
535
  await requireDaemon();
536
536
  const res = await fetch(`${BASE_URL}/api/skills`);
537
537
  const skills = await res.json();
538
- console.log('\n Available skills:\n');
538
+ console.log('\n Built-in skills:\n');
539
539
  for (const s of (Array.isArray(skills) ? skills : skills.skills ?? [])) {
540
- console.log(` /${s.name.padEnd(22)} ${s.category.padEnd(10)} ${s.description}`);
540
+ console.log(` /${s.name.padEnd(22)} ${s.category?.padEnd(10) ?? ''.padEnd(10)} ${s.description}`);
541
541
  }
542
- console.log();
542
+ console.log('\n Anthropic skills (fetched on demand):\n');
543
+ const anthropicSkills = ['pdf','docx','xlsx','pptx','web-artifacts-builder','webapp-testing','frontend-design','mcp-builder','algorithmic-art','brand-guidelines','doc-coauthoring','internal-comms','slack-gif-creator','theme-factory','canvas-design','skill-creator','claude-api'];
544
+ for (const s of anthropicSkills) {
545
+ console.log(` /${s.padEnd(30)} fetched from github.com/anthropics/skills`);
546
+ }
547
+ console.log('\n Usage: 0agent /<skill-name> or 0agent run "<task>" --skill <name>\n');
543
548
  break;
544
549
  }
545
550
  case 'show': {
package/dist/daemon.mjs CHANGED
@@ -2451,6 +2451,125 @@ content = element.text if element else page.get_all_text()` : `content = page.ge
2451
2451
  }
2452
2452
  };
2453
2453
 
2454
+ // packages/daemon/src/AnthropicSkillFetcher.ts
2455
+ var BASE_URL = "https://raw.githubusercontent.com/anthropics/skills/main";
2456
+ var CACHE_TTL_MS = 60 * 60 * 1e3;
2457
+ var ANTHROPIC_SKILLS = [
2458
+ "algorithmic-art",
2459
+ "brand-guidelines",
2460
+ "canvas-design",
2461
+ "claude-api",
2462
+ "doc-coauthoring",
2463
+ "docx",
2464
+ "frontend-design",
2465
+ "internal-comms",
2466
+ "mcp-builder",
2467
+ "pdf",
2468
+ "pptx",
2469
+ "skill-creator",
2470
+ "slack-gif-creator",
2471
+ "theme-factory",
2472
+ "web-artifacts-builder",
2473
+ "webapp-testing",
2474
+ "xlsx"
2475
+ ];
2476
+ var AnthropicSkillFetcher = class {
2477
+ cache = /* @__PURE__ */ new Map();
2478
+ /**
2479
+ * Fetch a skill's instructions from the Anthropic repo.
2480
+ * Returns the Markdown body as a role_prompt string.
2481
+ * Caches for 1 hour.
2482
+ */
2483
+ async fetch(skillName) {
2484
+ const cached = this.cache.get(skillName);
2485
+ if (cached && Date.now() - cached.fetched_at < CACHE_TTL_MS) {
2486
+ return this.parseSkillMd(skillName, cached.prompt, true);
2487
+ }
2488
+ const urls = [
2489
+ `${BASE_URL}/skills/${skillName}/SKILL.md`,
2490
+ `${BASE_URL}/${skillName}/SKILL.md`,
2491
+ `${BASE_URL}/skills/${skillName}/README.md`
2492
+ ];
2493
+ for (const url of urls) {
2494
+ try {
2495
+ const res = await fetch(url, {
2496
+ headers: { "User-Agent": "0agent/1.0" },
2497
+ signal: AbortSignal.timeout(8e3)
2498
+ });
2499
+ if (res.ok) {
2500
+ const text = await res.text();
2501
+ this.cache.set(skillName, { prompt: text, fetched_at: Date.now() });
2502
+ return this.parseSkillMd(skillName, text, false);
2503
+ }
2504
+ } catch {
2505
+ }
2506
+ }
2507
+ return null;
2508
+ }
2509
+ /**
2510
+ * Parse a SKILL.md file into a FetchedSkill.
2511
+ * Extracts name/description from YAML frontmatter, instructions from body.
2512
+ */
2513
+ parseSkillMd(skillName, raw, cached) {
2514
+ let name = skillName;
2515
+ let description = "";
2516
+ let instructions = raw;
2517
+ const frontmatterMatch = raw.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
2518
+ if (frontmatterMatch) {
2519
+ const frontmatter = frontmatterMatch[1];
2520
+ instructions = frontmatterMatch[2].trim();
2521
+ const nameMatch = frontmatter.match(/^name:\s*(.+)$/m);
2522
+ if (nameMatch) name = nameMatch[1].trim().replace(/["']/g, "");
2523
+ const descMatch = frontmatter.match(/^description:\s*([\s\S]*?)(?=^\w|\Z)/m);
2524
+ if (descMatch) description = descMatch[1].replace(/\s+/g, " ").trim().replace(/["']/g, "");
2525
+ }
2526
+ return {
2527
+ name,
2528
+ description,
2529
+ instructions,
2530
+ source_url: `https://github.com/anthropics/skills/tree/main/skills/${skillName}`,
2531
+ cached
2532
+ };
2533
+ }
2534
+ /**
2535
+ * Build a system prompt that injects the Anthropic skill instructions.
2536
+ * This is what gets passed to the agent as context.
2537
+ */
2538
+ buildSystemPrompt(skill) {
2539
+ return [
2540
+ `You are using the "${skill.name}" skill from Anthropic's skill library.`,
2541
+ ``,
2542
+ `Skill description: ${skill.description}`,
2543
+ ``,
2544
+ `Instructions:`,
2545
+ `---`,
2546
+ skill.instructions,
2547
+ `---`,
2548
+ ``,
2549
+ `Use the tools available to you (shell_exec, file_op, web_search, scrape_url, browser_open)`,
2550
+ `to complete the task following these instructions.`
2551
+ ].join("\n");
2552
+ }
2553
+ /**
2554
+ * List all known Anthropic skills.
2555
+ */
2556
+ listAvailable() {
2557
+ return [...ANTHROPIC_SKILLS];
2558
+ }
2559
+ /**
2560
+ * Check if a skill name is a known Anthropic skill.
2561
+ */
2562
+ isAnthropicSkill(name) {
2563
+ return ANTHROPIC_SKILLS.includes(name);
2564
+ }
2565
+ /**
2566
+ * Clear the cache (force re-fetch on next request).
2567
+ */
2568
+ clearCache() {
2569
+ this.cache.clear();
2570
+ }
2571
+ };
2572
+
2454
2573
  // packages/daemon/src/SessionManager.ts
2455
2574
  var SessionManager = class {
2456
2575
  sessions = /* @__PURE__ */ new Map();
@@ -2459,6 +2578,7 @@ var SessionManager = class {
2459
2578
  graph;
2460
2579
  llm;
2461
2580
  cwd;
2581
+ anthropicFetcher = new AnthropicSkillFetcher();
2462
2582
  constructor(deps = {}) {
2463
2583
  this.inferenceEngine = deps.inferenceEngine;
2464
2584
  this.eventBus = deps.eventBus;
@@ -2632,6 +2752,15 @@ var SessionManager = class {
2632
2752
  } else {
2633
2753
  this.addStep(session.id, "No inference engine connected \u2014 executing task directly");
2634
2754
  }
2755
+ let anthropicContext;
2756
+ if (enrichedReq.skill && this.anthropicFetcher.isAnthropicSkill(enrichedReq.skill)) {
2757
+ this.addStep(session.id, `Fetching skill instructions: ${enrichedReq.skill}`);
2758
+ const fetched = await this.anthropicFetcher.fetch(enrichedReq.skill);
2759
+ if (fetched) {
2760
+ anthropicContext = this.anthropicFetcher.buildSystemPrompt(fetched);
2761
+ this.addStep(session.id, `Loaded skill: ${fetched.name} (${fetched.cached ? "cached" : "fresh"})`);
2762
+ }
2763
+ }
2635
2764
  if (this.llm?.isConfigured) {
2636
2765
  const executor = new AgentExecutor(
2637
2766
  this.llm,
@@ -2641,7 +2770,10 @@ var SessionManager = class {
2641
2770
  // token callback → emit session.token events
2642
2771
  (token) => this.emit({ type: "session.token", session_id: session.id, token })
2643
2772
  );
2644
- const systemContext = enrichedReq.context?.system_context ? String(enrichedReq.context.system_context) : void 0;
2773
+ const systemContext = [
2774
+ anthropicContext,
2775
+ enrichedReq.context?.system_context ? String(enrichedReq.context.system_context) : void 0
2776
+ ].filter(Boolean).join("\n\n") || void 0;
2645
2777
  const agentResult = await executor.execute(enrichedReq.task, systemContext);
2646
2778
  if (agentResult.files_written.length > 0) {
2647
2779
  this.addStep(session.id, `Files written: ${agentResult.files_written.join(", ")}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "0agent",
3
- "version": "1.0.12",
3
+ "version": "1.0.13",
4
4
  "description": "A persistent, learning AI agent that runs on your machine. An agent that learns.",
5
5
  "private": false,
6
6
  "license": "Apache-2.0",