@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/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 constants = new Set(Array.from(functionString.match(/([A-Z_]){3,}/g) ?? []));
2374
- constants.delete("CONFIG");
2375
- constants.delete("CONFIG_PREFIX_SEPARATOR");
2376
- constants.delete("ENV");
2377
- return [...constants].join(", ");
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: fstatSync2 } = __require("fs");
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 lstatSync(body.path).size;
4342
+ return lstatSync2(body.path).size;
4343
4343
  } else if (typeof body.fd === "number") {
4344
- return fstatSync2(body.fd).size;
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 import_client6, 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 () => {
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
- import_client6.setCredentialFeature(credentials, "CREDENTIALS_ENV_VARS", "g");
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
- import_client6 = __toESM(require_client2(), 1);
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
- [constants.HTTP2_HEADER_PATH]: path,
18833
- [constants.HTTP2_HEADER_METHOD]: method
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 import_client7, 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 = {}) => {
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) => import_client7.setCredentialFeature(creds, "CREDENTIALS_HTTP", "z"));
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
- import_client7 = __toESM(require_client2(), 1);
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 import_client8, import_config15, SHOULD_FAIL_CREDENTIAL_CHAIN = false, resolveSSOCredentials = async ({ ssoStartUrl, ssoSession, ssoAccountId, ssoRegion, ssoRoleName, ssoClient, clientConfig, parentClientConfig, callerClientConfig, profile, filepath, configFilepath, ignoreCache, logger }) => {
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
- import_client8.setCredentialFeature(credentials, "CREDENTIALS_SSO", "s");
20532
+ import_client9.setCredentialFeature(credentials, "CREDENTIALS_SSO", "s");
20533
20533
  } else {
20534
- import_client8.setCredentialFeature(credentials, "CREDENTIALS_SSO_LEGACY", "u");
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
- import_client8 = __toESM(require_client2(), 1);
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 import_client9, import_config18, resolveCredentialSource = (credentialSource, profileName, logger) => {
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) => import_client9.setCredentialFeature(creds, "CREDENTIALS_PROFILE_NAMED_PROVIDER", "p");
20676
+ }, setNamedProvider = (creds) => import_client10.setCredentialFeature(creds, "CREDENTIALS_PROFILE_NAMED_PROVIDER", "p");
20677
20677
  var init_resolveCredentialSource = __esm(() => {
20678
- import_client9 = __toESM(require_client2(), 1);
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 import_client10, import_config19, isAssumeRoleProfile = (arg, { profile = "default", logger } = {}) => {
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) => import_client10.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
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) => import_client10.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SOURCE_PROFILE", "o"));
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
- import_client10 = __toESM(require_client2(), 1);
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 import_client11, import_config21, fromLoginCredentials = (init) => async ({ callerClientConfig } = {}) => {
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 import_client11.setCredentialFeature(credentials, "CREDENTIALS_LOGIN", "AD");
22784
+ return import_client12.setCredentialFeature(credentials, "CREDENTIALS_LOGIN", "AD");
22785
22785
  };
22786
22786
  var init_fromLoginCredentials = __esm(() => {
22787
22787
  init_LoginCredentialsFetcher();
22788
- import_client11 = __toESM(require_client2(), 1);
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 import_client12, isLoginProfile = (data) => {
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 import_client12.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_LOGIN", "AC");
22810
+ return import_client13.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_LOGIN", "AC");
22811
22811
  };
22812
22812
  var init_resolveLoginCredentials = __esm(() => {
22813
- import_client12 = __toESM(require_client2(), 1);
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 import_client13, getValidatedProcessCredentials = (profileName, data, profiles) => {
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
- import_client13.setCredentialFeature(credentials, "CREDENTIALS_PROCESS", "w");
22843
+ import_client14.setCredentialFeature(credentials, "CREDENTIALS_PROCESS", "w");
22844
22844
  return credentials;
22845
22845
  };
22846
22846
  var init_getValidatedProcessCredentials = __esm(() => {
22847
- import_client13 = __toESM(require_client2(), 1);
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 import_client14, isProcessProfile = (arg) => Boolean(arg) && typeof arg === "object" && typeof arg.credential_process === "string", resolveProcessCredentials2 = async (options, profile) => {
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 import_client14.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_PROCESS", "v");
22914
+ return import_client15.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_PROCESS", "v");
22915
22915
  };
22916
22916
  var init_resolveProcessCredentials2 = __esm(() => {
22917
- import_client14 = __toESM(require_client2(), 1);
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 import_client15, resolveSsoCredentials = async (profile, profileData, options = {}, callerClientConfig) => {
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 import_client15.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO", "r");
22932
+ return import_client16.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO", "r");
22933
22933
  } else {
22934
- return import_client15.setCredentialFeature(creds, "CREDENTIALS_PROFILE_SSO_LEGACY", "t");
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
- import_client15 = __toESM(require_client2(), 1);
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 import_client16, 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) => {
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 import_client16.setCredentialFeature(credentials, "CREDENTIALS_PROFILE", "n");
22952
+ return import_client17.setCredentialFeature(credentials, "CREDENTIALS_PROFILE", "n");
22953
22953
  };
22954
22954
  var init_resolveStaticCredentials = __esm(() => {
22955
- import_client16 = __toESM(require_client2(), 1);
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 import_client17, 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) => {
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
- import_client17.setCredentialFeature(credentials, "CREDENTIALS_ENV_VARS_STS_WEB_ID_TOKEN", "h");
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
- import_client17 = __toESM(require_client2(), 1);
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 import_client18, 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) => {
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 import_client18.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN", "q");
23036
+ return import_client19.setCredentialFeature(credentials, "CREDENTIALS_PROFILE_STS_WEB_ID_TOKEN", "q");
23037
23037
  };
23038
23038
  var init_resolveWebIdentityCredentials = __esm(() => {
23039
- import_client18 = __toESM(require_client2(), 1);
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
- for (const key of SKILLS_API_URL_ENV_KEYS) {
24793
- const value = env[key]?.trim();
24794
- if (value)
24795
- return { value, source: key };
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 credentialDiskSources(SKILLS_APP, env);
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
- return resolveSkillsFleetOrThrow(env, options);
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 resolveSkillsFleetOrThrow(env, options) {
24837
- let resolution;
24838
- try {
24839
- resolution = resolveClientTransport(SKILLS_APP, env, { credentials: options.credentials });
24840
- } catch (error) {
24841
- if (!isClientTransportConfigurationError(error))
24842
- throw error;
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
- throw error;
24852
+ snapshot[key] = descriptor.value;
24854
24853
  }
24855
- const configured = configuredSkillsApiUrl(env, options.credentials?.keychain);
24856
- const apiOrigin = configured ? normalizeSkillsApiOrigin(configured.value) : stripV1(resolution.baseUrl);
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
- throw new SkillsFleetCredentialError(`A Skills authority resolved but no API key did. Sign in with: skills auth login`);
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: resolution.apiUrlSource ?? (configured?.source ?? "default"),
24865
- apiKeySource: resolution.apiKeySource ?? credential.source,
24866
- apiKeyTier: resolution.apiKeyTier,
24867
- warning: resolution.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
- const fleet = resolveSkillsFleet(env, options);
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, env);
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 apiKey = await resolveSkillsApiKey(env, options);
24913
- return apiKey ? { apiKey, reason: null } : { apiKey: null, reason: null };
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.3.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 import_client24 = __toESM(require_client2(), 1);
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 import_client25 = __toESM(require_client(), 1);
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 import_client3 = __toESM(require_client(), 1);
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 import_client2 = __toESM(require_client2(), 1);
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 = import_client2.awsEndpointFunctions;
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 = import_client3.getSmithyContext(context)?.commandInstance?.constructor?.getEndpointParameterInstructions;
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: import_client3.getSmithyContext(context).operation,
28478
- region: await import_client3.normalizeProvider(config.region)() || (() => {
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: import_client3.normalizeProvider(config.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 import_client4 = __toESM(require_client(), 1);
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 = import_client4.makeBuilder(commonParams, "AmazonS3", "S3Client", import_endpoints4.getEndpointPlugin);
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 import_client5 = __toESM(require_client(), 1);
28645
- class S3ServiceException extends import_client5.ServiceException {
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 import_client20 = __toESM(require_client2(), 1);
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 import_client21 = __toESM(require_client(), 1);
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 import_client19 = __toESM(require_client(), 1);
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 import_client19.NoOpLogger,
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
- import_client21.emitWarningIfUnsupportedVersion(process.version);
34949
+ import_client22.emitWarningIfUnsupportedVersion(process.version);
34920
34950
  const defaultsMode = import_config28.resolveDefaultsModeConfig(config);
34921
- const defaultConfigProvider = () => defaultsMode().then(import_client21.loadConfigsForDefaultMode);
34951
+ const defaultConfigProvider = () => defaultsMode().then(import_client22.loadConfigsForDefaultMode);
34922
34952
  const clientSharedValues = getRuntimeConfig2(config);
34923
- import_client20.emitWarningIfUnsupportedVersion(process.version);
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 ?? import_client20.createDefaultUserAgentProvider({ serviceId: clientSharedValues.serviceId, clientVersion: package_default2.version }),
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(import_client20.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig)
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 import_client22 = __toESM(require_client2(), 1);
34960
- var import_client23 = __toESM(require_client(), 1);
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(import_client22.getAwsRegionExtensionConfiguration(runtimeConfig), import_client23.getDefaultExtensionConfiguration(runtimeConfig), import_protocols5.getHttpHandlerExtensionConfiguration(runtimeConfig), getHttpAuthExtensionConfiguration2(runtimeConfig));
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, import_client22.resolveAwsRegionExtensionConfiguration(extensionConfiguration), import_client23.resolveDefaultRuntimeConfig(extensionConfiguration), import_protocols5.resolveHttpHandlerRuntimeConfig(extensionConfiguration), resolveHttpAuthRuntimeConfig2(extensionConfiguration));
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 import_client25.Client {
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 = import_client24.resolveUserAgentConfig(_config_1);
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 = import_client24.resolveHostHeaderConfig(_config_5);
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(import_client24.getUserAgentPlugin(this.config));
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(import_client24.getHostHeaderPlugin(this.config));
35033
- this.middlewareStack.use(import_client24.getLoggerPlugin(this.config));
35034
- this.middlewareStack.use(import_client24.getRecursionDetectionPlugin(this.config));
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.replace(/^["']|["']$/g, "");
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 (lstatSync(entryPath).isSymbolicLink()) {
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 lstatSync2,
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 = lstatSync2(source).isSymbolicLink() ? realpathSync(source) : source;
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 (lstatSync2(src).isSymbolicLink())
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 import_client34 = __toESM(require_client2(), 1);
47890
+ var import_client35 = __toESM(require_client2(), 1);
47848
47891
  var import_core2 = __toESM(require_dist_cjs2(), 1);
47849
- var import_client35 = __toESM(require_client(), 1);
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 import_client26 = __toESM(require_client(), 1);
47901
+ var import_client27 = __toESM(require_client(), 1);
47859
47902
  var defaultECSHttpAuthSchemeParametersProvider = async (config, context, input) => {
47860
47903
  return {
47861
- operation: import_client26.getSmithyContext(context).operation,
47862
- region: await import_client26.normalizeProvider(config.region)() || (() => {
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: import_client26.normalizeProvider(config.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 import_client30 = __toESM(require_client2(), 1);
48029
+ var import_client31 = __toESM(require_client2(), 1);
47987
48030
  var import_httpAuthSchemes6 = __toESM(require_httpAuthSchemes(), 1);
47988
- var import_client31 = __toESM(require_client(), 1);
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 import_client29 = __toESM(require_client(), 1);
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 import_client27 = __toESM(require_client2(), 1);
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 = import_client27.awsEndpointFunctions;
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 import_client28 = __toESM(require_client(), 1);
48107
- class ECSServiceException extends import_client28.ServiceException {
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 import_client29.NoOpLogger,
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
- import_client31.emitWarningIfUnsupportedVersion(process.version);
50973
+ import_client32.emitWarningIfUnsupportedVersion(process.version);
50931
50974
  const defaultsMode = import_config38.resolveDefaultsModeConfig(config);
50932
- const defaultConfigProvider = () => defaultsMode().then(import_client31.loadConfigsForDefaultMode);
50975
+ const defaultConfigProvider = () => defaultsMode().then(import_client32.loadConfigsForDefaultMode);
50933
50976
  const clientSharedValues = getRuntimeConfig4(config);
50934
- import_client30.emitWarningIfUnsupportedVersion(process.version);
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 ?? import_client30.createDefaultUserAgentProvider({ serviceId: clientSharedValues.serviceId, clientVersion: package_default3.version }),
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(import_client30.NODE_APP_ID_CONFIG_OPTIONS, loaderConfig)
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 import_client32 = __toESM(require_client2(), 1);
50964
- var import_client33 = __toESM(require_client(), 1);
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(import_client32.getAwsRegionExtensionConfiguration(runtimeConfig), import_client33.getDefaultExtensionConfiguration(runtimeConfig), import_protocols9.getHttpHandlerExtensionConfiguration(runtimeConfig), getHttpAuthExtensionConfiguration3(runtimeConfig));
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, import_client32.resolveAwsRegionExtensionConfiguration(extensionConfiguration), import_client33.resolveDefaultRuntimeConfig(extensionConfiguration), import_protocols9.resolveHttpHandlerRuntimeConfig(extensionConfiguration), resolveHttpAuthRuntimeConfig3(extensionConfiguration));
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 import_client35.Client {
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 = import_client34.resolveUserAgentConfig(_config_1);
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 = import_client34.resolveHostHeaderConfig(_config_4);
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(import_client34.getUserAgentPlugin(this.config));
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(import_client34.getHostHeaderPlugin(this.config));
51034
- this.middlewareStack.use(import_client34.getLoggerPlugin(this.config));
51035
- this.middlewareStack.use(import_client34.getRecursionDetectionPlugin(this.config));
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 import_client36 = __toESM(require_client(), 1);
51093
+ var import_client37 = __toESM(require_client(), 1);
51051
51094
  var import_endpoints9 = __toESM(require_endpoints(), 1);
51052
- var command3 = import_client36.makeBuilder(commonParams3, "AmazonEC2ContainerServiceV20141113", "ECSClient", import_endpoints9.getEndpointPlugin);
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,