@hasna/skills 0.1.72 → 0.2.1

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/worker.js CHANGED
@@ -47,7 +47,7 @@ var __export = (target, all) => {
47
47
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
48
48
  var __require = import.meta.require;
49
49
 
50
- // ../../node_modules/.bun/@smithy+types@4.17.2/node_modules/@smithy/types/dist-cjs/index.js
50
+ // node_modules/@smithy/types/dist-cjs/index.js
51
51
  var require_dist_cjs = __commonJS((exports) => {
52
52
  var HttpAuthLocation;
53
53
  (function(HttpAuthLocation2) {
@@ -138,7 +138,7 @@ var require_dist_cjs = __commonJS((exports) => {
138
138
  exports.resolveDefaultRuntimeConfig = resolveDefaultRuntimeConfig;
139
139
  });
140
140
 
141
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/transport/index.js
141
+ // node_modules/@smithy/core/dist-cjs/submodules/transport/index.js
142
142
  var require_transport = __commonJS((exports) => {
143
143
  var { SMITHY_CONTEXT_KEY } = require_dist_cjs();
144
144
  var getSmithyContext = (context) => context[SMITHY_CONTEXT_KEY] || (context[SMITHY_CONTEXT_KEY] = {});
@@ -305,7 +305,7 @@ var require_transport = __commonJS((exports) => {
305
305
  exports.toEndpointV1 = toEndpointV1;
306
306
  });
307
307
 
308
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/schema/index.js
308
+ // node_modules/@smithy/core/dist-cjs/submodules/schema/index.js
309
309
  var require_schema = __commonJS((exports) => {
310
310
  var { getSmithyContext, HttpResponse, toEndpointV1 } = require_transport();
311
311
  var deref = (schemaRef) => {
@@ -974,7 +974,7 @@ var require_schema = __commonJS((exports) => {
974
974
  exports.translateTraits = translateTraits;
975
975
  });
976
976
 
977
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/client/index.js
977
+ // node_modules/@smithy/core/dist-cjs/submodules/client/index.js
978
978
  var require_client = __commonJS((exports) => {
979
979
  var { getSmithyContext, normalizeProvider } = require_transport();
980
980
  exports.getSmithyContext = getSmithyContext;
@@ -2043,7 +2043,7 @@ var require_client = __commonJS((exports) => {
2043
2043
  exports.withBaseException = withBaseException;
2044
2044
  });
2045
2045
 
2046
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/config/index.js
2046
+ // node_modules/@smithy/core/dist-cjs/submodules/config/index.js
2047
2047
  var require_config = __commonJS((exports) => {
2048
2048
  var { homedir } = __require("os");
2049
2049
  var { sep, join } = __require("path");
@@ -2738,7 +2738,7 @@ var require_config = __commonJS((exports) => {
2738
2738
  exports.resolveRegionConfig = resolveRegionConfig;
2739
2739
  });
2740
2740
 
2741
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/endpoints/index.js
2741
+ // node_modules/@smithy/core/dist-cjs/submodules/endpoints/index.js
2742
2742
  var require_endpoints = __commonJS((exports) => {
2743
2743
  var { CONFIG_PREFIX_SEPARATOR, booleanSelector, SelectorType, loadConfig } = require_config();
2744
2744
  var { toEndpointV1, getSmithyContext, normalizeProvider, isValidHostLabel } = require_transport();
@@ -3550,7 +3550,7 @@ var require_endpoints = __commonJS((exports) => {
3550
3550
  exports.resolveParams = resolveParams;
3551
3551
  });
3552
3552
 
3553
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/serde/index.js
3553
+ // node_modules/@smithy/core/dist-cjs/submodules/serde/index.js
3554
3554
  var require_serde = __commonJS((exports) => {
3555
3555
  var { createHmac, createHash, getRandomValues } = __require("crypto");
3556
3556
  var { ReadStream, lstatSync, fstatSync } = __require("fs");
@@ -5188,7 +5188,7 @@ ${value}\r
5188
5188
  exports.v4 = v4;
5189
5189
  });
5190
5190
 
5191
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/checksum/index.js
5191
+ // node_modules/@smithy/core/dist-cjs/submodules/checksum/index.js
5192
5192
  var require_checksum = __commonJS((exports) => {
5193
5193
  var { createReadStream } = __require("fs");
5194
5194
  var { Writable } = __require("stream");
@@ -5804,7 +5804,7 @@ var require_checksum = __commonJS((exports) => {
5804
5804
  exports.readableStreamHasher = readableStreamHasher;
5805
5805
  });
5806
5806
 
5807
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/event-streams/index.js
5807
+ // node_modules/@smithy/core/dist-cjs/submodules/event-streams/index.js
5808
5808
  var require_event_streams = __commonJS((exports) => {
5809
5809
  var { Crc32 } = require_checksum();
5810
5810
  var { toHex, fromHex, toUtf8, fromUtf8 } = require_serde();
@@ -6687,7 +6687,7 @@ var require_event_streams = __commonJS((exports) => {
6687
6687
  exports.universalEventStreamSerdeProvider = eventStreamSerdeProvider$1;
6688
6688
  });
6689
6689
 
6690
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/protocols/index.js
6690
+ // node_modules/@smithy/core/dist-cjs/submodules/protocols/index.js
6691
6691
  var require_protocols = __commonJS((exports) => {
6692
6692
  var { Uint8ArrayBlobAdapter, sdkStreamMixin, splitEvery, splitHeader, fromBase64, _parseEpochTimestamp, _parseRfc7231DateTime, _parseRfc3339DateTimeWithOffset, LazyJsonString, NumericValue, toUtf8, fromUtf8, generateIdempotencyToken, toBase64, dateToUtcString, quoteHeader } = require_serde();
6693
6693
  var { TypeRegistry, NormalizedSchema, translateTraits } = require_schema();
@@ -7677,7 +7677,7 @@ var require_protocols = __commonJS((exports) => {
7677
7677
  exports.resolvedPath = resolvedPath;
7678
7678
  });
7679
7679
 
7680
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/retry/index.js
7680
+ // node_modules/@smithy/core/dist-cjs/submodules/retry/index.js
7681
7681
  var require_retry = __commonJS((exports) => {
7682
7682
  var { Readable } = __require("stream");
7683
7683
  var { NoOpLogger, normalizeProvider } = require_client();
@@ -8474,7 +8474,7 @@ var require_retry = __commonJS((exports) => {
8474
8474
  exports.retryMiddlewareOptions = retryMiddlewareOptions;
8475
8475
  });
8476
8476
 
8477
- // ../../node_modules/.bun/@aws+lambda-invoke-store@0.3.0/node_modules/@aws/lambda-invoke-store/dist-cjs/invoke-store.js
8477
+ // node_modules/@aws/lambda-invoke-store/dist-cjs/invoke-store.js
8478
8478
  var require_invoke_store = __commonJS((exports) => {
8479
8479
  var PROTECTED_KEYS = {
8480
8480
  REQUEST_ID: Symbol.for("_AWS_LAMBDA_REQUEST_ID"),
@@ -8603,7 +8603,7 @@ var require_invoke_store = __commonJS((exports) => {
8603
8603
  exports.InvokeStoreBase = InvokeStoreBase;
8604
8604
  });
8605
8605
 
8606
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/index.js
8606
+ // node_modules/@smithy/core/dist-cjs/index.js
8607
8607
  var require_dist_cjs2 = __commonJS((exports) => {
8608
8608
  var { getSmithyContext } = require_transport();
8609
8609
  exports.getSmithyContext = getSmithyContext;
@@ -8929,7 +8929,7 @@ var require_dist_cjs2 = __commonJS((exports) => {
8929
8929
  exports.setFeature = setFeature;
8930
8930
  });
8931
8931
 
8932
- // ../../node_modules/.bun/bowser@2.14.1/node_modules/bowser/es5.js
8932
+ // node_modules/bowser/es5.js
8933
8933
  var require_es5 = __commonJS((exports, module) => {
8934
8934
  (function(e, t) {
8935
8935
  typeof exports == "object" && typeof module == "object" ? module.exports = t() : typeof define == "function" && define.amd ? define([], t) : typeof exports == "object" ? exports.bowser = t() : e.bowser = t();
@@ -9769,7 +9769,7 @@ var require_es5 = __commonJS((exports, module) => {
9769
9769
  });
9770
9770
  });
9771
9771
 
9772
- // ../../node_modules/.bun/@aws-sdk+core@3.977.8/node_modules/@aws-sdk/core/dist-cjs/submodules/client/index.js
9772
+ // node_modules/@aws-sdk/core/dist-cjs/submodules/client/index.js
9773
9773
  var require_client2 = __commonJS((exports) => {
9774
9774
  var { Retry, RETRY_MODES } = require_retry();
9775
9775
  var { HttpRequest, parseUrl } = require_protocols();
@@ -10707,7 +10707,7 @@ More information can be found at: https://a.co/c895JFp`);
10707
10707
  exports.userAgentMiddleware = userAgentMiddleware;
10708
10708
  });
10709
10709
 
10710
- // ../../node_modules/.bun/@aws-sdk+checksums@3.1000.28/node_modules/@aws-sdk/checksums/dist-cjs/submodules/crc/index.js
10710
+ // node_modules/@aws-sdk/checksums/dist-cjs/submodules/crc/index.js
10711
10711
  var require_crc = __commonJS((exports) => {
10712
10712
  var { Crc32, Crc32Js, Crc32Node } = require_checksum();
10713
10713
  exports.Crc32 = Crc32;
@@ -10864,7 +10864,7 @@ var require_crc = __commonJS((exports) => {
10864
10864
  exports.crc64NvmeCrtContainer = crc64NvmeCrtContainer;
10865
10865
  });
10866
10866
 
10867
- // ../../node_modules/.bun/@smithy+signature-v4@5.7.2/node_modules/@smithy/signature-v4/dist-cjs/index.js
10867
+ // node_modules/@smithy/signature-v4/dist-cjs/index.js
10868
10868
  var require_dist_cjs3 = __commonJS((exports) => {
10869
10869
  var { fromUtf8, fromHex, toHex, toUint8Array: toUint8Array2, isArrayBuffer: isArrayBuffer2 } = require_serde();
10870
10870
  var { normalizeProvider: normalizeProvider2 } = require_client();
@@ -11404,7 +11404,7 @@ ${toHex(hashedRequest)}`;
11404
11404
  exports.signatureV4aContainer = signatureV4aContainer;
11405
11405
  });
11406
11406
 
11407
- // ../../node_modules/.bun/@aws-sdk+signature-v4-multi-region@3.996.45/node_modules/@aws-sdk/signature-v4-multi-region/dist-cjs/index.js
11407
+ // node_modules/@aws-sdk/signature-v4-multi-region/dist-cjs/index.js
11408
11408
  var require_dist_cjs4 = __commonJS((exports) => {
11409
11409
  var { SignatureV4, signatureV4aContainer } = require_dist_cjs3();
11410
11410
  var signatureV4CrtContainer = {
@@ -11536,7 +11536,7 @@ var require_dist_cjs4 = __commonJS((exports) => {
11536
11536
  exports.signatureV4CrtContainer = signatureV4CrtContainer;
11537
11537
  });
11538
11538
 
11539
- // ../../node_modules/.bun/@aws-sdk+core@3.977.8/node_modules/@aws-sdk/core/dist-cjs/submodules/util/index.js
11539
+ // node_modules/@aws-sdk/core/dist-cjs/submodules/util/index.js
11540
11540
  var require_util = __commonJS((exports) => {
11541
11541
  var { buildQueryString } = require_protocols();
11542
11542
  var validate = (str) => typeof str === "string" && str.indexOf("arn:") === 0 && str.split(":").length >= 6;
@@ -11594,7 +11594,7 @@ var require_util = __commonJS((exports) => {
11594
11594
  exports.validate = validate;
11595
11595
  });
11596
11596
 
11597
- // ../../node_modules/.bun/@smithy+core@3.33.2/node_modules/@smithy/core/dist-cjs/submodules/cbor/index.js
11597
+ // node_modules/@smithy/core/dist-cjs/submodules/cbor/index.js
11598
11598
  var require_cbor = __commonJS((exports) => {
11599
11599
  var { nv, NumericValue, calculateBodyLength, generateIdempotencyToken, fromBase64, _parseEpochTimestamp } = require_serde();
11600
11600
  var { HttpRequest: HttpRequest2, collectBody, SerdeContext, RpcProtocol } = require_protocols();
@@ -13962,7 +13962,7 @@ var require_cbor = __commonJS((exports) => {
13962
13962
  exports.tagSymbol = tagSymbol;
13963
13963
  });
13964
13964
 
13965
- // ../../node_modules/.bun/@aws-sdk+xml-builder@3.972.39/node_modules/@aws-sdk/xml-builder/dist-cjs/index.js
13965
+ // node_modules/@aws-sdk/xml-builder/dist-cjs/index.js
13966
13966
  var require_dist_cjs5 = __commonJS((exports) => {
13967
13967
  var ATTR_ESCAPE_RE = /[&<>"]/g;
13968
13968
  var ATTR_ESCAPE_MAP = {
@@ -14330,7 +14330,7 @@ var require_dist_cjs5 = __commonJS((exports) => {
14330
14330
  exports.parseXML = parseXML;
14331
14331
  });
14332
14332
 
14333
- // ../../node_modules/.bun/@aws-sdk+core@3.977.8/node_modules/@aws-sdk/core/dist-cjs/submodules/protocols/index.js
14333
+ // node_modules/@aws-sdk/core/dist-cjs/submodules/protocols/index.js
14334
14334
  var require_protocols2 = __commonJS((exports) => {
14335
14335
  var { SmithyRpcV2CborProtocol, loadSmithyRpcV2CborErrorCode } = require_cbor();
14336
14336
  var { TypeRegistry, NormalizedSchema, deref } = require_schema();
@@ -17171,7 +17171,7 @@ var require_protocols2 = __commonJS((exports) => {
17171
17171
  exports.parseXmlErrorBody = parseXmlErrorBody;
17172
17172
  });
17173
17173
 
17174
- // ../../node_modules/.bun/@aws-sdk+core@3.977.8/node_modules/@aws-sdk/core/dist-cjs/submodules/httpAuthSchemes/index.js
17174
+ // node_modules/@aws-sdk/core/dist-cjs/submodules/httpAuthSchemes/index.js
17175
17175
  var require_httpAuthSchemes = __commonJS((exports) => {
17176
17176
  var { ProviderError, booleanSelector: booleanSelector2, SelectorType: SelectorType3, loadConfig } = require_config();
17177
17177
  var { setCredentialFeature } = require_client2();
@@ -17501,7 +17501,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
17501
17501
  exports.validateSigningProperties = validateSigningProperties;
17502
17502
  });
17503
17503
 
17504
- // ../../node_modules/.bun/@aws-sdk+credential-provider-env@3.972.69/node_modules/@aws-sdk/credential-provider-env/dist-es/fromEnv.js
17504
+ // node_modules/@aws-sdk/credential-provider-env/dist-es/fromEnv.js
17505
17505
  var import_client5, import_config, ENV_KEY = "AWS_ACCESS_KEY_ID", ENV_SECRET = "AWS_SECRET_ACCESS_KEY", ENV_SESSION = "AWS_SESSION_TOKEN", ENV_EXPIRATION = "AWS_CREDENTIAL_EXPIRATION", ENV_CREDENTIAL_SCOPE = "AWS_CREDENTIAL_SCOPE", ENV_ACCOUNT_ID = "AWS_ACCOUNT_ID", fromEnv = (init) => async () => {
17506
17506
  init?.logger?.debug("@aws-sdk/credential-provider-env - fromEnv");
17507
17507
  const accessKeyId = process.env[ENV_KEY];
@@ -17529,7 +17529,7 @@ var init_fromEnv = __esm(() => {
17529
17529
  import_config = __toESM(require_config(), 1);
17530
17530
  });
17531
17531
 
17532
- // ../../node_modules/.bun/@aws-sdk+credential-provider-env@3.972.69/node_modules/@aws-sdk/credential-provider-env/dist-es/index.js
17532
+ // node_modules/@aws-sdk/credential-provider-env/dist-es/index.js
17533
17533
  var exports_dist_es = {};
17534
17534
  __export(exports_dist_es, {
17535
17535
  fromEnv: () => fromEnv,
@@ -17544,7 +17544,7 @@ var init_dist_es = __esm(() => {
17544
17544
  init_fromEnv();
17545
17545
  });
17546
17546
 
17547
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/ImdsCredentials.js
17547
+ // node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/ImdsCredentials.js
17548
17548
  var isImdsCredentials = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.AccessKeyId === "string" && typeof arg.SecretAccessKey === "string" && typeof arg.Token === "string" && typeof arg.Expiration === "string", fromImdsCredentials = (creds) => ({
17549
17549
  accessKeyId: creds.AccessKeyId,
17550
17550
  secretAccessKey: creds.SecretAccessKey,
@@ -17553,14 +17553,14 @@ var isImdsCredentials = (arg) => Boolean(arg) && typeof arg === "object" && type
17553
17553
  ...creds.AccountId && { accountId: creds.AccountId }
17554
17554
  });
17555
17555
 
17556
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/RemoteProviderInit.js
17556
+ // node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/RemoteProviderInit.js
17557
17557
  var DEFAULT_TIMEOUT = 1000, DEFAULT_MAX_RETRIES = 0, providerConfigFromInit = ({ maxRetries = DEFAULT_MAX_RETRIES, timeout = DEFAULT_TIMEOUT }) => ({ maxRetries, timeout });
17558
17558
 
17559
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/node-http.js
17559
+ // node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/node-http.js
17560
17560
  import node_http from "http";
17561
17561
  var init_node_http = () => {};
17562
17562
 
17563
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/httpRequest.js
17563
+ // node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/httpRequest.js
17564
17564
  function httpRequest(options) {
17565
17565
  return new Promise((resolve, reject) => {
17566
17566
  const req = node_http.request({
@@ -17600,7 +17600,7 @@ var init_httpRequest = __esm(() => {
17600
17600
  import_config2 = __toESM(require_config(), 1);
17601
17601
  });
17602
17602
 
17603
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/retry.js
17603
+ // node_modules/@smithy/credential-provider-imds/dist-es/remoteProvider/retry.js
17604
17604
  var retry = (toRetry, maxRetries) => {
17605
17605
  let promise = toRetry();
17606
17606
  for (let i2 = 0;i2 < maxRetries; i2++) {
@@ -17609,7 +17609,7 @@ var retry = (toRetry, maxRetries) => {
17609
17609
  return promise;
17610
17610
  };
17611
17611
 
17612
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/fromContainerMetadata.js
17612
+ // node_modules/@smithy/credential-provider-imds/dist-es/fromContainerMetadata.js
17613
17613
  var import_config3, ENV_CMDS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI", ENV_CMDS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", ENV_CMDS_AUTH_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN", fromContainerMetadata = (init = {}) => {
17614
17614
  const { timeout, maxRetries } = providerConfigFromInit(init);
17615
17615
  return () => retry(async () => {
@@ -17679,7 +17679,7 @@ var init_fromContainerMetadata = __esm(() => {
17679
17679
  GREENGRASS_PROTOCOLS = new Set(["http:", "https:"]);
17680
17680
  });
17681
17681
 
17682
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/error/InstanceMetadataV1FallbackError.js
17682
+ // node_modules/@smithy/credential-provider-imds/dist-es/error/InstanceMetadataV1FallbackError.js
17683
17683
  var import_config4, InstanceMetadataV1FallbackError;
17684
17684
  var init_InstanceMetadataV1FallbackError = __esm(() => {
17685
17685
  import_config4 = __toESM(require_config(), 1);
@@ -17694,7 +17694,7 @@ var init_InstanceMetadataV1FallbackError = __esm(() => {
17694
17694
  };
17695
17695
  });
17696
17696
 
17697
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/config/Endpoint.js
17697
+ // node_modules/@smithy/credential-provider-imds/dist-es/config/Endpoint.js
17698
17698
  var Endpoint;
17699
17699
  var init_Endpoint = __esm(() => {
17700
17700
  (function(Endpoint2) {
@@ -17703,7 +17703,7 @@ var init_Endpoint = __esm(() => {
17703
17703
  })(Endpoint || (Endpoint = {}));
17704
17704
  });
17705
17705
 
17706
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/config/EndpointConfigOptions.js
17706
+ // node_modules/@smithy/credential-provider-imds/dist-es/config/EndpointConfigOptions.js
17707
17707
  var ENV_ENDPOINT_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT", CONFIG_ENDPOINT_NAME = "ec2_metadata_service_endpoint", ENDPOINT_CONFIG_OPTIONS;
17708
17708
  var init_EndpointConfigOptions = __esm(() => {
17709
17709
  ENDPOINT_CONFIG_OPTIONS = {
@@ -17713,7 +17713,7 @@ var init_EndpointConfigOptions = __esm(() => {
17713
17713
  };
17714
17714
  });
17715
17715
 
17716
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/config/EndpointMode.js
17716
+ // node_modules/@smithy/credential-provider-imds/dist-es/config/EndpointMode.js
17717
17717
  var EndpointMode;
17718
17718
  var init_EndpointMode = __esm(() => {
17719
17719
  (function(EndpointMode2) {
@@ -17722,7 +17722,7 @@ var init_EndpointMode = __esm(() => {
17722
17722
  })(EndpointMode || (EndpointMode = {}));
17723
17723
  });
17724
17724
 
17725
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/config/EndpointModeConfigOptions.js
17725
+ // node_modules/@smithy/credential-provider-imds/dist-es/config/EndpointModeConfigOptions.js
17726
17726
  var ENV_ENDPOINT_MODE_NAME = "AWS_EC2_METADATA_SERVICE_ENDPOINT_MODE", CONFIG_ENDPOINT_MODE_NAME = "ec2_metadata_service_endpoint_mode", ENDPOINT_MODE_CONFIG_OPTIONS;
17727
17727
  var init_EndpointModeConfigOptions = __esm(() => {
17728
17728
  init_EndpointMode();
@@ -17733,7 +17733,7 @@ var init_EndpointModeConfigOptions = __esm(() => {
17733
17733
  };
17734
17734
  });
17735
17735
 
17736
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/utils/getInstanceMetadataEndpoint.js
17736
+ // node_modules/@smithy/credential-provider-imds/dist-es/utils/getInstanceMetadataEndpoint.js
17737
17737
  var import_config5, import_protocols, getInstanceMetadataEndpoint = async () => import_protocols.parseUrl(await getFromEndpointConfig() || await getFromEndpointModeConfig()), getFromEndpointConfig = async () => import_config5.loadConfig(ENDPOINT_CONFIG_OPTIONS)(), getFromEndpointModeConfig = async () => {
17738
17738
  const endpointMode = await import_config5.loadConfig(ENDPOINT_MODE_CONFIG_OPTIONS)();
17739
17739
  switch (endpointMode) {
@@ -17754,7 +17754,7 @@ var init_getInstanceMetadataEndpoint = __esm(() => {
17754
17754
  import_protocols = __toESM(require_protocols(), 1);
17755
17755
  });
17756
17756
 
17757
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/utils/getExtendedInstanceMetadataCredentials.js
17757
+ // node_modules/@smithy/credential-provider-imds/dist-es/utils/getExtendedInstanceMetadataCredentials.js
17758
17758
  var STATIC_STABILITY_REFRESH_INTERVAL_SECONDS, STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS, STATIC_STABILITY_DOC_URL = "https://docs.aws.amazon.com/sdkref/latest/guide/feature-static-credentials.html", getExtendedInstanceMetadataCredentials = (credentials, logger) => {
17759
17759
  const refreshInterval = STATIC_STABILITY_REFRESH_INTERVAL_SECONDS + Math.floor(Math.random() * STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS);
17760
17760
  const newExpiration = new Date(Date.now() + refreshInterval * 1000);
@@ -17772,7 +17772,7 @@ var init_getExtendedInstanceMetadataCredentials = __esm(() => {
17772
17772
  STATIC_STABILITY_REFRESH_INTERVAL_JITTER_WINDOW_SECONDS = 5 * 60;
17773
17773
  });
17774
17774
 
17775
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/utils/staticStabilityProvider.js
17775
+ // node_modules/@smithy/credential-provider-imds/dist-es/utils/staticStabilityProvider.js
17776
17776
  var staticStabilityProvider = (provider, options = {}) => {
17777
17777
  const logger = options?.logger || console;
17778
17778
  let pastCredentials;
@@ -17799,7 +17799,7 @@ var init_staticStabilityProvider = __esm(() => {
17799
17799
  init_getExtendedInstanceMetadataCredentials();
17800
17800
  });
17801
17801
 
17802
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/fromInstanceMetadata.js
17802
+ // node_modules/@smithy/credential-provider-imds/dist-es/fromInstanceMetadata.js
17803
17803
  var import_config6, IMDS_PATH = "/latest/meta-data/iam/security-credentials/", IMDS_TOKEN_PATH = "/latest/api/token", AWS_EC2_METADATA_V1_DISABLED = "AWS_EC2_METADATA_V1_DISABLED", PROFILE_AWS_EC2_METADATA_V1_DISABLED = "ec2_metadata_v1_disabled", X_AWS_EC2_METADATA_TOKEN = "x-aws-ec2-metadata-token", fromInstanceMetadata = (init = {}) => staticStabilityProvider(getInstanceMetadataProvider(init), { logger: init.logger }), getInstanceMetadataProvider = (init = {}) => {
17804
17804
  let disableFetchToken = false;
17805
17805
  const { logger, profile } = init;
@@ -17919,7 +17919,7 @@ var init_fromInstanceMetadata = __esm(() => {
17919
17919
  import_config6 = __toESM(require_config(), 1);
17920
17920
  });
17921
17921
 
17922
- // ../../node_modules/.bun/@smithy+credential-provider-imds@4.5.2/node_modules/@smithy/credential-provider-imds/dist-es/index.js
17922
+ // node_modules/@smithy/credential-provider-imds/dist-es/index.js
17923
17923
  var exports_dist_es2 = {};
17924
17924
  __export(exports_dist_es2, {
17925
17925
  providerConfigFromInit: () => providerConfigFromInit,
@@ -17942,7 +17942,7 @@ var init_dist_es2 = __esm(() => {
17942
17942
  init_Endpoint();
17943
17943
  });
17944
17944
 
17945
- // ../../node_modules/.bun/@smithy+node-http-handler@4.11.2/node_modules/@smithy/node-http-handler/dist-cjs/index.js
17945
+ // node_modules/@smithy/node-http-handler/dist-cjs/index.js
17946
17946
  var require_dist_cjs6 = __commonJS((exports) => {
17947
17947
  var { buildQueryString, HttpResponse: HttpResponse2 } = require_protocols();
17948
17948
  var node_https = __require("https");
@@ -18756,7 +18756,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
18756
18756
  exports.NodeHttpHandler = NodeHttpHandler;
18757
18757
  });
18758
18758
 
18759
- // ../../node_modules/.bun/@aws-sdk+credential-provider-http@3.972.71/node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/checkUrl.js
18759
+ // node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/checkUrl.js
18760
18760
  var import_config7, ECS_CONTAINER_HOST = "169.254.170.2", EKS_CONTAINER_HOST_IPv4 = "169.254.170.23", EKS_CONTAINER_HOST_IPv6 = "[fd00:ec2::23]", checkUrl = (url, logger) => {
18761
18761
  if (url.protocol === "https:") {
18762
18762
  return;
@@ -18790,7 +18790,7 @@ var init_checkUrl = __esm(() => {
18790
18790
  import_config7 = __toESM(require_config(), 1);
18791
18791
  });
18792
18792
 
18793
- // ../../node_modules/.bun/@aws-sdk+credential-provider-http@3.972.71/node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/requestHelpers.js
18793
+ // node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/requestHelpers.js
18794
18794
  function createGetRequest(url) {
18795
18795
  return new import_protocols2.HttpRequest({
18796
18796
  protocol: url.protocol,
@@ -18839,7 +18839,7 @@ var init_requestHelpers = __esm(() => {
18839
18839
  import_serde2 = __toESM(require_serde(), 1);
18840
18840
  });
18841
18841
 
18842
- // ../../node_modules/.bun/@aws-sdk+credential-provider-http@3.972.71/node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/retry-wrapper.js
18842
+ // node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/retry-wrapper.js
18843
18843
  var retryWrapper = (toRetry, maxRetries, delayMs) => {
18844
18844
  return async () => {
18845
18845
  for (let i2 = 0;i2 < maxRetries; ++i2) {
@@ -18853,7 +18853,7 @@ var retryWrapper = (toRetry, maxRetries, delayMs) => {
18853
18853
  };
18854
18854
  };
18855
18855
 
18856
- // ../../node_modules/.bun/@aws-sdk+credential-provider-http@3.972.71/node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/fromHttp.js
18856
+ // node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/fromHttp.js
18857
18857
  import fs from "fs/promises";
18858
18858
  var import_client6, import_config9, import_node_http_handler, AWS_CONTAINER_CREDENTIALS_RELATIVE_URI = "AWS_CONTAINER_CREDENTIALS_RELATIVE_URI", DEFAULT_LINK_LOCAL_HOST = "http://169.254.170.2", AWS_CONTAINER_CREDENTIALS_FULL_URI = "AWS_CONTAINER_CREDENTIALS_FULL_URI", AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE = "AWS_CONTAINER_AUTHORIZATION_TOKEN_FILE", AWS_CONTAINER_AUTHORIZATION_TOKEN = "AWS_CONTAINER_AUTHORIZATION_TOKEN", fromHttp = (options = {}) => {
18859
18859
  options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp");
@@ -18919,7 +18919,7 @@ var init_fromHttp = __esm(() => {
18919
18919
  import_node_http_handler = __toESM(require_dist_cjs6(), 1);
18920
18920
  });
18921
18921
 
18922
- // ../../node_modules/.bun/@aws-sdk+credential-provider-http@3.972.71/node_modules/@aws-sdk/credential-provider-http/dist-es/index.js
18922
+ // node_modules/@aws-sdk/credential-provider-http/dist-es/index.js
18923
18923
  var exports_dist_es3 = {};
18924
18924
  __export(exports_dist_es3, {
18925
18925
  fromHttp: () => fromHttp
@@ -18928,16 +18928,16 @@ var init_dist_es3 = __esm(() => {
18928
18928
  init_fromHttp();
18929
18929
  });
18930
18930
 
18931
- // ../../node_modules/.bun/@aws-sdk+credential-provider-sso@3.973.13/node_modules/@aws-sdk/credential-provider-sso/dist-es/isSsoProfile.js
18931
+ // node_modules/@aws-sdk/credential-provider-sso/dist-es/isSsoProfile.js
18932
18932
  var isSsoProfile = (arg) => arg && (typeof arg.sso_start_url === "string" || typeof arg.sso_account_id === "string" || typeof arg.sso_session === "string" || typeof arg.sso_region === "string" || typeof arg.sso_role_name === "string");
18933
18933
 
18934
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/constants.js
18934
+ // node_modules/@aws-sdk/token-providers/dist-es/constants.js
18935
18935
  var EXPIRE_WINDOW_MS, REFRESH_MESSAGE = `To refresh this SSO session run 'aws sso login' with the corresponding profile.`;
18936
18936
  var init_constants = __esm(() => {
18937
18937
  EXPIRE_WINDOW_MS = 5 * 60 * 1000;
18938
18938
  });
18939
18939
 
18940
- // ../../node_modules/.bun/@aws-sdk+nested-clients@3.997.43/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js
18940
+ // node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso-oidc/index.js
18941
18941
  var require_sso_oidc = __commonJS((exports) => {
18942
18942
  var { awsEndpointFunctions: awsEndpointFunctions2, emitWarningIfUnsupportedVersion: emitWarningIfUnsupportedVersion$1, createDefaultUserAgentProvider, NODE_APP_ID_CONFIG_OPTIONS, getAwsRegionExtensionConfiguration, resolveAwsRegionExtensionConfiguration, resolveUserAgentConfig, resolveHostHeaderConfig, getUserAgentPlugin, getHostHeaderPlugin, getLoggerPlugin, getRecursionDetectionPlugin } = require_client2();
18943
18943
  var { NoAuthSigner, getHttpAuthSchemeEndpointRuleSetPlugin, DefaultIdentityProviderConfig, getHttpSigningPlugin } = require_dist_cjs2();
@@ -19692,7 +19692,7 @@ var require_sso_oidc = __commonJS((exports) => {
19692
19692
  exports.errorTypeRegistries = errorTypeRegistries2;
19693
19693
  });
19694
19694
 
19695
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/getSsoOidcClient.js
19695
+ // node_modules/@aws-sdk/token-providers/dist-es/getSsoOidcClient.js
19696
19696
  var getSsoOidcClient = async (ssoRegion, init = {}, callerClientConfig) => {
19697
19697
  const { SSOOIDCClient } = await Promise.resolve().then(() => __toESM(require_sso_oidc(), 1));
19698
19698
  const coalesce = (prop) => init.clientConfig?.[prop] ?? init.parentClientConfig?.[prop] ?? callerClientConfig?.[prop];
@@ -19704,7 +19704,7 @@ var getSsoOidcClient = async (ssoRegion, init = {}, callerClientConfig) => {
19704
19704
  return ssoOidcClient;
19705
19705
  };
19706
19706
 
19707
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/getNewSsoOidcToken.js
19707
+ // node_modules/@aws-sdk/token-providers/dist-es/getNewSsoOidcToken.js
19708
19708
  var getNewSsoOidcToken = async (ssoToken, ssoRegion, init = {}, callerClientConfig) => {
19709
19709
  const { CreateTokenCommand } = await Promise.resolve().then(() => __toESM(require_sso_oidc(), 1));
19710
19710
  const ssoOidcClient = await getSsoOidcClient(ssoRegion, init, callerClientConfig);
@@ -19717,7 +19717,7 @@ var getNewSsoOidcToken = async (ssoToken, ssoRegion, init = {}, callerClientConf
19717
19717
  };
19718
19718
  var init_getNewSsoOidcToken = () => {};
19719
19719
 
19720
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/validateTokenExpiry.js
19720
+ // node_modules/@aws-sdk/token-providers/dist-es/validateTokenExpiry.js
19721
19721
  var import_config11, validateTokenExpiry = (token) => {
19722
19722
  if (token.expiration && token.expiration.getTime() < Date.now()) {
19723
19723
  throw new import_config11.TokenProviderError(`Token is expired. ${REFRESH_MESSAGE}`, false);
@@ -19728,7 +19728,7 @@ var init_validateTokenExpiry = __esm(() => {
19728
19728
  import_config11 = __toESM(require_config(), 1);
19729
19729
  });
19730
19730
 
19731
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/validateTokenKey.js
19731
+ // node_modules/@aws-sdk/token-providers/dist-es/validateTokenKey.js
19732
19732
  var import_config12, validateTokenKey = (key, value, forRefresh = false) => {
19733
19733
  if (typeof value === "undefined") {
19734
19734
  throw new import_config12.TokenProviderError(`Value not present for '${key}' in SSO Token${forRefresh ? ". Cannot refresh" : ""}. ${REFRESH_MESSAGE}`, false);
@@ -19739,7 +19739,7 @@ var init_validateTokenKey = __esm(() => {
19739
19739
  import_config12 = __toESM(require_config(), 1);
19740
19740
  });
19741
19741
 
19742
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/writeSSOTokenToFile.js
19742
+ // node_modules/@aws-sdk/token-providers/dist-es/writeSSOTokenToFile.js
19743
19743
  import { promises as fsPromises } from "fs";
19744
19744
  var import_config13, writeFile, writeSSOTokenToFile = (id, ssoToken) => {
19745
19745
  const tokenFilepath = import_config13.getSSOTokenFilepath(id);
@@ -19751,7 +19751,7 @@ var init_writeSSOTokenToFile = __esm(() => {
19751
19751
  ({ writeFile } = fsPromises);
19752
19752
  });
19753
19753
 
19754
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/fromSso.js
19754
+ // node_modules/@aws-sdk/token-providers/dist-es/fromSso.js
19755
19755
  var import_config14, lastRefreshAttemptTime, fromSso = (init = {}) => async ({ callerClientConfig } = {}) => {
19756
19756
  init.logger?.debug("@aws-sdk/token-providers - fromSso");
19757
19757
  const profiles = await import_config14.parseKnownFiles(init);
@@ -19830,12 +19830,12 @@ var init_fromSso = __esm(() => {
19830
19830
  lastRefreshAttemptTime = new Date(0);
19831
19831
  });
19832
19832
 
19833
- // ../../node_modules/.bun/@aws-sdk+token-providers@3.1111.0/node_modules/@aws-sdk/token-providers/dist-es/index.js
19833
+ // node_modules/@aws-sdk/token-providers/dist-es/index.js
19834
19834
  var init_dist_es4 = __esm(() => {
19835
19835
  init_fromSso();
19836
19836
  });
19837
19837
 
19838
- // ../../node_modules/.bun/@aws-sdk+nested-clients@3.997.43/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js
19838
+ // node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sso/index.js
19839
19839
  function createAwsAuthSigv4HttpAuthOption2(authParameters) {
19840
19840
  return {
19841
19841
  schemeId: "aws.auth#sigv4",
@@ -20283,7 +20283,7 @@ var init_sso = __esm(() => {
20283
20283
  $SSOClient = SSOClient;
20284
20284
  });
20285
20285
 
20286
- // ../../node_modules/.bun/@aws-sdk+credential-provider-sso@3.973.13/node_modules/@aws-sdk/credential-provider-sso/dist-es/loadSso.js
20286
+ // node_modules/@aws-sdk/credential-provider-sso/dist-es/loadSso.js
20287
20287
  var exports_loadSso = {};
20288
20288
  __export(exports_loadSso, {
20289
20289
  SSOClient: () => $SSOClient,
@@ -20293,7 +20293,7 @@ var init_loadSso = __esm(() => {
20293
20293
  init_sso();
20294
20294
  });
20295
20295
 
20296
- // ../../node_modules/.bun/@aws-sdk+credential-provider-sso@3.973.13/node_modules/@aws-sdk/credential-provider-sso/dist-es/resolveSSOCredentials.js
20296
+ // node_modules/@aws-sdk/credential-provider-sso/dist-es/resolveSSOCredentials.js
20297
20297
  var import_client7, import_config15, SHOULD_FAIL_CREDENTIAL_CHAIN = false, resolveSSOCredentials = async ({ ssoStartUrl, ssoSession, ssoAccountId, ssoRegion, ssoRoleName, ssoClient, clientConfig, parentClientConfig, callerClientConfig, profile, filepath, configFilepath, ignoreCache, logger }) => {
20298
20298
  let token;
20299
20299
  const refreshMessage = `To refresh this SSO session run aws sso login with the corresponding profile.`;
@@ -20382,7 +20382,7 @@ var init_resolveSSOCredentials = __esm(() => {
20382
20382
  import_config15 = __toESM(require_config(), 1);
20383
20383
  });
20384
20384
 
20385
- // ../../node_modules/.bun/@aws-sdk+credential-provider-sso@3.973.13/node_modules/@aws-sdk/credential-provider-sso/dist-es/validateSsoProfile.js
20385
+ // node_modules/@aws-sdk/credential-provider-sso/dist-es/validateSsoProfile.js
20386
20386
  var import_config16, validateSsoProfile = (profile, logger) => {
20387
20387
  const { sso_start_url, sso_account_id, sso_region, sso_role_name } = profile;
20388
20388
  if (!sso_start_url || !sso_account_id || !sso_region || !sso_role_name) {
@@ -20395,7 +20395,7 @@ var init_validateSsoProfile = __esm(() => {
20395
20395
  import_config16 = __toESM(require_config(), 1);
20396
20396
  });
20397
20397
 
20398
- // ../../node_modules/.bun/@aws-sdk+credential-provider-sso@3.973.13/node_modules/@aws-sdk/credential-provider-sso/dist-es/fromSSO.js
20398
+ // node_modules/@aws-sdk/credential-provider-sso/dist-es/fromSSO.js
20399
20399
  var import_config17, fromSSO = (init = {}) => async ({ callerClientConfig } = {}) => {
20400
20400
  init.logger?.debug("@aws-sdk/credential-provider-sso - fromSSO");
20401
20401
  const { ssoStartUrl, ssoAccountId, ssoRegion, ssoRoleName, ssoSession } = init;
@@ -20477,7 +20477,7 @@ var init_fromSSO = __esm(() => {
20477
20477
  import_config17 = __toESM(require_config(), 1);
20478
20478
  });
20479
20479
 
20480
- // ../../node_modules/.bun/@aws-sdk+credential-provider-sso@3.973.13/node_modules/@aws-sdk/credential-provider-sso/dist-es/index.js
20480
+ // node_modules/@aws-sdk/credential-provider-sso/dist-es/index.js
20481
20481
  var exports_dist_es4 = {};
20482
20482
  __export(exports_dist_es4, {
20483
20483
  validateSsoProfile: () => validateSsoProfile,
@@ -20489,7 +20489,7 @@ var init_dist_es5 = __esm(() => {
20489
20489
  init_validateSsoProfile();
20490
20490
  });
20491
20491
 
20492
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveCredentialSource.js
20492
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveCredentialSource.js
20493
20493
  var import_client8, import_config18, resolveCredentialSource = (credentialSource, profileName, logger) => {
20494
20494
  const sourceProvidersMap = {
20495
20495
  EcsContainer: async (options) => {
@@ -20520,7 +20520,7 @@ var init_resolveCredentialSource = __esm(() => {
20520
20520
  import_config18 = __toESM(require_config(), 1);
20521
20521
  });
20522
20522
 
20523
- // ../../node_modules/.bun/@aws-sdk+nested-clients@3.997.43/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js
20523
+ // node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/sts/index.js
20524
20524
  var require_sts = __commonJS((exports) => {
20525
20525
  var { awsEndpointFunctions: awsEndpointFunctions3, emitWarningIfUnsupportedVersion: emitWarningIfUnsupportedVersion$12, createDefaultUserAgentProvider: createDefaultUserAgentProvider2, NODE_APP_ID_CONFIG_OPTIONS: NODE_APP_ID_CONFIG_OPTIONS2, getAwsRegionExtensionConfiguration: getAwsRegionExtensionConfiguration2, resolveAwsRegionExtensionConfiguration: resolveAwsRegionExtensionConfiguration2, resolveUserAgentConfig: resolveUserAgentConfig2, resolveHostHeaderConfig: resolveHostHeaderConfig2, getUserAgentPlugin: getUserAgentPlugin2, getHostHeaderPlugin: getHostHeaderPlugin2, getLoggerPlugin: getLoggerPlugin2, getRecursionDetectionPlugin: getRecursionDetectionPlugin2, setCredentialFeature: setCredentialFeature5, stsRegionDefaultResolver } = require_client2();
20526
20526
  var { NoAuthSigner: NoAuthSigner2, getHttpAuthSchemeEndpointRuleSetPlugin: getHttpAuthSchemeEndpointRuleSetPlugin2, DefaultIdentityProviderConfig: DefaultIdentityProviderConfig2, getHttpSigningPlugin: getHttpSigningPlugin2 } = require_dist_cjs2();
@@ -21542,7 +21542,7 @@ var require_sts = __commonJS((exports) => {
21542
21542
  exports.getDefaultRoleAssumerWithWebIdentity = getDefaultRoleAssumerWithWebIdentity;
21543
21543
  });
21544
21544
 
21545
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveAssumeRoleCredentials.js
21545
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveAssumeRoleCredentials.js
21546
21546
  var import_client9, import_config19, isAssumeRoleProfile = (arg, { profile = "default", logger } = {}) => {
21547
21547
  return Boolean(arg) && typeof arg === "object" && typeof arg.role_arn === "string" && ["undefined", "string"].indexOf(typeof arg.role_session_name) > -1 && ["undefined", "string"].indexOf(typeof arg.external_id) > -1 && ["undefined", "string"].indexOf(typeof arg.mfa_serial) > -1 && (isAssumeRoleWithSourceProfile(arg, { profile, logger }) || isCredentialSourceProfile(arg, { profile, logger }));
21548
21548
  }, isAssumeRoleWithSourceProfile = (arg, { profile, logger }) => {
@@ -21610,7 +21610,7 @@ var init_resolveAssumeRoleCredentials = __esm(() => {
21610
21610
  import_config19 = __toESM(require_config(), 1);
21611
21611
  });
21612
21612
 
21613
- // ../../node_modules/.bun/@aws-sdk+nested-clients@3.997.43/node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js
21613
+ // node_modules/@aws-sdk/nested-clients/dist-cjs/submodules/signin/index.js
21614
21614
  var require_signin = __commonJS((exports) => {
21615
21615
  var { awsEndpointFunctions: awsEndpointFunctions3, emitWarningIfUnsupportedVersion: emitWarningIfUnsupportedVersion$12, createDefaultUserAgentProvider: createDefaultUserAgentProvider2, NODE_APP_ID_CONFIG_OPTIONS: NODE_APP_ID_CONFIG_OPTIONS2, getAwsRegionExtensionConfiguration: getAwsRegionExtensionConfiguration2, resolveAwsRegionExtensionConfiguration: resolveAwsRegionExtensionConfiguration2, resolveUserAgentConfig: resolveUserAgentConfig2, resolveHostHeaderConfig: resolveHostHeaderConfig2, getUserAgentPlugin: getUserAgentPlugin2, getHostHeaderPlugin: getHostHeaderPlugin2, getLoggerPlugin: getLoggerPlugin2, getRecursionDetectionPlugin: getRecursionDetectionPlugin2 } = require_client2();
21616
21616
  var { NoAuthSigner: NoAuthSigner2, getHttpAuthSchemeEndpointRuleSetPlugin: getHttpAuthSchemeEndpointRuleSetPlugin2, DefaultIdentityProviderConfig: DefaultIdentityProviderConfig2, getHttpSigningPlugin: getHttpSigningPlugin2 } = require_dist_cjs2();
@@ -22342,7 +22342,7 @@ var require_signin = __commonJS((exports) => {
22342
22342
  exports.errorTypeRegistries = errorTypeRegistries3;
22343
22343
  });
22344
22344
 
22345
- // ../../node_modules/.bun/@aws-sdk+credential-provider-login@3.972.76/node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
22345
+ // node_modules/@aws-sdk/credential-provider-login/dist-es/LoginCredentialsFetcher.js
22346
22346
  import { createHash, createPrivateKey, createPublicKey, sign } from "crypto";
22347
22347
  import { promises as fs2 } from "fs";
22348
22348
  import { homedir } from "os";
@@ -22606,7 +22606,7 @@ var init_LoginCredentialsFetcher = __esm(() => {
22606
22606
  };
22607
22607
  });
22608
22608
 
22609
- // ../../node_modules/.bun/@aws-sdk+credential-provider-login@3.972.76/node_modules/@aws-sdk/credential-provider-login/dist-es/fromLoginCredentials.js
22609
+ // node_modules/@aws-sdk/credential-provider-login/dist-es/fromLoginCredentials.js
22610
22610
  var import_client10, import_config21, fromLoginCredentials = (init) => async ({ callerClientConfig } = {}) => {
22611
22611
  init?.logger?.debug?.("@aws-sdk/credential-providers - fromLoginCredentials");
22612
22612
  const profiles = await import_config21.parseKnownFiles(init || {});
@@ -22630,7 +22630,7 @@ var init_fromLoginCredentials = __esm(() => {
22630
22630
  import_config21 = __toESM(require_config(), 1);
22631
22631
  });
22632
22632
 
22633
- // ../../node_modules/.bun/@aws-sdk+credential-provider-login@3.972.76/node_modules/@aws-sdk/credential-provider-login/dist-es/index.js
22633
+ // node_modules/@aws-sdk/credential-provider-login/dist-es/index.js
22634
22634
  var exports_dist_es5 = {};
22635
22635
  __export(exports_dist_es5, {
22636
22636
  fromLoginCredentials: () => fromLoginCredentials
@@ -22639,7 +22639,7 @@ var init_dist_es6 = __esm(() => {
22639
22639
  init_fromLoginCredentials();
22640
22640
  });
22641
22641
 
22642
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveLoginCredentials.js
22642
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveLoginCredentials.js
22643
22643
  var import_client11, isLoginProfile = (data) => {
22644
22644
  return Boolean(data && data.login_session);
22645
22645
  }, resolveLoginCredentials = async (profileName, options, callerClientConfig) => {
@@ -22654,7 +22654,7 @@ var init_resolveLoginCredentials = __esm(() => {
22654
22654
  import_client11 = __toESM(require_client2(), 1);
22655
22655
  });
22656
22656
 
22657
- // ../../node_modules/.bun/@aws-sdk+credential-provider-process@3.972.69/node_modules/@aws-sdk/credential-provider-process/dist-es/getValidatedProcessCredentials.js
22657
+ // node_modules/@aws-sdk/credential-provider-process/dist-es/getValidatedProcessCredentials.js
22658
22658
  var import_client12, getValidatedProcessCredentials = (profileName, data, profiles) => {
22659
22659
  if (data.Version !== 1) {
22660
22660
  throw Error(`Profile ${profileName} credential_process did not return Version 1.`);
@@ -22688,7 +22688,7 @@ var init_getValidatedProcessCredentials = __esm(() => {
22688
22688
  import_client12 = __toESM(require_client2(), 1);
22689
22689
  });
22690
22690
 
22691
- // ../../node_modules/.bun/@aws-sdk+credential-provider-process@3.972.69/node_modules/@aws-sdk/credential-provider-process/dist-es/resolveProcessCredentials.js
22691
+ // node_modules/@aws-sdk/credential-provider-process/dist-es/resolveProcessCredentials.js
22692
22692
  import { exec } from "child_process";
22693
22693
  import { promisify } from "util";
22694
22694
  var import_config22, resolveProcessCredentials = async (profileName, profiles, logger) => {
@@ -22723,7 +22723,7 @@ var init_resolveProcessCredentials = __esm(() => {
22723
22723
  import_config22 = __toESM(require_config(), 1);
22724
22724
  });
22725
22725
 
22726
- // ../../node_modules/.bun/@aws-sdk+credential-provider-process@3.972.69/node_modules/@aws-sdk/credential-provider-process/dist-es/fromProcess.js
22726
+ // node_modules/@aws-sdk/credential-provider-process/dist-es/fromProcess.js
22727
22727
  var import_config23, fromProcess = (init = {}) => async ({ callerClientConfig } = {}) => {
22728
22728
  init.logger?.debug("@aws-sdk/credential-provider-process - fromProcess");
22729
22729
  const profiles = await import_config23.parseKnownFiles(init);
@@ -22736,7 +22736,7 @@ var init_fromProcess = __esm(() => {
22736
22736
  import_config23 = __toESM(require_config(), 1);
22737
22737
  });
22738
22738
 
22739
- // ../../node_modules/.bun/@aws-sdk+credential-provider-process@3.972.69/node_modules/@aws-sdk/credential-provider-process/dist-es/index.js
22739
+ // node_modules/@aws-sdk/credential-provider-process/dist-es/index.js
22740
22740
  var exports_dist_es6 = {};
22741
22741
  __export(exports_dist_es6, {
22742
22742
  fromProcess: () => fromProcess
@@ -22745,7 +22745,7 @@ var init_dist_es7 = __esm(() => {
22745
22745
  init_fromProcess();
22746
22746
  });
22747
22747
 
22748
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveProcessCredentials.js
22748
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveProcessCredentials.js
22749
22749
  var import_client13, isProcessProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.credential_process === "string", resolveProcessCredentials2 = async (options, profile) => {
22750
22750
  const { fromProcess: fromProcess2 } = await Promise.resolve().then(() => (init_dist_es7(), exports_dist_es6));
22751
22751
  const credentials = await fromProcess2({
@@ -22758,7 +22758,7 @@ var init_resolveProcessCredentials2 = __esm(() => {
22758
22758
  import_client13 = __toESM(require_client2(), 1);
22759
22759
  });
22760
22760
 
22761
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveSsoCredentials.js
22761
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveSsoCredentials.js
22762
22762
  var import_client14, resolveSsoCredentials = async (profile, profileData, options = {}, callerClientConfig) => {
22763
22763
  const { fromSSO: fromSSO2 } = await Promise.resolve().then(() => (init_dist_es5(), exports_dist_es4));
22764
22764
  return fromSSO2({
@@ -22780,7 +22780,7 @@ var init_resolveSsoCredentials = __esm(() => {
22780
22780
  import_client14 = __toESM(require_client2(), 1);
22781
22781
  });
22782
22782
 
22783
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveStaticCredentials.js
22783
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveStaticCredentials.js
22784
22784
  var import_client15, isStaticCredsProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.aws_access_key_id === "string" && typeof arg.aws_secret_access_key === "string" && ["undefined", "string"].indexOf(typeof arg.aws_session_token) > -1 && ["undefined", "string"].indexOf(typeof arg.aws_account_id) > -1, resolveStaticCredentials = async (profile, options) => {
22785
22785
  options?.logger?.debug("@aws-sdk/credential-provider-ini - resolveStaticCredentials");
22786
22786
  const credentials = {
@@ -22796,7 +22796,7 @@ var init_resolveStaticCredentials = __esm(() => {
22796
22796
  import_client15 = __toESM(require_client2(), 1);
22797
22797
  });
22798
22798
 
22799
- // ../../node_modules/.bun/@aws-sdk+credential-provider-web-identity@3.972.75/node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromWebToken.js
22799
+ // node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromWebToken.js
22800
22800
  var fromWebToken = (init) => async (awsIdentityProperties) => {
22801
22801
  init.logger?.debug("@aws-sdk/credential-provider-web-identity - fromWebToken");
22802
22802
  const { roleArn, roleSessionName, webIdentityToken, providerId, policyArns, policy, durationSeconds } = init;
@@ -22823,7 +22823,7 @@ var fromWebToken = (init) => async (awsIdentityProperties) => {
22823
22823
  });
22824
22824
  };
22825
22825
 
22826
- // ../../node_modules/.bun/@aws-sdk+credential-provider-web-identity@3.972.75/node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromTokenFile.js
22826
+ // node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromTokenFile.js
22827
22827
  import { readFileSync } from "fs";
22828
22828
  var import_client16, import_config24, ENV_TOKEN_FILE = "AWS_WEB_IDENTITY_TOKEN_FILE", ENV_ROLE_ARN = "AWS_ROLE_ARN", ENV_ROLE_SESSION_NAME = "AWS_ROLE_SESSION_NAME", fromTokenFile = (init = {}) => async (awsIdentityProperties) => {
22829
22829
  init.logger?.debug("@aws-sdk/credential-provider-web-identity - fromTokenFile");
@@ -22851,7 +22851,7 @@ var init_fromTokenFile = __esm(() => {
22851
22851
  import_config24 = __toESM(require_config(), 1);
22852
22852
  });
22853
22853
 
22854
- // ../../node_modules/.bun/@aws-sdk+credential-provider-web-identity@3.972.75/node_modules/@aws-sdk/credential-provider-web-identity/dist-es/index.js
22854
+ // node_modules/@aws-sdk/credential-provider-web-identity/dist-es/index.js
22855
22855
  var exports_dist_es7 = {};
22856
22856
  __export(exports_dist_es7, {
22857
22857
  fromWebToken: () => fromWebToken,
@@ -22861,7 +22861,7 @@ var init_dist_es8 = __esm(() => {
22861
22861
  init_fromTokenFile();
22862
22862
  });
22863
22863
 
22864
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveWebIdentityCredentials.js
22864
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveWebIdentityCredentials.js
22865
22865
  var import_client17, isWebIdentityProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.web_identity_token_file === "string" && typeof arg.role_arn === "string" && ["undefined", "string"].indexOf(typeof arg.role_session_name) > -1, resolveWebIdentityCredentials = async (profile, options, callerClientConfig) => {
22866
22866
  const { fromTokenFile: fromTokenFile2 } = await Promise.resolve().then(() => (init_dist_es8(), exports_dist_es7));
22867
22867
  const credentials = await fromTokenFile2({
@@ -22880,7 +22880,7 @@ var init_resolveWebIdentityCredentials = __esm(() => {
22880
22880
  import_client17 = __toESM(require_client2(), 1);
22881
22881
  });
22882
22882
 
22883
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveProfileData.js
22883
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveProfileData.js
22884
22884
  var import_config25, resolveProfileData = async (profileName, profiles, options, callerClientConfig, visitedProfiles = {}, isAssumeRoleRecursiveCall = false) => {
22885
22885
  const data = profiles[profileName];
22886
22886
  if (Object.keys(visitedProfiles).length > 0 && isStaticCredsProfile(data)) {
@@ -22916,7 +22916,7 @@ var init_resolveProfileData = __esm(() => {
22916
22916
  import_config25 = __toESM(require_config(), 1);
22917
22917
  });
22918
22918
 
22919
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/fromIni.js
22919
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/fromIni.js
22920
22920
  var import_config26, fromIni = (init = {}) => async ({ callerClientConfig } = {}) => {
22921
22921
  init.logger?.debug("@aws-sdk/credential-provider-ini - fromIni");
22922
22922
  const profiles = await import_config26.parseKnownFiles(init);
@@ -22929,7 +22929,7 @@ var init_fromIni = __esm(() => {
22929
22929
  import_config26 = __toESM(require_config(), 1);
22930
22930
  });
22931
22931
 
22932
- // ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.14/node_modules/@aws-sdk/credential-provider-ini/dist-es/index.js
22932
+ // node_modules/@aws-sdk/credential-provider-ini/dist-es/index.js
22933
22933
  var exports_dist_es8 = {};
22934
22934
  __export(exports_dist_es8, {
22935
22935
  fromIni: () => fromIni
@@ -22940,6 +22940,128 @@ var init_dist_es9 = __esm(() => {
22940
22940
 
22941
22941
  // src/server/worker.ts
22942
22942
  import { randomUUID as randomUUID4 } from "crypto";
22943
+ // package.json
22944
+ var package_default = {
22945
+ name: "@hasna/skills",
22946
+ version: "0.2.1",
22947
+ description: "Skills library for AI coding agents",
22948
+ type: "module",
22949
+ bin: {
22950
+ skills: "bin/index.js",
22951
+ "skills-mcp": "bin/mcp.js",
22952
+ "skills-server": "bin/server.js",
22953
+ "skills-worker": "bin/worker.js",
22954
+ "skills-migrate": "bin/migrate.js"
22955
+ },
22956
+ exports: {
22957
+ ".": {
22958
+ import: "./dist/index.js",
22959
+ types: "./dist/index.d.ts"
22960
+ },
22961
+ "./storage": {
22962
+ import: "./dist/storage.js",
22963
+ types: "./dist/storage.d.ts"
22964
+ },
22965
+ "./sdk": {
22966
+ import: "./dist/sdk/index.js",
22967
+ types: "./dist/sdk/index.d.ts"
22968
+ },
22969
+ "./admin-contract": {
22970
+ import: "./dist/admin-contract.js",
22971
+ types: "./dist/admin-contract.d.ts"
22972
+ }
22973
+ },
22974
+ files: [
22975
+ "dist/",
22976
+ "!dist/**/*.test.d.ts",
22977
+ "!dist/test-preload.d.ts",
22978
+ "!dist/platform",
22979
+ "bin/",
22980
+ "migrations/",
22981
+ "docs/skill-standard.md",
22982
+ "schemas/",
22983
+ "LICENSE",
22984
+ "README.md"
22985
+ ],
22986
+ main: "./dist/index.js",
22987
+ types: "./dist/index.d.ts",
22988
+ scripts: {
22989
+ clean: "rm -rf bin/ dist/",
22990
+ build: "bun run clean && bun build ./src/cli/index.tsx --outdir ./bin --target bun && bun build ./src/mcp/index.ts --outfile ./bin/mcp.js --target bun && bun build ./src/server/index.ts --outfile ./bin/server.js --target bun && bun build ./src/server/worker.ts --outfile ./bin/worker.js --target bun && bun build ./src/server/migrate.ts --outfile ./bin/migrate.js --target bun && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
22991
+ "build:js": "rm -rf dist && bun build ./src/index.ts ./src/storage.ts ./src/sdk/index.ts ./src/admin-contract.ts --outdir ./dist --target bun && tsc --emitDeclarationOnly --declaration --outDir dist",
22992
+ test: "bun test --timeout 30000",
22993
+ dev: "bun run ./src/cli/index.tsx",
22994
+ "dev:watch": "bun --watch run ./src/cli/index.tsx",
22995
+ "dev:mcp": "bun --watch run ./src/mcp/index.ts",
22996
+ "dev:server": "bun --watch run ./src/server/index.ts",
22997
+ "dev:worker": "bun --watch run ./src/server/worker.ts",
22998
+ "docker:check": "bash scripts/docker-build-check.sh",
22999
+ migrate: "bun run ./src/server/migrate.ts",
23000
+ typecheck: "tsc --noEmit",
23001
+ "verify:release": "bun run scripts/release-guard.ts",
23002
+ prepare: "bun run build:js",
23003
+ prepack: "bun run build && bun run verify:release",
23004
+ prepublishOnly: "bun run typecheck && bun run test",
23005
+ postinstall: "mkdir -p $HOME/.hasna/skills/custom 2>/dev/null || true"
23006
+ },
23007
+ keywords: [
23008
+ "skills",
23009
+ "ai",
23010
+ "agent",
23011
+ "cli",
23012
+ "typescript",
23013
+ "bun",
23014
+ "claude",
23015
+ "codex",
23016
+ "gemini",
23017
+ "mcp",
23018
+ "model-context-protocol",
23019
+ "open-source",
23020
+ "skills-library",
23021
+ "automation"
23022
+ ],
23023
+ author: "Hasna",
23024
+ license: "Apache-2.0",
23025
+ devDependencies: {
23026
+ "@types/bun": "1.3.14",
23027
+ "@types/node": "25.2.3",
23028
+ "@types/react": "^18.2.0",
23029
+ "bun-types": "1.3.14",
23030
+ "react-devtools-core": "^7.0.1",
23031
+ typescript: "^5",
23032
+ yaml: "^2.9.0"
23033
+ },
23034
+ dependencies: {
23035
+ "@aws-sdk/client-ecs": "^3.1079.0",
23036
+ "@aws-sdk/client-s3": "^3.1079.0",
23037
+ "@hasna/events": "0.1.16",
23038
+ "@modelcontextprotocol/sdk": "^1.26.0",
23039
+ chalk: "^5.3.0",
23040
+ commander: "^12.1.0",
23041
+ ink: "^5.0.1",
23042
+ "ink-select-input": "^6.0.0",
23043
+ "ink-spinner": "^5.0.0",
23044
+ "ink-text-input": "^6.0.0",
23045
+ react: "^18.2.0",
23046
+ zod: "^4.3.6"
23047
+ },
23048
+ engines: {
23049
+ bun: ">=1.0.0"
23050
+ },
23051
+ publishConfig: {
23052
+ registry: "https://registry.npmjs.org",
23053
+ access: "public"
23054
+ },
23055
+ repository: {
23056
+ type: "git",
23057
+ url: "git+https://github.com/hasna/apps.git"
23058
+ },
23059
+ homepage: "https://github.com/hasna/skills",
23060
+ bugs: {
23061
+ url: "https://github.com/hasna/skills/issues"
23062
+ }
23063
+ };
23064
+
22943
23065
  // src/lib/skill-bundle.ts
22944
23066
  var ANY_SEGMENT_EXCLUDES = new Set([
22945
23067
  ".git",
@@ -23069,7 +23191,7 @@ function ownBytes(view) {
23069
23191
  return out;
23070
23192
  }
23071
23193
 
23072
- // ../../node_modules/.bun/@aws-sdk+checksums@3.1000.28/node_modules/@aws-sdk/checksums/dist-cjs/submodules/flexible-checksums/index.js
23194
+ // node_modules/@aws-sdk/checksums/dist-cjs/submodules/flexible-checksums/index.js
23073
23195
  var { setFeature } = require_client2();
23074
23196
  var { HttpRequest } = require_protocols();
23075
23197
  var { isArrayBuffer, toUint8Array, createBufferedReadable, createChecksumStream } = require_serde();
@@ -23462,10 +23584,10 @@ var $NODE_RESPONSE_CHECKSUM_VALIDATION_CONFIG_OPTIONS = NODE_RESPONSE_CHECKSUM_V
23462
23584
  var $getFlexibleChecksumsPlugin = getFlexibleChecksumsPlugin;
23463
23585
  var $resolveFlexibleChecksumsConfig = resolveFlexibleChecksumsConfig;
23464
23586
 
23465
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
23587
+ // node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
23466
23588
  var import_client23 = __toESM(require_client2(), 1);
23467
23589
 
23468
- // ../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.74/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/submodules/s3/index.js
23590
+ // node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/submodules/s3/index.js
23469
23591
  var { NoOpLogger, getSmithyContext } = require_client();
23470
23592
  var { HttpRequest: HttpRequest2, HttpResponse } = require_protocols();
23471
23593
  var { parseRfc7231DateTime } = require_serde();
@@ -24070,7 +24192,7 @@ var $getThrow200ExceptionsPlugin = getThrow200ExceptionsPlugin;
24070
24192
  var $getValidateBucketNamePlugin = getValidateBucketNamePlugin;
24071
24193
  var $resolveS3Config = resolveS3Config;
24072
24194
 
24073
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
24195
+ // node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
24074
24196
  var import_core = __toESM(require_dist_cjs2(), 1);
24075
24197
  var import_client24 = __toESM(require_client(), 1);
24076
24198
  var import_config29 = __toESM(require_config(), 1);
@@ -24080,17 +24202,17 @@ var import_protocols6 = __toESM(require_protocols(), 1);
24080
24202
  var import_retry4 = __toESM(require_retry(), 1);
24081
24203
  var import_schema2 = __toESM(require_schema(), 1);
24082
24204
 
24083
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthSchemeProvider.js
24205
+ // node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthSchemeProvider.js
24084
24206
  var import_httpAuthSchemes = __toESM(require_httpAuthSchemes(), 1);
24085
24207
  var import_signature_v4_multi_region = __toESM(require_dist_cjs4(), 1);
24086
24208
  var import_client2 = __toESM(require_client(), 1);
24087
24209
  var import_endpoints3 = __toESM(require_endpoints(), 1);
24088
24210
 
24089
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/endpoint/endpointResolver.js
24211
+ // node_modules/@aws-sdk/client-s3/dist-es/endpoint/endpointResolver.js
24090
24212
  var import_client = __toESM(require_client2(), 1);
24091
24213
  var import_endpoints2 = __toESM(require_endpoints(), 1);
24092
24214
 
24093
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/endpoint/bdd.js
24215
+ // node_modules/@aws-sdk/client-s3/dist-es/endpoint/bdd.js
24094
24216
  var import_endpoints = __toESM(require_endpoints(), 1);
24095
24217
  var aw = "ref";
24096
24218
  var ax = "argv";
@@ -26034,7 +26156,7 @@ var nodes = new Int32Array([
26034
26156
  ]);
26035
26157
  var bdd = import_endpoints.BinaryDecisionDiagram.from(nodes, root, _data.conditions, _data.results);
26036
26158
 
26037
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/endpoint/endpointResolver.js
26159
+ // node_modules/@aws-sdk/client-s3/dist-es/endpoint/endpointResolver.js
26038
26160
  var cache = new import_endpoints2.EndpointCache({
26039
26161
  size: 50,
26040
26162
  params: [
@@ -26062,7 +26184,7 @@ var defaultEndpointResolver = (endpointParams, context = {}) => {
26062
26184
  };
26063
26185
  import_endpoints2.customEndpointFunctions.aws = import_client.awsEndpointFunctions;
26064
26186
 
26065
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthSchemeProvider.js
26187
+ // node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthSchemeProvider.js
26066
26188
  var createEndpointRuleSetHttpAuthSchemeParametersProvider = (defaultHttpAuthSchemeParametersProvider) => async (config, context, input) => {
26067
26189
  if (!input) {
26068
26190
  throw new Error("Could not find `input` for `defaultEndpointRuleSetHttpAuthSchemeParametersProvider`");
@@ -26178,11 +26300,11 @@ var resolveHttpAuthSchemeConfig = (config) => {
26178
26300
  });
26179
26301
  };
26180
26302
 
26181
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/commandBuilder.js
26303
+ // node_modules/@aws-sdk/client-s3/dist-es/commandBuilder.js
26182
26304
  var import_client3 = __toESM(require_client(), 1);
26183
26305
  var import_endpoints4 = __toESM(require_endpoints(), 1);
26184
26306
 
26185
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/endpoint/EndpointParameters.js
26307
+ // node_modules/@aws-sdk/client-s3/dist-es/endpoint/EndpointParameters.js
26186
26308
  var resolveClientEndpointParameters = (options) => {
26187
26309
  return Object.assign(options, {
26188
26310
  useFipsEndpoint: options.useFipsEndpoint ?? false,
@@ -26208,7 +26330,7 @@ var commonParams = {
26208
26330
  UseDualStack: { type: "builtInParams", name: "useDualstackEndpoint" }
26209
26331
  };
26210
26332
 
26211
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/commandBuilder.js
26333
+ // node_modules/@aws-sdk/client-s3/dist-es/commandBuilder.js
26212
26334
  var command = import_client3.makeBuilder(commonParams, "AmazonS3", "S3Client", import_endpoints4.getEndpointPlugin);
26213
26335
  var _ep0 = {
26214
26336
  Bucket: { type: "contextParams", name: "Bucket" },
@@ -26240,10 +26362,10 @@ var _mw11 = (Command, cs, config, o2) => [
26240
26362
  $getSsecPlugin(config)
26241
26363
  ];
26242
26364
 
26243
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/schemas/schemas_0.js
26365
+ // node_modules/@aws-sdk/client-s3/dist-es/schemas/schemas_0.js
26244
26366
  var import_schema = __toESM(require_schema(), 1);
26245
26367
 
26246
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/models/S3ServiceException.js
26368
+ // node_modules/@aws-sdk/client-s3/dist-es/models/S3ServiceException.js
26247
26369
  var import_client4 = __toESM(require_client(), 1);
26248
26370
  class S3ServiceException extends import_client4.ServiceException {
26249
26371
  constructor(options) {
@@ -26252,7 +26374,7 @@ class S3ServiceException extends import_client4.ServiceException {
26252
26374
  }
26253
26375
  }
26254
26376
 
26255
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/models/errors.js
26377
+ // node_modules/@aws-sdk/client-s3/dist-es/models/errors.js
26256
26378
  class NoSuchUpload extends S3ServiceException {
26257
26379
  name = "NoSuchUpload";
26258
26380
  $fault = "client";
@@ -26530,7 +26652,7 @@ class ObjectAlreadyInActiveTierError extends S3ServiceException {
26530
26652
  }
26531
26653
  }
26532
26654
 
26533
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/schemas/schemas_0.js
26655
+ // node_modules/@aws-sdk/client-s3/dist-es/schemas/schemas_0.js
26534
26656
  var _A = "Account";
26535
26657
  var _AAO = "AnalyticsAndOperator";
26536
26658
  var _AC = "AccelerateConfiguration";
@@ -31982,13 +32104,13 @@ var WriteGetObjectResponse$ = [
31982
32104
  () => __Unit
31983
32105
  ];
31984
32106
 
31985
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/commands/CreateSessionCommand.js
32107
+ // node_modules/@aws-sdk/client-s3/dist-es/commands/CreateSessionCommand.js
31986
32108
  class CreateSessionCommand extends command(_ep4, _mw0, "CreateSession", CreateSession$) {
31987
32109
  }
31988
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/package.json
31989
- var package_default = {
32110
+ // node_modules/@aws-sdk/client-s3/package.json
32111
+ var package_default2 = {
31990
32112
  name: "@aws-sdk/client-s3",
31991
- version: "3.1112.0",
32113
+ version: "3.1113.0",
31992
32114
  description: "AWS SDK for JavaScript S3 Client for Node.js, Browser and React Native",
31993
32115
  homepage: "https://github.com/aws/aws-sdk-js-v3/tree/main/clients/client-s3",
31994
32116
  license: "Apache-2.0",
@@ -32055,7 +32177,7 @@ var package_default = {
32055
32177
  tslib: "^2.6.2"
32056
32178
  },
32057
32179
  devDependencies: {
32058
- "@aws-sdk/signature-v4-crt": "3.1112.0",
32180
+ "@aws-sdk/signature-v4-crt": "3.1113.0",
32059
32181
  "@smithy/snapshot-testing": "^2.2.16",
32060
32182
  "@tsconfig/node20": "20.1.8",
32061
32183
  "@types/node": "^20.14.8",
@@ -32070,15 +32192,15 @@ var package_default = {
32070
32192
  }
32071
32193
  };
32072
32194
 
32073
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
32195
+ // node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
32074
32196
  var import_client19 = __toESM(require_client2(), 1);
32075
32197
  var import_httpAuthSchemes3 = __toESM(require_httpAuthSchemes(), 1);
32076
32198
 
32077
- // ../../node_modules/.bun/@aws-sdk+credential-provider-node@3.972.80/node_modules/@aws-sdk/credential-provider-node/dist-es/defaultProvider.js
32199
+ // node_modules/@aws-sdk/credential-provider-node/dist-es/defaultProvider.js
32078
32200
  init_dist_es();
32079
32201
  var import_config27 = __toESM(require_config(), 1);
32080
32202
 
32081
- // ../../node_modules/.bun/@aws-sdk+credential-provider-node@3.972.80/node_modules/@aws-sdk/credential-provider-node/dist-es/remoteProvider.js
32203
+ // node_modules/@aws-sdk/credential-provider-node/dist-es/remoteProvider.js
32082
32204
  var import_config10 = __toESM(require_config(), 1);
32083
32205
  var ENV_IMDS_DISABLED = "AWS_EC2_METADATA_DISABLED";
32084
32206
  var remoteProvider = async (init) => {
@@ -32097,7 +32219,7 @@ var remoteProvider = async (init) => {
32097
32219
  return fromInstanceMetadata2(init);
32098
32220
  };
32099
32221
 
32100
- // ../../node_modules/.bun/@aws-sdk+credential-provider-node@3.972.80/node_modules/@aws-sdk/credential-provider-node/dist-es/runtime/memoize-chain.js
32222
+ // node_modules/@aws-sdk/credential-provider-node/dist-es/runtime/memoize-chain.js
32101
32223
  function memoizeChain(providers, treatAsExpired) {
32102
32224
  const chain2 = internalCreateChain(providers);
32103
32225
  let activeLock;
@@ -32161,7 +32283,7 @@ var internalCreateChain = (providers) => async (awsIdentityProperties) => {
32161
32283
  throw lastProviderError;
32162
32284
  };
32163
32285
 
32164
- // ../../node_modules/.bun/@aws-sdk+credential-provider-node@3.972.80/node_modules/@aws-sdk/credential-provider-node/dist-es/defaultProvider.js
32286
+ // node_modules/@aws-sdk/credential-provider-node/dist-es/defaultProvider.js
32165
32287
  var multipleCredentialSourceWarningEmitted = false;
32166
32288
  var defaultProvider = (init = {}) => memoizeChain([
32167
32289
  async () => {
@@ -32227,7 +32349,7 @@ var defaultProvider = (init = {}) => memoizeChain([
32227
32349
  }
32228
32350
  ], credentialsTreatedAsExpired);
32229
32351
  var credentialsTreatedAsExpired = (credentials) => credentials?.expiration !== undefined && credentials.expiration.getTime() - Date.now() < 300000;
32230
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
32352
+ // node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
32231
32353
  var import_checksum2 = __toESM(require_checksum(), 1);
32232
32354
  var import_client20 = __toESM(require_client(), 1);
32233
32355
  var import_config28 = __toESM(require_config(), 1);
@@ -32236,7 +32358,7 @@ var import_retry3 = __toESM(require_retry(), 1);
32236
32358
  var import_serde4 = __toESM(require_serde(), 1);
32237
32359
  var import_node_http_handler2 = __toESM(require_dist_cjs6(), 1);
32238
32360
 
32239
- // ../../node_modules/.bun/@aws-sdk+checksums@3.1000.28/node_modules/@aws-sdk/checksums/dist-cjs/submodules/sha/index.js
32361
+ // node_modules/@aws-sdk/checksums/dist-cjs/submodules/sha/index.js
32240
32362
  var { toUint8Array: toUint8Array2, concatBytes } = require_serde();
32241
32363
  var { createHmac, createHash: createHash2 } = __require("crypto");
32242
32364
  var { Sha256: Sha2562, Sha256Js, Sha256Node } = require_checksum();
@@ -32465,7 +32587,7 @@ var subtle = typeof digest === "function" && typeof sign2 === "function" && type
32465
32587
  var MAX_PENDING_BYTES = 8 * 1024 * 1024;
32466
32588
  var $Sha1 = Sha1Node;
32467
32589
 
32468
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.shared.js
32590
+ // node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.shared.js
32469
32591
  var import_httpAuthSchemes2 = __toESM(require_httpAuthSchemes(), 1);
32470
32592
  var import_signature_v4_multi_region2 = __toESM(require_dist_cjs4(), 1);
32471
32593
  var import_checksum = __toESM(require_checksum(), 1);
@@ -32517,7 +32639,7 @@ var getRuntimeConfig2 = (config) => {
32517
32639
  };
32518
32640
  };
32519
32641
 
32520
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
32642
+ // node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
32521
32643
  var getRuntimeConfig3 = (config) => {
32522
32644
  import_client20.emitWarningIfUnsupportedVersion(process.version);
32523
32645
  const defaultsMode = import_config28.resolveDefaultsModeConfig(config);
@@ -32536,7 +32658,7 @@ var getRuntimeConfig3 = (config) => {
32536
32658
  authSchemePreference: config?.authSchemePreference ?? import_config28.loadConfig(import_httpAuthSchemes3.NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, loaderConfig),
32537
32659
  bodyLengthChecker: config?.bodyLengthChecker ?? import_serde4.calculateBodyLength,
32538
32660
  credentialDefaultProvider: config?.credentialDefaultProvider ?? defaultProvider,
32539
- defaultUserAgentProvider: config?.defaultUserAgentProvider ?? import_client19.createDefaultUserAgentProvider({ serviceId: clientSharedValues.serviceId, clientVersion: package_default.version }),
32661
+ defaultUserAgentProvider: config?.defaultUserAgentProvider ?? import_client19.createDefaultUserAgentProvider({ serviceId: clientSharedValues.serviceId, clientVersion: package_default2.version }),
32540
32662
  disableS3ExpressSessionAuth: config?.disableS3ExpressSessionAuth ?? import_config28.loadConfig($NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_OPTIONS, loaderConfig),
32541
32663
  eventStreamSerdeProvider: config?.eventStreamSerdeProvider ?? import_event_streams.eventStreamSerdeProvider,
32542
32664
  maxAttempts: config?.maxAttempts ?? import_config28.loadConfig(import_retry3.NODE_MAX_ATTEMPT_CONFIG_OPTIONS, config),
@@ -32558,12 +32680,12 @@ var getRuntimeConfig3 = (config) => {
32558
32680
  };
32559
32681
  };
32560
32682
 
32561
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeExtensions.js
32683
+ // node_modules/@aws-sdk/client-s3/dist-es/runtimeExtensions.js
32562
32684
  var import_client21 = __toESM(require_client2(), 1);
32563
32685
  var import_client22 = __toESM(require_client(), 1);
32564
32686
  var import_protocols5 = __toESM(require_protocols(), 1);
32565
32687
 
32566
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthExtensionConfiguration.js
32688
+ // node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthExtensionConfiguration.js
32567
32689
  var getHttpAuthExtensionConfiguration2 = (runtimeConfig) => {
32568
32690
  const _httpAuthSchemes = runtimeConfig.httpAuthSchemes;
32569
32691
  let _httpAuthSchemeProvider = runtimeConfig.httpAuthSchemeProvider;
@@ -32602,14 +32724,14 @@ var resolveHttpAuthRuntimeConfig2 = (config) => {
32602
32724
  };
32603
32725
  };
32604
32726
 
32605
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeExtensions.js
32727
+ // node_modules/@aws-sdk/client-s3/dist-es/runtimeExtensions.js
32606
32728
  var resolveRuntimeExtensions2 = (runtimeConfig, extensions) => {
32607
32729
  const extensionConfiguration = Object.assign(import_client21.getAwsRegionExtensionConfiguration(runtimeConfig), import_client22.getDefaultExtensionConfiguration(runtimeConfig), import_protocols5.getHttpHandlerExtensionConfiguration(runtimeConfig), getHttpAuthExtensionConfiguration2(runtimeConfig));
32608
32730
  extensions.forEach((extension) => extension.configure(extensionConfiguration));
32609
32731
  return Object.assign(runtimeConfig, import_client21.resolveAwsRegionExtensionConfiguration(extensionConfiguration), import_client22.resolveDefaultRuntimeConfig(extensionConfiguration), import_protocols5.resolveHttpHandlerRuntimeConfig(extensionConfiguration), resolveHttpAuthRuntimeConfig2(extensionConfiguration));
32610
32732
  };
32611
32733
 
32612
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
32734
+ // node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
32613
32735
  class S3Client extends import_client24.Client {
32614
32736
  config;
32615
32737
  constructor(...[configuration]) {
@@ -32654,15 +32776,15 @@ class S3Client extends import_client24.Client {
32654
32776
  }
32655
32777
  }
32656
32778
 
32657
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/commands/DeleteObjectCommand.js
32779
+ // node_modules/@aws-sdk/client-s3/dist-es/commands/DeleteObjectCommand.js
32658
32780
  class DeleteObjectCommand extends command(_ep0, _mw0, "DeleteObject", DeleteObject$) {
32659
32781
  }
32660
32782
 
32661
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/commands/GetObjectCommand.js
32783
+ // node_modules/@aws-sdk/client-s3/dist-es/commands/GetObjectCommand.js
32662
32784
  class GetObjectCommand extends command(_ep0, _mw7, "GetObject", GetObject$) {
32663
32785
  }
32664
32786
 
32665
- // ../../node_modules/.bun/@aws-sdk+client-s3@3.1112.0/node_modules/@aws-sdk/client-s3/dist-es/commands/PutObjectCommand.js
32787
+ // node_modules/@aws-sdk/client-s3/dist-es/commands/PutObjectCommand.js
32666
32788
  class PutObjectCommand extends command(_ep0, _mw11, "PutObject", PutObject$) {
32667
32789
  }
32668
32790
 
@@ -32676,7 +32798,7 @@ class ArtifactStorage {
32676
32798
  constructor(options = {}) {
32677
32799
  this.bucket = options.bucket;
32678
32800
  this.prefix = (options.prefix || "skills/artifacts").replace(/^\/+|\/+$/g, "");
32679
- this.s3 = this.bucket ? new S3Client({ region: options.region || process.env.AWS_REGION || "us-east-1" }) : undefined;
32801
+ this.s3 = this.bucket ? options.client ?? new S3Client({ region: options.region || process.env.AWS_REGION || "us-east-1" }) : undefined;
32680
32802
  }
32681
32803
  get usesS3() {
32682
32804
  return Boolean(this.bucket);
@@ -32774,6 +32896,27 @@ class ArtifactStorage {
32774
32896
  keyFor(run, relativePath) {
32775
32897
  return this.objectKeyFor(run.orgId, run.id, relativePath);
32776
32898
  }
32899
+ async putVersionObjects(orgId, slug, version2, bytes, manifest, contentType = "application/gzip") {
32900
+ if (!this.bucket || !this.s3)
32901
+ return { storageKind: "db" };
32902
+ const key = this.versionKeyFor(orgId, slug, version2, "bundle.tar.gz");
32903
+ await this.s3.send(new PutObjectCommand({ Bucket: this.bucket, Key: key, Body: bytes, ContentType: contentType }));
32904
+ await this.s3.send(new PutObjectCommand({
32905
+ Bucket: this.bucket,
32906
+ Key: this.versionKeyFor(orgId, slug, version2, "manifest.json"),
32907
+ Body: new TextEncoder().encode(JSON.stringify(manifest, null, 2)),
32908
+ ContentType: "application/json"
32909
+ }));
32910
+ return { storageKind: "s3", storageKey: key };
32911
+ }
32912
+ versionPlacement(orgId, slug, version2) {
32913
+ if (!this.bucket || !this.s3)
32914
+ return { storageKind: "db" };
32915
+ return { storageKind: "s3", storageKey: this.versionKeyFor(orgId, slug, version2, "bundle.tar.gz") };
32916
+ }
32917
+ versionKeyFor(orgId, slug, version2, file) {
32918
+ return `${this.prefix}/skills/${encodeURIComponent(orgId)}/${encodeURIComponent(slug)}/${encodeURIComponent(version2)}/${file}`;
32919
+ }
32777
32920
  bundleKeyFor(orgId, sha256) {
32778
32921
  return `${this.prefix}/bundles/${encodeURIComponent(orgId)}/${sha256}.tar.gz`;
32779
32922
  }
@@ -32875,12 +33018,12 @@ var DEFAULT_RUN_QUOTA = {
32875
33018
  };
32876
33019
 
32877
33020
  // src/server/database-url.ts
32878
- import { isAbsolute, join as join5 } from "path";
33021
+ import { isAbsolute, join as join4 } from "path";
32879
33022
  import { fileURLToPath } from "url";
32880
33023
 
32881
33024
  // src/lib/config.ts
32882
33025
  import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync, mkdirSync, copyFileSync, readdirSync, statSync } from "fs";
32883
- import { join as join4, dirname as dirname2 } from "path";
33026
+ import { join as join3, dirname as dirname2 } from "path";
32884
33027
 
32885
33028
  // src/lib/retired-settings.ts
32886
33029
  var RETIRED_ENV_SUFFIXES = ["_STORAGE_MODE", "_DEPLOYMENT_MODE", "_CLOUD_MODE"];
@@ -32919,94 +33062,87 @@ function assertNoRetiredModeEnvVars(env, options) {
32919
33062
 
32920
33063
  // src/lib/app-home.ts
32921
33064
  import { existsSync } from "fs";
32922
- import { homedir as homedir3 } from "os";
32923
- import { join as join3, resolve } from "path";
32924
-
32925
- // ../../node_modules/.bun/@hasna+paths@0.1.0/node_modules/@hasna/paths/dist/index.js
32926
33065
  import { homedir as homedir2 } from "os";
32927
- import { join as join2 } from "path";
32928
- var KIND_ENV = {
33066
+ import { join as join2, resolve } from "path";
33067
+ import { homedir as pathsResolverHomedir } from "os";
33068
+ import { join as pathsResolverJoin } from "path";
33069
+ var PATHS_RESOLVER_KIND_ENV = {
32929
33070
  config: "HASNA_CONFIG_HOME",
32930
33071
  data: "HASNA_DATA_HOME",
32931
33072
  state: "HASNA_STATE_HOME",
32932
33073
  cache: "HASNA_CACHE_HOME"
32933
33074
  };
32934
- var APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
32935
- function assertApp(app) {
33075
+ var PATHS_RESOLVER_APP_SLUG_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
33076
+ function pathsResolverAssertApp(app) {
32936
33077
  if (typeof app !== "string" || app.length === 0) {
32937
33078
  throw new TypeError("paths: app must be a non-empty string");
32938
33079
  }
32939
- if (!APP_SLUG_RE.test(app)) {
33080
+ if (!PATHS_RESOLVER_APP_SLUG_RE.test(app)) {
32940
33081
  throw new TypeError(`paths: invalid app slug "${app}" \u2014 expected lowercase kebab-case ([a-z0-9]+(-[a-z0-9]+)*)`);
32941
33082
  }
32942
33083
  }
32943
- function envOf(options) {
32944
- return options.env ?? process.env;
32945
- }
32946
- function envValue(options, kind) {
32947
- const value = envOf(options)[KIND_ENV[kind]];
32948
- return typeof value === "string" && value.length > 0 ? value : undefined;
32949
- }
32950
- function isMacOS(platform) {
32951
- return platform === "darwin";
33084
+ function pathsResolverAssertKind(kind) {
33085
+ if (!Object.keys(PATHS_RESOLVER_KIND_ENV).includes(kind)) {
33086
+ throw new TypeError(`paths: invalid path kind "${kind}" \u2014 expected one of ${Object.keys(PATHS_RESOLVER_KIND_ENV).join(", ")}`);
33087
+ }
32952
33088
  }
32953
- function baseDir(kind, options) {
32954
- const override = envValue(options, kind);
32955
- if (override)
33089
+ function pathsResolverBaseDir(kind, options) {
33090
+ pathsResolverAssertKind(kind);
33091
+ const env = options.env ?? process.env;
33092
+ const override = env[PATHS_RESOLVER_KIND_ENV[kind]];
33093
+ if (typeof override === "string" && override.length > 0)
32956
33094
  return override;
32957
- const home = options.home ?? homedir2();
33095
+ const home = options.home ?? pathsResolverHomedir();
32958
33096
  const platform = options.platform ?? process.platform;
32959
- if (isMacOS(platform)) {
33097
+ if (platform === "darwin") {
32960
33098
  switch (kind) {
32961
33099
  case "config":
32962
33100
  case "data":
32963
- return join2(home, "Library", "Application Support", "Hasna");
33101
+ return pathsResolverJoin(home, "Library", "Application Support", "Hasna");
32964
33102
  case "cache":
32965
- return join2(home, "Library", "Caches", "Hasna");
33103
+ return pathsResolverJoin(home, "Library", "Caches", "Hasna");
32966
33104
  case "state":
32967
- return join2(home, "Library", "Logs", "Hasna");
33105
+ return pathsResolverJoin(home, "Library", "Logs", "Hasna");
32968
33106
  }
32969
33107
  }
32970
33108
  switch (kind) {
32971
33109
  case "config":
32972
- return join2(home, ".config", "hasna");
33110
+ return pathsResolverJoin(home, ".config", "hasna");
32973
33111
  case "data":
32974
- return join2(home, ".local", "share", "hasna");
33112
+ return pathsResolverJoin(home, ".local", "share", "hasna");
32975
33113
  case "state":
32976
- return join2(home, ".local", "state", "hasna");
33114
+ return pathsResolverJoin(home, ".local", "state", "hasna");
32977
33115
  case "cache":
32978
- return join2(home, ".cache", "hasna");
33116
+ return pathsResolverJoin(home, ".cache", "hasna");
32979
33117
  }
32980
33118
  }
32981
- function resolvePath(kind, options) {
32982
- assertApp(options.app);
32983
- const appSegment = options.internal === true ? join2("internal", options.app) : options.app;
32984
- return join2(baseDir(kind, options), appSegment);
33119
+ function pathsResolverResolve(kind, options) {
33120
+ pathsResolverAssertApp(options.app);
33121
+ const appSegment = options.internal === true ? pathsResolverJoin("internal", options.app) : options.app;
33122
+ return pathsResolverJoin(pathsResolverBaseDir(kind, options), appSegment);
32985
33123
  }
32986
33124
  function dataDir(options) {
32987
- return resolvePath("data", options);
33125
+ return pathsResolverResolve("data", options);
32988
33126
  }
32989
-
32990
- // src/lib/app-home.ts
32991
33127
  var DATA_DIR_ENV = "HASNA_SKILLS_DIR";
32992
33128
  var HASNA_SKILLS_HOME_ENV = "HASNA_SKILLS_HOME";
32993
33129
  var SKILLS_HOME_ENV = "SKILLS_HOME";
32994
33130
  var DEFAULT_SQLITE_FILENAME = "server.db";
32995
33131
  var GLOBAL_CONFIG_FILENAME = "config.json";
32996
33132
  function effectiveHome() {
32997
- return process.env["HOME"] || process.env["USERPROFILE"] || homedir3() || "/tmp";
33133
+ return process.env["HOME"] || process.env["USERPROFILE"] || homedir2() || "/tmp";
32998
33134
  }
32999
33135
  function legacyDataRoot() {
33000
- return join3(effectiveHome(), ".hasna", "skills");
33136
+ return join2(effectiveHome(), ".hasna", "skills");
33001
33137
  }
33002
- function resolverDataRoot(home = effectiveHome()) {
33003
- return dataDir({ app: "skills", home });
33138
+ function resolverDataRoot(home = effectiveHome(), env) {
33139
+ return dataDir({ app: "skills", home, env });
33004
33140
  }
33005
33141
  function adoptResolverDataRoot(resolved, env = process.env) {
33006
33142
  const dataOverride = env.HASNA_DATA_HOME;
33007
33143
  if (typeof dataOverride === "string" && dataOverride.trim().length > 0)
33008
33144
  return true;
33009
- return existsSync(join3(resolved, DEFAULT_SQLITE_FILENAME)) || existsSync(join3(resolved, GLOBAL_CONFIG_FILENAME));
33145
+ return existsSync(join2(resolved, DEFAULT_SQLITE_FILENAME)) || existsSync(join2(resolved, GLOBAL_CONFIG_FILENAME));
33010
33146
  }
33011
33147
  function exactDataRoot() {
33012
33148
  for (const key of [DATA_DIR_ENV, HASNA_SKILLS_HOME_ENV, SKILLS_HOME_ENV]) {
@@ -33035,8 +33171,8 @@ function mergeDirectoryContents(sourceDir, targetDir) {
33035
33171
  return;
33036
33172
  mkdirSync(targetDir, { recursive: true });
33037
33173
  for (const entry of readdirSync(sourceDir)) {
33038
- const sourcePath = join4(sourceDir, entry);
33039
- const targetPath = join4(targetDir, entry);
33174
+ const sourcePath = join3(sourceDir, entry);
33175
+ const targetPath = join3(targetDir, entry);
33040
33176
  try {
33041
33177
  const sourceStat = statSync(sourcePath);
33042
33178
  if (sourceStat.isDirectory()) {
@@ -33056,14 +33192,14 @@ function getDataDir() {
33056
33192
  if (hasOperatorOverride())
33057
33193
  return root3;
33058
33194
  const home = effectiveHome();
33059
- const oldDir = join4(home, ".skills");
33060
- const oldConfigFile = join4(home, ".skillsrc");
33195
+ const oldDir = join3(home, ".skills");
33196
+ const oldConfigFile = join3(home, ".skillsrc");
33061
33197
  try {
33062
33198
  mergeDirectoryContents(oldDir, root3);
33063
33199
  } catch {}
33064
- if (existsSync2(oldConfigFile) && !existsSync2(join4(root3, "config.json"))) {
33200
+ if (existsSync2(oldConfigFile) && !existsSync2(join3(root3, "config.json"))) {
33065
33201
  try {
33066
- copyFileSync(oldConfigFile, join4(root3, "config.json"));
33202
+ copyFileSync(oldConfigFile, join3(root3, "config.json"));
33067
33203
  } catch {}
33068
33204
  }
33069
33205
  return root3;
@@ -33077,7 +33213,7 @@ var SQLITE_SCHEMES = new Set(["sqlite", "sqlite3", "file"]);
33077
33213
  var MEMORY_SCHEMES = new Set(["memory"]);
33078
33214
  var SQLITE_EXTENSIONS = [".db", ".sqlite", ".sqlite3", ".db3"];
33079
33215
  function defaultSqlitePath() {
33080
- return join5(getDataDir(), DEFAULT_SQLITE_FILENAME2);
33216
+ return join4(getDataDir(), DEFAULT_SQLITE_FILENAME2);
33081
33217
  }
33082
33218
  function resolveDatabaseTarget(raw) {
33083
33219
  const value = raw?.trim();
@@ -33104,7 +33240,7 @@ function resolveDatabaseTarget(raw) {
33104
33240
  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()}.`);
33105
33241
  }
33106
33242
  if (looksLikeSqlitePath(value)) {
33107
- const path = isAbsolute(value) ? value : join5(process.cwd(), value);
33243
+ const path = isAbsolute(value) ? value : join4(process.cwd(), value);
33108
33244
  return { kind: "sqlite", path, durable: true, label: `sqlite (${path})` };
33109
33245
  }
33110
33246
  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()}.`);
@@ -33128,7 +33264,7 @@ function sqlitePathFromUrl(value, scheme) {
33128
33264
  }
33129
33265
  return rest.slice(2).replace(/^\/\/+/, "/");
33130
33266
  }
33131
- return isAbsolute(rest) ? rest : join5(process.cwd(), rest);
33267
+ return isAbsolute(rest) ? rest : join4(process.cwd(), rest);
33132
33268
  }
33133
33269
  function looksLikeSqlitePath(value) {
33134
33270
  if (value.includes("/"))
@@ -33140,7 +33276,7 @@ function looksLikeSqlitePath(value) {
33140
33276
  import { Database } from "bun:sqlite";
33141
33277
  import { randomUUID as randomUUID2 } from "crypto";
33142
33278
  import { mkdirSync as mkdirSync2, readFileSync as readFileSync3, readdirSync as readdirSync2 } from "fs";
33143
- import { dirname as dirname4, join as join7 } from "path";
33279
+ import { dirname as dirname4, join as join6 } from "path";
33144
33280
 
33145
33281
  // src/server/auth.ts
33146
33282
  import { createHash as createHash3 } from "crypto";
@@ -33162,15 +33298,15 @@ function publicPrincipal(partial = {}) {
33162
33298
 
33163
33299
  // src/server/migrations-dir.ts
33164
33300
  import { existsSync as existsSync3 } from "fs";
33165
- import { dirname as dirname3, join as join6 } from "path";
33301
+ import { dirname as dirname3, join as join5 } from "path";
33166
33302
  var MIGRATION_DIALECTS = ["postgres", "sqlite"];
33167
33303
  var MAX_WALK_UP = 6;
33168
33304
  function findMigrationsRoot(startDirs = defaultStartDirs()) {
33169
33305
  for (const start of startDirs) {
33170
33306
  let dir = start;
33171
33307
  for (let level = 0;level < MAX_WALK_UP; level += 1) {
33172
- const candidate = join6(dir, "migrations");
33173
- if (MIGRATION_DIALECTS.some((dialect) => existsSync3(join6(candidate, dialect))))
33308
+ const candidate = join5(dir, "migrations");
33309
+ if (MIGRATION_DIALECTS.some((dialect) => existsSync3(join5(candidate, dialect))))
33174
33310
  return candidate;
33175
33311
  const parent = dirname3(dir);
33176
33312
  if (parent === dir)
@@ -33184,7 +33320,7 @@ function resolveMigrationsDir(dialect, root3 = findMigrationsRoot()) {
33184
33320
  if (!root3) {
33185
33321
  throw new Error(`could not locate the migrations directory for dialect "${dialect}". ` + `Expected a migrations/${dialect}/ folder alongside the package root.`);
33186
33322
  }
33187
- const dir = join6(root3, dialect);
33323
+ const dir = join5(root3, dialect);
33188
33324
  if (!existsSync3(dir)) {
33189
33325
  throw new Error(`migrations directory not found: ${dir}`);
33190
33326
  }
@@ -33342,6 +33478,20 @@ function dateString(value) {
33342
33478
  return value.toISOString();
33343
33479
  return String(value);
33344
33480
  }
33481
+ function rowToSkillVersion(row) {
33482
+ return {
33483
+ orgId: String(row.org_id),
33484
+ slug: String(row.slug),
33485
+ version: String(row.version),
33486
+ bundleSha256: String(row.bundle_sha256),
33487
+ bundleByteSize: Number(row.bundle_byte_size),
33488
+ storageKind: String(row.storage_kind ?? "db"),
33489
+ ...typeof row.storage_key === "string" ? { storageKey: row.storage_key } : {},
33490
+ manifest: parseJsonObject(row.manifest_json),
33491
+ ...typeof row.published_by_user_id === "string" ? { publishedByUserId: row.published_by_user_id } : {},
33492
+ createdAt: dateString(row.created_at)
33493
+ };
33494
+ }
33345
33495
 
33346
33496
  // src/server/types.ts
33347
33497
  class StaleLeaseGenerationError extends Error {
@@ -33372,6 +33522,21 @@ class SkillRevisionConflictError extends Error {
33372
33522
  }
33373
33523
  }
33374
33524
 
33525
+ class SkillVersionExistsError extends Error {
33526
+ slug;
33527
+ version;
33528
+ existingSha256;
33529
+ attemptedSha256;
33530
+ constructor(slug, version2, existingSha256, attemptedSha256) {
33531
+ super(`version conflict for '${slug}@${version2}': already published with bundle ${existingSha256}, ` + `refusing to overwrite it with ${attemptedSha256}. Publish a new version instead.`);
33532
+ this.slug = slug;
33533
+ this.version = version2;
33534
+ this.existingSha256 = existingSha256;
33535
+ this.attemptedSha256 = attemptedSha256;
33536
+ this.name = "SkillVersionExistsError";
33537
+ }
33538
+ }
33539
+
33375
33540
  // src/lib/revision.ts
33376
33541
  import { createHash as createHash4 } from "crypto";
33377
33542
  function revisionIdOf(content) {
@@ -33667,6 +33832,13 @@ class SqliteSkillsStore {
33667
33832
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
33668
33833
  }
33669
33834
  const carriedSha = input.bundle?.sha256 ?? previousSha;
33835
+ if (input.version && carriedSha) {
33836
+ const existingVersion = this.get("SELECT bundle_sha256 FROM skills_versions WHERE org_id = ? AND slug = ? AND version = ? LIMIT 1", [orgId, input.slug, input.version]);
33837
+ const existingSha = typeof existingVersion?.bundle_sha256 === "string" ? existingVersion.bundle_sha256 : null;
33838
+ if (existingSha && existingSha !== carriedSha) {
33839
+ throw new SkillVersionExistsError(input.slug, input.version, existingSha, carriedSha);
33840
+ }
33841
+ }
33670
33842
  const carriedSize = input.bundle?.byteSize ?? (previous?.bundle_byte_size == null ? null : Number(previous.bundle_byte_size));
33671
33843
  const revisionId = revisionIdOfRecord({
33672
33844
  slug: input.slug,
@@ -33754,6 +33926,21 @@ class SqliteSkillsStore {
33754
33926
  const currentId = typeof current?.revision_id === "string" ? current.revision_id : null;
33755
33927
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, currentId);
33756
33928
  }
33929
+ if (input.version && carriedSha) {
33930
+ this.db.run(`INSERT OR IGNORE INTO skills_versions (org_id, slug, version, bundle_sha256, bundle_byte_size, storage_kind, storage_key, manifest_json, published_by_user_id, created_at)
33931
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`, [
33932
+ orgId,
33933
+ input.slug,
33934
+ input.version,
33935
+ carriedSha,
33936
+ carriedSize ?? 0,
33937
+ input.versionStorage?.storageKind ?? "db",
33938
+ input.versionStorage?.storageKey ?? null,
33939
+ JSON.stringify(input.versionManifest ?? {}),
33940
+ input.principal.userId ?? null,
33941
+ now
33942
+ ]);
33943
+ }
33757
33944
  if (previousSha && input.bundle && previousSha !== input.bundle.sha256)
33758
33945
  this.collectOrphanBundle(orgId, previousSha);
33759
33946
  this.db.run("DELETE FROM skills_tags WHERE org_id = ? AND slug = ?", [orgId, input.slug]);
@@ -33861,6 +34048,13 @@ class SqliteSkillsStore {
33861
34048
  const row = this.get("SELECT * FROM skills_bundles WHERE org_id = ? AND sha256 = ? LIMIT 1", [principal.orgId, sha256]);
33862
34049
  return row ? rowToSkillBundle(row) : null;
33863
34050
  }
34051
+ async listSkillVersions(principal, slug) {
34052
+ return this.all("SELECT * FROM skills_versions WHERE org_id = ? AND slug = ? ORDER BY created_at DESC, version DESC", [principal.orgId, slug]).map(rowToSkillVersion);
34053
+ }
34054
+ async getSkillVersion(principal, slug, version2) {
34055
+ const row = this.get("SELECT * FROM skills_versions WHERE org_id = ? AND slug = ? AND version = ? LIMIT 1", [principal.orgId, slug, version2]);
34056
+ return row ? rowToSkillVersion(row) : null;
34057
+ }
33864
34058
  async pinSkill(principal, slug, metadata = {}) {
33865
34059
  const row = this.get(`INSERT INTO skills_pins (org_id, principal, slug, pinned_at, metadata_json)
33866
34060
  VALUES (?, ?, ?, ?, ?)
@@ -33900,7 +34094,7 @@ class SqliteSkillsStore {
33900
34094
  return this.all("SELECT slug FROM skills_registry WHERE org_id = ? AND tombstoned_at IS NULL ORDER BY slug ASC", [principal.orgId]).map((row) => String(row.slug));
33901
34095
  }
33902
34096
  collectOrphanBundle(orgId, sha256) {
33903
- const referenced = this.get("SELECT 1 AS present FROM skills_registry WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha256]);
34097
+ const referenced = this.get("SELECT 1 AS present FROM skills_registry WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha256]) ?? this.get("SELECT 1 AS present FROM skills_versions WHERE org_id = ? AND bundle_sha256 = ? LIMIT 1", [orgId, sha256]);
33904
34098
  if (referenced)
33905
34099
  return;
33906
34100
  this.db.run("DELETE FROM skills_bundles WHERE org_id = ? AND sha256 = ?", [orgId, sha256]);
@@ -33929,7 +34123,7 @@ function applySqliteMigrations(db, migrationsDir = resolveMigrationsDir("sqlite"
33929
34123
  const appliedNow = [];
33930
34124
  for (const file of files) {
33931
34125
  const version2 = file.replace(/\.sql$/, "");
33932
- const text = readFileSync3(join7(migrationsDir, file), "utf8");
34126
+ const text = readFileSync3(join6(migrationsDir, file), "utf8");
33933
34127
  const apply = db.transaction(() => {
33934
34128
  const already = db.query("SELECT 1 AS present FROM schema_migrations WHERE version = ? LIMIT 1").get(version2);
33935
34129
  if (already)
@@ -33984,320 +34178,1167 @@ function parseScopes(value) {
33984
34178
  }
33985
34179
  }
33986
34180
 
33987
- // src/server/config.ts
33988
- var DATABASE_URL_ENV = "HASNA_SKILLS_DATABASE_URL";
33989
- var SKILLS_ENV_NAMESPACE = "SKILLS";
33990
- function resolveServerConfig(env = process.env) {
33991
- assertNoRetiredModeEnvVars(env, {
33992
- app: SKILLS_ENV_NAMESPACE,
33993
- replacement: DATABASE_URL_ENV
33994
- });
33995
- const nodeEnv = env.NODE_ENV || "development";
33996
- const host = env.HOST || env.SKILLS_HOST || "0.0.0.0";
33997
- const port = parsePositiveInt(env.PORT || env.SKILLS_PORT, 8787);
33998
- return {
33999
- host,
34000
- port,
34001
- databaseUrl: env[DATABASE_URL_ENV] || env.DATABASE_URL || undefined,
34002
- bootstrapApiKey: env.HASNA_SKILLS_BOOTSTRAP_API_KEY || undefined,
34003
- artifactBucket: env.HASNA_SKILLS_S3_BUCKET || env.SKILLS_S3_BUCKET || undefined,
34004
- artifactPrefix: normalizePrefix(env.HASNA_SKILLS_S3_PREFIX || env.SKILLS_S3_PREFIX || "skills/artifacts"),
34005
- inlineWorker: env.HASNA_SKILLS_INLINE_WORKER === "1",
34006
- bundleSigningKey: env.HASNA_SKILLS_API_SIGNING_KEY || env.HASNA_SKILLS_SIGNING_KEY || undefined,
34007
- requestBodyLimitBytes: parsePositiveInt(env.HASNA_SKILLS_REQUEST_BODY_LIMIT_BYTES, 1e6),
34008
- skillBundleLimitBytes: parsePositiveInt(env.HASNA_SKILLS_BUNDLE_LIMIT_BYTES, 25000000),
34009
- tombstoneWindowMs: parsePositiveInt(env.HASNA_SKILLS_TOMBSTONE_WINDOW_MS, 7 * 24 * 60 * 60 * 1000),
34010
- publicBaseUrl: (env.SKILLS_PUBLIC_BASE_URL || localOrigin(host, port)).replace(/\/+$/, ""),
34011
- nodeEnv,
34012
- allowEphemeralStore: env.HASNA_SKILLS_ALLOW_EPHEMERAL_STORE === "1"
34013
- };
34014
- }
34015
- function localOrigin(host, port) {
34016
- const hostname = host === "0.0.0.0" || host === "::" ? "localhost" : host;
34017
- return `http://${hostname.includes(":") ? `[${hostname}]` : hostname}:${port}`;
34018
- }
34019
- function parsePositiveInt(value, fallback) {
34020
- const parsed = Number.parseInt(value ?? "", 10);
34021
- return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
34022
- }
34023
- function normalizePrefix(value) {
34024
- return value.replace(/^\/+|\/+$/g, "") || "skills/artifacts";
34025
- }
34026
-
34027
- // src/server/handlers.ts
34028
- import { createHash as createHash5 } from "crypto";
34181
+ // src/lib/installer.ts
34182
+ import { existsSync as existsSync4, readFileSync as readFileSync4, rmSync } from "fs";
34183
+ import { dirname as dirname5, join as join7 } from "path";
34184
+ import { fileURLToPath as fileURLToPath2 } from "url";
34029
34185
 
34030
- // src/server/store.ts
34031
- import { randomUUID as randomUUID3 } from "crypto";
34032
- function recordFieldsOf(input, carriedBundle, carriedSkillMd) {
34033
- return {
34034
- slug: input.slug,
34035
- displayName: input.displayName,
34036
- description: input.description,
34037
- category: input.category,
34038
- tags: input.tags,
34039
- source: input.source,
34040
- kind: input.kind,
34041
- ...input.version ? { version: input.version } : {},
34042
- ...carriedSkillMd ? { skillMd: carriedSkillMd } : {},
34043
- bundleSha256: input.bundle?.sha256 ?? carriedBundle.bundleSha256,
34044
- bundleByteSize: input.bundle?.byteSize ?? carriedBundle.bundleByteSize
34045
- };
34046
- }
34047
- function resolvePoolMax(env = process.env) {
34048
- const parsed = Number.parseInt(env.HASNA_SKILLS_DATABASE_POOL_MAX || env.SKILLS_DATABASE_POOL_MAX || "", 10);
34049
- return Number.isFinite(parsed) && parsed > 0 ? parsed : 4;
34050
- }
34051
- var LOG_SEQUENCE_ATTEMPTS = 12;
34052
- function createArtifactId() {
34053
- return artifactId();
34054
- }
34055
- async function createStore(options = {}) {
34056
- const target = resolveDatabaseTarget(options.databaseUrl);
34057
- const store = instantiateStore(target, options.sqlite);
34058
- await store.verifyConnectivity?.();
34059
- if (options.bootstrapApiKey && store.ensureBootstrapApiKey) {
34060
- await store.ensureBootstrapApiKey(options.bootstrapApiKey);
34061
- }
34062
- return store;
34063
- }
34064
- function instantiateStore(target, sqliteOptions) {
34065
- switch (target.kind) {
34066
- case "postgres":
34067
- return new PostgresSkillsStore(target.url);
34068
- case "sqlite":
34069
- return new SqliteSkillsStore(target.path, sqliteOptions);
34070
- case "memory":
34071
- return new MemorySkillsStore;
34186
+ // src/lib/registry-data/development-tools.ts
34187
+ var DEVELOPMENT_TOOLS_SKILLS = [
34188
+ {
34189
+ name: "repo-onboarding-report",
34190
+ displayName: "Repo Onboarding Report",
34191
+ description: "Generate repository onboarding packages with architecture maps, setup guides, risk registers, and first-week plans",
34192
+ category: "Development Tools",
34193
+ kind: "instruction",
34194
+ tags: ["repository", "onboarding", "architecture", "developer-tools"]
34195
+ },
34196
+ {
34197
+ name: "security-audit-report",
34198
+ displayName: "Security Audit Report",
34199
+ description: "Generate application security hardening reports covering auth, secrets, headers, webhooks, RLS, permissions, dependencies, and prioritized fixes",
34200
+ category: "Development Tools",
34201
+ kind: "instruction",
34202
+ tags: ["security", "audit", "hardening", "rls", "webhooks"]
34203
+ },
34204
+ {
34205
+ name: "performance-audit-report",
34206
+ displayName: "Performance Audit Report",
34207
+ description: "Generate performance audit reports with metrics, findings, budgets, remediation plans, and manifest artifacts",
34208
+ category: "Development Tools",
34209
+ kind: "instruction",
34210
+ tags: ["performance", "audit", "latency", "budget", "web"]
34211
+ },
34212
+ {
34213
+ name: "migration-plan-pack",
34214
+ displayName: "Migration Plan Pack",
34215
+ description: "Generate migration plans for frameworks, libraries, databases, infrastructure, and architecture upgrades with risk matrix, checklist, rollout, and test strategy artifacts",
34216
+ category: "Development Tools",
34217
+ kind: "instruction",
34218
+ tags: ["migration", "upgrade", "planning", "frameworks", "databases"]
34219
+ },
34220
+ {
34221
+ name: "test-suite-generator",
34222
+ displayName: "Test Suite Generator",
34223
+ description: "Generate runnable API, unit, and browser test suite packages with coverage notes",
34224
+ category: "Development Tools",
34225
+ kind: "instruction",
34226
+ tags: ["testing", "qa", "api-tests", "browser-tests", "coverage"]
34227
+ },
34228
+ {
34229
+ name: "api-test-suite",
34230
+ displayName: "API Test Suite",
34231
+ description: "Generate and run API test suites with comprehensive endpoint coverage",
34232
+ category: "Development Tools",
34233
+ tags: ["api", "testing", "automation", "qa"]
34234
+ },
34235
+ {
34236
+ name: "api-docs-portal",
34237
+ displayName: "API Docs Portal",
34238
+ description: "Generate static API documentation portals from OpenAPI specs, route lists, and endpoint examples",
34239
+ category: "Development Tools",
34240
+ tags: ["api", "documentation", "openapi", "portal"]
34241
+ },
34242
+ {
34243
+ name: "codefix",
34244
+ displayName: "Code Fix",
34245
+ description: "Code quality CLI for auto-linting, formatting, fixing, and style enforcement",
34246
+ category: "Development Tools",
34247
+ tags: ["code", "linting", "formatting", "quality"]
34248
+ },
34249
+ {
34250
+ name: "commitpush",
34251
+ displayName: "Commit Push",
34252
+ description: "Create logical commits from repo changes and push directly to the main branch",
34253
+ category: "Development Tools",
34254
+ tags: ["git", "commit", "push", "automation"]
34255
+ },
34256
+ {
34257
+ name: "commitpushpr",
34258
+ displayName: "Commit Push PR",
34259
+ description: "Create logical commits, push a feature branch, and open a GitHub pull request",
34260
+ category: "Development Tools",
34261
+ dependencies: ["commitpush"],
34262
+ tags: ["git", "commit", "pull-request", "github", "automation"]
34263
+ },
34264
+ {
34265
+ name: "database-explorer",
34266
+ displayName: "Database Explorer",
34267
+ description: "Explore and query databases with an interactive interface",
34268
+ category: "Development Tools",
34269
+ tags: ["database", "explorer", "sql", "query"]
34270
+ },
34271
+ {
34272
+ name: "diff-viewer",
34273
+ displayName: "Diff Viewer",
34274
+ description: "View and analyze file differences with visual diff representation",
34275
+ category: "Development Tools",
34276
+ tags: ["diff", "comparison", "files", "code-review"]
34277
+ },
34278
+ {
34279
+ name: "generate-api-client",
34280
+ displayName: "Generate API Client",
34281
+ description: "Generate API client libraries from OpenAPI specs and documentation",
34282
+ category: "Development Tools",
34283
+ tags: ["api", "client", "code-generation", "openapi"]
34284
+ },
34285
+ {
34286
+ name: "generate-dockerfile",
34287
+ displayName: "Generate Dockerfile",
34288
+ description: "Generate optimized Dockerfiles for containerized applications",
34289
+ category: "Development Tools",
34290
+ tags: ["docker", "dockerfile", "containers", "devops"]
34291
+ },
34292
+ {
34293
+ name: "generate-env",
34294
+ displayName: "Generate Env",
34295
+ description: "Generate environment variable files from templates and configurations",
34296
+ category: "Development Tools",
34297
+ tags: ["env", "environment", "configuration", "dotenv"]
34298
+ },
34299
+ {
34300
+ name: "generate-sitemap",
34301
+ displayName: "Generate Sitemap",
34302
+ description: "Generate XML sitemaps for websites and web applications",
34303
+ category: "Development Tools",
34304
+ tags: ["sitemap", "seo", "xml", "web"]
34305
+ },
34306
+ {
34307
+ name: "hook",
34308
+ displayName: "Hook",
34309
+ description: "Claude Code hook creation skill - generates standardized hook scaffolds",
34310
+ category: "Development Tools",
34311
+ tags: ["hooks", "scaffold", "claude-code", "automation"]
34312
+ },
34313
+ {
34314
+ name: "http-server",
34315
+ displayName: "HTTP Server",
34316
+ description: "Spin up local HTTP servers for development and testing",
34317
+ category: "Development Tools",
34318
+ tags: ["http", "server", "development", "local"]
34319
+ },
34320
+ {
34321
+ name: "lorem-generator",
34322
+ displayName: "Lorem Generator",
34323
+ description: "Generate placeholder text in various styles and lengths",
34324
+ category: "Development Tools",
34325
+ tags: ["lorem", "placeholder", "text", "mockup"]
34326
+ },
34327
+ {
34328
+ name: "managemcp",
34329
+ displayName: "Manage MCP",
34330
+ description: "Manage MCP servers with install, configure, and lifecycle operations",
34331
+ category: "Development Tools",
34332
+ tags: ["mcp", "management", "servers", "configuration"]
34333
+ },
34334
+ {
34335
+ name: "markdown-validator",
34336
+ displayName: "Markdown Validator",
34337
+ description: "Validate markdown files for syntax, links, and formatting issues",
34338
+ category: "Development Tools",
34339
+ tags: ["markdown", "validation", "linting", "formatting"]
34340
+ },
34341
+ {
34342
+ name: "monitor",
34343
+ displayName: "Monitor",
34344
+ description: "Operate the monitor MCP for machine health, processes, cron jobs, and cleanup workflows",
34345
+ category: "Development Tools",
34346
+ tags: ["monitoring", "mcp", "processes", "operations"]
34347
+ },
34348
+ {
34349
+ name: "regex-tester",
34350
+ displayName: "Regex Tester",
34351
+ description: "Test and validate regular expressions with sample inputs",
34352
+ category: "Development Tools",
34353
+ tags: ["regex", "testing", "validation", "patterns"]
34354
+ },
34355
+ {
34356
+ name: "scancommitpr",
34357
+ displayName: "Scan Commit PR",
34358
+ description: "Scan repo changes, group into logical commits, push, and optionally create a PR",
34359
+ category: "Development Tools",
34360
+ dependencies: ["scancommitpush"],
34361
+ tags: ["git", "commit", "push", "pull-request", "automation"]
34362
+ },
34363
+ {
34364
+ name: "scancommitpush",
34365
+ displayName: "Scan Commit Push",
34366
+ description: "Scan repo changes, group into logical commits with conventional messages, and push to GitHub",
34367
+ category: "Development Tools",
34368
+ tags: ["git", "commit", "push", "automation"]
34369
+ },
34370
+ {
34371
+ name: "security-audit",
34372
+ displayName: "Security Audit",
34373
+ description: "Perform security audits on codebases and infrastructure configurations",
34374
+ category: "Development Tools",
34375
+ tags: ["security", "audit", "vulnerabilities", "scanning"]
34376
+ },
34377
+ {
34378
+ name: "tmux-session",
34379
+ displayName: "Tmux Session",
34380
+ description: "Create and manage grouped tmux sessions with workspace-aware naming and window layout guidance",
34381
+ category: "Development Tools",
34382
+ tags: ["tmux", "terminal", "sessions", "workspace"]
34383
+ },
34384
+ {
34385
+ name: "validate-config",
34386
+ displayName: "Validate Config",
34387
+ description: "Validate configuration files for syntax and schema compliance",
34388
+ category: "Development Tools",
34389
+ tags: ["config", "validation", "schema", "linting"]
34390
+ },
34391
+ {
34392
+ name: "oss-app-two-backend-storage",
34393
+ displayName: "OSS App Two-Backend Storage",
34394
+ description: "Recipe for the Hasna two-backend storage contract: client transport + HTTP store, server PG/SQLite backend, pg-migrations + apply script, fail-closed URL-without-key, bun bins, contract manifest, Dockerfile",
34395
+ category: "Development Tools",
34396
+ tags: ["storage", "backend", "postgresql", "sqlite", "two-backend", "oss-app"],
34397
+ kind: "instruction"
34072
34398
  }
34073
- }
34399
+ ];
34074
34400
 
34075
- class MemorySkillsStore {
34076
- backend = { kind: "memory", durable: false, label: "memory (non-durable)" };
34077
- apiKeys = new Map;
34078
- runs = new Map;
34079
- logs = new Map;
34080
- artifacts = new Map;
34081
- idempotency = new Map;
34082
- skills = new Map;
34083
- bundles = new Map;
34084
- pins = new Map;
34085
- constructor(apiKeys = []) {
34086
- for (const key of apiKeys)
34087
- this.addApiKey(key.token, key.principal);
34088
- }
34089
- addApiKey(token, principal) {
34090
- const resolved = publicPrincipal(principal);
34091
- this.apiKeys.set(hashApiKey(token), resolved);
34092
- return resolved;
34093
- }
34094
- async ensureBootstrapApiKey(token, principal) {
34095
- this.addApiKey(token, principal);
34401
+ // src/lib/registry-data/business-marketing.ts
34402
+ var BUSINESS_MARKETING_SKILLS = [
34403
+ {
34404
+ name: "customer-feedback-report",
34405
+ displayName: "Customer Feedback Report",
34406
+ description: "Generate customer feedback reports with clusters, sentiment, root causes, roadmap recommendations, evidence, and PDF/Markdown artifacts",
34407
+ category: "Business & Marketing",
34408
+ kind: "instruction",
34409
+ tags: ["feedback", "customer", "sentiment", "roadmap", "report"]
34410
+ },
34411
+ {
34412
+ name: "pitch-deck",
34413
+ displayName: "Pitch Deck",
34414
+ description: "Generate investor and sales deck packages with slides, speaker notes, design direction, PDF, and PPTX artifacts",
34415
+ category: "Business & Marketing",
34416
+ kind: "instruction",
34417
+ dependencies: ["market-research-report"],
34418
+ tags: ["deck", "presentation", "investor", "sales", "pptx"]
34419
+ },
34420
+ {
34421
+ name: "proposal-pack",
34422
+ displayName: "Proposal Pack",
34423
+ description: "Generate client proposal packages with proposal, statement of work, pricing, timeline, assumptions, cover email, and PDF/Markdown artifacts",
34424
+ category: "Business & Marketing",
34425
+ kind: "instruction",
34426
+ tags: ["proposal", "sow", "sales", "pricing", "timeline"]
34427
+ },
34428
+ {
34429
+ name: "seo-content-pack",
34430
+ displayName: "SEO Content Pack",
34431
+ description: "Generate SEO content packages with topic clusters, articles, metadata, internal links, FAQs, and publishing cadence",
34432
+ category: "Business & Marketing",
34433
+ kind: "instruction",
34434
+ tags: ["seo", "content", "articles", "metadata"]
34435
+ },
34436
+ {
34437
+ name: "landing-page-pack",
34438
+ displayName: "Landing Page Pack",
34439
+ description: "Generate landing page packages with conversion copy, wireframes, CTA maps, experiments, preview HTML, and implementation notes",
34440
+ category: "Business & Marketing",
34441
+ kind: "instruction",
34442
+ tags: ["landing-page", "sales", "copywriting", "conversion"]
34443
+ },
34444
+ {
34445
+ name: "ad-creative-pack",
34446
+ displayName: "Ad Creative Pack",
34447
+ description: "Generate paid ad packages with platform copy, creative concepts, image prompts, audience angles, and test matrices",
34448
+ category: "Business & Marketing",
34449
+ kind: "instruction",
34450
+ tags: ["ads", "creative", "marketing", "copywriting"]
34451
+ },
34452
+ {
34453
+ name: "email-sequence",
34454
+ displayName: "Email Sequence",
34455
+ description: "Generate email campaign packages with subject lines, preview text, body copy, segmentation notes, CTA variants, HTML emails, and send plans",
34456
+ category: "Business & Marketing",
34457
+ kind: "instruction",
34458
+ tags: ["email", "marketing", "campaign", "copywriting"]
34459
+ },
34460
+ {
34461
+ name: "social-content-calendar",
34462
+ displayName: "Social Content Calendar",
34463
+ description: "Generate social content calendars with daily posts, channel strategy, asset briefs, hooks, publishing schedules, and repurposing maps",
34464
+ category: "Business & Marketing",
34465
+ kind: "instruction",
34466
+ tags: ["social", "content", "calendar", "marketing"]
34467
+ },
34468
+ {
34469
+ name: "one-page-website",
34470
+ displayName: "One Page Website",
34471
+ description: "Generate static one-page website bundles with HTML, CSS, JavaScript, copy, section maps, deploy notes, and manifest",
34472
+ category: "Business & Marketing",
34473
+ tags: ["website", "landing-page", "static-site", "html"]
34096
34474
  }
34097
- async authenticateApiKeyHash(hash) {
34098
- return this.apiKeys.get(hash) ?? null;
34475
+ ];
34476
+
34477
+ // src/lib/registry-data/productivity-organization.ts
34478
+ var PRODUCTIVITY_ORGANIZATION_SKILLS = [
34479
+ {
34480
+ name: "meeting-pack",
34481
+ displayName: "Meeting Pack",
34482
+ description: "Generate meeting artifact packages with summaries, decisions, action items, follow-up email, timeline, project export, and manifest",
34483
+ category: "Productivity & Organization",
34484
+ kind: "instruction",
34485
+ tags: ["meeting", "summary", "action-items", "decisions"]
34486
+ },
34487
+ {
34488
+ name: "file-organizer",
34489
+ displayName: "File Organizer",
34490
+ description: "Organize files into structured directories based on type, date, or content",
34491
+ category: "Productivity & Organization",
34492
+ tags: ["files", "organization", "sorting", "cleanup"]
34493
+ },
34494
+ {
34495
+ name: "folder-tree",
34496
+ displayName: "Folder Tree",
34497
+ description: "Generate and display folder tree structures for documentation",
34498
+ category: "Productivity & Organization",
34499
+ tags: ["folder", "tree", "structure", "visualization"]
34500
+ },
34501
+ {
34502
+ name: "form-filler",
34503
+ displayName: "Form Filler",
34504
+ description: "Automatically fill out web forms and document templates",
34505
+ category: "Productivity & Organization",
34506
+ tags: ["forms", "automation", "filling", "data-entry"]
34507
+ },
34508
+ {
34509
+ name: "merge-pdfs",
34510
+ displayName: "Merge PDFs",
34511
+ description: "Merge multiple PDF files into a single document",
34512
+ category: "Productivity & Organization",
34513
+ tags: ["pdf", "merge", "documents", "combining"]
34514
+ },
34515
+ {
34516
+ name: "split-pdf",
34517
+ displayName: "Split PDF",
34518
+ description: "Split PDF documents into separate pages or sections",
34519
+ category: "Productivity & Organization",
34520
+ tags: ["pdf", "split", "documents", "pages"]
34099
34521
  }
34100
- async createRun(input) {
34101
- const idemKey = input.idempotencyKey?.trim();
34102
- const idemMapKey = idemKey ? `${input.principal.orgId}:${idemKey}` : undefined;
34103
- if (idemMapKey) {
34104
- const existing = this.idempotency.get(idemMapKey);
34105
- if (existing)
34106
- return this.runs.get(existing);
34107
- }
34108
- const now = nowIso();
34109
- const run = {
34110
- id: runId(),
34111
- orgId: input.principal.orgId,
34112
- userId: input.principal.userId,
34113
- skill: input.slug,
34114
- requestedSlug: input.slug,
34115
- status: "queued",
34116
- input: input.input,
34117
- args: input.args,
34118
- ...idemKey ? { idempotencyKey: idemKey } : {},
34119
- correlationId: randomUUID3(),
34120
- costCents: 0,
34121
- leaseGeneration: 0,
34122
- createdAt: now
34123
- };
34124
- this.runs.set(run.id, run);
34125
- this.logs.set(run.id, []);
34126
- this.artifacts.set(run.id, []);
34127
- if (idemMapKey)
34128
- this.idempotency.set(idemMapKey, run.id);
34129
- return run;
34130
- }
34131
- async listRuns(principal, limit) {
34132
- return Array.from(this.runs.values()).filter((run) => run.orgId === principal.orgId).sort((a3, b3) => b3.createdAt.localeCompare(a3.createdAt)).slice(0, normalizeLimit(limit));
34133
- }
34134
- async getRun(principal, runId2) {
34135
- const run = this.runs.get(runId2);
34136
- return run && run.orgId === principal.orgId ? run : null;
34137
- }
34138
- async claimNextRun(_input) {
34139
- const run = Array.from(this.runs.values()).filter((candidate) => candidate.status === "queued" || candidate.status === "retrying").sort((a3, b3) => a3.createdAt.localeCompare(b3.createdAt))[0];
34140
- if (!run)
34141
- return null;
34142
- return this.patchRun(run.id, { status: "running", startedAt: run.startedAt ?? nowIso(), leaseGeneration: run.leaseGeneration + 1 });
34143
- }
34144
- async updateRun(runId2, patch) {
34145
- return this.patchRun(runId2, patch);
34146
- }
34147
- async transitionRun(runId2, patch, expectedGeneration) {
34148
- const run = this.runs.get(runId2);
34149
- if (!run)
34150
- return null;
34151
- if (run.leaseGeneration !== expectedGeneration) {
34152
- throw new StaleLeaseGenerationError(runId2, expectedGeneration, run.leaseGeneration, run.status);
34153
- }
34154
- return this.patchRun(runId2, patch);
34155
- }
34156
- async appendLog(runId2, orgId, level, message) {
34157
- const entries = this.logs.get(runId2) ?? [];
34158
- const log = { runId: runId2, sequence: entries.length + 1, level, message, createdAt: nowIso() };
34159
- entries.push(log);
34160
- this.logs.set(runId2, entries);
34161
- return log;
34162
- }
34163
- async listLogs(principal, runId2) {
34164
- const run = await this.getRun(principal, runId2);
34165
- return run ? [...this.logs.get(runId2) ?? []] : [];
34166
- }
34167
- async addArtifact(artifact) {
34168
- const next = { ...artifact, createdAt: nowIso() };
34169
- const artifacts = this.artifacts.get(artifact.runId) ?? [];
34170
- artifacts.push(next);
34171
- this.artifacts.set(artifact.runId, artifacts);
34172
- return next;
34173
- }
34174
- async listArtifacts(principal, runId2) {
34175
- const run = await this.getRun(principal, runId2);
34176
- return run ? [...this.artifacts.get(runId2) ?? []] : [];
34177
- }
34178
- async getArtifact(principal, runId2, id) {
34179
- const artifacts = await this.listArtifacts(principal, runId2);
34180
- return artifacts.find((artifact) => artifact.id === id) ?? null;
34181
- }
34182
- async publishSkill(input) {
34183
- const key = skillKey(input.principal.orgId, input.slug);
34184
- const now = nowIso();
34185
- const previous = this.skills.get(key);
34186
- if (previous && !previous.tombstonedAt && input.expectedRevisionId !== previous.revisionId) {
34187
- throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previous.revisionId);
34188
- }
34189
- if (input.bundle) {
34190
- const bundleMapKey = skillKey(input.principal.orgId, input.bundle.sha256);
34191
- this.bundles.set(bundleMapKey, {
34192
- ...this.bundles.get(bundleMapKey),
34193
- ...input.bundle,
34194
- orgId: input.principal.orgId,
34195
- createdAt: this.bundles.get(bundleMapKey)?.createdAt ?? now
34196
- });
34197
- }
34198
- const carriedBundle = !input.bundle && previous?.bundleSha256 ? { bundleSha256: previous.bundleSha256, ...previous.bundleByteSize === undefined ? {} : { bundleByteSize: previous.bundleByteSize } } : {};
34199
- const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : previous?.skillMd;
34200
- const record = {
34201
- orgId: input.principal.orgId,
34202
- slug: input.slug,
34203
- displayName: input.displayName,
34204
- description: input.description,
34205
- category: input.category,
34206
- tags: [...input.tags],
34207
- source: input.source,
34208
- kind: input.kind,
34209
- ...input.version ? { version: input.version } : {},
34210
- ...carriedSkillMd ? { skillMd: carriedSkillMd } : {},
34211
- ...input.bundle ? { bundleSha256: input.bundle.sha256, bundleByteSize: input.bundle.byteSize } : carriedBundle,
34212
- publishedByUserId: input.principal.userId,
34213
- createdAt: previous?.createdAt ?? now,
34214
- updatedAt: now,
34215
- revisionId: revisionIdOfRecord(recordFieldsOf(input, carriedBundle, carriedSkillMd)),
34216
- revisionNumber: (previous?.revisionNumber ?? 0) + 1
34217
- };
34218
- this.skills.set(key, record);
34219
- if (previous?.bundleSha256 && input.bundle && previous.bundleSha256 !== input.bundle.sha256) {
34220
- this.collectOrphanBundle(input.principal.orgId, previous.bundleSha256);
34221
- }
34222
- return record;
34223
- }
34224
- async listSkills(principal) {
34225
- return Array.from(this.skills.values()).filter((skill) => skill.orgId === principal.orgId && !skill.tombstonedAt).sort((a3, b3) => a3.slug.localeCompare(b3.slug));
34522
+ ];
34523
+
34524
+ // src/lib/registry-data/project-management.ts
34525
+ var PROJECT_MANAGEMENT_SKILLS = [
34526
+ {
34527
+ name: "businessactivity",
34528
+ displayName: "Business Activity",
34529
+ description: "Business activity, workflow, and ownership management service",
34530
+ category: "Project Management",
34531
+ tags: ["business", "workflow", "activities", "management"]
34532
+ },
34533
+ {
34534
+ name: "implementation",
34535
+ displayName: "Implementation",
34536
+ description: "Create .implementation scaffold for project development tracking",
34537
+ category: "Project Management",
34538
+ tags: ["implementation", "tracking", "scaffold", "project"]
34539
+ },
34540
+ {
34541
+ name: "implementation-plan",
34542
+ displayName: "Implementation Plan",
34543
+ description: "Generate detailed implementation plans with phases and milestones",
34544
+ category: "Project Management",
34545
+ tags: ["implementation", "planning", "milestones", "phases"]
34546
+ },
34547
+ {
34548
+ name: "implementation-todo",
34549
+ displayName: "Implementation Todo",
34550
+ description: "Manage implementation task lists and todo items",
34551
+ category: "Project Management",
34552
+ tags: ["implementation", "todo", "tasks", "tracking"]
34553
+ },
34554
+ {
34555
+ name: "todos-plan",
34556
+ displayName: "Todos Plan",
34557
+ description: "Author, sync, route, and verify Todos plans using Todos CLI plan IDs as source of truth",
34558
+ category: "Project Management",
34559
+ tags: ["todos", "plans", "tasks", "verification", "workflow"]
34226
34560
  }
34227
- async getSkill(principal, slug) {
34228
- const skill = this.skills.get(skillKey(principal.orgId, slug));
34229
- return skill && skill.orgId === principal.orgId ? skill : null;
34561
+ ];
34562
+
34563
+ // src/lib/registry-data/content-generation.ts
34564
+ var CONTENT_GENERATION_SKILLS = [
34565
+ {
34566
+ name: "pdf-generate",
34567
+ displayName: "PDF Generate",
34568
+ description: "Generate PDF documents with rich formatting and layouts",
34569
+ category: "Content Generation",
34570
+ tags: ["pdf", "document", "generation", "formatting"]
34571
+ },
34572
+ {
34573
+ name: "slide-deck-generator",
34574
+ displayName: "Slide Deck Generator",
34575
+ description: "Generate slide decks from briefs, docs, or outlines with PDF, PPTX, speaker notes, and structured slide metadata",
34576
+ category: "Content Generation",
34577
+ tags: ["presentation", "slides", "deck", "documents"]
34578
+ },
34579
+ {
34580
+ name: "generate-qrcode",
34581
+ displayName: "Generate QR Code",
34582
+ description: "Generate QR codes with custom styling and embedded data",
34583
+ category: "Content Generation",
34584
+ tags: ["qrcode", "generation", "encoding", "visual"]
34585
+ },
34586
+ {
34587
+ name: "generate-resume",
34588
+ displayName: "Generate Resume",
34589
+ description: "Generate professional resumes with formatting and content optimization",
34590
+ category: "Content Generation",
34591
+ tags: ["resume", "cv", "career", "generation"]
34230
34592
  }
34231
- async updateSkill(principal, slug, patch, expectedRevisionId) {
34232
- const current = await this.getSkill(principal, slug);
34233
- if (!current || current.tombstonedAt)
34234
- return null;
34235
- if (expectedRevisionId !== current.revisionId) {
34236
- throw new SkillRevisionConflictError(slug, expectedRevisionId, current.revisionId);
34237
- }
34238
- const latest = this.skills.get(skillKey(principal.orgId, slug));
34239
- if (!latest || latest.tombstonedAt)
34240
- return null;
34241
- if (latest.revisionId !== current.revisionId) {
34242
- throw new SkillRevisionConflictError(slug, expectedRevisionId, latest.revisionId);
34243
- }
34244
- const next = {
34245
- ...latest,
34246
- ...patch,
34247
- updatedAt: nowIso(),
34248
- revisionId: revisionIdOfRecord({ ...latest, ...patch }),
34249
- revisionNumber: latest.revisionNumber + 1
34250
- };
34251
- this.skills.set(skillKey(principal.orgId, slug), next);
34252
- return next;
34593
+ ];
34594
+
34595
+ // src/lib/registry-data/finance-compliance.ts
34596
+ var FINANCE_COMPLIANCE_SKILLS = [
34597
+ {
34598
+ name: "contract-review-report",
34599
+ displayName: "Contract Review Report",
34600
+ description: "Generate contract review reports with risk register, clause summary, redline suggestions, negotiation email, and manifest artifacts",
34601
+ category: "Finance & Compliance",
34602
+ kind: "instruction",
34603
+ tags: ["contract", "legal", "review", "risk"]
34604
+ },
34605
+ {
34606
+ name: "invoice",
34607
+ displayName: "Invoice",
34608
+ description: "Generate professional invoices with company management and PDF export",
34609
+ category: "Finance & Compliance",
34610
+ tags: ["invoice", "billing", "pdf", "finance"]
34611
+ },
34612
+ {
34613
+ name: "invoice-reconciliation",
34614
+ displayName: "Invoice Reconciliation",
34615
+ description: "Generate invoice reconciliation reports with matched payments, discrepancies, anomaly notes, summaries, and manifest artifacts",
34616
+ category: "Finance & Compliance",
34617
+ tags: ["invoice", "payments", "reconciliation", "finance"]
34253
34618
  }
34254
- async deleteSkill(principal, slug, tombstoneWindowMs) {
34255
- const current = await this.getSkill(principal, slug);
34256
- if (!current)
34257
- return null;
34258
- if (!current.tombstonedAt) {
34259
- const tombstoned = nowIso();
34260
- const purgeAfter = new Date(Date.now() + tombstoneWindowMs).toISOString();
34261
- const next = { ...current, tombstonedAt: tombstoned, tombstonePurgeAfter: purgeAfter, updatedAt: tombstoned };
34262
- this.skills.set(skillKey(principal.orgId, slug), next);
34263
- return next;
34264
- }
34265
- return current;
34619
+ ];
34620
+
34621
+ // src/lib/registry-data/data-analysis.ts
34622
+ var DATA_ANALYSIS_SKILLS = [
34623
+ {
34624
+ name: "analyze-data",
34625
+ displayName: "Analyze Data",
34626
+ description: "Data science insights for CSV and JSON datasets with statistical analysis",
34627
+ category: "Data & Analysis",
34628
+ tags: ["data", "analysis", "csv", "json", "statistics"]
34629
+ },
34630
+ {
34631
+ name: "dashboard-builder",
34632
+ displayName: "Dashboard Builder",
34633
+ description: "Build data dashboards with charts, metrics, and visualizations",
34634
+ category: "Data & Analysis",
34635
+ tags: ["dashboard", "visualization", "charts", "metrics"]
34636
+ },
34637
+ {
34638
+ name: "data-anonymizer",
34639
+ displayName: "Data Anonymizer",
34640
+ description: "Anonymize sensitive data in datasets for privacy compliance",
34641
+ category: "Data & Analysis",
34642
+ tags: ["anonymization", "privacy", "data", "compliance"]
34643
+ },
34644
+ {
34645
+ name: "generate-chart",
34646
+ displayName: "Generate Chart",
34647
+ description: "Generate data charts and visualizations from datasets",
34648
+ category: "Data & Analysis",
34649
+ tags: ["charts", "visualization", "data", "graphs"]
34650
+ },
34651
+ {
34652
+ name: "read-csv",
34653
+ displayName: "Read CSV",
34654
+ description: "Parse CSV files into structured JSON with delimiter and encoding detection",
34655
+ category: "Data & Analysis",
34656
+ tags: ["csv", "parsing", "tabular", "data"]
34657
+ },
34658
+ {
34659
+ name: "read-excel",
34660
+ displayName: "Read Excel",
34661
+ description: "Parse XLS and XLSX workbooks into structured JSON with sheet and formatted cell metadata",
34662
+ category: "Data & Analysis",
34663
+ tags: ["excel", "spreadsheet", "xlsx", "data"]
34664
+ },
34665
+ {
34666
+ name: "pdf-to-markdown",
34667
+ displayName: "PDF to Markdown",
34668
+ description: "Convert PDFs into clean markdown with remote extraction and structure cleanup",
34669
+ category: "Data & Analysis",
34670
+ tags: ["pdf", "markdown", "conversion"]
34671
+ },
34672
+ {
34673
+ name: "pdf-to-dataset",
34674
+ displayName: "PDF to Dataset",
34675
+ description: "Extract PDF tables, forms, invoices, and semi-structured content into CSV and JSON datasets",
34676
+ category: "Data & Analysis",
34677
+ tags: ["pdf", "dataset", "csv", "json", "extraction"]
34678
+ },
34679
+ {
34680
+ name: "doc-read",
34681
+ displayName: "Doc Read",
34682
+ description: "Read and extract text from DOCX files with section parsing and metadata extraction",
34683
+ category: "Data & Analysis",
34684
+ tags: ["docx", "reader", "extraction", "word"]
34266
34685
  }
34267
- async purgeExpiredTombstones(principal) {
34268
- const now = nowIso();
34269
- const purged = [];
34270
- for (const [key, skill] of this.skills) {
34271
- if (skill.orgId !== principal.orgId || !skill.tombstonedAt || !skill.tombstonePurgeAfter)
34272
- continue;
34273
- if (skill.tombstonePurgeAfter > now)
34274
- continue;
34275
- this.skills.delete(key);
34276
- if (skill.bundleSha256)
34277
- this.collectOrphanBundle(principal.orgId, skill.bundleSha256);
34278
- purged.push(skill);
34279
- }
34280
- return purged;
34686
+ ];
34687
+
34688
+ // src/lib/registry-data/media-processing.ts
34689
+ var MEDIA_PROCESSING_SKILLS = [
34690
+ {
34691
+ name: "video-highlight-pack",
34692
+ displayName: "Video Highlight Pack",
34693
+ description: "Generate video highlight packages with clip plans, captions, thumbnail briefs, chapter markers, social posts, and edit decisions",
34694
+ category: "Media Processing",
34695
+ kind: "instruction",
34696
+ tags: ["video", "highlights", "clips", "captions"]
34697
+ },
34698
+ {
34699
+ name: "compress-video",
34700
+ displayName: "Compress Video",
34701
+ description: "Compress video files while preserving visual quality using ffmpeg",
34702
+ category: "Media Processing",
34703
+ tags: ["video", "compression", "ffmpeg", "optimization"]
34704
+ },
34705
+ {
34706
+ name: "audio-extract",
34707
+ displayName: "Audio Extract",
34708
+ description: "Extract audio tracks from video files with multiple format support",
34709
+ category: "Media Processing",
34710
+ tags: ["audio", "extraction", "video", "conversion"]
34711
+ },
34712
+ {
34713
+ name: "extract-frames",
34714
+ displayName: "Extract Frames",
34715
+ description: "Extract frames from video files at specified intervals or timestamps",
34716
+ category: "Media Processing",
34717
+ tags: ["frames", "video", "extraction", "images"]
34718
+ },
34719
+ {
34720
+ name: "gif-maker",
34721
+ displayName: "GIF Maker",
34722
+ description: "Create animated GIFs from images, videos, or screen recordings",
34723
+ category: "Media Processing",
34724
+ tags: ["gif", "animation", "images", "video"]
34725
+ },
34726
+ {
34727
+ name: "video-downloader",
34728
+ displayName: "Video Downloader",
34729
+ description: "Download videos from various online platforms and services",
34730
+ category: "Media Processing",
34731
+ tags: ["video", "download", "platforms", "media"]
34732
+ },
34733
+ {
34734
+ name: "watermark",
34735
+ displayName: "Watermark",
34736
+ description: "Add watermarks to images and documents for copyright protection",
34737
+ category: "Media Processing",
34738
+ tags: ["watermark", "protection", "copyright", "images"]
34281
34739
  }
34282
- async getSkillBundle(principal, sha256) {
34283
- const bundle = this.bundles.get(skillKey(principal.orgId, sha256));
34284
- return bundle && bundle.orgId === principal.orgId ? bundle : null;
34740
+ ];
34741
+
34742
+ // src/lib/registry-data/design-branding.ts
34743
+ var DESIGN_BRANDING_SKILLS = [
34744
+ {
34745
+ name: "brand-kit",
34746
+ displayName: "Brand Kit",
34747
+ description: "Generate brand kits with logo usage, palette, typography, brand voice, sample applications, Markdown guide, PDF guide, and SVG assets",
34748
+ category: "Design & Branding",
34749
+ kind: "instruction",
34750
+ tags: ["brand", "design", "palette", "typography"]
34751
+ },
34752
+ {
34753
+ name: "brand-assets",
34754
+ displayName: "Brand Assets",
34755
+ description: "Fetch official brand assets from a website or brand name with logos, PNG sizes, palette, typography, source metadata, and manifests",
34756
+ category: "Design & Branding",
34757
+ tags: ["brand", "logo", "assets", "palette", "typography"]
34758
+ },
34759
+ {
34760
+ name: "logo-design",
34761
+ displayName: "Logo Design",
34762
+ description: "Generate multi-variant logo packages with transparent PNGs, vector-style SVGs, usage notes, and manifests",
34763
+ category: "Design & Branding",
34764
+ tags: ["logo", "design", "branding", "identity"]
34765
+ },
34766
+ {
34767
+ name: "generate-favicon",
34768
+ displayName: "Generate Favicon",
34769
+ description: "Generate favicons in multiple sizes and formats for websites",
34770
+ category: "Design & Branding",
34771
+ tags: ["favicon", "icon", "design", "web"]
34772
+ },
34773
+ {
34774
+ name: "product-mockup",
34775
+ displayName: "Product Mockup",
34776
+ description: "Generate product mockup packages with visual variants, prompts, usage notes, and asset metadata",
34777
+ category: "Design & Branding",
34778
+ tags: ["product", "mockup", "visualization", "marketing"]
34779
+ },
34780
+ {
34781
+ name: "siteanalyze",
34782
+ displayName: "Site Analyze",
34783
+ description: "Analyze any website's design system \u2014 detects shadcn/ui, Tailwind, extracts colors, typography, and components via Playwright + Claude Vision.",
34784
+ category: "Design & Branding",
34785
+ tags: ["design", "shadcn", "tailwind", "colors", "typography", "playwright", "analysis", "styles"]
34285
34786
  }
34286
- async pinSkill(principal, slug, metadata = {}) {
34287
- const pin = { orgId: principal.orgId, principal: principal.apiKeyId, slug, pinnedAt: nowIso(), metadata: { ...metadata } };
34288
- this.pins.set(pinKey(principal.orgId, principal.apiKeyId, slug), pin);
34289
- return pin;
34787
+ ];
34788
+
34789
+ // src/lib/registry-data/web-browser.ts
34790
+ var WEB_BROWSER_SKILLS = [
34791
+ {
34792
+ name: "domainpurchase",
34793
+ displayName: "Domain Purchase",
34794
+ description: "Purchase and manage domains via registrar connectors",
34795
+ category: "Web & Browser",
34796
+ tags: ["domain", "purchase", "registrar", "management"]
34290
34797
  }
34291
- async unpinSkill(principal, slug) {
34292
- return this.pins.delete(pinKey(principal.orgId, principal.apiKeyId, slug));
34798
+ ];
34799
+
34800
+ // src/lib/registry-data/research-writing.ts
34801
+ var RESEARCH_WRITING_SKILLS = [
34802
+ {
34803
+ name: "blog-article",
34804
+ displayName: "Blog Article",
34805
+ description: "Create SEO-optimized blog article artifact packages",
34806
+ category: "Research & Writing",
34807
+ kind: "instruction",
34808
+ tags: ["blog", "article", "writing", "seo"]
34809
+ },
34810
+ {
34811
+ name: "market-research-report",
34812
+ displayName: "Market Research Report",
34813
+ description: "Generate market research packages with competitor tables, positioning, pricing notes, source notes, and PDF/Markdown artifacts",
34814
+ category: "Research & Writing",
34815
+ kind: "instruction",
34816
+ tags: ["market-research", "competitors", "positioning", "pricing", "report"]
34293
34817
  }
34294
- async listPins(principal) {
34295
- return Array.from(this.pins.values()).filter((pin) => pin.orgId === principal.orgId && pin.principal === principal.apiKeyId).sort((a3, b3) => a3.slug.localeCompare(b3.slug));
34818
+ ];
34819
+
34820
+ // src/lib/registry-data/science-academic.ts
34821
+ var SCIENCE_ACADEMIC_SKILLS = [
34822
+ {
34823
+ name: "bio-sequence-tool",
34824
+ displayName: "Bio Sequence Tool",
34825
+ description: "Analyze and manipulate biological sequences including DNA, RNA, and protein data",
34826
+ category: "Science & Academic",
34827
+ tags: ["biology", "dna", "sequence", "bioinformatics"]
34828
+ },
34829
+ {
34830
+ name: "experiment-power-calculator",
34831
+ displayName: "Experiment Power Calculator",
34832
+ description: "Calculate statistical power and sample size for experiments",
34833
+ category: "Science & Academic",
34834
+ tags: ["experiment", "statistics", "power-analysis", "sample-size"]
34835
+ },
34836
+ {
34837
+ name: "latex-table-generator",
34838
+ displayName: "LaTeX Table Generator",
34839
+ description: "Generate formatted LaTeX tables from data for academic papers",
34840
+ category: "Science & Academic",
34841
+ tags: ["latex", "tables", "academic", "formatting"]
34842
+ },
34843
+ {
34844
+ name: "scientific-figure-check",
34845
+ displayName: "Scientific Figure Check",
34846
+ description: "Validate scientific figures for accuracy, formatting, and publication standards",
34847
+ category: "Science & Academic",
34848
+ tags: ["scientific", "figures", "validation", "publishing"]
34849
+ },
34850
+ {
34851
+ name: "statistical-test-selector",
34852
+ displayName: "Statistical Test Selector",
34853
+ description: "Recommend appropriate statistical tests based on data and research questions",
34854
+ category: "Science & Academic",
34855
+ tags: ["statistics", "test-selection", "research", "analysis"]
34296
34856
  }
34297
- async listTags(principal) {
34298
- await this.purgeExpiredTombstones(principal);
34299
- const tags = new Set;
34300
- for (const skill of this.skills.values()) {
34857
+ ];
34858
+
34859
+ // src/lib/registry-data/education-learning.ts
34860
+ var EDUCATION_LEARNING_SKILLS = [];
34861
+
34862
+ // src/lib/registry-data/communication.ts
34863
+ var COMMUNICATION_SKILLS = [];
34864
+
34865
+ // src/lib/registry-data/health-wellness.ts
34866
+ var HEALTH_WELLNESS_SKILLS = [];
34867
+
34868
+ // src/lib/registry-data/travel-lifestyle.ts
34869
+ var TRAVEL_LIFESTYLE_SKILLS = [];
34870
+
34871
+ // src/lib/registry-data/event-management.ts
34872
+ var EVENT_MANAGEMENT_SKILLS = [];
34873
+
34874
+ // src/lib/registry-data/index.ts
34875
+ var SKILLS = [
34876
+ ...DEVELOPMENT_TOOLS_SKILLS,
34877
+ ...BUSINESS_MARKETING_SKILLS,
34878
+ ...PRODUCTIVITY_ORGANIZATION_SKILLS,
34879
+ ...PROJECT_MANAGEMENT_SKILLS,
34880
+ ...CONTENT_GENERATION_SKILLS,
34881
+ ...FINANCE_COMPLIANCE_SKILLS,
34882
+ ...DATA_ANALYSIS_SKILLS,
34883
+ ...MEDIA_PROCESSING_SKILLS,
34884
+ ...DESIGN_BRANDING_SKILLS,
34885
+ ...WEB_BROWSER_SKILLS,
34886
+ ...RESEARCH_WRITING_SKILLS,
34887
+ ...SCIENCE_ACADEMIC_SKILLS,
34888
+ ...EDUCATION_LEARNING_SKILLS,
34889
+ ...COMMUNICATION_SKILLS,
34890
+ ...HEALTH_WELLNESS_SKILLS,
34891
+ ...TRAVEL_LIFESTYLE_SKILLS,
34892
+ ...EVENT_MANAGEMENT_SKILLS
34893
+ ];
34894
+
34895
+ // src/lib/hosted-skill-set.ts
34896
+ var HOSTED_RUNTIMES = new Set(["hosted"]);
34897
+ var HOSTED_SOURCES = new Set(["remote", "private-hosted"]);
34898
+ var HOSTED_METADATA_SET_EMPTY_ERROR = [
34899
+ "The hosted metadata skill set is empty, but the packaging guards that depend on it",
34900
+ "only mean anything while it is non-empty: an empty set makes every one of them pass",
34901
+ "vacuously and silently removes the protection that keeps hosted implementation source",
34902
+ "out of the published package.",
34903
+ "",
34904
+ "If emptying the set is intentional (every hosted skill was deleted or converted to a",
34905
+ "runnable in-repo skill), retire the derived guards in the SAME change \u2014 do not let them",
34906
+ "stay green and empty."
34907
+ ].join(`
34908
+ `);
34909
+ var SLUG = "[^,{}/]+";
34910
+ var BRACE_SOURCE_EXCLUSION = new RegExp(`^!skills/\\{(${SLUG}(?:,${SLUG})+)\\}/src$`);
34911
+ var SINGLE_SOURCE_EXCLUSION = new RegExp(`^!skills/(${SLUG})/src$`);
34912
+
34913
+ // src/lib/skill-validation.ts
34914
+ var RESERVED_SKILL_ENTRIES = new Set([
34915
+ ".env",
34916
+ ".npmrc",
34917
+ ".pypirc",
34918
+ ".netrc",
34919
+ "id_rsa",
34920
+ "id_ed25519"
34921
+ ]);
34922
+ var KNOWN_TOP_LEVEL_ENTRIES = new Set([
34923
+ ".claude",
34924
+ ".env.example",
34925
+ ".gitignore",
34926
+ ".skills",
34927
+ "CLAUDE.md",
34928
+ "AGENTS.md",
34929
+ "LICENSE",
34930
+ "PROJECT_OVERVIEW.md",
34931
+ "QUICKSTART.md",
34932
+ "README.md",
34933
+ "SKILL.md",
34934
+ "api-docs-list.json",
34935
+ "auth.ts",
34936
+ "bun.lock",
34937
+ "bunfig.toml",
34938
+ "data",
34939
+ "dist",
34940
+ "examples",
34941
+ "exports",
34942
+ "http-client.ts",
34943
+ "index.ts",
34944
+ "install.sh",
34945
+ "installer.ts",
34946
+ "logs",
34947
+ "node_modules",
34948
+ "package.json",
34949
+ "scripts",
34950
+ "skill-install.ts",
34951
+ "skill.json",
34952
+ "src",
34953
+ "tests",
34954
+ "references",
34955
+ "assets",
34956
+ "tsconfig.json",
34957
+ "vision.ts"
34958
+ ]);
34959
+ var VALID_PROVENANCE_SOURCES = new Set(["official", "custom", "remote", "private", "private-hosted", "upstream", "extension"]);
34960
+
34961
+ // src/lib/skill-hash.ts
34962
+ var HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
34963
+
34964
+ // src/lib/portable-skills-files.ts
34965
+ var ANY_SEGMENT_COPY_EXCLUDES = new Set([
34966
+ ".git",
34967
+ ".DS_Store",
34968
+ ".system",
34969
+ "node_modules"
34970
+ ]);
34971
+ var FIRST_SEGMENT_COPY_EXCLUDES = new Set([
34972
+ "dist",
34973
+ "build",
34974
+ ".turbo"
34975
+ ]);
34976
+ // src/lib/portable-skills.ts
34977
+ var OFFICIAL_SKILL_NAMES = new Set(SKILLS.map((skill) => skill.name));
34978
+ // src/lib/installer.ts
34979
+ var __dirname2 = dirname5(fileURLToPath2(import.meta.url));
34980
+ function findSkillsDir() {
34981
+ let dir = __dirname2;
34982
+ for (let i3 = 0;i3 < 5; i3++) {
34983
+ const candidate = join7(dir, "skills");
34984
+ if (existsSync4(candidate) && !dir.includes(".skills"))
34985
+ return candidate;
34986
+ dir = dirname5(dir);
34987
+ }
34988
+ return join7(__dirname2, "..", "skills");
34989
+ }
34990
+ var SKILLS_DIR = findSkillsDir();
34991
+
34992
+ // src/server/skills-api.ts
34993
+ var MAX_SKILL_MD_BYTES = 512000;
34994
+ var MAX_MANIFEST_BYTES = MAX_SKILL_MD_BYTES + 64000;
34995
+ var ALLOWED_PUBLISH_PARTS = new Set(["manifest", "bundle"]);
34996
+ var MAX_VERSION_MANIFEST_BYTES = 512 * 1024;
34997
+
34998
+ // src/server/config.ts
34999
+ var DATABASE_URL_ENV = "HASNA_SKILLS_DATABASE_URL";
35000
+ var SKILLS_ENV_NAMESPACE = "SKILLS";
35001
+ function resolveServerConfig(env = process.env) {
35002
+ assertNoRetiredModeEnvVars(env, {
35003
+ app: SKILLS_ENV_NAMESPACE,
35004
+ replacement: DATABASE_URL_ENV
35005
+ });
35006
+ const nodeEnv = env.NODE_ENV || "development";
35007
+ const host = env.HOST || env.SKILLS_HOST || "0.0.0.0";
35008
+ const port = parsePositiveInt(env.PORT || env.SKILLS_PORT, 8787);
35009
+ return {
35010
+ host,
35011
+ port,
35012
+ databaseUrl: env[DATABASE_URL_ENV] || env.DATABASE_URL || undefined,
35013
+ bootstrapApiKey: env.HASNA_SKILLS_BOOTSTRAP_API_KEY || undefined,
35014
+ seedBundledCorpus: (env.HASNA_SKILLS_SEED_BUNDLED_CORPUS ?? "1") !== "0",
35015
+ artifactBucket: env.HASNA_SKILLS_S3_BUCKET || env.SKILLS_S3_BUCKET || undefined,
35016
+ artifactPrefix: normalizePrefix(env.HASNA_SKILLS_S3_PREFIX || env.SKILLS_S3_PREFIX || "skills/artifacts"),
35017
+ inlineWorker: env.HASNA_SKILLS_INLINE_WORKER === "1",
35018
+ bundleSigningKey: env.HASNA_SKILLS_API_SIGNING_KEY || env.HASNA_SKILLS_SIGNING_KEY || undefined,
35019
+ requestBodyLimitBytes: parsePositiveInt(env.HASNA_SKILLS_REQUEST_BODY_LIMIT_BYTES, 1e6),
35020
+ skillBundleLimitBytes: parsePositiveInt(env.HASNA_SKILLS_BUNDLE_LIMIT_BYTES, 25000000),
35021
+ tombstoneWindowMs: parsePositiveInt(env.HASNA_SKILLS_TOMBSTONE_WINDOW_MS, 7 * 24 * 60 * 60 * 1000),
35022
+ publicBaseUrl: (env.SKILLS_PUBLIC_BASE_URL || localOrigin(host, port)).replace(/\/+$/, ""),
35023
+ nodeEnv,
35024
+ allowEphemeralStore: env.HASNA_SKILLS_ALLOW_EPHEMERAL_STORE === "1"
35025
+ };
35026
+ }
35027
+ function localOrigin(host, port) {
35028
+ const hostname = host === "0.0.0.0" || host === "::" ? "localhost" : host;
35029
+ return `http://${hostname.includes(":") ? `[${hostname}]` : hostname}:${port}`;
35030
+ }
35031
+ function parsePositiveInt(value, fallback) {
35032
+ const parsed = Number.parseInt(value ?? "", 10);
35033
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
35034
+ }
35035
+ function normalizePrefix(value) {
35036
+ return value.replace(/^\/+|\/+$/g, "") || "skills/artifacts";
35037
+ }
35038
+
35039
+ // src/server/handlers.ts
35040
+ import { createHash as createHash5 } from "crypto";
35041
+
35042
+ // src/server/store.ts
35043
+ import { randomUUID as randomUUID3 } from "crypto";
35044
+ function recordFieldsOf(input, carriedBundle, carriedSkillMd) {
35045
+ return {
35046
+ slug: input.slug,
35047
+ displayName: input.displayName,
35048
+ description: input.description,
35049
+ category: input.category,
35050
+ tags: input.tags,
35051
+ source: input.source,
35052
+ kind: input.kind,
35053
+ ...input.version ? { version: input.version } : {},
35054
+ ...carriedSkillMd ? { skillMd: carriedSkillMd } : {},
35055
+ bundleSha256: input.bundle?.sha256 ?? carriedBundle.bundleSha256,
35056
+ bundleByteSize: input.bundle?.byteSize ?? carriedBundle.bundleByteSize
35057
+ };
35058
+ }
35059
+ function resolvePoolMax(env = process.env) {
35060
+ const parsed = Number.parseInt(env.HASNA_SKILLS_DATABASE_POOL_MAX || env.SKILLS_DATABASE_POOL_MAX || "", 10);
35061
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 4;
35062
+ }
35063
+ var LOG_SEQUENCE_ATTEMPTS = 12;
35064
+ function createArtifactId() {
35065
+ return artifactId();
35066
+ }
35067
+ async function createStore(options = {}) {
35068
+ const target = resolveDatabaseTarget(options.databaseUrl);
35069
+ const store = instantiateStore(target, options.sqlite);
35070
+ await store.verifyConnectivity?.();
35071
+ if (options.bootstrapApiKey && store.ensureBootstrapApiKey) {
35072
+ await store.ensureBootstrapApiKey(options.bootstrapApiKey);
35073
+ }
35074
+ return store;
35075
+ }
35076
+ function instantiateStore(target, sqliteOptions) {
35077
+ switch (target.kind) {
35078
+ case "postgres":
35079
+ return new PostgresSkillsStore(target.url);
35080
+ case "sqlite":
35081
+ return new SqliteSkillsStore(target.path, sqliteOptions);
35082
+ case "memory":
35083
+ return new MemorySkillsStore;
35084
+ }
35085
+ }
35086
+
35087
+ class MemorySkillsStore {
35088
+ backend = { kind: "memory", durable: false, label: "memory (non-durable)" };
35089
+ apiKeys = new Map;
35090
+ runs = new Map;
35091
+ logs = new Map;
35092
+ artifacts = new Map;
35093
+ idempotency = new Map;
35094
+ skills = new Map;
35095
+ bundles = new Map;
35096
+ versions = new Map;
35097
+ pins = new Map;
35098
+ constructor(apiKeys = []) {
35099
+ for (const key of apiKeys)
35100
+ this.addApiKey(key.token, key.principal);
35101
+ }
35102
+ addApiKey(token, principal) {
35103
+ const resolved = publicPrincipal(principal);
35104
+ this.apiKeys.set(hashApiKey(token), resolved);
35105
+ return resolved;
35106
+ }
35107
+ async ensureBootstrapApiKey(token, principal) {
35108
+ this.addApiKey(token, principal);
35109
+ }
35110
+ async authenticateApiKeyHash(hash) {
35111
+ return this.apiKeys.get(hash) ?? null;
35112
+ }
35113
+ async createRun(input) {
35114
+ const idemKey = input.idempotencyKey?.trim();
35115
+ const idemMapKey = idemKey ? `${input.principal.orgId}:${idemKey}` : undefined;
35116
+ if (idemMapKey) {
35117
+ const existing = this.idempotency.get(idemMapKey);
35118
+ if (existing)
35119
+ return this.runs.get(existing);
35120
+ }
35121
+ const now = nowIso();
35122
+ const run = {
35123
+ id: runId(),
35124
+ orgId: input.principal.orgId,
35125
+ userId: input.principal.userId,
35126
+ skill: input.slug,
35127
+ requestedSlug: input.slug,
35128
+ status: "queued",
35129
+ input: input.input,
35130
+ args: input.args,
35131
+ ...idemKey ? { idempotencyKey: idemKey } : {},
35132
+ correlationId: randomUUID3(),
35133
+ costCents: 0,
35134
+ leaseGeneration: 0,
35135
+ createdAt: now
35136
+ };
35137
+ this.runs.set(run.id, run);
35138
+ this.logs.set(run.id, []);
35139
+ this.artifacts.set(run.id, []);
35140
+ if (idemMapKey)
35141
+ this.idempotency.set(idemMapKey, run.id);
35142
+ return run;
35143
+ }
35144
+ async listRuns(principal, limit) {
35145
+ return Array.from(this.runs.values()).filter((run) => run.orgId === principal.orgId).sort((a3, b3) => b3.createdAt.localeCompare(a3.createdAt)).slice(0, normalizeLimit(limit));
35146
+ }
35147
+ async getRun(principal, runId2) {
35148
+ const run = this.runs.get(runId2);
35149
+ return run && run.orgId === principal.orgId ? run : null;
35150
+ }
35151
+ async claimNextRun(_input) {
35152
+ const run = Array.from(this.runs.values()).filter((candidate) => candidate.status === "queued" || candidate.status === "retrying").sort((a3, b3) => a3.createdAt.localeCompare(b3.createdAt))[0];
35153
+ if (!run)
35154
+ return null;
35155
+ return this.patchRun(run.id, { status: "running", startedAt: run.startedAt ?? nowIso(), leaseGeneration: run.leaseGeneration + 1 });
35156
+ }
35157
+ async updateRun(runId2, patch) {
35158
+ return this.patchRun(runId2, patch);
35159
+ }
35160
+ async transitionRun(runId2, patch, expectedGeneration) {
35161
+ const run = this.runs.get(runId2);
35162
+ if (!run)
35163
+ return null;
35164
+ if (run.leaseGeneration !== expectedGeneration) {
35165
+ throw new StaleLeaseGenerationError(runId2, expectedGeneration, run.leaseGeneration, run.status);
35166
+ }
35167
+ return this.patchRun(runId2, patch);
35168
+ }
35169
+ async appendLog(runId2, orgId, level, message) {
35170
+ const entries = this.logs.get(runId2) ?? [];
35171
+ const log = { runId: runId2, sequence: entries.length + 1, level, message, createdAt: nowIso() };
35172
+ entries.push(log);
35173
+ this.logs.set(runId2, entries);
35174
+ return log;
35175
+ }
35176
+ async listLogs(principal, runId2) {
35177
+ const run = await this.getRun(principal, runId2);
35178
+ return run ? [...this.logs.get(runId2) ?? []] : [];
35179
+ }
35180
+ async addArtifact(artifact) {
35181
+ const next = { ...artifact, createdAt: nowIso() };
35182
+ const artifacts = this.artifacts.get(artifact.runId) ?? [];
35183
+ artifacts.push(next);
35184
+ this.artifacts.set(artifact.runId, artifacts);
35185
+ return next;
35186
+ }
35187
+ async listArtifacts(principal, runId2) {
35188
+ const run = await this.getRun(principal, runId2);
35189
+ return run ? [...this.artifacts.get(runId2) ?? []] : [];
35190
+ }
35191
+ async getArtifact(principal, runId2, id) {
35192
+ const artifacts = await this.listArtifacts(principal, runId2);
35193
+ return artifacts.find((artifact) => artifact.id === id) ?? null;
35194
+ }
35195
+ async publishSkill(input) {
35196
+ const key = skillKey(input.principal.orgId, input.slug);
35197
+ const now = nowIso();
35198
+ const previous = this.skills.get(key);
35199
+ if (previous && !previous.tombstonedAt && input.expectedRevisionId !== previous.revisionId) {
35200
+ throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previous.revisionId);
35201
+ }
35202
+ const versionSha = input.bundle?.sha256 ?? previous?.bundleSha256;
35203
+ if (input.version && versionSha) {
35204
+ const existing = this.versions.get(versionKey(input.principal.orgId, input.slug, input.version));
35205
+ if (existing && existing.bundleSha256 !== versionSha) {
35206
+ throw new SkillVersionExistsError(input.slug, input.version, existing.bundleSha256, versionSha);
35207
+ }
35208
+ }
35209
+ if (input.bundle) {
35210
+ const bundleMapKey = skillKey(input.principal.orgId, input.bundle.sha256);
35211
+ this.bundles.set(bundleMapKey, {
35212
+ ...this.bundles.get(bundleMapKey),
35213
+ ...input.bundle,
35214
+ orgId: input.principal.orgId,
35215
+ createdAt: this.bundles.get(bundleMapKey)?.createdAt ?? now
35216
+ });
35217
+ }
35218
+ const carriedBundle = !input.bundle && previous?.bundleSha256 ? { bundleSha256: previous.bundleSha256, ...previous.bundleByteSize === undefined ? {} : { bundleByteSize: previous.bundleByteSize } } : {};
35219
+ const carriedSkillMd = typeof input.skillMd === "string" ? input.skillMd : previous?.skillMd;
35220
+ const record = {
35221
+ orgId: input.principal.orgId,
35222
+ slug: input.slug,
35223
+ displayName: input.displayName,
35224
+ description: input.description,
35225
+ category: input.category,
35226
+ tags: [...input.tags],
35227
+ source: input.source,
35228
+ kind: input.kind,
35229
+ ...input.version ? { version: input.version } : {},
35230
+ ...carriedSkillMd ? { skillMd: carriedSkillMd } : {},
35231
+ ...input.bundle ? { bundleSha256: input.bundle.sha256, bundleByteSize: input.bundle.byteSize } : carriedBundle,
35232
+ publishedByUserId: input.principal.userId,
35233
+ createdAt: previous?.createdAt ?? now,
35234
+ updatedAt: now,
35235
+ revisionId: revisionIdOfRecord(recordFieldsOf(input, carriedBundle, carriedSkillMd)),
35236
+ revisionNumber: (previous?.revisionNumber ?? 0) + 1
35237
+ };
35238
+ this.skills.set(key, record);
35239
+ if (input.version && versionSha && !this.versions.has(versionKey(input.principal.orgId, input.slug, input.version))) {
35240
+ this.versions.set(versionKey(input.principal.orgId, input.slug, input.version), {
35241
+ orgId: input.principal.orgId,
35242
+ slug: input.slug,
35243
+ version: input.version,
35244
+ bundleSha256: versionSha,
35245
+ bundleByteSize: input.bundle?.byteSize ?? previous?.bundleByteSize ?? 0,
35246
+ storageKind: input.versionStorage?.storageKind ?? "db",
35247
+ ...input.versionStorage?.storageKey ? { storageKey: input.versionStorage.storageKey } : {},
35248
+ manifest: { ...input.versionManifest ?? {} },
35249
+ ...input.principal.userId ? { publishedByUserId: input.principal.userId } : {},
35250
+ createdAt: now
35251
+ });
35252
+ }
35253
+ if (previous?.bundleSha256 && input.bundle && previous.bundleSha256 !== input.bundle.sha256) {
35254
+ this.collectOrphanBundle(input.principal.orgId, previous.bundleSha256);
35255
+ }
35256
+ return record;
35257
+ }
35258
+ async listSkillVersions(principal, slug) {
35259
+ return Array.from(this.versions.values()).filter((v2) => v2.orgId === principal.orgId && v2.slug === slug).sort((a3, b3) => b3.createdAt.localeCompare(a3.createdAt) || b3.version.localeCompare(a3.version));
35260
+ }
35261
+ async getSkillVersion(principal, slug, version2) {
35262
+ const found = this.versions.get(versionKey(principal.orgId, slug, version2));
35263
+ return found && found.orgId === principal.orgId ? found : null;
35264
+ }
35265
+ async listSkills(principal) {
35266
+ return Array.from(this.skills.values()).filter((skill) => skill.orgId === principal.orgId && !skill.tombstonedAt).sort((a3, b3) => a3.slug.localeCompare(b3.slug));
35267
+ }
35268
+ async getSkill(principal, slug) {
35269
+ const skill = this.skills.get(skillKey(principal.orgId, slug));
35270
+ return skill && skill.orgId === principal.orgId ? skill : null;
35271
+ }
35272
+ async updateSkill(principal, slug, patch, expectedRevisionId) {
35273
+ const current = await this.getSkill(principal, slug);
35274
+ if (!current || current.tombstonedAt)
35275
+ return null;
35276
+ if (expectedRevisionId !== current.revisionId) {
35277
+ throw new SkillRevisionConflictError(slug, expectedRevisionId, current.revisionId);
35278
+ }
35279
+ const latest = this.skills.get(skillKey(principal.orgId, slug));
35280
+ if (!latest || latest.tombstonedAt)
35281
+ return null;
35282
+ if (latest.revisionId !== current.revisionId) {
35283
+ throw new SkillRevisionConflictError(slug, expectedRevisionId, latest.revisionId);
35284
+ }
35285
+ const next = {
35286
+ ...latest,
35287
+ ...patch,
35288
+ updatedAt: nowIso(),
35289
+ revisionId: revisionIdOfRecord({ ...latest, ...patch }),
35290
+ revisionNumber: latest.revisionNumber + 1
35291
+ };
35292
+ this.skills.set(skillKey(principal.orgId, slug), next);
35293
+ return next;
35294
+ }
35295
+ async deleteSkill(principal, slug, tombstoneWindowMs) {
35296
+ const current = await this.getSkill(principal, slug);
35297
+ if (!current)
35298
+ return null;
35299
+ if (!current.tombstonedAt) {
35300
+ const tombstoned = nowIso();
35301
+ const purgeAfter = new Date(Date.now() + tombstoneWindowMs).toISOString();
35302
+ const next = { ...current, tombstonedAt: tombstoned, tombstonePurgeAfter: purgeAfter, updatedAt: tombstoned };
35303
+ this.skills.set(skillKey(principal.orgId, slug), next);
35304
+ return next;
35305
+ }
35306
+ return current;
35307
+ }
35308
+ async purgeExpiredTombstones(principal) {
35309
+ const now = nowIso();
35310
+ const purged = [];
35311
+ for (const [key, skill] of this.skills) {
35312
+ if (skill.orgId !== principal.orgId || !skill.tombstonedAt || !skill.tombstonePurgeAfter)
35313
+ continue;
35314
+ if (skill.tombstonePurgeAfter > now)
35315
+ continue;
35316
+ this.skills.delete(key);
35317
+ if (skill.bundleSha256)
35318
+ this.collectOrphanBundle(principal.orgId, skill.bundleSha256);
35319
+ purged.push(skill);
35320
+ }
35321
+ return purged;
35322
+ }
35323
+ async getSkillBundle(principal, sha256) {
35324
+ const bundle = this.bundles.get(skillKey(principal.orgId, sha256));
35325
+ return bundle && bundle.orgId === principal.orgId ? bundle : null;
35326
+ }
35327
+ async pinSkill(principal, slug, metadata = {}) {
35328
+ const pin = { orgId: principal.orgId, principal: principal.apiKeyId, slug, pinnedAt: nowIso(), metadata: { ...metadata } };
35329
+ this.pins.set(pinKey(principal.orgId, principal.apiKeyId, slug), pin);
35330
+ return pin;
35331
+ }
35332
+ async unpinSkill(principal, slug) {
35333
+ return this.pins.delete(pinKey(principal.orgId, principal.apiKeyId, slug));
35334
+ }
35335
+ async listPins(principal) {
35336
+ return Array.from(this.pins.values()).filter((pin) => pin.orgId === principal.orgId && pin.principal === principal.apiKeyId).sort((a3, b3) => a3.slug.localeCompare(b3.slug));
35337
+ }
35338
+ async listTags(principal) {
35339
+ await this.purgeExpiredTombstones(principal);
35340
+ const tags = new Set;
35341
+ for (const skill of this.skills.values()) {
34301
35342
  if (skill.orgId !== principal.orgId)
34302
35343
  continue;
34303
35344
  for (const tag of skill.tags) {
@@ -34324,7 +35365,7 @@ class MemorySkillsStore {
34324
35365
  return Array.from(this.skills.values()).filter((skill) => skill.orgId === principal.orgId && !skill.tombstonedAt).map((skill) => skill.slug).sort();
34325
35366
  }
34326
35367
  collectOrphanBundle(orgId, sha256) {
34327
- const referenced = Array.from(this.skills.values()).some((skill) => skill.orgId === orgId && skill.bundleSha256 === sha256);
35368
+ const referenced = Array.from(this.skills.values()).some((skill) => skill.orgId === orgId && skill.bundleSha256 === sha256) || Array.from(this.versions.values()).some((v2) => v2.orgId === orgId && v2.bundleSha256 === sha256);
34328
35369
  if (!referenced)
34329
35370
  this.bundles.delete(skillKey(orgId, sha256));
34330
35371
  }
@@ -34343,6 +35384,9 @@ function skillKey(orgId, slug) {
34343
35384
  function pinKey(orgId, principal, slug) {
34344
35385
  return `${orgId.length}:${orgId}:${principal.length}:${principal}:${slug}`;
34345
35386
  }
35387
+ function versionKey(orgId, slug, version2) {
35388
+ return `${orgId.length}:${orgId}:${slug.length}:${slug}:${version2}`;
35389
+ }
34346
35390
 
34347
35391
  class PostgresSkillsStore {
34348
35392
  backend = { kind: "postgres", durable: true, label: "postgres" };
@@ -34617,6 +35661,15 @@ class PostgresSkillsStore {
34617
35661
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, previousRevisionId);
34618
35662
  }
34619
35663
  const carriedSha = input.bundle?.sha256 ?? previousSha;
35664
+ if (input.version && carriedSha) {
35665
+ const existingVersion = await tx`
35666
+ SELECT bundle_sha256 FROM skills_versions WHERE org_id = ${orgId} AND slug = ${input.slug} AND version = ${input.version} LIMIT 1
35667
+ `;
35668
+ const existingSha = existingVersion[0] && typeof existingVersion[0].bundle_sha256 === "string" ? String(existingVersion[0].bundle_sha256) : null;
35669
+ if (existingSha && existingSha !== carriedSha) {
35670
+ throw new SkillVersionExistsError(input.slug, input.version, existingSha, carriedSha);
35671
+ }
35672
+ }
34620
35673
  const carriedSize = input.bundle?.byteSize ?? (previous?.bundle_byte_size == null ? null : Number(previous.bundle_byte_size));
34621
35674
  const revisionId = revisionIdOfRecord({
34622
35675
  slug: input.slug,
@@ -34680,11 +35733,20 @@ class PostgresSkillsStore {
34680
35733
  const currentId = current[0] && typeof current[0].revision_id === "string" ? String(current[0].revision_id) : null;
34681
35734
  throw new SkillRevisionConflictError(input.slug, input.expectedRevisionId, currentId);
34682
35735
  }
35736
+ if (input.version && carriedSha) {
35737
+ await tx`
35738
+ INSERT INTO skills_versions (org_id, slug, version, bundle_sha256, bundle_byte_size, storage_kind, storage_key, manifest_json, published_by_user_id)
35739
+ VALUES (${orgId}, ${input.slug}, ${input.version}, ${carriedSha}, ${carriedSize ?? 0}, ${input.versionStorage?.storageKind ?? "db"},
35740
+ ${input.versionStorage?.storageKey ?? null}, ${JSON.stringify(input.versionManifest ?? {})}::jsonb, ${input.principal.userId})
35741
+ ON CONFLICT (org_id, slug, version) DO NOTHING
35742
+ `;
35743
+ }
34683
35744
  if (previousSha && input.bundle && previousSha !== input.bundle.sha256) {
34684
35745
  await tx`
34685
35746
  DELETE FROM skills_bundles
34686
35747
  WHERE org_id = ${orgId} AND sha256 = ${previousSha}
34687
35748
  AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${orgId} AND bundle_sha256 = ${previousSha})
35749
+ AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${orgId} AND bundle_sha256 = ${previousSha})
34688
35750
  `;
34689
35751
  }
34690
35752
  await tx`DELETE FROM skills_tags WHERE org_id = ${orgId} AND slug = ${input.slug}`;
@@ -34793,6 +35855,7 @@ class PostgresSkillsStore {
34793
35855
  DELETE FROM skills_bundles
34794
35856
  WHERE org_id = ${principal.orgId} AND sha256 = ${record.bundleSha256}
34795
35857
  AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${record.bundleSha256})
35858
+ AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${principal.orgId} AND bundle_sha256 = ${record.bundleSha256})
34796
35859
  `;
34797
35860
  }
34798
35861
  purged.push(record);
@@ -34804,1055 +35867,247 @@ class PostgresSkillsStore {
34804
35867
  const rows = await this.sql`SELECT * FROM skills_bundles WHERE org_id = ${principal.orgId} AND sha256 = ${sha256} LIMIT 1`;
34805
35868
  return rows[0] ? rowToSkillBundle(rows[0]) : null;
34806
35869
  }
34807
- async pinSkill(principal, slug, metadata = {}) {
34808
- const rows = await this.sql`
34809
- INSERT INTO skills_pins (org_id, principal, slug, pinned_at, metadata_json)
34810
- VALUES (${principal.orgId}, ${principal.apiKeyId}, ${slug}, now(), ${JSON.stringify(metadata)}::jsonb)
34811
- ON CONFLICT (org_id, principal, slug) DO UPDATE SET
34812
- pinned_at = now(),
34813
- metadata_json = EXCLUDED.metadata_json
34814
- RETURNING *
34815
- `;
34816
- return rowToPin(rows[0]);
34817
- }
34818
- async unpinSkill(principal, slug) {
34819
- const rows = await this.sql`
34820
- DELETE FROM skills_pins WHERE org_id = ${principal.orgId} AND principal = ${principal.apiKeyId} AND slug = ${slug}
34821
- RETURNING 1 AS present
34822
- `;
34823
- return rows.length > 0;
34824
- }
34825
- async listPins(principal) {
34826
- const rows = await this.sql`
34827
- SELECT * FROM skills_pins WHERE org_id = ${principal.orgId} AND principal = ${principal.apiKeyId} ORDER BY slug ASC
34828
- `;
34829
- return rows.map(rowToPin);
34830
- }
34831
- async listTags(principal) {
34832
- await this.purgeExpiredTombstones(principal);
35870
+ async listSkillVersions(principal, slug) {
34833
35871
  const rows = await this.sql`
34834
- SELECT DISTINCT tag FROM skills_tags WHERE org_id = ${principal.orgId} ORDER BY tag ASC
35872
+ SELECT * FROM skills_versions WHERE org_id = ${principal.orgId} AND slug = ${slug}
35873
+ ORDER BY created_at DESC, version DESC
34835
35874
  `;
34836
- return rows.map((row) => String(row.tag));
35875
+ return rows.map((row) => rowToSkillVersion(row));
34837
35876
  }
34838
- async listSkillsByTag(principal, tag) {
34839
- await this.purgeExpiredTombstones(principal);
35877
+ async getSkillVersion(principal, slug, version2) {
34840
35878
  const rows = await this.sql`
34841
- SELECT s.* FROM skills_registry s
34842
- JOIN skills_tags t ON t.org_id = s.org_id AND t.slug = s.slug
34843
- WHERE t.org_id = ${principal.orgId} AND t.tag = ${tag} AND s.tombstoned_at IS NULL
34844
- ORDER BY s.slug ASC
35879
+ SELECT * FROM skills_versions WHERE org_id = ${principal.orgId} AND slug = ${slug} AND version = ${version2} LIMIT 1
34845
35880
  `;
34846
- return rows.map(rowToSkill);
35881
+ return rows[0] ? rowToSkillVersion(rows[0]) : null;
34847
35882
  }
34848
- async listPinsByTag(principal, tag) {
34849
- await this.purgeExpiredTombstones(principal);
35883
+ async pinSkill(principal, slug, metadata = {}) {
34850
35884
  const rows = await this.sql`
34851
- SELECT p.* FROM skills_pins p
34852
- JOIN skills_tags t ON t.org_id = p.org_id AND t.slug = p.slug
34853
- JOIN skills_registry s ON s.org_id = p.org_id AND s.slug = p.slug
34854
- WHERE p.org_id = ${principal.orgId} AND p.principal = ${principal.apiKeyId}
34855
- AND t.tag = ${tag} AND s.tombstoned_at IS NULL
34856
- ORDER BY p.slug ASC
34857
- `;
34858
- return rows.map(rowToPin);
34859
- }
34860
- async listPublishedSlugs(principal) {
34861
- const rows = await this.sql`
34862
- SELECT slug FROM skills_registry WHERE org_id = ${principal.orgId} AND tombstoned_at IS NULL ORDER BY slug ASC
34863
- `;
34864
- return rows.map((row) => String(row.slug));
34865
- }
34866
- async collectOrphanBundle(orgId, sha256) {
34867
- await this.sql`
34868
- DELETE FROM skills_bundles
34869
- WHERE org_id = ${orgId} AND sha256 = ${sha256}
34870
- AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${orgId} AND bundle_sha256 = ${sha256})
34871
- `;
34872
- }
34873
- }
34874
- var NO_REVISION_SENTINEL2 = "0000000000000000000000000000000000000000000000000000000000000000";
34875
- function isUniqueViolation(error) {
34876
- const code = error?.code;
34877
- if (code === "23505" || code === 23505)
34878
- return true;
34879
- const message = error instanceof Error ? error.message : String(error);
34880
- return /duplicate key value violates unique constraint/i.test(message);
34881
- }
34882
- function connectionFailureSummary(error) {
34883
- const message = error instanceof Error ? error.message : String(error);
34884
- return message.replace(/[a-z][a-z0-9+.-]*:\/\/\S*/gi, "<redacted-url>").split(`
34885
- `)[0].slice(0, 200);
34886
- }
34887
-
34888
- // src/server/redaction.ts
34889
- var SECRET_PATTERNS = [
34890
- /\bsk-[A-Za-z0-9_-]{8,}\b/g,
34891
- /\bsk_[A-Za-z0-9_-]{8,}\b/g,
34892
- /\bgh[opsur]_[A-Za-z0-9_]{8,}\b/g,
34893
- /\bgithub_pat_[A-Za-z0-9_]{8,}\b/g,
34894
- /\bnpm_[A-Za-z0-9_]{8,}\b/g,
34895
- /\bAKIA[A-Z0-9]{12,}\b/g,
34896
- /\bAIza[A-Za-z0-9_-]{10,}\b/g,
34897
- /\b[A-Z0-9_]*(?:API_KEY|SECRET|TOKEN|PASSWORD|DATABASE_URL)[A-Z0-9_]*\s*[:=]\s*[^ \n\r\t]+/gi,
34898
- /\bhttps?:\/\/[^ \n\r\t]+X-Amz-Signature=[^ \n\r\t]+/gi
34899
- ];
34900
- function redactForClient(value) {
34901
- const text = typeof value === "string" ? value : JSON.stringify(value);
34902
- return SECRET_PATTERNS.reduce((current, pattern) => current.replace(pattern, "credential"), text).replace(/\s+$/g, "").slice(0, 20000);
34903
- }
34904
-
34905
- // src/server/handlers.ts
34906
- var DETERMINISTIC_TEXT_HANDLERS = new Set([
34907
- "audio-transcript-pack",
34908
- "transcript",
34909
- "video-highlight-pack"
34910
- ]);
34911
- async function executeRun(store, run, storage = new ArtifactStorage) {
34912
- try {
34913
- await store.appendLog(run.id, run.orgId, "info", redactForClient(`starting run ${run.skill}`));
34914
- if (!DETERMINISTIC_TEXT_HANDLERS.has(run.skill)) {
34915
- await store.appendLog(run.id, run.orgId, "warn", `${run.skill} has no provider-free handler yet`);
34916
- return await failRun(store, run, "HANDLER_UNAVAILABLE", "This deployment has no safe provider-free handler for that skill yet.");
34917
- }
34918
- const text = extractText(run);
34919
- if (!text.trim()) {
34920
- return await failRun(store, run, "INVALID_INPUT", "Provide transcript text with input.transcript, input.text, --text, --source, or positional text.");
34921
- }
34922
- const title = extractOption(run.args, "--title") || stringInput(run.input, "title") || "Skills run";
34923
- const summary = summarize(text);
34924
- const artifacts = [
34925
- textArtifact(run, "transcript.md", `# ${title}
34926
-
34927
- ${text.trim()}
34928
- `),
34929
- textArtifact(run, "summary.md", `# Summary
34930
-
34931
- ${summary}
34932
- `),
34933
- textArtifact(run, "show-notes.md", `# Show Notes
34934
-
34935
- - ${summary}
34936
- - Generated by the skills deterministic worker.
34937
- `),
34938
- textArtifact(run, "clips.csv", `start,end,title,summary
34939
- 00:00,00:30,"Opening","${csv(summary)}"
34940
- `),
34941
- textArtifact(run, "manifest.json", JSON.stringify({
34942
- runId: run.id,
34943
- skill: run.skill,
34944
- requestedSlug: run.requestedSlug,
34945
- generatedAt: new Date().toISOString(),
34946
- artifacts: ["transcript.md", "summary.md", "show-notes.md", "clips.csv"]
34947
- }, null, 2) + `
34948
- `, "application/json")
34949
- ];
34950
- for (const artifact of artifacts) {
34951
- await store.addArtifact(await storage.materialize(run, artifact.meta, artifact.body));
34952
- }
34953
- await store.appendLog(run.id, run.orgId, "info", `generated ${artifacts.length} artifacts`);
34954
- return await completeRun(store, run, summary);
34955
- } catch (error) {
34956
- return await failRun(store, run, "WORKER_ERROR", redactForClient(error.message));
34957
- }
34958
- }
34959
- function textArtifact(run, relativePath, bodyText, contentType = relativePath.endsWith(".json") ? "application/json" : "text/markdown; charset=utf-8") {
34960
- const bytes = new TextEncoder().encode(bodyText);
34961
- return {
34962
- meta: {
34963
- id: createArtifactId(),
34964
- runId: run.id,
34965
- orgId: run.orgId,
34966
- fileName: relativePath.split("/").pop() || relativePath,
34967
- relativePath,
34968
- contentType,
34969
- byteSize: bytes.byteLength,
34970
- sha256: createHash5("sha256").update(bytes).digest("hex"),
34971
- visibility: "private"
34972
- },
34973
- body: { relativePath, bodyText, contentType }
34974
- };
34975
- }
34976
- async function completeRun(store, run, preview) {
34977
- const next = await fencedTransition(store, run, {
34978
- status: "succeeded",
34979
- outputType: "artifact_bundle",
34980
- outputPreview: preview,
34981
- completedAt: new Date().toISOString()
34982
- });
34983
- return next ?? run;
34984
- }
34985
- async function failRun(store, run, code, message) {
34986
- try {
34987
- await store.appendLog(run.id, run.orgId, "error", message);
34988
- } catch {}
34989
- const next = await fencedTransition(store, run, {
34990
- status: "failed",
34991
- errorCode: code,
34992
- errorMessage: message,
34993
- completedAt: new Date().toISOString()
34994
- });
34995
- return next ?? run;
34996
- }
34997
- async function fencedTransition(store, run, patch) {
34998
- if (!store.transitionRun)
34999
- return store.updateRun(run.id, patch);
35000
- const next = await store.transitionRun(run.id, patch, run.leaseGeneration);
35001
- if (!next) {
35002
- try {
35003
- await store.appendLog(run.id, run.orgId, "warn", `late write rejected: run no longer owned at lease_generation ${run.leaseGeneration}`);
35004
- } catch {}
35005
- }
35006
- return next;
35007
- }
35008
- function extractText(run) {
35009
- return stringInput(run.input, "transcript") || stringInput(run.input, "text") || extractOption(run.args, "--text") || extractOption(run.args, "--source") || run.args.filter((arg) => !arg.startsWith("--")).join(" ");
35010
- }
35011
- function stringInput(input, key) {
35012
- const value = input[key];
35013
- return typeof value === "string" && value.trim() ? value : undefined;
35014
- }
35015
- function extractOption(args, flag) {
35016
- for (let i3 = 0;i3 < args.length; i3++) {
35017
- const arg = args[i3];
35018
- if (arg === flag && args[i3 + 1])
35019
- return args[i3 + 1];
35020
- if (arg.startsWith(`${flag}=`))
35021
- return arg.slice(flag.length + 1);
35022
- }
35023
- return;
35024
- }
35025
- function summarize(text) {
35026
- const normalized = redactForClient(text).replace(/\s+/g, " ").trim();
35027
- if (normalized.length <= 220)
35028
- return normalized;
35029
- return `${normalized.slice(0, 217)}...`;
35030
- }
35031
- function csv(value) {
35032
- return value.replace(/"/g, '""');
35033
- }
35034
-
35035
- // src/lib/registry-data/development-tools.ts
35036
- var DEVELOPMENT_TOOLS_SKILLS = [
35037
- {
35038
- name: "repo-onboarding-report",
35039
- displayName: "Repo Onboarding Report",
35040
- description: "Generate repository onboarding packages with architecture maps, setup guides, risk registers, and first-week plans",
35041
- category: "Development Tools",
35042
- kind: "instruction",
35043
- tags: ["repository", "onboarding", "architecture", "developer-tools"]
35044
- },
35045
- {
35046
- name: "security-audit-report",
35047
- displayName: "Security Audit Report",
35048
- description: "Generate application security hardening reports covering auth, secrets, headers, webhooks, RLS, permissions, dependencies, and prioritized fixes",
35049
- category: "Development Tools",
35050
- kind: "instruction",
35051
- tags: ["security", "audit", "hardening", "rls", "webhooks"]
35052
- },
35053
- {
35054
- name: "performance-audit-report",
35055
- displayName: "Performance Audit Report",
35056
- description: "Generate performance audit reports with metrics, findings, budgets, remediation plans, and manifest artifacts",
35057
- category: "Development Tools",
35058
- kind: "instruction",
35059
- tags: ["performance", "audit", "latency", "budget", "web"]
35060
- },
35061
- {
35062
- name: "migration-plan-pack",
35063
- displayName: "Migration Plan Pack",
35064
- description: "Generate migration plans for frameworks, libraries, databases, infrastructure, and architecture upgrades with risk matrix, checklist, rollout, and test strategy artifacts",
35065
- category: "Development Tools",
35066
- kind: "instruction",
35067
- tags: ["migration", "upgrade", "planning", "frameworks", "databases"]
35068
- },
35069
- {
35070
- name: "test-suite-generator",
35071
- displayName: "Test Suite Generator",
35072
- description: "Generate runnable API, unit, and browser test suite packages with coverage notes",
35073
- category: "Development Tools",
35074
- kind: "instruction",
35075
- tags: ["testing", "qa", "api-tests", "browser-tests", "coverage"]
35076
- },
35077
- {
35078
- name: "api-test-suite",
35079
- displayName: "API Test Suite",
35080
- description: "Generate and run API test suites with comprehensive endpoint coverage",
35081
- category: "Development Tools",
35082
- tags: ["api", "testing", "automation", "qa"]
35083
- },
35084
- {
35085
- name: "api-docs-portal",
35086
- displayName: "API Docs Portal",
35087
- description: "Generate static API documentation portals from OpenAPI specs, route lists, and endpoint examples",
35088
- category: "Development Tools",
35089
- tags: ["api", "documentation", "openapi", "portal"]
35090
- },
35091
- {
35092
- name: "codefix",
35093
- displayName: "Code Fix",
35094
- description: "Code quality CLI for auto-linting, formatting, fixing, and style enforcement",
35095
- category: "Development Tools",
35096
- tags: ["code", "linting", "formatting", "quality"]
35097
- },
35098
- {
35099
- name: "commitpush",
35100
- displayName: "Commit Push",
35101
- description: "Create logical commits from repo changes and push directly to the main branch",
35102
- category: "Development Tools",
35103
- tags: ["git", "commit", "push", "automation"]
35104
- },
35105
- {
35106
- name: "commitpushpr",
35107
- displayName: "Commit Push PR",
35108
- description: "Create logical commits, push a feature branch, and open a GitHub pull request",
35109
- category: "Development Tools",
35110
- dependencies: ["commitpush"],
35111
- tags: ["git", "commit", "pull-request", "github", "automation"]
35112
- },
35113
- {
35114
- name: "database-explorer",
35115
- displayName: "Database Explorer",
35116
- description: "Explore and query databases with an interactive interface",
35117
- category: "Development Tools",
35118
- tags: ["database", "explorer", "sql", "query"]
35119
- },
35120
- {
35121
- name: "diff-viewer",
35122
- displayName: "Diff Viewer",
35123
- description: "View and analyze file differences with visual diff representation",
35124
- category: "Development Tools",
35125
- tags: ["diff", "comparison", "files", "code-review"]
35126
- },
35127
- {
35128
- name: "generate-api-client",
35129
- displayName: "Generate API Client",
35130
- description: "Generate API client libraries from OpenAPI specs and documentation",
35131
- category: "Development Tools",
35132
- tags: ["api", "client", "code-generation", "openapi"]
35133
- },
35134
- {
35135
- name: "generate-dockerfile",
35136
- displayName: "Generate Dockerfile",
35137
- description: "Generate optimized Dockerfiles for containerized applications",
35138
- category: "Development Tools",
35139
- tags: ["docker", "dockerfile", "containers", "devops"]
35140
- },
35141
- {
35142
- name: "generate-env",
35143
- displayName: "Generate Env",
35144
- description: "Generate environment variable files from templates and configurations",
35145
- category: "Development Tools",
35146
- tags: ["env", "environment", "configuration", "dotenv"]
35147
- },
35148
- {
35149
- name: "generate-sitemap",
35150
- displayName: "Generate Sitemap",
35151
- description: "Generate XML sitemaps for websites and web applications",
35152
- category: "Development Tools",
35153
- tags: ["sitemap", "seo", "xml", "web"]
35154
- },
35155
- {
35156
- name: "hook",
35157
- displayName: "Hook",
35158
- description: "Claude Code hook creation skill - generates standardized hook scaffolds",
35159
- category: "Development Tools",
35160
- tags: ["hooks", "scaffold", "claude-code", "automation"]
35161
- },
35162
- {
35163
- name: "http-server",
35164
- displayName: "HTTP Server",
35165
- description: "Spin up local HTTP servers for development and testing",
35166
- category: "Development Tools",
35167
- tags: ["http", "server", "development", "local"]
35168
- },
35169
- {
35170
- name: "lorem-generator",
35171
- displayName: "Lorem Generator",
35172
- description: "Generate placeholder text in various styles and lengths",
35173
- category: "Development Tools",
35174
- tags: ["lorem", "placeholder", "text", "mockup"]
35175
- },
35176
- {
35177
- name: "managemcp",
35178
- displayName: "Manage MCP",
35179
- description: "Manage MCP servers with install, configure, and lifecycle operations",
35180
- category: "Development Tools",
35181
- tags: ["mcp", "management", "servers", "configuration"]
35182
- },
35183
- {
35184
- name: "markdown-validator",
35185
- displayName: "Markdown Validator",
35186
- description: "Validate markdown files for syntax, links, and formatting issues",
35187
- category: "Development Tools",
35188
- tags: ["markdown", "validation", "linting", "formatting"]
35189
- },
35190
- {
35191
- name: "monitor",
35192
- displayName: "Monitor",
35193
- description: "Operate the monitor MCP for machine health, processes, cron jobs, and cleanup workflows",
35194
- category: "Development Tools",
35195
- tags: ["monitoring", "mcp", "processes", "operations"]
35196
- },
35197
- {
35198
- name: "regex-tester",
35199
- displayName: "Regex Tester",
35200
- description: "Test and validate regular expressions with sample inputs",
35201
- category: "Development Tools",
35202
- tags: ["regex", "testing", "validation", "patterns"]
35203
- },
35204
- {
35205
- name: "scancommitpr",
35206
- displayName: "Scan Commit PR",
35207
- description: "Scan repo changes, group into logical commits, push, and optionally create a PR",
35208
- category: "Development Tools",
35209
- dependencies: ["scancommitpush"],
35210
- tags: ["git", "commit", "push", "pull-request", "automation"]
35211
- },
35212
- {
35213
- name: "scancommitpush",
35214
- displayName: "Scan Commit Push",
35215
- description: "Scan repo changes, group into logical commits with conventional messages, and push to GitHub",
35216
- category: "Development Tools",
35217
- tags: ["git", "commit", "push", "automation"]
35218
- },
35219
- {
35220
- name: "security-audit",
35221
- displayName: "Security Audit",
35222
- description: "Perform security audits on codebases and infrastructure configurations",
35223
- category: "Development Tools",
35224
- tags: ["security", "audit", "vulnerabilities", "scanning"]
35225
- },
35226
- {
35227
- name: "tmux-session",
35228
- displayName: "Tmux Session",
35229
- description: "Create and manage grouped tmux sessions with workspace-aware naming and window layout guidance",
35230
- category: "Development Tools",
35231
- tags: ["tmux", "terminal", "sessions", "workspace"]
35232
- },
35233
- {
35234
- name: "validate-config",
35235
- displayName: "Validate Config",
35236
- description: "Validate configuration files for syntax and schema compliance",
35237
- category: "Development Tools",
35238
- tags: ["config", "validation", "schema", "linting"]
35239
- },
35240
- {
35241
- name: "oss-app-two-backend-storage",
35242
- displayName: "OSS App Two-Backend Storage",
35243
- description: "Recipe for the Hasna two-backend storage contract: client transport + HTTP store, server PG/SQLite backend, pg-migrations + apply script, fail-closed URL-without-key, bun bins, contract manifest, Dockerfile",
35244
- category: "Development Tools",
35245
- tags: ["storage", "backend", "postgresql", "sqlite", "two-backend", "oss-app"],
35246
- kind: "instruction"
35247
- },
35248
- {
35249
- name: "session-inject-monitor",
35250
- displayName: "Session Inject Monitor",
35251
- description: "Set up a declarative monitor that injects a prompt into a live coding-agent session when a watched source (conversations, email, todos, knowledge, command output) has new content",
35252
- category: "Development Tools",
35253
- tags: ["monitor", "session", "injection", "automation", "wake"],
35254
- kind: "instruction"
35255
- }
35256
- ];
35257
-
35258
- // src/lib/registry-data/business-marketing.ts
35259
- var BUSINESS_MARKETING_SKILLS = [
35260
- {
35261
- name: "customer-feedback-report",
35262
- displayName: "Customer Feedback Report",
35263
- description: "Generate customer feedback reports with clusters, sentiment, root causes, roadmap recommendations, evidence, and PDF/Markdown artifacts",
35264
- category: "Business & Marketing",
35265
- kind: "instruction",
35266
- tags: ["feedback", "customer", "sentiment", "roadmap", "report"]
35267
- },
35268
- {
35269
- name: "pitch-deck",
35270
- displayName: "Pitch Deck",
35271
- description: "Generate investor and sales deck packages with slides, speaker notes, design direction, PDF, and PPTX artifacts",
35272
- category: "Business & Marketing",
35273
- kind: "instruction",
35274
- dependencies: ["market-research-report"],
35275
- tags: ["deck", "presentation", "investor", "sales", "pptx"]
35276
- },
35277
- {
35278
- name: "proposal-pack",
35279
- displayName: "Proposal Pack",
35280
- description: "Generate client proposal packages with proposal, statement of work, pricing, timeline, assumptions, cover email, and PDF/Markdown artifacts",
35281
- category: "Business & Marketing",
35282
- kind: "instruction",
35283
- tags: ["proposal", "sow", "sales", "pricing", "timeline"]
35284
- },
35285
- {
35286
- name: "seo-content-pack",
35287
- displayName: "SEO Content Pack",
35288
- description: "Generate SEO content packages with topic clusters, articles, metadata, internal links, FAQs, and publishing cadence",
35289
- category: "Business & Marketing",
35290
- kind: "instruction",
35291
- tags: ["seo", "content", "articles", "metadata"]
35292
- },
35293
- {
35294
- name: "landing-page-pack",
35295
- displayName: "Landing Page Pack",
35296
- description: "Generate landing page packages with conversion copy, wireframes, CTA maps, experiments, preview HTML, and implementation notes",
35297
- category: "Business & Marketing",
35298
- kind: "instruction",
35299
- tags: ["landing-page", "sales", "copywriting", "conversion"]
35300
- },
35301
- {
35302
- name: "ad-creative-pack",
35303
- displayName: "Ad Creative Pack",
35304
- description: "Generate paid ad packages with platform copy, creative concepts, image prompts, audience angles, and test matrices",
35305
- category: "Business & Marketing",
35306
- kind: "instruction",
35307
- tags: ["ads", "creative", "marketing", "copywriting"]
35308
- },
35309
- {
35310
- name: "email-sequence",
35311
- displayName: "Email Sequence",
35312
- description: "Generate email campaign packages with subject lines, preview text, body copy, segmentation notes, CTA variants, HTML emails, and send plans",
35313
- category: "Business & Marketing",
35314
- kind: "instruction",
35315
- tags: ["email", "marketing", "campaign", "copywriting"]
35316
- },
35317
- {
35318
- name: "social-content-calendar",
35319
- displayName: "Social Content Calendar",
35320
- description: "Generate social content calendars with daily posts, channel strategy, asset briefs, hooks, publishing schedules, and repurposing maps",
35321
- category: "Business & Marketing",
35322
- kind: "instruction",
35323
- tags: ["social", "content", "calendar", "marketing"]
35324
- },
35325
- {
35326
- name: "one-page-website",
35327
- displayName: "One Page Website",
35328
- description: "Generate static one-page website bundles with HTML, CSS, JavaScript, copy, section maps, deploy notes, and manifest",
35329
- category: "Business & Marketing",
35330
- tags: ["website", "landing-page", "static-site", "html"]
35331
- }
35332
- ];
35333
-
35334
- // src/lib/registry-data/productivity-organization.ts
35335
- var PRODUCTIVITY_ORGANIZATION_SKILLS = [
35336
- {
35337
- name: "meeting-pack",
35338
- displayName: "Meeting Pack",
35339
- description: "Generate meeting artifact packages with summaries, decisions, action items, follow-up email, timeline, project export, and manifest",
35340
- category: "Productivity & Organization",
35341
- kind: "instruction",
35342
- tags: ["meeting", "summary", "action-items", "decisions"]
35343
- },
35344
- {
35345
- name: "file-organizer",
35346
- displayName: "File Organizer",
35347
- description: "Organize files into structured directories based on type, date, or content",
35348
- category: "Productivity & Organization",
35349
- tags: ["files", "organization", "sorting", "cleanup"]
35350
- },
35351
- {
35352
- name: "folder-tree",
35353
- displayName: "Folder Tree",
35354
- description: "Generate and display folder tree structures for documentation",
35355
- category: "Productivity & Organization",
35356
- tags: ["folder", "tree", "structure", "visualization"]
35357
- },
35358
- {
35359
- name: "form-filler",
35360
- displayName: "Form Filler",
35361
- description: "Automatically fill out web forms and document templates",
35362
- category: "Productivity & Organization",
35363
- tags: ["forms", "automation", "filling", "data-entry"]
35364
- },
35365
- {
35366
- name: "merge-pdfs",
35367
- displayName: "Merge PDFs",
35368
- description: "Merge multiple PDF files into a single document",
35369
- category: "Productivity & Organization",
35370
- tags: ["pdf", "merge", "documents", "combining"]
35371
- },
35372
- {
35373
- name: "split-pdf",
35374
- displayName: "Split PDF",
35375
- description: "Split PDF documents into separate pages or sections",
35376
- category: "Productivity & Organization",
35377
- tags: ["pdf", "split", "documents", "pages"]
35378
- }
35379
- ];
35380
-
35381
- // src/lib/registry-data/project-management.ts
35382
- var PROJECT_MANAGEMENT_SKILLS = [
35383
- {
35384
- name: "businessactivity",
35385
- displayName: "Business Activity",
35386
- description: "Business activity, workflow, and ownership management service",
35387
- category: "Project Management",
35388
- tags: ["business", "workflow", "activities", "management"]
35389
- },
35390
- {
35391
- name: "implementation",
35392
- displayName: "Implementation",
35393
- description: "Create .implementation scaffold for project development tracking",
35394
- category: "Project Management",
35395
- tags: ["implementation", "tracking", "scaffold", "project"]
35396
- },
35397
- {
35398
- name: "implementation-plan",
35399
- displayName: "Implementation Plan",
35400
- description: "Generate detailed implementation plans with phases and milestones",
35401
- category: "Project Management",
35402
- tags: ["implementation", "planning", "milestones", "phases"]
35403
- },
35404
- {
35405
- name: "implementation-todo",
35406
- displayName: "Implementation Todo",
35407
- description: "Manage implementation task lists and todo items",
35408
- category: "Project Management",
35409
- tags: ["implementation", "todo", "tasks", "tracking"]
35410
- },
35411
- {
35412
- name: "todos-plan",
35413
- displayName: "Todos Plan",
35414
- description: "Author, sync, route, and verify Todos plans using Todos CLI plan IDs as source of truth",
35415
- category: "Project Management",
35416
- tags: ["todos", "plans", "tasks", "verification", "workflow"]
35417
- }
35418
- ];
35419
-
35420
- // src/lib/registry-data/content-generation.ts
35421
- var CONTENT_GENERATION_SKILLS = [
35422
- {
35423
- name: "pdf-generate",
35424
- displayName: "PDF Generate",
35425
- description: "Generate PDF documents with rich formatting and layouts",
35426
- category: "Content Generation",
35427
- tags: ["pdf", "document", "generation", "formatting"]
35428
- },
35429
- {
35430
- name: "slide-deck-generator",
35431
- displayName: "Slide Deck Generator",
35432
- description: "Generate slide decks from briefs, docs, or outlines with PDF, PPTX, speaker notes, and structured slide metadata",
35433
- category: "Content Generation",
35434
- tags: ["presentation", "slides", "deck", "documents"]
35435
- },
35436
- {
35437
- name: "generate-qrcode",
35438
- displayName: "Generate QR Code",
35439
- description: "Generate QR codes with custom styling and embedded data",
35440
- category: "Content Generation",
35441
- tags: ["qrcode", "generation", "encoding", "visual"]
35442
- },
35443
- {
35444
- name: "generate-resume",
35445
- displayName: "Generate Resume",
35446
- description: "Generate professional resumes with formatting and content optimization",
35447
- category: "Content Generation",
35448
- tags: ["resume", "cv", "career", "generation"]
35449
- }
35450
- ];
35451
-
35452
- // src/lib/registry-data/finance-compliance.ts
35453
- var FINANCE_COMPLIANCE_SKILLS = [
35454
- {
35455
- name: "contract-review-report",
35456
- displayName: "Contract Review Report",
35457
- description: "Generate contract review reports with risk register, clause summary, redline suggestions, negotiation email, and manifest artifacts",
35458
- category: "Finance & Compliance",
35459
- kind: "instruction",
35460
- tags: ["contract", "legal", "review", "risk"]
35461
- },
35462
- {
35463
- name: "invoice",
35464
- displayName: "Invoice",
35465
- description: "Generate professional invoices with company management and PDF export",
35466
- category: "Finance & Compliance",
35467
- tags: ["invoice", "billing", "pdf", "finance"]
35468
- },
35469
- {
35470
- name: "invoice-reconciliation",
35471
- displayName: "Invoice Reconciliation",
35472
- description: "Generate invoice reconciliation reports with matched payments, discrepancies, anomaly notes, summaries, and manifest artifacts",
35473
- category: "Finance & Compliance",
35474
- tags: ["invoice", "payments", "reconciliation", "finance"]
35475
- }
35476
- ];
35477
-
35478
- // src/lib/registry-data/data-analysis.ts
35479
- var DATA_ANALYSIS_SKILLS = [
35480
- {
35481
- name: "analyze-data",
35482
- displayName: "Analyze Data",
35483
- description: "Data science insights for CSV and JSON datasets with statistical analysis",
35484
- category: "Data & Analysis",
35485
- tags: ["data", "analysis", "csv", "json", "statistics"]
35486
- },
35487
- {
35488
- name: "dashboard-builder",
35489
- displayName: "Dashboard Builder",
35490
- description: "Build data dashboards with charts, metrics, and visualizations",
35491
- category: "Data & Analysis",
35492
- tags: ["dashboard", "visualization", "charts", "metrics"]
35493
- },
35494
- {
35495
- name: "data-anonymizer",
35496
- displayName: "Data Anonymizer",
35497
- description: "Anonymize sensitive data in datasets for privacy compliance",
35498
- category: "Data & Analysis",
35499
- tags: ["anonymization", "privacy", "data", "compliance"]
35500
- },
35501
- {
35502
- name: "generate-chart",
35503
- displayName: "Generate Chart",
35504
- description: "Generate data charts and visualizations from datasets",
35505
- category: "Data & Analysis",
35506
- tags: ["charts", "visualization", "data", "graphs"]
35507
- },
35508
- {
35509
- name: "read-csv",
35510
- displayName: "Read CSV",
35511
- description: "Parse CSV files into structured JSON with delimiter and encoding detection",
35512
- category: "Data & Analysis",
35513
- tags: ["csv", "parsing", "tabular", "data"]
35514
- },
35515
- {
35516
- name: "read-excel",
35517
- displayName: "Read Excel",
35518
- description: "Parse XLS and XLSX workbooks into structured JSON with sheet and formatted cell metadata",
35519
- category: "Data & Analysis",
35520
- tags: ["excel", "spreadsheet", "xlsx", "data"]
35521
- },
35522
- {
35523
- name: "pdf-to-markdown",
35524
- displayName: "PDF to Markdown",
35525
- description: "Convert PDFs into clean markdown with remote extraction and structure cleanup",
35526
- category: "Data & Analysis",
35527
- tags: ["pdf", "markdown", "conversion"]
35528
- },
35529
- {
35530
- name: "pdf-to-dataset",
35531
- displayName: "PDF to Dataset",
35532
- description: "Extract PDF tables, forms, invoices, and semi-structured content into CSV and JSON datasets",
35533
- category: "Data & Analysis",
35534
- tags: ["pdf", "dataset", "csv", "json", "extraction"]
35535
- },
35536
- {
35537
- name: "doc-read",
35538
- displayName: "Doc Read",
35539
- description: "Read and extract text from DOCX files with section parsing and metadata extraction",
35540
- category: "Data & Analysis",
35541
- tags: ["docx", "reader", "extraction", "word"]
35885
+ INSERT INTO skills_pins (org_id, principal, slug, pinned_at, metadata_json)
35886
+ VALUES (${principal.orgId}, ${principal.apiKeyId}, ${slug}, now(), ${JSON.stringify(metadata)}::jsonb)
35887
+ ON CONFLICT (org_id, principal, slug) DO UPDATE SET
35888
+ pinned_at = now(),
35889
+ metadata_json = EXCLUDED.metadata_json
35890
+ RETURNING *
35891
+ `;
35892
+ return rowToPin(rows[0]);
35542
35893
  }
35543
- ];
35544
-
35545
- // src/lib/registry-data/media-processing.ts
35546
- var MEDIA_PROCESSING_SKILLS = [
35547
- {
35548
- name: "video-highlight-pack",
35549
- displayName: "Video Highlight Pack",
35550
- description: "Generate video highlight packages with clip plans, captions, thumbnail briefs, chapter markers, social posts, and edit decisions",
35551
- category: "Media Processing",
35552
- kind: "instruction",
35553
- tags: ["video", "highlights", "clips", "captions"]
35554
- },
35555
- {
35556
- name: "compress-video",
35557
- displayName: "Compress Video",
35558
- description: "Compress video files while preserving visual quality using ffmpeg",
35559
- category: "Media Processing",
35560
- tags: ["video", "compression", "ffmpeg", "optimization"]
35561
- },
35562
- {
35563
- name: "audio-extract",
35564
- displayName: "Audio Extract",
35565
- description: "Extract audio tracks from video files with multiple format support",
35566
- category: "Media Processing",
35567
- tags: ["audio", "extraction", "video", "conversion"]
35568
- },
35569
- {
35570
- name: "extract-frames",
35571
- displayName: "Extract Frames",
35572
- description: "Extract frames from video files at specified intervals or timestamps",
35573
- category: "Media Processing",
35574
- tags: ["frames", "video", "extraction", "images"]
35575
- },
35576
- {
35577
- name: "gif-maker",
35578
- displayName: "GIF Maker",
35579
- description: "Create animated GIFs from images, videos, or screen recordings",
35580
- category: "Media Processing",
35581
- tags: ["gif", "animation", "images", "video"]
35582
- },
35583
- {
35584
- name: "video-downloader",
35585
- displayName: "Video Downloader",
35586
- description: "Download videos from various online platforms and services",
35587
- category: "Media Processing",
35588
- tags: ["video", "download", "platforms", "media"]
35589
- },
35590
- {
35591
- name: "watermark",
35592
- displayName: "Watermark",
35593
- description: "Add watermarks to images and documents for copyright protection",
35594
- category: "Media Processing",
35595
- tags: ["watermark", "protection", "copyright", "images"]
35894
+ async unpinSkill(principal, slug) {
35895
+ const rows = await this.sql`
35896
+ DELETE FROM skills_pins WHERE org_id = ${principal.orgId} AND principal = ${principal.apiKeyId} AND slug = ${slug}
35897
+ RETURNING 1 AS present
35898
+ `;
35899
+ return rows.length > 0;
35596
35900
  }
35597
- ];
35598
-
35599
- // src/lib/registry-data/design-branding.ts
35600
- var DESIGN_BRANDING_SKILLS = [
35601
- {
35602
- name: "brand-kit",
35603
- displayName: "Brand Kit",
35604
- description: "Generate brand kits with logo usage, palette, typography, brand voice, sample applications, Markdown guide, PDF guide, and SVG assets",
35605
- category: "Design & Branding",
35606
- kind: "instruction",
35607
- tags: ["brand", "design", "palette", "typography"]
35608
- },
35609
- {
35610
- name: "brand-assets",
35611
- displayName: "Brand Assets",
35612
- description: "Fetch official brand assets from a website or brand name with logos, PNG sizes, palette, typography, source metadata, and manifests",
35613
- category: "Design & Branding",
35614
- tags: ["brand", "logo", "assets", "palette", "typography"]
35615
- },
35616
- {
35617
- name: "logo-design",
35618
- displayName: "Logo Design",
35619
- description: "Generate multi-variant logo packages with transparent PNGs, vector-style SVGs, usage notes, and manifests",
35620
- category: "Design & Branding",
35621
- tags: ["logo", "design", "branding", "identity"]
35622
- },
35623
- {
35624
- name: "generate-favicon",
35625
- displayName: "Generate Favicon",
35626
- description: "Generate favicons in multiple sizes and formats for websites",
35627
- category: "Design & Branding",
35628
- tags: ["favicon", "icon", "design", "web"]
35629
- },
35630
- {
35631
- name: "product-mockup",
35632
- displayName: "Product Mockup",
35633
- description: "Generate product mockup packages with visual variants, prompts, usage notes, and asset metadata",
35634
- category: "Design & Branding",
35635
- tags: ["product", "mockup", "visualization", "marketing"]
35636
- },
35637
- {
35638
- name: "siteanalyze",
35639
- displayName: "Site Analyze",
35640
- description: "Analyze any website's design system \u2014 detects shadcn/ui, Tailwind, extracts colors, typography, and components via Playwright + Claude Vision.",
35641
- category: "Design & Branding",
35642
- tags: ["design", "shadcn", "tailwind", "colors", "typography", "playwright", "analysis", "styles"]
35901
+ async listPins(principal) {
35902
+ const rows = await this.sql`
35903
+ SELECT * FROM skills_pins WHERE org_id = ${principal.orgId} AND principal = ${principal.apiKeyId} ORDER BY slug ASC
35904
+ `;
35905
+ return rows.map(rowToPin);
35643
35906
  }
35644
- ];
35645
-
35646
- // src/lib/registry-data/web-browser.ts
35647
- var WEB_BROWSER_SKILLS = [
35648
- {
35649
- name: "domainpurchase",
35650
- displayName: "Domain Purchase",
35651
- description: "Purchase and manage domains via registrar connectors",
35652
- category: "Web & Browser",
35653
- tags: ["domain", "purchase", "registrar", "management"]
35907
+ async listTags(principal) {
35908
+ await this.purgeExpiredTombstones(principal);
35909
+ const rows = await this.sql`
35910
+ SELECT DISTINCT tag FROM skills_tags WHERE org_id = ${principal.orgId} ORDER BY tag ASC
35911
+ `;
35912
+ return rows.map((row) => String(row.tag));
35654
35913
  }
35655
- ];
35656
-
35657
- // src/lib/registry-data/research-writing.ts
35658
- var RESEARCH_WRITING_SKILLS = [
35659
- {
35660
- name: "blog-article",
35661
- displayName: "Blog Article",
35662
- description: "Create SEO-optimized blog article artifact packages",
35663
- category: "Research & Writing",
35664
- kind: "instruction",
35665
- tags: ["blog", "article", "writing", "seo"]
35666
- },
35667
- {
35668
- name: "market-research-report",
35669
- displayName: "Market Research Report",
35670
- description: "Generate market research packages with competitor tables, positioning, pricing notes, source notes, and PDF/Markdown artifacts",
35671
- category: "Research & Writing",
35672
- kind: "instruction",
35673
- tags: ["market-research", "competitors", "positioning", "pricing", "report"]
35914
+ async listSkillsByTag(principal, tag) {
35915
+ await this.purgeExpiredTombstones(principal);
35916
+ const rows = await this.sql`
35917
+ SELECT s.* FROM skills_registry s
35918
+ JOIN skills_tags t ON t.org_id = s.org_id AND t.slug = s.slug
35919
+ WHERE t.org_id = ${principal.orgId} AND t.tag = ${tag} AND s.tombstoned_at IS NULL
35920
+ ORDER BY s.slug ASC
35921
+ `;
35922
+ return rows.map(rowToSkill);
35674
35923
  }
35675
- ];
35676
-
35677
- // src/lib/registry-data/science-academic.ts
35678
- var SCIENCE_ACADEMIC_SKILLS = [
35679
- {
35680
- name: "bio-sequence-tool",
35681
- displayName: "Bio Sequence Tool",
35682
- description: "Analyze and manipulate biological sequences including DNA, RNA, and protein data",
35683
- category: "Science & Academic",
35684
- tags: ["biology", "dna", "sequence", "bioinformatics"]
35685
- },
35686
- {
35687
- name: "experiment-power-calculator",
35688
- displayName: "Experiment Power Calculator",
35689
- description: "Calculate statistical power and sample size for experiments",
35690
- category: "Science & Academic",
35691
- tags: ["experiment", "statistics", "power-analysis", "sample-size"]
35692
- },
35693
- {
35694
- name: "latex-table-generator",
35695
- displayName: "LaTeX Table Generator",
35696
- description: "Generate formatted LaTeX tables from data for academic papers",
35697
- category: "Science & Academic",
35698
- tags: ["latex", "tables", "academic", "formatting"]
35699
- },
35700
- {
35701
- name: "scientific-figure-check",
35702
- displayName: "Scientific Figure Check",
35703
- description: "Validate scientific figures for accuracy, formatting, and publication standards",
35704
- category: "Science & Academic",
35705
- tags: ["scientific", "figures", "validation", "publishing"]
35706
- },
35707
- {
35708
- name: "statistical-test-selector",
35709
- displayName: "Statistical Test Selector",
35710
- description: "Recommend appropriate statistical tests based on data and research questions",
35711
- category: "Science & Academic",
35712
- tags: ["statistics", "test-selection", "research", "analysis"]
35924
+ async listPinsByTag(principal, tag) {
35925
+ await this.purgeExpiredTombstones(principal);
35926
+ const rows = await this.sql`
35927
+ SELECT p.* FROM skills_pins p
35928
+ JOIN skills_tags t ON t.org_id = p.org_id AND t.slug = p.slug
35929
+ JOIN skills_registry s ON s.org_id = p.org_id AND s.slug = p.slug
35930
+ WHERE p.org_id = ${principal.orgId} AND p.principal = ${principal.apiKeyId}
35931
+ AND t.tag = ${tag} AND s.tombstoned_at IS NULL
35932
+ ORDER BY p.slug ASC
35933
+ `;
35934
+ return rows.map(rowToPin);
35713
35935
  }
35714
- ];
35715
-
35716
- // src/lib/registry-data/education-learning.ts
35717
- var EDUCATION_LEARNING_SKILLS = [];
35718
-
35719
- // src/lib/registry-data/communication.ts
35720
- var COMMUNICATION_SKILLS = [];
35721
-
35722
- // src/lib/registry-data/health-wellness.ts
35723
- var HEALTH_WELLNESS_SKILLS = [];
35724
-
35725
- // src/lib/registry-data/travel-lifestyle.ts
35726
- var TRAVEL_LIFESTYLE_SKILLS = [];
35727
-
35728
- // src/lib/registry-data/event-management.ts
35729
- var EVENT_MANAGEMENT_SKILLS = [];
35936
+ async listPublishedSlugs(principal) {
35937
+ const rows = await this.sql`
35938
+ SELECT slug FROM skills_registry WHERE org_id = ${principal.orgId} AND tombstoned_at IS NULL ORDER BY slug ASC
35939
+ `;
35940
+ return rows.map((row) => String(row.slug));
35941
+ }
35942
+ async collectOrphanBundle(orgId, sha256) {
35943
+ await this.sql`
35944
+ DELETE FROM skills_bundles
35945
+ WHERE org_id = ${orgId} AND sha256 = ${sha256}
35946
+ AND NOT EXISTS (SELECT 1 FROM skills_registry WHERE org_id = ${orgId} AND bundle_sha256 = ${sha256})
35947
+ AND NOT EXISTS (SELECT 1 FROM skills_versions WHERE org_id = ${orgId} AND bundle_sha256 = ${sha256})
35948
+ `;
35949
+ }
35950
+ }
35951
+ var NO_REVISION_SENTINEL2 = "0000000000000000000000000000000000000000000000000000000000000000";
35952
+ function isUniqueViolation(error) {
35953
+ const code = error?.code;
35954
+ if (code === "23505" || code === 23505)
35955
+ return true;
35956
+ const message = error instanceof Error ? error.message : String(error);
35957
+ return /duplicate key value violates unique constraint/i.test(message);
35958
+ }
35959
+ function connectionFailureSummary(error) {
35960
+ const message = error instanceof Error ? error.message : String(error);
35961
+ return message.replace(/[a-z][a-z0-9+.-]*:\/\/\S*/gi, "<redacted-url>").split(`
35962
+ `)[0].slice(0, 200);
35963
+ }
35730
35964
 
35731
- // src/lib/registry-data/index.ts
35732
- var SKILLS = [
35733
- ...DEVELOPMENT_TOOLS_SKILLS,
35734
- ...BUSINESS_MARKETING_SKILLS,
35735
- ...PRODUCTIVITY_ORGANIZATION_SKILLS,
35736
- ...PROJECT_MANAGEMENT_SKILLS,
35737
- ...CONTENT_GENERATION_SKILLS,
35738
- ...FINANCE_COMPLIANCE_SKILLS,
35739
- ...DATA_ANALYSIS_SKILLS,
35740
- ...MEDIA_PROCESSING_SKILLS,
35741
- ...DESIGN_BRANDING_SKILLS,
35742
- ...WEB_BROWSER_SKILLS,
35743
- ...RESEARCH_WRITING_SKILLS,
35744
- ...SCIENCE_ACADEMIC_SKILLS,
35745
- ...EDUCATION_LEARNING_SKILLS,
35746
- ...COMMUNICATION_SKILLS,
35747
- ...HEALTH_WELLNESS_SKILLS,
35748
- ...TRAVEL_LIFESTYLE_SKILLS,
35749
- ...EVENT_MANAGEMENT_SKILLS
35965
+ // src/server/redaction.ts
35966
+ var SECRET_PATTERNS = [
35967
+ /\bsk-[A-Za-z0-9_-]{8,}\b/g,
35968
+ /\bsk_[A-Za-z0-9_-]{8,}\b/g,
35969
+ /\bgh[opsur]_[A-Za-z0-9_]{8,}\b/g,
35970
+ /\bgithub_pat_[A-Za-z0-9_]{8,}\b/g,
35971
+ /\bnpm_[A-Za-z0-9_]{8,}\b/g,
35972
+ /\bAKIA[A-Z0-9]{12,}\b/g,
35973
+ /\bAIza[A-Za-z0-9_-]{10,}\b/g,
35974
+ /\b[A-Z0-9_]*(?:API_KEY|SECRET|TOKEN|PASSWORD|DATABASE_URL)[A-Z0-9_]*\s*[:=]\s*[^ \n\r\t]+/gi,
35975
+ /\bhttps?:\/\/[^ \n\r\t]+X-Amz-Signature=[^ \n\r\t]+/gi
35750
35976
  ];
35977
+ function redactForClient(value) {
35978
+ const text = typeof value === "string" ? value : JSON.stringify(value);
35979
+ return SECRET_PATTERNS.reduce((current, pattern) => current.replace(pattern, "credential"), text).replace(/\s+$/g, "").slice(0, 20000);
35980
+ }
35751
35981
 
35752
- // src/lib/hosted-skill-set.ts
35753
- var HOSTED_RUNTIMES = new Set(["hosted"]);
35754
- var HOSTED_SOURCES = new Set(["remote", "private-hosted"]);
35755
- var HOSTED_METADATA_SET_EMPTY_ERROR = [
35756
- "The hosted metadata skill set is empty, but the packaging guards that depend on it",
35757
- "only mean anything while it is non-empty: an empty set makes every one of them pass",
35758
- "vacuously and silently removes the protection that keeps hosted implementation source",
35759
- "out of the published package.",
35760
- "",
35761
- "If emptying the set is intentional (every hosted skill was deleted or converted to a",
35762
- "runnable in-repo skill), retire the derived guards in the SAME change \u2014 do not let them",
35763
- "stay green and empty."
35764
- ].join(`
35765
- `);
35766
- var SLUG = "[^,{}/]+";
35767
- var BRACE_SOURCE_EXCLUSION = new RegExp(`^!skills/\\{(${SLUG}(?:,${SLUG})+)\\}/src$`);
35768
- var SINGLE_SOURCE_EXCLUSION = new RegExp(`^!skills/(${SLUG})/src$`);
35769
-
35770
- // src/lib/skill-validation.ts
35771
- var RESERVED_SKILL_ENTRIES = new Set([
35772
- ".env",
35773
- ".npmrc",
35774
- ".pypirc",
35775
- ".netrc",
35776
- "id_rsa",
35777
- "id_ed25519"
35778
- ]);
35779
- var KNOWN_TOP_LEVEL_ENTRIES = new Set([
35780
- ".claude",
35781
- ".env.example",
35782
- ".gitignore",
35783
- ".skills",
35784
- "CLAUDE.md",
35785
- "AGENTS.md",
35786
- "LICENSE",
35787
- "PROJECT_OVERVIEW.md",
35788
- "QUICKSTART.md",
35789
- "README.md",
35790
- "SKILL.md",
35791
- "api-docs-list.json",
35792
- "auth.ts",
35793
- "bun.lock",
35794
- "bunfig.toml",
35795
- "data",
35796
- "dist",
35797
- "examples",
35798
- "exports",
35799
- "http-client.ts",
35800
- "index.ts",
35801
- "install.sh",
35802
- "installer.ts",
35803
- "logs",
35804
- "node_modules",
35805
- "package.json",
35806
- "scripts",
35807
- "skill-install.ts",
35808
- "skill.json",
35809
- "src",
35810
- "tests",
35811
- "references",
35812
- "assets",
35813
- "tsconfig.json",
35814
- "vision.ts"
35982
+ // src/server/handlers.ts
35983
+ var DETERMINISTIC_TEXT_HANDLERS = new Set([
35984
+ "audio-transcript-pack",
35985
+ "transcript",
35986
+ "video-highlight-pack"
35815
35987
  ]);
35816
- var VALID_PROVENANCE_SOURCES = new Set(["official", "custom", "remote", "private", "private-hosted", "upstream", "extension"]);
35988
+ async function executeRun(store, run, storage = new ArtifactStorage) {
35989
+ try {
35990
+ await store.appendLog(run.id, run.orgId, "info", redactForClient(`starting run ${run.skill}`));
35991
+ if (!DETERMINISTIC_TEXT_HANDLERS.has(run.skill)) {
35992
+ await store.appendLog(run.id, run.orgId, "warn", `${run.skill} has no provider-free handler yet`);
35993
+ return await failRun(store, run, "HANDLER_UNAVAILABLE", "This deployment has no safe provider-free handler for that skill yet.");
35994
+ }
35995
+ const text = extractText(run);
35996
+ if (!text.trim()) {
35997
+ return await failRun(store, run, "INVALID_INPUT", "Provide transcript text with input.transcript, input.text, --text, --source, or positional text.");
35998
+ }
35999
+ const title = extractOption(run.args, "--title") || stringInput(run.input, "title") || "Skills run";
36000
+ const summary = summarize(text);
36001
+ const artifacts = [
36002
+ textArtifact(run, "transcript.md", `# ${title}
35817
36003
 
35818
- // src/lib/skill-hash.ts
35819
- var HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
36004
+ ${text.trim()}
36005
+ `),
36006
+ textArtifact(run, "summary.md", `# Summary
35820
36007
 
35821
- // src/lib/portable-skills-files.ts
35822
- var ANY_SEGMENT_COPY_EXCLUDES = new Set([
35823
- ".git",
35824
- ".DS_Store",
35825
- ".system",
35826
- "node_modules"
35827
- ]);
35828
- var FIRST_SEGMENT_COPY_EXCLUDES = new Set([
35829
- "dist",
35830
- "build",
35831
- ".turbo"
35832
- ]);
35833
- // src/lib/portable-skills.ts
35834
- var OFFICIAL_SKILL_NAMES = new Set(SKILLS.map((skill) => skill.name));
35835
- // src/lib/installer.ts
35836
- import { existsSync as existsSync4, readFileSync as readFileSync4, rmSync } from "fs";
35837
- import { dirname as dirname5, join as join8 } from "path";
35838
- import { fileURLToPath as fileURLToPath2 } from "url";
35839
- var __dirname2 = dirname5(fileURLToPath2(import.meta.url));
35840
- function findSkillsDir() {
35841
- let dir = __dirname2;
35842
- for (let i3 = 0;i3 < 5; i3++) {
35843
- const candidate = join8(dir, "skills");
35844
- if (existsSync4(candidate) && !dir.includes(".skills"))
35845
- return candidate;
35846
- dir = dirname5(dir);
36008
+ ${summary}
36009
+ `),
36010
+ textArtifact(run, "show-notes.md", `# Show Notes
36011
+
36012
+ - ${summary}
36013
+ - Generated by the skills deterministic worker.
36014
+ `),
36015
+ textArtifact(run, "clips.csv", `start,end,title,summary
36016
+ 00:00,00:30,"Opening","${csv(summary)}"
36017
+ `),
36018
+ textArtifact(run, "manifest.json", JSON.stringify({
36019
+ runId: run.id,
36020
+ skill: run.skill,
36021
+ requestedSlug: run.requestedSlug,
36022
+ generatedAt: new Date().toISOString(),
36023
+ artifacts: ["transcript.md", "summary.md", "show-notes.md", "clips.csv"]
36024
+ }, null, 2) + `
36025
+ `, "application/json")
36026
+ ];
36027
+ for (const artifact of artifacts) {
36028
+ await store.addArtifact(await storage.materialize(run, artifact.meta, artifact.body));
36029
+ }
36030
+ await store.appendLog(run.id, run.orgId, "info", `generated ${artifacts.length} artifacts`);
36031
+ return await completeRun(store, run, summary);
36032
+ } catch (error) {
36033
+ return await failRun(store, run, "WORKER_ERROR", redactForClient(error.message));
35847
36034
  }
35848
- return join8(__dirname2, "..", "skills");
35849
36035
  }
35850
- var SKILLS_DIR = findSkillsDir();
35851
-
35852
- // src/server/skills-api.ts
35853
- var MAX_SKILL_MD_BYTES = 512000;
35854
- var MAX_MANIFEST_BYTES = MAX_SKILL_MD_BYTES + 64000;
35855
- var ALLOWED_PUBLISH_PARTS = new Set(["manifest", "bundle"]);
36036
+ function textArtifact(run, relativePath, bodyText, contentType = relativePath.endsWith(".json") ? "application/json" : "text/markdown; charset=utf-8") {
36037
+ const bytes = new TextEncoder().encode(bodyText);
36038
+ return {
36039
+ meta: {
36040
+ id: createArtifactId(),
36041
+ runId: run.id,
36042
+ orgId: run.orgId,
36043
+ fileName: relativePath.split("/").pop() || relativePath,
36044
+ relativePath,
36045
+ contentType,
36046
+ byteSize: bytes.byteLength,
36047
+ sha256: createHash5("sha256").update(bytes).digest("hex"),
36048
+ visibility: "private"
36049
+ },
36050
+ body: { relativePath, bodyText, contentType }
36051
+ };
36052
+ }
36053
+ async function completeRun(store, run, preview) {
36054
+ const next = await fencedTransition(store, run, {
36055
+ status: "succeeded",
36056
+ outputType: "artifact_bundle",
36057
+ outputPreview: preview,
36058
+ completedAt: new Date().toISOString()
36059
+ });
36060
+ return next ?? run;
36061
+ }
36062
+ async function failRun(store, run, code, message) {
36063
+ try {
36064
+ await store.appendLog(run.id, run.orgId, "error", message);
36065
+ } catch {}
36066
+ const next = await fencedTransition(store, run, {
36067
+ status: "failed",
36068
+ errorCode: code,
36069
+ errorMessage: message,
36070
+ completedAt: new Date().toISOString()
36071
+ });
36072
+ return next ?? run;
36073
+ }
36074
+ async function fencedTransition(store, run, patch) {
36075
+ if (!store.transitionRun)
36076
+ return store.updateRun(run.id, patch);
36077
+ const next = await store.transitionRun(run.id, patch, run.leaseGeneration);
36078
+ if (!next) {
36079
+ try {
36080
+ await store.appendLog(run.id, run.orgId, "warn", `late write rejected: run no longer owned at lease_generation ${run.leaseGeneration}`);
36081
+ } catch {}
36082
+ }
36083
+ return next;
36084
+ }
36085
+ function extractText(run) {
36086
+ return stringInput(run.input, "transcript") || stringInput(run.input, "text") || extractOption(run.args, "--text") || extractOption(run.args, "--source") || run.args.filter((arg) => !arg.startsWith("--")).join(" ");
36087
+ }
36088
+ function stringInput(input, key) {
36089
+ const value = input[key];
36090
+ return typeof value === "string" && value.trim() ? value : undefined;
36091
+ }
36092
+ function extractOption(args, flag) {
36093
+ for (let i3 = 0;i3 < args.length; i3++) {
36094
+ const arg = args[i3];
36095
+ if (arg === flag && args[i3 + 1])
36096
+ return args[i3 + 1];
36097
+ if (arg.startsWith(`${flag}=`))
36098
+ return arg.slice(flag.length + 1);
36099
+ }
36100
+ return;
36101
+ }
36102
+ function summarize(text) {
36103
+ const normalized = redactForClient(text).replace(/\s+/g, " ").trim();
36104
+ if (normalized.length <= 220)
36105
+ return normalized;
36106
+ return `${normalized.slice(0, 217)}...`;
36107
+ }
36108
+ function csv(value) {
36109
+ return value.replace(/"/g, '""');
36110
+ }
35856
36111
 
35857
36112
  // src/server/app.ts
35858
36113
  function assertDurableStore(store, config) {
@@ -35880,6 +36135,26 @@ async function runWorkerOnce(store, workerId = `worker_${randomUUID4().slice(0,
35880
36135
  return true;
35881
36136
  }
35882
36137
  if (import.meta.main) {
36138
+ const EARLY_ARGV = process.argv.slice(2);
36139
+ if (EARLY_ARGV.includes("--version") || EARLY_ARGV.includes("-V")) {
36140
+ console.log(package_default.version);
36141
+ process.exit(0);
36142
+ }
36143
+ if (EARLY_ARGV.includes("--help") || EARLY_ARGV.includes("-h")) {
36144
+ console.log(`Usage: skills-worker [options]
36145
+
36146
+ Drains @hasna/skills runs from the store.
36147
+
36148
+ Options:
36149
+ -V, --version output the version number
36150
+ -h, --help display help for command
36151
+ --once process exactly one run, then exit
36152
+
36153
+ Environment:
36154
+ HASNA_SKILLS_WORKER_ID Worker identity (default: worker_<random>)
36155
+ HASNA_SKILLS_WORKER_IDLE_MS Idle pause between polls (default: 1000)`);
36156
+ process.exit(0);
36157
+ }
35883
36158
  const config = resolveServerConfig();
35884
36159
  const store = await createStore({ databaseUrl: config.databaseUrl, bootstrapApiKey: config.bootstrapApiKey });
35885
36160
  assertDurableStore(store, config);