@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/README.md +4 -2
- package/bin/index.js +29419 -18305
- package/bin/mcp.js +13798 -3053
- package/bin/migrate.js +114 -62
- package/bin/server.js +3517 -3015
- package/bin/worker.js +1788 -1513
- package/dist/admin-contract.d.ts +887 -5832
- package/dist/admin-contract.js +13914 -3611
- package/dist/cli/commands/install.d.ts +16 -0
- package/dist/cli/commands/publish.d.ts +49 -0
- package/dist/cli/commands/registry.d.ts +5 -0
- package/dist/index.js +14654 -4123
- package/dist/lib/app-home.d.ts +27 -1
- package/dist/lib/feedback.d.ts +6 -0
- package/dist/lib/installer.d.ts +2 -0
- package/dist/lib/portable-skills-files.d.ts +9 -0
- package/dist/lib/portable-skills.d.ts +2 -2
- package/dist/lib/pull.d.ts +18 -1
- package/dist/lib/remote-client.d.ts +15 -1
- package/dist/lib/skill-version.d.ts +11 -0
- package/dist/sdk/index.js +20030 -9222
- package/dist/sdk/runs.d.ts +19 -101
- package/dist/server/app.d.ts +3 -0
- package/dist/server/artifact-storage.d.ts +38 -0
- package/dist/server/config.d.ts +2 -0
- package/dist/server/rows.d.ts +2 -1
- package/dist/server/seed-bundled.d.ts +20 -0
- package/dist/server/skills-api.d.ts +31 -3
- package/dist/server/sqlite-store.d.ts +3 -1
- package/dist/server/store.d.ts +6 -1
- package/dist/server/types.d.ts +43 -0
- package/dist/storage.js +62 -61
- package/migrations/postgres/0006_skill_versions.sql +30 -0
- package/migrations/sqlite/0006_skill_versions.sql +17 -0
- package/package.json +2 -3
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
23587
|
+
// node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
|
|
23466
23588
|
var import_client23 = __toESM(require_client2(), 1);
|
|
23467
23589
|
|
|
23468
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
31989
|
-
var
|
|
32110
|
+
// node_modules/@aws-sdk/client-s3/package.json
|
|
32111
|
+
var package_default2 = {
|
|
31990
32112
|
name: "@aws-sdk/client-s3",
|
|
31991
|
-
version: "3.
|
|
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.
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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:
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
-
//
|
|
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
|
|
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
|
|
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
|
-
|
|
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
|
|
32935
|
-
function
|
|
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 (!
|
|
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
|
|
32944
|
-
|
|
32945
|
-
}
|
|
32946
|
-
|
|
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
|
|
32954
|
-
|
|
32955
|
-
|
|
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 ??
|
|
33095
|
+
const home = options.home ?? pathsResolverHomedir();
|
|
32958
33096
|
const platform = options.platform ?? process.platform;
|
|
32959
|
-
if (
|
|
33097
|
+
if (platform === "darwin") {
|
|
32960
33098
|
switch (kind) {
|
|
32961
33099
|
case "config":
|
|
32962
33100
|
case "data":
|
|
32963
|
-
return
|
|
33101
|
+
return pathsResolverJoin(home, "Library", "Application Support", "Hasna");
|
|
32964
33102
|
case "cache":
|
|
32965
|
-
return
|
|
33103
|
+
return pathsResolverJoin(home, "Library", "Caches", "Hasna");
|
|
32966
33104
|
case "state":
|
|
32967
|
-
return
|
|
33105
|
+
return pathsResolverJoin(home, "Library", "Logs", "Hasna");
|
|
32968
33106
|
}
|
|
32969
33107
|
}
|
|
32970
33108
|
switch (kind) {
|
|
32971
33109
|
case "config":
|
|
32972
|
-
return
|
|
33110
|
+
return pathsResolverJoin(home, ".config", "hasna");
|
|
32973
33111
|
case "data":
|
|
32974
|
-
return
|
|
33112
|
+
return pathsResolverJoin(home, ".local", "share", "hasna");
|
|
32975
33113
|
case "state":
|
|
32976
|
-
return
|
|
33114
|
+
return pathsResolverJoin(home, ".local", "state", "hasna");
|
|
32977
33115
|
case "cache":
|
|
32978
|
-
return
|
|
33116
|
+
return pathsResolverJoin(home, ".cache", "hasna");
|
|
32979
33117
|
}
|
|
32980
33118
|
}
|
|
32981
|
-
function
|
|
32982
|
-
|
|
32983
|
-
const appSegment = options.internal === true ?
|
|
32984
|
-
return
|
|
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
|
|
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"] ||
|
|
33133
|
+
return process.env["HOME"] || process.env["USERPROFILE"] || homedir2() || "/tmp";
|
|
32998
33134
|
}
|
|
32999
33135
|
function legacyDataRoot() {
|
|
33000
|
-
return
|
|
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(
|
|
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 =
|
|
33039
|
-
const targetPath =
|
|
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 =
|
|
33060
|
-
const oldConfigFile =
|
|
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(
|
|
33200
|
+
if (existsSync2(oldConfigFile) && !existsSync2(join3(root3, "config.json"))) {
|
|
33065
33201
|
try {
|
|
33066
|
-
copyFileSync(oldConfigFile,
|
|
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
|
|
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 :
|
|
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 :
|
|
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
|
|
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
|
|
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 =
|
|
33173
|
-
if (MIGRATION_DIALECTS.some((dialect) => existsSync3(
|
|
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 =
|
|
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(
|
|
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/
|
|
33988
|
-
|
|
33989
|
-
|
|
33990
|
-
|
|
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/
|
|
34031
|
-
|
|
34032
|
-
|
|
34033
|
-
|
|
34034
|
-
|
|
34035
|
-
|
|
34036
|
-
|
|
34037
|
-
|
|
34038
|
-
tags:
|
|
34039
|
-
|
|
34040
|
-
|
|
34041
|
-
|
|
34042
|
-
|
|
34043
|
-
|
|
34044
|
-
|
|
34045
|
-
|
|
34046
|
-
|
|
34047
|
-
|
|
34048
|
-
|
|
34049
|
-
|
|
34050
|
-
|
|
34051
|
-
|
|
34052
|
-
|
|
34053
|
-
|
|
34054
|
-
|
|
34055
|
-
|
|
34056
|
-
|
|
34057
|
-
|
|
34058
|
-
|
|
34059
|
-
|
|
34060
|
-
|
|
34061
|
-
|
|
34062
|
-
|
|
34063
|
-
}
|
|
34064
|
-
|
|
34065
|
-
|
|
34066
|
-
|
|
34067
|
-
|
|
34068
|
-
|
|
34069
|
-
|
|
34070
|
-
|
|
34071
|
-
|
|
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
|
-
|
|
34076
|
-
|
|
34077
|
-
|
|
34078
|
-
|
|
34079
|
-
|
|
34080
|
-
|
|
34081
|
-
|
|
34082
|
-
|
|
34083
|
-
|
|
34084
|
-
|
|
34085
|
-
|
|
34086
|
-
|
|
34087
|
-
|
|
34088
|
-
|
|
34089
|
-
|
|
34090
|
-
|
|
34091
|
-
|
|
34092
|
-
|
|
34093
|
-
}
|
|
34094
|
-
|
|
34095
|
-
|
|
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
|
-
|
|
34098
|
-
|
|
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
|
-
|
|
34101
|
-
|
|
34102
|
-
|
|
34103
|
-
|
|
34104
|
-
|
|
34105
|
-
|
|
34106
|
-
|
|
34107
|
-
|
|
34108
|
-
|
|
34109
|
-
|
|
34110
|
-
|
|
34111
|
-
|
|
34112
|
-
|
|
34113
|
-
|
|
34114
|
-
|
|
34115
|
-
|
|
34116
|
-
|
|
34117
|
-
|
|
34118
|
-
|
|
34119
|
-
|
|
34120
|
-
|
|
34121
|
-
|
|
34122
|
-
|
|
34123
|
-
|
|
34124
|
-
|
|
34125
|
-
|
|
34126
|
-
|
|
34127
|
-
|
|
34128
|
-
|
|
34129
|
-
|
|
34130
|
-
|
|
34131
|
-
|
|
34132
|
-
|
|
34133
|
-
|
|
34134
|
-
|
|
34135
|
-
|
|
34136
|
-
|
|
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
|
-
|
|
34228
|
-
|
|
34229
|
-
|
|
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
|
-
|
|
34232
|
-
|
|
34233
|
-
|
|
34234
|
-
|
|
34235
|
-
|
|
34236
|
-
|
|
34237
|
-
|
|
34238
|
-
|
|
34239
|
-
|
|
34240
|
-
|
|
34241
|
-
|
|
34242
|
-
|
|
34243
|
-
|
|
34244
|
-
|
|
34245
|
-
|
|
34246
|
-
|
|
34247
|
-
|
|
34248
|
-
|
|
34249
|
-
|
|
34250
|
-
|
|
34251
|
-
|
|
34252
|
-
|
|
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
|
-
|
|
34255
|
-
|
|
34256
|
-
|
|
34257
|
-
|
|
34258
|
-
|
|
34259
|
-
|
|
34260
|
-
|
|
34261
|
-
|
|
34262
|
-
|
|
34263
|
-
|
|
34264
|
-
|
|
34265
|
-
|
|
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
|
-
|
|
34268
|
-
|
|
34269
|
-
|
|
34270
|
-
|
|
34271
|
-
|
|
34272
|
-
|
|
34273
|
-
|
|
34274
|
-
|
|
34275
|
-
|
|
34276
|
-
|
|
34277
|
-
|
|
34278
|
-
|
|
34279
|
-
|
|
34280
|
-
|
|
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
|
-
|
|
34283
|
-
|
|
34284
|
-
|
|
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
|
-
|
|
34287
|
-
|
|
34288
|
-
|
|
34289
|
-
|
|
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
|
-
|
|
34292
|
-
|
|
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
|
-
|
|
34295
|
-
|
|
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
|
-
|
|
34298
|
-
|
|
34299
|
-
|
|
34300
|
-
|
|
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
|
|
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
|
|
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) =>
|
|
35875
|
+
return rows.map((row) => rowToSkillVersion(row));
|
|
34837
35876
|
}
|
|
34838
|
-
async
|
|
34839
|
-
await this.purgeExpiredTombstones(principal);
|
|
35877
|
+
async getSkillVersion(principal, slug, version2) {
|
|
34840
35878
|
const rows = await this.sql`
|
|
34841
|
-
SELECT
|
|
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
|
|
35881
|
+
return rows[0] ? rowToSkillVersion(rows[0]) : null;
|
|
34847
35882
|
}
|
|
34848
|
-
async
|
|
34849
|
-
await this.purgeExpiredTombstones(principal);
|
|
35883
|
+
async pinSkill(principal, slug, metadata = {}) {
|
|
34850
35884
|
const rows = await this.sql`
|
|
34851
|
-
|
|
34852
|
-
|
|
34853
|
-
|
|
34854
|
-
|
|
34855
|
-
|
|
34856
|
-
|
|
34857
|
-
`;
|
|
34858
|
-
return rows
|
|
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
|
-
|
|
35546
|
-
|
|
35547
|
-
|
|
35548
|
-
|
|
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
|
-
|
|
35600
|
-
|
|
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
|
-
|
|
35647
|
-
|
|
35648
|
-
|
|
35649
|
-
|
|
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
|
-
|
|
35658
|
-
|
|
35659
|
-
|
|
35660
|
-
|
|
35661
|
-
|
|
35662
|
-
|
|
35663
|
-
|
|
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
|
-
|
|
35678
|
-
|
|
35679
|
-
|
|
35680
|
-
|
|
35681
|
-
|
|
35682
|
-
|
|
35683
|
-
|
|
35684
|
-
|
|
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
|
-
|
|
35717
|
-
|
|
35718
|
-
|
|
35719
|
-
|
|
35720
|
-
|
|
35721
|
-
|
|
35722
|
-
|
|
35723
|
-
|
|
35724
|
-
|
|
35725
|
-
|
|
35726
|
-
|
|
35727
|
-
|
|
35728
|
-
|
|
35729
|
-
var
|
|
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/
|
|
35732
|
-
var
|
|
35733
|
-
|
|
35734
|
-
|
|
35735
|
-
|
|
35736
|
-
|
|
35737
|
-
|
|
35738
|
-
|
|
35739
|
-
|
|
35740
|
-
|
|
35741
|
-
|
|
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/
|
|
35753
|
-
var
|
|
35754
|
-
|
|
35755
|
-
|
|
35756
|
-
"
|
|
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
|
-
|
|
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
|
-
|
|
35819
|
-
|
|
36004
|
+
${text.trim()}
|
|
36005
|
+
`),
|
|
36006
|
+
textArtifact(run, "summary.md", `# Summary
|
|
35820
36007
|
|
|
35821
|
-
|
|
35822
|
-
|
|
35823
|
-
|
|
35824
|
-
|
|
35825
|
-
|
|
35826
|
-
|
|
35827
|
-
|
|
35828
|
-
|
|
35829
|
-
|
|
35830
|
-
|
|
35831
|
-
|
|
35832
|
-
|
|
35833
|
-
|
|
35834
|
-
|
|
35835
|
-
|
|
35836
|
-
|
|
35837
|
-
|
|
35838
|
-
|
|
35839
|
-
|
|
35840
|
-
|
|
35841
|
-
|
|
35842
|
-
|
|
35843
|
-
|
|
35844
|
-
|
|
35845
|
-
|
|
35846
|
-
|
|
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
|
-
|
|
35851
|
-
|
|
35852
|
-
|
|
35853
|
-
|
|
35854
|
-
|
|
35855
|
-
|
|
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);
|