@hasna/skills 0.1.25 → 0.1.26

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.
@@ -12,6 +12,7 @@ export interface SkillsConfig {
12
12
  defaultAgent?: "claude" | "codex" | "gemini" | "pi" | "opencode" | "all";
13
13
  defaultScope?: "global" | "project";
14
14
  format?: "compact" | "json" | "csv";
15
+ apiUrl?: string;
15
16
  }
16
17
  export type ConfigScope = "global" | "project";
17
18
  /**
@@ -0,0 +1,53 @@
1
+ import { type SkillRegistryProfile } from "./registry.js";
2
+ import { type SkillDocs, type SkillRequirements } from "./skillinfo.js";
3
+ import { type SkillValidationResult } from "./skill-validation.js";
4
+ export interface RegistrySyncOptions {
5
+ profile?: SkillRegistryProfile;
6
+ includeDocs?: boolean;
7
+ includeRequirements?: boolean;
8
+ includeValidation?: boolean;
9
+ packageName?: string;
10
+ packageVersion?: string;
11
+ sourceRepository?: string;
12
+ }
13
+ export interface RegistrySyncSkill {
14
+ name: string;
15
+ slug: string;
16
+ displayName: string;
17
+ description: string;
18
+ category: string;
19
+ tags: string[];
20
+ dependencies: string[];
21
+ source: {
22
+ packageName: string;
23
+ packageVersion: string;
24
+ repository: string;
25
+ directory: string;
26
+ };
27
+ docs?: SkillDocs & {
28
+ best: string | null;
29
+ };
30
+ requirements?: SkillRequirements | null;
31
+ validation?: SkillValidationResult;
32
+ }
33
+ export interface RegistrySyncArtifact {
34
+ schemaVersion: 1;
35
+ source: {
36
+ packageName: string;
37
+ packageVersion: string;
38
+ repository: string;
39
+ profile: SkillRegistryProfile;
40
+ };
41
+ summary: {
42
+ skillCount: number;
43
+ validSkillCount: number | null;
44
+ invalidSkillCount: number | null;
45
+ categories: Array<{
46
+ name: string;
47
+ count: number;
48
+ }>;
49
+ };
50
+ skills: RegistrySyncSkill[];
51
+ }
52
+ export declare function createRegistrySyncArtifact(options?: RegistrySyncOptions): RegistrySyncArtifact;
53
+ export declare function writeRegistrySyncArtifact(path: string, artifact: RegistrySyncArtifact): void;
@@ -8,7 +8,7 @@ export interface SkillMeta {
8
8
  category: string;
9
9
  tags: string[];
10
10
  dependencies?: string[];
11
- source?: "official" | "custom";
11
+ source?: "official" | "custom" | "remote";
12
12
  }
13
13
  export declare const CATEGORIES: readonly ["Development Tools", "Business & Marketing", "Productivity & Organization", "Project Management", "Content Generation", "Finance & Compliance", "Data & Analysis", "Media Processing", "Design & Branding", "Web & Browser", "Research & Writing", "Science & Academic", "Education & Learning", "Communication", "Health & Wellness", "Travel & Lifestyle", "Event Management"];
14
14
  export type Category = (typeof CATEGORIES)[number];
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Remote registry client.
3
+ *
4
+ * Local registry behavior remains the default. These helpers are opt-in and
5
+ * read from SKILLS_API_URL or config.apiUrl so private SaaS products can expose
6
+ * a compatible registry API without hard-coding any SaaS details upstream.
7
+ */
8
+ import { type SkillsConfig } from "./config.js";
9
+ import type { SkillMeta } from "./registry.js";
10
+ export interface RemoteRegistryOptions {
11
+ apiUrl?: string;
12
+ endpoint?: string;
13
+ timeoutMs?: number;
14
+ fetchImpl?: (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
15
+ }
16
+ export declare function getConfiguredApiUrl(config?: SkillsConfig, env?: Record<string, string | undefined>): string | undefined;
17
+ export declare function buildSkillsApiUrl(apiUrl: string, endpoint?: string): string;
18
+ export declare function parseRemoteRegistryPayload(payload: unknown): SkillMeta[];
19
+ export declare function loadRemoteRegistry(options?: RemoteRegistryOptions): Promise<SkillMeta[]>;
@@ -0,0 +1,45 @@
1
+ import type { SkillMeta } from "./registry.js";
2
+ export interface SkillValidationMessage {
3
+ code: string;
4
+ message: string;
5
+ }
6
+ export interface SkillValidationResult {
7
+ name: string;
8
+ path: string;
9
+ valid: boolean;
10
+ issues: SkillValidationMessage[];
11
+ warnings: SkillValidationMessage[];
12
+ metadata: {
13
+ packageName?: string;
14
+ version?: string;
15
+ binCommands: string[];
16
+ docFiles: string[];
17
+ skillMdFrontmatter?: SkillFrontmatter;
18
+ provenance?: SkillValidationProvenance;
19
+ };
20
+ }
21
+ export interface RegistryConsistencyResult {
22
+ valid: boolean;
23
+ missingDirectories: string[];
24
+ orphanDirectories: string[];
25
+ duplicateRegistryNames: string[];
26
+ }
27
+ export interface SkillFrontmatter {
28
+ name?: string;
29
+ description?: string;
30
+ displayName?: string;
31
+ category?: string;
32
+ tags?: string[];
33
+ version?: string;
34
+ source?: string;
35
+ }
36
+ export interface SkillValidationProvenance {
37
+ directoryName: string;
38
+ packageName?: string;
39
+ packageVersion?: string;
40
+ frontmatterSource?: string;
41
+ registrySource?: string;
42
+ }
43
+ export declare function parseSkillFrontmatter(content: string): SkillFrontmatter | null;
44
+ export declare function validateSkillDirectory(name: string, skillPath: string, registryMeta?: SkillMeta): SkillValidationResult;
45
+ export declare function validateRegistryConsistency(registry: SkillMeta[], skillsDir: string): RegistryConsistencyResult;
@@ -13,6 +13,7 @@ export interface SkillResponse {
13
13
  envVarsSet: string[];
14
14
  systemDeps: string[];
15
15
  cliCommand: string | null;
16
+ source?: "official" | "custom" | "remote";
16
17
  }
17
18
  export interface SkillDetailResponse extends SkillResponse {
18
19
  docs: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/skills",
3
- "version": "0.1.25",
3
+ "version": "0.1.26",
4
4
  "description": "Skills library for AI coding agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -0,0 +1,2 @@
1
+ # Environment Variables
2
+
@@ -0,0 +1,72 @@
1
+ # my-app
2
+
3
+ REST API boilerplate
4
+
5
+ ## Tech Stack
6
+
7
+ - **Framework**: REST API
8
+ - **Language**: TypeScript
9
+ - **Styling**: Tailwind CSS
10
+
11
+ ## Prerequisites
12
+
13
+ - Node.js 18+ (or Bun)
14
+ -
15
+
16
+ ## Getting Started
17
+
18
+ 1. Install dependencies:
19
+
20
+ ```bash
21
+ bun install
22
+ ```
23
+
24
+ 2. Copy environment variables:
25
+
26
+ ```bash
27
+ cp .env.example .env
28
+ ```
29
+
30
+ 3. Fill in the environment variables in `.env`
31
+
32
+ 5. Run the development server:
33
+
34
+ ```bash
35
+ bun dev
36
+ ```
37
+
38
+ ## Available Scripts
39
+
40
+ - `bun dev` - Start development server
41
+ - `bun build` - Build for production
42
+ - `bun start` - Start production server
43
+ - `bun lint` - Run ESLint
44
+ - `bun format` - Format code with Prettier
45
+
46
+ ## Project Structure
47
+
48
+ ```
49
+ my-app/
50
+ ├── src/
51
+ │ ├── app/ # Application routes
52
+ │ ├── components/ # React components
53
+ │ ├── lib/ # Utility functions
54
+ │ └── types/ # TypeScript types
55
+ ├── public/ # Static assets
56
+ ├── .env.example # Environment variables template
57
+ ├── package.json
58
+ └── README.md
59
+ ```
60
+
61
+ ## Learn More
62
+
63
+ - [REST API Documentation](https://nextjs.org/docs)
64
+ - [Tailwind CSS](https://tailwindcss.com/docs)
65
+
66
+ ## Deployment
67
+
68
+ Deploy your application on [Vercel](https://vercel.com) or [Railway](https://railway.app).
69
+
70
+ ---
71
+
72
+ Generated with [scaffold-project](https://skills.md/skills/scaffold-project)
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "my-app",
3
+ "version": "0.1.0",
4
+ "private": true,
5
+ "scripts": {
6
+ "dev": "tsx watch src/index.ts",
7
+ "build": "tsc",
8
+ "start": "node dist/index.js",
9
+ "lint": "eslint .",
10
+ "format": "prettier --write ."
11
+ },
12
+ "dependencies": {
13
+ "express": "latest",
14
+ "cors": "latest",
15
+ "dotenv": "latest",
16
+ "tailwindcss": "latest",
17
+ "autoprefixer": "latest",
18
+ "postcss": "latest"
19
+ },
20
+ "devDependencies": {
21
+ "@types/express": "latest",
22
+ "@types/cors": "latest",
23
+ "@types/node": "latest",
24
+ "typescript": "latest",
25
+ "tsx": "latest",
26
+ "eslint": "latest",
27
+ "prettier": "latest"
28
+ }
29
+ }
@@ -0,0 +1,23 @@
1
+ import express from 'express'
2
+ import cors from 'cors'
3
+ import dotenv from 'dotenv'
4
+
5
+ dotenv.config()
6
+
7
+ const app = express()
8
+ const port = process.env.PORT || 3000
9
+
10
+ app.use(cors())
11
+ app.use(express.json())
12
+
13
+ app.get('/', (req, res) => {
14
+ res.json({ message: 'API is running' })
15
+ })
16
+
17
+ app.get('/health', (req, res) => {
18
+ res.json({ status: 'ok' })
19
+ })
20
+
21
+ app.listen(port, () => {
22
+ console.log(`Server running on http://localhost:${port}`)
23
+ })
@@ -0,0 +1,33 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "lib": [
5
+ "ES2020",
6
+ "DOM",
7
+ "DOM.Iterable"
8
+ ],
9
+ "module": "ESNext",
10
+ "skipLibCheck": true,
11
+ "moduleResolution": "bundler",
12
+ "allowImportingTsExtensions": true,
13
+ "resolveJsonModule": true,
14
+ "isolatedModules": true,
15
+ "noEmit": true,
16
+ "strict": true,
17
+ "noUnusedLocals": true,
18
+ "noUnusedParameters": true,
19
+ "noFallthroughCasesInSwitch": true,
20
+ "baseUrl": ".",
21
+ "paths": {
22
+ "@/*": [
23
+ "./src/*"
24
+ ]
25
+ }
26
+ },
27
+ "include": [
28
+ "src"
29
+ ],
30
+ "exclude": [
31
+ "node_modules"
32
+ ]
33
+ }