@hasna/skills 0.1.29 → 0.1.31

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.
@@ -9,5 +9,5 @@ export declare function getAuthConfig(): AuthConfig | null;
9
9
  export declare function saveAuthConfig(config: AuthConfig): void;
10
10
  export declare function clearAuthConfig(): void;
11
11
  export declare function getApiKey(): string | null;
12
- export declare function normalizePlatformApiOrigin(apiUrl: string): string;
12
+ export declare function normalizeSkillsApiOrigin(apiUrl: string): string;
13
13
  export declare function getApiUrl(): string;
@@ -9,6 +9,7 @@
9
9
  * Values from the project config override global config.
10
10
  */
11
11
  export interface SkillsConfig {
12
+ mode?: "local" | "skills.md";
12
13
  defaultAgent?: "claude" | "codex" | "gemini" | "pi" | "opencode" | "all";
13
14
  defaultScope?: "global" | "project";
14
15
  format?: "compact" | "json" | "csv";
@@ -0,0 +1,23 @@
1
+ import type { SkillMeta } from "./registry-types.js";
2
+ import { type PublicSkillPricing } from "./pricing.js";
3
+ export interface CompactSkillDiscovery {
4
+ name: string;
5
+ category: string;
6
+ pricing: PublicSkillPricing;
7
+ }
8
+ export type PublicSkillDiscovery<T extends SkillMeta = SkillMeta> = Omit<T, "description" | "tags"> & {
9
+ description: string;
10
+ tags: string[];
11
+ pricing: PublicSkillPricing;
12
+ };
13
+ export declare function getCompactSkillDiscovery(skill: SkillMeta): CompactSkillDiscovery;
14
+ export declare function getPublicSkillDiscovery<T extends SkillMeta>(skill: T): PublicSkillDiscovery<T>;
15
+ export declare function publicDiscoveryPriceLabel(skill: {
16
+ name: string;
17
+ pricing?: PublicSkillPricing;
18
+ }): string;
19
+ export declare function publicDiscoveryTags(tags: string[]): string[];
20
+ export declare function sanitizePublicDiscoveryText(text: string): string;
21
+ export declare function publicDiscoveryEnvVars(skillName: string, envVars: string[]): string[];
22
+ export declare function publicDiscoveryDependencies(skillName: string, dependencies: Record<string, string>): Record<string, string>;
23
+ export declare function publicDiscoveryDocumentation(skill: SkillMeta, documentation: string | null): string | null;
@@ -0,0 +1,89 @@
1
+ export type BillingTier = "free" | "premium";
2
+ export interface SkillPricing {
3
+ slug: string;
4
+ displayName: string;
5
+ tier: BillingTier;
6
+ costCents: number;
7
+ providers: string[];
8
+ description: string;
9
+ provider?: string;
10
+ model?: string;
11
+ costMicros?: number;
12
+ }
13
+ export interface PublicSkillPricing {
14
+ tier: BillingTier;
15
+ billingUnit: "run" | "image" | "second" | "character" | "song" | "thousand_tokens" | "article";
16
+ costCents: number;
17
+ formattedCost: string;
18
+ formattedUnitCost?: string;
19
+ unitCount?: number;
20
+ estimated: boolean;
21
+ quoteDependsOnInput: boolean;
22
+ quoteRequired: boolean;
23
+ description: string;
24
+ }
25
+ export type SkillCatalogBillingMode = "free" | "credits" | "subscription" | "metered";
26
+ export interface SkillCatalogBillingFields {
27
+ billingMode: SkillCatalogBillingMode;
28
+ creditsPerExecution: number;
29
+ }
30
+ export type MediaModality = "image" | "video" | "audio" | "music";
31
+ export type MediaProvider = "openai" | "minimax" | "gemini" | "seedance";
32
+ type PriceUnit = "image" | "second" | "character" | "song" | "thousand_tokens";
33
+ interface MediaPrice {
34
+ slug: MediaModality;
35
+ provider: MediaProvider;
36
+ model: string;
37
+ unit: PriceUnit;
38
+ costMicros: number;
39
+ description: string;
40
+ default?: boolean;
41
+ resolution?: string;
42
+ durationSeconds?: number;
43
+ }
44
+ export declare const MUSIC_ALBUM_SLUG = "music-album";
45
+ export declare const MUSIC_ALBUM_SONG_COUNTS: readonly [7, 14, 21];
46
+ export declare const PREMIUM_SKILLS: SkillPricing[];
47
+ export declare const ARTICLE_GENERATION_SLUG = "blog-article";
48
+ export declare const ARTICLE_MAX_COUNT = 12;
49
+ export declare const ARTICLE_COUNT_ERROR = "Count must be an integer between 1 and 12.";
50
+ declare const ARTICLE_TONES: readonly ["professional", "casual", "technical", "friendly"];
51
+ declare const ARTICLE_LENGTHS: readonly ["short", "medium", "long"];
52
+ export type ArticleTone = typeof ARTICLE_TONES[number];
53
+ export type ArticleLength = typeof ARTICLE_LENGTHS[number];
54
+ export interface BlogArticleRunOptions {
55
+ topic?: string;
56
+ audience?: string;
57
+ tone: ArticleTone;
58
+ length: ArticleLength;
59
+ seo: boolean;
60
+ outline?: string;
61
+ count: number;
62
+ }
63
+ export type BlogArticleValidationResult = {
64
+ ok: true;
65
+ options: BlogArticleRunOptions;
66
+ input: Record<string, unknown>;
67
+ errors: [];
68
+ } | {
69
+ ok: false;
70
+ input: Record<string, unknown>;
71
+ errors: string[];
72
+ };
73
+ export declare const MEDIA_GENERATION_PRICES: MediaPrice[];
74
+ export declare function getSkillPricing(slug: string): SkillPricing | null;
75
+ export declare function isPremiumSkill(slug: string): boolean;
76
+ export declare function getSkillCostCents(slug: string): number;
77
+ export declare function getSkillRunPricing(slug: string, input?: unknown, args?: string[]): SkillPricing | null;
78
+ export declare function validateBlogArticleRunOptions(input?: unknown, args?: string[], validation?: {
79
+ requireTopic?: boolean;
80
+ }): BlogArticleValidationResult;
81
+ export declare function getSkillRunCostCents(slug: string, input?: unknown, args?: string[]): number;
82
+ export declare function getPublicSkillPricing(slug: string, input?: unknown, args?: string[]): PublicSkillPricing;
83
+ export declare function getSkillCatalogBillingFields(slug: string, input?: unknown, args?: string[]): SkillCatalogBillingFields;
84
+ export declare function formatPublicPricing(slug: string, input?: unknown, args?: string[]): string;
85
+ export declare function isMediaGenerationSkill(slug: string): boolean;
86
+ export declare function getMediaProviders(slug: MediaModality): string[];
87
+ export declare function formatCost(cents: number): string;
88
+ export declare function getAllPremiumSlugs(): string[];
89
+ export {};
@@ -0,0 +1,18 @@
1
+ import { type RemoteSkillRunContract } from "./remote-run-contract.js";
2
+ export declare class RemoteSkillsClient {
3
+ private apiUrl;
4
+ private apiKey;
5
+ constructor(apiKey: string, apiUrl?: string);
6
+ private request;
7
+ listSkills(): Promise<any[]>;
8
+ getSkillMd(slug: string): Promise<string | null>;
9
+ getSkill(slug: string): Promise<any | null>;
10
+ quoteSkill(slug: string, input?: Record<string, unknown>, args?: string[]): Promise<any>;
11
+ submitRun(slug: string, input?: Record<string, unknown>, args?: string[]): Promise<RemoteSkillRunContract>;
12
+ getRun(runId: string): Promise<RemoteSkillRunContract | null>;
13
+ getRunLogs(runId: string): Promise<any[]>;
14
+ listRuns(limit?: number): Promise<any[]>;
15
+ getRunArtifacts(runId: string): Promise<any[]>;
16
+ downloadRunArtifact(runId: string, artifactId: string): Promise<Response>;
17
+ }
18
+ export declare function createRemoteSkillsClient(): RemoteSkillsClient | null;
@@ -0,0 +1,29 @@
1
+ import type { PublicSkillPricing } from "./pricing";
2
+ export declare const REMOTE_SKILL_RUN_CONTRACT_VERSION: 1;
3
+ export interface RemoteSkillRunContract {
4
+ contractVersion: typeof REMOTE_SKILL_RUN_CONTRACT_VERSION;
5
+ id?: string;
6
+ skill?: string;
7
+ requestedSlug?: string;
8
+ status?: string;
9
+ exitCode?: number;
10
+ correlationId?: string;
11
+ costCents?: number;
12
+ cost?: string;
13
+ pricing?: PublicSkillPricing;
14
+ createdAt?: string;
15
+ startedAt?: string;
16
+ completedAt?: string;
17
+ durationMs?: number;
18
+ outputType?: string;
19
+ outputPreview?: unknown;
20
+ errorCode?: string;
21
+ errorMessage?: string;
22
+ creditsUsed?: number;
23
+ error?: string;
24
+ code?: string;
25
+ details?: unknown;
26
+ balance?: string;
27
+ balanceCents?: number;
28
+ }
29
+ export declare function normalizeRemoteSkillRunContract(payload: unknown, fallbackSkill?: string): RemoteSkillRunContract;
@@ -2,6 +2,7 @@ import { createServer, type IncomingMessage, type ServerResponse } from "node:ht
2
2
  export declare const MCP_HTTP_DEFAULT_PORT = 8836;
3
3
  export declare const MCP_HTTP_SERVICE_NAME = "skills";
4
4
  export declare function isMcpHttpMode(argv?: string[]): boolean;
5
+ export declare function isMcpStdioMode(argv?: string[]): boolean;
5
6
  export declare function parseMcpHttpPort(argv: string[], defaultPort?: number): number;
6
7
  export declare function handleMcpHttpNodeRequest(req: IncomingMessage, res: ServerResponse): Promise<boolean>;
7
8
  export declare function startSkillsMcpHttpServer(options?: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.1.29",
3
+ "version": "0.1.31",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -36,17 +36,6 @@
36
36
  "dev:watch": "bun --watch run ./src/cli/index.tsx",
37
37
  "dev:mcp": "bun --watch run ./src/mcp/index.ts",
38
38
  "typecheck": "tsc --noEmit",
39
- "db:migrate:preview": "bun run scripts/apply_database_migrations.ts",
40
- "aws:bootstrap:ecs": "bash scripts/bootstrap_ecs_foundation.sh",
41
- "aws:bootstrap:s3": "bash scripts/bootstrap_s3_buckets.sh",
42
- "aws:bootstrap:secrets": "bash scripts/bootstrap_secrets.sh",
43
- "aws:bootstrap:preview-edge": "bash scripts/bootstrap_preview_edge.sh",
44
- "aws:bootstrap:preview-stripe": "bash scripts/preview_bootstrap_stripe.sh",
45
- "aws:verify:preview-stripe": "bash scripts/preview_verify_stripe.sh",
46
- "aws:bootstrap:production-edge": "bash scripts/bootstrap_production_edge.sh",
47
- "aws:bootstrap:production-stripe": "bash scripts/production_bootstrap_stripe.sh",
48
- "aws:production:readiness": "bash scripts/production_readiness.sh",
49
- "upstream:check": "bash scripts/check_upstream_sync.sh",
50
39
  "prepublishOnly": "bun run build",
51
40
  "postinstall": "mkdir -p $HOME/.hasna/skills/custom 2>/dev/null || true"
52
41
  },
@@ -70,11 +59,10 @@
70
59
  "license": "Apache-2.0",
71
60
  "devDependencies": {
72
61
  "@types/bun": "latest",
62
+ "@types/react": "^18.2.0",
73
63
  "typescript": "^5"
74
64
  },
75
65
  "dependencies": {
76
- "@hasna/cloud": "^0.1.24",
77
- "@hasna/skills": "0.1.27",
78
66
  "@modelcontextprotocol/sdk": "^1.26.0",
79
67
  "chalk": "^5.3.0",
80
68
  "commander": "^12.1.0",
@@ -82,6 +70,7 @@
82
70
  "ink-select-input": "^6.0.0",
83
71
  "ink-spinner": "^5.0.0",
84
72
  "ink-text-input": "^6.0.0",
73
+ "react": "^18.2.0",
85
74
  "zod": "^4.3.6"
86
75
  },
87
76
  "engines": {
@@ -0,0 +1,5 @@
1
+ {
2
+ "env": {
3
+ "CLAUDE_CODE_TASK_LIST_ID": "service-apidocs-dev"
4
+ }
5
+ }
@@ -53,7 +53,7 @@ const PATTERNS = [
53
53
  { name: "Eval Usage", regex: /eval\(/, severity: "MEDIUM" },
54
54
  {
55
55
  name: "Insecure HTTP",
56
- regex: /http:\/\/(?!localhost(?:[:/$]|$)|127\.0\.0\.1(?:[:/$]|$)|0\.0\.0\.0(?:[:/$]|$))/,
56
+ regex: /http:\/\/(?!localhost(?:[:/$]|$)|127\.0\.0\.1(?:[:/$]|$)|0\.0\.0\.0(?:[:/$]|$)|\$\{)/,
57
57
  severity: "LOW",
58
58
  },
59
59
  ];