@hasna/skills 0.3.0 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +94 -10
- package/bin/index.js +1398 -571
- package/bin/mcp.js +899 -211
- package/bin/server.js +14 -5
- package/bin/worker.js +2 -3
- package/dist/cli/commands/remote-account.d.ts +7 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +770 -210
- package/dist/lib/auth-store.d.ts +1 -1
- package/dist/lib/fleet-credentials.d.ts +8 -2
- package/dist/lib/instance-credentials-race.fixture.d.ts +1 -0
- package/dist/lib/instance-credentials.d.ts +13 -0
- package/dist/lib/mcp-contracts.d.ts +4 -0
- package/dist/lib/portable-skills-files.d.ts +4 -0
- package/dist/lib/portable-skills-types.d.ts +2 -0
- package/dist/lib/remote-account.d.ts +42 -0
- package/dist/lib/remote-auth.d.ts +32 -0
- package/dist/lib/remote-client.d.ts +56 -1
- package/dist/lib/remote-customer-operations.d.ts +106 -0
- package/dist/lib/remote-files.d.ts +21 -0
- package/dist/lib/run-routing.d.ts +1 -0
- package/dist/lib/run-state.d.ts +3 -0
- package/dist/mcp/remote-customer-tools.d.ts +2 -0
- package/dist/sdk/index.d.ts +4 -0
- package/dist/sdk/index.js +1057 -280
- package/dist/sdk/runs.d.ts +4 -4
- package/package.json +2 -3
package/dist/sdk/index.js
CHANGED
|
@@ -2370,11 +2370,11 @@ var require_config = __commonJS((exports) => {
|
|
|
2370
2370
|
};
|
|
2371
2371
|
function getSelectorName(functionString) {
|
|
2372
2372
|
try {
|
|
2373
|
-
const
|
|
2374
|
-
|
|
2375
|
-
|
|
2376
|
-
|
|
2377
|
-
return [...
|
|
2373
|
+
const constants2 = new Set(Array.from(functionString.match(/([A-Z_]){3,}/g) ?? []));
|
|
2374
|
+
constants2.delete("CONFIG");
|
|
2375
|
+
constants2.delete("CONFIG_PREFIX_SEPARATOR");
|
|
2376
|
+
constants2.delete("ENV");
|
|
2377
|
+
return [...constants2].join(", ");
|
|
2378
2378
|
} catch (ignored) {
|
|
2379
2379
|
return functionString;
|
|
2380
2380
|
}
|
|
@@ -3573,7 +3573,7 @@ var require_serde = __commonJS((exports) => {
|
|
|
3573
3573
|
var { createHmac: createHmac2, createHash: createHash2, getRandomValues } = __require("crypto");
|
|
3574
3574
|
var { hasOwn: hasOwn2, HttpResponse } = require_transport();
|
|
3575
3575
|
exports.hasOwn = hasOwn2;
|
|
3576
|
-
var { ReadStream, lstatSync, fstatSync:
|
|
3576
|
+
var { ReadStream, lstatSync: lstatSync2, fstatSync: fstatSync3 } = __require("fs");
|
|
3577
3577
|
var { toEndpointV1 } = require_endpoints();
|
|
3578
3578
|
var { Readable, Writable, PassThrough } = __require("stream");
|
|
3579
3579
|
var isArrayBuffer = (arg) => typeof ArrayBuffer === "function" && arg instanceof ArrayBuffer || Object.prototype.toString.call(arg) === "[object ArrayBuffer]";
|
|
@@ -4339,9 +4339,9 @@ var require_serde = __commonJS((exports) => {
|
|
|
4339
4339
|
return body.end + 1 - body.start;
|
|
4340
4340
|
} else if (body instanceof ReadStream) {
|
|
4341
4341
|
if (body.path != null) {
|
|
4342
|
-
return
|
|
4342
|
+
return lstatSync2(body.path).size;
|
|
4343
4343
|
} else if (typeof body.fd === "number") {
|
|
4344
|
-
return
|
|
4344
|
+
return fstatSync3(body.fd).size;
|
|
4345
4345
|
}
|
|
4346
4346
|
}
|
|
4347
4347
|
throw new Error(`Body Length computation failed for ${body}`);
|
|
@@ -17645,7 +17645,7 @@ var require_httpAuthSchemes = __commonJS((exports) => {
|
|
|
17645
17645
|
});
|
|
17646
17646
|
|
|
17647
17647
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-env@3.972.70/node_modules/@aws-sdk/credential-provider-env/dist-es/fromEnv.js
|
|
17648
|
-
var
|
|
17648
|
+
var import_client7, 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 () => {
|
|
17649
17649
|
init?.logger?.debug("@aws-sdk/credential-provider-env - fromEnv");
|
|
17650
17650
|
const accessKeyId = process.env[ENV_KEY];
|
|
17651
17651
|
const secretAccessKey = process.env[ENV_SECRET];
|
|
@@ -17662,13 +17662,13 @@ var import_client6, import_config, ENV_KEY = "AWS_ACCESS_KEY_ID", ENV_SECRET = "
|
|
|
17662
17662
|
...credentialScope && { credentialScope },
|
|
17663
17663
|
...accountId && { accountId }
|
|
17664
17664
|
};
|
|
17665
|
-
|
|
17665
|
+
import_client7.setCredentialFeature(credentials, "CREDENTIALS_ENV_VARS", "g");
|
|
17666
17666
|
return credentials;
|
|
17667
17667
|
}
|
|
17668
17668
|
throw new import_config.CredentialsProviderError("Unable to find environment variable credentials.", { logger: init?.logger });
|
|
17669
17669
|
};
|
|
17670
17670
|
var init_fromEnv = __esm(() => {
|
|
17671
|
-
|
|
17671
|
+
import_client7 = __toESM(require_client2(), 1);
|
|
17672
17672
|
import_config = __toESM(require_config(), 1);
|
|
17673
17673
|
});
|
|
17674
17674
|
|
|
@@ -18738,7 +18738,7 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18738
18738
|
return this.connectOptions === undefined ? http2.connect(url) : http2.connect(url, this.connectOptions);
|
|
18739
18739
|
}
|
|
18740
18740
|
}
|
|
18741
|
-
var { constants } = http2;
|
|
18741
|
+
var { constants: constants2 } = http2;
|
|
18742
18742
|
|
|
18743
18743
|
class NodeHttp2Handler {
|
|
18744
18744
|
config;
|
|
@@ -18829,8 +18829,8 @@ or increase socketAcquisitionWarningTimeout=(millis) in the NodeHttpHandler conf
|
|
|
18829
18829
|
}
|
|
18830
18830
|
const clientHttp2Stream = session.request({
|
|
18831
18831
|
...request.headers,
|
|
18832
|
-
[
|
|
18833
|
-
[
|
|
18832
|
+
[constants2.HTTP2_HEADER_PATH]: path,
|
|
18833
|
+
[constants2.HTTP2_HEADER_METHOD]: method
|
|
18834
18834
|
});
|
|
18835
18835
|
if (effectiveRequestTimeout) {
|
|
18836
18836
|
clientHttp2Stream.setTimeout(effectiveRequestTimeout, () => {
|
|
@@ -19010,7 +19010,7 @@ var retryWrapper = (toRetry, maxRetries, delayMs) => {
|
|
|
19010
19010
|
|
|
19011
19011
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-http@3.972.72/node_modules/@aws-sdk/credential-provider-http/dist-es/fromHttp/fromHttp.js
|
|
19012
19012
|
import fs from "fs/promises";
|
|
19013
|
-
var
|
|
19013
|
+
var import_client8, 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 = {}) => {
|
|
19014
19014
|
options.logger?.debug("@aws-sdk/credential-provider-http - fromHttp");
|
|
19015
19015
|
let host;
|
|
19016
19016
|
const relative2 = options.awsContainerCredentialsRelativeUri ?? process.env[AWS_CONTAINER_CREDENTIALS_RELATIVE_URI];
|
|
@@ -19047,7 +19047,7 @@ Set AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
|
|
|
19047
19047
|
}
|
|
19048
19048
|
try {
|
|
19049
19049
|
const result = await requestHandler.handle(request, { requestTimeout });
|
|
19050
|
-
return getCredentials(result.response).then((creds) =>
|
|
19050
|
+
return getCredentials(result.response).then((creds) => import_client8.setCredentialFeature(creds, "CREDENTIALS_HTTP", "z"));
|
|
19051
19051
|
} catch (e2) {
|
|
19052
19052
|
throw new import_config9.CredentialsProviderError(String(e2), { logger: options.logger });
|
|
19053
19053
|
}
|
|
@@ -19069,7 +19069,7 @@ Set AWS_CONTAINER_CREDENTIALS_FULL_URI or AWS_CONTAINER_CREDENTIALS_RELATIVE_URI
|
|
|
19069
19069
|
var init_fromHttp = __esm(() => {
|
|
19070
19070
|
init_checkUrl();
|
|
19071
19071
|
init_requestHelpers();
|
|
19072
|
-
|
|
19072
|
+
import_client8 = __toESM(require_client2(), 1);
|
|
19073
19073
|
import_config9 = __toESM(require_config(), 1);
|
|
19074
19074
|
import_node_http_handler = __toESM(require_dist_cjs6(), 1);
|
|
19075
19075
|
});
|
|
@@ -20453,7 +20453,7 @@ var init_loadSso = __esm(() => {
|
|
|
20453
20453
|
});
|
|
20454
20454
|
|
|
20455
20455
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-sso@3.973.14/node_modules/@aws-sdk/credential-provider-sso/dist-es/resolveSSOCredentials.js
|
|
20456
|
-
var
|
|
20456
|
+
var import_client9, import_config15, SHOULD_FAIL_CREDENTIAL_CHAIN = false, resolveSSOCredentials = async ({ ssoStartUrl, ssoSession, ssoAccountId, ssoRegion, ssoRoleName, ssoClient, clientConfig, parentClientConfig, callerClientConfig, profile, filepath, configFilepath, ignoreCache, logger }) => {
|
|
20457
20457
|
let token;
|
|
20458
20458
|
const refreshMessage = `To refresh this SSO session run aws sso login with the corresponding profile.`;
|
|
20459
20459
|
if (ssoSession) {
|
|
@@ -20529,15 +20529,15 @@ var import_client8, import_config15, SHOULD_FAIL_CREDENTIAL_CHAIN = false, resol
|
|
|
20529
20529
|
...accountId && { accountId }
|
|
20530
20530
|
};
|
|
20531
20531
|
if (ssoSession) {
|
|
20532
|
-
|
|
20532
|
+
import_client9.setCredentialFeature(credentials, "CREDENTIALS_SSO", "s");
|
|
20533
20533
|
} else {
|
|
20534
|
-
|
|
20534
|
+
import_client9.setCredentialFeature(credentials, "CREDENTIALS_SSO_LEGACY", "u");
|
|
20535
20535
|
}
|
|
20536
20536
|
return credentials;
|
|
20537
20537
|
};
|
|
20538
20538
|
var init_resolveSSOCredentials = __esm(() => {
|
|
20539
20539
|
init_dist_es4();
|
|
20540
|
-
|
|
20540
|
+
import_client9 = __toESM(require_client2(), 1);
|
|
20541
20541
|
import_config15 = __toESM(require_config(), 1);
|
|
20542
20542
|
});
|
|
20543
20543
|
|
|
@@ -20649,7 +20649,7 @@ var init_dist_es5 = __esm(() => {
|
|
|
20649
20649
|
});
|
|
20650
20650
|
|
|
20651
20651
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveCredentialSource.js
|
|
20652
|
-
var
|
|
20652
|
+
var import_client10, import_config18, resolveCredentialSource = (credentialSource, profileName, logger) => {
|
|
20653
20653
|
const sourceProvidersMap = {
|
|
20654
20654
|
EcsContainer: async (options) => {
|
|
20655
20655
|
const { fromHttp: fromHttp2 } = await Promise.resolve().then(() => (init_dist_es3(), exports_dist_es3));
|
|
@@ -20673,9 +20673,9 @@ var import_client9, import_config18, resolveCredentialSource = (credentialSource
|
|
|
20673
20673
|
} else {
|
|
20674
20674
|
throw new import_config18.CredentialsProviderError(`Unsupported credential source in profile ${profileName}. Got ${credentialSource}, expected EcsContainer or Ec2InstanceMetadata or Environment.`, { logger });
|
|
20675
20675
|
}
|
|
20676
|
-
}, setNamedProvider = (creds) =>
|
|
20676
|
+
}, setNamedProvider = (creds) => import_client10.setCredentialFeature(creds, "CREDENTIALS_PROFILE_NAMED_PROVIDER", "p");
|
|
20677
20677
|
var init_resolveCredentialSource = __esm(() => {
|
|
20678
|
-
|
|
20678
|
+
import_client10 = __toESM(require_client2(), 1);
|
|
20679
20679
|
import_config18 = __toESM(require_config(), 1);
|
|
20680
20680
|
});
|
|
20681
20681
|
|
|
@@ -21702,7 +21702,7 @@ var require_sts = __commonJS((exports) => {
|
|
|
21702
21702
|
});
|
|
21703
21703
|
|
|
21704
21704
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveAssumeRoleCredentials.js
|
|
21705
|
-
var
|
|
21705
|
+
var import_client11, import_config19, isAssumeRoleProfile = (arg, { profile = "default", logger } = {}) => {
|
|
21706
21706
|
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 }));
|
|
21707
21707
|
}, isAssumeRoleWithSourceProfile = (arg, { profile, logger }) => {
|
|
21708
21708
|
const withSourceProfile = typeof arg.source_profile === "string" && typeof arg.credential_source === "undefined";
|
|
@@ -21741,7 +21741,7 @@ var import_client10, import_config19, isAssumeRoleProfile = (arg, { profile = "d
|
|
|
21741
21741
|
[source_profile]: true
|
|
21742
21742
|
}, isCredentialSourceWithoutRoleArn(profiles[source_profile] ?? {})) : (await resolveCredentialSource(profileData.credential_source, profileName, options.logger)(options))();
|
|
21743
21743
|
if (isCredentialSourceWithoutRoleArn(profileData)) {
|
|
21744
|
-
return sourceCredsProvider.then((creds) =>
|
|
21744
|
+
return sourceCredsProvider.then((creds) => import_client11.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
21745
21745
|
} else {
|
|
21746
21746
|
const params = {
|
|
21747
21747
|
RoleArn: profileData.role_arn,
|
|
@@ -21758,14 +21758,14 @@ var import_client10, import_config19, isAssumeRoleProfile = (arg, { profile = "d
|
|
|
21758
21758
|
params.TokenCode = await options.mfaCodeProvider(mfa_serial);
|
|
21759
21759
|
}
|
|
21760
21760
|
const sourceCreds = await sourceCredsProvider;
|
|
21761
|
-
return options.roleAssumer(sourceCreds, params).then((creds) =>
|
|
21761
|
+
return options.roleAssumer(sourceCreds, params).then((creds) => import_client11.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
|
|
21762
21762
|
}
|
|
21763
21763
|
}, isCredentialSourceWithoutRoleArn = (section) => {
|
|
21764
21764
|
return !section.role_arn && !!section.credential_source;
|
|
21765
21765
|
};
|
|
21766
21766
|
var init_resolveAssumeRoleCredentials = __esm(() => {
|
|
21767
21767
|
init_resolveCredentialSource();
|
|
21768
|
-
|
|
21768
|
+
import_client11 = __toESM(require_client2(), 1);
|
|
21769
21769
|
import_config19 = __toESM(require_config(), 1);
|
|
21770
21770
|
});
|
|
21771
21771
|
|
|
@@ -22766,7 +22766,7 @@ var init_LoginCredentialsFetcher = __esm(() => {
|
|
|
22766
22766
|
});
|
|
22767
22767
|
|
|
22768
22768
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-login@3.972.77/node_modules/@aws-sdk/credential-provider-login/dist-es/fromLoginCredentials.js
|
|
22769
|
-
var
|
|
22769
|
+
var import_client12, import_config21, fromLoginCredentials = (init) => async ({ callerClientConfig } = {}) => {
|
|
22770
22770
|
init?.logger?.debug?.("@aws-sdk/credential-providers - fromLoginCredentials");
|
|
22771
22771
|
const profiles = await import_config21.parseKnownFiles(init || {});
|
|
22772
22772
|
const profileName = import_config21.getProfileName({
|
|
@@ -22781,11 +22781,11 @@ var import_client11, import_config21, fromLoginCredentials = (init) => async ({
|
|
|
22781
22781
|
}
|
|
22782
22782
|
const fetcher = new LoginCredentialsFetcher(profile, init, callerClientConfig);
|
|
22783
22783
|
const credentials = await fetcher.loadCredentials();
|
|
22784
|
-
return
|
|
22784
|
+
return import_client12.setCredentialFeature(credentials, "CREDENTIALS_LOGIN", "AD");
|
|
22785
22785
|
};
|
|
22786
22786
|
var init_fromLoginCredentials = __esm(() => {
|
|
22787
22787
|
init_LoginCredentialsFetcher();
|
|
22788
|
-
|
|
22788
|
+
import_client12 = __toESM(require_client2(), 1);
|
|
22789
22789
|
import_config21 = __toESM(require_config(), 1);
|
|
22790
22790
|
});
|
|
22791
22791
|
|
|
@@ -22799,7 +22799,7 @@ var init_dist_es6 = __esm(() => {
|
|
|
22799
22799
|
});
|
|
22800
22800
|
|
|
22801
22801
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveLoginCredentials.js
|
|
22802
|
-
var
|
|
22802
|
+
var import_client13, isLoginProfile = (data) => {
|
|
22803
22803
|
return Boolean(data && data.login_session);
|
|
22804
22804
|
}, resolveLoginCredentials = async (profileName, options, callerClientConfig) => {
|
|
22805
22805
|
const { fromLoginCredentials: fromLoginCredentials2 } = await Promise.resolve().then(() => (init_dist_es6(), exports_dist_es5));
|
|
@@ -22807,14 +22807,14 @@ var import_client12, isLoginProfile = (data) => {
|
|
|
22807
22807
|
...options,
|
|
22808
22808
|
profile: profileName
|
|
22809
22809
|
})({ callerClientConfig });
|
|
22810
|
-
return
|
|
22810
|
+
return import_client13.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_LOGIN", "AC");
|
|
22811
22811
|
};
|
|
22812
22812
|
var init_resolveLoginCredentials = __esm(() => {
|
|
22813
|
-
|
|
22813
|
+
import_client13 = __toESM(require_client2(), 1);
|
|
22814
22814
|
});
|
|
22815
22815
|
|
|
22816
22816
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-process@3.972.70/node_modules/@aws-sdk/credential-provider-process/dist-es/getValidatedProcessCredentials.js
|
|
22817
|
-
var
|
|
22817
|
+
var import_client14, getValidatedProcessCredentials = (profileName, data, profiles) => {
|
|
22818
22818
|
if (data.Version !== 1) {
|
|
22819
22819
|
throw Error(`Profile ${profileName} credential_process did not return Version 1.`);
|
|
22820
22820
|
}
|
|
@@ -22840,11 +22840,11 @@ var import_client13, getValidatedProcessCredentials = (profileName, data, profil
|
|
|
22840
22840
|
...data.CredentialScope && { credentialScope: data.CredentialScope },
|
|
22841
22841
|
...accountId && { accountId }
|
|
22842
22842
|
};
|
|
22843
|
-
|
|
22843
|
+
import_client14.setCredentialFeature(credentials, "CREDENTIALS_PROCESS", "w");
|
|
22844
22844
|
return credentials;
|
|
22845
22845
|
};
|
|
22846
22846
|
var init_getValidatedProcessCredentials = __esm(() => {
|
|
22847
|
-
|
|
22847
|
+
import_client14 = __toESM(require_client2(), 1);
|
|
22848
22848
|
});
|
|
22849
22849
|
|
|
22850
22850
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-process@3.972.70/node_modules/@aws-sdk/credential-provider-process/dist-es/resolveProcessCredentials.js
|
|
@@ -22905,20 +22905,20 @@ var init_dist_es7 = __esm(() => {
|
|
|
22905
22905
|
});
|
|
22906
22906
|
|
|
22907
22907
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveProcessCredentials.js
|
|
22908
|
-
var
|
|
22908
|
+
var import_client15, isProcessProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.credential_process === "string", resolveProcessCredentials2 = async (options, profile) => {
|
|
22909
22909
|
const { fromProcess: fromProcess2 } = await Promise.resolve().then(() => (init_dist_es7(), exports_dist_es6));
|
|
22910
22910
|
const credentials = await fromProcess2({
|
|
22911
22911
|
...options,
|
|
22912
22912
|
profile
|
|
22913
22913
|
})();
|
|
22914
|
-
return
|
|
22914
|
+
return import_client15.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_PROCESS", "v");
|
|
22915
22915
|
};
|
|
22916
22916
|
var init_resolveProcessCredentials2 = __esm(() => {
|
|
22917
|
-
|
|
22917
|
+
import_client15 = __toESM(require_client2(), 1);
|
|
22918
22918
|
});
|
|
22919
22919
|
|
|
22920
22920
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveSsoCredentials.js
|
|
22921
|
-
var
|
|
22921
|
+
var import_client16, resolveSsoCredentials = async (profile, profileData, options = {}, callerClientConfig) => {
|
|
22922
22922
|
const { fromSSO: fromSSO2 } = await Promise.resolve().then(() => (init_dist_es5(), exports_dist_es4));
|
|
22923
22923
|
return fromSSO2({
|
|
22924
22924
|
profile,
|
|
@@ -22929,18 +22929,18 @@ var import_client15, resolveSsoCredentials = async (profile, profileData, option
|
|
|
22929
22929
|
callerClientConfig
|
|
22930
22930
|
}).then((creds) => {
|
|
22931
22931
|
if (profileData.sso_session) {
|
|
22932
|
-
return
|
|
22932
|
+
return import_client16.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO", "r");
|
|
22933
22933
|
} else {
|
|
22934
|
-
return
|
|
22934
|
+
return import_client16.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO_LEGACY", "t");
|
|
22935
22935
|
}
|
|
22936
22936
|
});
|
|
22937
22937
|
}, isSsoProfile2 = (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");
|
|
22938
22938
|
var init_resolveSsoCredentials = __esm(() => {
|
|
22939
|
-
|
|
22939
|
+
import_client16 = __toESM(require_client2(), 1);
|
|
22940
22940
|
});
|
|
22941
22941
|
|
|
22942
22942
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveStaticCredentials.js
|
|
22943
|
-
var
|
|
22943
|
+
var import_client17, 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) => {
|
|
22944
22944
|
options?.logger?.debug("@aws-sdk/credential-provider-ini - resolveStaticCredentials");
|
|
22945
22945
|
const credentials = {
|
|
22946
22946
|
accessKeyId: profile.aws_access_key_id,
|
|
@@ -22949,10 +22949,10 @@ var import_client16, isStaticCredsProfile = (arg) => Boolean(arg) && typeof arg
|
|
|
22949
22949
|
...profile.aws_credential_scope && { credentialScope: profile.aws_credential_scope },
|
|
22950
22950
|
...profile.aws_account_id && { accountId: profile.aws_account_id }
|
|
22951
22951
|
};
|
|
22952
|
-
return
|
|
22952
|
+
return import_client17.setCredentialFeature(credentials, "CREDENTIALS_PROFILE", "n");
|
|
22953
22953
|
};
|
|
22954
22954
|
var init_resolveStaticCredentials = __esm(() => {
|
|
22955
|
-
|
|
22955
|
+
import_client17 = __toESM(require_client2(), 1);
|
|
22956
22956
|
});
|
|
22957
22957
|
|
|
22958
22958
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-web-identity@3.972.76/node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromWebToken.js
|
|
@@ -22984,7 +22984,7 @@ var fromWebToken = (init) => async (awsIdentityProperties) => {
|
|
|
22984
22984
|
|
|
22985
22985
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-web-identity@3.972.76/node_modules/@aws-sdk/credential-provider-web-identity/dist-es/fromTokenFile.js
|
|
22986
22986
|
import { readFileSync as readFileSync3 } from "fs";
|
|
22987
|
-
var
|
|
22987
|
+
var import_client18, 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) => {
|
|
22988
22988
|
init.logger?.debug("@aws-sdk/credential-provider-web-identity - fromTokenFile");
|
|
22989
22989
|
const webIdentityTokenFile = init?.webIdentityTokenFile ?? process.env[ENV_TOKEN_FILE];
|
|
22990
22990
|
const roleArn = init?.roleArn ?? process.env[ENV_ROLE_ARN];
|
|
@@ -23001,12 +23001,12 @@ var import_client17, import_config24, ENV_TOKEN_FILE = "AWS_WEB_IDENTITY_TOKEN_F
|
|
|
23001
23001
|
roleSessionName
|
|
23002
23002
|
})(awsIdentityProperties);
|
|
23003
23003
|
if (webIdentityTokenFile === process.env[ENV_TOKEN_FILE]) {
|
|
23004
|
-
|
|
23004
|
+
import_client18.setCredentialFeature(credentials, "CREDENTIALS_ENV_VARS_STS_WEB_ID_TOKEN", "h");
|
|
23005
23005
|
}
|
|
23006
23006
|
return credentials;
|
|
23007
23007
|
};
|
|
23008
23008
|
var init_fromTokenFile = __esm(() => {
|
|
23009
|
-
|
|
23009
|
+
import_client18 = __toESM(require_client2(), 1);
|
|
23010
23010
|
import_config24 = __toESM(require_config(), 1);
|
|
23011
23011
|
});
|
|
23012
23012
|
|
|
@@ -23021,7 +23021,7 @@ var init_dist_es8 = __esm(() => {
|
|
|
23021
23021
|
});
|
|
23022
23022
|
|
|
23023
23023
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveWebIdentityCredentials.js
|
|
23024
|
-
var
|
|
23024
|
+
var import_client19, 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) => {
|
|
23025
23025
|
const { fromTokenFile: fromTokenFile2 } = await Promise.resolve().then(() => (init_dist_es8(), exports_dist_es7));
|
|
23026
23026
|
const credentials = await fromTokenFile2({
|
|
23027
23027
|
webIdentityTokenFile: profile.web_identity_token_file,
|
|
@@ -23033,10 +23033,10 @@ var import_client18, isWebIdentityProfile = (arg) => Boolean(arg) && typeof arg
|
|
|
23033
23033
|
})({
|
|
23034
23034
|
callerClientConfig
|
|
23035
23035
|
});
|
|
23036
|
-
return
|
|
23036
|
+
return import_client19.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN", "q");
|
|
23037
23037
|
};
|
|
23038
23038
|
var init_resolveWebIdentityCredentials = __esm(() => {
|
|
23039
|
-
|
|
23039
|
+
import_client19 = __toESM(require_client2(), 1);
|
|
23040
23040
|
});
|
|
23041
23041
|
|
|
23042
23042
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-ini@3.973.15/node_modules/@aws-sdk/credential-provider-ini/dist-es/resolveProfileData.js
|
|
@@ -24525,7 +24525,6 @@ async function completePointerCredential(name, pointerResolution, env = process.
|
|
|
24525
24525
|
});
|
|
24526
24526
|
}
|
|
24527
24527
|
var DEFAULT_FLEET_GATEWAY_ORIGIN = "https://api.hasna.com";
|
|
24528
|
-
var DEFAULT_AUTHORITY_SOURCE = "default";
|
|
24529
24528
|
function defaultFleetGatewayBaseUrl(name) {
|
|
24530
24529
|
return `${DEFAULT_FLEET_GATEWAY_ORIGIN}/${validateAppSlug(name)}`;
|
|
24531
24530
|
}
|
|
@@ -24644,102 +24643,6 @@ function toV1BaseUrl(apiUrl) {
|
|
|
24644
24643
|
url.pathname = `${path}/v1`;
|
|
24645
24644
|
return url.toString().replace(/\/+$/, "");
|
|
24646
24645
|
}
|
|
24647
|
-
class ClientTransportConfigurationError extends Error {
|
|
24648
|
-
appName;
|
|
24649
|
-
sources;
|
|
24650
|
-
constructor(appName, message, sources = []) {
|
|
24651
|
-
super(message);
|
|
24652
|
-
this.name = "ClientTransportConfigurationError";
|
|
24653
|
-
this.appName = appName;
|
|
24654
|
-
this.sources = Object.freeze([...sources]);
|
|
24655
|
-
}
|
|
24656
|
-
}
|
|
24657
|
-
function resolveClientTransportSnapshot(name, env = process.env, options = {}) {
|
|
24658
|
-
env = snapshotClientEnvironment(name, env);
|
|
24659
|
-
const keys = clientTransportEnvKeys(name);
|
|
24660
|
-
const definedUrlEntries = keys.apiUrlKeys.filter((key) => Object.prototype.hasOwnProperty.call(env, key) && env[key] !== undefined).map((key) => ({ key, raw: String(env[key]) }));
|
|
24661
|
-
const blankUrl = definedUrlEntries.find((entry) => entry.raw.trim().length === 0);
|
|
24662
|
-
if (blankUrl) {
|
|
24663
|
-
throw new ClientTransportConfigurationError(name, `${blankUrl.key} is set but blank; public clients require an explicit HTTPS API URL and never select local storage.`, [blankUrl.key]);
|
|
24664
|
-
}
|
|
24665
|
-
const controlledUrl = definedUrlEntries.find((entry) => ASCII_CONTROL_PATTERN.test(entry.raw));
|
|
24666
|
-
if (controlledUrl) {
|
|
24667
|
-
throw new ClientTransportConfigurationError(name, `${controlledUrl.key} contains ASCII control characters.`, [controlledUrl.key]);
|
|
24668
|
-
}
|
|
24669
|
-
const usableUrlEntries = definedUrlEntries.map((entry) => ({ key: entry.key, value: entry.raw.trim() }));
|
|
24670
|
-
if (usableUrlEntries.length > 1 && new Set(usableUrlEntries.map((entry) => entry.value)).size > 1) {
|
|
24671
|
-
throw new ClientTransportConfigurationError(name, `${usableUrlEntries.map((entry) => entry.key).join(" and ")} disagree; client authority aliases must be identical or only one may be set.`, usableUrlEntries.map((entry) => entry.key));
|
|
24672
|
-
}
|
|
24673
|
-
const envUrlHit = usableUrlEntries[0] ?? null;
|
|
24674
|
-
const keychainUrlHit = keychainConfigValue(name, env, options.credentials?.keychain);
|
|
24675
|
-
const diskConfigUrlHit = appConfigDiskValue(name, env, keys.apiUrlKeys);
|
|
24676
|
-
if (diskConfigUrlHit?.unusable) {
|
|
24677
|
-
throw new ClientTransportConfigurationError(name, `${diskConfigUrlHit.key} in ${diskConfigUrlHit.path} is declared but blank or malformed; public clients require a valid HTTPS service authority.`, [diskConfigUrlHit.path]);
|
|
24678
|
-
}
|
|
24679
|
-
const urlCandidates = [
|
|
24680
|
-
...envUrlHit ? [envUrlHit] : [],
|
|
24681
|
-
...keychainUrlHit ? [{ key: keychainUrlHit.source, value: keychainUrlHit.value }] : [],
|
|
24682
|
-
...diskConfigUrlHit ? [{ key: diskConfigUrlHit.path, value: diskConfigUrlHit.value.trim() }] : []
|
|
24683
|
-
];
|
|
24684
|
-
const configuredUrl = urlCandidates[0] ?? null;
|
|
24685
|
-
const divergentUrls = urlCandidates.filter((candidate) => candidate.value !== configuredUrl?.value);
|
|
24686
|
-
if (configuredUrl && divergentUrls.length > 0) {
|
|
24687
|
-
throw new ClientTransportConfigurationError(name, `${configuredUrl.key} and ${divergentUrls.map((candidate) => candidate.key).join(" and ")} select different service authorities; refusing to send a credential written for one authority to the other.`, urlCandidates.map((candidate) => candidate.key));
|
|
24688
|
-
}
|
|
24689
|
-
const warnings = [];
|
|
24690
|
-
if (configuredUrl && !envUrlHit) {
|
|
24691
|
-
warnings.push(`No ${keys.apiUrlKeys[0]} in the environment; the server URL in ${configuredUrl.key} was used, so this client connects to the server. ` + `Keep that entry aligned with the intended service authority.`);
|
|
24692
|
-
}
|
|
24693
|
-
const credential = resolveCredential(name, env, options.credentials);
|
|
24694
|
-
if (!credential) {
|
|
24695
|
-
const diskHint = credentialDiskSourcesForMessage(name, env);
|
|
24696
|
-
const lead = configuredUrl ? `${configuredUrl.key} selects the HTTP server for '${name}', but no API key could be resolved` : `${keys.apiUrlKeys[0]} is not set and no API key could be resolved for '${name}'; a credential is required before the default fleet gateway authority applies`;
|
|
24697
|
-
warnings.push(`${lead}; refusing to create an unauthenticated client \u2014 public clients never fall back to SQLite or another local store. ` + `Looked in the Keychain (macOS only), then for a credential file at ${diskHint}, then for ${keys.apiKeyKeys[0]} in the environment.`);
|
|
24698
|
-
throw new ClientTransportConfigurationError(name, warnings.join(" "), [configuredUrl?.key ?? keys.apiUrlKeys[0]]);
|
|
24699
|
-
}
|
|
24700
|
-
if (credential.warning)
|
|
24701
|
-
warnings.push(credential.warning);
|
|
24702
|
-
let urlHit;
|
|
24703
|
-
if (configuredUrl) {
|
|
24704
|
-
urlHit = configuredUrl;
|
|
24705
|
-
} else {
|
|
24706
|
-
try {
|
|
24707
|
-
urlHit = { key: DEFAULT_AUTHORITY_SOURCE, value: defaultFleetGatewayBaseUrl(name) };
|
|
24708
|
-
} catch (error) {
|
|
24709
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
24710
|
-
throw new ClientTransportConfigurationError(name, `No ${keys.apiUrlKeys[0]} is configured and the default fleet gateway authority cannot be composed for '${name}': ${message}`, [keys.apiUrlKeys[0]]);
|
|
24711
|
-
}
|
|
24712
|
-
}
|
|
24713
|
-
const apiUrlSource = urlHit.key;
|
|
24714
|
-
let baseUrl;
|
|
24715
|
-
try {
|
|
24716
|
-
baseUrl = toV1BaseUrl(urlHit.value);
|
|
24717
|
-
} catch (error) {
|
|
24718
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
24719
|
-
throw new ClientTransportConfigurationError(name, `Invalid API URL from ${apiUrlSource}: ${message}`, [apiUrlSource]);
|
|
24720
|
-
}
|
|
24721
|
-
return {
|
|
24722
|
-
resolution: {
|
|
24723
|
-
transport: "http",
|
|
24724
|
-
transportSource: urlHit.key,
|
|
24725
|
-
baseUrl,
|
|
24726
|
-
apiUrlSource,
|
|
24727
|
-
apiKeyPresent: true,
|
|
24728
|
-
apiKeySource: credential.source,
|
|
24729
|
-
apiKeyTier: credential.tier,
|
|
24730
|
-
misconfigured: false,
|
|
24731
|
-
warning: warnings.length > 0 ? warnings.join(" ") : null
|
|
24732
|
-
},
|
|
24733
|
-
credential
|
|
24734
|
-
};
|
|
24735
|
-
}
|
|
24736
|
-
function resolveClientTransport(name, env = process.env, options = {}) {
|
|
24737
|
-
return resolveClientTransportSnapshot(name, env, options).resolution;
|
|
24738
|
-
}
|
|
24739
|
-
function credentialDiskSourcesForMessage(name, env) {
|
|
24740
|
-
const paths = credentialDiskSources(name, env);
|
|
24741
|
-
return paths.length > 0 ? paths.join(" or ") : "<no HOME or HASNA_HOME set in this environment, so no credential file was consulted>";
|
|
24742
|
-
}
|
|
24743
24646
|
var IDEMPOTENT_METHODS = new Set(["GET", "HEAD", "PUT", "DELETE", "OPTIONS"]);
|
|
24744
24647
|
var AUTHORITY_OVERRIDE_HEADERS = new Set([
|
|
24745
24648
|
"host",
|
|
@@ -24749,6 +24652,94 @@ var AUTHORITY_OVERRIDE_HEADERS = new Set([
|
|
|
24749
24652
|
"x-original-host"
|
|
24750
24653
|
]);
|
|
24751
24654
|
|
|
24655
|
+
// src/lib/instance-credentials.ts
|
|
24656
|
+
import { closeSync as closeSync2, constants, fstatSync as fstatSync2, lstatSync, openSync as openSync2, readSync } from "fs";
|
|
24657
|
+
var SKILLS_BOUND_API_URL = "HASNA_SKILLS_BOUND_API_URL";
|
|
24658
|
+
function selectedSkillsProfile(env, explicit) {
|
|
24659
|
+
const selected = explicit ?? env.HASNA_PROFILE;
|
|
24660
|
+
if (selected === undefined)
|
|
24661
|
+
return null;
|
|
24662
|
+
const profile = selected.trim();
|
|
24663
|
+
if (!/^[A-Za-z0-9](?:[A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(profile))
|
|
24664
|
+
throw new Error("Invalid Skills credential profile");
|
|
24665
|
+
return profile;
|
|
24666
|
+
}
|
|
24667
|
+
function skillsProfileCredentialFiles(env, explicit) {
|
|
24668
|
+
return credentialDiskSourceList("skills", env, selectedSkillsProfile(env, explicit)).map((source) => source.path);
|
|
24669
|
+
}
|
|
24670
|
+
function fileIdentity(file) {
|
|
24671
|
+
try {
|
|
24672
|
+
return lstatSync(file);
|
|
24673
|
+
} catch (error) {
|
|
24674
|
+
if (["ENOENT", "ENOTDIR"].includes(error.code ?? ""))
|
|
24675
|
+
return null;
|
|
24676
|
+
throw new Error("Cannot inspect Skills instance configuration");
|
|
24677
|
+
}
|
|
24678
|
+
}
|
|
24679
|
+
function unchanged(before, after) {
|
|
24680
|
+
return before === null || after === null ? before === after : ["dev", "ino", "size", "mtimeMs", "ctimeMs", "mode", "uid"].every((key) => before[key] === after[key]);
|
|
24681
|
+
}
|
|
24682
|
+
function captureSkillsCredentialFiles(files) {
|
|
24683
|
+
const identities = files.map((file) => [file, fileIdentity(file)]);
|
|
24684
|
+
return () => {
|
|
24685
|
+
if (identities.some(([file, before]) => !unchanged(before, fileIdentity(file)))) {
|
|
24686
|
+
throw new Error("Skills instance configuration changed while resolving credentials; retry without sending a credential");
|
|
24687
|
+
}
|
|
24688
|
+
};
|
|
24689
|
+
}
|
|
24690
|
+
function readMetadataText(file) {
|
|
24691
|
+
let fd;
|
|
24692
|
+
try {
|
|
24693
|
+
fd = openSync2(file, constants.O_RDONLY | constants.O_NOFOLLOW | constants.O_NONBLOCK);
|
|
24694
|
+
} catch (error) {
|
|
24695
|
+
if (["ENOENT", "ENOTDIR"].includes(error.code ?? ""))
|
|
24696
|
+
return null;
|
|
24697
|
+
throw new Error("Cannot safely read Skills instance configuration");
|
|
24698
|
+
}
|
|
24699
|
+
try {
|
|
24700
|
+
const before = fstatSync2(fd);
|
|
24701
|
+
const uid = process.getuid?.() ?? process.geteuid?.();
|
|
24702
|
+
if (!before.isFile() || ![256, 384].includes(before.mode & 4095) || uid !== undefined && before.uid !== uid || before.size > 64 * 1024) {
|
|
24703
|
+
throw new Error("Unsafe Skills instance configuration; expected a bounded owner-only regular file");
|
|
24704
|
+
}
|
|
24705
|
+
const bytes = Buffer.alloc(64 * 1024 + 1);
|
|
24706
|
+
let length = 0;
|
|
24707
|
+
while (length < bytes.length) {
|
|
24708
|
+
const count = readSync(fd, bytes, length, bytes.length - length, null);
|
|
24709
|
+
if (!count)
|
|
24710
|
+
break;
|
|
24711
|
+
length += count;
|
|
24712
|
+
}
|
|
24713
|
+
if (length > 64 * 1024 || !unchanged(before, fstatSync2(fd)) || !unchanged(before, fileIdentity(file))) {
|
|
24714
|
+
throw new Error("Skills instance configuration changed while reading");
|
|
24715
|
+
}
|
|
24716
|
+
return bytes.subarray(0, length).toString("utf8");
|
|
24717
|
+
} finally {
|
|
24718
|
+
closeSync2(fd);
|
|
24719
|
+
}
|
|
24720
|
+
}
|
|
24721
|
+
function readSkillsInstanceMetadata(file) {
|
|
24722
|
+
const text = readMetadataText(file);
|
|
24723
|
+
if (text === null)
|
|
24724
|
+
return {};
|
|
24725
|
+
const values = new Map;
|
|
24726
|
+
for (const line of text.split(/\r?\n/)) {
|
|
24727
|
+
const match = /^\s*(?:export\s+)?(HASNA_SKILLS_API_URL|SKILLS_API_URL|HASNA_SKILLS_BOUND_API_URL)\s*=\s*(.*)$/.exec(line);
|
|
24728
|
+
if (!match)
|
|
24729
|
+
continue;
|
|
24730
|
+
let value = match[2].trim();
|
|
24731
|
+
if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'"))
|
|
24732
|
+
value = value.slice(1, -1);
|
|
24733
|
+
if (!value || /[\x00-\x20\x7f]/.test(value) || values.has(match[1]))
|
|
24734
|
+
throw new Error("Invalid Skills instance configuration");
|
|
24735
|
+
values.set(match[1], value);
|
|
24736
|
+
}
|
|
24737
|
+
const urls = [values.get("HASNA_SKILLS_API_URL"), values.get("SKILLS_API_URL")].filter(Boolean);
|
|
24738
|
+
if (new Set(urls).size > 1)
|
|
24739
|
+
throw new Error("Skills API URL aliases disagree");
|
|
24740
|
+
return { apiUrl: urls[0], binding: values.get(SKILLS_BOUND_API_URL) };
|
|
24741
|
+
}
|
|
24742
|
+
|
|
24752
24743
|
// src/lib/fleet-credentials.ts
|
|
24753
24744
|
var SKILLS_APP = "skills";
|
|
24754
24745
|
var ENV_KEYS = clientTransportEnvKeys(SKILLS_APP);
|
|
@@ -24765,9 +24756,6 @@ class SkillsFleetCredentialError extends Error {
|
|
|
24765
24756
|
this.code = code;
|
|
24766
24757
|
}
|
|
24767
24758
|
}
|
|
24768
|
-
function isClientTransportConfigurationError(error) {
|
|
24769
|
-
return error instanceof ClientTransportConfigurationError || typeof error === "object" && error !== null && error.name === "ClientTransportConfigurationError";
|
|
24770
|
-
}
|
|
24771
24759
|
function isCredentialResolutionError(error) {
|
|
24772
24760
|
return error instanceof CredentialResolutionError || typeof error === "object" && error !== null && error.name === "CredentialResolutionError";
|
|
24773
24761
|
}
|
|
@@ -24778,6 +24766,9 @@ function asSkillsFleetCredentialError(error) {
|
|
|
24778
24766
|
}
|
|
24779
24767
|
function normalizeSkillsApiOrigin(apiUrl) {
|
|
24780
24768
|
const url = new URL(apiUrl);
|
|
24769
|
+
if (url.username || url.password || url.search || url.hash || url.protocol !== "https:" && !(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname))) {
|
|
24770
|
+
throw new SkillsFleetCredentialError("A Skills API URL must use HTTPS (or loopback HTTP), without credentials, query or fragment", "INVALID_API_URL");
|
|
24771
|
+
}
|
|
24781
24772
|
const pathname = url.pathname.replace(/\/+$/, "");
|
|
24782
24773
|
if (pathname === "/api" || pathname === "/api/v1") {
|
|
24783
24774
|
url.pathname = "/";
|
|
@@ -24788,11 +24779,24 @@ function normalizeSkillsApiOrigin(apiUrl) {
|
|
|
24788
24779
|
}
|
|
24789
24780
|
return url.toString().replace(/\/+$/, "");
|
|
24790
24781
|
}
|
|
24791
|
-
function configuredSkillsApiUrl(env = process.env, keychain) {
|
|
24792
|
-
|
|
24793
|
-
|
|
24794
|
-
if (value)
|
|
24795
|
-
|
|
24782
|
+
function configuredSkillsApiUrl(env = process.env, keychain, profile) {
|
|
24783
|
+
const declared = SKILLS_API_URL_ENV_KEYS.filter((key) => env[key] !== undefined).map((key) => ({ key, value: env[key] }));
|
|
24784
|
+
for (const entry of declared) {
|
|
24785
|
+
if (!entry.value.trim() || /[\x00-\x1f\x7f]/.test(entry.value))
|
|
24786
|
+
throw new SkillsFleetCredentialError(`${entry.key} is blank or contains control characters`, "INVALID_API_URL");
|
|
24787
|
+
}
|
|
24788
|
+
const normalized = declared.map((entry) => ({ value: normalizeSkillsApiOrigin(entry.value), source: entry.key }));
|
|
24789
|
+
if (new Set(normalized.map((entry) => entry.value)).size > 1)
|
|
24790
|
+
throw new SkillsFleetCredentialError("Skills API URL aliases disagree", "INVALID_API_URL");
|
|
24791
|
+
if (normalized[0])
|
|
24792
|
+
return normalized[0];
|
|
24793
|
+
if (selectedSkillsProfile(env, profile)) {
|
|
24794
|
+
for (const file of skillsProfileCredentialFiles(env, profile)) {
|
|
24795
|
+
const metadata = readSkillsInstanceMetadata(file);
|
|
24796
|
+
if (metadata.apiUrl || metadata.binding)
|
|
24797
|
+
return { value: metadata.apiUrl ?? metadata.binding, source: file };
|
|
24798
|
+
}
|
|
24799
|
+
return { value: defaultFleetGatewayBaseUrl(SKILLS_APP), source: "default" };
|
|
24796
24800
|
}
|
|
24797
24801
|
const fromKeychain = keychainConfigValue(SKILLS_APP, env, keychain);
|
|
24798
24802
|
if (fromKeychain)
|
|
@@ -24806,7 +24810,7 @@ function configuredSkillsApiUrl(env = process.env, keychain) {
|
|
|
24806
24810
|
return null;
|
|
24807
24811
|
}
|
|
24808
24812
|
function skillsCredentialFiles(env = process.env) {
|
|
24809
|
-
return
|
|
24813
|
+
return skillsProfileCredentialFiles(env);
|
|
24810
24814
|
}
|
|
24811
24815
|
function skillsCredentialFilePath(env = process.env) {
|
|
24812
24816
|
const paths = skillsCredentialFiles(env);
|
|
@@ -24825,7 +24829,11 @@ function noticeLocalSkillsMode(write = (line) => console.error(line)) {
|
|
|
24825
24829
|
}
|
|
24826
24830
|
function resolveSkillsFleet(env = process.env, options = {}) {
|
|
24827
24831
|
try {
|
|
24828
|
-
|
|
24832
|
+
const snapshot = snapshotSkillsEnvironment(env);
|
|
24833
|
+
const resolved = resolveSkillsFleetOrThrow(snapshot, snapshotSkillsOptions(env, options));
|
|
24834
|
+
if (resolved.mode === "local" && env === process.env)
|
|
24835
|
+
noticeLocalSkillsMode();
|
|
24836
|
+
return resolved;
|
|
24829
24837
|
} catch (error) {
|
|
24830
24838
|
const translated = asSkillsFleetCredentialError(error);
|
|
24831
24839
|
if (translated)
|
|
@@ -24833,38 +24841,46 @@ function resolveSkillsFleet(env = process.env, options = {}) {
|
|
|
24833
24841
|
throw error;
|
|
24834
24842
|
}
|
|
24835
24843
|
}
|
|
24836
|
-
function
|
|
24837
|
-
|
|
24838
|
-
|
|
24839
|
-
|
|
24840
|
-
|
|
24841
|
-
|
|
24842
|
-
|
|
24843
|
-
const configured2 = configuredSkillsApiUrl(env, options.credentials?.keychain);
|
|
24844
|
-
const credential2 = resolveCredential(SKILLS_APP, env, options.credentials);
|
|
24845
|
-
if (!configured2 && !credential2) {
|
|
24846
|
-
if (env === process.env)
|
|
24847
|
-
noticeLocalSkillsMode();
|
|
24848
|
-
return { mode: "local", apiOrigin: null, apiKey: null };
|
|
24849
|
-
}
|
|
24850
|
-
if (configured2 && !credential2) {
|
|
24851
|
-
throw new SkillsFleetCredentialError(`${configured2.source} points this CLI at a Skills service but no API key resolved \u2014 ` + `refusing to run locally instead. Looked in the Keychain item ` + `hasna.credentials.${SKILLS_APP}.api-key, then ${skillsCredentialFiles(env).join(" or ") || "no credentials file (no HOME)"}, ` + `then ${SKILLS_API_KEY_ENV}. Sign in with: skills auth login`);
|
|
24844
|
+
function snapshotSkillsEnvironment(env) {
|
|
24845
|
+
const snapshot = {};
|
|
24846
|
+
for (const [key, descriptor] of Object.entries(Object.getOwnPropertyDescriptors(env))) {
|
|
24847
|
+
if (!("value" in descriptor)) {
|
|
24848
|
+
if (/^(?:HASNA_|SKILLS_|HOME$|USER$)/.test(key))
|
|
24849
|
+
throw new SkillsFleetCredentialError("Accessor-backed Skills configuration is unsupported");
|
|
24850
|
+
continue;
|
|
24852
24851
|
}
|
|
24853
|
-
|
|
24852
|
+
snapshot[key] = descriptor.value;
|
|
24854
24853
|
}
|
|
24855
|
-
|
|
24856
|
-
|
|
24854
|
+
return Object.freeze(snapshot);
|
|
24855
|
+
}
|
|
24856
|
+
function snapshotSkillsOptions(env, options) {
|
|
24857
|
+
if (env !== process.env)
|
|
24858
|
+
return options;
|
|
24859
|
+
return { ...options, credentials: { ...options.credentials, keychain: {
|
|
24860
|
+
...options.credentials?.keychain,
|
|
24861
|
+
enabled: options.credentials?.keychain?.enabled ?? true
|
|
24862
|
+
} } };
|
|
24863
|
+
}
|
|
24864
|
+
function resolveSkillsFleetOrThrow(env, options) {
|
|
24865
|
+
const assertFilesUnchanged = captureSkillsCredentialFiles(skillsProfileCredentialFiles(env, options.credentials?.profile));
|
|
24866
|
+
const configured = configuredSkillsApiUrl(env, options.credentials?.keychain, options.credentials?.profile);
|
|
24857
24867
|
const credential = resolveCredential(SKILLS_APP, env, options.credentials);
|
|
24858
24868
|
if (!credential) {
|
|
24859
|
-
|
|
24869
|
+
if (!configured)
|
|
24870
|
+
return { mode: "local", apiOrigin: null, apiKey: null };
|
|
24871
|
+
throw new SkillsFleetCredentialError(`${configured.source} points this CLI at a Skills service but no API key resolved \u2014 refusing to run locally instead. ` + `Looked in hasna.credentials.skills.api-key, ${skillsCredentialFiles(env).join(" or ") || "no credentials file"}, and ${SKILLS_API_KEY_ENV}. Sign in with: skills auth login`);
|
|
24860
24872
|
}
|
|
24873
|
+
const apiOrigin = normalizeSkillsApiOrigin(configured?.value ?? defaultFleetGatewayBaseUrl(SKILLS_APP));
|
|
24874
|
+
toV1BaseUrl(apiOrigin);
|
|
24875
|
+
assertCredentialInstance(credential, apiOrigin, env, options);
|
|
24876
|
+
assertFilesUnchanged();
|
|
24861
24877
|
const base = {
|
|
24862
24878
|
mode: "hosted",
|
|
24863
24879
|
apiOrigin,
|
|
24864
|
-
apiUrlSource:
|
|
24865
|
-
apiKeySource:
|
|
24866
|
-
apiKeyTier:
|
|
24867
|
-
warning:
|
|
24880
|
+
apiUrlSource: configured?.source ?? "default",
|
|
24881
|
+
apiKeySource: credential.source,
|
|
24882
|
+
apiKeyTier: credential.tier,
|
|
24883
|
+
warning: credential.warning
|
|
24868
24884
|
};
|
|
24869
24885
|
if (credential.tier === "pointer") {
|
|
24870
24886
|
return { ...base, apiKey: null, apiKeyPointer: credential };
|
|
@@ -24874,19 +24890,37 @@ function resolveSkillsFleetOrThrow(env, options) {
|
|
|
24874
24890
|
}
|
|
24875
24891
|
return { ...base, apiKey: credential.apiKey, apiKeyPointer: null };
|
|
24876
24892
|
}
|
|
24893
|
+
function assertCredentialInstance(credential, apiOrigin, env, options) {
|
|
24894
|
+
let bound;
|
|
24895
|
+
if (credential.tier === "disk" || credential.tier === "profile") {
|
|
24896
|
+
const metadata = readSkillsInstanceMetadata(credential.source);
|
|
24897
|
+
bound = metadata.binding ?? metadata.apiUrl ?? defaultFleetGatewayBaseUrl(SKILLS_APP);
|
|
24898
|
+
} else if (credential.tier === "keychain") {
|
|
24899
|
+
bound = keychainConfigValue(SKILLS_APP, env, options.credentials?.keychain)?.value ?? defaultFleetGatewayBaseUrl(SKILLS_APP);
|
|
24900
|
+
}
|
|
24901
|
+
if (bound && normalizeSkillsApiOrigin(bound) !== apiOrigin) {
|
|
24902
|
+
throw new SkillsFleetCredentialError("The selected Skills API does not match this credential's instance. Select its profile or sign in to the new instance; no credential was sent.", "INSTANCE_CREDENTIAL_MISMATCH");
|
|
24903
|
+
}
|
|
24904
|
+
}
|
|
24877
24905
|
async function resolveSkillsApiKey(env = process.env, options = {}) {
|
|
24878
|
-
|
|
24906
|
+
return (await resolveSkillsConnection(env, options))?.apiKey ?? null;
|
|
24907
|
+
}
|
|
24908
|
+
async function resolveSkillsConnection(env = process.env, options = {}) {
|
|
24909
|
+
const snapshotEnv = snapshotSkillsEnvironment(env);
|
|
24910
|
+
const fleet = resolveSkillsFleet(snapshotEnv, snapshotSkillsOptions(env, options));
|
|
24911
|
+
if (fleet.mode === "local" && env === process.env)
|
|
24912
|
+
noticeLocalSkillsMode();
|
|
24879
24913
|
if (fleet.mode !== "hosted")
|
|
24880
24914
|
return null;
|
|
24881
24915
|
if (fleet.apiKey)
|
|
24882
|
-
return fleet.apiKey;
|
|
24916
|
+
return { ...fleet, apiKey: fleet.apiKey };
|
|
24883
24917
|
const pointer = fleet.apiKeyPointer;
|
|
24884
24918
|
if (!pointer) {
|
|
24885
24919
|
throw new SkillsFleetCredentialError(`A Skills authority resolved but no API key did. Sign in with: skills auth login`);
|
|
24886
24920
|
}
|
|
24887
24921
|
let completed;
|
|
24888
24922
|
try {
|
|
24889
|
-
completed = await completePointerCredential(SKILLS_APP, pointer,
|
|
24923
|
+
completed = await completePointerCredential(SKILLS_APP, pointer, snapshotEnv);
|
|
24890
24924
|
} catch (error) {
|
|
24891
24925
|
const translated = asSkillsFleetCredentialError(error);
|
|
24892
24926
|
if (translated)
|
|
@@ -24896,7 +24930,7 @@ async function resolveSkillsApiKey(env = process.env, options = {}) {
|
|
|
24896
24930
|
if (!completed.apiKey?.trim()) {
|
|
24897
24931
|
throw new SkillsFleetCredentialError(`${credentialPointerEnvKey(SKILLS_APP)} names a vault item that produced an empty Skills API key \u2014 ` + `refusing to send an unauthenticated request.`);
|
|
24898
24932
|
}
|
|
24899
|
-
return completed.apiKey;
|
|
24933
|
+
return { ...fleet, apiKey: completed.apiKey, apiKeyPointer: null };
|
|
24900
24934
|
}
|
|
24901
24935
|
async function requireSkillsApiKey(action = "This command", env = process.env, options = {}) {
|
|
24902
24936
|
const apiKey = await resolveSkillsApiKey(env, options);
|
|
@@ -24904,22 +24938,19 @@ async function requireSkillsApiKey(action = "This command", env = process.env, o
|
|
|
24904
24938
|
throw new MissingSkillsFleetError(action);
|
|
24905
24939
|
return apiKey;
|
|
24906
24940
|
}
|
|
24907
|
-
function stripV1(baseUrl) {
|
|
24908
|
-
return baseUrl.replace(/\/v1$/, "").replace(/\/+$/, "");
|
|
24909
|
-
}
|
|
24910
24941
|
async function skillsCredentialOrReason(env = process.env, options = {}) {
|
|
24911
24942
|
try {
|
|
24912
|
-
const
|
|
24913
|
-
return
|
|
24943
|
+
const connection = await resolveSkillsConnection(env, options);
|
|
24944
|
+
return connection ? { apiKey: connection.apiKey, apiOrigin: connection.apiOrigin, reason: null } : { apiKey: null, apiOrigin: null, reason: null };
|
|
24914
24945
|
} catch (error) {
|
|
24915
24946
|
if (error instanceof SkillsFleetCredentialError || error?.name === "SkillsFleetCredentialError") {
|
|
24916
|
-
return { apiKey: null, reason: error.message };
|
|
24947
|
+
return { apiKey: null, apiOrigin: null, reason: error.message };
|
|
24917
24948
|
}
|
|
24918
24949
|
throw error;
|
|
24919
24950
|
}
|
|
24920
24951
|
}
|
|
24921
24952
|
function resolveSkillsApiOrigin(env = process.env, options = {}) {
|
|
24922
|
-
const configured = configuredSkillsApiUrl(env, options.credentials?.keychain);
|
|
24953
|
+
const configured = configuredSkillsApiUrl(env, options.credentials?.keychain, options.credentials?.profile);
|
|
24923
24954
|
if (configured) {
|
|
24924
24955
|
toV1BaseUrl(configured.value);
|
|
24925
24956
|
return { origin: normalizeSkillsApiOrigin(configured.value), source: configured.source };
|
|
@@ -24950,7 +24981,7 @@ class MissingSkillsFleetError extends Error {
|
|
|
24950
24981
|
// package.json
|
|
24951
24982
|
var package_default = {
|
|
24952
24983
|
name: "@hasna/skills",
|
|
24953
|
-
version: "0.
|
|
24984
|
+
version: "0.4.0",
|
|
24954
24985
|
description: "Skills library for AI coding agents",
|
|
24955
24986
|
type: "module",
|
|
24956
24987
|
bin: {
|
|
@@ -25009,8 +25040,7 @@ var package_default = {
|
|
|
25009
25040
|
"verify:release": "bun run scripts/release-guard.ts",
|
|
25010
25041
|
prepare: "bun run build:js",
|
|
25011
25042
|
prepack: "bun run build && bun run verify:release",
|
|
25012
|
-
prepublishOnly: "bun run typecheck && bun run test"
|
|
25013
|
-
postinstall: "mkdir -p $HOME/.hasna/skills/custom 2>/dev/null || true"
|
|
25043
|
+
prepublishOnly: "bun run typecheck && bun run test"
|
|
25014
25044
|
},
|
|
25015
25045
|
keywords: [
|
|
25016
25046
|
"skills",
|
|
@@ -25860,7 +25890,7 @@ var $getFlexibleChecksumsPlugin = getFlexibleChecksumsPlugin;
|
|
|
25860
25890
|
var $resolveFlexibleChecksumsConfig = resolveFlexibleChecksumsConfig;
|
|
25861
25891
|
|
|
25862
25892
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
|
|
25863
|
-
var
|
|
25893
|
+
var import_client25 = __toESM(require_client2(), 1);
|
|
25864
25894
|
|
|
25865
25895
|
// ../../node_modules/.bun/@aws-sdk+middleware-sdk-s3@3.972.75/node_modules/@aws-sdk/middleware-sdk-s3/dist-cjs/submodules/s3/index.js
|
|
25866
25896
|
var { NoOpLogger, getSmithyContext } = require_client();
|
|
@@ -26469,7 +26499,7 @@ var $resolveS3Config = resolveS3Config;
|
|
|
26469
26499
|
|
|
26470
26500
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
|
|
26471
26501
|
var import_core = __toESM(require_dist_cjs2(), 1);
|
|
26472
|
-
var
|
|
26502
|
+
var import_client26 = __toESM(require_client(), 1);
|
|
26473
26503
|
var import_config29 = __toESM(require_config(), 1);
|
|
26474
26504
|
var import_endpoints5 = __toESM(require_endpoints(), 1);
|
|
26475
26505
|
var import_event_streams2 = __toESM(require_event_streams(), 1);
|
|
@@ -26480,11 +26510,11 @@ var import_schema2 = __toESM(require_schema(), 1);
|
|
|
26480
26510
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthSchemeProvider.js
|
|
26481
26511
|
var import_httpAuthSchemes = __toESM(require_httpAuthSchemes(), 1);
|
|
26482
26512
|
var import_signature_v4_multi_region = __toESM(require_dist_cjs4(), 1);
|
|
26483
|
-
var
|
|
26513
|
+
var import_client4 = __toESM(require_client(), 1);
|
|
26484
26514
|
var import_endpoints3 = __toESM(require_endpoints(), 1);
|
|
26485
26515
|
|
|
26486
26516
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/endpoint/endpointResolver.js
|
|
26487
|
-
var
|
|
26517
|
+
var import_client3 = __toESM(require_client2(), 1);
|
|
26488
26518
|
var import_endpoints2 = __toESM(require_endpoints(), 1);
|
|
26489
26519
|
|
|
26490
26520
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/endpoint/bdd.js
|
|
@@ -28457,7 +28487,7 @@ var defaultEndpointResolver = (endpointParams, context = {}) => {
|
|
|
28457
28487
|
logger: context.logger
|
|
28458
28488
|
}));
|
|
28459
28489
|
};
|
|
28460
|
-
import_endpoints2.customEndpointFunctions.aws =
|
|
28490
|
+
import_endpoints2.customEndpointFunctions.aws = import_client3.awsEndpointFunctions;
|
|
28461
28491
|
|
|
28462
28492
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthSchemeProvider.js
|
|
28463
28493
|
var createEndpointRuleSetHttpAuthSchemeParametersProvider = (defaultHttpAuthSchemeParametersProvider) => async (config, context, input) => {
|
|
@@ -28465,7 +28495,7 @@ var createEndpointRuleSetHttpAuthSchemeParametersProvider = (defaultHttpAuthSche
|
|
|
28465
28495
|
throw new Error("Could not find `input` for `defaultEndpointRuleSetHttpAuthSchemeParametersProvider`");
|
|
28466
28496
|
}
|
|
28467
28497
|
const defaultParameters = await defaultHttpAuthSchemeParametersProvider(config, context, input);
|
|
28468
|
-
const instructionsFn =
|
|
28498
|
+
const instructionsFn = import_client4.getSmithyContext(context)?.commandInstance?.constructor?.getEndpointParameterInstructions;
|
|
28469
28499
|
if (!instructionsFn) {
|
|
28470
28500
|
throw new Error(`getEndpointParameterInstructions() is not defined on '${context.commandName}'`);
|
|
28471
28501
|
}
|
|
@@ -28474,8 +28504,8 @@ var createEndpointRuleSetHttpAuthSchemeParametersProvider = (defaultHttpAuthSche
|
|
|
28474
28504
|
};
|
|
28475
28505
|
var _defaultS3HttpAuthSchemeParametersProvider = async (config, context, input) => {
|
|
28476
28506
|
return {
|
|
28477
|
-
operation:
|
|
28478
|
-
region: await
|
|
28507
|
+
operation: import_client4.getSmithyContext(context).operation,
|
|
28508
|
+
region: await import_client4.normalizeProvider(config.region)() || (() => {
|
|
28479
28509
|
throw new Error("expected `region` to be configured for `aws.auth#sigv4`");
|
|
28480
28510
|
})()
|
|
28481
28511
|
};
|
|
@@ -28571,12 +28601,12 @@ var resolveHttpAuthSchemeConfig = (config) => {
|
|
|
28571
28601
|
const config_0 = import_httpAuthSchemes.resolveAwsSdkSigV4Config(config);
|
|
28572
28602
|
const config_1 = import_httpAuthSchemes.resolveAwsSdkSigV4AConfig(config_0);
|
|
28573
28603
|
return Object.assign(config_1, {
|
|
28574
|
-
authSchemePreference:
|
|
28604
|
+
authSchemePreference: import_client4.normalizeProvider(config.authSchemePreference ?? [])
|
|
28575
28605
|
});
|
|
28576
28606
|
};
|
|
28577
28607
|
|
|
28578
28608
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/commandBuilder.js
|
|
28579
|
-
var
|
|
28609
|
+
var import_client5 = __toESM(require_client(), 1);
|
|
28580
28610
|
var import_endpoints4 = __toESM(require_endpoints(), 1);
|
|
28581
28611
|
|
|
28582
28612
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/endpoint/EndpointParameters.js
|
|
@@ -28606,7 +28636,7 @@ var commonParams = {
|
|
|
28606
28636
|
};
|
|
28607
28637
|
|
|
28608
28638
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/commandBuilder.js
|
|
28609
|
-
var command =
|
|
28639
|
+
var command = import_client5.makeBuilder(commonParams, "AmazonS3", "S3Client", import_endpoints4.getEndpointPlugin);
|
|
28610
28640
|
var _ep0 = {
|
|
28611
28641
|
Bucket: { type: "contextParams", name: "Bucket" },
|
|
28612
28642
|
Key: { type: "contextParams", name: "Key" }
|
|
@@ -28641,8 +28671,8 @@ var _mw11 = (Command, cs, config, o2) => [
|
|
|
28641
28671
|
var import_schema = __toESM(require_schema(), 1);
|
|
28642
28672
|
|
|
28643
28673
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/models/S3ServiceException.js
|
|
28644
|
-
var
|
|
28645
|
-
class S3ServiceException extends
|
|
28674
|
+
var import_client6 = __toESM(require_client(), 1);
|
|
28675
|
+
class S3ServiceException extends import_client6.ServiceException {
|
|
28646
28676
|
constructor(options) {
|
|
28647
28677
|
super(options);
|
|
28648
28678
|
Object.setPrototypeOf(this, S3ServiceException.prototype);
|
|
@@ -34468,7 +34498,7 @@ var package_default2 = {
|
|
|
34468
34498
|
};
|
|
34469
34499
|
|
|
34470
34500
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
|
|
34471
|
-
var
|
|
34501
|
+
var import_client21 = __toESM(require_client2(), 1);
|
|
34472
34502
|
var import_httpAuthSchemes3 = __toESM(require_httpAuthSchemes(), 1);
|
|
34473
34503
|
|
|
34474
34504
|
// ../../node_modules/.bun/@aws-sdk+credential-provider-node@3.972.82/node_modules/@aws-sdk/credential-provider-node/dist-es/defaultProvider.js
|
|
@@ -34626,7 +34656,7 @@ var defaultProvider = (init = {}) => memoizeChain([
|
|
|
34626
34656
|
var credentialsTreatedAsExpired = (credentials) => credentials?.expiration !== undefined && credentials.expiration.getTime() - Date.now() < 300000;
|
|
34627
34657
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
|
|
34628
34658
|
var import_checksum2 = __toESM(require_checksum(), 1);
|
|
34629
|
-
var
|
|
34659
|
+
var import_client22 = __toESM(require_client(), 1);
|
|
34630
34660
|
var import_config28 = __toESM(require_config(), 1);
|
|
34631
34661
|
var import_event_streams = __toESM(require_event_streams(), 1);
|
|
34632
34662
|
var import_retry3 = __toESM(require_retry(), 1);
|
|
@@ -34866,7 +34896,7 @@ var $Sha1 = Sha1Node;
|
|
|
34866
34896
|
var import_httpAuthSchemes2 = __toESM(require_httpAuthSchemes(), 1);
|
|
34867
34897
|
var import_signature_v4_multi_region2 = __toESM(require_dist_cjs4(), 1);
|
|
34868
34898
|
var import_checksum = __toESM(require_checksum(), 1);
|
|
34869
|
-
var
|
|
34899
|
+
var import_client20 = __toESM(require_client(), 1);
|
|
34870
34900
|
var import_protocols4 = __toESM(require_protocols(), 1);
|
|
34871
34901
|
var import_serde3 = __toESM(require_serde(), 1);
|
|
34872
34902
|
var getRuntimeConfig2 = (config) => {
|
|
@@ -34891,7 +34921,7 @@ var getRuntimeConfig2 = (config) => {
|
|
|
34891
34921
|
signer: new import_httpAuthSchemes2.AwsSdkSigV4ASigner
|
|
34892
34922
|
}
|
|
34893
34923
|
],
|
|
34894
|
-
logger: config?.logger ?? new
|
|
34924
|
+
logger: config?.logger ?? new import_client20.NoOpLogger,
|
|
34895
34925
|
md5: config?.md5 ?? import_checksum.Md5,
|
|
34896
34926
|
protocol: config?.protocol ?? $S3RestXmlProtocol,
|
|
34897
34927
|
protocolSettings: config?.protocolSettings ?? {
|
|
@@ -34916,11 +34946,11 @@ var getRuntimeConfig2 = (config) => {
|
|
|
34916
34946
|
|
|
34917
34947
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeConfig.js
|
|
34918
34948
|
var getRuntimeConfig3 = (config) => {
|
|
34919
|
-
|
|
34949
|
+
import_client22.emitWarningIfUnsupportedVersion(process.version);
|
|
34920
34950
|
const defaultsMode = import_config28.resolveDefaultsModeConfig(config);
|
|
34921
|
-
const defaultConfigProvider = () => defaultsMode().then(
|
|
34951
|
+
const defaultConfigProvider = () => defaultsMode().then(import_client22.loadConfigsForDefaultMode);
|
|
34922
34952
|
const clientSharedValues = getRuntimeConfig2(config);
|
|
34923
|
-
|
|
34953
|
+
import_client21.emitWarningIfUnsupportedVersion(process.version);
|
|
34924
34954
|
const loaderConfig = {
|
|
34925
34955
|
profile: config?.profile,
|
|
34926
34956
|
logger: clientSharedValues.logger
|
|
@@ -34933,7 +34963,7 @@ var getRuntimeConfig3 = (config) => {
|
|
|
34933
34963
|
authSchemePreference: config?.authSchemePreference ?? import_config28.loadConfig(import_httpAuthSchemes3.NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, loaderConfig),
|
|
34934
34964
|
bodyLengthChecker: config?.bodyLengthChecker ?? import_serde4.calculateBodyLength,
|
|
34935
34965
|
credentialDefaultProvider: config?.credentialDefaultProvider ?? defaultProvider,
|
|
34936
|
-
defaultUserAgentProvider: config?.defaultUserAgentProvider ??
|
|
34966
|
+
defaultUserAgentProvider: config?.defaultUserAgentProvider ?? import_client21.createDefaultUserAgentProvider({ serviceId: clientSharedValues.serviceId, clientVersion: package_default2.version }),
|
|
34937
34967
|
disableS3ExpressSessionAuth: config?.disableS3ExpressSessionAuth ?? import_config28.loadConfig($NODE_DISABLE_S3_EXPRESS_SESSION_AUTH_OPTIONS, loaderConfig),
|
|
34938
34968
|
eventStreamSerdeProvider: config?.eventStreamSerdeProvider ?? import_event_streams.eventStreamSerdeProvider,
|
|
34939
34969
|
maxAttempts: config?.maxAttempts ?? import_config28.loadConfig(import_retry3.NODE_MAX_ATTEMPT_CONFIG_OPTIONS, config),
|
|
@@ -34951,13 +34981,13 @@ var getRuntimeConfig3 = (config) => {
|
|
|
34951
34981
|
useArnRegion: config?.useArnRegion ?? import_config28.loadConfig($NODE_USE_ARN_REGION_CONFIG_OPTIONS, loaderConfig),
|
|
34952
34982
|
useDualstackEndpoint: config?.useDualstackEndpoint ?? import_config28.loadConfig(import_config28.NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
34953
34983
|
useFipsEndpoint: config?.useFipsEndpoint ?? import_config28.loadConfig(import_config28.NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
34954
|
-
userAgentAppId: config?.userAgentAppId ?? import_config28.loadConfig(
|
|
34984
|
+
userAgentAppId: config?.userAgentAppId ?? import_config28.loadConfig(import_client21.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig)
|
|
34955
34985
|
};
|
|
34956
34986
|
};
|
|
34957
34987
|
|
|
34958
34988
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeExtensions.js
|
|
34959
|
-
var
|
|
34960
|
-
var
|
|
34989
|
+
var import_client23 = __toESM(require_client2(), 1);
|
|
34990
|
+
var import_client24 = __toESM(require_client(), 1);
|
|
34961
34991
|
var import_protocols5 = __toESM(require_protocols(), 1);
|
|
34962
34992
|
|
|
34963
34993
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/auth/httpAuthExtensionConfiguration.js
|
|
@@ -35001,24 +35031,24 @@ var resolveHttpAuthRuntimeConfig2 = (config) => {
|
|
|
35001
35031
|
|
|
35002
35032
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/runtimeExtensions.js
|
|
35003
35033
|
var resolveRuntimeExtensions2 = (runtimeConfig, extensions) => {
|
|
35004
|
-
const extensionConfiguration = Object.assign(
|
|
35034
|
+
const extensionConfiguration = Object.assign(import_client23.getAwsRegionExtensionConfiguration(runtimeConfig), import_client24.getDefaultExtensionConfiguration(runtimeConfig), import_protocols5.getHttpHandlerExtensionConfiguration(runtimeConfig), getHttpAuthExtensionConfiguration2(runtimeConfig));
|
|
35005
35035
|
extensions.forEach((extension) => extension.configure(extensionConfiguration));
|
|
35006
|
-
return Object.assign(runtimeConfig,
|
|
35036
|
+
return Object.assign(runtimeConfig, import_client23.resolveAwsRegionExtensionConfiguration(extensionConfiguration), import_client24.resolveDefaultRuntimeConfig(extensionConfiguration), import_protocols5.resolveHttpHandlerRuntimeConfig(extensionConfiguration), resolveHttpAuthRuntimeConfig2(extensionConfiguration));
|
|
35007
35037
|
};
|
|
35008
35038
|
|
|
35009
35039
|
// ../../node_modules/.bun/@aws-sdk+client-s3@3.1126.0/node_modules/@aws-sdk/client-s3/dist-es/S3Client.js
|
|
35010
|
-
class S3Client extends
|
|
35040
|
+
class S3Client extends import_client26.Client {
|
|
35011
35041
|
config;
|
|
35012
35042
|
constructor(...[configuration]) {
|
|
35013
35043
|
const _config_0 = getRuntimeConfig3(configuration || {});
|
|
35014
35044
|
super(_config_0);
|
|
35015
35045
|
this.initConfig = _config_0;
|
|
35016
35046
|
const _config_1 = resolveClientEndpointParameters(_config_0);
|
|
35017
|
-
const _config_2 =
|
|
35047
|
+
const _config_2 = import_client25.resolveUserAgentConfig(_config_1);
|
|
35018
35048
|
const _config_3 = $resolveFlexibleChecksumsConfig(_config_2);
|
|
35019
35049
|
const _config_4 = import_retry4.resolveRetryConfig(_config_3);
|
|
35020
35050
|
const _config_5 = import_config29.resolveRegionConfig(_config_4);
|
|
35021
|
-
const _config_6 =
|
|
35051
|
+
const _config_6 = import_client25.resolveHostHeaderConfig(_config_5);
|
|
35022
35052
|
const _config_7 = import_endpoints5.resolveEndpointConfig(_config_6);
|
|
35023
35053
|
const _config_8 = import_event_streams2.resolveEventStreamSerdeConfig(_config_7);
|
|
35024
35054
|
const _config_9 = resolveHttpAuthSchemeConfig(_config_8);
|
|
@@ -35026,12 +35056,12 @@ class S3Client extends import_client25.Client {
|
|
|
35026
35056
|
const _config_11 = resolveRuntimeExtensions2(_config_10, configuration?.extensions || []);
|
|
35027
35057
|
this.config = _config_11;
|
|
35028
35058
|
this.middlewareStack.use(import_schema2.getSchemaSerdePlugin(this.config));
|
|
35029
|
-
this.middlewareStack.use(
|
|
35059
|
+
this.middlewareStack.use(import_client25.getUserAgentPlugin(this.config));
|
|
35030
35060
|
this.middlewareStack.use(import_retry4.getRetryPlugin(this.config));
|
|
35031
35061
|
this.middlewareStack.use(import_protocols6.getContentLengthPlugin(this.config));
|
|
35032
|
-
this.middlewareStack.use(
|
|
35033
|
-
this.middlewareStack.use(
|
|
35034
|
-
this.middlewareStack.use(
|
|
35062
|
+
this.middlewareStack.use(import_client25.getHostHeaderPlugin(this.config));
|
|
35063
|
+
this.middlewareStack.use(import_client25.getLoggerPlugin(this.config));
|
|
35064
|
+
this.middlewareStack.use(import_client25.getRecursionDetectionPlugin(this.config));
|
|
35035
35065
|
this.middlewareStack.use(import_core.getHttpAuthSchemeEndpointRuleSetPlugin(this.config, {
|
|
35036
35066
|
httpAuthSchemeParametersProvider: defaultS3HttpAuthSchemeParametersProvider,
|
|
35037
35067
|
identityProviderConfigProvider: async (config) => new import_core.DefaultIdentityProviderConfig({
|
|
@@ -37821,7 +37851,7 @@ var BRACE_SOURCE_EXCLUSION = new RegExp(`^!skills/\\{(${SLUG}(?:,${SLUG})+)\\}/s
|
|
|
37821
37851
|
var SINGLE_SOURCE_EXCLUSION = new RegExp(`^!skills/(${SLUG})/src$`);
|
|
37822
37852
|
|
|
37823
37853
|
// src/lib/skill-validation.ts
|
|
37824
|
-
import { existsSync as existsSync5, lstatSync, readFileSync as readFileSync7, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
37854
|
+
import { existsSync as existsSync5, lstatSync as lstatSync2, readFileSync as readFileSync7, readdirSync as readdirSync5, statSync as statSync4 } from "fs";
|
|
37825
37855
|
import { isAbsolute as isAbsolute3, join as join10, normalize } from "path";
|
|
37826
37856
|
var VALID_SKILL_KINDS = ["executable", "instruction"];
|
|
37827
37857
|
var DOC_FILES = ["SKILL.md", "README.md", "CLAUDE.md"];
|
|
@@ -37902,6 +37932,16 @@ function isHostedMetadataSkill(skillName, frontmatter, registryMeta, packageDecl
|
|
|
37902
37932
|
return true;
|
|
37903
37933
|
return false;
|
|
37904
37934
|
}
|
|
37935
|
+
function frontmatterString(raw) {
|
|
37936
|
+
if (raw.startsWith('"') && raw.endsWith('"')) {
|
|
37937
|
+
try {
|
|
37938
|
+
const decoded = JSON.parse(raw);
|
|
37939
|
+
if (typeof decoded === "string")
|
|
37940
|
+
return decoded;
|
|
37941
|
+
} catch {}
|
|
37942
|
+
}
|
|
37943
|
+
return raw.replace(/^["']|["']$/g, "");
|
|
37944
|
+
}
|
|
37905
37945
|
function parseSkillFrontmatter(content) {
|
|
37906
37946
|
const match = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
37907
37947
|
if (!match)
|
|
@@ -37921,12 +37961,12 @@ function parseSkillFrontmatter(content) {
|
|
|
37921
37961
|
const tags = [];
|
|
37922
37962
|
while (i3 + 1 < lines.length && /^\s+-\s+/.test(lines[i3 + 1])) {
|
|
37923
37963
|
i3++;
|
|
37924
|
-
tags.push(lines[i3].replace(/^\s+-\s+/, "").trim());
|
|
37964
|
+
tags.push(frontmatterString(lines[i3].replace(/^\s+-\s+/, "").trim()));
|
|
37925
37965
|
}
|
|
37926
37966
|
result.tags = tags;
|
|
37927
37967
|
continue;
|
|
37928
37968
|
}
|
|
37929
|
-
const value = rawValue
|
|
37969
|
+
const value = frontmatterString(rawValue);
|
|
37930
37970
|
if (!value)
|
|
37931
37971
|
continue;
|
|
37932
37972
|
if (key === "name")
|
|
@@ -37979,7 +38019,7 @@ function validateSkillDirectory(name, skillPath, registryMeta) {
|
|
|
37979
38019
|
if (RESERVED_SKILL_ENTRIES.has(entry)) {
|
|
37980
38020
|
add(issues, "skill.reserved_file", `Reserved file '${entry}' is not allowed in skill packages`);
|
|
37981
38021
|
}
|
|
37982
|
-
if (
|
|
38022
|
+
if (lstatSync2(entryPath).isSymbolicLink()) {
|
|
37983
38023
|
add(issues, "skill.symlink_forbidden", `Symlink '${entry}' is not allowed in skill packages`);
|
|
37984
38024
|
}
|
|
37985
38025
|
if (!KNOWN_TOP_LEVEL_ENTRIES.has(entry)) {
|
|
@@ -38461,7 +38501,7 @@ function validateRuntimeContract(manifest, issues, strict) {
|
|
|
38461
38501
|
import {
|
|
38462
38502
|
cpSync,
|
|
38463
38503
|
existsSync as existsSync7,
|
|
38464
|
-
lstatSync as
|
|
38504
|
+
lstatSync as lstatSync3,
|
|
38465
38505
|
mkdirSync as mkdirSync4,
|
|
38466
38506
|
readFileSync as readFileSync9,
|
|
38467
38507
|
realpathSync,
|
|
@@ -38559,8 +38599,8 @@ function createInstructionManifest(name, options) {
|
|
|
38559
38599
|
description: options.description,
|
|
38560
38600
|
version: PORTABLE_SKILL_DEFAULT_VERSION,
|
|
38561
38601
|
displayName: displayName(name),
|
|
38562
|
-
category: "Development Tools",
|
|
38563
|
-
tags: ["custom", name],
|
|
38602
|
+
category: options.category ?? "Development Tools",
|
|
38603
|
+
tags: options.tags ?? ["custom", name],
|
|
38564
38604
|
kind: "instruction",
|
|
38565
38605
|
inputs: [],
|
|
38566
38606
|
commands: [],
|
|
@@ -38575,16 +38615,16 @@ function writeInstructionSkillTemplate(skillPath, manifest) {
|
|
|
38575
38615
|
}
|
|
38576
38616
|
function renderInstructionSkillMd(manifest) {
|
|
38577
38617
|
const tags = manifest.tags?.length ? `tags:
|
|
38578
|
-
${manifest.tags.map((tag) => ` - ${tag}`).join(`
|
|
38618
|
+
${manifest.tags.map((tag) => ` - ${yamlString(tag)}`).join(`
|
|
38579
38619
|
`)}
|
|
38580
38620
|
` : "";
|
|
38581
38621
|
return `---
|
|
38582
38622
|
name: ${manifest.name}
|
|
38583
|
-
description: ${manifest.description}
|
|
38623
|
+
description: ${yamlString(manifest.description)}
|
|
38584
38624
|
kind: instruction
|
|
38585
38625
|
version: ${manifest.version}
|
|
38586
38626
|
source: custom
|
|
38587
|
-
category: ${manifest.category ?? "Development Tools"}
|
|
38627
|
+
category: ${yamlString(manifest.category ?? "Development Tools")}
|
|
38588
38628
|
${tags}---
|
|
38589
38629
|
|
|
38590
38630
|
# ${manifest.displayName ?? displayName(manifest.name)}
|
|
@@ -38605,8 +38645,8 @@ function createPortableManifest(name, options) {
|
|
|
38605
38645
|
description: options.description,
|
|
38606
38646
|
version: PORTABLE_SKILL_DEFAULT_VERSION,
|
|
38607
38647
|
displayName: displayName(name),
|
|
38608
|
-
category: "Development Tools",
|
|
38609
|
-
tags: ["custom", name],
|
|
38648
|
+
category: options.category ?? "Development Tools",
|
|
38649
|
+
tags: options.tags ?? ["custom", name],
|
|
38610
38650
|
inputs: DEFAULT_INPUTS,
|
|
38611
38651
|
commands: [{
|
|
38612
38652
|
name,
|
|
@@ -38769,7 +38809,7 @@ function ensureInstructionSkillFiles(skillPath, manifest) {
|
|
|
38769
38809
|
return readPortableSkillManifest(skillPath, next.name);
|
|
38770
38810
|
}
|
|
38771
38811
|
function copySkillDirectory(source, destination) {
|
|
38772
|
-
const resolvedSource =
|
|
38812
|
+
const resolvedSource = lstatSync3(source).isSymbolicLink() ? realpathSync(source) : source;
|
|
38773
38813
|
mkdirSync4(destination, { recursive: true });
|
|
38774
38814
|
cpSync(resolvedSource, destination, {
|
|
38775
38815
|
recursive: true,
|
|
@@ -38782,7 +38822,7 @@ function copySkillDirectory(source, destination) {
|
|
|
38782
38822
|
if (isExcludedCopyEntry(segments[i3], i3 === 0))
|
|
38783
38823
|
return false;
|
|
38784
38824
|
}
|
|
38785
|
-
if (
|
|
38825
|
+
if (lstatSync3(src).isSymbolicLink())
|
|
38786
38826
|
return false;
|
|
38787
38827
|
return true;
|
|
38788
38828
|
}
|
|
@@ -38797,10 +38837,13 @@ function isExcludedCopyEntry(name, isFirstSegment) {
|
|
|
38797
38837
|
return true;
|
|
38798
38838
|
return false;
|
|
38799
38839
|
}
|
|
38840
|
+
function yamlString(value) {
|
|
38841
|
+
return JSON.stringify(value);
|
|
38842
|
+
}
|
|
38800
38843
|
function renderSkillMd(manifest) {
|
|
38801
38844
|
return `---
|
|
38802
38845
|
name: ${manifest.name}
|
|
38803
|
-
description: ${manifest.description}
|
|
38846
|
+
description: ${yamlString(manifest.description)}
|
|
38804
38847
|
---
|
|
38805
38848
|
|
|
38806
38849
|
# ${manifest.displayName ?? displayName(manifest.name)}
|
|
@@ -39183,11 +39226,11 @@ function scaffoldPortableSkill(name, options = {}) {
|
|
|
39183
39226
|
const kind = options.kind ?? "executable";
|
|
39184
39227
|
const description = options.description ?? `${displayName(skillName)} skill`;
|
|
39185
39228
|
if (kind === "instruction") {
|
|
39186
|
-
const manifest2 = createInstructionManifest(skillName, { description });
|
|
39229
|
+
const manifest2 = createInstructionManifest(skillName, { description, category: options.category, tags: options.tags });
|
|
39187
39230
|
writeInstructionSkillTemplate(skillPath, manifest2);
|
|
39188
39231
|
return { name: skillName, path: skillPath, manifest: manifest2, created: true };
|
|
39189
39232
|
}
|
|
39190
|
-
const manifest = createPortableManifest(skillName, { description });
|
|
39233
|
+
const manifest = createPortableManifest(skillName, { description, category: options.category, tags: options.tags });
|
|
39191
39234
|
writePortableSkillTemplate(skillPath, manifest);
|
|
39192
39235
|
return { name: skillName, path: skillPath, manifest, created: true };
|
|
39193
39236
|
}
|
|
@@ -47844,9 +47887,9 @@ function createReceiptService(store) {
|
|
|
47844
47887
|
import { createHash as createHash11 } from "crypto";
|
|
47845
47888
|
|
|
47846
47889
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/ECSClient.js
|
|
47847
|
-
var
|
|
47890
|
+
var import_client35 = __toESM(require_client2(), 1);
|
|
47848
47891
|
var import_core2 = __toESM(require_dist_cjs2(), 1);
|
|
47849
|
-
var
|
|
47892
|
+
var import_client36 = __toESM(require_client(), 1);
|
|
47850
47893
|
var import_config39 = __toESM(require_config(), 1);
|
|
47851
47894
|
var import_endpoints8 = __toESM(require_endpoints(), 1);
|
|
47852
47895
|
var import_protocols10 = __toESM(require_protocols(), 1);
|
|
@@ -47855,11 +47898,11 @@ var import_schema4 = __toESM(require_schema(), 1);
|
|
|
47855
47898
|
|
|
47856
47899
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/auth/httpAuthSchemeProvider.js
|
|
47857
47900
|
var import_httpAuthSchemes4 = __toESM(require_httpAuthSchemes(), 1);
|
|
47858
|
-
var
|
|
47901
|
+
var import_client27 = __toESM(require_client(), 1);
|
|
47859
47902
|
var defaultECSHttpAuthSchemeParametersProvider = async (config, context, input) => {
|
|
47860
47903
|
return {
|
|
47861
|
-
operation:
|
|
47862
|
-
region: await
|
|
47904
|
+
operation: import_client27.getSmithyContext(context).operation,
|
|
47905
|
+
region: await import_client27.normalizeProvider(config.region)() || (() => {
|
|
47863
47906
|
throw new Error("expected `region` to be configured for `aws.auth#sigv4`");
|
|
47864
47907
|
})()
|
|
47865
47908
|
};
|
|
@@ -47891,7 +47934,7 @@ var defaultECSHttpAuthSchemeProvider = (authParameters) => {
|
|
|
47891
47934
|
var resolveHttpAuthSchemeConfig3 = (config) => {
|
|
47892
47935
|
const config_0 = import_httpAuthSchemes4.resolveAwsSdkSigV4Config(config);
|
|
47893
47936
|
return Object.assign(config_0, {
|
|
47894
|
-
authSchemePreference:
|
|
47937
|
+
authSchemePreference: import_client27.normalizeProvider(config.authSchemePreference ?? [])
|
|
47895
47938
|
});
|
|
47896
47939
|
};
|
|
47897
47940
|
|
|
@@ -47983,9 +48026,9 @@ var package_default3 = {
|
|
|
47983
48026
|
};
|
|
47984
48027
|
|
|
47985
48028
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/runtimeConfig.js
|
|
47986
|
-
var
|
|
48029
|
+
var import_client31 = __toESM(require_client2(), 1);
|
|
47987
48030
|
var import_httpAuthSchemes6 = __toESM(require_httpAuthSchemes(), 1);
|
|
47988
|
-
var
|
|
48031
|
+
var import_client32 = __toESM(require_client(), 1);
|
|
47989
48032
|
var import_config38 = __toESM(require_config(), 1);
|
|
47990
48033
|
var import_retry5 = __toESM(require_retry(), 1);
|
|
47991
48034
|
var import_serde6 = __toESM(require_serde(), 1);
|
|
@@ -47995,12 +48038,12 @@ var import_node_http_handler3 = __toESM(require_dist_cjs6(), 1);
|
|
|
47995
48038
|
var import_httpAuthSchemes5 = __toESM(require_httpAuthSchemes(), 1);
|
|
47996
48039
|
var import_protocols7 = __toESM(require_protocols2(), 1);
|
|
47997
48040
|
var import_checksum3 = __toESM(require_checksum(), 1);
|
|
47998
|
-
var
|
|
48041
|
+
var import_client30 = __toESM(require_client(), 1);
|
|
47999
48042
|
var import_protocols8 = __toESM(require_protocols(), 1);
|
|
48000
48043
|
var import_serde5 = __toESM(require_serde(), 1);
|
|
48001
48044
|
|
|
48002
48045
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/endpoint/endpointResolver.js
|
|
48003
|
-
var
|
|
48046
|
+
var import_client28 = __toESM(require_client2(), 1);
|
|
48004
48047
|
var import_endpoints7 = __toESM(require_endpoints(), 1);
|
|
48005
48048
|
|
|
48006
48049
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/endpoint/bdd.js
|
|
@@ -48097,14 +48140,14 @@ var defaultEndpointResolver3 = (endpointParams, context = {}) => {
|
|
|
48097
48140
|
logger: context.logger
|
|
48098
48141
|
}));
|
|
48099
48142
|
};
|
|
48100
|
-
import_endpoints7.customEndpointFunctions.aws =
|
|
48143
|
+
import_endpoints7.customEndpointFunctions.aws = import_client28.awsEndpointFunctions;
|
|
48101
48144
|
|
|
48102
48145
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/schemas/schemas_0.js
|
|
48103
48146
|
var import_schema3 = __toESM(require_schema(), 1);
|
|
48104
48147
|
|
|
48105
48148
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/models/ECSServiceException.js
|
|
48106
|
-
var
|
|
48107
|
-
class ECSServiceException extends
|
|
48149
|
+
var import_client29 = __toESM(require_client(), 1);
|
|
48150
|
+
class ECSServiceException extends import_client29.ServiceException {
|
|
48108
48151
|
constructor(options) {
|
|
48109
48152
|
super(options);
|
|
48110
48153
|
Object.setPrototypeOf(this, ECSServiceException.prototype);
|
|
@@ -50908,7 +50951,7 @@ var getRuntimeConfig4 = (config) => {
|
|
|
50908
50951
|
signer: new import_httpAuthSchemes5.AwsSdkSigV4Signer
|
|
50909
50952
|
}
|
|
50910
50953
|
],
|
|
50911
|
-
logger: config?.logger ?? new
|
|
50954
|
+
logger: config?.logger ?? new import_client30.NoOpLogger,
|
|
50912
50955
|
protocol: config?.protocol ?? import_protocols7.AwsJson1_1Protocol,
|
|
50913
50956
|
protocolSettings: config?.protocolSettings ?? {
|
|
50914
50957
|
defaultNamespace: "com.amazonaws.ecs",
|
|
@@ -50927,11 +50970,11 @@ var getRuntimeConfig4 = (config) => {
|
|
|
50927
50970
|
|
|
50928
50971
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/runtimeConfig.js
|
|
50929
50972
|
var getRuntimeConfig5 = (config) => {
|
|
50930
|
-
|
|
50973
|
+
import_client32.emitWarningIfUnsupportedVersion(process.version);
|
|
50931
50974
|
const defaultsMode = import_config38.resolveDefaultsModeConfig(config);
|
|
50932
|
-
const defaultConfigProvider = () => defaultsMode().then(
|
|
50975
|
+
const defaultConfigProvider = () => defaultsMode().then(import_client32.loadConfigsForDefaultMode);
|
|
50933
50976
|
const clientSharedValues = getRuntimeConfig4(config);
|
|
50934
|
-
|
|
50977
|
+
import_client31.emitWarningIfUnsupportedVersion(process.version);
|
|
50935
50978
|
const loaderConfig = {
|
|
50936
50979
|
profile: config?.profile,
|
|
50937
50980
|
logger: clientSharedValues.logger
|
|
@@ -50944,7 +50987,7 @@ var getRuntimeConfig5 = (config) => {
|
|
|
50944
50987
|
authSchemePreference: config?.authSchemePreference ?? import_config38.loadConfig(import_httpAuthSchemes6.NODE_AUTH_SCHEME_PREFERENCE_OPTIONS, loaderConfig),
|
|
50945
50988
|
bodyLengthChecker: config?.bodyLengthChecker ?? import_serde6.calculateBodyLength,
|
|
50946
50989
|
credentialDefaultProvider: config?.credentialDefaultProvider ?? defaultProvider,
|
|
50947
|
-
defaultUserAgentProvider: config?.defaultUserAgentProvider ??
|
|
50990
|
+
defaultUserAgentProvider: config?.defaultUserAgentProvider ?? import_client31.createDefaultUserAgentProvider({ serviceId: clientSharedValues.serviceId, clientVersion: package_default3.version }),
|
|
50948
50991
|
maxAttempts: config?.maxAttempts ?? import_config38.loadConfig(import_retry5.NODE_MAX_ATTEMPT_CONFIG_OPTIONS, config),
|
|
50949
50992
|
region: config?.region ?? import_config38.loadConfig(import_config38.NODE_REGION_CONFIG_OPTIONS, { ...import_config38.NODE_REGION_CONFIG_FILE_OPTIONS, ...loaderConfig }),
|
|
50950
50993
|
requestHandler: import_node_http_handler3.NodeHttpHandler.create(config?.requestHandler ?? defaultConfigProvider),
|
|
@@ -50955,13 +50998,13 @@ var getRuntimeConfig5 = (config) => {
|
|
|
50955
50998
|
streamCollector: config?.streamCollector ?? import_node_http_handler3.streamCollector,
|
|
50956
50999
|
useDualstackEndpoint: config?.useDualstackEndpoint ?? import_config38.loadConfig(import_config38.NODE_USE_DUALSTACK_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
50957
51000
|
useFipsEndpoint: config?.useFipsEndpoint ?? import_config38.loadConfig(import_config38.NODE_USE_FIPS_ENDPOINT_CONFIG_OPTIONS, loaderConfig),
|
|
50958
|
-
userAgentAppId: config?.userAgentAppId ?? import_config38.loadConfig(
|
|
51001
|
+
userAgentAppId: config?.userAgentAppId ?? import_config38.loadConfig(import_client31.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig)
|
|
50959
51002
|
};
|
|
50960
51003
|
};
|
|
50961
51004
|
|
|
50962
51005
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/runtimeExtensions.js
|
|
50963
|
-
var
|
|
50964
|
-
var
|
|
51006
|
+
var import_client33 = __toESM(require_client2(), 1);
|
|
51007
|
+
var import_client34 = __toESM(require_client(), 1);
|
|
50965
51008
|
var import_protocols9 = __toESM(require_protocols(), 1);
|
|
50966
51009
|
|
|
50967
51010
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/auth/httpAuthExtensionConfiguration.js
|
|
@@ -51005,34 +51048,34 @@ var resolveHttpAuthRuntimeConfig3 = (config) => {
|
|
|
51005
51048
|
|
|
51006
51049
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/runtimeExtensions.js
|
|
51007
51050
|
var resolveRuntimeExtensions3 = (runtimeConfig, extensions) => {
|
|
51008
|
-
const extensionConfiguration = Object.assign(
|
|
51051
|
+
const extensionConfiguration = Object.assign(import_client33.getAwsRegionExtensionConfiguration(runtimeConfig), import_client34.getDefaultExtensionConfiguration(runtimeConfig), import_protocols9.getHttpHandlerExtensionConfiguration(runtimeConfig), getHttpAuthExtensionConfiguration3(runtimeConfig));
|
|
51009
51052
|
extensions.forEach((extension) => extension.configure(extensionConfiguration));
|
|
51010
|
-
return Object.assign(runtimeConfig,
|
|
51053
|
+
return Object.assign(runtimeConfig, import_client33.resolveAwsRegionExtensionConfiguration(extensionConfiguration), import_client34.resolveDefaultRuntimeConfig(extensionConfiguration), import_protocols9.resolveHttpHandlerRuntimeConfig(extensionConfiguration), resolveHttpAuthRuntimeConfig3(extensionConfiguration));
|
|
51011
51054
|
};
|
|
51012
51055
|
|
|
51013
51056
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/ECSClient.js
|
|
51014
|
-
class ECSClient extends
|
|
51057
|
+
class ECSClient extends import_client36.Client {
|
|
51015
51058
|
config;
|
|
51016
51059
|
constructor(...[configuration]) {
|
|
51017
51060
|
const _config_0 = getRuntimeConfig5(configuration || {});
|
|
51018
51061
|
super(_config_0);
|
|
51019
51062
|
this.initConfig = _config_0;
|
|
51020
51063
|
const _config_1 = resolveClientEndpointParameters3(_config_0);
|
|
51021
|
-
const _config_2 =
|
|
51064
|
+
const _config_2 = import_client35.resolveUserAgentConfig(_config_1);
|
|
51022
51065
|
const _config_3 = import_retry6.resolveRetryConfig(_config_2);
|
|
51023
51066
|
const _config_4 = import_config39.resolveRegionConfig(_config_3);
|
|
51024
|
-
const _config_5 =
|
|
51067
|
+
const _config_5 = import_client35.resolveHostHeaderConfig(_config_4);
|
|
51025
51068
|
const _config_6 = import_endpoints8.resolveEndpointConfig(_config_5);
|
|
51026
51069
|
const _config_7 = resolveHttpAuthSchemeConfig3(_config_6);
|
|
51027
51070
|
const _config_8 = resolveRuntimeExtensions3(_config_7, configuration?.extensions || []);
|
|
51028
51071
|
this.config = _config_8;
|
|
51029
51072
|
this.middlewareStack.use(import_schema4.getSchemaSerdePlugin(this.config));
|
|
51030
|
-
this.middlewareStack.use(
|
|
51073
|
+
this.middlewareStack.use(import_client35.getUserAgentPlugin(this.config));
|
|
51031
51074
|
this.middlewareStack.use(import_retry6.getRetryPlugin(this.config));
|
|
51032
51075
|
this.middlewareStack.use(import_protocols10.getContentLengthPlugin(this.config));
|
|
51033
|
-
this.middlewareStack.use(
|
|
51034
|
-
this.middlewareStack.use(
|
|
51035
|
-
this.middlewareStack.use(
|
|
51076
|
+
this.middlewareStack.use(import_client35.getHostHeaderPlugin(this.config));
|
|
51077
|
+
this.middlewareStack.use(import_client35.getLoggerPlugin(this.config));
|
|
51078
|
+
this.middlewareStack.use(import_client35.getRecursionDetectionPlugin(this.config));
|
|
51036
51079
|
this.middlewareStack.use(import_core2.getHttpAuthSchemeEndpointRuleSetPlugin(this.config, {
|
|
51037
51080
|
httpAuthSchemeParametersProvider: defaultECSHttpAuthSchemeParametersProvider,
|
|
51038
51081
|
identityProviderConfigProvider: async (config) => new import_core2.DefaultIdentityProviderConfig({
|
|
@@ -51047,9 +51090,9 @@ class ECSClient extends import_client35.Client {
|
|
|
51047
51090
|
}
|
|
51048
51091
|
|
|
51049
51092
|
// ../../node_modules/.bun/@aws-sdk+client-ecs@3.1126.0/node_modules/@aws-sdk/client-ecs/dist-es/commandBuilder.js
|
|
51050
|
-
var
|
|
51093
|
+
var import_client37 = __toESM(require_client(), 1);
|
|
51051
51094
|
var import_endpoints9 = __toESM(require_endpoints(), 1);
|
|
51052
|
-
var command3 =
|
|
51095
|
+
var command3 = import_client37.makeBuilder(commonParams3, "AmazonEC2ContainerServiceV20141113", "ECSClient", import_endpoints9.getEndpointPlugin);
|
|
51053
51096
|
var _ep03 = {};
|
|
51054
51097
|
var _mw03 = (Command, cs, config, o2) => [];
|
|
51055
51098
|
|
|
@@ -51603,6 +51646,733 @@ function createOfflineGate(options) {
|
|
|
51603
51646
|
}
|
|
51604
51647
|
};
|
|
51605
51648
|
}
|
|
51649
|
+
// src/lib/auth-store.ts
|
|
51650
|
+
function getApiUrl(action, env = process.env, options = {}) {
|
|
51651
|
+
return requireSkillsApiOrigin(action, env, options);
|
|
51652
|
+
}
|
|
51653
|
+
|
|
51654
|
+
// src/lib/remote-account.ts
|
|
51655
|
+
class RemoteCreditApprovalError extends Error {
|
|
51656
|
+
requiredCredits;
|
|
51657
|
+
maximumCredits;
|
|
51658
|
+
code = "CREDIT_APPROVAL_REQUIRED";
|
|
51659
|
+
constructor(requiredCredits, maximumCredits) {
|
|
51660
|
+
super(`This run requires ${requiredCredits} credits; the approved maximum is ${maximumCredits}. Quote the run and explicitly approve its cost.`);
|
|
51661
|
+
this.requiredCredits = requiredCredits;
|
|
51662
|
+
this.maximumCredits = maximumCredits;
|
|
51663
|
+
this.name = "RemoteCreditApprovalError";
|
|
51664
|
+
}
|
|
51665
|
+
}
|
|
51666
|
+
function creditCount(value) {
|
|
51667
|
+
if (typeof value !== "number" || !Number.isSafeInteger(value) || value < 0 || value > 2147483647) {
|
|
51668
|
+
throw new Error("The Skills server returned an invalid credit count");
|
|
51669
|
+
}
|
|
51670
|
+
return value;
|
|
51671
|
+
}
|
|
51672
|
+
function parseRemoteRunQuote(value) {
|
|
51673
|
+
const quote = object(value);
|
|
51674
|
+
const pricing = object(quote.pricing);
|
|
51675
|
+
if (typeof quote.skill !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(quote.skill))
|
|
51676
|
+
throw new Error("Invalid quoted skill");
|
|
51677
|
+
const costCents = creditCount(pricing.costCredits ?? pricing.costCents);
|
|
51678
|
+
if (pricing.costCredits !== undefined && pricing.costCents !== undefined && pricing.costCents !== costCents)
|
|
51679
|
+
throw new Error("Inconsistent quoted credit count");
|
|
51680
|
+
if (quote.availability && object(quote.availability).status !== "available")
|
|
51681
|
+
throw new Error("This skill is unavailable for remote execution");
|
|
51682
|
+
return { ...quote, skill: quote.skill, pricing: { ...pricing, costCredits: costCents, costCents, formattedCost: `${costCents} credits` } };
|
|
51683
|
+
}
|
|
51684
|
+
function parseRemoteCreditPacks(value) {
|
|
51685
|
+
if (!Array.isArray(value))
|
|
51686
|
+
throw new Error("Invalid credit pack response");
|
|
51687
|
+
const ids = new Set;
|
|
51688
|
+
return value.map((value2) => {
|
|
51689
|
+
const row = object(value2);
|
|
51690
|
+
const counts = [row.credits, row.creditsCents, row.amountCents].filter((value3) => value3 !== undefined).map(creditCount);
|
|
51691
|
+
if (!counts.length || counts[0] === 0 || counts.some((count) => count !== counts[0]))
|
|
51692
|
+
throw new Error("Inconsistent credit pack counts");
|
|
51693
|
+
const credits = counts[0];
|
|
51694
|
+
const id = row.id ?? `credits_${credits}`;
|
|
51695
|
+
if (typeof id !== "string" || !/^[a-z0-9][a-z0-9_-]{0,99}$/.test(id) || ids.has(id))
|
|
51696
|
+
throw new Error("Invalid credit pack ID");
|
|
51697
|
+
if (id.startsWith("credits_") && id !== `credits_${credits}`)
|
|
51698
|
+
throw new Error("Inconsistent credit pack ID");
|
|
51699
|
+
ids.add(id);
|
|
51700
|
+
return { id, credits, ...row.expiresInDays === undefined ? {} : { expiresInDays: creditCount(row.expiresInDays) } };
|
|
51701
|
+
});
|
|
51702
|
+
}
|
|
51703
|
+
function parseRemoteBillingStatus(value) {
|
|
51704
|
+
const row = object(value);
|
|
51705
|
+
const counts = [row.creditBalance, row.balanceCents].filter((value2) => value2 !== undefined).map(creditCount);
|
|
51706
|
+
if (!counts.length || counts.some((count) => count !== counts[0]))
|
|
51707
|
+
throw new Error("Inconsistent credit balance");
|
|
51708
|
+
return {
|
|
51709
|
+
creditBalance: counts[0],
|
|
51710
|
+
formattedCreditBalance: `${counts[0]} credits`,
|
|
51711
|
+
...typeof row.plan === "string" ? { plan: row.plan } : {},
|
|
51712
|
+
...typeof row.hasPaymentMethod === "boolean" ? { hasPaymentMethod: row.hasPaymentMethod } : {}
|
|
51713
|
+
};
|
|
51714
|
+
}
|
|
51715
|
+
function parseRemoteCheckout(value) {
|
|
51716
|
+
const row = object(value);
|
|
51717
|
+
if (typeof row.url !== "string")
|
|
51718
|
+
throw new Error("Invalid checkout URL");
|
|
51719
|
+
const url = new URL(row.url);
|
|
51720
|
+
if (url.protocol !== "https:" || url.username || url.password)
|
|
51721
|
+
throw new Error("Invalid checkout URL");
|
|
51722
|
+
return { url: row.url };
|
|
51723
|
+
}
|
|
51724
|
+
function object(value) {
|
|
51725
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
51726
|
+
throw new Error("Invalid Skills server response");
|
|
51727
|
+
return value;
|
|
51728
|
+
}
|
|
51729
|
+
|
|
51730
|
+
// src/lib/remote-files.ts
|
|
51731
|
+
import { createHash as createHash12 } from "crypto";
|
|
51732
|
+
var MAX_REMOTE_FILE_BYTES = 64 * 1024 * 1024;
|
|
51733
|
+
function describeRemoteFiles(files) {
|
|
51734
|
+
if (files.length > 10)
|
|
51735
|
+
throw new Error("At most 10 input files are supported");
|
|
51736
|
+
const names = new Set;
|
|
51737
|
+
let total = 0;
|
|
51738
|
+
return files.map((file) => {
|
|
51739
|
+
if (!/^[A-Za-z0-9][A-Za-z0-9._-]{0,199}$/.test(file.name) || file.name === "." || file.name === ".." || names.has(file.name))
|
|
51740
|
+
throw new Error("Input file names must be unique safe basenames");
|
|
51741
|
+
names.add(file.name);
|
|
51742
|
+
total += file.bytes.byteLength;
|
|
51743
|
+
if (file.bytes.byteLength > 20 * 1024 * 1024 || total > 50 * 1024 * 1024)
|
|
51744
|
+
throw new Error("Input files exceed the supported size limit");
|
|
51745
|
+
return { name: file.name, sizeBytes: file.bytes.byteLength, sha256: sha256(file.bytes), contentType: file.contentType ?? "application/octet-stream" };
|
|
51746
|
+
});
|
|
51747
|
+
}
|
|
51748
|
+
function sha256(bytes) {
|
|
51749
|
+
return createHash12("sha256").update(bytes).digest("hex");
|
|
51750
|
+
}
|
|
51751
|
+
async function readBoundedResponse(response, maximum) {
|
|
51752
|
+
if (!Number.isSafeInteger(maximum) || maximum < 0 || maximum > MAX_REMOTE_FILE_BYTES)
|
|
51753
|
+
throw new Error("Invalid artifact size limit");
|
|
51754
|
+
const length = response.headers.get("content-length");
|
|
51755
|
+
if (length && (!/^\d+$/.test(length) || Number(length) > maximum)) {
|
|
51756
|
+
await response.body?.cancel();
|
|
51757
|
+
throw new Error("Artifact exceeds its declared size limit");
|
|
51758
|
+
}
|
|
51759
|
+
const reader = response.body?.getReader();
|
|
51760
|
+
if (!reader)
|
|
51761
|
+
return new Uint8Array;
|
|
51762
|
+
const chunks = [];
|
|
51763
|
+
let size = 0;
|
|
51764
|
+
try {
|
|
51765
|
+
while (true) {
|
|
51766
|
+
const next = await reader.read();
|
|
51767
|
+
if (next.done)
|
|
51768
|
+
break;
|
|
51769
|
+
size += next.value.byteLength;
|
|
51770
|
+
if (size > maximum)
|
|
51771
|
+
throw new Error("Artifact exceeds its declared size limit");
|
|
51772
|
+
chunks.push(next.value);
|
|
51773
|
+
}
|
|
51774
|
+
} catch (error) {
|
|
51775
|
+
await reader.cancel().catch(() => {});
|
|
51776
|
+
throw error;
|
|
51777
|
+
} finally {
|
|
51778
|
+
reader.releaseLock();
|
|
51779
|
+
}
|
|
51780
|
+
const bytes = new Uint8Array(size);
|
|
51781
|
+
let offset = 0;
|
|
51782
|
+
for (const chunk of chunks) {
|
|
51783
|
+
bytes.set(chunk, offset);
|
|
51784
|
+
offset += chunk.byteLength;
|
|
51785
|
+
}
|
|
51786
|
+
return bytes;
|
|
51787
|
+
}
|
|
51788
|
+
|
|
51789
|
+
// src/lib/remote-client.ts
|
|
51790
|
+
class RemoteRouteUnsupportedError extends Error {
|
|
51791
|
+
path;
|
|
51792
|
+
status;
|
|
51793
|
+
instance;
|
|
51794
|
+
constructor(path, status, instance) {
|
|
51795
|
+
super(`The configured Skills instance does not support ${path} (HTTP ${status}). ` + `The instance at ${instance} predates this client feature \u2014 upgrade the server, or ` + `use a client version that matches it.`);
|
|
51796
|
+
this.path = path;
|
|
51797
|
+
this.status = status;
|
|
51798
|
+
this.instance = instance;
|
|
51799
|
+
this.name = "RemoteRouteUnsupportedError";
|
|
51800
|
+
}
|
|
51801
|
+
}
|
|
51802
|
+
|
|
51803
|
+
class RemoteRequestError extends Error {
|
|
51804
|
+
path;
|
|
51805
|
+
status;
|
|
51806
|
+
constructor(path, status, statusText) {
|
|
51807
|
+
super(`Remote request to ${path} failed: HTTP ${status}${statusText ? ` ${statusText}` : ""}`);
|
|
51808
|
+
this.path = path;
|
|
51809
|
+
this.status = status;
|
|
51810
|
+
this.name = "RemoteRequestError";
|
|
51811
|
+
}
|
|
51812
|
+
}
|
|
51813
|
+
|
|
51814
|
+
class RemoteSkillsClient {
|
|
51815
|
+
apiUrl;
|
|
51816
|
+
apiKey;
|
|
51817
|
+
capabilities;
|
|
51818
|
+
constructor(apiKey, apiUrl = getApiUrl()) {
|
|
51819
|
+
this.apiKey = apiKey;
|
|
51820
|
+
this.apiUrl = normalizeSkillsApiOrigin(apiUrl);
|
|
51821
|
+
}
|
|
51822
|
+
async request(path, options) {
|
|
51823
|
+
return fetch(`${this.apiUrl}${path}`, {
|
|
51824
|
+
...options,
|
|
51825
|
+
redirect: "error",
|
|
51826
|
+
signal: options?.signal ?? AbortSignal.timeout(15000),
|
|
51827
|
+
headers: {
|
|
51828
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
51829
|
+
"Content-Type": "application/json",
|
|
51830
|
+
...options?.headers
|
|
51831
|
+
}
|
|
51832
|
+
});
|
|
51833
|
+
}
|
|
51834
|
+
async requestNewRoute(path, options, opts = {}) {
|
|
51835
|
+
const response = await this.request(path, options);
|
|
51836
|
+
const routePath = path.split("?")[0];
|
|
51837
|
+
if (response.status === 404 || response.status === 405) {
|
|
51838
|
+
if (response.status === 404 && opts.domainNotFoundCodes?.length && await responseBodyCarriesCode(response, opts.domainNotFoundCodes)) {
|
|
51839
|
+
return response;
|
|
51840
|
+
}
|
|
51841
|
+
throw new RemoteRouteUnsupportedError(routePath, response.status, this.apiUrl);
|
|
51842
|
+
}
|
|
51843
|
+
if (!response.ok) {
|
|
51844
|
+
throw new RemoteRequestError(routePath, response.status, response.statusText);
|
|
51845
|
+
}
|
|
51846
|
+
return response;
|
|
51847
|
+
}
|
|
51848
|
+
async listSkills() {
|
|
51849
|
+
return this.arrayResponse("/api/v1/skills");
|
|
51850
|
+
}
|
|
51851
|
+
async getSkillMd(slug) {
|
|
51852
|
+
const res = await this.request(`/api/v1/skills/${slug}/skill.md`);
|
|
51853
|
+
if (!res.ok)
|
|
51854
|
+
return null;
|
|
51855
|
+
return res.text();
|
|
51856
|
+
}
|
|
51857
|
+
async getSkill(slug) {
|
|
51858
|
+
const res = await this.request(`/api/v1/skills/${slug}`);
|
|
51859
|
+
if (!res.ok)
|
|
51860
|
+
return null;
|
|
51861
|
+
return res.json();
|
|
51862
|
+
}
|
|
51863
|
+
async getSkillStatus(slug) {
|
|
51864
|
+
const res = await this.request(`/api/v1/skills/${encodeURIComponent(slug)}`, { method: "GET" });
|
|
51865
|
+
let body = null;
|
|
51866
|
+
try {
|
|
51867
|
+
body = await res.json();
|
|
51868
|
+
} catch {}
|
|
51869
|
+
return { status: res.status, body };
|
|
51870
|
+
}
|
|
51871
|
+
async submitRun(slug, input, args, approval = {}) {
|
|
51872
|
+
if (approval.idempotencyKey !== undefined && !/^[A-Za-z0-9._:-]{1,128}$/.test(approval.idempotencyKey))
|
|
51873
|
+
throw new Error("Idempotency key must be 1-128 URL-safe characters");
|
|
51874
|
+
if (approval.maxCostCents !== undefined)
|
|
51875
|
+
creditCount(approval.maxCostCents);
|
|
51876
|
+
if (approval.maxCredits !== undefined)
|
|
51877
|
+
creditCount(approval.maxCredits);
|
|
51878
|
+
if (approval.maxCredits !== undefined && approval.maxCostCents !== undefined && approval.maxCredits !== approval.maxCostCents)
|
|
51879
|
+
throw new Error("Credit approval fields disagree");
|
|
51880
|
+
const res = await this.request(`/api/v1/runs/${encodeURIComponent(slug)}`, {
|
|
51881
|
+
method: "POST",
|
|
51882
|
+
body: JSON.stringify({
|
|
51883
|
+
input,
|
|
51884
|
+
args,
|
|
51885
|
+
...approval.maxCredits !== undefined ? { maxCredits: approval.maxCredits } : {},
|
|
51886
|
+
...approval.maxCostCents !== undefined ? { maxCostCents: approval.maxCostCents } : {},
|
|
51887
|
+
...approval.idempotencyKey !== undefined ? { idempotencyKey: approval.idempotencyKey } : {},
|
|
51888
|
+
...approval.inputFiles !== undefined ? { files: approval.inputFiles } : {}
|
|
51889
|
+
})
|
|
51890
|
+
});
|
|
51891
|
+
return normalizeRemoteSkillRunContract(await res.json(), slug);
|
|
51892
|
+
}
|
|
51893
|
+
async quoteRun(slug, input = {}, args = []) {
|
|
51894
|
+
const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug)}/quote`, {
|
|
51895
|
+
method: "POST",
|
|
51896
|
+
body: JSON.stringify({ input, args })
|
|
51897
|
+
});
|
|
51898
|
+
return parseRemoteRunQuote(await response.json());
|
|
51899
|
+
}
|
|
51900
|
+
getCapabilities() {
|
|
51901
|
+
if (!this.capabilities)
|
|
51902
|
+
this.capabilities = (async () => {
|
|
51903
|
+
const value = await (await this.requestNewRoute("/api/v1/capabilities")).json();
|
|
51904
|
+
if (value.contractVersion !== 1 || value.apiVersion !== 1 || !Array.isArray(value.capabilities) || value.capabilities.some((item) => typeof item !== "string"))
|
|
51905
|
+
throw new Error("Unsupported Skills server capability contract");
|
|
51906
|
+
const billing = value.billing;
|
|
51907
|
+
return { contractVersion: 1, apiVersion: 1, capabilities: value.capabilities, ...billing ? { billing } : {} };
|
|
51908
|
+
})();
|
|
51909
|
+
return this.capabilities;
|
|
51910
|
+
}
|
|
51911
|
+
async submitQuotedRun(slug, input = {}, args = [], approval = {}) {
|
|
51912
|
+
const maximum = creditCount(approval.maxCredits ?? approval.maxCostCents ?? 0);
|
|
51913
|
+
if (approval.maxCostCents !== undefined && approval.maxCostCents !== maximum)
|
|
51914
|
+
throw new Error("Credit approval fields disagree");
|
|
51915
|
+
const quote = await this.quoteRun(slug, input, args);
|
|
51916
|
+
if (quote.pricing.costCents > maximum)
|
|
51917
|
+
throw new RemoteCreditApprovalError(quote.pricing.costCents, maximum);
|
|
51918
|
+
const capabilities = await this.getCapabilities();
|
|
51919
|
+
if (!capabilities.capabilities.includes("runs.submit") || capabilities.billing?.boundedRunApproval !== true || capabilities.billing.unit !== "credits") {
|
|
51920
|
+
throw new Error("The configured server does not support bounded credit approval; refusing remote submission");
|
|
51921
|
+
}
|
|
51922
|
+
return this.submitRun(quote.skill, input, args, { ...approval, maxCredits: maximum, maxCostCents: maximum });
|
|
51923
|
+
}
|
|
51924
|
+
async getIdentity() {
|
|
51925
|
+
return (await this.requestNewRoute("/api/auth/whoami")).json();
|
|
51926
|
+
}
|
|
51927
|
+
async listApiKeys() {
|
|
51928
|
+
return this.arrayResponse("/api/auth/keys");
|
|
51929
|
+
}
|
|
51930
|
+
async createApiKey(name, scopes) {
|
|
51931
|
+
if (!name.trim() || name.length > 100)
|
|
51932
|
+
throw new Error("API key name must be 1-100 characters");
|
|
51933
|
+
const value = await (await this.requestNewRoute("/api/auth/keys", { method: "POST", body: JSON.stringify({ name, ...scopes ? { scopes } : {} }) })).json();
|
|
51934
|
+
if (!value || typeof value.key !== "string" || !value.key.trim())
|
|
51935
|
+
throw new Error("The server did not return a created API key");
|
|
51936
|
+
return value;
|
|
51937
|
+
}
|
|
51938
|
+
async revokeApiKey(keyId) {
|
|
51939
|
+
return (await this.requestNewRoute(`/api/auth/keys/${encodeURIComponent(keyId)}`, { method: "DELETE" })).json();
|
|
51940
|
+
}
|
|
51941
|
+
async getBillingStatus() {
|
|
51942
|
+
return parseRemoteBillingStatus(await (await this.requestNewRoute("/api/v1/billing/status")).json());
|
|
51943
|
+
}
|
|
51944
|
+
async listCreditPacks() {
|
|
51945
|
+
return parseRemoteCreditPacks(await (await this.requestNewRoute("/api/v1/billing/credits")).json());
|
|
51946
|
+
}
|
|
51947
|
+
async createCreditCheckout(packId) {
|
|
51948
|
+
const packs = await this.listCreditPacks();
|
|
51949
|
+
if (!packs.some((pack) => pack.id === packId))
|
|
51950
|
+
throw new Error("Choose a credit pack returned by skills credits packs");
|
|
51951
|
+
return parseRemoteCheckout(await (await this.requestNewRoute("/api/v1/billing/credits", {
|
|
51952
|
+
method: "POST",
|
|
51953
|
+
body: JSON.stringify({ packId })
|
|
51954
|
+
})).json());
|
|
51955
|
+
}
|
|
51956
|
+
async getUsage() {
|
|
51957
|
+
return this.arrayResponse("/api/v1/billing/usage");
|
|
51958
|
+
}
|
|
51959
|
+
async listInvoices() {
|
|
51960
|
+
return this.arrayResponse("/api/v1/billing/invoices");
|
|
51961
|
+
}
|
|
51962
|
+
async createBillingCheckout() {
|
|
51963
|
+
return this.checkoutResponse("/api/v1/billing/checkout");
|
|
51964
|
+
}
|
|
51965
|
+
async createBillingPortal() {
|
|
51966
|
+
return this.checkoutResponse("/api/v1/billing/portal");
|
|
51967
|
+
}
|
|
51968
|
+
async cancelRun(runId2) {
|
|
51969
|
+
return this.controlRun(runId2, "cancel");
|
|
51970
|
+
}
|
|
51971
|
+
async resumeRun(runId2) {
|
|
51972
|
+
return this.controlRun(runId2, "resume");
|
|
51973
|
+
}
|
|
51974
|
+
async controlRun(runId2, action) {
|
|
51975
|
+
const response = await this.requestNewRoute(`/api/v1/runs/${encodeURIComponent(runId2)}/${action}`, { method: "POST", body: "{}" });
|
|
51976
|
+
return normalizeRemoteSkillRunContract(await response.json());
|
|
51977
|
+
}
|
|
51978
|
+
async checkoutResponse(path) {
|
|
51979
|
+
return parseRemoteCheckout(await (await this.requestNewRoute(path, { method: "POST", body: "{}" })).json());
|
|
51980
|
+
}
|
|
51981
|
+
async arrayResponse(path) {
|
|
51982
|
+
const rows = await (await this.requestNewRoute(path)).json();
|
|
51983
|
+
if (!Array.isArray(rows) || rows.some((row) => !row || typeof row !== "object" || Array.isArray(row)))
|
|
51984
|
+
throw new Error("Invalid Skills server list response");
|
|
51985
|
+
return rows;
|
|
51986
|
+
}
|
|
51987
|
+
async getRun(runId2) {
|
|
51988
|
+
const path = `/api/v1/runs/${encodeURIComponent(runId2)}`;
|
|
51989
|
+
const res = await this.request(path);
|
|
51990
|
+
if (res.status === 404)
|
|
51991
|
+
return null;
|
|
51992
|
+
if (!res.ok)
|
|
51993
|
+
throw new RemoteRequestError(path, res.status, res.statusText);
|
|
51994
|
+
return normalizeRemoteSkillRunContract(await res.json());
|
|
51995
|
+
}
|
|
51996
|
+
async getRunLogs(runId2) {
|
|
51997
|
+
return this.arrayResponse(`/api/v1/runs/${encodeURIComponent(runId2)}/logs`);
|
|
51998
|
+
}
|
|
51999
|
+
async listRuns(limit = 20) {
|
|
52000
|
+
if (!Number.isInteger(limit) || limit < 1 || limit > 100)
|
|
52001
|
+
throw new Error("Run limit must be an integer from 1 to 100");
|
|
52002
|
+
return this.arrayResponse(`/api/v1/runs?limit=${limit}`);
|
|
52003
|
+
}
|
|
52004
|
+
async getRunArtifacts(runId2) {
|
|
52005
|
+
return this.arrayResponse(`/api/v1/runs/${encodeURIComponent(runId2)}/artifacts`);
|
|
52006
|
+
}
|
|
52007
|
+
async downloadRunArtifact(runId2, artifactId2) {
|
|
52008
|
+
return this.request(`/api/v1/runs/${encodeURIComponent(runId2)}/artifacts/${encodeURIComponent(artifactId2)}/download`, {
|
|
52009
|
+
method: "GET"
|
|
52010
|
+
});
|
|
52011
|
+
}
|
|
52012
|
+
async getVerifiedRunArtifact(runId2, artifactId2, maximumBytes = MAX_REMOTE_FILE_BYTES) {
|
|
52013
|
+
const artifacts = await this.getRunArtifacts(runId2);
|
|
52014
|
+
const artifact = artifacts.find((row) => row.id === artifactId2);
|
|
52015
|
+
if (!artifact)
|
|
52016
|
+
throw new Error("Run artifact not found");
|
|
52017
|
+
if (!Number.isSafeInteger(artifact.byteSize) || artifact.byteSize < 0 || artifact.byteSize > maximumBytes || typeof artifact.sha256 !== "string" || !/^[a-f0-9]{64}$/.test(artifact.sha256))
|
|
52018
|
+
throw new Error("The server does not provide valid artifact integrity metadata");
|
|
52019
|
+
const response = await this.downloadRunArtifact(runId2, artifactId2);
|
|
52020
|
+
if (!response.ok)
|
|
52021
|
+
throw new RemoteRequestError("artifact download", response.status, response.statusText);
|
|
52022
|
+
const bytes = await readBoundedResponse(response, artifact.byteSize);
|
|
52023
|
+
if (bytes.byteLength !== artifact.byteSize || sha256(bytes) !== artifact.sha256)
|
|
52024
|
+
throw new Error("Artifact integrity verification failed");
|
|
52025
|
+
return { id: artifactId2, fileName: String(artifact.fileName ?? artifactId2), bytes, byteSize: bytes.byteLength, sha256: artifact.sha256 };
|
|
52026
|
+
}
|
|
52027
|
+
async submitQuotedRunWithFiles(slug, input, args, files, approval = {}) {
|
|
52028
|
+
const inputFiles = describeRemoteFiles(files);
|
|
52029
|
+
if (files.length && !(await this.getCapabilities()).capabilities.includes("runs.uploads"))
|
|
52030
|
+
throw new Error("The configured server does not support input uploads");
|
|
52031
|
+
const run = await this.submitQuotedRun(slug, input, args, { ...approval, inputFiles });
|
|
52032
|
+
if (run.error || !run.id || !files.length)
|
|
52033
|
+
return run;
|
|
52034
|
+
const pastUploads = (status) => typeof status === "string" && [
|
|
52035
|
+
"running",
|
|
52036
|
+
"completed",
|
|
52037
|
+
"failed",
|
|
52038
|
+
"cancelled",
|
|
52039
|
+
"expired",
|
|
52040
|
+
"pending_approval",
|
|
52041
|
+
"approved",
|
|
52042
|
+
"waiting"
|
|
52043
|
+
].includes(status);
|
|
52044
|
+
if (pastUploads(run.status))
|
|
52045
|
+
return run;
|
|
52046
|
+
try {
|
|
52047
|
+
await this.uploadRunFiles(run.id, files);
|
|
52048
|
+
} catch {
|
|
52049
|
+
try {
|
|
52050
|
+
const current = await this.getRun(run.id);
|
|
52051
|
+
if (current && pastUploads(current.status))
|
|
52052
|
+
return current;
|
|
52053
|
+
} catch {}
|
|
52054
|
+
let cancellationRequested = false;
|
|
52055
|
+
try {
|
|
52056
|
+
await this.cancelRun(run.id);
|
|
52057
|
+
cancellationRequested = true;
|
|
52058
|
+
} catch {}
|
|
52059
|
+
throw new Error(`Input upload failed for run ${run.id}; ${cancellationRequested ? "cancellation requested" : "check its status and cancel the run"}`);
|
|
52060
|
+
}
|
|
52061
|
+
return run;
|
|
52062
|
+
}
|
|
52063
|
+
async uploadRunFiles(runId2, files) {
|
|
52064
|
+
const descriptors = describeRemoteFiles(files);
|
|
52065
|
+
const response = await this.requestNewRoute(`/api/v1/runs/${encodeURIComponent(runId2)}/uploads`, { method: "POST", body: JSON.stringify({ files: descriptors }) });
|
|
52066
|
+
const payload = await response.json();
|
|
52067
|
+
if (!Array.isArray(payload.files) || payload.files.length !== files.length || new Set(payload.files.map((file) => file.name)).size !== files.length)
|
|
52068
|
+
throw new Error("Invalid input upload response");
|
|
52069
|
+
for (const file of files) {
|
|
52070
|
+
const upload = payload.files.find((row) => row.name === file.name);
|
|
52071
|
+
if (!upload)
|
|
52072
|
+
throw new Error("Missing input upload URL");
|
|
52073
|
+
const url = new URL(upload.uploadUrl);
|
|
52074
|
+
if (url.username || url.password || url.hash || url.protocol !== "https:" && !(url.protocol === "http:" && ["localhost", "127.0.0.1", "[::1]"].includes(url.hostname)))
|
|
52075
|
+
throw new Error("Unsafe input upload URL");
|
|
52076
|
+
const uploaded = await fetch(url, { method: "PUT", body: file.bytes, headers: { "Content-Type": file.contentType ?? "application/octet-stream" }, redirect: "error", signal: AbortSignal.timeout(60000) });
|
|
52077
|
+
if (!uploaded.ok)
|
|
52078
|
+
throw new Error("Input upload failed");
|
|
52079
|
+
await uploaded.body?.cancel();
|
|
52080
|
+
}
|
|
52081
|
+
}
|
|
52082
|
+
async publishSkill(manifest, bundle, ifMatch) {
|
|
52083
|
+
const form = new FormData;
|
|
52084
|
+
form.set("manifest", JSON.stringify(manifest));
|
|
52085
|
+
if (bundle) {
|
|
52086
|
+
form.set("bundle", new Blob([bundle], { type: "application/gzip" }), `${String(manifest.slug ?? "skill")}.tar.gz`);
|
|
52087
|
+
}
|
|
52088
|
+
const headers = { Authorization: `Bearer ${this.apiKey}` };
|
|
52089
|
+
if (ifMatch)
|
|
52090
|
+
headers["If-Match"] = ifMatch;
|
|
52091
|
+
return fetch(`${this.apiUrl}/api/v1/skills`, {
|
|
52092
|
+
method: "POST",
|
|
52093
|
+
headers,
|
|
52094
|
+
body: form,
|
|
52095
|
+
redirect: "error",
|
|
52096
|
+
signal: AbortSignal.timeout(15000)
|
|
52097
|
+
});
|
|
52098
|
+
}
|
|
52099
|
+
async deleteSkill(slug) {
|
|
52100
|
+
return this.request(`/api/v1/skills/${encodeURIComponent(slug)}`, { method: "DELETE" });
|
|
52101
|
+
}
|
|
52102
|
+
async downloadSkillBundle(slug) {
|
|
52103
|
+
return this.request(`/api/v1/skills/${encodeURIComponent(slug)}/bundle`, { method: "GET" });
|
|
52104
|
+
}
|
|
52105
|
+
async getBundle(slug, version2) {
|
|
52106
|
+
const path = version2 ? `/api/v1/skills/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version2)}/bundle` : `/api/v1/skills/${encodeURIComponent(slug)}/bundle`;
|
|
52107
|
+
const response = await this.request(path, { method: "GET" });
|
|
52108
|
+
if (response.status === 404)
|
|
52109
|
+
return null;
|
|
52110
|
+
return response;
|
|
52111
|
+
}
|
|
52112
|
+
async listSkillVersions(slug) {
|
|
52113
|
+
const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug)}/versions`, undefined, { domainNotFoundCodes: ["SKILL_NOT_FOUND"] });
|
|
52114
|
+
if (response.status === 404)
|
|
52115
|
+
return [];
|
|
52116
|
+
if (!response.ok)
|
|
52117
|
+
throw new Error(`versions request failed: ${response.status}`);
|
|
52118
|
+
const body = await response.json();
|
|
52119
|
+
return Array.isArray(body.versions) ? body.versions : [];
|
|
52120
|
+
}
|
|
52121
|
+
async getSkillVersion(slug, version2) {
|
|
52122
|
+
const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug)}/versions/${encodeURIComponent(version2)}`, undefined, { domainNotFoundCodes: ["SKILL_NOT_FOUND", "SKILL_VERSION_NOT_FOUND"] });
|
|
52123
|
+
if (response.status === 404)
|
|
52124
|
+
return null;
|
|
52125
|
+
if (!response.ok)
|
|
52126
|
+
throw new Error(`version request failed: ${response.status}`);
|
|
52127
|
+
return await response.json();
|
|
52128
|
+
}
|
|
52129
|
+
async listPins() {
|
|
52130
|
+
const response = await this.requestNewRoute("/api/v1/pins");
|
|
52131
|
+
return normalizePinList(await response.json());
|
|
52132
|
+
}
|
|
52133
|
+
async pin(slug, metadata) {
|
|
52134
|
+
const path = `/api/v1/pins/${encodeURIComponent(slug)}`;
|
|
52135
|
+
const response = await this.requestNewRoute(path, {
|
|
52136
|
+
method: "PUT",
|
|
52137
|
+
body: JSON.stringify({ ...metadata ? { metadata } : {} })
|
|
52138
|
+
});
|
|
52139
|
+
return normalizePin(await response.json());
|
|
52140
|
+
}
|
|
52141
|
+
async unpin(slug) {
|
|
52142
|
+
const path = `/api/v1/pins/${encodeURIComponent(slug)}`;
|
|
52143
|
+
const response = await this.requestNewRoute(path, { method: "DELETE" }, { domainNotFoundCodes: ["PIN_NOT_FOUND"] });
|
|
52144
|
+
return response.status !== 404;
|
|
52145
|
+
}
|
|
52146
|
+
async listTags() {
|
|
52147
|
+
const response = await this.requestNewRoute("/api/v1/tags");
|
|
52148
|
+
const payload = await response.json();
|
|
52149
|
+
if (!Array.isArray(payload)) {
|
|
52150
|
+
throw new Error("Remote tags payload did not match the expected contract (expected an array of tag names)");
|
|
52151
|
+
}
|
|
52152
|
+
const isName = (value) => typeof value === "string" && value.trim().length > 0;
|
|
52153
|
+
if (payload.every(isName))
|
|
52154
|
+
return payload;
|
|
52155
|
+
if (payload.every((tag) => tag !== null && typeof tag === "object" && !Array.isArray(tag) && isName(tag.name) && Number.isSafeInteger(tag.count) && tag.count >= 0)) {
|
|
52156
|
+
return payload.map((tag) => tag.name);
|
|
52157
|
+
}
|
|
52158
|
+
throw new Error("Remote tags payload did not match the expected contract (every element must be a non-empty tag name, or every element must be a counted tag record)");
|
|
52159
|
+
}
|
|
52160
|
+
async skillsByTag(tag) {
|
|
52161
|
+
const path = `/api/v1/tags/${encodeURIComponent(tag)}/skills`;
|
|
52162
|
+
const response = await this.requestNewRoute(path);
|
|
52163
|
+
return normalizeSkillSummaryList(await response.json());
|
|
52164
|
+
}
|
|
52165
|
+
async listUpdatedSince(since, options = {}) {
|
|
52166
|
+
const params = new URLSearchParams({ since });
|
|
52167
|
+
if (options.cursor)
|
|
52168
|
+
params.set("cursor", options.cursor);
|
|
52169
|
+
if (options.limit !== undefined)
|
|
52170
|
+
params.set("limit", String(options.limit));
|
|
52171
|
+
const response = await this.requestNewRoute(`/api/v1/skills/updated?${params.toString()}`);
|
|
52172
|
+
return normalizeUpdatedSincePage(await response.json());
|
|
52173
|
+
}
|
|
52174
|
+
}
|
|
52175
|
+
function requireOptionalString(record, field) {
|
|
52176
|
+
if (record[field] === undefined)
|
|
52177
|
+
return;
|
|
52178
|
+
if (typeof record[field] !== "string") {
|
|
52179
|
+
throw new Error(`Remote payload did not match the expected contract (${field} must be a string when present)`);
|
|
52180
|
+
}
|
|
52181
|
+
return record[field];
|
|
52182
|
+
}
|
|
52183
|
+
function normalizePin(entry) {
|
|
52184
|
+
if (!entry || typeof entry !== "object") {
|
|
52185
|
+
throw new Error("Remote pin payload did not match the expected contract (expected an object)");
|
|
52186
|
+
}
|
|
52187
|
+
const record = entry;
|
|
52188
|
+
const slug = typeof record.slug === "string" && record.slug.trim() ? record.slug.trim() : undefined;
|
|
52189
|
+
if (!slug) {
|
|
52190
|
+
throw new Error("Remote pin payload did not match the expected contract (missing slug)");
|
|
52191
|
+
}
|
|
52192
|
+
let metadata;
|
|
52193
|
+
if (record.metadata !== undefined) {
|
|
52194
|
+
if (!record.metadata || typeof record.metadata !== "object" || Array.isArray(record.metadata)) {
|
|
52195
|
+
throw new Error("Remote pin payload did not match the expected contract (metadata must be a JSON object when present)");
|
|
52196
|
+
}
|
|
52197
|
+
metadata = record.metadata;
|
|
52198
|
+
}
|
|
52199
|
+
const pinnedAt = requireOptionalString(record, "pinnedAt");
|
|
52200
|
+
return {
|
|
52201
|
+
slug,
|
|
52202
|
+
...pinnedAt !== undefined ? { pinnedAt } : {},
|
|
52203
|
+
...metadata ? { metadata } : {}
|
|
52204
|
+
};
|
|
52205
|
+
}
|
|
52206
|
+
function normalizePinList(payload) {
|
|
52207
|
+
if (!Array.isArray(payload)) {
|
|
52208
|
+
throw new Error("Remote pins payload did not match the expected contract (expected an array of pins)");
|
|
52209
|
+
}
|
|
52210
|
+
return payload.map(normalizePin);
|
|
52211
|
+
}
|
|
52212
|
+
function normalizeSkillSummary(entry) {
|
|
52213
|
+
if (!entry || typeof entry !== "object") {
|
|
52214
|
+
throw new Error("Remote skill payload did not match the expected contract (expected an object)");
|
|
52215
|
+
}
|
|
52216
|
+
const record = entry;
|
|
52217
|
+
const slug = typeof record.slug === "string" && record.slug.trim() ? record.slug.trim() : undefined;
|
|
52218
|
+
if (!slug) {
|
|
52219
|
+
throw new Error("Remote skill payload did not match the expected contract (missing slug)");
|
|
52220
|
+
}
|
|
52221
|
+
return {
|
|
52222
|
+
slug,
|
|
52223
|
+
...requireOptionalString(record, "name") !== undefined ? { name: requireOptionalString(record, "name") } : {},
|
|
52224
|
+
...requireOptionalString(record, "version") !== undefined ? { version: requireOptionalString(record, "version") } : {},
|
|
52225
|
+
...requireOptionalString(record, "updatedAt") !== undefined ? { updatedAt: requireOptionalString(record, "updatedAt") } : {}
|
|
52226
|
+
};
|
|
52227
|
+
}
|
|
52228
|
+
function normalizeSkillSummaryList(payload) {
|
|
52229
|
+
if (!Array.isArray(payload)) {
|
|
52230
|
+
throw new Error("Remote skills payload did not match the expected contract (expected an array of skills)");
|
|
52231
|
+
}
|
|
52232
|
+
return payload.map(normalizeSkillSummary);
|
|
52233
|
+
}
|
|
52234
|
+
async function responseBodyCarriesCode(response, codes) {
|
|
52235
|
+
try {
|
|
52236
|
+
const payload = await response.clone().json();
|
|
52237
|
+
if (!payload || typeof payload !== "object")
|
|
52238
|
+
return false;
|
|
52239
|
+
const code = payload.code;
|
|
52240
|
+
return typeof code === "string" && codes.includes(code);
|
|
52241
|
+
} catch {
|
|
52242
|
+
return false;
|
|
52243
|
+
}
|
|
52244
|
+
}
|
|
52245
|
+
function normalizeUpdatedSincePage(payload) {
|
|
52246
|
+
if (!payload || typeof payload !== "object") {
|
|
52247
|
+
throw new Error("Updated-since payload did not match the expected contract (expected an object)");
|
|
52248
|
+
}
|
|
52249
|
+
const record = payload;
|
|
52250
|
+
if (!Array.isArray(record.skills)) {
|
|
52251
|
+
throw new Error("Updated-since payload did not match the expected contract (missing skills array)");
|
|
52252
|
+
}
|
|
52253
|
+
const skills = record.skills.map(normalizeSkillSummary);
|
|
52254
|
+
const nextCursor = record.nextCursor === undefined || record.nextCursor === null ? null : record.nextCursor;
|
|
52255
|
+
if (nextCursor !== null && typeof nextCursor !== "string") {
|
|
52256
|
+
throw new Error("Updated-since payload did not match the expected contract (nextCursor must be a string or absent)");
|
|
52257
|
+
}
|
|
52258
|
+
return { skills, nextCursor };
|
|
52259
|
+
}
|
|
52260
|
+
async function createRemoteSkillsClient(env = process.env) {
|
|
52261
|
+
const connection = await resolveSkillsConnection(env);
|
|
52262
|
+
return connection ? new RemoteSkillsClient(connection.apiKey, connection.apiOrigin) : null;
|
|
52263
|
+
}
|
|
52264
|
+
// src/lib/remote-auth.ts
|
|
52265
|
+
var MAX_ERROR_DETAIL_LENGTH = 200;
|
|
52266
|
+
|
|
52267
|
+
class HostedApiError extends Error {
|
|
52268
|
+
status;
|
|
52269
|
+
code;
|
|
52270
|
+
detail;
|
|
52271
|
+
endpoint;
|
|
52272
|
+
apiUrl;
|
|
52273
|
+
constructor(message, options = {}) {
|
|
52274
|
+
super(message);
|
|
52275
|
+
this.name = "HostedApiError";
|
|
52276
|
+
this.status = options.status;
|
|
52277
|
+
this.code = options.code;
|
|
52278
|
+
this.detail = options.detail;
|
|
52279
|
+
this.endpoint = options.endpoint;
|
|
52280
|
+
this.apiUrl = options.apiUrl;
|
|
52281
|
+
}
|
|
52282
|
+
}
|
|
52283
|
+
async function requestAuthApi(instance, path, options) {
|
|
52284
|
+
const url = normalizeSkillsApiOrigin(instance);
|
|
52285
|
+
const safeUrl = url;
|
|
52286
|
+
const endpoint = `${(options?.method || "GET").toUpperCase()} ${safeUrl}${path}`;
|
|
52287
|
+
let res;
|
|
52288
|
+
try {
|
|
52289
|
+
res = await fetch(`${url}${path}`, {
|
|
52290
|
+
...options,
|
|
52291
|
+
redirect: "error",
|
|
52292
|
+
signal: options?.signal ?? AbortSignal.timeout(15000),
|
|
52293
|
+
headers: { "Content-Type": "application/json", ...options?.headers }
|
|
52294
|
+
});
|
|
52295
|
+
} catch (err) {
|
|
52296
|
+
throw new HostedApiError(`Unable to reach the Skills API: ${err.message}`, {
|
|
52297
|
+
endpoint,
|
|
52298
|
+
apiUrl: safeUrl
|
|
52299
|
+
});
|
|
52300
|
+
}
|
|
52301
|
+
const text = await res.text();
|
|
52302
|
+
const body = text ? parseJsonBody(text) : {};
|
|
52303
|
+
if (!res.ok) {
|
|
52304
|
+
const record = isRecord5(body) ? body : {};
|
|
52305
|
+
const detail = typeof record.detail === "string" ? record.detail : undefined;
|
|
52306
|
+
const error = typeof record.error === "string" ? record.error : undefined;
|
|
52307
|
+
const code = typeof record.code === "string" ? record.code : undefined;
|
|
52308
|
+
throw new HostedApiError(detail || error || `${res.status} ${res.statusText}`, {
|
|
52309
|
+
status: res.status,
|
|
52310
|
+
code,
|
|
52311
|
+
detail,
|
|
52312
|
+
endpoint,
|
|
52313
|
+
apiUrl: safeUrl
|
|
52314
|
+
});
|
|
52315
|
+
}
|
|
52316
|
+
return body;
|
|
52317
|
+
}
|
|
52318
|
+
function parseJsonBody(text) {
|
|
52319
|
+
try {
|
|
52320
|
+
return JSON.parse(text);
|
|
52321
|
+
} catch {
|
|
52322
|
+
return { detail: condenseErrorBody(text) };
|
|
52323
|
+
}
|
|
52324
|
+
}
|
|
52325
|
+
function condenseErrorBody(text) {
|
|
52326
|
+
const stripped = /<[a-z!/]/i.test(text) ? text.replace(/<(script|style)[\s\S]*?<\/\1>/gi, " ").replace(/<[^>]*>/g, " ") : text;
|
|
52327
|
+
const collapsed = stripped.replace(/\s+/g, " ").trim();
|
|
52328
|
+
if (collapsed.length <= MAX_ERROR_DETAIL_LENGTH)
|
|
52329
|
+
return collapsed;
|
|
52330
|
+
return `${collapsed.slice(0, MAX_ERROR_DETAIL_LENGTH - 1).trimEnd()}\u2026`;
|
|
52331
|
+
}
|
|
52332
|
+
function isRecord5(value) {
|
|
52333
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
52334
|
+
}
|
|
52335
|
+
|
|
52336
|
+
class RemoteSkillsAuthClient {
|
|
52337
|
+
apiOrigin;
|
|
52338
|
+
constructor(apiUrl) {
|
|
52339
|
+
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
52340
|
+
}
|
|
52341
|
+
requestCode(email) {
|
|
52342
|
+
return this.request("/api/auth/login", { method: "POST", body: JSON.stringify({ email }) });
|
|
52343
|
+
}
|
|
52344
|
+
verifyCode(email, code) {
|
|
52345
|
+
return this.request("/api/auth/verify", { method: "POST", body: JSON.stringify({ email, code }) });
|
|
52346
|
+
}
|
|
52347
|
+
startDevice() {
|
|
52348
|
+
return this.request("/api/auth/device/start", { method: "POST", body: JSON.stringify({ client: "skills-sdk" }) });
|
|
52349
|
+
}
|
|
52350
|
+
pollDevice(deviceCode) {
|
|
52351
|
+
return this.request("/api/auth/device/token", { method: "POST", body: JSON.stringify({ deviceCode }) });
|
|
52352
|
+
}
|
|
52353
|
+
async sessionClient(email, code) {
|
|
52354
|
+
if (!email.includes("@") || !/^\d{6}$/.test(code))
|
|
52355
|
+
throw new Error("Fresh email and six-digit verification code are required to manage API keys");
|
|
52356
|
+
const login = await this.verifyCode(email, code);
|
|
52357
|
+
if (!login || typeof login.token !== "string" || !login.token)
|
|
52358
|
+
throw new Error("The server did not return an authorized account session");
|
|
52359
|
+
return new RemoteSkillsClient(login.token, this.apiOrigin);
|
|
52360
|
+
}
|
|
52361
|
+
async createApiKey(email, code, name, scopes) {
|
|
52362
|
+
return (await this.sessionClient(email, code)).createApiKey(name, scopes);
|
|
52363
|
+
}
|
|
52364
|
+
async listApiKeys(email, code) {
|
|
52365
|
+
return (await this.sessionClient(email, code)).listApiKeys();
|
|
52366
|
+
}
|
|
52367
|
+
async revokeApiKey(email, code, keyId) {
|
|
52368
|
+
return (await this.sessionClient(email, code)).revokeApiKey(keyId);
|
|
52369
|
+
}
|
|
52370
|
+
request(path, options) {
|
|
52371
|
+
if (!["/api/auth/login", "/api/auth/verify", "/api/auth/device/start", "/api/auth/device/token", "/api/auth/keys", "/api/auth/whoami"].includes(path))
|
|
52372
|
+
throw new Error("Unsupported authentication operation");
|
|
52373
|
+
return requestAuthApi(this.apiOrigin, path, options);
|
|
52374
|
+
}
|
|
52375
|
+
}
|
|
51606
52376
|
export {
|
|
51607
52377
|
validateRunLifecycleEvent,
|
|
51608
52378
|
startedByFor,
|
|
@@ -51656,6 +52426,7 @@ export {
|
|
|
51656
52426
|
createRunStateMachine,
|
|
51657
52427
|
createRunService,
|
|
51658
52428
|
createRunEventEmitter,
|
|
52429
|
+
createRemoteSkillsClient,
|
|
51659
52430
|
createReceiptService,
|
|
51660
52431
|
createOfflineGate,
|
|
51661
52432
|
createImageProfileRegistry,
|
|
@@ -51680,6 +52451,11 @@ export {
|
|
|
51680
52451
|
SKILLS_APP,
|
|
51681
52452
|
SKILLS_API_URL_ENV,
|
|
51682
52453
|
SKILLS_API_KEY_ENV,
|
|
52454
|
+
RemoteSkillsClient,
|
|
52455
|
+
RemoteSkillsAuthClient,
|
|
52456
|
+
RemoteRouteUnsupportedError,
|
|
52457
|
+
RemoteRequestError,
|
|
52458
|
+
RemoteCreditApprovalError,
|
|
51683
52459
|
RUN_PROTOCOL_VERSION,
|
|
51684
52460
|
RUN_PROTOCOL_STATES,
|
|
51685
52461
|
RUN_LIFECYCLE_EVENT_TYPES,
|
|
@@ -51693,6 +52469,7 @@ export {
|
|
|
51693
52469
|
MemoryGovernanceStore,
|
|
51694
52470
|
LEGAL_TRANSITIONS,
|
|
51695
52471
|
ImageProfileResolutionError,
|
|
52472
|
+
HostedApiError,
|
|
51696
52473
|
GovernanceError,
|
|
51697
52474
|
GOVERNANCE_ERROR_CODES,
|
|
51698
52475
|
EcsDispatcher,
|