@hasna/skills 0.1.53 → 0.1.55

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/dist/index.js CHANGED
@@ -224,8 +224,8 @@ var PREMIUM_SKILLS = [
224
224
  { slug: "transcript", displayName: "Transcript", tier: "premium", costCents: 10, providers: ["openai", "elevenlabs", "deepgram", "hosted"], description: "Audio/video transcription with timestamps, diarization, and URL support" },
225
225
  { slug: "webcrawling", displayName: "Web Crawling", tier: "premium", costCents: 5, providers: ["firecrawl"], description: "Structured web page crawling and extraction" },
226
226
  { slug: "browse", displayName: "Browse", tier: "premium", costCents: 5, providers: ["browser"], description: "Web browsing and page interaction" },
227
- { slug: "read-pdf", displayName: "Read PDF", tier: "premium", costCents: 5, providers: ["cerebras"], description: "Hosted PDF extraction and structured content analysis" },
228
- { slug: "pdf-read", displayName: "PDF Read", tier: "premium", costCents: 5, providers: ["cerebras"], description: "Hosted multi-PDF text extraction with page ranges" },
227
+ { slug: "read-pdf", displayName: "Read PDF", tier: "premium", costCents: 5, providers: ["openrouter"], description: "Hosted PDF extraction and structured content analysis" },
228
+ { slug: "pdf-read", displayName: "PDF Read", tier: "premium", costCents: 5, providers: ["openrouter"], description: "Hosted multi-PDF text extraction with page ranges" },
229
229
  { slug: "pdf-to-markdown", displayName: "PDF to Markdown", tier: "premium", costCents: 5, providers: ["hosted"], description: "Hosted PDF to markdown conversion and cleanup" },
230
230
  { slug: "pdf-to-dataset", displayName: "PDF to Dataset", tier: "premium", costCents: 15, providers: ["hosted"], description: "Hosted PDF table and form extraction into CSV/JSON datasets" },
231
231
  { slug: "market-research-report", displayName: "Market Research Report", tier: "premium", costCents: 150, providers: ["hosted"], description: "Hosted market research report with competitor, audience, pricing, and source artifacts" },
@@ -308,9 +308,9 @@ function getSkillRunPricing(slug, input, args = []) {
308
308
  tier: "premium",
309
309
  costCents: ARTICLE_USER_COST_CENTS * count,
310
310
  costMicros: ARTICLE_INTERNAL_COST_CENTS * count * 1e4,
311
- provider: "cerebras",
312
- model: "gpt-oss",
313
- providers: ["cerebras"],
311
+ provider: "openrouter",
312
+ model: "openai/gpt-4o-mini",
313
+ providers: ["openrouter"],
314
314
  description: `Remote article generation; ${count} article${count === 1 ? "" : "s"}`
315
315
  };
316
316
  }
@@ -2353,6 +2353,13 @@ var PROJECT_MANAGEMENT_SKILLS = [
2353
2353
  description: "Create, validate, and serve standardized Hasna project dashboard reports",
2354
2354
  category: "Project Management",
2355
2355
  tags: ["projects", "dashboard", "reports", "json-render"]
2356
+ },
2357
+ {
2358
+ name: "todos-plan",
2359
+ displayName: "Todos Plan",
2360
+ description: "Author, sync, route, and verify Todos plans using Todos CLI plan IDs as source of truth",
2361
+ category: "Project Management",
2362
+ tags: ["todos", "plans", "tasks", "verification", "workflow"]
2356
2363
  }
2357
2364
  ];
2358
2365
 
@@ -2721,14 +2728,14 @@ var DATA_ANALYSIS_SKILLS = [
2721
2728
  displayName: "Read PDF",
2722
2729
  description: "Extract text and structured content from PDF files with chunked Claude document analysis",
2723
2730
  category: "Data & Analysis",
2724
- tags: ["pdf", "documents", "extraction", "analysis", "remote", "premium", "cerebras"]
2731
+ tags: ["pdf", "documents", "extraction", "analysis", "remote", "premium", "gateway"]
2725
2732
  },
2726
2733
  {
2727
2734
  name: "pdf-read",
2728
2735
  displayName: "PDF Read",
2729
2736
  description: "Read multiple PDFs with page-range selection, chunked reading, and parallel processing",
2730
2737
  category: "Data & Analysis",
2731
- tags: ["pdf", "reader", "extraction", "parallel", "remote", "premium", "cerebras"]
2738
+ tags: ["pdf", "reader", "extraction", "parallel", "remote", "premium", "gateway"]
2732
2739
  },
