@hasna/skills 0.5.3 → 0.5.5

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/bin/migrate.js CHANGED
@@ -7,7 +7,7 @@ import { join as join6 } from "path";
7
7
  // package.json
8
8
  var package_default = {
9
9
  name: "@hasna/skills",
10
- version: "0.5.3",
10
+ version: "0.5.5",
11
11
  description: "Skills library for AI coding agents",
12
12
  type: "module",
13
13
  bin: {
@@ -1246,10 +1246,16 @@ class SqliteSkillsStore {
1246
1246
  const orgId = input.principal.orgId;
1247
1247
  const now = nowIso();
1248
1248
  return this.db.transaction(() => {
1249
- const previous = this.get("SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at FROM skills_registry WHERE org_id = ? AND slug = ?", [orgId, input.slug]);
1249
+ const previous = this.get("SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at, source FROM skills_registry WHERE org_id = ? AND slug = ?", [orgId, input.slug]);
1250
1250
  const previousSha = typeof previous?.bundle_sha256 === "string" ? previous.bundle_sha256 : null;
1251
1251
  const previousRevisionId = typeof previous?.revision_id === "string" && previous.revision_id ? previous.revision_id : null;
1252
1252
  const tombstoned = previous?.tombstoned_at != null;
1253
+ if (input.seedBundledOnly && input.expectedRevisionId && !previous) {
1254
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
1255
+ }
1256
+ if (input.seedBundledOnly && previous && (tombstoned || previous.source !== "bundled")) {
1257
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
1258
+ }
1253
1259
  const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : typeof previous?.skill_md === "string" ? previous.skill_md : null;
1254
1260
  if (previous && !tombstoned && input.expectedRevisionId !== previousRevisionId) {
1255
1261
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
@@ -1323,8 +1329,9 @@ class SqliteSkillsStore {
1323
1329
  tombstoned_at = NULL,
1324
1330
  tombstone_purge_after = NULL,
1325
1331
  updated_at = excluded.updated_at
1326
- WHERE skills_registry.tombstoned_at IS NOT NULL
1327
- OR skills_registry.revision_id = ?
1332
+ WHERE (skills_registry.tombstoned_at IS NOT NULL OR skills_registry.revision_id = ?)
1333
+ AND (? = 0 OR (skills_registry.tombstoned_at IS NULL AND skills_registry.source = 'bundled'
1334
+ AND skills_registry.revision_id = ?))
1328
1335
  RETURNING *`, [
1329
1336
  orgId,
1330
1337
  input.slug,
@@ -1342,6 +1349,8 @@ class SqliteSkillsStore {
1342
1349
  revisionId,
1343
1350
  now,
1344
1351
  now,
1352
+ input.expectedRevisionId ?? NO_REVISION_SENTINEL,
1353
+ input.seedBundledOnly ? 1 : 0,
1345
1354
  input.expectedRevisionId ?? NO_REVISION_SENTINEL
1346
1355
  ]);
1347
1356
  if (!row) {
package/bin/server.js CHANGED
@@ -23100,7 +23100,7 @@ var init_dist_es9 = __esm(() => {
23100
23100
  // package.json
23101
23101
  var package_default = {
23102
23102
  name: "@hasna/skills",
23103
- version: "0.5.3",
23103
+ version: "0.5.5",
23104
23104
  description: "Skills library for AI coding agents",
23105
23105
  type: "module",
23106
23106
  bin: {
@@ -34472,10 +34472,16 @@ class SqliteSkillsStore {
34472
34472
  const orgId = input.principal.orgId;
34473
34473
  const now = nowIso();
34474
34474
  return this.db.transaction(() => {
34475
- const previous = this.get("SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at FROM skills_registry WHERE org_id = ? AND slug = ?", [orgId, input.slug]);
34475
+ const previous = this.get("SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at, source FROM skills_registry WHERE org_id = ? AND slug = ?", [orgId, input.slug]);
34476
34476
  const previousSha = typeof previous?.bundle_sha256 === "string" ? previous.bundle_sha256 : null;
34477
34477
  const previousRevisionId = typeof previous?.revision_id === "string" && previous.revision_id ? previous.revision_id : null;
34478
34478
  const tombstoned = previous?.tombstoned_at != null;
34479
+ if (input.seedBundledOnly && input.expectedRevisionId && !previous) {
34480
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
34481
+ }
34482
+ if (input.seedBundledOnly && previous && (tombstoned || previous.source !== "bundled")) {
34483
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
34484
+ }
34479
34485
  const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : typeof previous?.skill_md === "string" ? previous.skill_md : null;
34480
34486
  if (previous && !tombstoned && input.expectedRevisionId !== previousRevisionId) {
34481
34487
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
@@ -34549,8 +34555,9 @@ class SqliteSkillsStore {
34549
34555
  tombstoned_at = NULL,
34550
34556
  tombstone_purge_after = NULL,
34551
34557
  updated_at = excluded.updated_at
34552
- WHERE skills_registry.tombstoned_at IS NOT NULL
34553
- OR skills_registry.revision_id = ?
34558
+ WHERE (skills_registry.tombstoned_at IS NOT NULL OR skills_registry.revision_id = ?)
34559
+ AND (? = 0 OR (skills_registry.tombstoned_at IS NULL AND skills_registry.source = 'bundled'
34560
+ AND skills_registry.revision_id = ?))
34554
34561
  RETURNING *`, [
34555
34562
  orgId,
34556
34563
  input.slug,
@@ -34568,6 +34575,8 @@ class SqliteSkillsStore {
34568
34575
  revisionId,
34569
34576
  now,
34570
34577
  now,
34578
+ input.expectedRevisionId ?? NO_REVISION_SENTINEL,
34579
+ input.seedBundledOnly ? 1 : 0,
34571
34580
  input.expectedRevisionId ?? NO_REVISION_SENTINEL
34572
34581
  ]);
34573
34582
  if (!row) {
@@ -36875,6 +36884,12 @@ async function storePublishedSkill(store, artifactStorage, principal, parsed, ex
36875
36884
  principal,
36876
36885
  ...expectedRevisionId ? { expectedRevisionId } : {}
36877
36886
  };
36887
+ if (input.seedBundledOnly && expectedRevisionId && !current) {
36888
+ throw new SkillRevisionConflictError(input.slug, expectedRevisionId, null);
36889
+ }
36890
+ if (input.seedBundledOnly && current && (current.tombstonedAt || current.source !== "bundled")) {
36891
+ throw new SkillRevisionConflictError(input.slug, expectedRevisionId, current.revisionId);
36892
+ }
36878
36893
  if (current && !current.tombstonedAt && expectedRevisionId !== current.revisionId) {
36879
36894
  throw new SkillRevisionConflictError(input.slug, expectedRevisionId, current.revisionId);
36880
36895
  }
@@ -37124,6 +37139,15 @@ async function seedBundledCorpus(options) {
37124
37139
  result.skipped.push(slug);
37125
37140
  continue;
37126
37141
  }
37142
+ const current = await options.store.getSkill(options.principal, slug);
37143
+ if (current) {
37144
+ const previousVersion = current.version ? await options.store.getSkillVersion(options.principal, slug, current.version) : null;
37145
+ const provenance = previousVersion?.manifest.provenance;
37146
+ if (current.tombstonedAt || current.source !== "bundled" || provenance?.seededFrom !== "bundled-corpus" || provenance.seededRevisionId !== current.revisionId) {
37147
+ result.skipped.push(slug);
37148
+ continue;
37149
+ }
37150
+ }
37127
37151
  const dir = getSkillPath(slug);
37128
37152
  if (!existsSync11(dir)) {
37129
37153
  result.skipped.push(slug);
@@ -37133,32 +37157,40 @@ async function seedBundledCorpus(options) {
37133
37157
  const packed = packSkillBundle(dir, { maxUnpackedBytes: 50000000 });
37134
37158
  const skillMdPath = join14(dir, "SKILL.md");
37135
37159
  const skillMd = existsSync11(skillMdPath) ? readFileSync11(skillMdPath, "utf-8") : undefined;
37136
- const current = await options.store.getSkill(options.principal, slug);
37160
+ const content = {
37161
+ slug,
37162
+ displayName: manifest.displayName ?? skill.displayName ?? slug,
37163
+ description: manifest.description ?? skill.description ?? slug,
37164
+ category: manifest.category ?? skill.category ?? "Development Tools",
37165
+ tags: manifest.tags ?? skill.tags ?? [],
37166
+ source: "bundled",
37167
+ kind: manifest.kind ?? "instruction",
37168
+ version: version2,
37169
+ ...skillMd ? { skillMd } : {},
37170
+ bundleSha256: packed.sha256,
37171
+ bundleByteSize: packed.bytes.byteLength
37172
+ };
37137
37173
  const { record } = await storePublishedSkill(options.store, options.artifactStorage, options.principal, {
37138
37174
  input: {
37139
- slug,
37140
- displayName: manifest.displayName ?? skill.displayName ?? slug,
37141
- description: manifest.description ?? skill.description ?? slug,
37142
- category: manifest.category ?? skill.category ?? "Development Tools",
37143
- tags: manifest.tags ?? skill.tags ?? [],
37144
- source: "bundled",
37145
- kind: manifest.kind ?? "instruction",
37146
- version: version2,
37147
- ...skillMd ? { skillMd } : {},
37175
+ ...content,
37176
+ seedBundledOnly: true,
37148
37177
  bundle: { sha256: packed.sha256, byteSize: packed.bytes.byteLength, contentType: "application/gzip", storageKind: "db" },
37149
37178
  versionManifest: {
37150
37179
  files: packed.paths,
37151
37180
  fileCount: packed.fileCount,
37152
37181
  unpackedByteSize: packed.unpackedByteSize,
37153
37182
  bundleSha256: packed.sha256,
37154
- provenance: { seededFrom: "bundled-corpus", packageVersion: package_default.version }
37183
+ provenance: { seededFrom: "bundled-corpus", packageVersion: package_default.version, seededRevisionId: revisionIdOfRecord(content) }
37155
37184
  }
37156
37185
  },
37157
37186
  bundleBytes: packed.bytes
37158
37187
  }, current?.revisionId);
37159
37188
  result.seeded.push(`${record.slug}@${version2}`);
37160
37189
  } catch (error) {
37161
- result.failed.push({ slug, error: error.message });
37190
+ if (error instanceof SkillRevisionConflictError)
37191
+ result.skipped.push(slug);
37192
+ else
37193
+ result.failed.push({ slug, error: error.message });
37162
37194
  }
37163
37195
  }
37164
37196
  log(`skills: bundled corpus seed v${version2}: ${result.seeded.length} seeded, ${result.skipped.length} skipped, ${result.failed.length} failed`);
@@ -37368,6 +37400,12 @@ class MemorySkillsStore {
37368
37400
  const key = skillKey(input.principal.orgId, input.slug);
37369
37401
  const now = nowIso();
37370
37402
  const previous = this.skills.get(key);
37403
+ if (input.seedBundledOnly && input.expectedRevisionId && !previous) {
37404
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
37405
+ }
37406
+ if (input.seedBundledOnly && previous && (previous.tombstonedAt || previous.source !== "bundled")) {
37407
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previous.revisionId);
37408
+ }
37371
37409
  if (previous && !previous.tombstonedAt && input.expectedRevisionId !== previous.revisionId) {
37372
37410
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previous.revisionId);
37373
37411
  }
@@ -37821,13 +37859,19 @@ class PostgresSkillsStore {
37821
37859
  const orgId = input.principal.orgId;
37822
37860
  return await this.sql.begin(async (tx) => {
37823
37861
  const previousRows = await tx`
37824
- SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at
37862
+ SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at, source
37825
37863
  FROM skills_registry WHERE org_id = ${orgId} AND slug = ${input.slug} LIMIT 1
37826
37864
  `;
37827
37865
  const previous = previousRows[0];
37828
37866
  const previousSha = typeof previous?.bundle_sha256 === "string" ? String(previous.bundle_sha256) : null;
37829
37867
  const previousRevisionId = typeof previous?.revision_id === "string" && previous.revision_id ? String(previous.revision_id) : null;
37830
37868
  const tombstoned = previous?.tombstoned_at != null;
37869
+ if (input.seedBundledOnly && input.expectedRevisionId && !previous) {
37870
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
37871
+ }
37872
+ if (input.seedBundledOnly && previous && (tombstoned || previous.source !== "bundled")) {
37873
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
37874
+ }
37831
37875
  const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : typeof previous?.skill_md === "string" ? String(previous.skill_md) : null;
37832
37876
  if (previous && !tombstoned && input.expectedRevisionId !== previousRevisionId) {
37833
37877
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
@@ -37868,6 +37912,12 @@ class PostgresSkillsStore {
37868
37912
  body_blob = EXCLUDED.body_blob
37869
37913
  `;
37870
37914
  }
37915
+ if (input.seedBundledOnly) {
37916
+ const seedRows = await tx`SELECT revision_id FROM skills_registry WHERE org_id = ${orgId} AND slug = ${input.slug} FOR UPDATE`;
37917
+ if (input.expectedRevisionId && !seedRows[0]) {
37918
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
37919
+ }
37920
+ }
37871
37921
  const rows = await tx`
37872
37922
  INSERT INTO skills_registry (org_id, slug, display_name, description, category, tags_json, source, kind, version, skill_md,
37873
37923
  bundle_sha256, bundle_byte_size, published_by_user_id, revision_id, revision_number, updated_at)
@@ -37896,8 +37946,11 @@ class PostgresSkillsStore {
37896
37946
  tombstoned_at = NULL,
37897
37947
  tombstone_purge_after = NULL,
37898
37948
  updated_at = EXCLUDED.updated_at
37899
- WHERE skills_registry.tombstoned_at IS NOT NULL
37900
- OR skills_registry.revision_id = ${input.expectedRevisionId ?? NO_REVISION_SENTINEL2}
37949
+ WHERE (skills_registry.tombstoned_at IS NOT NULL
37950
+ OR skills_registry.revision_id = ${input.expectedRevisionId ?? NO_REVISION_SENTINEL2})
37951
+ AND (NOT ${Boolean(input.seedBundledOnly)} OR
37952
+ (skills_registry.tombstoned_at IS NULL AND skills_registry.source = 'bundled'
37953
+ AND skills_registry.revision_id = ${input.expectedRevisionId ?? NO_REVISION_SENTINEL2}))
37901
37954
  RETURNING *
37902
37955
  `;
37903
37956
  if (!rows[0]) {
@@ -38312,6 +38365,15 @@ async function createSkillsFetchHandler(options = {}) {
38312
38365
  }
38313
38366
  return async function fetch(request) {
38314
38367
  const url = new URL(request.url);
38368
+ const versionedAliases = {
38369
+ "/v1/health": "/health",
38370
+ "/v1/auth/whoami": "/api/auth/whoami"
38371
+ };
38372
+ const alias = versionedAliases[url.pathname] ?? (url.pathname === "/v1" || url.pathname.startsWith("/v1/") ? `/api${url.pathname}` : undefined);
38373
+ if (alias) {
38374
+ url.pathname = alias;
38375
+ request = new Request(url, request);
38376
+ }
38315
38377
  const segments = pathSegments(url.pathname);
38316
38378
  try {
38317
38379
  if (request.method === "GET" && url.pathname === "/health") {
package/bin/worker.js CHANGED
@@ -23103,7 +23103,7 @@ import { randomUUID as randomUUID4 } from "crypto";
23103
23103
  // package.json
23104
23104
  var package_default = {
23105
23105
  name: "@hasna/skills",
23106
- version: "0.5.3",
23106
+ version: "0.5.5",
23107
23107
  description: "Skills library for AI coding agents",
23108
23108
  type: "module",
23109
23109
  bin: {
@@ -34128,10 +34128,16 @@ class SqliteSkillsStore {
34128
34128
  const orgId = input.principal.orgId;
34129
34129
  const now = nowIso();
34130
34130
  return this.db.transaction(() => {
34131
- const previous = this.get("SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at FROM skills_registry WHERE org_id = ? AND slug = ?", [orgId, input.slug]);
34131
+ const previous = this.get("SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at, source FROM skills_registry WHERE org_id = ? AND slug = ?", [orgId, input.slug]);
34132
34132
  const previousSha = typeof previous?.bundle_sha256 === "string" ? previous.bundle_sha256 : null;
34133
34133
  const previousRevisionId = typeof previous?.revision_id === "string" && previous.revision_id ? previous.revision_id : null;
34134
34134
  const tombstoned = previous?.tombstoned_at != null;
34135
+ if (input.seedBundledOnly && input.expectedRevisionId && !previous) {
34136
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
34137
+ }
34138
+ if (input.seedBundledOnly && previous && (tombstoned || previous.source !== "bundled")) {
34139
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
34140
+ }
34135
34141
  const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : typeof previous?.skill_md === "string" ? previous.skill_md : null;
34136
34142
  if (previous && !tombstoned && input.expectedRevisionId !== previousRevisionId) {
34137
34143
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
@@ -34205,8 +34211,9 @@ class SqliteSkillsStore {
34205
34211
  tombstoned_at = NULL,
34206
34212
  tombstone_purge_after = NULL,
34207
34213
  updated_at = excluded.updated_at
34208
- WHERE skills_registry.tombstoned_at IS NOT NULL
34209
- OR skills_registry.revision_id = ?
34214
+ WHERE (skills_registry.tombstoned_at IS NOT NULL OR skills_registry.revision_id = ?)
34215
+ AND (? = 0 OR (skills_registry.tombstoned_at IS NULL AND skills_registry.source = 'bundled'
34216
+ AND skills_registry.revision_id = ?))
34210
34217
  RETURNING *`, [
34211
34218
  orgId,
34212
34219
  input.slug,
@@ -34224,6 +34231,8 @@ class SqliteSkillsStore {
34224
34231
  revisionId,
34225
34232
  now,
34226
34233
  now,
34234
+ input.expectedRevisionId ?? NO_REVISION_SENTINEL,
34235
+ input.seedBundledOnly ? 1 : 0,
34227
34236
  input.expectedRevisionId ?? NO_REVISION_SENTINEL
34228
34237
  ]);
34229
34238
  if (!row) {
@@ -35515,6 +35524,12 @@ class MemorySkillsStore {
35515
35524
  const key = skillKey(input.principal.orgId, input.slug);
35516
35525
  const now = nowIso();
35517
35526
  const previous = this.skills.get(key);
35527
+ if (input.seedBundledOnly && input.expectedRevisionId && !previous) {
35528
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
35529
+ }
35530
+ if (input.seedBundledOnly && previous && (previous.tombstonedAt || previous.source !== "bundled")) {
35531
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previous.revisionId);
35532
+ }
35518
35533
  if (previous && !previous.tombstonedAt && input.expectedRevisionId !== previous.revisionId) {
35519
35534
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previous.revisionId);
35520
35535
  }
@@ -35968,13 +35983,19 @@ class PostgresSkillsStore {
35968
35983
  const orgId = input.principal.orgId;
35969
35984
  return await this.sql.begin(async (tx) => {
35970
35985
  const previousRows = await tx`
35971
- SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at
35986
+ SELECT revision_id, revision_number, bundle_sha256, bundle_byte_size, skill_md, tombstoned_at, source
35972
35987
  FROM skills_registry WHERE org_id = ${orgId} AND slug = ${input.slug} LIMIT 1
35973
35988
  `;
35974
35989
  const previous = previousRows[0];
35975
35990
  const previousSha = typeof previous?.bundle_sha256 === "string" ? String(previous.bundle_sha256) : null;
35976
35991
  const previousRevisionId = typeof previous?.revision_id === "string" && previous.revision_id ? String(previous.revision_id) : null;
35977
35992
  const tombstoned = previous?.tombstoned_at != null;
35993
+ if (input.seedBundledOnly && input.expectedRevisionId && !previous) {
35994
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
35995
+ }
35996
+ if (input.seedBundledOnly && previous && (tombstoned || previous.source !== "bundled")) {
35997
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
35998
+ }
35978
35999
  const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : typeof previous?.skill_md === "string" ? String(previous.skill_md) : null;
35979
36000
  if (previous && !tombstoned && input.expectedRevisionId !== previousRevisionId) {
35980
36001
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
@@ -36015,6 +36036,12 @@ class PostgresSkillsStore {
36015
36036
  body_blob = EXCLUDED.body_blob
36016
36037
  `;
36017
36038
  }
36039
+ if (input.seedBundledOnly) {
36040
+ const seedRows = await tx`SELECT revision_id FROM skills_registry WHERE org_id = ${orgId} AND slug = ${input.slug} FOR UPDATE`;
36041
+ if (input.expectedRevisionId && !seedRows[0]) {
36042
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, null);
36043
+ }
36044
+ }
36018
36045
  const rows = await tx`
36019
36046
  INSERT INTO skills_registry (org_id, slug, display_name, description, category, tags_json, source, kind, version, skill_md,
36020
36047
  bundle_sha256, bundle_byte_size, published_by_user_id, revision_id, revision_number, updated_at)
@@ -36043,8 +36070,11 @@ class PostgresSkillsStore {
36043
36070
  tombstoned_at = NULL,
36044
36071
  tombstone_purge_after = NULL,
36045
36072
  updated_at = EXCLUDED.updated_at
36046
- WHERE skills_registry.tombstoned_at IS NOT NULL
36047
- OR skills_registry.revision_id = ${input.expectedRevisionId ?? NO_REVISION_SENTINEL2}
36073
+ WHERE (skills_registry.tombstoned_at IS NOT NULL
36074
+ OR skills_registry.revision_id = ${input.expectedRevisionId ?? NO_REVISION_SENTINEL2})
36075
+ AND (NOT ${Boolean(input.seedBundledOnly)} OR
36076
+ (skills_registry.tombstoned_at IS NULL AND skills_registry.source = 'bundled'
36077
+ AND skills_registry.revision_id = ${input.expectedRevisionId ?? NO_REVISION_SENTINEL2}))
36048
36078
  RETURNING *
36049
36079
  `;
36050
36080
  if (!rows[0]) {
@@ -0,0 +1,2 @@
1
+ import type { Command } from "commander";
2
+ export declare function registerPrivatePublications(parent: Command): void;
package/dist/index.d.ts CHANGED
@@ -18,7 +18,7 @@ export { ARTICLE_GENERATION_SLUG, validateBlogArticleRunOptions, type BlogArticl
18
18
  export { getCompactSkillDiscovery, getPublicSkillDiscovery, publicDiscoveryDependencies, publicDiscoveryDocumentation, publicDiscoveryEnvVars, sanitizePublicDiscoveryText, type CompactSkillDiscovery, type PublicSkillDiscovery, } from "./lib/discovery.js";
19
19
  export { TOOL_PRIMITIVE_SCHEMA_VERSION, TOOL_PRIMITIVES, createSkillToolDependencies, getSkillToolDependencies, getToolPrimitive, isGatewayBackedSkill, listToolPrimitives, validateToolPrimitiveCoverage, type SkillToolDependencies, type SkillToolDependency, type ToolPrimitive, type ToolPrimitiveCoverageIssue, type ToolPrimitiveCoverageResult, type ToolPrimitiveRuntime, type ToolPrimitiveSummary, } from "./lib/tool-primitives.js";
20
20
  export { MissingSkillsFleetError, SkillsFleetCredentialError, SKILLS_API_KEY_ENV, SKILLS_API_KEY_ENV_KEYS, SKILLS_API_URL_ENV, SKILLS_API_URL_ENV_KEYS, SKILLS_APP, SKILLS_LOCAL_OPT_IN_ENV_KEYS, configuredSkillsApiUrl, isSkillsLocalOptIn, noticeLocalSkillsMode, normalizeSkillsApiOrigin, requireSkillsApiKey, requireSkillsApiOrigin, requireSkillsFleet, resolveSkillsApiKey, resolveSkillsApiOrigin, resolveSkillsFleet, selectsSkillsLocalMode, skillsCredentialFilePath, skillsCredentialFiles, skillsCredentialOrReason, type HostedSkillsFleet, type LocalSkillsFleet, type SkillsFleet, type SkillsFleetErrorCode, type SkillsFleetOptions, } from "./lib/fleet-credentials.js";
21
- export { RemoteSkillsClient, createRemoteSkillsClient, RemoteRouteUnsupportedError, RemoteRequestError, RemoteWorkspaceMemberError, RemoteCapabilityUnavailableError, type RemotePin, type RemoteSkillSummary, type UpdatedSincePage, } from "./lib/remote-client.js";
21
+ export { RemoteSkillsClient, createRemoteSkillsClient, RemoteRouteUnsupportedError, RemoteRequestError, RemoteQuoteUnavailableError, type RemoteQuoteUnavailableCode, RemoteWorkspaceMemberError, RemoteCapabilityUnavailableError, type RemotePin, type RemoteSkillSummary, type UpdatedSincePage, } from "./lib/remote-client.js";
22
22
  export { REMOTE_SKILL_RUN_CONTRACT_VERSION, normalizeRemoteSkillRunContract, type RemoteSkillRunContract, } from "./lib/remote-run-contract.js";
23
23
  export { addSchedule, listSchedules, removeSchedule, setScheduleEnabled, getDueSchedules, recordScheduleRun, validateCron, getNextRun, type SkillSchedule, } from "./lib/scheduler.js";
24
24
  export { parseSkillFrontmatter, validateRegistryConsistency, validateSkillDirectory, type RegistryConsistencyResult, type SkillFrontmatter, type SkillValidationMessage, type SkillValidationResult, } from "./lib/skill-validation.js";
@@ -52,3 +52,5 @@ export { WorkspaceLeaveInputError, RemoteWorkspaceLeaveError, RemoteWorkspaceLea
52
52
  export type { RemoteWorkspaceInvitation, RemoteWorkspaceInvitationsPage, RemoteWorkspaceInvitationResult, RemoteWorkspaceInvitationAcceptance, ListRemoteWorkspaceInvitations, IssueRemoteWorkspaceInvitation, ResendRemoteWorkspaceInvitation, RevokeRemoteWorkspaceInvitation, AcceptRemoteWorkspaceInvitation, RemoteWorkspaceInvitationErrorCode } from "./lib/remote-invitations.js";
53
53
  export { WorkspaceInvitationInputError, RemoteWorkspaceInvitationError, RemoteWorkspaceInvitationUnconfirmedError, RemoteWorkspaceInvitationReadError } from "./lib/remote-invitations.js";
54
54
  export { InvitationEmailInputError, RemoteInvitationEmailError, RemoteInvitationEmailUnconfirmedError, type RequestInvitationEmailChallenge, type AcceptInvitationEmailChallenge, type RemoteInvitationEmailChallenge, type RemoteInvitationEmailAcceptance, type RemoteInvitationEmailErrorCode } from "./lib/remote-invitation-recovery.js";
55
+ export { RemotePrivatePublicationsClient, PrivatePublicationError, PRIVATE_PUBLICATION_MAX_BYTES, type PrivatePublicationDeclaration, type PrivatePublicationView, type PrivatePublicationState, type PrivatePublishingCapability } from "./lib/remote-private-publications.js";
56
+ export { preparePrivatePublication, readPrivatePublicationRecovery, continuePrivatePublication, inspectPrivatePublication, type PrivatePublicationRecovery, type PrivatePublicationResult } from "./lib/private-publication-recovery.js";