@hasna/skills 0.7.2 → 0.8.0
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/README.md +69 -18
- package/bin/index.js +31416 -17660
- package/bin/mcp.js +20185 -5957
- package/bin/migrate.js +24 -61
- package/bin/server.js +73578 -20340
- package/bin/worker.js +65161 -19252
- package/dist/admin-contract.js +34 -15
- package/dist/index.d.ts +1 -1
- package/dist/index.js +19581 -5535
- package/dist/lib/agent-discovery-bytes.d.ts +1 -0
- package/dist/lib/agent-discovery-path-bytes.d.ts +5 -0
- package/dist/lib/agent-discovery.d.ts +3 -1
- package/dist/lib/agent-policy-limits.d.ts +4 -0
- package/dist/lib/config.d.ts +3 -23
- package/dist/lib/installer.d.ts +1 -1
- package/dist/lib/portable-skills-types.d.ts +2 -0
- package/dist/lib/portable-skills.d.ts +1 -1
- package/dist/lib/registry-data/index.d.ts +1 -0
- package/dist/lib/registry-types.d.ts +2 -1
- package/dist/lib/registry.d.ts +2 -12
- package/dist/lib/release-dependencies.d.ts +30 -0
- package/dist/lib/skill-aliases.d.ts +2 -3
- package/dist/mcp/mcp-test-client.d.ts +2 -2
- package/dist/sdk/executor.d.ts +5 -5
- package/dist/sdk/index.js +89668 -40182
- package/dist/sdk/registry.d.ts +3 -3
- package/dist/server/config.d.ts +1 -2
- package/dist/server/handlers.d.ts +5 -2
- package/dist/server/registry.d.ts +6 -3
- package/dist/server/skills-api.d.ts +6 -38
- package/dist/storage.js +5 -42
- package/package.json +5 -3
- package/dist/lib/registry-data/business-marketing.d.ts +0 -2
- package/dist/lib/registry-data/communication.d.ts +0 -2
- package/dist/lib/registry-data/content-generation.d.ts +0 -2
- package/dist/lib/registry-data/data-analysis.d.ts +0 -2
- package/dist/lib/registry-data/design-branding.d.ts +0 -2
- package/dist/lib/registry-data/development-tools.d.ts +0 -2
- package/dist/lib/registry-data/education-learning.d.ts +0 -2
- package/dist/lib/registry-data/event-management.d.ts +0 -2
- package/dist/lib/registry-data/finance-compliance.d.ts +0 -2
- package/dist/lib/registry-data/health-wellness.d.ts +0 -2
- package/dist/lib/registry-data/media-processing.d.ts +0 -2
- package/dist/lib/registry-data/productivity-organization.d.ts +0 -2
- package/dist/lib/registry-data/project-management.d.ts +0 -2
- package/dist/lib/registry-data/research-writing.d.ts +0 -2
- package/dist/lib/registry-data/science-academic.d.ts +0 -2
- package/dist/lib/registry-data/travel-lifestyle.d.ts +0 -2
- package/dist/lib/registry-data/web-browser.d.ts +0 -2
- package/dist/server/seed-bundled.d.ts +0 -20
package/bin/migrate.js
CHANGED
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// src/server/migrate.ts
|
|
5
|
-
import { existsSync as existsSync4, readdirSync as
|
|
6
|
-
import { join as
|
|
5
|
+
import { existsSync as existsSync4, readdirSync as readdirSync2, readFileSync as readFileSync3 } from "fs";
|
|
6
|
+
import { join as join5 } from "path";
|
|
7
7
|
// package.json
|
|
8
8
|
var package_default = {
|
|
9
9
|
name: "@hasna/skills",
|
|
10
|
-
version: "0.
|
|
10
|
+
version: "0.8.0",
|
|
11
11
|
description: "Skills library for AI coding agents",
|
|
12
12
|
type: "module",
|
|
13
13
|
bin: {
|
|
@@ -70,7 +70,8 @@ var package_default = {
|
|
|
70
70
|
"verify:consumer-types": "bun run scripts/consumer-types.ts",
|
|
71
71
|
prepare: "bun run build:js",
|
|
72
72
|
prepack: "bun run build && bun run verify:release && bun run verify:consumer-types",
|
|
73
|
-
prepublishOnly: "bun run typecheck && bun run test"
|
|
73
|
+
prepublishOnly: "bun run verify:producer && bun run typecheck && bun run test",
|
|
74
|
+
"verify:producer": "bun run scripts/release-dependencies.ts"
|
|
74
75
|
},
|
|
75
76
|
keywords: [
|
|
76
77
|
"skills",
|
|
@@ -91,7 +92,8 @@ var package_default = {
|
|
|
91
92
|
author: "Hasna",
|
|
92
93
|
license: "Apache-2.0",
|
|
93
94
|
devDependencies: {
|
|
94
|
-
"@hasna/contracts": "1.0
|
|
95
|
+
"@hasna/contracts": "1.1.0",
|
|
96
|
+
"@hasna/secrets": "0.4.2",
|
|
95
97
|
"@types/bun": "1.3.14",
|
|
96
98
|
"@types/node": "25.2.3",
|
|
97
99
|
"@types/react": "^18.2.0",
|
|
@@ -188,7 +190,6 @@ function resolveServerConfig(env = process.env) {
|
|
|
188
190
|
port,
|
|
189
191
|
databaseUrl: env[DATABASE_URL_ENV] || env.DATABASE_URL || undefined,
|
|
190
192
|
bootstrapApiKey: env.HASNA_SKILLS_BOOTSTRAP_API_KEY || undefined,
|
|
191
|
-
seedBundledCorpus: (env.HASNA_SKILLS_SEED_BUNDLED_CORPUS ?? "1") !== "0",
|
|
192
193
|
artifactBucket: env.HASNA_SKILLS_S3_BUCKET || env.SKILLS_S3_BUCKET || undefined,
|
|
193
194
|
artifactPrefix: normalizePrefix(env.HASNA_SKILLS_S3_PREFIX || env.SKILLS_S3_PREFIX || "skills/artifacts"),
|
|
194
195
|
runArtifactPrefix: env.HASNA_SKILLS_S3_RUN_PREFIX ? normalizePrefix(env.HASNA_SKILLS_S3_RUN_PREFIX) : undefined,
|
|
@@ -215,12 +216,11 @@ function normalizePrefix(value) {
|
|
|
215
216
|
}
|
|
216
217
|
|
|
217
218
|
// src/server/database-url.ts
|
|
218
|
-
import { isAbsolute, join as
|
|
219
|
+
import { isAbsolute, join as join2 } from "path";
|
|
219
220
|
import { fileURLToPath } from "url";
|
|
220
221
|
|
|
221
222
|
// src/lib/config.ts
|
|
222
|
-
import { existsSync as existsSync2, readFileSync, writeFileSync, mkdirSync
|
|
223
|
-
import { join as join2, dirname } from "path";
|
|
223
|
+
import { existsSync as existsSync2, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
224
224
|
|
|
225
225
|
// src/lib/app-home.ts
|
|
226
226
|
import { existsSync } from "fs";
|
|
@@ -280,12 +280,6 @@ function exactDataRoot() {
|
|
|
280
280
|
}
|
|
281
281
|
return;
|
|
282
282
|
}
|
|
283
|
-
function hasExactOverride(env = process.env) {
|
|
284
|
-
return Boolean(env[DATA_DIR_ENV]?.trim()) || Boolean(env[HASNA_SKILLS_HOME_ENV]?.trim()) || Boolean(env[SKILLS_HOME_ENV]?.trim());
|
|
285
|
-
}
|
|
286
|
-
function hasOperatorOverride(env = process.env) {
|
|
287
|
-
return hasExactOverride(env) || Boolean(env.HASNA_DATA_HOME?.trim());
|
|
288
|
-
}
|
|
289
283
|
function getDataRoot() {
|
|
290
284
|
const exact = exactDataRoot();
|
|
291
285
|
if (exact)
|
|
@@ -294,42 +288,11 @@ function getDataRoot() {
|
|
|
294
288
|
return adoptResolverDataRoot(resolved) ? resolve(resolved) : resolve(legacyDataRoot());
|
|
295
289
|
}
|
|
296
290
|
// src/lib/config.ts
|
|
297
|
-
function mergeDirectoryContents(sourceDir, targetDir) {
|
|
298
|
-
if (!existsSync2(sourceDir))
|
|
299
|
-
return;
|
|
300
|
-
mkdirSync(targetDir, { recursive: true });
|
|
301
|
-
for (const entry of readdirSync(sourceDir)) {
|
|
302
|
-
const sourcePath = join2(sourceDir, entry);
|
|
303
|
-
const targetPath = join2(targetDir, entry);
|
|
304
|
-
try {
|
|
305
|
-
const sourceStat = statSync(sourcePath);
|
|
306
|
-
if (sourceStat.isDirectory()) {
|
|
307
|
-
mergeDirectoryContents(sourcePath, targetPath);
|
|
308
|
-
continue;
|
|
309
|
-
}
|
|
310
|
-
if (!existsSync2(targetPath))
|
|
311
|
-
copyFileSync(sourcePath, targetPath);
|
|
312
|
-
} catch {}
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
291
|
function getDataDir() {
|
|
316
292
|
const root = getDataRoot();
|
|
317
293
|
try {
|
|
318
294
|
mkdirSync(root, { recursive: true });
|
|
319
295
|
} catch {}
|
|
320
|
-
if (hasOperatorOverride())
|
|
321
|
-
return root;
|
|
322
|
-
const home = effectiveHome();
|
|
323
|
-
const oldDir = join2(home, ".skills");
|
|
324
|
-
const oldConfigFile = join2(home, ".skillsrc");
|
|
325
|
-
try {
|
|
326
|
-
mergeDirectoryContents(oldDir, root);
|
|
327
|
-
} catch {}
|
|
328
|
-
if (existsSync2(oldConfigFile) && !existsSync2(join2(root, "config.json"))) {
|
|
329
|
-
try {
|
|
330
|
-
copyFileSync(oldConfigFile, join2(root, "config.json"));
|
|
331
|
-
} catch {}
|
|
332
|
-
}
|
|
333
296
|
return root;
|
|
334
297
|
}
|
|
335
298
|
|
|
@@ -341,7 +304,7 @@ var SQLITE_SCHEMES = new Set(["sqlite", "sqlite3", "file"]);
|
|
|
341
304
|
var MEMORY_SCHEMES = new Set(["memory"]);
|
|
342
305
|
var SQLITE_EXTENSIONS = [".db", ".sqlite", ".sqlite3", ".db3"];
|
|
343
306
|
function defaultSqlitePath() {
|
|
344
|
-
return
|
|
307
|
+
return join2(getDataDir(), DEFAULT_SQLITE_FILENAME2);
|
|
345
308
|
}
|
|
346
309
|
function resolveDatabaseTarget(raw) {
|
|
347
310
|
const value = raw?.trim();
|
|
@@ -368,7 +331,7 @@ function resolveDatabaseTarget(raw) {
|
|
|
368
331
|
throw new Error(`unsupported database scheme "${scheme}:". Supported: postgres://, postgresql://, sqlite:, file:, ` + `an absolute or relative path to a .db/.sqlite file, ":memory:", or "memory:" (non-durable, tests only). ` + `Leave the setting empty to use the default SQLite database at ${defaultSqlitePath()}.`);
|
|
369
332
|
}
|
|
370
333
|
if (looksLikeSqlitePath(value)) {
|
|
371
|
-
const path = isAbsolute(value) ? value :
|
|
334
|
+
const path = isAbsolute(value) ? value : join2(process.cwd(), value);
|
|
372
335
|
return { kind: "sqlite", path, durable: true, label: `sqlite (${path})` };
|
|
373
336
|
}
|
|
374
337
|
throw new Error(`could not resolve a database backend from "${value}". Use postgres://\u2026, sqlite:\u2026, an absolute or ` + `relative path ending in ${SQLITE_EXTENSIONS.join("/")}, ":memory:", or leave it empty for the ` + `default SQLite database at ${defaultSqlitePath()}.`);
|
|
@@ -392,7 +355,7 @@ function sqlitePathFromUrl(value, scheme) {
|
|
|
392
355
|
}
|
|
393
356
|
return rest.slice(2).replace(/^\/\/+/, "/");
|
|
394
357
|
}
|
|
395
|
-
return isAbsolute(rest) ? rest :
|
|
358
|
+
return isAbsolute(rest) ? rest : join2(process.cwd(), rest);
|
|
396
359
|
}
|
|
397
360
|
function looksLikeSqlitePath(value) {
|
|
398
361
|
if (value.includes("/"))
|
|
@@ -402,17 +365,17 @@ function looksLikeSqlitePath(value) {
|
|
|
402
365
|
|
|
403
366
|
// src/server/migrations-dir.ts
|
|
404
367
|
import { existsSync as existsSync3 } from "fs";
|
|
405
|
-
import { dirname
|
|
368
|
+
import { dirname, join as join3 } from "path";
|
|
406
369
|
var MIGRATION_DIALECTS = ["postgres", "sqlite"];
|
|
407
370
|
var MAX_WALK_UP = 6;
|
|
408
371
|
function findMigrationsRoot(startDirs = defaultStartDirs()) {
|
|
409
372
|
for (const start of startDirs) {
|
|
410
373
|
let dir = start;
|
|
411
374
|
for (let level = 0;level < MAX_WALK_UP; level += 1) {
|
|
412
|
-
const candidate =
|
|
413
|
-
if (MIGRATION_DIALECTS.some((dialect) => existsSync3(
|
|
375
|
+
const candidate = join3(dir, "migrations");
|
|
376
|
+
if (MIGRATION_DIALECTS.some((dialect) => existsSync3(join3(candidate, dialect))))
|
|
414
377
|
return candidate;
|
|
415
|
-
const parent =
|
|
378
|
+
const parent = dirname(dir);
|
|
416
379
|
if (parent === dir)
|
|
417
380
|
break;
|
|
418
381
|
dir = parent;
|
|
@@ -424,7 +387,7 @@ function resolveMigrationsDir(dialect, root = findMigrationsRoot()) {
|
|
|
424
387
|
if (!root) {
|
|
425
388
|
throw new Error(`could not locate the migrations directory for dialect "${dialect}". ` + `Expected a migrations/${dialect}/ folder alongside the package root.`);
|
|
426
389
|
}
|
|
427
|
-
const dir =
|
|
390
|
+
const dir = join3(root, dialect);
|
|
428
391
|
if (!existsSync3(dir)) {
|
|
429
392
|
throw new Error(`migrations directory not found: ${dir}`);
|
|
430
393
|
}
|
|
@@ -539,8 +502,8 @@ class SqliteSkillSelectionStore {
|
|
|
539
502
|
|
|
540
503
|
// src/server/sqlite-store.ts
|
|
541
504
|
import { randomUUID as randomUUID3 } from "crypto";
|
|
542
|
-
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, readdirSync
|
|
543
|
-
import { dirname as
|
|
505
|
+
import { mkdirSync as mkdirSync2, readFileSync as readFileSync2, readdirSync } from "fs";
|
|
506
|
+
import { dirname as dirname2, join as join4 } from "path";
|
|
544
507
|
|
|
545
508
|
// src/server/auth.ts
|
|
546
509
|
import { createHash } from "crypto";
|
|
@@ -1100,7 +1063,7 @@ class SqliteSkillsStore {
|
|
|
1100
1063
|
constructor(path = SQLITE_MEMORY_PATH, options = {}) {
|
|
1101
1064
|
const inMemory = path === SQLITE_MEMORY_PATH;
|
|
1102
1065
|
if (!inMemory)
|
|
1103
|
-
mkdirSync2(
|
|
1066
|
+
mkdirSync2(dirname2(path), { recursive: true });
|
|
1104
1067
|
this.db = openDatabase(path);
|
|
1105
1068
|
this.db.exec(`PRAGMA busy_timeout = ${Math.max(0, options.busyTimeoutMs ?? 5000)}`);
|
|
1106
1069
|
if (!inMemory)
|
|
@@ -1653,14 +1616,14 @@ function applySqliteMigrations(db, migrationsDir = resolveMigrationsDir("sqlite"
|
|
|
1653
1616
|
version text PRIMARY KEY,
|
|
1654
1617
|
applied_at text NOT NULL DEFAULT (strftime('%Y-%m-%dT%H:%M:%fZ', 'now'))
|
|
1655
1618
|
)`);
|
|
1656
|
-
const files =
|
|
1619
|
+
const files = readdirSync(migrationsDir).filter((name) => name.endsWith(".sql")).sort();
|
|
1657
1620
|
if (files.length === 0) {
|
|
1658
1621
|
throw new Error(`no .sql migrations found in ${migrationsDir}`);
|
|
1659
1622
|
}
|
|
1660
1623
|
const appliedNow = [];
|
|
1661
1624
|
for (const file of files) {
|
|
1662
1625
|
const version = file.replace(/\.sql$/, "");
|
|
1663
|
-
const text = readFileSync2(
|
|
1626
|
+
const text = readFileSync2(join4(migrationsDir, file), "utf8");
|
|
1664
1627
|
const apply = db.transaction(() => {
|
|
1665
1628
|
const already = db.query("SELECT 1 AS present FROM schema_migrations WHERE version = ? LIMIT 1").get(version);
|
|
1666
1629
|
if (already)
|
|
@@ -1742,14 +1705,14 @@ async function runPostgresMigrations(databaseUrl, migrationsDir) {
|
|
|
1742
1705
|
const appliedRows = await sql`SELECT version FROM schema_migrations`;
|
|
1743
1706
|
const applied = new Set(appliedRows.map((row) => row.version));
|
|
1744
1707
|
const appliedNow = [];
|
|
1745
|
-
const files =
|
|
1708
|
+
const files = readdirSync2(migrationsDir).filter((name) => name.endsWith(".sql")).sort();
|
|
1746
1709
|
if (files.length === 0)
|
|
1747
1710
|
throw new Error(`no .sql migrations found in ${migrationsDir}`);
|
|
1748
1711
|
for (const file of files) {
|
|
1749
1712
|
const version = file.replace(/\.sql$/, "");
|
|
1750
1713
|
if (applied.has(version))
|
|
1751
1714
|
continue;
|
|
1752
|
-
const sqlText = readFileSync3(
|
|
1715
|
+
const sqlText = readFileSync3(join5(migrationsDir, file), "utf8");
|
|
1753
1716
|
await sql.unsafe("BEGIN");
|
|
1754
1717
|
try {
|
|
1755
1718
|
await sql.unsafe(sqlText);
|