@hasna/skills 0.1.43 → 0.1.45

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.
@@ -0,0 +1,14 @@
1
+ export type SkillsCliMcpParityDomain = "discovery" | "portable-skills" | "runtime" | "validation";
2
+ export interface SkillsCliMcpParityEntry {
3
+ domain: SkillsCliMcpParityDomain;
4
+ operation: string;
5
+ cliCommands: string[];
6
+ mcpTools: string[];
7
+ jsonContracts: string[];
8
+ status: "matched" | "intentional-gap";
9
+ notes?: string;
10
+ }
11
+ export declare const SKILLS_CLI_MCP_PARITY: SkillsCliMcpParityEntry[];
12
+ export declare function validateSkillsCliMcpParity(): string[];
13
+ export declare function findSkillsParityForCliCommand(command: string): SkillsCliMcpParityEntry | undefined;
14
+ export declare function findSkillsParityForMcpTool(tool: string): SkillsCliMcpParityEntry | undefined;
@@ -15,7 +15,7 @@ export interface JsonSchemaObject {
15
15
  additionalProperties?: boolean | JsonSchemaObject;
16
16
  oneOf?: JsonSchemaObject[];
17
17
  }
18
- export type McpToolCategory = "agent-session" | "discovery" | "execution" | "feedback" | "metadata" | "pinning" | "scheduling" | "validation";
18
+ export type McpToolCategory = "agent-session" | "discovery" | "execution" | "feedback" | "metadata" | "pinning" | "scaffolding" | "scheduling" | "storage" | "validation";
19
19
  export type McpToolSideEffect = "filesystem" | "local-process-or-remote-run" | "none" | "schedule-state";