2733
2740
  {
2734
2741
  name: "pdf-to-markdown",
@@ -18302,6 +18309,7 @@ var VENDOR_TERMS = [
18302
18309
  "DALL-E 3",
18303
18310
  "GPT-4o Mini",
18304
18311
  "Cerebras",
18312
+ "OpenRouter",
18305
18313
  "Firecrawl",
18306
18314
  "ElevenLabs",
18307
18315
  "Anthropic",
@@ -18330,6 +18338,7 @@ var VENDOR_TAGS = new Set([
18330
18338
  "google",
18331
18339
  "minimax",
18332
18340
  "openai",
18341
+ "openrouter",
18333
18342
  "seedance",
18334
18343
  "whisper",
18335
18344
  "xai"
@@ -18343,6 +18352,7 @@ var VENDOR_ENV_PREFIXES = [
18343
18352
  "GOOGLE_",
18344
18353
  "MINIMAX_",
18345
18354
  "OPENAI_",
18355
+ "OPENROUTER_",
18346
18356
  "XAI_"
18347
18357
  ];
18348
18358
  var VENDOR_PACKAGE_PATTERNS = [
@@ -18353,6 +18363,7 @@ var VENDOR_PACKAGE_PATTERNS = [
18353
18363
  /gemini/i,
18354
18364
  /minimax/i,
18355
18365
  /openai/i,
18366
+ /openrouter/i,
18356
18367
  /xai/i
18357
18368
  ];
18358
18369
  var vendorPattern = new RegExp(`\\b(${VENDOR_TERMS.map(escapeRegExp).join("|")})\\b`, "gi");
@@ -18417,6 +18428,396 @@ function escapeRegExp(value) {
18417
18428
  function resolveDiscoveryPricing(skill) {
18418
18429
  return skill.pricing && typeof skill.pricing.formattedCost === "string" ? skill.pricing : getPublicSkillPricing(skill.name);
18419
18430
  }
18431
+ // src/lib/tool-primitives.ts
18432
+ var TOOL_PRIMITIVE_SCHEMA_VERSION = 1;
18433
+ var TOOL_PRIMITIVES = [
18434
+ {
18435
+ name: "ai-gateway",
18436
+ title: "AI Gateway",
18437
+ family: "ai",
18438
+ description: "Provider-neutral text, code, reasoning, and multimodal model calls routed through the configured hosted gateway.",
18439
+ runtime: "gateway",
18440
+ stable: true,
18441
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18442
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18443
+ apiSurfaces: ["runSkill", "SkillRunRecord", "RemoteSkillRunContract"],
18444
+ envVars: ["SKILLS_API_KEY"],
18445
+ outputTypes: ["text", "json", "markdown", "artifact"],
18446
+ capabilities: ["completion", "reasoning", "tool-calling", "vision-input", "structured-output"]
18447
+ },
18448
+ {
18449
+ name: "documents-read",
18450
+ title: "Document Read",
18451
+ family: "documents",
18452
+ description: "Read, parse, normalize, and extract from PDF, DOCX, slides, invoices, contracts, and other document files.",
18453
+ runtime: "mixed",
18454
+ stable: true,
18455
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18456
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18457
+ apiSurfaces: ["getSkillRequirements", "runSkill"],
18458
+ envVars: [],
18459
+ outputTypes: ["text", "json", "markdown"],
18460
+ capabilities: ["pdf-parse", "office-parse", "ocr", "metadata-extraction"]
18461
+ },
18462
+ {
18463
+ name: "documents-write",
18464
+ title: "Document Write",
18465
+ family: "documents",
18466
+ description: "Generate PDFs, DOCX, slide decks, ebooks, reports, and other downloadable document artifacts.",
18467
+ runtime: "mixed",
18468
+ stable: true,
18469
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18470
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18471
+ apiSurfaces: ["createSkillRun", "completeSkillRun", "writeRunLogs"],
18472
+ envVars: [],
18473
+ outputTypes: ["pdf", "docx", "pptx", "markdown", "zip"],
18474
+ capabilities: ["document-generation", "layout", "export-artifacts"]
18475
+ },
18476
+ {
18477
+ name: "structured-data",
18478
+ title: "Structured Data",
18479
+ family: "data",
18480
+ description: "Read, transform, validate, and export CSV, Excel, JSON, SQL, metrics, and tabular datasets.",
18481
+ runtime: "mixed",
18482
+ stable: true,
18483
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18484
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18485
+ apiSurfaces: ["runSkill", "SkillRunArtifact"],
18486
+ envVars: [],
18487
+ outputTypes: ["csv", "xlsx", "json", "sql", "markdown"],
18488
+ capabilities: ["csv", "excel", "etl", "schema", "analytics"]
18489
+ },
18490
+ {
18491
+ name: "media-image",
18492
+ title: "Image Tooling",
18493
+ family: "media",
18494
+ description: "Generate, inspect, transform, remove backgrounds from, and package image artifacts.",
18495
+ runtime: "gateway",
18496
+ stable: true,
18497
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18498
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18499
+ apiSurfaces: ["runSkill", "RemoteSkillRunContract"],
18500
+ envVars: ["SKILLS_API_KEY"],
18501
+ outputTypes: ["png", "jpeg", "webp", "svg", "zip"],
18502
+ capabilities: ["image-generation", "image-analysis", "image-editing", "asset-packaging"]
18503
+ },
18504
+ {
18505
+ name: "media-audio",
18506
+ title: "Audio Tooling",
18507
+ family: "media",
18508
+ description: "Transcribe, extract, clean, generate, and package audio, voiceover, music, and podcast outputs.",
18509
+ runtime: "gateway",
18510
+ stable: true,
18511
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18512
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18513
+ apiSurfaces: ["runSkill", "RemoteSkillRunContract"],
18514
+ envVars: ["SKILLS_API_KEY"],
18515
+ outputTypes: ["mp3", "wav", "txt", "srt", "json", "zip"],
18516
+ capabilities: ["transcription", "audio-generation", "voiceover", "audio-cleanup"]
18517
+ },
18518
+ {
18519
+ name: "media-video",
18520
+ title: "Video Tooling",
18521
+ family: "media",
18522
+ description: "Generate, analyze, cut, caption, summarize, thumbnail, and package video outputs.",
18523
+ runtime: "gateway",
18524
+ stable: true,
18525
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18526
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18527
+ apiSurfaces: ["runSkill", "RemoteSkillRunContract"],
18528
+ envVars: ["SKILLS_API_KEY"],
18529
+ outputTypes: ["mp4", "mov", "srt", "png", "json", "zip"],
18530
+ capabilities: ["video-generation", "video-analysis", "captioning", "highlight-extraction"]
18531
+ },
18532
+ {
18533
+ name: "web-browser",
18534
+ title: "Web Browser",
18535
+ family: "web",
18536
+ description: "Browse, crawl, search, screenshot, inspect, and analyze websites and web application states.",
18537
+ runtime: "mixed",
18538
+ stable: true,
18539
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18540
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18541
+ apiSurfaces: ["runSkill", "SkillRunArtifact"],
18542
+ envVars: [],
18543
+ outputTypes: ["html", "markdown", "png", "json", "har"],
18544
+ capabilities: ["crawl", "browser-automation", "screenshots", "site-analysis"]
18545
+ },
18546
+ {
18547
+ name: "connectors-run",
18548
+ title: "Connector Operations",
18549
+ family: "connectors",
18550
+ description: "Declare and execute external account operations through approved connector plans instead of direct provider CLIs.",
18551
+ runtime: "connector",
18552
+ stable: true,
18553
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18554
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18555
+ apiSurfaces: ["SkillRunContext", "RemoteSkillRunContract"],
18556
+ envVars: ["SKILLS_API_KEY"],
18557
+ outputTypes: ["json", "artifact"],
18558
+ capabilities: ["approval", "external-api", "account-scoped-execution"]
18559
+ },
18560
+ {
18561
+ name: "project-artifacts",
18562
+ title: "Project Artifacts",
18563
+ family: "workspace",
18564
+ description: "Read project context and write deterministic run logs, exports, and downloadable artifacts.",
18565
+ runtime: "local",
18566
+ stable: true,
18567
+ cliCommands: ["skills tools deps <skill>", "skills run <skill>"],
18568
+ mcpTools: ["get_skill_tool_dependencies", "run_skill"],
18569
+ apiSurfaces: ["createSkillRun", "completeSkillRun", "writeRunLogs", "SkillRunArtifact"],
18570
+ envVars: [],
18571
+ outputTypes: ["log", "json", "markdown", "file"],
18572
+ capabilities: ["filesystem", "run-state", "artifact-export", "deterministic-logs"]
18573
+ },
18574
+ {
18575
+ name: "safety-approval",
18576
+ title: "Safety And Approval",
18577
+ family: "safety",
18578
+ description: "Gate risky, paid, security-sensitive, or compliance-sensitive skill actions behind explicit approval and structured evidence.",
18579
+ runtime: "mixed",
18580
+ stable: true,
18581
+ cliCommands: ["skills quote <skill>", "skills tools deps <skill>"],
18582
+ mcpTools: ["quote_skill", "get_skill_tool_dependencies"],
18583
+ apiSurfaces: ["getSkillPricing", "getSkillRunCostCents", "validateSkillDirectory"],
18584
+ envVars: [],
18585
+ outputTypes: ["json", "markdown"],
18586
+ capabilities: ["pricing-approval", "risk-review", "policy-evidence", "validation"]
18587
+ },
18588
+ {
18589
+ name: "hosted-auth",
18590
+ title: "Hosted Auth",
18591
+ family: "hosted",
18592
+ description: "Authenticate hosted and premium runs through Skills account credentials rather than local provider keys.",
18593
+ runtime: "hosted",
18594
+ stable: true,
18595
+ cliCommands: ["skills auth login", "skills billing status", "skills run <skill>"],
18596
+ mcpTools: ["run_skill", "quote_skill"],
18597
+ apiSurfaces: ["RemoteSkillsClient", "RemoteSkillRunContract"],
18598
+ envVars: ["SKILLS_API_KEY"],
18599
+ outputTypes: ["json"],
18600
+ capabilities: ["account-auth", "billing", "remote-run-submit"]
18601
+ }
18602
+ ];
18603
+ var CATEGORY_RULES = [
18604
+ { primitive: "ai-gateway", categories: ["Business & Marketing", "Content Generation", "Design & Branding", "Research & Writing", "Education & Learning", "Communication", "Health & Wellness", "Travel & Lifestyle", "Event Management", "Science & Academic"], reason: "Category is primarily AI-assisted generation, analysis, or planning." },
18605
+ { primitive: "project-artifacts", categories: ["Development Tools", "Project Management", "Productivity & Organization"], reason: "Category operates on project context, run logs, or workspace artifacts." },
18606
+ { primitive: "structured-data", categories: ["Data & Analysis", "Finance & Compliance", "Science & Academic"], reason: "Category works with structured inputs, tabular evidence, metrics, or analytical outputs." },
18607
+ { primitive: "safety-approval", categories: ["Finance & Compliance"], reason: "Category has compliance-sensitive outputs that need reviewable evidence." },
18608
+ { primitive: "web-browser", categories: ["Web & Browser"], reason: "Category depends on browser, crawl, search, or web inspection primitives." },
18609
+ { primitive: "media-image", categories: ["Media Processing", "Design & Branding"], reason: "Category includes visual asset generation, inspection, or packaging." }
18610
+ ];
18611
+ var NAME_RULES = [
18612
+ { primitive: "documents-read", names: ["read-pdf", "pdf-read", "pdf-to-markdown", "pdf-to-dataset", "doc-read", "extract-invoice", "contract-review-report", "invoice-reconciliation"], reason: "Skill explicitly reads or extracts from document files." },
18613
+ { primitive: "documents-write", names: ["pdf-generate", "doc-generate", "generate-presentation", "slide-deck-generator", "pitch-deck", "proposal-pack", "create-ebook", "generate-book-cover", "api-docs-portal", "landing-page-pack", "one-page-website"], reason: "Skill generates downloadable documents or presentation artifacts." },
18614
+ { primitive: "structured-data", names: ["read-csv", "read-excel", "excel", "generate-sql", "generate-mock-data", "benchmark-finder", "budget-variance-analyzer", "subscription-spend-watcher", "payroll-change-prepper"], reason: "Skill reads, creates, or analyzes structured data." },
18615
+ { primitive: "media-image", names: ["image", "read-image", "brand-photo-shoot", "campaign-moodboard", "logo-design", "icon-pack", "emoji", "product-mockup", "photo-album", "remove-background", "video-thumbnail", "banner-ad-suite", "ad-creative-generator", "ad-creative-pack", "print-collateral-designer", "packaging-concept-studio"], reason: "Skill works directly with image or visual asset primitives." },
18616
+ { primitive: "media-audio", names: ["audio", "music", "transcript", "audio-extract", "audio-transcript-pack", "music-album", "voiceover-jingle-pack", "podcast-show-notes", "subtitle", "audio-cleanup-lab"], reason: "Skill works directly with audio, music, voiceover, or transcription primitives." },
18617
+ { primitive: "media-video", names: ["video", "short-video-pack", "video-highlight-pack", "video-cut-suggester", "video-thumbnail"], reason: "Skill works directly with video generation, editing, captions, or thumbnails." },
18618
+ { primitive: "web-browser", names: ["browse", "webcrawling", "siteanalyze", "performance-audit-report", "seo-content-pack", "competitor-ad-analyzer", "security-audit-report"], reason: "Skill needs live web, crawl, browser, or site inspection primitives." },
18619
+ { primitive: "connectors-run", names: ["email-sequence", "meeting-pack", "customer-feedback-report", "inbox-priority-planner", "crm-note-enhancer", "campaign-metric-brief"], reason: "Skill can execute account-scoped external communication or CRM operations." },
18620
+ { primitive: "safety-approval", names: ["security-audit-report", "contract-review-report", "risk-disclosure-kit", "compliance-report-pack", "procurement-scorecard"], reason: "Skill produces security, legal, compliance, or procurement-sensitive evidence." }
18621
+ ];
18622
+ var KEYWORD_RULES = [
18623
+ { primitive: "documents-read", keywords: ["pdf", "docx", "document", "invoice", "contract"], reason: "Skill metadata references document parsing or review." },
18624
+ { primitive: "documents-write", keywords: ["deck", "presentation", "report", "proposal", "ebook", "pdf"], reason: "Skill metadata references generated document artifacts." },
18625
+ { primitive: "structured-data", keywords: ["csv", "excel", "spreadsheet", "dataset", "sql", "metric", "analytics", "scorecard", "budget"], reason: "Skill metadata references tabular or analytical data." },
18626
+ { primitive: "media-image", keywords: ["image", "photo", "logo", "icon", "thumbnail", "visual", "ad creative", "mockup"], reason: "Skill metadata references image or visual assets." },
18627
+ { primitive: "media-audio", keywords: ["audio", "voice", "music", "podcast", "transcript", "subtitle"], reason: "Skill metadata references audio or transcript assets." },
18628
+ { primitive: "media-video", keywords: ["video", "clip", "caption", "highlight"], reason: "Skill metadata references video assets." },
18629
+ { primitive: "web-browser", keywords: ["web", "website", "browser", "crawl", "seo", "landing page", "site"], reason: "Skill metadata references web or browser work." },
18630
+ { primitive: "connectors-run", keywords: ["email", "calendar", "crm", "inbox", "meeting", "outreach"], reason: "Skill metadata references external account operations." }
18631
+ ];
18632
+ var primitiveByName = new Map(TOOL_PRIMITIVES.map((primitive) => [primitive.name, primitive]));
18633
+ var HOSTED_RUNTIME_SKILL_NAMES = new Set([
18634
+ "audio",
18635
+ "browse",
18636
+ "convert",
18637
+ "image",
18638
+ "music",
18639
+ "pdf-read",
18640
+ "pdf-to-dataset",
18641
+ "pdf-to-markdown",
18642
+ "read-pdf",
18643
+ "transcript",
18644
+ "video",
18645
+ "webcrawling"
18646
+ ]);
18647
+ function listToolPrimitives(query) {
18648
+ const needle = query?.trim().toLowerCase();
18649
+ return TOOL_PRIMITIVES.filter((primitive) => !needle || primitiveHaystack(primitive).includes(needle)).map(summarizeToolPrimitive).sort((a, b) => a.name.localeCompare(b.name));
18650
+ }
18651
+ function getToolPrimitive(name) {
18652
+ return clone2(primitiveByName.get(name));
18653
+ }
18654
+ function getSkillToolDependencies(name) {
18655
+ const skill = getSkill(name);
18656
+ if (!skill)
18657
+ return null;
18658
+ return createSkillToolDependencies(skill);
18659
+ }
18660
+ function createSkillToolDependencies(skill) {
18661
+ const dependencies = inferPrimitiveDependencies(skill);
18662
+ const primitiveNames = new Set(dependencies.map((dependency) => dependency.primitive));
18663
+ return {
18664
+ schemaVersion: TOOL_PRIMITIVE_SCHEMA_VERSION,
18665
+ skill: skill.name,
18666
+ category: skill.category,
18667
+ source: skill.source ?? "official",
18668
+ dependencies,
18669
+ gatewayBacked: [...primitiveNames].some((name) => primitiveByName.get(name)?.runtime === "gateway" || name === "ai-gateway"),
18670
+ hostedRuntime: isHostedRuntimeSkill(skill) || primitiveNames.has("hosted-auth")
18671
+ };
18672
+ }
18673
+ function isGatewayBackedSkill(name) {
18674
+ return getSkillToolDependencies(name)?.gatewayBacked ?? false;
18675
+ }
18676
+ function validateToolPrimitiveCoverage(profile = "all") {
18677
+ const skills = loadRegistryProfile(profile);
18678
+ const issues = [];
18679
+ let mappedSkillCount = 0;
18680
+ let gatewayBackedSkillCount = 0;
18681
+ let hostedRuntimeSkillCount = 0;
18682
+ for (const skill of skills) {
18683
+ const deps = createSkillToolDependencies(skill);
18684
+ if (deps.dependencies.length === 0) {
18685
+ issues.push({
18686
+ skill: skill.name,
18687
+ code: "skill.unmapped",
18688
+ message: `Skill '${skill.name}' has no primitive dependencies.`
18689
+ });
18690
+ continue;
18691
+ }
18692
+ mappedSkillCount++;
18693
+ if (deps.gatewayBacked)
18694
+ gatewayBackedSkillCount++;
18695
+ if (deps.hostedRuntime)
18696
+ hostedRuntimeSkillCount++;
18697
+ for (const dependency of deps.dependencies) {
18698
+ if (!primitiveByName.has(dependency.primitive)) {
18699
+ issues.push({
18700
+ skill: skill.name,
18701
+ code: "primitive.missing",
18702
+ message: `Skill '${skill.name}' references missing primitive '${dependency.primitive}'.`
18703
+ });
18704
+ }
18705
+ }
18706
+ }
18707
+ return {
18708
+ schemaVersion: TOOL_PRIMITIVE_SCHEMA_VERSION,
18709
+ valid: issues.length === 0,
18710
+ profile,
18711
+ skillCount: skills.length,
18712
+ primitiveCount: TOOL_PRIMITIVES.length,
18713
+ mappedSkillCount,
18714
+ gatewayBackedSkillCount,
18715
+ hostedRuntimeSkillCount,
18716
+ issues
18717
+ };
18718
+ }
18719
+ function inferPrimitiveDependencies(skill) {
18720
+ const matches = [];
18721
+ const allRules = [...CATEGORY_RULES, ...NAME_RULES, ...KEYWORD_RULES];
18722
+ for (const rule of allRules) {
18723
+ if (!ruleMatches(skill, rule))
18724
+ continue;
18725
+ const primitive = primitiveByName.get(rule.primitive);
18726
+ if (!primitive)
18727
+ continue;
18728
+ matches.push({
18729
+ skill: skill.name,
18730
+ primitive: primitive.name,
18731
+ family: primitive.family,
18732
+ required: rule.required ?? true,
18733
+ reason: rule.reason
18734
+ });
18735
+ }
18736
+ if (isHostedRuntimeSkill(skill)) {
18737
+ const primitive = primitiveByName.get("hosted-auth");
18738
+ matches.push({
18739
+ skill: skill.name,
18740
+ primitive: primitive.name,
18741
+ family: primitive.family,
18742
+ required: true,
18743
+ reason: "Skill is premium, remote, or hosted and must use Skills account authentication."
18744
+ });
18745
+ }
18746
+ if (matches.length === 0) {
18747
+ const primitive = primitiveByName.get("project-artifacts");
18748
+ matches.push({
18749
+ skill: skill.name,
18750
+ primitive: primitive.name,
18751
+ family: primitive.family,
18752
+ required: true,
18753
+ reason: "Default workspace primitive for local skill execution, run logs, and artifacts."
18754
+ });
18755
+ }
18756
+ return dedupeDependencies(matches).sort((a, b) => a.primitive.localeCompare(b.primitive));
18757
+ }
18758
+ function ruleMatches(skill, rule) {
18759
+ const name = skill.name.toLowerCase();
18760
+ const category = skill.category.toLowerCase();
18761
+ const tags = skill.tags.map((tag) => tag.toLowerCase());
18762
+ const haystack = [
18763
+ skill.name,
18764
+ skill.displayName,
18765
+ skill.description,
18766
+ skill.category,
18767
+ ...skill.tags
18768
+ ].join(" ").toLowerCase();
18769
+ if (rule.names?.some((candidate) => candidate.toLowerCase() === name))
18770
+ return true;
18771
+ if (rule.categories?.some((candidate) => candidate.toLowerCase() === category))
18772
+ return true;
18773
+ if (rule.tags?.some((candidate) => tags.includes(candidate.toLowerCase())))
18774
+ return true;
18775
+ if (rule.keywords?.some((keyword) => haystack.includes(keyword.toLowerCase())))
18776
+ return true;
18777
+ return false;
18778
+ }
18779
+ function isHostedRuntimeSkill(skill) {
18780
+ const tags = new Set(skill.tags.map((tag) => tag.toLowerCase()));
18781
+ return isPremiumSkill(skill.name) || HOSTED_RUNTIME_SKILL_NAMES.has(skill.name) || tags.has("premium") || tags.has("remote") || tags.has("hosted") || skill.pricing?.tier === "premium";
18782
+ }
18783
+ function dedupeDependencies(dependencies) {
18784
+ const byPrimitive = new Map;
18785
+ for (const dependency of dependencies) {
18786
+ const existing = byPrimitive.get(dependency.primitive);
18787
+ if (!existing) {
18788
+ byPrimitive.set(dependency.primitive, dependency);
18789
+ continue;
18790
+ }
18791
+ byPrimitive.set(dependency.primitive, {
18792
+ ...existing,
18793
+ required: existing.required || dependency.required,
18794
+ reason: existing.reason === dependency.reason ? existing.reason : `${existing.reason} ${dependency.reason}`
18795
+ });
18796
+ }
18797
+ return [...byPrimitive.values()];
18798
+ }
18799
+ function summarizeToolPrimitive(primitive) {
18800
+ return {
18801
+ name: primitive.name,
18802
+ title: primitive.title,
18803
+ family: primitive.family,
18804
+ runtime: primitive.runtime,
18805
+ description: primitive.description
18806
+ };
18807
+ }
18808
+ function primitiveHaystack(primitive) {
18809
+ return [
18810
+ primitive.name,
18811
+ primitive.title,
18812
+ primitive.family,
18813
+ primitive.description,
18814
+ primitive.runtime,
18815
+ ...primitive.capabilities
18816
+ ].join(" ").toLowerCase();
18817
+ }
18818
+ function clone2(value) {
18819
+ return value === undefined ? undefined : JSON.parse(JSON.stringify(value));
18820
+ }
18420
18821
  // src/lib/remote-run-contract.ts
18421
18822
  var REMOTE_SKILL_RUN_CONTRACT_VERSION = 1;
18422
18823
  function normalizeRemoteSkillRunContract(payload, fallbackSkill) {
@@ -18805,6 +19206,30 @@ var SKILLS_CLI_MCP_PARITY = [
18805
19206
  mcpTools: ["validate_skill"],
18806
19207
  jsonContracts: ["skill_validation_result", "structured_error"],
18807
19208
  status: "matched"
19209
+ },
19210
+ {
19211
+ domain: "tool-primitives",
19212
+ operation: "list",
19213
+ cliCommands: ["skills tools list"],
19214
+ mcpTools: ["list_tool_primitives"],
19215
+ jsonContracts: ["tool_primitive_summary"],
19216
+ status: "matched"
19217
+ },
19218
+ {
19219
+ domain: "tool-primitives",
19220
+ operation: "deps",
19221
+ cliCommands: ["skills tools deps"],
19222
+ mcpTools: ["get_skill_tool_dependencies"],
19223
+ jsonContracts: ["skill_tool_dependencies"],
19224
+ status: "matched"
19225
+ },
19226
+ {
19227
+ domain: "tool-primitives",
19228
+ operation: "validate",
19229
+ cliCommands: ["skills tools validate"],
19230
+ mcpTools: ["validate_tool_primitives"],
19231
+ jsonContracts: ["tool_primitive_coverage_result"],
19232
+ status: "matched"
18808
19233
  }
18809
19234
  ];
18810
19235
  function validateSkillsCliMcpParity() {
@@ -18840,7 +19265,7 @@ import { dirname as dirname4, relative as relative3 } from "path";
18840
19265
  // package.json
18841
19266
  var package_default = {
18842
19267
  name: "@hasna/skills",
18843
- version: "0.1.53",
19268
+ version: "0.1.55",
18844
19269
  description: "Skills library for AI coding agents",
18845
19270
  type: "module",
18846
19271
  bin: {
@@ -19071,6 +19496,20 @@ var skillSummarySchema = objectSchema({
19071
19496
  category: stringSchema("Skill category."),
19072
19497
  pricing: pricingSchema
19073
19498
  }, ["name", "category"], "Compact skill summary.");
19499
+ var toolPrimitiveSummarySchema = objectSchema({
19500
+ name: stringSchema("Primitive tool name."),
19501
+ title: stringSchema("Display name."),
19502
+ family: stringSchema("Primitive family."),
19503
+ runtime: stringSchema("Runtime type: local, hosted, gateway, connector, or mixed."),
19504
+ description: stringSchema("Primitive description.")
19505
+ }, ["name", "title", "family", "runtime", "description"], "Primitive tool summary.");
19506
+ var skillToolDependencySchema = objectSchema({
19507
+ skill: stringSchema("Skill slug."),
19508
+ primitive: stringSchema("Primitive tool name."),
19509
+ family: stringSchema("Primitive family."),
19510
+ required: { type: "boolean" },
19511
+ reason: stringSchema("Why this skill depends on the primitive.")
19512
+ }, ["skill", "primitive", "family", "required", "reason"], "Primitive dependency for a skill.");
19074
19513
  var validationMessageSchema = objectSchema({
19075
19514
  code: stringSchema("Stable validation code."),
19076
19515
  message: stringSchema("Validation message."),
@@ -19251,6 +19690,74 @@ var toolContracts = [
19251
19690
  inputSchema: objectSchema({ name: skillNameInput }, ["name"]),
19252
19691
  outputSchema: { type: "string", description: "Best available skill documentation." }
19253
19692
  },
19693
+ {
19694
+ name: "list_tool_primitives",
19695
+ title: "List Tool Primitives",
19696
+ description: "List primitive tools used by skills across CLI, MCP, API, and hosted worker execution.",
19697
+ params: ["query?"],
19698
+ category: "discovery",
19699
+ sideEffects: "none",
19700
+ stable: true,
19701
+ inputSchema: objectSchema({ query: stringSchema("Optional primitive search query.") }),
19702
+ outputSchema: objectSchema({
19703
+ schemaVersion: { type: "number" },
19704
+ primitives: arraySchema(toolPrimitiveSummarySchema),
19705
+ total: { type: "number" }
19706
+ }, ["schemaVersion", "primitives", "total"])
19707
+ },
19708
+ {
19709
+ name: "get_tool_primitive",
19710
+ title: "Get Tool Primitive",
19711
+ description: "Get one primitive tool definition by name.",
19712
+ params: ["name"],
19713
+ category: "metadata",
19714
+ sideEffects: "none",
19715
+ stable: true,
19716
+ inputSchema: objectSchema({ name: stringSchema("Primitive tool name.") }, ["name"]),
19717
+ outputSchema: objectSchema({}, [], "Primitive tool definition.", true)
19718
+ },
19719
+ {
19720
+ name: "get_skill_tool_dependencies",
19721
+ title: "Get Skill Tool Dependencies",
19722
+ description: "Get primitive tool dependencies for one skill.",
19723
+ params: ["name"],
19724
+ category: "metadata",
19725
+ sideEffects: "none",
19726
+ stable: true,
19727
+ inputSchema: objectSchema({ name: skillNameInput }, ["name"]),
19728
+ outputSchema: objectSchema({
19729
+ schemaVersion: { type: "number" },
19730
+ skill: skillNameInput,
19731
+ category: stringSchema("Skill category."),
19732
+ source: stringSchema("Skill source."),
19733
+ dependencies: arraySchema(skillToolDependencySchema),
19734
+ gatewayBacked: { type: "boolean" },
19735
+ hostedRuntime: { type: "boolean" }
19736
+ }, ["schemaVersion", "skill", "category", "dependencies", "gatewayBacked", "hostedRuntime"])
19737
+ },
19738
+ {
19739
+ name: "validate_tool_primitives",
19740
+ title: "Validate Tool Primitives",
19741
+ description: "Validate primitive tool coverage for the bundled skill catalog.",
19742
+ params: ["profile?"],
19743
+ category: "validation",
19744
+ sideEffects: "none",
19745
+ stable: true,
19746
+ inputSchema: objectSchema({
19747
+ profile: { type: "string", enum: ["basic", "all"], default: "all" }
19748
+ }),
19749
+ outputSchema: objectSchema({
19750
+ schemaVersion: { type: "number" },
19751
+ valid: { type: "boolean" },
19752
+ profile: stringSchema("Registry profile."),
19753
+ skillCount: { type: "number" },
19754
+ primitiveCount: { type: "number" },
19755
+ mappedSkillCount: { type: "number" },
19756
+ gatewayBackedSkillCount: { type: "number" },
19757
+ hostedRuntimeSkillCount: { type: "number" },
19758
+ issues: arraySchema(objectSchema({}, [], "Coverage issue.", true))
19759
+ }, ["schemaVersion", "valid", "profile", "skillCount", "primitiveCount", "mappedSkillCount", "issues"])
19760
+ },
19254
19761
  {
19255
19762
  name: "pin_skill",
19256
19763
  title: "Pin Skill",
@@ -19643,6 +20150,13 @@ var resourceContracts = [
19643
20150
  mimeType: "application/json",
19644
20151
  schema: arraySchema(skillSummarySchema)
19645
20152
  },
20153
+ {
20154
+ uri: "skills://tool-primitives",
20155
+ name: "Tool Primitives",
20156
+ description: "Primitive tool catalog used by skills across CLI, MCP, API, and hosted workers.",
20157
+ mimeType: "application/json",
20158
+ schema: arraySchema(toolPrimitiveSummarySchema)
20159
+ },
19646
20160
  {
19647
20161
  uri: "skills://{name}",
19648
20162
  name: "Skill Info",
@@ -19663,7 +20177,7 @@ function listMcpToolContracts(query) {
19663
20177
  ].join(" ").toLowerCase();
19664
20178
  return haystack.includes(needle);
19665
20179
  }) : contracts;
19666
- return clone2(filtered);
20180
+ return clone3(filtered);
19667
20181
  }
19668
20182
  function describeMcpToolContracts(names) {
19669
20183
  const byName = new Map(contracts.map((contract) => [contract.name, contract]));
@@ -19677,7 +20191,7 @@ function describeMcpToolContracts(names) {
19677
20191
  params: []
19678
20192
  };
19679
20193
  }
19680
- return { ...clone2(contract), known: true };
20194
+ return { ...clone3(contract), known: true };
19681
20195
  });
19682
20196
  }
19683
20197
  function summarizeMcpToolContract(contract) {
@@ -19691,21 +20205,21 @@ function summarizeMcpToolContract(contract) {
19691
20205
  };
19692
20206
  }
19693
20207
  function getMcpResourceContracts() {
19694
- return clone2(resourceContracts);
20208
+ return clone3(resourceContracts);
19695
20209
  }
19696
20210
  function createMcpContractManifest(options = {}) {
19697
20211
  const selectedNames = options.names ? new Set(options.names) : null;
19698
20212
  const tools = selectedNames ? contracts.filter((contract) => selectedNames.has(contract.name)) : contracts;
19699
20213
  return {
19700
20214
  schemaVersion: MCP_CONTRACT_SCHEMA_VERSION,
19701
- tools: clone2(tools),
20215
+ tools: clone3(tools),
19702
20216
  resources: options.includeResources === false ? [] : getMcpResourceContracts()
19703
20217
  };
19704
20218
  }
19705
20219
  function createSkillMcpMetadata(skill) {
19706
- const installInput = clone2(getRequiredContract("pin_skill").inputSchema);
19707
- const runInput = clone2(getRequiredContract("run_skill").inputSchema);
19708
- const validateInput = clone2(getRequiredContract("validate_skill").inputSchema);
20220
+ const installInput = clone3(getRequiredContract("pin_skill").inputSchema);
20221
+ const runInput = clone3(getRequiredContract("run_skill").inputSchema);
20222
+ const validateInput = clone3(getRequiredContract("validate_skill").inputSchema);
19709
20223
  installInput.properties = {
19710
20224
  ...installInput.properties,
19711
20225
  name: {
@@ -19744,17 +20258,17 @@ function createSkillMcpMetadata(skill) {
19744
20258
  install: {
19745
20259
  tool: "pin_skill",
19746
20260
  inputSchema: installInput,
19747
- outputSchema: clone2(getRequiredContract("pin_skill").outputSchema)
20261
+ outputSchema: clone3(getRequiredContract("pin_skill").outputSchema)
19748
20262
  },
19749
20263
  run: {
19750
20264
  tool: "run_skill",
19751
20265
  inputSchema: runInput,
19752
- outputSchema: clone2(getRequiredContract("run_skill").outputSchema)
20266
+ outputSchema: clone3(getRequiredContract("run_skill").outputSchema)
19753
20267
  },
19754
20268
  validate: {
19755
20269
  tool: "validate_skill",
19756
20270
  inputSchema: validateInput,
19757
- outputSchema: clone2(getRequiredContract("validate_skill").outputSchema)
20271
+ outputSchema: clone3(getRequiredContract("validate_skill").outputSchema)
19758
20272
  }
19759
20273
  }
19760
20274
  };
@@ -19771,7 +20285,7 @@ function getRequiredContract(name) {
19771
20285
  throw new Error(`Missing MCP tool contract: ${name}`);
19772
20286
  return contract;
19773
20287
  }
19774
- function clone2(value) {
20288
+ function clone3(value) {
19775
20289
  return JSON.parse(JSON.stringify(value));
19776
20290
  }
19777
20291
  // src/lib/feedback.ts
@@ -20369,6 +20883,7 @@ function toArrayBuffer(bytes) {
20369
20883
  export {
20370
20884
  writeRunLogs,
20371
20885
  writeRegistrySyncArtifact,
20886
+ validateToolPrimitiveCoverage,
20372
20887
  validateSkillsCliMcpParity,
20373
20888
  validateSkillDirectory,
20374
20889
  validateRegistryConsistency,
@@ -20422,6 +20937,7 @@ export {
20422
20937
  loadProjectConfig,
20423
20938
  loadConfig,
20424
20939
  loadBasicRegistry,
20940
+ listToolPrimitives,
20425
20941
  listSkillRuns,
20426
20942
  listSchedules,
20427
20943
  listPortableSkills,
@@ -20429,6 +20945,7 @@ export {
20429
20945
  listPinnedSkills,
20430
20946
  listMcpToolContracts,
20431
20947
  isPremiumSkill,
20948
+ isGatewayBackedSkill,
20432
20949
  isBasicSkillName,
20433
20950
  installSkills,
20434
20951
  installSkillSource,
@@ -20436,6 +20953,7 @@ export {
20436
20953
  installSkillForAgent,
20437
20954
  installSkill,
20438
20955
  importSkillsLocalSnapshot,
20956
+ getToolPrimitive,
20439
20957
  getStorageStatus,
20440
20958
  getStorageMode,
20441
20959
  getStorageDatabaseUrl,
@@ -20447,6 +20965,7 @@ export {
20447
20965
  getSkillsNativeStorageStatus,
20448
20966
  getSkillsByTag,
20449
20967
  getSkillsByCategory,
20968
+ getSkillToolDependencies,
20450
20969
  getSkillRunCostCents,
20451
20970
  getSkillRequirements,
20452
20971
  getSkillPricing,
@@ -20494,6 +21013,7 @@ export {
20494
21013
  createSkillsSnapshotSyncRecord,
20495
21014
  createSkillsS3ObjectStore,
20496
21015
  createSkillsPostgresSyncStore,
21016
+ createSkillToolDependencies,
20497
21017
  createSkillRun,
20498
21018
  createSkillMcpMetadata,
20499
21019
  createRemoteSkillsClient,
@@ -20506,6 +21026,8 @@ export {
20506
21026
  buildSkillsApiUrl,
20507
21027
  appendRunEvent,
20508
21028
  addSchedule,
21029
+ TOOL_PRIMITIVE_SCHEMA_VERSION,
21030
+ TOOL_PRIMITIVES,
20509
21031
  SkillsS3ObjectStore,
20510
21032
  SkillsPostgresSyncStore,
20511
21033
  STORAGE_TABLES,