20
20
  export interface McpToolContract {
21
21
  name: string;
@@ -0,0 +1,251 @@
1
+ export type SkillsStorageMode = "local" | "remote" | "hybrid";
2
+ export declare const SKILLS_STORAGE_TABLES: readonly ["skills_sync_records", "skills_sync_cursors"];
3
+ export declare const STORAGE_TABLES: readonly ["skills_sync_records", "skills_sync_cursors"];
4
+ export type SkillsStorageTable = typeof SKILLS_STORAGE_TABLES[number];
5
+ export interface SkillsNativeStorageConfig {
6
+ mode: SkillsStorageMode;
7
+ databaseUrl?: string;
8
+ databaseSsl?: boolean;
9
+ databaseSchema?: string;
10
+ s3Bucket?: string;
11
+ s3Prefix?: string;
12
+ awsRegion?: string;
13
+ s3Endpoint?: string;
14
+ s3ForcePathStyle?: boolean;
15
+ syncBatchSize: number;
16
+ dryRun: boolean;
17
+ }
18
+ export declare const SKILLS_NATIVE_STORAGE_ENV: {
19
+ readonly mode: "HASNA_SKILLS_STORAGE_MODE";
20
+ readonly databaseUrl: "HASNA_SKILLS_DATABASE_URL";
21
+ readonly databaseSsl: "HASNA_SKILLS_DATABASE_SSL";
22
+ readonly databaseSchema: "HASNA_SKILLS_DATABASE_SCHEMA";
23
+ readonly s3Bucket: "HASNA_SKILLS_S3_BUCKET";
24
+ readonly s3Prefix: "HASNA_SKILLS_S3_PREFIX";
25
+ readonly awsRegion: "HASNA_SKILLS_AWS_REGION";
26
+ readonly s3Endpoint: "HASNA_SKILLS_S3_ENDPOINT";
27
+ readonly s3ForcePathStyle: "HASNA_SKILLS_S3_FORCE_PATH_STYLE";
28
+ readonly s3AccessKeyId: "HASNA_SKILLS_S3_ACCESS_KEY_ID";
29
+ readonly s3SecretAccessKey: "HASNA_SKILLS_S3_SECRET_ACCESS_KEY";
30
+ readonly s3SessionToken: "HASNA_SKILLS_S3_SESSION_TOKEN";
31
+ readonly syncBatchSize: "HASNA_SKILLS_SYNC_BATCH_SIZE";
32
+ readonly dryRun: "HASNA_SKILLS_SYNC_DRY_RUN";
33
+ };
34
+ export declare const SKILLS_NATIVE_STORAGE_FALLBACK_ENV: {
35
+ readonly mode: "SKILLS_STORAGE_MODE";
36
+ readonly databaseUrl: "SKILLS_DATABASE_URL";
37
+ readonly databaseSsl: "SKILLS_DATABASE_SSL";
38
+ readonly databaseSchema: "SKILLS_DATABASE_SCHEMA";
39
+ readonly s3Bucket: "SKILLS_S3_BUCKET";
40
+ readonly s3Prefix: "SKILLS_S3_PREFIX";
41
+ readonly awsRegion: "SKILLS_AWS_REGION";
42
+ readonly s3Endpoint: "SKILLS_S3_ENDPOINT";
43
+ readonly s3ForcePathStyle: "SKILLS_S3_FORCE_PATH_STYLE";
44
+ readonly s3AccessKeyId: "SKILLS_S3_ACCESS_KEY_ID";
45
+ readonly s3SecretAccessKey: "SKILLS_S3_SECRET_ACCESS_KEY";
46
+ readonly s3SessionToken: "SKILLS_S3_SESSION_TOKEN";
47
+ readonly syncBatchSize: "SKILLS_SYNC_BATCH_SIZE";
48
+ readonly dryRun: "SKILLS_SYNC_DRY_RUN";
49
+ };
50
+ export declare const SKILLS_STORAGE_ENV: {
51
+ readonly mode: "HASNA_SKILLS_STORAGE_MODE";
52
+ readonly databaseUrl: "HASNA_SKILLS_DATABASE_URL";
53
+ readonly databaseSsl: "HASNA_SKILLS_DATABASE_SSL";
54
+ readonly databaseSchema: "HASNA_SKILLS_DATABASE_SCHEMA";
55
+ readonly s3Bucket: "HASNA_SKILLS_S3_BUCKET";
56
+ readonly s3Prefix: "HASNA_SKILLS_S3_PREFIX";
57
+ readonly awsRegion: "HASNA_SKILLS_AWS_REGION";
58
+ readonly s3Endpoint: "HASNA_SKILLS_S3_ENDPOINT";
59
+ readonly s3ForcePathStyle: "HASNA_SKILLS_S3_FORCE_PATH_STYLE";
60
+ readonly s3AccessKeyId: "HASNA_SKILLS_S3_ACCESS_KEY_ID";
61
+ readonly s3SecretAccessKey: "HASNA_SKILLS_S3_SECRET_ACCESS_KEY";
62
+ readonly s3SessionToken: "HASNA_SKILLS_S3_SESSION_TOKEN";
63
+ readonly syncBatchSize: "HASNA_SKILLS_SYNC_BATCH_SIZE";
64
+ readonly dryRun: "HASNA_SKILLS_SYNC_DRY_RUN";
65
+ };
66
+ export declare const SKILLS_STORAGE_FALLBACK_ENV: {
67
+ readonly mode: "SKILLS_STORAGE_MODE";
68
+ readonly databaseUrl: "SKILLS_DATABASE_URL";
69
+ readonly databaseSsl: "SKILLS_DATABASE_SSL";
70
+ readonly databaseSchema: "SKILLS_DATABASE_SCHEMA";
71
+ readonly s3Bucket: "SKILLS_S3_BUCKET";
72
+ readonly s3Prefix: "SKILLS_S3_PREFIX";
73
+ readonly awsRegion: "SKILLS_AWS_REGION";
74
+ readonly s3Endpoint: "SKILLS_S3_ENDPOINT";
75
+ readonly s3ForcePathStyle: "SKILLS_S3_FORCE_PATH_STYLE";
76
+ readonly s3AccessKeyId: "SKILLS_S3_ACCESS_KEY_ID";
77
+ readonly s3SecretAccessKey: "SKILLS_S3_SECRET_ACCESS_KEY";
78
+ readonly s3SessionToken: "SKILLS_S3_SESSION_TOKEN";
79
+ readonly syncBatchSize: "SKILLS_SYNC_BATCH_SIZE";
80
+ readonly dryRun: "SKILLS_SYNC_DRY_RUN";
81
+ };
82
+ export declare function resolveSkillsNativeStorageConfig(env?: Record<string, string | undefined>): SkillsNativeStorageConfig;
83
+ export declare function resolveStorageConfig(env?: Record<string, string | undefined>): SkillsNativeStorageConfig;
84
+ export declare function getSkillsStorageMode(env?: Record<string, string | undefined>): SkillsStorageMode;
85
+ export declare function getStorageMode(env?: Record<string, string | undefined>): SkillsStorageMode;
86
+ export declare function getSkillsStorageDatabaseEnv(env?: Record<string, string | undefined>): string;
87
+ export declare function getStorageDatabaseEnv(env?: Record<string, string | undefined>): string;
88
+ export declare function getSkillsStorageDatabaseUrl(env?: Record<string, string | undefined>): string | undefined;
89
+ export declare function getStorageDatabaseUrl(env?: Record<string, string | undefined>): string | undefined;
90
+ export interface SkillsNativeStorageStatus {
91
+ package: "open-skills";
92
+ mode: SkillsStorageMode;
93
+ tables: readonly SkillsStorageTable[];
94
+ env: {
95
+ mode: string;
96
+ databaseUrl: string;
97
+ s3Bucket: string;
98
+ };
99
+ local: {
100
+ dataDir: string;
101
+ projectStateDir: string;
102
+ feedbackDbPath: string;
103
+ };
104
+ remote: {
105
+ databaseConfigured: boolean;
106
+ s3Configured: boolean;
107
+ databaseEnv: string;
108
+ s3BucketEnv: string;
109
+ activeModeEnv: string;
110
+ activeDatabaseEnv: string;
111
+ activeS3BucketEnv: string;
112
+ region: string;
113
+ dryRun: boolean;
114
+ };
115
+ }
116
+ export declare function getSkillsNativeStorageStatus(options?: {
117
+ targetDir?: string;
118
+ env?: Record<string, string | undefined>;
119
+ }): SkillsNativeStorageStatus;
120
+ export declare function getSkillsStorageStatus(options?: {
121
+ targetDir?: string;
122
+ env?: Record<string, string | undefined>;
123
+ }): SkillsNativeStorageStatus;
124
+ export declare function getStorageStatus(options?: {
125
+ targetDir?: string;
126
+ env?: Record<string, string | undefined>;
127
+ }): SkillsNativeStorageStatus;
128
+ export interface SkillsSnapshotFile {
129
+ path: string;
130
+ sizeBytes: number;
131
+ sha256: string;
132
+ contentBase64?: string;
133
+ }
134
+ export interface SkillsLocalSnapshot {
135
+ schemaVersion: 1;
136
+ exportedAt: string;
137
+ files: SkillsSnapshotFile[];
138
+ }
139
+ export declare function exportSkillsLocalSnapshot(targetDir?: string, options?: {
140
+ includeFileContents?: boolean;
141
+ }): SkillsLocalSnapshot;
142
+ export declare function importSkillsLocalSnapshot(snapshot: SkillsLocalSnapshot, targetDir?: string, options?: {
143
+ overwrite?: boolean;
144
+ }): {
145
+ written: number;
146
+ skipped: number;
147
+ };
148
+ export interface SkillsPostgresQueryClient {
149
+ query<T = unknown>(sql: string, values?: readonly unknown[]): Promise<{
150
+ rows: T[];
151
+ }>;
152
+ }
153
+ export interface SkillsSyncRecord {
154
+ scope: string;
155
+ kind: string;
156
+ id: string;
157
+ updatedAt: string;
158
+ deletedAt?: string | null;
159
+ source?: string | null;
160
+ payload: Record<string, unknown>;
161
+ }
162
+ export declare const skillsPostgresSyncSchemaSql: string;
163
+ export declare class SkillsPostgresSyncStore {
164
+ private readonly client;
165
+ constructor(client: SkillsPostgresQueryClient);
166
+ ensureSchema(): Promise<void>;
167
+ upsertRecords(records: readonly SkillsSyncRecord[]): Promise<number>;
168
+ pullUpdatedSince(params: {
169
+ scope: string;
170
+ since?: string;
171
+ limit?: number;
172
+ }): Promise<SkillsSyncRecord[]>;
173
+ getCursor(scope: string, cursorName: string): Promise<string | null>;
174
+ setCursor(scope: string, cursorName: string, value: string): Promise<void>;
175
+ }
176
+ export declare function createSkillsPostgresSyncStore(client: SkillsPostgresQueryClient): SkillsPostgresSyncStore;
177
+ export declare function createSkillsSnapshotSyncRecord(snapshot: SkillsLocalSnapshot, options?: {
178
+ scope?: string;
179
+ id?: string;
180
+ source?: string;
181
+ }): SkillsSyncRecord;
182
+ export interface AwsCredentials {
183
+ accessKeyId: string;
184
+ secretAccessKey: string;
185
+ sessionToken?: string;
186
+ }
187
+ export interface SkillsS3ObjectStoreOptions {
188
+ bucket: string;
189
+ region?: string;
190
+ prefix?: string;
191
+ endpoint?: string;
192
+ forcePathStyle?: boolean;
193
+ credentials: AwsCredentials;
194
+ fetch?: SkillsFetch;
195
+ }
196
+ export interface SkillsS3PutObjectOptions {
197
+ key: string;
198
+ body: Uint8Array | string;
199
+ contentType?: string;
200
+ }
201
+ export interface SkillsS3StoredObject {
202
+ key: string;
203
+ url: string;
204
+ etag?: string | null;
205
+ sizeBytes: number;
206
+ }
207
+ export type SkillsFetch = (input: string | URL | Request, init?: RequestInit) => Promise<Response>;
208
+ export declare class SkillsS3ObjectStore {
209
+ private readonly options;
210
+ private readonly fetchImpl;
211
+ private readonly region;
212
+ private readonly prefix;
213
+ constructor(options: SkillsS3ObjectStoreOptions);
214
+ objectKey(path: string): string;
215
+ objectUrl(key: string): string;
216
+ putObject(params: SkillsS3PutObjectOptions): Promise<SkillsS3StoredObject>;
217
+ getObject(key: string): Promise<Uint8Array>;
218
+ }
219
+ export declare function createSkillsS3ObjectStore(options: SkillsS3ObjectStoreOptions): SkillsS3ObjectStore;
220
+ export interface SkillsS3SnapshotPlanEntry {
221
+ path: string;
222
+ key: string;
223
+ sizeBytes: number;
224
+ sha256: string;
225
+ }
226
+ export declare function planSkillsS3SnapshotUpload(snapshot: SkillsLocalSnapshot, options?: {
227
+ prefix?: string;
228
+ }): SkillsS3SnapshotPlanEntry[];
229
+ export declare function uploadSkillsSnapshotFilesToS3(snapshot: SkillsLocalSnapshot, store: SkillsS3ObjectStore): Promise<SkillsS3StoredObject[]>;
230
+ export interface SignSkillsAwsV4RequestOptions {
231
+ method: string;
232
+ url: string;
233
+ region: string;
234
+ service: string;
235
+ headers?: Record<string, string>;
236
+ body?: Uint8Array | string;
237
+ credentials: AwsCredentials;
238
+ now?: Date;
239
+ }
240
+ export declare function signSkillsAwsV4Request(options: SignSkillsAwsV4RequestOptions): {
241
+ headers: Record<string, string>;
242
+ canonicalRequest: string;
243
+ stringToSign: string;
244
+ };
245
+ export declare function buildSkillsS3ObjectUrl(params: {
246
+ bucket: string;
247
+ key: string;
248
+ region?: string;
249
+ endpoint?: string;
250
+ forcePathStyle?: boolean;
251
+ }): string;
@@ -0,0 +1,79 @@
1
+ import type { SkillMeta } from "./registry-types.js";
2
+ import { type SkillValidationResult } from "./skill-validation.js";
3
+ export declare const PORTABLE_SKILL_STANDARD = "hasna.skill.v1";
4
+ export declare const PORTABLE_SKILL_SCHEMA = "https://hasna.dev/schemas/skill.v1.json";
5
+ export declare const PORTABLE_SKILL_DEFAULT_VERSION = "0.1.0";
6
+ export interface PortableSkillInput {
7
+ name: string;
8
+ type: string;
9
+ required?: boolean;
10
+ description?: string;
11
+ }
12
+ export interface PortableSkillCommand {
13
+ name: string;
14
+ description?: string;
15
+ entry?: string;
16
+ command?: string;
17
+ args?: string[];
18
+ }
19
+ export interface PortableSkillManifest {
20
+ $schema?: string;
21
+ standard: typeof PORTABLE_SKILL_STANDARD | string;
22
+ name: string;
23
+ description: string;
24
+ version: string;
25
+ displayName?: string;
26
+ category?: string;
27
+ tags?: string[];
28
+ inputs: PortableSkillInput[];
29
+ commands: PortableSkillCommand[];
30
+ }
31
+ export interface PortableSkillSummary {
32
+ name: string;
33
+ displayName: string;
34
+ description: string;
35
+ version: string;
36
+ path: string;
37
+ commands: PortableSkillCommand[];
38
+ source: "custom";
39
+ standard: string;
40
+ }
41
+ export interface PortableSkillOptions {
42
+ rootDir?: string;
43
+ homeDir?: string;
44
+ }
45
+ export interface ScaffoldPortableSkillOptions extends PortableSkillOptions {
46
+ description?: string;
47
+ overwrite?: boolean;
48
+ }
49
+ export interface PortPortableSkillOptions extends PortableSkillOptions {
50
+ name?: string;
51
+ overwrite?: boolean;
52
+ }
53
+ export interface PortableSkillWriteResult {
54
+ name: string;
55
+ path: string;
56
+ manifest: PortableSkillManifest;
57
+ created: boolean;
58
+ }
59
+ export interface PortableSkillRunOptions extends PortableSkillOptions {
60
+ stdio?: "inherit" | "pipe";
61
+ env?: Record<string, string>;
62
+ }
63
+ export interface PortableSkillRunResult {
64
+ exitCode: number;
65
+ stdout?: string;
66
+ stderr?: string;
67
+ error?: string;
68
+ }
69
+ export declare function normalizePortableSkillName(name: string): string;
70
+ export declare function getPortableSkillsRoot(options?: PortableSkillOptions): string;
71
+ export declare function getPortableSkillPath(name: string, options?: PortableSkillOptions): string;
72
+ export declare function findPortableSkill(name: string, options?: PortableSkillOptions): PortableSkillSummary | null;
73
+ export declare function listPortableSkills(options?: PortableSkillOptions): PortableSkillSummary[];
74
+ export declare function listPortableSkillMetas(options?: PortableSkillOptions): SkillMeta[];
75
+ export declare function readPortableSkillManifest(skillPath: string, fallbackName?: string): PortableSkillManifest;
76
+ export declare function scaffoldPortableSkill(name: string, options?: ScaffoldPortableSkillOptions): PortableSkillWriteResult;
77
+ export declare function portPortableSkill(sourcePath: string, options?: PortPortableSkillOptions): PortableSkillWriteResult;
78
+ export declare function validatePortableSkillDirectory(name: string, skillPath: string): SkillValidationResult;
79
+ export declare function runPortableSkill(name: string, args: string[], options?: PortableSkillRunOptions): Promise<PortableSkillRunResult>;
@@ -8,7 +8,7 @@ export type { Category, SkillMeta, SkillRegistryProfile };
8
8
  export declare function isBasicSkillName(name: string): boolean;
9
9
  /**
10
10
  * Load the full registry: official skills merged with global custom skills
11
- * from ~/.hasna/skills/custom/.
11
+ * from ~/.hasna/skills/<name>/ and the legacy ~/.hasna/skills/custom/<name>/ path.
12
12
  *
13
13
  * Custom skills with the same name as official skills take precedence.
14
14
  * Results are cached for 5 seconds.
@@ -1,4 +1,5 @@
1
1
  import type { SkillMeta } from "./registry.js";
2
+ import type { PortableSkillManifest } from "./portable-skills.js";
2
3
  export interface SkillValidationMessage {
3
4
  code: string;
4
5
  message: string;
@@ -15,6 +16,7 @@ export interface SkillValidationResult {
15
16
  binCommands: string[];
16
17
  docFiles: string[];
17
18
  skillMdFrontmatter?: SkillFrontmatter;
19
+ portableManifest?: PortableSkillManifest;
18
20
  provenance?: SkillValidationProvenance;
19
21
  runtime?: "local" | "hosted";
20
22
  };
@@ -0,0 +1,2 @@
1
+ import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ export declare function registerStorageTools(server: McpServer): void;
@@ -0,0 +1 @@
1
+ export { SKILLS_NATIVE_STORAGE_ENV, SKILLS_NATIVE_STORAGE_FALLBACK_ENV, SKILLS_STORAGE_ENV, SKILLS_STORAGE_FALLBACK_ENV, SKILLS_STORAGE_TABLES, STORAGE_TABLES, SkillsPostgresSyncStore, SkillsS3ObjectStore, buildSkillsS3ObjectUrl, createSkillsPostgresSyncStore, createSkillsS3ObjectStore, createSkillsSnapshotSyncRecord, exportSkillsLocalSnapshot, getSkillsNativeStorageStatus, getSkillsStorageDatabaseEnv, getSkillsStorageDatabaseUrl, getSkillsStorageMode, getSkillsStorageStatus, getStorageDatabaseEnv, getStorageDatabaseUrl, getStorageMode, getStorageStatus, importSkillsLocalSnapshot, planSkillsS3SnapshotUpload, resolveSkillsNativeStorageConfig, resolveStorageConfig, signSkillsAwsV4Request, skillsPostgresSyncSchemaSql, uploadSkillsSnapshotFilesToS3, type AwsCredentials, type SignSkillsAwsV4RequestOptions, type SkillsFetch, type SkillsLocalSnapshot, type SkillsNativeStorageConfig, type SkillsNativeStorageStatus, type SkillsPostgresQueryClient, type SkillsS3ObjectStoreOptions, type SkillsS3PutObjectOptions, type SkillsS3SnapshotPlanEntry, type SkillsS3StoredObject, type SkillsSnapshotFile, type SkillsStorageMode, type SkillsStorageTable, type SkillsSyncRecord, } from "./lib/native-storage.js";