@hasna/skills 0.5.4 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/mcp.js CHANGED
@@ -20,14 +20,12 @@ var __toESM = (mod, isNodeMode, target) => {
20
20
  }
21
21
  target = mod != null ? __create(__getProtoOf(mod)) : {};
22
22
  const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
23
- if (mod && typeof mod === "object" || typeof mod === "function") {
24
- for (let key of __getOwnPropNames(mod))
25
- if (!__hasOwnProp.call(to, key))
26
- __defProp(to, key, {
27
- get: __accessProp.bind(mod, key),
28
- enumerable: true
29
- });
30
- }
23
+ for (let key of __getOwnPropNames(mod))
24
+ if (!__hasOwnProp.call(to, key))
25
+ __defProp(to, key, {
26
+ get: __accessProp.bind(mod, key),
27
+ enumerable: true
28
+ });
31
29
  if (canCache)
32
30
  cache.set(mod, to);
33
31
  return to;
@@ -114,55 +112,55 @@ var init_core = __esm(() => {
114
112
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v4/core/util.js
115
113
  var exports_util = {};
116
114
  __export(exports_util, {
117
- BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES,
118
- Class: () => Class,
119
- NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
120
- aborted: () => aborted,
121
- allowsEval: () => allowsEval,
122
- assert: () => assert,
123
- assertEqual: () => assertEqual,
124
- assertIs: () => assertIs,
125
- assertNever: () => assertNever,
126
- assertNotEqual: () => assertNotEqual,
127
- assignProp: () => assignProp,
128
- cached: () => cached,
129
- captureStackTrace: () => captureStackTrace,
130
- cleanEnum: () => cleanEnum,
131
- cleanRegex: () => cleanRegex,
132
- clone: () => clone,
133
- createTransparentProxy: () => createTransparentProxy,
134
- defineLazy: () => defineLazy,
135
- esc: () => esc,
136
- escapeRegex: () => escapeRegex,
137
- extend: () => extend,
138
- finalizeIssue: () => finalizeIssue,
139
- floatSafeRemainder: () => floatSafeRemainder,
140
- getElementAtPath: () => getElementAtPath,
141
- getEnumValues: () => getEnumValues,
142
- getLengthableOrigin: () => getLengthableOrigin,
143
- getParsedType: () => getParsedType,
144
- getSizableOrigin: () => getSizableOrigin,
145
- isObject: () => isObject,
146
- isPlainObject: () => isPlainObject,
147
- issue: () => issue,
148
- joinValues: () => joinValues,
149
- jsonStringifyReplacer: () => jsonStringifyReplacer,
150
- merge: () => merge,
151
- normalizeParams: () => normalizeParams,
152
- nullish: () => nullish,
153
- numKeys: () => numKeys,
154
- omit: () => omit,
155
- optionalKeys: () => optionalKeys,
156
- partial: () => partial,
157
- pick: () => pick,
158
- prefixIssues: () => prefixIssues,
159
- primitiveTypes: () => primitiveTypes,
160
- promiseAllObject: () => promiseAllObject,
161
- propertyKeyTypes: () => propertyKeyTypes,
162
- randomString: () => randomString,
163
- required: () => required,
115
+ unwrapMessage: () => unwrapMessage,
164
116
  stringifyPrimitive: () => stringifyPrimitive,
165
- unwrapMessage: () => unwrapMessage
117
+ required: () => required,
118
+ randomString: () => randomString,
119
+ propertyKeyTypes: () => propertyKeyTypes,
120
+ promiseAllObject: () => promiseAllObject,
121
+ primitiveTypes: () => primitiveTypes,
122
+ prefixIssues: () => prefixIssues,
123
+ pick: () => pick,
124
+ partial: () => partial,
125
+ optionalKeys: () => optionalKeys,
126
+ omit: () => omit,
127
+ numKeys: () => numKeys,
128
+ nullish: () => nullish,
129
+ normalizeParams: () => normalizeParams,
130
+ merge: () => merge,
131
+ jsonStringifyReplacer: () => jsonStringifyReplacer,
132
+ joinValues: () => joinValues,
133
+ issue: () => issue,
134
+ isPlainObject: () => isPlainObject,
135
+ isObject: () => isObject,
136
+ getSizableOrigin: () => getSizableOrigin,
137
+ getParsedType: () => getParsedType,
138
+ getLengthableOrigin: () => getLengthableOrigin,
139
+ getEnumValues: () => getEnumValues,
140
+ getElementAtPath: () => getElementAtPath,
141
+ floatSafeRemainder: () => floatSafeRemainder,
142
+ finalizeIssue: () => finalizeIssue,
143
+ extend: () => extend,
144
+ escapeRegex: () => escapeRegex,
145
+ esc: () => esc,
146
+ defineLazy: () => defineLazy,
147
+ createTransparentProxy: () => createTransparentProxy,
148
+ clone: () => clone,
149
+ cleanRegex: () => cleanRegex,
150
+ cleanEnum: () => cleanEnum,
151
+ captureStackTrace: () => captureStackTrace,
152
+ cached: () => cached,
153
+ assignProp: () => assignProp,
154
+ assertNotEqual: () => assertNotEqual,
155
+ assertNever: () => assertNever,
156
+ assertIs: () => assertIs,
157
+ assertEqual: () => assertEqual,
158
+ assert: () => assert,
159
+ allowsEval: () => allowsEval,
160
+ aborted: () => aborted,
161
+ NUMBER_FORMAT_RANGES: () => NUMBER_FORMAT_RANGES,
162
+ Class: () => Class,
163
+ BIGINT_FORMAT_RANGES: () => BIGINT_FORMAT_RANGES
166
164
  });
167
165
  function assertEqual(val) {
168
166
  return val;
@@ -3901,14 +3899,14 @@ var init_checks2 = __esm(() => {
3901
3899
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v4/classic/iso.js
3902
3900
  var exports_iso = {};
3903
3901
  __export(exports_iso, {
3904
- ZodISODate: () => ZodISODate,
3905
- ZodISODateTime: () => ZodISODateTime,
3906
- ZodISODuration: () => ZodISODuration,
3907
- ZodISOTime: () => ZodISOTime,
3908
- date: () => date2,
3909
- datetime: () => datetime2,
3902
+ time: () => time2,
3910
3903
  duration: () => duration2,
3911
- time: () => time2
3904
+ datetime: () => datetime2,
3905
+ date: () => date2,
3906
+ ZodISOTime: () => ZodISOTime,
3907
+ ZodISODuration: () => ZodISODuration,
3908
+ ZodISODateTime: () => ZodISODateTime,
3909
+ ZodISODate: () => ZodISODate
3912
3910
  });
3913
3911
  function datetime2(params) {
3914
3912
  return _isoDateTime(ZodISODateTime, params);
@@ -5588,7 +5586,7 @@ var package_default;
5588
5586
  var init_package = __esm(() => {
5589
5587
  package_default = {
5590
5588
  name: "@hasna/skills",
5591
- version: "0.5.4",
5589
+ version: "0.5.5",
5592
5590
  description: "Skills library for AI coding agents",
5593
5591
  type: "module",
5594
5592
  bin: {
@@ -6506,31 +6504,32 @@ var init_local_opt_in = __esm(() => {
6506
6504
  // src/lib/fleet-credentials.ts
6507
6505
  var exports_fleet_credentials = {};
6508
6506
  __export(exports_fleet_credentials, {
6509
- MissingSkillsFleetError: () => MissingSkillsFleetError,
6510
- SKILLS_API_KEY_ENV: () => SKILLS_API_KEY_ENV,
6511
- SKILLS_API_KEY_ENV_KEYS: () => SKILLS_API_KEY_ENV_KEYS,
6512
- SKILLS_API_URL_ENV: () => SKILLS_API_URL_ENV,
6513
- SKILLS_API_URL_ENV_KEYS: () => SKILLS_API_URL_ENV_KEYS,
6514
- SKILLS_APP: () => SKILLS_APP,
6515
- SKILLS_LOCAL_OPT_IN_ENV_KEYS: () => SKILLS_LOCAL_OPT_IN_ENV_KEYS,
6516
- SkillsFleetCredentialError: () => SkillsFleetCredentialError,
6517
- configuredSkillsApiUrl: () => configuredSkillsApiUrl,
6518
- isSkillsFleetCredentialError: () => isSkillsFleetCredentialError,
6519
- isSkillsLocalOptIn: () => isSkillsLocalOptIn,
6520
- normalizeSkillsApiOrigin: () => normalizeSkillsApiOrigin,
6521
- noticeLocalSkillsMode: () => noticeLocalSkillsMode,
6522
- requireSkillsApiKey: () => requireSkillsApiKey,
6523
- requireSkillsApiOrigin: () => requireSkillsApiOrigin,
6524
- requireSkillsFleet: () => requireSkillsFleet,
6525
- resetLocalSkillsModeNotice: () => resetLocalSkillsModeNotice,
6526
- resolveSkillsApiKey: () => resolveSkillsApiKey,
6527
- resolveSkillsApiOrigin: () => resolveSkillsApiOrigin,
6528
- resolveSkillsConnection: () => resolveSkillsConnection,
6529
- resolveSkillsFleet: () => resolveSkillsFleet,
6530
- selectsSkillsLocalMode: () => selectsSkillsLocalMode,
6531
- skillsCredentialFilePath: () => skillsCredentialFilePath,
6507
+ skillsCredentialOrReason: () => skillsCredentialOrReason,
6532
6508
  skillsCredentialFiles: () => skillsCredentialFiles,
6533
- skillsCredentialOrReason: () => skillsCredentialOrReason
6509
+ skillsCredentialFilePath: () => skillsCredentialFilePath,
6510
+ skillsApiRequestUrl: () => skillsApiRequestUrl,
6511
+ selectsSkillsLocalMode: () => selectsSkillsLocalMode,
6512
+ resolveSkillsFleet: () => resolveSkillsFleet,
6513
+ resolveSkillsConnection: () => resolveSkillsConnection,
6514
+ resolveSkillsApiOrigin: () => resolveSkillsApiOrigin,
6515
+ resolveSkillsApiKey: () => resolveSkillsApiKey,
6516
+ resetLocalSkillsModeNotice: () => resetLocalSkillsModeNotice,
6517
+ requireSkillsFleet: () => requireSkillsFleet,
6518
+ requireSkillsApiOrigin: () => requireSkillsApiOrigin,
6519
+ requireSkillsApiKey: () => requireSkillsApiKey,
6520
+ noticeLocalSkillsMode: () => noticeLocalSkillsMode,
6521
+ normalizeSkillsApiOrigin: () => normalizeSkillsApiOrigin,
6522
+ isSkillsLocalOptIn: () => isSkillsLocalOptIn,
6523
+ isSkillsFleetCredentialError: () => isSkillsFleetCredentialError,
6524
+ configuredSkillsApiUrl: () => configuredSkillsApiUrl,
6525
+ SkillsFleetCredentialError: () => SkillsFleetCredentialError,
6526
+ SKILLS_LOCAL_OPT_IN_ENV_KEYS: () => SKILLS_LOCAL_OPT_IN_ENV_KEYS,
6527
+ SKILLS_APP: () => SKILLS_APP,
6528
+ SKILLS_API_URL_ENV_KEYS: () => SKILLS_API_URL_ENV_KEYS,
6529
+ SKILLS_API_URL_ENV: () => SKILLS_API_URL_ENV,
6530
+ SKILLS_API_KEY_ENV_KEYS: () => SKILLS_API_KEY_ENV_KEYS,
6531
+ SKILLS_API_KEY_ENV: () => SKILLS_API_KEY_ENV,
6532
+ MissingSkillsFleetError: () => MissingSkillsFleetError
6534
6533
  });
6535
6534
  function isCredentialResolutionError(error2) {
6536
6535
  return error2 instanceof CredentialResolutionError || typeof error2 === "object" && error2 !== null && error2.name === "CredentialResolutionError";
@@ -6549,7 +6548,9 @@ function normalizeSkillsApiOrigin(apiUrl) {
6549
6548
  throw new SkillsFleetCredentialError("A Skills API URL must use HTTPS (or loopback HTTP), without credentials, query or fragment", "INVALID_API_URL");
6550
6549
  }
6551
6550
  const pathname = url.pathname.replace(/\/+$/, "");
6552
- if (pathname === "/api" || pathname === "/api/v1") {
6551
+ if (url.origin === "https://api.hasna.com" && pathname === "/skills/v1") {
6552
+ url.pathname = "/skills";
6553
+ } else if (pathname === "/api" || pathname === "/api/v1") {
6553
6554
  url.pathname = "/";
6554
6555
  } else if (pathname.endsWith("/api/v1")) {
6555
6556
  url.pathname = pathname.slice(0, -"/api/v1".length) || "/";
@@ -6558,6 +6559,21 @@ function normalizeSkillsApiOrigin(apiUrl) {
6558
6559
  }
6559
6560
  return url.toString().replace(/\/+$/, "");
6560
6561
  }
6562
+ function skillsApiRequestUrl(apiUrl, route) {
6563
+ const origin = normalizeSkillsApiOrigin(apiUrl);
6564
+ if (!route.startsWith("/api/") || route.includes("#") || route.includes("\\")) {
6565
+ throw new SkillsFleetCredentialError("Invalid Skills API route", "INVALID_API_URL");
6566
+ }
6567
+ if (origin === "https://api.hasna.com/skills") {
6568
+ if (route === "/api/auth/whoami")
6569
+ return `${origin}/v1/auth/whoami`;
6570
+ if (!route.startsWith("/api/v1/")) {
6571
+ throw new SkillsFleetCredentialError("The internal Skills gateway has no established login contract yet. Select an explicitly configured instance with supported authentication.", "GATEWAY_AUTH_UNAVAILABLE");
6572
+ }
6573
+ return `${origin}${route.slice("/api".length)}`;
6574
+ }
6575
+ return `${origin}${route}`;
6576
+ }
6561
6577
  function configuredSkillsApiUrl(env = process.env, keychain, profile) {
6562
6578
  const declared = SKILLS_API_URL_ENV_KEYS.filter((key) => env[key] !== undefined).map((key) => ({ key, value: env[key] }));
6563
6579
  for (const entry of declared) {
@@ -10636,113 +10652,113 @@ var init_types2 = __esm(() => {
10636
10652
  // ../../node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
10637
10653
  var exports_external = {};
10638
10654
  __export(exports_external, {
10639
- BRAND: () => BRAND,
10640
- DIRTY: () => DIRTY,
10641
- EMPTY_PATH: () => EMPTY_PATH,
10642
- INVALID: () => INVALID,
10643
- NEVER: () => NEVER2,
10644
- OK: () => OK,
10645
- ParseStatus: () => ParseStatus,
10646
- Schema: () => ZodType2,
10647
- ZodAny: () => ZodAny,
10648
- ZodArray: () => ZodArray2,
10649
- ZodBigInt: () => ZodBigInt,
10650
- ZodBoolean: () => ZodBoolean2,
10651
- ZodBranded: () => ZodBranded,
10652
- ZodCatch: () => ZodCatch2,
10653
- ZodDate: () => ZodDate,
10654
- ZodDefault: () => ZodDefault2,
10655
- ZodDiscriminatedUnion: () => ZodDiscriminatedUnion2,
10656
- ZodEffects: () => ZodEffects,
10657
- ZodEnum: () => ZodEnum2,
10658
- ZodError: () => ZodError2,
10659
- ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
10660
- ZodFunction: () => ZodFunction,
10661
- ZodIntersection: () => ZodIntersection2,
10662
- ZodIssueCode: () => ZodIssueCode,
10663
- ZodLazy: () => ZodLazy,
10664
- ZodLiteral: () => ZodLiteral2,
10665
- ZodMap: () => ZodMap,
10666
- ZodNaN: () => ZodNaN,
10667
- ZodNativeEnum: () => ZodNativeEnum,
10668
- ZodNever: () => ZodNever2,
10669
- ZodNull: () => ZodNull2,
10670
- ZodNullable: () => ZodNullable2,
10671
- ZodNumber: () => ZodNumber2,
10672
- ZodObject: () => ZodObject2,
10673
- ZodOptional: () => ZodOptional2,
10674
- ZodParsedType: () => ZodParsedType,
10675
- ZodPipeline: () => ZodPipeline,
10676
- ZodPromise: () => ZodPromise,
10677
- ZodReadonly: () => ZodReadonly2,
10678
- ZodRecord: () => ZodRecord2,
10679
- ZodSchema: () => ZodType2,
10680
- ZodSet: () => ZodSet,
10681
- ZodString: () => ZodString2,
10682
- ZodSymbol: () => ZodSymbol,
10683
- ZodTransformer: () => ZodEffects,
10684
- ZodTuple: () => ZodTuple,
10685
- ZodType: () => ZodType2,
10686
- ZodUndefined: () => ZodUndefined,
10687
- ZodUnion: () => ZodUnion2,
10688
- ZodUnknown: () => ZodUnknown2,
10689
- ZodVoid: () => ZodVoid,
10690
- addIssueToContext: () => addIssueToContext,
10691
- any: () => anyType,
10692
- array: () => arrayType,
10693
- bigint: () => bigIntType,
10694
- boolean: () => booleanType,
10695
- coerce: () => coerce,
10696
- custom: () => custom2,
10697
- date: () => dateType,
10698
- datetimeRegex: () => datetimeRegex,
10699
- defaultErrorMap: () => en_default2,
10700
- discriminatedUnion: () => discriminatedUnionType,
10701
- effect: () => effectsType,
10702
- enum: () => enumType,
10703
- function: () => functionType,
10704
- getErrorMap: () => getErrorMap,
10705
- getParsedType: () => getParsedType2,
10706
- instanceof: () => instanceOfType,
10707
- intersection: () => intersectionType,
10708
- isAborted: () => isAborted,
10709
- isAsync: () => isAsync,
10710
- isDirty: () => isDirty,
10711
- isValid: () => isValid,
10712
- late: () => late,
10713
- lazy: () => lazyType,
10714
- literal: () => literalType,
10715
- makeIssue: () => makeIssue,
10716
- map: () => mapType,
10717
- nan: () => nanType,
10718
- nativeEnum: () => nativeEnumType,
10719
- never: () => neverType,
10720
- null: () => nullType,
10721
- nullable: () => nullableType,
10722
- number: () => numberType,
10723
- object: () => objectType,
10724
- objectUtil: () => objectUtil,
10725
- oboolean: () => oboolean,
10726
- onumber: () => onumber,
10727
- optional: () => optionalType,
10728
- ostring: () => ostring,
10729
- pipeline: () => pipelineType,
10730
- preprocess: () => preprocessType,
10731
- promise: () => promiseType,
10732
- quotelessJson: () => quotelessJson,
10733
- record: () => recordType,
10734
- set: () => setType,
10735
- setErrorMap: () => setErrorMap,
10736
- strictObject: () => strictObjectType,
10737
- string: () => stringType,
10738
- symbol: () => symbolType,
10739
- transformer: () => effectsType,
10740
- tuple: () => tupleType,
10741
- undefined: () => undefinedType,
10742
- union: () => unionType,
10743
- unknown: () => unknownType,
10655
+ void: () => voidType,
10744
10656
  util: () => util,
10745
- void: () => voidType
10657
+ unknown: () => unknownType,
10658
+ union: () => unionType,
10659
+ undefined: () => undefinedType,
10660
+ tuple: () => tupleType,
10661
+ transformer: () => effectsType,
10662
+ symbol: () => symbolType,
10663
+ string: () => stringType,
10664
+ strictObject: () => strictObjectType,
10665
+ setErrorMap: () => setErrorMap,
10666
+ set: () => setType,
10667
+ record: () => recordType,
10668
+ quotelessJson: () => quotelessJson,
10669
+ promise: () => promiseType,
10670
+ preprocess: () => preprocessType,
10671
+ pipeline: () => pipelineType,
10672
+ ostring: () => ostring,
10673
+ optional: () => optionalType,
10674
+ onumber: () => onumber,
10675
+ oboolean: () => oboolean,
10676
+ objectUtil: () => objectUtil,
10677
+ object: () => objectType,
10678
+ number: () => numberType,
10679
+ nullable: () => nullableType,
10680
+ null: () => nullType,
10681
+ never: () => neverType,
10682
+ nativeEnum: () => nativeEnumType,
10683
+ nan: () => nanType,
10684
+ map: () => mapType,
10685
+ makeIssue: () => makeIssue,
10686
+ literal: () => literalType,
10687
+ lazy: () => lazyType,
10688
+ late: () => late,
10689
+ isValid: () => isValid,
10690
+ isDirty: () => isDirty,
10691
+ isAsync: () => isAsync,
10692
+ isAborted: () => isAborted,
10693
+ intersection: () => intersectionType,
10694
+ instanceof: () => instanceOfType,
10695
+ getParsedType: () => getParsedType2,
10696
+ getErrorMap: () => getErrorMap,
10697
+ function: () => functionType,
10698
+ enum: () => enumType,
10699
+ effect: () => effectsType,
10700
+ discriminatedUnion: () => discriminatedUnionType,
10701
+ defaultErrorMap: () => en_default2,
10702
+ datetimeRegex: () => datetimeRegex,
10703
+ date: () => dateType,
10704
+ custom: () => custom2,
10705
+ coerce: () => coerce,
10706
+ boolean: () => booleanType,
10707
+ bigint: () => bigIntType,
10708
+ array: () => arrayType,
10709
+ any: () => anyType,
10710
+ addIssueToContext: () => addIssueToContext,
10711
+ ZodVoid: () => ZodVoid,
10712
+ ZodUnknown: () => ZodUnknown2,
10713
+ ZodUnion: () => ZodUnion2,
10714
+ ZodUndefined: () => ZodUndefined,
10715
+ ZodType: () => ZodType2,
10716
+ ZodTuple: () => ZodTuple,
10717
+ ZodTransformer: () => ZodEffects,
10718
+ ZodSymbol: () => ZodSymbol,
10719
+ ZodString: () => ZodString2,
10720
+ ZodSet: () => ZodSet,
10721
+ ZodSchema: () => ZodType2,
10722
+ ZodRecord: () => ZodRecord2,
10723
+ ZodReadonly: () => ZodReadonly2,
10724
+ ZodPromise: () => ZodPromise,
10725
+ ZodPipeline: () => ZodPipeline,
10726
+ ZodParsedType: () => ZodParsedType,
10727
+ ZodOptional: () => ZodOptional2,
10728
+ ZodObject: () => ZodObject2,
10729
+ ZodNumber: () => ZodNumber2,
10730
+ ZodNullable: () => ZodNullable2,
10731
+ ZodNull: () => ZodNull2,
10732
+ ZodNever: () => ZodNever2,
10733
+ ZodNativeEnum: () => ZodNativeEnum,
10734
+ ZodNaN: () => ZodNaN,
10735
+ ZodMap: () => ZodMap,
10736
+ ZodLiteral: () => ZodLiteral2,
10737
+ ZodLazy: () => ZodLazy,
10738
+ ZodIssueCode: () => ZodIssueCode,
10739
+ ZodIntersection: () => ZodIntersection2,
10740
+ ZodFunction: () => ZodFunction,
10741
+ ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
10742
+ ZodError: () => ZodError2,
10743
+ ZodEnum: () => ZodEnum2,
10744
+ ZodEffects: () => ZodEffects,
10745
+ ZodDiscriminatedUnion: () => ZodDiscriminatedUnion2,
10746
+ ZodDefault: () => ZodDefault2,
10747
+ ZodDate: () => ZodDate,
10748
+ ZodCatch: () => ZodCatch2,
10749
+ ZodBranded: () => ZodBranded,
10750
+ ZodBoolean: () => ZodBoolean2,
10751
+ ZodBigInt: () => ZodBigInt,
10752
+ ZodArray: () => ZodArray2,
10753
+ ZodAny: () => ZodAny,
10754
+ Schema: () => ZodType2,
10755
+ ParseStatus: () => ParseStatus,
10756
+ OK: () => OK,
10757
+ NEVER: () => NEVER2,
10758
+ INVALID: () => INVALID,
10759
+ EMPTY_PATH: () => EMPTY_PATH,
10760
+ DIRTY: () => DIRTY,
10761
+ BRAND: () => BRAND
10746
10762
  });
10747
10763
  var init_external2 = __esm(() => {
10748
10764
  init_errors3();
@@ -13305,7 +13321,7 @@ var init_protocol = __esm(() => {
13305
13321
  });
13306
13322
 
13307
13323
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/code.js
13308
- var require_code = __commonJS(function(exports) {
13324
+ var require_code = __commonJS((exports) => {
13309
13325
  Object.defineProperty(exports, "__esModule", { value: true });
13310
13326
  exports.regexpCode = exports.getEsmExportName = exports.getProperty = exports.safeStringify = exports.stringify = exports.strConcat = exports.addCodeArg = exports.str = exports._ = exports.nil = exports._Code = exports.Name = exports.IDENTIFIER = exports._CodeOrName = undefined;
13311
13327
 
@@ -13459,7 +13475,7 @@ var require_code = __commonJS(function(exports) {
13459
13475
  });
13460
13476
 
13461
13477
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/scope.js
13462
- var require_scope = __commonJS(function(exports) {
13478
+ var require_scope = __commonJS((exports) => {
13463
13479
  Object.defineProperty(exports, "__esModule", { value: true });
13464
13480
  exports.ValueScope = exports.ValueScopeName = exports.Scope = exports.varKinds = exports.UsedValueState = undefined;
13465
13481
  var code_1 = require_code();
@@ -13605,7 +13621,7 @@ var require_scope = __commonJS(function(exports) {
13605
13621
  });
13606
13622
 
13607
13623
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/codegen/index.js
13608
- var require_codegen = __commonJS(function(exports) {
13624
+ var require_codegen = __commonJS((exports) => {
13609
13625
  Object.defineProperty(exports, "__esModule", { value: true });
13610
13626
  exports.or = exports.and = exports.not = exports.CodeGen = exports.operators = exports.varKinds = exports.ValueScopeName = exports.ValueScope = exports.Scope = exports.Name = exports.regexpCode = exports.stringify = exports.getProperty = exports.nil = exports.strConcat = exports.str = exports._ = undefined;
13611
13627
  var code_1 = require_code();
@@ -14315,7 +14331,7 @@ var require_codegen = __commonJS(function(exports) {
14315
14331
  });
14316
14332
 
14317
14333
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/util.js
14318
- var require_util = __commonJS(function(exports) {
14334
+ var require_util = __commonJS((exports) => {
14319
14335
  Object.defineProperty(exports, "__esModule", { value: true });
14320
14336
  exports.checkStrictMode = exports.getErrorPath = exports.Type = exports.useFunc = exports.setEvaluated = exports.evaluatedPropsToName = exports.mergeEvaluated = exports.eachItem = exports.unescapeJsonPointer = exports.escapeJsonPointer = exports.escapeFragment = exports.unescapeFragment = exports.schemaRefOrVal = exports.schemaHasRulesButRef = exports.schemaHasRules = exports.checkUnknownRules = exports.alwaysValidSchema = exports.toHash = undefined;
14321
14337
  var codegen_1 = require_codegen();
@@ -14479,7 +14495,7 @@ var require_util = __commonJS(function(exports) {
14479
14495
  });
14480
14496
 
14481
14497
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/names.js
14482
- var require_names = __commonJS(function(exports) {
14498
+ var require_names = __commonJS((exports) => {
14483
14499
  Object.defineProperty(exports, "__esModule", { value: true });
14484
14500
  var codegen_1 = require_codegen();
14485
14501
  var names = {
@@ -14504,7 +14520,7 @@ var require_names = __commonJS(function(exports) {
14504
14520
  });
14505
14521
 
14506
14522
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/errors.js
14507
- var require_errors = __commonJS(function(exports) {
14523
+ var require_errors = __commonJS((exports) => {
14508
14524
  Object.defineProperty(exports, "__esModule", { value: true });
14509
14525
  exports.extendErrors = exports.resetErrorsCount = exports.reportExtraError = exports.reportError = exports.keyword$DataError = exports.keywordError = undefined;
14510
14526
  var codegen_1 = require_codegen();
@@ -14622,7 +14638,7 @@ var require_errors = __commonJS(function(exports) {
14622
14638
  });
14623
14639
 
14624
14640
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/validate/boolSchema.js
14625
- var require_boolSchema = __commonJS(function(exports) {
14641
+ var require_boolSchema = __commonJS((exports) => {
14626
14642
  Object.defineProperty(exports, "__esModule", { value: true });
14627
14643
  exports.boolOrEmptySchema = exports.topBoolOrEmptySchema = undefined;
14628
14644
  var errors_1 = require_errors();
@@ -14670,7 +14686,7 @@ var require_boolSchema = __commonJS(function(exports) {
14670
14686
  });
14671
14687
 
14672
14688
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/rules.js
14673
- var require_rules = __commonJS(function(exports) {
14689
+ var require_rules = __commonJS((exports) => {
14674
14690
  Object.defineProperty(exports, "__esModule", { value: true });
14675
14691
  exports.getRules = exports.isJSONType = undefined;
14676
14692
  var _jsonTypes = ["string", "number", "integer", "boolean", "null", "object", "array"];
@@ -14698,7 +14714,7 @@ var require_rules = __commonJS(function(exports) {
14698
14714
  });
14699
14715
 
14700
14716
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/validate/applicability.js
14701
- var require_applicability = __commonJS(function(exports) {
14717
+ var require_applicability = __commonJS((exports) => {
14702
14718
  Object.defineProperty(exports, "__esModule", { value: true });
14703
14719
  exports.shouldUseRule = exports.shouldUseGroup = exports.schemaHasRulesForType = undefined;
14704
14720
  function schemaHasRulesForType({ schema, self }, type) {
@@ -14718,7 +14734,7 @@ var require_applicability = __commonJS(function(exports) {
14718
14734
  });
14719
14735
 
14720
14736
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/validate/dataType.js
14721
- var require_dataType = __commonJS(function(exports) {
14737
+ var require_dataType = __commonJS((exports) => {
14722
14738
  Object.defineProperty(exports, "__esModule", { value: true });
14723
14739
  exports.reportTypeError = exports.checkDataTypes = exports.checkDataType = exports.coerceAndCheckDataType = exports.getJSONTypes = exports.getSchemaTypes = exports.DataType = undefined;
14724
14740
  var rules_1 = require_rules();
@@ -14899,7 +14915,7 @@ var require_dataType = __commonJS(function(exports) {
14899
14915
  });
14900
14916
 
14901
14917
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/validate/defaults.js
14902
- var require_defaults = __commonJS(function(exports) {
14918
+ var require_defaults = __commonJS((exports) => {
14903
14919
  Object.defineProperty(exports, "__esModule", { value: true });
14904
14920
  exports.assignDefaults = undefined;
14905
14921
  var codegen_1 = require_codegen();
@@ -14933,7 +14949,7 @@ var require_defaults = __commonJS(function(exports) {
14933
14949
  });
14934
14950
 
14935
14951
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/code.js
14936
- var require_code2 = __commonJS(function(exports) {
14952
+ var require_code2 = __commonJS((exports) => {
14937
14953
  Object.defineProperty(exports, "__esModule", { value: true });
14938
14954
  exports.validateUnion = exports.validateArray = exports.usePattern = exports.callValidateCode = exports.schemaProperties = exports.allSchemaProperties = exports.noPropertyInData = exports.propertyInData = exports.isOwnProperty = exports.hasPropFunc = exports.reportMissingProp = exports.checkMissingProp = exports.checkReportMissingProp = undefined;
14939
14955
  var codegen_1 = require_codegen();
@@ -15062,7 +15078,7 @@ var require_code2 = __commonJS(function(exports) {
15062
15078
  });
15063
15079
 
15064
15080
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/validate/keyword.js
15065
- var require_keyword = __commonJS(function(exports) {
15081
+ var require_keyword = __commonJS((exports) => {
15066
15082
  Object.defineProperty(exports, "__esModule", { value: true });
15067
15083
  exports.validateKeywordUsage = exports.validSchemaType = exports.funcKeywordCode = exports.macroKeywordCode = undefined;
15068
15084
  var codegen_1 = require_codegen();
@@ -15177,7 +15193,7 @@ var require_keyword = __commonJS(function(exports) {
15177
15193
  });
15178
15194
 
15179
15195
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/validate/subschema.js
15180
- var require_subschema = __commonJS(function(exports) {
15196
+ var require_subschema = __commonJS((exports) => {
15181
15197
  Object.defineProperty(exports, "__esModule", { value: true });
15182
15198
  exports.extendSubschemaMode = exports.extendSubschemaData = exports.getSubschema = undefined;
15183
15199
  var codegen_1 = require_codegen();
@@ -15257,7 +15273,7 @@ var require_subschema = __commonJS(function(exports) {
15257
15273
  });
15258
15274
 
15259
15275
  // ../../node_modules/.bun/fast-deep-equal@3.1.3/node_modules/fast-deep-equal/index.js
15260
- var require_fast_deep_equal = __commonJS(function(exports, module) {
15276
+ var require_fast_deep_equal = __commonJS((exports, module) => {
15261
15277
  module.exports = function equal(a, b) {
15262
15278
  if (a === b)
15263
15279
  return true;
@@ -15299,7 +15315,7 @@ var require_fast_deep_equal = __commonJS(function(exports, module) {
15299
15315
  });
15300
15316
 
15301
15317
  // ../../node_modules/.bun/json-schema-traverse@1.0.0/node_modules/json-schema-traverse/index.js
15302
- var require_json_schema_traverse = __commonJS(function(exports, module) {
15318
+ var require_json_schema_traverse = __commonJS((exports, module) => {
15303
15319
  var traverse = module.exports = function(schema, opts, cb) {
15304
15320
  if (typeof opts == "function") {
15305
15321
  cb = opts;
@@ -15382,7 +15398,7 @@ var require_json_schema_traverse = __commonJS(function(exports, module) {
15382
15398
  });
15383
15399
 
15384
15400
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/resolve.js
15385
- var require_resolve = __commonJS(function(exports) {
15401
+ var require_resolve = __commonJS((exports) => {
15386
15402
  Object.defineProperty(exports, "__esModule", { value: true });
15387
15403
  exports.getSchemaRefs = exports.resolveUrl = exports.normalizeId = exports._getFullPath = exports.getFullPath = exports.inlineRef = undefined;
15388
15404
  var util_1 = require_util();
@@ -15535,7 +15551,7 @@ var require_resolve = __commonJS(function(exports) {
15535
15551
  });
15536
15552
 
15537
15553
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/validate/index.js
15538
- var require_validate = __commonJS(function(exports) {
15554
+ var require_validate = __commonJS((exports) => {
15539
15555
  Object.defineProperty(exports, "__esModule", { value: true });
15540
15556
  exports.getData = exports.KeywordCxt = exports.validateFunctionCode = undefined;
15541
15557
  var boolSchema_1 = require_boolSchema();
@@ -16040,7 +16056,7 @@ var require_validate = __commonJS(function(exports) {
16040
16056
  });
16041
16057
 
16042
16058
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/runtime/validation_error.js
16043
- var require_validation_error = __commonJS(function(exports) {
16059
+ var require_validation_error = __commonJS((exports) => {
16044
16060
  Object.defineProperty(exports, "__esModule", { value: true });
16045
16061
 
16046
16062
  class ValidationError extends Error {
@@ -16054,7 +16070,7 @@ var require_validation_error = __commonJS(function(exports) {
16054
16070
  });
16055
16071
 
16056
16072
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/ref_error.js
16057
- var require_ref_error = __commonJS(function(exports) {
16073
+ var require_ref_error = __commonJS((exports) => {
16058
16074
  Object.defineProperty(exports, "__esModule", { value: true });
16059
16075
  var resolve_1 = require_resolve();
16060
16076
 
@@ -16069,7 +16085,7 @@ var require_ref_error = __commonJS(function(exports) {
16069
16085
  });
16070
16086
 
16071
16087
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/compile/index.js
16072
- var require_compile = __commonJS(function(exports) {
16088
+ var require_compile = __commonJS((exports) => {
16073
16089
  Object.defineProperty(exports, "__esModule", { value: true });
16074
16090
  exports.resolveSchema = exports.getCompilingSchema = exports.resolveRef = exports.compileSchema = exports.SchemaEnv = undefined;
16075
16091
  var codegen_1 = require_codegen();
@@ -16290,7 +16306,7 @@ var require_compile = __commonJS(function(exports) {
16290
16306
  });
16291
16307
 
16292
16308
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/refs/data.json
16293
- var require_data = __commonJS(function(exports, module) {
16309
+ var require_data = __commonJS((exports, module) => {
16294
16310
  module.exports = {
16295
16311
  $id: "https://raw.githubusercontent.com/ajv-validator/ajv/master/lib/refs/data.json#",
16296
16312
  description: "Meta-schema for $data reference (JSON AnySchema extension proposal)",
@@ -16307,7 +16323,7 @@ var require_data = __commonJS(function(exports, module) {
16307
16323
  });
16308
16324
 
16309
16325
  // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/utils.js
16310
- var require_utils = __commonJS(function(exports, module) {
16326
+ var require_utils = __commonJS((exports, module) => {
16311
16327
  var isUUID = RegExp.prototype.test.bind(/^[\da-f]{8}-[\da-f]{4}-[\da-f]{4}-[\da-f]{4}-[\da-f]{12}$/iu);
16312
16328
  var isIPv4 = RegExp.prototype.test.bind(/^(?:(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d{2}|[1-9]\d|\d)$/u);
16313
16329
  var isPort = RegExp.prototype.test.bind(/^\d*$/u);
@@ -16824,7 +16840,7 @@ var require_utils = __commonJS(function(exports, module) {
16824
16840
  });
16825
16841
 
16826
16842
  // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/lib/schemes.js
16827
- var require_schemes = __commonJS(function(exports, module) {
16843
+ var require_schemes = __commonJS((exports, module) => {
16828
16844
  var { isUUID } = require_utils();
16829
16845
  var URN_REG = /^([\da-z][\d\-a-z]{0,31}):((?:[\w!$'()*+,\-./:;=@]|%[\da-f]{2})+)$/iu;
16830
16846
  var supportedSchemeNames = [
@@ -16999,7 +17015,7 @@ var require_schemes = __commonJS(function(exports, module) {
16999
17015
  });
17000
17016
 
17001
17017
  // ../../node_modules/.bun/fast-uri@3.1.7/node_modules/fast-uri/index.js
17002
- var require_fast_uri = __commonJS(function(exports, module) {
17018
+ var require_fast_uri = __commonJS((exports, module) => {
17003
17019
  var { normalizeIPv6, removeDotSegments, recomposeAuthority, normalizePercentEncoding, normalizePathEncoding, serializePathEncoding, normalizeQueryFragmentEncoding, encodeQuery, encodeFragment, reescapeHostDelimiters, isIPv4, nonSimpleDomain } = require_utils();
17004
17020
  var { SCHEMES, getSchemeHandler } = require_schemes();
17005
17021
  var VALID_SCHEME = /^[A-Za-z][A-Za-z0-9+.-]*$/u;
@@ -17401,7 +17417,7 @@ var require_fast_uri = __commonJS(function(exports, module) {
17401
17417
  });
17402
17418
 
17403
17419
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/runtime/uri.js
17404
- var require_uri = __commonJS(function(exports) {
17420
+ var require_uri = __commonJS((exports) => {
17405
17421
  Object.defineProperty(exports, "__esModule", { value: true });
17406
17422
  var uri = require_fast_uri();
17407
17423
  uri.code = 'require("ajv/dist/runtime/uri").default';
@@ -17409,7 +17425,7 @@ var require_uri = __commonJS(function(exports) {
17409
17425
  });
17410
17426
 
17411
17427
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/core.js
17412
- var require_core = __commonJS(function(exports) {
17428
+ var require_core = __commonJS((exports) => {
17413
17429
  Object.defineProperty(exports, "__esModule", { value: true });
17414
17430
  exports.CodeGen = exports.Name = exports.nil = exports.stringify = exports.str = exports._ = exports.KeywordCxt = undefined;
17415
17431
  var validate_1 = require_validate();
@@ -18002,7 +18018,7 @@ var require_core = __commonJS(function(exports) {
18002
18018
  });
18003
18019
 
18004
18020
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/id.js
18005
- var require_id = __commonJS(function(exports) {
18021
+ var require_id = __commonJS((exports) => {
18006
18022
  Object.defineProperty(exports, "__esModule", { value: true });
18007
18023
  var def = {
18008
18024
  keyword: "id",
@@ -18014,7 +18030,7 @@ var require_id = __commonJS(function(exports) {
18014
18030
  });
18015
18031
 
18016
18032
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/ref.js
18017
- var require_ref = __commonJS(function(exports) {
18033
+ var require_ref = __commonJS((exports) => {
18018
18034
  Object.defineProperty(exports, "__esModule", { value: true });
18019
18035
  exports.callRef = exports.getValidate = undefined;
18020
18036
  var ref_error_1 = require_ref_error();
@@ -18133,7 +18149,7 @@ var require_ref = __commonJS(function(exports) {
18133
18149
  });
18134
18150
 
18135
18151
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/core/index.js
18136
- var require_core2 = __commonJS(function(exports) {
18152
+ var require_core2 = __commonJS((exports) => {
18137
18153
  Object.defineProperty(exports, "__esModule", { value: true });
18138
18154
  var id_1 = require_id();
18139
18155
  var ref_1 = require_ref();
@@ -18151,7 +18167,7 @@ var require_core2 = __commonJS(function(exports) {
18151
18167
  });
18152
18168
 
18153
18169
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitNumber.js
18154
- var require_limitNumber = __commonJS(function(exports) {
18170
+ var require_limitNumber = __commonJS((exports) => {
18155
18171
  Object.defineProperty(exports, "__esModule", { value: true });
18156
18172
  var codegen_1 = require_codegen();
18157
18173
  var ops = codegen_1.operators;
@@ -18180,7 +18196,7 @@ var require_limitNumber = __commonJS(function(exports) {
18180
18196
  });
18181
18197
 
18182
18198
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/multipleOf.js
18183
- var require_multipleOf = __commonJS(function(exports) {
18199
+ var require_multipleOf = __commonJS((exports) => {
18184
18200
  Object.defineProperty(exports, "__esModule", { value: true });
18185
18201
  var codegen_1 = require_codegen();
18186
18202
  var error2 = {
@@ -18205,7 +18221,7 @@ var require_multipleOf = __commonJS(function(exports) {
18205
18221
  });
18206
18222
 
18207
18223
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/runtime/ucs2length.js
18208
- var require_ucs2length = __commonJS(function(exports) {
18224
+ var require_ucs2length = __commonJS((exports) => {
18209
18225
  Object.defineProperty(exports, "__esModule", { value: true });
18210
18226
  function ucs2length(str) {
18211
18227
  const len = str.length;
@@ -18228,7 +18244,7 @@ var require_ucs2length = __commonJS(function(exports) {
18228
18244
  });
18229
18245
 
18230
18246
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitLength.js
18231
- var require_limitLength = __commonJS(function(exports) {
18247
+ var require_limitLength = __commonJS((exports) => {
18232
18248
  Object.defineProperty(exports, "__esModule", { value: true });
18233
18249
  var codegen_1 = require_codegen();
18234
18250
  var util_1 = require_util();
@@ -18257,7 +18273,7 @@ var require_limitLength = __commonJS(function(exports) {
18257
18273
  });
18258
18274
 
18259
18275
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/pattern.js
18260
- var require_pattern = __commonJS(function(exports) {
18276
+ var require_pattern = __commonJS((exports) => {
18261
18277
  Object.defineProperty(exports, "__esModule", { value: true });
18262
18278
  var code_1 = require_code2();
18263
18279
  var util_1 = require_util();
@@ -18291,7 +18307,7 @@ var require_pattern = __commonJS(function(exports) {
18291
18307
  });
18292
18308
 
18293
18309
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitProperties.js
18294
- var require_limitProperties = __commonJS(function(exports) {
18310
+ var require_limitProperties = __commonJS((exports) => {
18295
18311
  Object.defineProperty(exports, "__esModule", { value: true });
18296
18312
  var codegen_1 = require_codegen();
18297
18313
  var error2 = {
@@ -18317,7 +18333,7 @@ var require_limitProperties = __commonJS(function(exports) {
18317
18333
  });
18318
18334
 
18319
18335
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/required.js
18320
- var require_required = __commonJS(function(exports) {
18336
+ var require_required = __commonJS((exports) => {
18321
18337
  Object.defineProperty(exports, "__esModule", { value: true });
18322
18338
  var code_1 = require_code2();
18323
18339
  var codegen_1 = require_codegen();
@@ -18396,7 +18412,7 @@ var require_required = __commonJS(function(exports) {
18396
18412
  });
18397
18413
 
18398
18414
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/limitItems.js
18399
- var require_limitItems = __commonJS(function(exports) {
18415
+ var require_limitItems = __commonJS((exports) => {
18400
18416
  Object.defineProperty(exports, "__esModule", { value: true });
18401
18417
  var codegen_1 = require_codegen();
18402
18418
  var error2 = {
@@ -18422,7 +18438,7 @@ var require_limitItems = __commonJS(function(exports) {
18422
18438
  });
18423
18439
 
18424
18440
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/runtime/equal.js
18425
- var require_equal = __commonJS(function(exports) {
18441
+ var require_equal = __commonJS((exports) => {
18426
18442
  Object.defineProperty(exports, "__esModule", { value: true });
18427
18443
  var equal = require_fast_deep_equal();
18428
18444
  equal.code = 'require("ajv/dist/runtime/equal").default';
@@ -18430,7 +18446,7 @@ var require_equal = __commonJS(function(exports) {
18430
18446
  });
18431
18447
 
18432
18448
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js
18433
- var require_uniqueItems = __commonJS(function(exports) {
18449
+ var require_uniqueItems = __commonJS((exports) => {
18434
18450
  Object.defineProperty(exports, "__esModule", { value: true });
18435
18451
  var dataType_1 = require_dataType();
18436
18452
  var codegen_1 = require_codegen();
@@ -18494,7 +18510,7 @@ var require_uniqueItems = __commonJS(function(exports) {
18494
18510
  });
18495
18511
 
18496
18512
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/const.js
18497
- var require_const = __commonJS(function(exports) {
18513
+ var require_const = __commonJS((exports) => {
18498
18514
  Object.defineProperty(exports, "__esModule", { value: true });
18499
18515
  var codegen_1 = require_codegen();
18500
18516
  var util_1 = require_util();
@@ -18520,7 +18536,7 @@ var require_const = __commonJS(function(exports) {
18520
18536
  });
18521
18537
 
18522
18538
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/enum.js
18523
- var require_enum = __commonJS(function(exports) {
18539
+ var require_enum = __commonJS((exports) => {
18524
18540
  Object.defineProperty(exports, "__esModule", { value: true });
18525
18541
  var codegen_1 = require_codegen();
18526
18542
  var util_1 = require_util();
@@ -18566,7 +18582,7 @@ var require_enum = __commonJS(function(exports) {
18566
18582
  });
18567
18583
 
18568
18584
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/validation/index.js
18569
- var require_validation = __commonJS(function(exports) {
18585
+ var require_validation = __commonJS((exports) => {
18570
18586
  Object.defineProperty(exports, "__esModule", { value: true });
18571
18587
  var limitNumber_1 = require_limitNumber();
18572
18588
  var multipleOf_1 = require_multipleOf();
@@ -18596,7 +18612,7 @@ var require_validation = __commonJS(function(exports) {
18596
18612
  });
18597
18613
 
18598
18614
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js
18599
- var require_additionalItems = __commonJS(function(exports) {
18615
+ var require_additionalItems = __commonJS((exports) => {
18600
18616
  Object.defineProperty(exports, "__esModule", { value: true });
18601
18617
  exports.validateAdditionalItems = undefined;
18602
18618
  var codegen_1 = require_codegen();
@@ -18646,7 +18662,7 @@ var require_additionalItems = __commonJS(function(exports) {
18646
18662
  });
18647
18663
 
18648
18664
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items.js
18649
- var require_items = __commonJS(function(exports) {
18665
+ var require_items = __commonJS((exports) => {
18650
18666
  Object.defineProperty(exports, "__esModule", { value: true });
18651
18667
  exports.validateTuple = undefined;
18652
18668
  var codegen_1 = require_codegen();
@@ -18700,7 +18716,7 @@ var require_items = __commonJS(function(exports) {
18700
18716
  });
18701
18717
 
18702
18718
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js
18703
- var require_prefixItems = __commonJS(function(exports) {
18719
+ var require_prefixItems = __commonJS((exports) => {
18704
18720
  Object.defineProperty(exports, "__esModule", { value: true });
18705
18721
  var items_1 = require_items();
18706
18722
  var def = {
@@ -18714,7 +18730,7 @@ var require_prefixItems = __commonJS(function(exports) {
18714
18730
  });
18715
18731
 
18716
18732
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/items2020.js
18717
- var require_items2020 = __commonJS(function(exports) {
18733
+ var require_items2020 = __commonJS((exports) => {
18718
18734
  Object.defineProperty(exports, "__esModule", { value: true });
18719
18735
  var codegen_1 = require_codegen();
18720
18736
  var util_1 = require_util();
@@ -18746,7 +18762,7 @@ var require_items2020 = __commonJS(function(exports) {
18746
18762
  });
18747
18763
 
18748
18764
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/contains.js
18749
- var require_contains = __commonJS(function(exports) {
18765
+ var require_contains = __commonJS((exports) => {
18750
18766
  Object.defineProperty(exports, "__esModule", { value: true });
18751
18767
  var codegen_1 = require_codegen();
18752
18768
  var util_1 = require_util();
@@ -18837,7 +18853,7 @@ var require_contains = __commonJS(function(exports) {
18837
18853
  });
18838
18854
 
18839
18855
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/dependencies.js
18840
- var require_dependencies = __commonJS(function(exports) {
18856
+ var require_dependencies = __commonJS((exports) => {
18841
18857
  Object.defineProperty(exports, "__esModule", { value: true });
18842
18858
  exports.validateSchemaDeps = exports.validatePropertyDeps = exports.error = undefined;
18843
18859
  var codegen_1 = require_codegen();
@@ -18922,7 +18938,7 @@ var require_dependencies = __commonJS(function(exports) {
18922
18938
  });
18923
18939
 
18924
18940
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js
18925
- var require_propertyNames = __commonJS(function(exports) {
18941
+ var require_propertyNames = __commonJS((exports) => {
18926
18942
  Object.defineProperty(exports, "__esModule", { value: true });
18927
18943
  var codegen_1 = require_codegen();
18928
18944
  var util_1 = require_util();
@@ -18962,7 +18978,7 @@ var require_propertyNames = __commonJS(function(exports) {
18962
18978
  });
18963
18979
 
18964
18980
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js
18965
- var require_additionalProperties = __commonJS(function(exports) {
18981
+ var require_additionalProperties = __commonJS((exports) => {
18966
18982
  Object.defineProperty(exports, "__esModule", { value: true });
18967
18983
  var code_1 = require_code2();
18968
18984
  var codegen_1 = require_codegen();
@@ -19065,7 +19081,7 @@ var require_additionalProperties = __commonJS(function(exports) {
19065
19081
  });
19066
19082
 
19067
19083
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/properties.js
19068
- var require_properties = __commonJS(function(exports) {
19084
+ var require_properties = __commonJS((exports) => {
19069
19085
  Object.defineProperty(exports, "__esModule", { value: true });
19070
19086
  var validate_1 = require_validate();
19071
19087
  var code_1 = require_code2();
@@ -19120,7 +19136,7 @@ var require_properties = __commonJS(function(exports) {
19120
19136
  });
19121
19137
 
19122
19138
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js
19123
- var require_patternProperties = __commonJS(function(exports) {
19139
+ var require_patternProperties = __commonJS((exports) => {
19124
19140
  Object.defineProperty(exports, "__esModule", { value: true });
19125
19141
  var code_1 = require_code2();
19126
19142
  var codegen_1 = require_codegen();
@@ -19191,7 +19207,7 @@ var require_patternProperties = __commonJS(function(exports) {
19191
19207
  });
19192
19208
 
19193
19209
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/not.js
19194
- var require_not = __commonJS(function(exports) {
19210
+ var require_not = __commonJS((exports) => {
19195
19211
  Object.defineProperty(exports, "__esModule", { value: true });
19196
19212
  var util_1 = require_util();
19197
19213
  var def = {
@@ -19219,7 +19235,7 @@ var require_not = __commonJS(function(exports) {
19219
19235
  });
19220
19236
 
19221
19237
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/anyOf.js
19222
- var require_anyOf = __commonJS(function(exports) {
19238
+ var require_anyOf = __commonJS((exports) => {
19223
19239
  Object.defineProperty(exports, "__esModule", { value: true });
19224
19240
  var code_1 = require_code2();
19225
19241
  var def = {
@@ -19233,7 +19249,7 @@ var require_anyOf = __commonJS(function(exports) {
19233
19249
  });
19234
19250
 
19235
19251
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/oneOf.js
19236
- var require_oneOf = __commonJS(function(exports) {
19252
+ var require_oneOf = __commonJS((exports) => {
19237
19253
  Object.defineProperty(exports, "__esModule", { value: true });
19238
19254
  var codegen_1 = require_codegen();
19239
19255
  var util_1 = require_util();
@@ -19288,7 +19304,7 @@ var require_oneOf = __commonJS(function(exports) {
19288
19304
  });
19289
19305
 
19290
19306
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/allOf.js
19291
- var require_allOf = __commonJS(function(exports) {
19307
+ var require_allOf = __commonJS((exports) => {
19292
19308
  Object.defineProperty(exports, "__esModule", { value: true });
19293
19309
  var util_1 = require_util();
19294
19310
  var def = {
@@ -19312,7 +19328,7 @@ var require_allOf = __commonJS(function(exports) {
19312
19328
  });
19313
19329
 
19314
19330
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/if.js
19315
- var require_if = __commonJS(function(exports) {
19331
+ var require_if = __commonJS((exports) => {
19316
19332
  Object.defineProperty(exports, "__esModule", { value: true });
19317
19333
  var codegen_1 = require_codegen();
19318
19334
  var util_1 = require_util();
@@ -19378,7 +19394,7 @@ var require_if = __commonJS(function(exports) {
19378
19394
  });
19379
19395
 
19380
19396
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/thenElse.js
19381
- var require_thenElse = __commonJS(function(exports) {
19397
+ var require_thenElse = __commonJS((exports) => {
19382
19398
  Object.defineProperty(exports, "__esModule", { value: true });
19383
19399
  var util_1 = require_util();
19384
19400
  var def = {
@@ -19393,7 +19409,7 @@ var require_thenElse = __commonJS(function(exports) {
19393
19409
  });
19394
19410
 
19395
19411
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/applicator/index.js
19396
- var require_applicator = __commonJS(function(exports) {
19412
+ var require_applicator = __commonJS((exports) => {
19397
19413
  Object.defineProperty(exports, "__esModule", { value: true });
19398
19414
  var additionalItems_1 = require_additionalItems();
19399
19415
  var prefixItems_1 = require_prefixItems();
@@ -19436,7 +19452,7 @@ var require_applicator = __commonJS(function(exports) {
19436
19452
  });
19437
19453
 
19438
19454
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/format/format.js
19439
- var require_format = __commonJS(function(exports) {
19455
+ var require_format = __commonJS((exports) => {
19440
19456
  Object.defineProperty(exports, "__esModule", { value: true });
19441
19457
  var codegen_1 = require_codegen();
19442
19458
  var error2 = {
@@ -19523,7 +19539,7 @@ var require_format = __commonJS(function(exports) {
19523
19539
  });
19524
19540
 
19525
19541
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/format/index.js
19526
- var require_format2 = __commonJS(function(exports) {
19542
+ var require_format2 = __commonJS((exports) => {
19527
19543
  Object.defineProperty(exports, "__esModule", { value: true });
19528
19544
  var format_1 = require_format();
19529
19545
  var format = [format_1.default];
@@ -19531,7 +19547,7 @@ var require_format2 = __commonJS(function(exports) {
19531
19547
  });
19532
19548
 
19533
19549
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/metadata.js
19534
- var require_metadata = __commonJS(function(exports) {
19550
+ var require_metadata = __commonJS((exports) => {
19535
19551
  Object.defineProperty(exports, "__esModule", { value: true });
19536
19552
  exports.contentVocabulary = exports.metadataVocabulary = undefined;
19537
19553
  exports.metadataVocabulary = [
@@ -19551,7 +19567,7 @@ var require_metadata = __commonJS(function(exports) {
19551
19567
  });
19552
19568
 
19553
19569
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/draft7.js
19554
- var require_draft7 = __commonJS(function(exports) {
19570
+ var require_draft7 = __commonJS((exports) => {
19555
19571
  Object.defineProperty(exports, "__esModule", { value: true });
19556
19572
  var core_1 = require_core2();
19557
19573
  var validation_1 = require_validation();
@@ -19570,7 +19586,7 @@ var require_draft7 = __commonJS(function(exports) {
19570
19586
  });
19571
19587
 
19572
19588
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/discriminator/types.js
19573
- var require_types = __commonJS(function(exports) {
19589
+ var require_types = __commonJS((exports) => {
19574
19590
  Object.defineProperty(exports, "__esModule", { value: true });
19575
19591
  exports.DiscrError = undefined;
19576
19592
  var DiscrError;
@@ -19581,7 +19597,7 @@ var require_types = __commonJS(function(exports) {
19581
19597
  });
19582
19598
 
19583
19599
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/vocabularies/discriminator/index.js
19584
- var require_discriminator = __commonJS(function(exports) {
19600
+ var require_discriminator = __commonJS((exports) => {
19585
19601
  Object.defineProperty(exports, "__esModule", { value: true });
19586
19602
  var codegen_1 = require_codegen();
19587
19603
  var types_1 = require_types();
@@ -19683,7 +19699,7 @@ var require_discriminator = __commonJS(function(exports) {
19683
19699
  });
19684
19700
 
19685
19701
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/refs/json-schema-draft-07.json
19686
- var require_json_schema_draft_07 = __commonJS(function(exports, module) {
19702
+ var require_json_schema_draft_07 = __commonJS((exports, module) => {
19687
19703
  module.exports = {
19688
19704
  $schema: "http://json-schema.org/draft-07/schema#",
19689
19705
  $id: "http://json-schema.org/draft-07/schema#",
@@ -19838,7 +19854,7 @@ var require_json_schema_draft_07 = __commonJS(function(exports, module) {
19838
19854
  });
19839
19855
 
19840
19856
  // ../../node_modules/.bun/ajv@8.20.0/node_modules/ajv/dist/ajv.js
19841
- var require_ajv = __commonJS(function(exports, module) {
19857
+ var require_ajv = __commonJS((exports, module) => {
19842
19858
  Object.defineProperty(exports, "__esModule", { value: true });
19843
19859
  exports.MissingRefError = exports.ValidationError = exports.CodeGen = exports.Name = exports.nil = exports.stringify = exports.str = exports._ = exports.KeywordCxt = exports.Ajv = undefined;
19844
19860
  var core_1 = require_core();
@@ -19906,7 +19922,7 @@ var require_ajv = __commonJS(function(exports, module) {
19906
19922
  });
19907
19923
 
19908
19924
  // ../../node_modules/.bun/ajv-formats@3.0.1/node_modules/ajv-formats/dist/formats.js
19909
- var require_formats = __commonJS(function(exports) {
19925
+ var require_formats = __commonJS((exports) => {
19910
19926
  Object.defineProperty(exports, "__esModule", { value: true });
19911
19927
  exports.formatNames = exports.fastFormats = exports.fullFormats = undefined;
19912
19928
  function fmtDef(validate, compare) {
@@ -20083,7 +20099,7 @@ var require_formats = __commonJS(function(exports) {
20083
20099
  });
20084
20100
 
20085
20101
  // ../../node_modules/.bun/ajv-formats@3.0.1/node_modules/ajv-formats/dist/limit.js
20086
- var require_limit = __commonJS(function(exports) {
20102
+ var require_limit = __commonJS((exports) => {
20087
20103
  Object.defineProperty(exports, "__esModule", { value: true });
20088
20104
  exports.formatLimitDefinition = undefined;
20089
20105
  var ajv_1 = require_ajv();
@@ -20152,7 +20168,7 @@ var require_limit = __commonJS(function(exports) {
20152
20168
  });
20153
20169
 
20154
20170
  // ../../node_modules/.bun/ajv-formats@3.0.1/node_modules/ajv-formats/dist/index.js
20155
- var require_dist = __commonJS(function(exports, module) {
20171
+ var require_dist = __commonJS((exports, module) => {
20156
20172
  Object.defineProperty(exports, "__esModule", { value: true });
20157
20173
  var formats_1 = require_formats();
20158
20174
  var limit_1 = require_limit();
@@ -23125,6 +23141,39 @@ var init_skill_validation = __esm(() => {
23125
23141
  VALID_PROVENANCE_SOURCES = new Set(["official", "custom", "remote", "private", "private-hosted", "upstream", "extension"]);
23126
23142
  VALID_BIN_COMMAND = /^[a-z0-9][a-z0-9._-]*$/;
23127
23143
  });
23144
+
23145
+ // src/lib/skill-entry-path.ts
23146
+ class SkillEntryPaths {
23147
+ files = new Set;
23148
+ directories = new Set;
23149
+ add(path, maxBytes, invalid, limit) {
23150
+ if (path.length > maxBytes)
23151
+ limit();
23152
+ const encoded = new TextEncoder().encode(path);
23153
+ if (encoded.byteLength > maxBytes)
23154
+ limit();
23155
+ if (new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(encoded) !== path)
23156
+ invalid("Invalid UTF-8 entry path");
23157
+ if (!path || /[\\:\x00-\x1f\x7f]/u.test(path))
23158
+ invalid("Unsafe entry path");
23159
+ if (path.split("/").some((segment) => !segment || segment === "." || segment === ".."))
23160
+ invalid("Unsafe entry path segment");
23161
+ const key = path.normalize("NFC").toLowerCase().normalize("NFC");
23162
+ if (this.files.has(key) || this.directories.has(key))
23163
+ invalid("Duplicate or conflicting entry path");
23164
+ const parents = key.split("/");
23165
+ parents.pop();
23166
+ while (parents.length) {
23167
+ const parent = parents.join("/");
23168
+ if (this.files.has(parent))
23169
+ invalid("Conflicting entry file ancestor");
23170
+ this.directories.add(parent);
23171
+ parents.pop();
23172
+ }
23173
+ this.files.add(key);
23174
+ }
23175
+ }
23176
+
23128
23177
  // src/lib/skill-hash.ts
23129
23178
  import { createHash } from "crypto";
23130
23179
  import { existsSync as existsSync5, readdirSync as readdirSync4, readFileSync as readFileSync5, statSync as statSync4 } from "fs";
@@ -23242,6 +23291,186 @@ function hashBundleFiles(files) {
23242
23291
  hash.update(part);
23243
23292
  return hash.digest("hex");
23244
23293
  }
23294
+ async function hashBundleFilesCooperatively(files, check2) {
23295
+ const hash = createHash(CONTENT_HASH_ALGORITHM);
23296
+ let bytesSinceYield = 0;
23297
+ for (const part of bundleHashParts(files)) {
23298
+ for (let offset = 0;offset < part.byteLength; offset += 64 * 1024) {
23299
+ check2();
23300
+ const chunk = part.subarray(offset, offset + 64 * 1024);
23301
+ hash.update(chunk);
23302
+ bytesSinceYield += chunk.byteLength;
23303
+ if (bytesSinceYield >= 256 * 1024) {
23304
+ await new Promise((resolve2) => setImmediate(resolve2));
23305
+ bytesSinceYield = 0;
23306
+ }
23307
+ }
23308
+ }
23309
+ check2();
23310
+ return hash.digest("hex");
23311
+ }
23312
+ function invalidContent(message = "Invalid content hash input") {
23313
+ throw new ContentHashInputError("CONTENT_HASH_INVALID", message);
23314
+ }
23315
+ function contentLimit(message) {
23316
+ throw new ContentHashInputError("CONTENT_HASH_LIMIT", message);
23317
+ }
23318
+ function contentRecord(value, allowed) {
23319
+ if (!value || typeof value !== "object" || ![Object.prototype, null].includes(Object.getPrototypeOf(value)))
23320
+ invalidContent();
23321
+ const result = Object.create(null);
23322
+ for (const key of Reflect.ownKeys(value)) {
23323
+ if (typeof key !== "string" || !allowed.includes(key))
23324
+ invalidContent();
23325
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
23326
+ if (!descriptor || !("value" in descriptor))
23327
+ invalidContent("Accessor content hash input is unsupported");
23328
+ result[key] = descriptor.value;
23329
+ }
23330
+ return result;
23331
+ }
23332
+ function contentOptions(options) {
23333
+ const record3 = contentRecord(options, ["limits", "signal"]);
23334
+ const limits = { ...CONTENT_HASH_LIMITS };
23335
+ if (record3.limits !== undefined) {
23336
+ const supplied = contentRecord(record3.limits, Object.keys(limits));
23337
+ for (const key of Object.keys(supplied)) {
23338
+ const value = supplied[key];
23339
+ if (typeof value !== "number" || !Number.isSafeInteger(value) || value <= 0 || value > limits[key])
23340
+ contentLimit("Invalid content hash limit");
23341
+ limits[key] = value;
23342
+ }
23343
+ }
23344
+ if (record3.signal !== undefined && !(record3.signal instanceof AbortSignal))
23345
+ invalidContent("Invalid content hash signal");
23346
+ return { limits, signal: record3.signal };
23347
+ }
23348
+ function snapshotContentEntries(entries, limits, check2) {
23349
+ if (!Array.isArray(entries))
23350
+ invalidContent("Content hash entries must be an array");
23351
+ if (entries.length > limits.entries)
23352
+ contentLimit("Content hash entry limit exceeded");
23353
+ if (Reflect.ownKeys(entries).length !== entries.length + 1)
23354
+ invalidContent("Invalid content hash entry array");
23355
+ const snapshot = [];
23356
+ const paths = new SkillEntryPaths;
23357
+ let rawBytes = 0;
23358
+ for (let index = 0;index < entries.length; index++) {
23359
+ check2();
23360
+ const descriptor = Object.getOwnPropertyDescriptor(entries, String(index));
23361
+ if (!descriptor || !("value" in descriptor))
23362
+ invalidContent("Invalid content hash entry array");
23363
+ const entry = contentRecord(descriptor.value, ["path", "bytes", "mode"]);
23364
+ if (typeof entry.path !== "string" || typeof entry.mode !== "number" || !Number.isInteger(entry.mode) || entry.mode < 0 || entry.mode > 511)
23365
+ invalidContent("Invalid regular-file content hash entry");
23366
+ paths.add(entry.path, limits.pathBytes, invalidContent, () => contentLimit("Content hash path limit exceeded"));
23367
+ if (!(entry.bytes instanceof Uint8Array) || !ArrayBuffer.isView(entry.bytes))
23368
+ invalidContent("Content hash entry requires bytes");
23369
+ const size = byteLengthOf.call(entry.bytes);
23370
+ if (!(bufferOf.call(entry.bytes) instanceof ArrayBuffer))
23371
+ invalidContent("Shared content hash bytes are unsupported");
23372
+ if (size > limits.fileBytes || rawBytes + size > limits.rawBytes)
23373
+ contentLimit("Content hash raw byte limit exceeded");
23374
+ if (entry.path === "skill.json" && size > limits.manifestBytes)
23375
+ contentLimit("Content hash manifest byte limit exceeded");
23376
+ rawBytes += size;
23377
+ const bytes = new Uint8Array(new ArrayBuffer(size));
23378
+ bytes.set(entry.bytes);
23379
+ snapshot.push({ path: entry.path, bytes, mode: entry.mode });
23380
+ }
23381
+ check2();
23382
+ return snapshot;
23383
+ }
23384
+ function coveredContentPath(path) {
23385
+ const segments = path.split("/");
23386
+ if (!HASH_COVERAGE.includes(segments[0]))
23387
+ return false;
23388
+ return !segments.slice(1).some((segment, index) => excludedHashEntry(segment, index < segments.length - 2));
23389
+ }
23390
+ function boundedManifest(raw, maxDepth) {
23391
+ let parsed;
23392
+ try {
23393
+ parsed = JSON.parse(raw);
23394
+ } catch {
23395
+ return;
23396
+ }
23397
+ const pending = [{ value: parsed, depth: 1 }];
23398
+ while (pending.length) {
23399
+ const { value, depth } = pending.pop();
23400
+ if (!value || typeof value !== "object")
23401
+ continue;
23402
+ if (depth > maxDepth)
23403
+ contentLimit("Content hash manifest depth limit exceeded");
23404
+ for (const child of Object.values(value))
23405
+ pending.push({ value: child, depth: depth + 1 });
23406
+ }
23407
+ return parsed;
23408
+ }
23409
+ async function hashContentEntries(entries, options) {
23410
+ const { limits, signal } = contentOptions(options);
23411
+ const deadline = performance.now() + limits.timeoutMs;
23412
+ let terminal;
23413
+ const abort = () => {
23414
+ terminal ??= new ContentHashInputError("CONTENT_HASH_ABORTED", "Content hashing aborted");
23415
+ };
23416
+ const timer = setTimeout(() => {
23417
+ terminal ??= new ContentHashInputError("CONTENT_HASH_TIMEOUT", "Content hashing deadline exceeded");
23418
+ }, limits.timeoutMs);
23419
+ const check2 = () => {
23420
+ if (signal?.aborted)
23421
+ abort();
23422
+ if (terminal)
23423
+ throw terminal;
23424
+ if (performance.now() >= deadline)
23425
+ throw new ContentHashInputError("CONTENT_HASH_TIMEOUT", "Content hashing deadline exceeded");
23426
+ };
23427
+ try {
23428
+ signal?.addEventListener("abort", abort, { once: true });
23429
+ check2();
23430
+ const snapshot = snapshotContentEntries(entries, limits, check2);
23431
+ const normalized = [];
23432
+ let normalizedBytes = 0;
23433
+ let manifest;
23434
+ await new Promise((resolve2) => setImmediate(resolve2));
23435
+ for (const entry of snapshot) {
23436
+ check2();
23437
+ if (!coveredContentPath(entry.path))
23438
+ continue;
23439
+ if (entry.path === "skill.json")
23440
+ manifest = boundedManifest(new TextDecoder().decode(entry.bytes), limits.manifestDepth);
23441
+ const file = normalizeBundleFile(entry.path, entry.bytes);
23442
+ check2();
23443
+ if (file.content.byteLength > limits.normalizedFileBytes || normalizedBytes + file.content.byteLength > limits.normalizedBytes)
23444
+ contentLimit("Content hash normalized byte limit exceeded");
23445
+ normalizedBytes += file.content.byteLength;
23446
+ normalized.push(file);
23447
+ await new Promise((resolve2) => setImmediate(resolve2));
23448
+ }
23449
+ normalized.sort((a, b) => a.rel < b.rel ? -1 : a.rel > b.rel ? 1 : 0);
23450
+ check2();
23451
+ return { hash: await hashBundleFilesCooperatively(normalized, check2), manifest };
23452
+ } catch (error2) {
23453
+ if (error2 instanceof ContentHashInputError)
23454
+ throw error2;
23455
+ throw new ContentHashInputError("CONTENT_HASH_INVALID", "Invalid content hash input");
23456
+ } finally {
23457
+ clearTimeout(timer);
23458
+ signal?.removeEventListener("abort", abort);
23459
+ }
23460
+ }
23461
+ async function verifyContentHashFromEntries(entries, options = {}) {
23462
+ const { hash, manifest } = await hashContentEntries(entries, options);
23463
+ const provenance = manifest && typeof manifest === "object" && !Array.isArray(manifest) ? manifest.provenance : undefined;
23464
+ const value = provenance && typeof provenance === "object" && !Array.isArray(provenance) ? provenance.content_hash : undefined;
23465
+ if (value !== undefined && typeof value !== "string")
23466
+ invalidContent("Invalid content hash declaration");
23467
+ const declaredHash = value?.trim() || undefined;
23468
+ if (!declaredHash)
23469
+ return { declared: false, valid: false };
23470
+ if (!/^[a-f0-9]{64}$/.test(declaredHash))
23471
+ return { declared: true, valid: false, declaredHash };
23472
+ return { declared: true, valid: hash === declaredHash, declaredHash, computedHash: hash };
23473
+ }
23245
23474
  function verifyContentHash(skillPath, manifest) {
23246
23475
  const declaredHash = manifest?.provenance?.content_hash?.trim() || undefined;
23247
23476
  if (!declaredHash)
@@ -23257,7 +23486,7 @@ function verifyContentHash(skillPath, manifest) {
23257
23486
  computedHash
23258
23487
  };
23259
23488
  }
23260
- var CONTENT_HASH_ALGORITHM = "sha256", HASH_EXCLUDE_DIRS, HASH_COVERAGE, CONTENT_HASH_LIMITS, typedArrayPrototype, byteLengthOf, bufferOf;
23489
+ var CONTENT_HASH_ALGORITHM = "sha256", HASH_EXCLUDE_DIRS, HASH_COVERAGE, CONTENT_HASH_LIMITS, ContentHashInputError, typedArrayPrototype, byteLengthOf, bufferOf;
23261
23490
  var init_skill_hash = __esm(() => {
23262
23491
  HASH_EXCLUDE_DIRS = new Set([".git", "node_modules", "dist", "build", ".turbo"]);
23263
23492
  HASH_COVERAGE = [
@@ -23282,6 +23511,14 @@ var init_skill_hash = __esm(() => {
23282
23511
  manifestDepth: 64,
23283
23512
  timeoutMs: 5000
23284
23513
  });
23514
+ ContentHashInputError = class ContentHashInputError extends Error {
23515
+ code;
23516
+ constructor(code, message) {
23517
+ super(message);
23518
+ this.code = code;
23519
+ this.name = "ContentHashInputError";
23520
+ }
23521
+ };
23285
23522
  typedArrayPrototype = Object.getPrototypeOf(Uint8Array.prototype);
23286
23523
  byteLengthOf = Object.getOwnPropertyDescriptor(typedArrayPrototype, "byteLength").get;
23287
23524
  bufferOf = Object.getOwnPropertyDescriptor(typedArrayPrototype, "buffer").get;
@@ -24867,7 +25104,14 @@ function getConfiguredApiUrl(env = process.env) {
24867
25104
  }
24868
25105
  function buildSkillsApiUrl(apiUrl, endpoint = "/skills") {
24869
25106
  const url = new URL(apiUrl);
25107
+ if (url.origin === "https://api.hasna.com" && /^\/skills\/(?:api\/)?v1\/skills\/?$/.test(url.pathname)) {
25108
+ url.pathname = "/skills";
25109
+ apiUrl = url.toString();
25110
+ }
24870
25111
  const cleanEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
25112
+ if (normalizeSkillsApiOrigin(apiUrl) === "https://api.hasna.com/skills") {
25113
+ return skillsApiRequestUrl(apiUrl, `/api/v1${cleanEndpoint}`);
25114
+ }
24871
25115
  const pathname = url.pathname.replace(/\/+$/, "");
24872
25116
  const apiBase = /\/api(?:\/v1)?\/skills$/.test(pathname) ? pathname.slice(0, -"/skills".length) : pathname;
24873
25117
  if (/\/api(?:\/v1)?$/.test(apiBase)) {
@@ -25769,7 +26013,7 @@ var MCP_CONTRACT_SCHEMA_VERSION = 1, stringSchema = (description) => ({
25769
26013
  type: "array",
25770
26014
  items,
25771
26015
  ...description ? { description } : {}
25772
- }), skillNameInput, optionalAgentInput, scopeInput, runInputSchema, runArgsSchema, errorSchema, skillSummarySchema, toolPrimitiveSummarySchema, skillToolDependencySchema, validationMessageSchema, validationOutputSchema, installOutputSchema, runOutputSchema, toolContracts, remoteCustomerContracts, contracts, resourceContracts;
26016
+ }), skillNameInput, optionalAgentInput, scopeInput, runInputSchema, runArgsSchema, errorSchema, skillSummarySchema, toolPrimitiveSummarySchema, skillToolDependencySchema, validationMessageSchema, validationOutputSchema, installOutputSchema, runOutputSchema, toolContracts, remoteCustomerContracts, publicationUuidSchema, publicationVerification, privatePublicationContracts, contracts, resourceContracts;
25773
26017
  var init_mcp_contracts = __esm(() => {
25774
26018
  init_remote_customer_operations();
25775
26019
  skillNameInput = stringSchema("skill name or alias.");
@@ -26275,7 +26519,7 @@ var init_mcp_contracts = __esm(() => {
26275
26519
  name: "run_skill",
26276
26520
  title: "Run Skill",
26277
26521
  description: "Run a skill locally or through a configured remote runner. Returns compact stdout/stderr previews and run summaries by default; pass detail:true for full records.",
26278
- params: ["name", "input?", "args?", "detail?", "remote?", "maxCredits?", "maxCostCents?", "idempotency_key?", "files?"],
26522
+ params: ["name", "input?", "args?", "detail?", "remote?", "maxCredits?", "maxCostCents?", "quoteReceipt?", "idempotency_key?", "files?"],
26279
26523
  category: "execution",
26280
26524
  sideEffects: "local-process-or-remote-run",
26281
26525
  stable: true,
@@ -26287,6 +26531,7 @@ var init_mcp_contracts = __esm(() => {
26287
26531
  remote: { type: "boolean", description: "Use the configured server catalog." },
26288
26532
  maxCredits: { type: "integer", minimum: 0, description: "Maximum explicitly approved integer credits; omitted permits only free remote runs." },
26289
26533
  maxCostCents: { type: "integer", minimum: 0, description: "Legacy alias for maxCredits; both must agree." },
26534
+ quoteReceipt: { type: "string", minLength: 1, maxLength: 4096, description: "Opaque approved quote receipt, at most 4096 UTF-8 bytes. Preserve it and the quoted input/args unchanged; never refresh after confirmation." },
26290
26535
  idempotency_key: { type: "string", pattern: "^[A-Za-z0-9._:-]{1,128}$", description: "Stable retry key for the same remote submission." },
26291
26536
  files: { type: "array", maxItems: 10, items: objectSchema({ name: stringSchema("Safe basename"), base64: { type: "string", maxLength: 1398104 }, contentType: stringSchema("MIME type") }, ["name", "base64"]), description: "Inline remote inputs, at most 1 MiB combined." }
26292
26537
  }, ["name"]),
@@ -26570,12 +26815,17 @@ var init_mcp_contracts = __esm(() => {
26570
26815
  name: "quote_skill",
26571
26816
  title: "Quote Remote Skill",
26572
26817
  description: "Get a server credit quote without submitting a run.",
26573
- params: ["name", "input?", "args?"],
26818
+ params: ["name", "input?", "args?", "files?"],
26574
26819
  category: "execution",
26575
26820
  sideEffects: "none",
26576
26821
  stable: true,
26577
- inputSchema: objectSchema({ name: skillNameInput, input: runInputSchema, args: runArgsSchema }, ["name"]),
26578
- outputSchema: objectSchema({ skill: stringSchema("Canonical server skill."), pricing: objectSchema({}, [], "Quoted integer credits.", true) }, ["skill", "pricing"], undefined, true)
26822
+ inputSchema: objectSchema({
26823
+ name: skillNameInput,
26824
+ input: runInputSchema,
26825
+ args: runArgsSchema,
26826
+ files: { type: "array", maxItems: 10, items: objectSchema({ name: stringSchema("Safe basename"), base64: { type: "string", maxLength: 1398104 }, contentType: stringSchema("MIME type") }, ["name", "base64"]), description: "Same inline files to submit after approval, at most 1 MiB combined." }
26827
+ }, ["name"]),
26828
+ outputSchema: objectSchema({ skill: stringSchema("Canonical server skill."), pricing: objectSchema({}, [], "Quoted integer credits.", true), quoteReceipt: { type: "string", minLength: 1, maxLength: 4096, description: "Opaque server quote binding, at most 4096 UTF-8 bytes; preserve verbatim for approval." } }, ["skill", "pricing"], undefined, true)
26579
26829
  });
26580
26830
  remoteCustomerContracts.push({
26581
26831
  name: "download_run_artifact",
@@ -26588,7 +26838,47 @@ var init_mcp_contracts = __esm(() => {
26588
26838
  inputSchema: objectSchema({ run_id: stringSchema("Run identifier."), artifact_id: stringSchema("Artifact identifier.") }, ["run_id", "artifact_id"]),
26589
26839
  outputSchema: objectSchema({ id: stringSchema("Artifact identifier."), fileName: stringSchema("Artifact file name."), base64: stringSchema("Verified bytes."), sha256: stringSchema("SHA256 digest."), byteSize: { type: "integer", minimum: 0 } }, ["id", "fileName", "base64", "sha256", "byteSize"])
26590
26840
  });
26591
- contracts = [...toolContracts, ...remoteCustomerContracts].sort((a, b) => a.name.localeCompare(b.name));
26841
+ publicationUuidSchema = { type: "string", pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" };
26842
+ publicationVerification = {
26843
+ email: { type: "string", format: "email", maxLength: 254 },
26844
+ code: { type: "string", pattern: "^\\d{6}$" },
26845
+ userId: publicationUuidSchema,
26846
+ membershipId: publicationUuidSchema,
26847
+ recoveryDirectory: { type: "string", maxLength: 4096, description: "Absolute host-local recovery directory without symbolic links." }
26848
+ };
26849
+ privatePublicationContracts = [
26850
+ { name: "publish_private_skill", title: "Publish private skill", extras: {
26851
+ directory: { type: "string", maxLength: 4096, description: "Absolute local skill source directory." },
26852
+ skillId: publicationUuidSchema,
26853
+ expectedCurrentVersionId: { oneOf: [publicationUuidSchema, { type: "null" }] },
26854
+ idempotencyKey: publicationUuidSchema,
26855
+ confirm: { const: true },
26856
+ waitMs: { type: "integer", minimum: 0, maximum: 300000 }
26857
+ }, required: ["directory", "skillId", "expectedCurrentVersionId", "confirm"] },
26858
+ { name: "get_private_publication", title: "Get private publication", extras: {}, required: [] },
26859
+ { name: "resume_private_publication", title: "Resume private publication", extras: { confirm: { const: true }, waitMs: { type: "integer", minimum: 0, maximum: 300000 } }, required: ["confirm"] },
26860
+ { name: "cancel_private_publication", title: "Cancel private publication", extras: { confirm: { const: true } }, required: ["confirm"] }
26861
+ ].map((operation) => ({
26862
+ name: operation.name,
26863
+ title: operation.title,
26864
+ description: "Manage private source publication with fresh workspace verification and durable host-local recovery. Upload consent and current version comparison are explicit; private execution remains unavailable.",
26865
+ params: [...Object.keys(publicationVerification), ...Object.keys(operation.extras)],
26866
+ category: "storage",
26867
+ sideEffects: "filesystem",
26868
+ stable: true,
26869
+ inputSchema: objectSchema({ ...publicationVerification, ...operation.extras }, [...Object.keys(publicationVerification), ...operation.required]),
26870
+ outputSchema: objectSchema({
26871
+ recoveryDirectory: { type: "string" },
26872
+ skillId: publicationUuidSchema,
26873
+ intentId: { oneOf: [publicationUuidSchema, { type: "null" }] },
26874
+ state: { type: "string" },
26875
+ versionId: { oneOf: [publicationUuidSchema, { type: "null" }] },
26876
+ committed: { type: "boolean" },
26877
+ executionEnabled: { const: false },
26878
+ nextAction: { type: "string" }
26879
+ }, ["recoveryDirectory", "skillId", "intentId", "state", "versionId", "committed", "executionEnabled", "nextAction"])
26880
+ }));
26881
+ contracts = [...toolContracts, ...remoteCustomerContracts, ...privatePublicationContracts].sort((a, b) => a.name.localeCompare(b.name));
26592
26882
  resourceContracts = [
26593
26883
  {
26594
26884
  uri: "skills://mcp/contracts",
@@ -27656,10 +27946,10 @@ var init_run_routing = __esm(() => {
27656
27946
  // src/lib/blog-article.ts
27657
27947
  var exports_blog_article = {};
27658
27948
  __export(exports_blog_article, {
27659
- ARTICLE_COUNT_ERROR: () => ARTICLE_COUNT_ERROR,
27660
- ARTICLE_GENERATION_SLUG: () => ARTICLE_GENERATION_SLUG,
27949
+ validateBlogArticleRunOptions: () => validateBlogArticleRunOptions,
27661
27950
  ARTICLE_MAX_COUNT: () => ARTICLE_MAX_COUNT,
27662
- validateBlogArticleRunOptions: () => validateBlogArticleRunOptions
27951
+ ARTICLE_GENERATION_SLUG: () => ARTICLE_GENERATION_SLUG,
27952
+ ARTICLE_COUNT_ERROR: () => ARTICLE_COUNT_ERROR
27663
27953
  });
27664
27954
  function validateBlogArticleRunOptions(input, args = [], validation = {}) {
27665
27955
  const options = collectRunOptions(input, args);
@@ -27786,11 +28076,11 @@ var init_blog_article = __esm(() => {
27786
28076
  // src/lib/remote-files.ts
27787
28077
  var exports_remote_files = {};
27788
28078
  __export(exports_remote_files, {
27789
- MAX_REMOTE_FILE_BYTES: () => MAX_REMOTE_FILE_BYTES,
27790
- decodeRemoteFiles: () => decodeRemoteFiles,
27791
- describeRemoteFiles: () => describeRemoteFiles,
28079
+ sha256: () => sha256,
27792
28080
  readBoundedResponse: () => readBoundedResponse,
27793
- sha256: () => sha256
28081
+ describeRemoteFiles: () => describeRemoteFiles,
28082
+ decodeRemoteFiles: () => decodeRemoteFiles,
28083
+ MAX_REMOTE_FILE_BYTES: () => MAX_REMOTE_FILE_BYTES
27794
28084
  });
27795
28085
  import { createHash as createHash3 } from "crypto";
27796
28086
  function describeRemoteFiles(files) {
@@ -28290,8 +28580,17 @@ function creditCount(value) {
28290
28580
  }
28291
28581
  return value;
28292
28582
  }
28583
+ function runQuoteReceipt(value) {
28584
+ if (value === undefined)
28585
+ return;
28586
+ if (typeof value !== "string" || !value.length || Buffer.byteLength(value, "utf8") > 4096) {
28587
+ throw new Error("Invalid quote receipt");
28588
+ }
28589
+ return value;
28590
+ }
28293
28591
  function parseRemoteRunQuote(value) {
28294
28592
  const quote = object4(value);
28593
+ runQuoteReceipt(quote.quoteReceipt);
28295
28594
  const pricing = object4(quote.pricing);
28296
28595
  if (typeof quote.skill !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(quote.skill))
28297
28596
  throw new Error("Invalid quoted skill");
@@ -28462,15 +28761,15 @@ var init_remote_quote_errors = __esm(() => {
28462
28761
  // src/lib/remote-client.ts
28463
28762
  var exports_remote_client = {};
28464
28763
  __export(exports_remote_client, {
28465
- RemoteCapabilityUnavailableError: () => RemoteCapabilityUnavailableError,
28466
- RemoteQuoteUnavailableError: () => RemoteQuoteUnavailableError,
28467
- RemoteRequestError: () => RemoteRequestError,
28468
- RemoteRouteUnsupportedError: () => RemoteRouteUnsupportedError,
28469
- RemoteSkillsClient: () => RemoteSkillsClient,
28470
- RemoteWorkspaceMemberError: () => RemoteWorkspaceMemberError,
28471
- RemoteWorkspaceSelectionError: () => RemoteWorkspaceSelectionError,
28764
+ createRemoteSkillsClientReadOnly: () => createRemoteSkillsClientReadOnly,
28472
28765
  createRemoteSkillsClient: () => createRemoteSkillsClient,
28473
- createRemoteSkillsClientReadOnly: () => createRemoteSkillsClientReadOnly
28766
+ RemoteWorkspaceSelectionError: () => RemoteWorkspaceSelectionError,
28767
+ RemoteWorkspaceMemberError: () => RemoteWorkspaceMemberError,
28768
+ RemoteSkillsClient: () => RemoteSkillsClient,
28769
+ RemoteRouteUnsupportedError: () => RemoteRouteUnsupportedError,
28770
+ RemoteRequestError: () => RemoteRequestError,
28771
+ RemoteQuoteUnavailableError: () => RemoteQuoteUnavailableError,
28772
+ RemoteCapabilityUnavailableError: () => RemoteCapabilityUnavailableError
28474
28773
  });
28475
28774
 
28476
28775
  class RemoteSkillsClient {
@@ -28482,7 +28781,7 @@ class RemoteSkillsClient {
28482
28781
  this.apiUrl = normalizeSkillsApiOrigin(apiUrl);
28483
28782
  }
28484
28783
  async request(path, options) {
28485
- return fetch(`${this.apiUrl}${path}`, {
28784
+ return fetch(skillsApiRequestUrl(this.apiUrl, path), {
28486
28785
  ...options,
28487
28786
  redirect: "error",
28488
28787
  credentials: "omit",
@@ -28542,6 +28841,7 @@ class RemoteSkillsClient {
28542
28841
  return { status: res.status, body };
28543
28842
  }
28544
28843
  async submitRun(slug, input, args, approval = {}) {
28844
+ const quoteReceipt = runQuoteReceipt(approval.quoteReceipt);
28545
28845
  if (approval.idempotencyKey !== undefined && !/^[A-Za-z0-9._:-]{1,128}$/.test(approval.idempotencyKey))
28546
28846
  throw new Error("Idempotency key must be 1-128 URL-safe characters");
28547
28847
  if (approval.maxCostCents !== undefined)
@@ -28558,15 +28858,20 @@ class RemoteSkillsClient {
28558
28858
  ...approval.maxCredits !== undefined ? { maxCredits: approval.maxCredits } : {},
28559
28859
  ...approval.maxCostCents !== undefined ? { maxCostCents: approval.maxCostCents } : {},
28560
28860
  ...approval.idempotencyKey !== undefined ? { idempotencyKey: approval.idempotencyKey } : {},
28561
- ...approval.inputFiles !== undefined ? { files: approval.inputFiles } : {}
28861
+ ...approval.inputFiles !== undefined ? { files: approval.inputFiles } : {},
28862
+ ...quoteReceipt !== undefined ? { quoteReceipt } : {}
28562
28863
  })
28563
28864
  });
28865
+ if (!res.ok) {
28866
+ res.body?.cancel().catch(() => {});
28867
+ throw new RemoteRequestError(`/api/v1/runs/${encodeURIComponent(slug)}`, res.status);
28868
+ }
28564
28869
  return normalizeRemoteSkillRunContract(await res.json(), slug);
28565
28870
  }
28566
- async quoteRun(slug, input = {}, args = []) {
28871
+ async quoteRun(slug, input = {}, args = [], files) {
28567
28872
  const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug)}/quote`, {
28568
28873
  method: "POST",
28569
- body: JSON.stringify({ input, args })
28874
+ body: JSON.stringify({ input, args, ...files === undefined ? {} : { files } })
28570
28875
  }, { quoteRefusal: true });
28571
28876
  return parseRemoteRunQuote(await response.json());
28572
28877
  }
@@ -28582,17 +28887,24 @@ class RemoteSkillsClient {
28582
28887
  return this.capabilities;
28583
28888
  }
28584
28889
  async submitQuotedRun(slug, input = {}, args = [], approval = {}) {
28890
+ runQuoteReceipt(approval.quoteReceipt);
28891
+ ({ input, args, approval } = JSON.parse(JSON.stringify({ input, args, approval })));
28585
28892
  const maximum = creditCount(approval.maxCredits ?? approval.maxCostCents ?? 0);
28586
28893
  if (approval.maxCostCents !== undefined && approval.maxCostCents !== maximum)
28587
28894
  throw new Error("Credit approval fields disagree");
28588
- const quote = await this.quoteRun(slug, input, args);
28589
- if (quote.pricing.costCents > maximum)
28895
+ const quote = approval.quoteReceipt === undefined ? await this.quoteRun(slug, input, args, approval.inputFiles?.length ? approval.inputFiles : undefined) : undefined;
28896
+ if (quote && quote.pricing.costCents > maximum)
28590
28897
  throw new RemoteCreditApprovalError(quote.pricing.costCents, maximum);
28591
28898
  const capabilities = await this.getCapabilities();
28592
28899
  if (!capabilities.capabilities.includes("runs.submit") || capabilities.billing?.boundedRunApproval !== true || capabilities.billing.unit !== "credits") {
28593
28900
  throw new Error("The configured server does not support bounded credit approval; refusing remote submission");
28594
28901
  }
28595
- return this.submitRun(quote.skill, input, args, { ...approval, maxCredits: maximum, maxCostCents: maximum });
28902
+ return this.submitRun(quote?.skill ?? slug, input, args, {
28903
+ ...approval,
28904
+ maxCredits: maximum,
28905
+ maxCostCents: maximum,
28906
+ ...(quote?.quoteReceipt ?? approval.quoteReceipt) === undefined ? {} : { quoteReceipt: quote?.quoteReceipt ?? approval.quoteReceipt }
28907
+ });
28596
28908
  }
28597
28909
  async getIdentity() {
28598
28910
  return (await this.requestNewRoute("/api/auth/whoami")).json();
@@ -28880,6 +29192,10 @@ class RemoteSkillsClient {
28880
29192
  return { id: artifactId, fileName: String(artifact.fileName ?? artifactId), bytes, byteSize: bytes.byteLength, sha256: artifact.sha256 };
28881
29193
  }
28882
29194
  async submitQuotedRunWithFiles(slug, input, args, files, approval = {}) {
29195
+ runQuoteReceipt(approval.quoteReceipt);
29196
+ ({ input, args, approval } = JSON.parse(JSON.stringify({ input, args, approval })));
29197
+ describeRemoteFiles(files);
29198
+ files = files.map((file) => ({ name: file.name, contentType: file.contentType, bytes: new Uint8Array(file.bytes) }));
28883
29199
  const inputFiles = describeRemoteFiles(files);
28884
29200
  if (files.length && !(await this.getCapabilities()).capabilities.includes("runs.uploads"))
28885
29201
  throw new Error("The configured server does not support input uploads");
@@ -28943,7 +29259,7 @@ class RemoteSkillsClient {
28943
29259
  const headers = { Authorization: `Bearer ${this.apiKey}` };
28944
29260
  if (ifMatch)
28945
29261
  headers["If-Match"] = ifMatch;
28946
- return fetch(`${this.apiUrl}/api/v1/skills`, {
29262
+ return fetch(skillsApiRequestUrl(this.apiUrl, "/api/v1/skills"), {
28947
29263
  method: "POST",
28948
29264
  headers,
28949
29265
  body: form,
@@ -29448,11 +29764,12 @@ function registerOperationTools(server) {
29448
29764
  detail: exports_external.boolean().optional(),
29449
29765
  maxCostCents: exports_external.number().int().min(0).max(2147483647).optional().describe("Maximum integer credits explicitly approved by the user for a remote run; omitted permits only free runs"),
29450
29766
  maxCredits: exports_external.number().int().min(0).max(2147483647).optional(),
29767
+ quoteReceipt: exports_external.string().min(1).max(4096).refine((value) => Buffer.byteLength(value, "utf8") <= 4096, "Quote receipt exceeds 4096 UTF-8 bytes").optional().describe("Opaque receipt from the approved quote; send unchanged with the same input, args and files. Never refresh after confirmation."),
29451
29768
  remote: exports_external.boolean().optional().describe("Use the configured server catalog, including skills not installed locally"),
29452
29769
  idempotency_key: exports_external.string().regex(/^[A-Za-z0-9._:-]{1,128}$/).optional().describe("Reuse for the same approved submission after an interrupted response"),
29453
29770
  files: exports_external.array(exports_external.object({ name: exports_external.string(), base64: exports_external.string().max(1398104), contentType: exports_external.string().optional() })).max(10).optional().describe("Inline remote inputs, at most 1 MiB combined; use CLI or SDK for larger files")
29454
29771
  }
29455
- }, async ({ name, input, args, detail, maxCostCents, maxCredits, remote, idempotency_key, files }) => {
29772
+ }, async ({ name, input, args, detail, maxCostCents, maxCredits, quoteReceipt, remote, idempotency_key, files }) => {
29456
29773
  const skill = remote ? { name, serverOwned: true } : getSkill(name);
29457
29774
  if (!skill) {
29458
29775
  return mcpError("SKILL_NOT_FOUND", `Skill '${name}' not found`, findSimilarSkills(name));
@@ -29493,7 +29810,7 @@ function registerOperationTools(server) {
29493
29810
  try {
29494
29811
  const { RemoteSkillsClient: RemoteSkillsClient2 } = await Promise.resolve().then(() => (init_remote_client(), exports_remote_client));
29495
29812
  const client = new RemoteSkillsClient2(routing.apiKey, routing.apiOrigin);
29496
- const run = await client.submitQuotedRunWithFiles(skillName, runInput, runArgs, inputFiles, { maxCredits, maxCostCents, idempotencyKey: idempotency_key ?? runContext.record.id });
29813
+ const run = await client.submitQuotedRunWithFiles(skillName, runInput, runArgs, inputFiles, { maxCredits, maxCostCents, quoteReceipt, idempotencyKey: idempotency_key ?? runContext.record.id });
29497
29814
  if (run.error) {
29498
29815
  writeRunLogs(runContext, "", String(run.error) + `
29499
29816
  `);
@@ -30487,7 +30804,7 @@ async function requestInvitationEmail(origin, action, input) {
30487
30804
  }
30488
30805
  const body = JSON.stringify({ invitationId: value.invitationId, token: value.token, challengeId: value.challengeId, ...action === "accept" ? { code: value.code } : {} });
30489
30806
  try {
30490
- const response = await fetch(`${target}/api/v1/account/invitations/email-${action}`, {
30807
+ const response = await fetch(skillsApiRequestUrl(target, `/api/v1/account/invitations/email-${action}`), {
30491
30808
  method: "POST",
30492
30809
  headers: { "Content-Type": "application/json" },
30493
30810
  body,
@@ -30562,14 +30879,318 @@ var init_remote_invitation_recovery = __esm(() => {
30562
30879
  };
30563
30880
  });
30564
30881
 
30882
+ // src/lib/remote-private-publications.ts
30883
+ import { createHash as createHash5 } from "crypto";
30884
+ function checkedPublicationDeclaration(value) {
30885
+ if (!exact(value, ["idempotencyKey", "version", "expectedCurrentVersionId", "manifestText", "archiveSha256", "archiveByteSize"]) || !publicationUuid(value.idempotencyKey) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || typeof value.manifestText !== "string" || Buffer.byteLength(value.manifestText) > 16384 || !hash(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES)
30886
+ return bad();
30887
+ try {
30888
+ const manifest = JSON.parse(value.manifestText);
30889
+ if (!record7(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash(manifest.provenance?.content_hash))
30890
+ return bad();
30891
+ } catch {
30892
+ return bad();
30893
+ }
30894
+ return Object.freeze({ ...value });
30895
+ }
30896
+ function checkedPublicationView(value, skillId, intentId, declaration) {
30897
+ if (!exact(value, ["id", "skillId", "version", "expectedCurrentVersionId", "archiveSha256", "archiveByteSize", "state", "expiresAt", "createdAt", "versionId"]) || !publicationUuid(value.id) || value.skillId !== skillId || intentId !== undefined && value.id !== intentId || typeof value.version !== "string" || !value.version || value.version.length > 128 || /[\p{Cc}\p{Cs}]/u.test(value.version) || !(value.expectedCurrentVersionId === null || publicationUuid(value.expectedCurrentVersionId)) || !hash(value.archiveSha256) || !Number.isSafeInteger(value.archiveByteSize) || Number(value.archiveByteSize) < 1 || Number(value.archiveByteSize) > PRIVATE_PUBLICATION_MAX_BYTES || typeof value.state !== "string" || !["awaiting_upload", "queued", "verifying", "needs_attention", "committed", "rejected", "cancelled", "expired"].includes(value.state) || !date4(value.expiresAt) || !date4(value.createdAt) || !(value.versionId === null || publicationUuid(value.versionId)) || value.state === "committed" && value.versionId === null)
30898
+ return invalid3();
30899
+ if (declaration && ["version", "expectedCurrentVersionId", "archiveSha256", "archiveByteSize"].some((k) => value[k] !== declaration[k]))
30900
+ return invalid3();
30901
+ return Object.freeze({ ...value });
30902
+ }
30903
+ async function boundedJson(url, init, token, mutation, budget = 15000, signal) {
30904
+ const controller = new AbortController;
30905
+ let reader;
30906
+ let response;
30907
+ const timeout = new PrivatePublicationError("PUBLICATION_UNCONFIRMED", "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
30908
+ let timer;
30909
+ let abort;
30910
+ try {
30911
+ return await Promise.race([(async () => {
30912
+ if (signal?.aborted)
30913
+ throw timeout;
30914
+ response = await fetch(url, {
30915
+ ...init,
30916
+ redirect: "error",
30917
+ credentials: "omit",
30918
+ signal: controller.signal,
30919
+ headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }
30920
+ });
30921
+ const length = response.headers.get("content-length");
30922
+ if (length !== null && (!/^\d+$/.test(length) || Number(length) > 65536))
30923
+ return invalid3();
30924
+ reader = response.body?.getReader();
30925
+ const chunks = [];
30926
+ let size = 0;
30927
+ if (reader)
30928
+ while (true) {
30929
+ const part = await reader.read();
30930
+ if (part.done)
30931
+ break;
30932
+ size += part.value.byteLength;
30933
+ if (size > 65536)
30934
+ return invalid3();
30935
+ chunks.push(part.value);
30936
+ }
30937
+ if (controller.signal.aborted)
30938
+ throw timeout;
30939
+ const bytes = Buffer.concat(chunks);
30940
+ let body;
30941
+ try {
30942
+ body = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
30943
+ } catch {
30944
+ return invalid3();
30945
+ }
30946
+ if (!response.ok) {
30947
+ const code = record7(body) && typeof body.code === "string" && Object.hasOwn(failures, body.code) ? body.code : null;
30948
+ if (code && failures[code][0] === response.status)
30949
+ throw new PrivatePublicationError(code, failures[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
30950
+ throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
30951
+ }
30952
+ return body;
30953
+ })(), new Promise((_, reject) => {
30954
+ abort = () => {
30955
+ controller.abort();
30956
+ reject(timeout);
30957
+ };
30958
+ timer = setTimeout(abort, Math.max(1, Math.min(15000, budget)));
30959
+ signal?.addEventListener("abort", abort, { once: true });
30960
+ })]);
30961
+ } catch (error2) {
30962
+ if (error2 instanceof PrivatePublicationError) {
30963
+ if (mutation && error2.code === "INVALID_PUBLICATION_RESPONSE")
30964
+ throw timeout;
30965
+ throw error2;
30966
+ }
30967
+ throw timeout;
30968
+ } finally {
30969
+ if (timer)
30970
+ clearTimeout(timer);
30971
+ if (abort)
30972
+ signal?.removeEventListener("abort", abort);
30973
+ controller.abort();
30974
+ if (reader)
30975
+ reader.cancel().catch(() => {});
30976
+ else
30977
+ response?.body?.cancel().catch(() => {});
30978
+ }
30979
+ }
30980
+
30981
+ class RemotePrivatePublicationsClient {
30982
+ apiOrigin;
30983
+ organizationId;
30984
+ userId;
30985
+ membershipId;
30986
+ #token;
30987
+ constructor(apiUrl, session) {
30988
+ const checked = parseWorkspaceSession(session, { userId: session?.user?.id, membershipId: session?.user?.membershipId });
30989
+ if (checked.user.role === "viewer")
30990
+ throw new PrivatePublicationError("PUBLICATION_FORBIDDEN", failures.PUBLICATION_FORBIDDEN[1]);
30991
+ this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
30992
+ this.#token = checked.token;
30993
+ this.organizationId = checked.organization.id;
30994
+ this.userId = checked.user.id;
30995
+ this.membershipId = checked.user.membershipId;
30996
+ Object.freeze(this);
30997
+ }
30998
+ async getCapability(options = {}) {
30999
+ if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
31000
+ return bad();
31001
+ const response = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/capabilities"), {}, this.#token, false, options.timeoutMs, options.signal);
31002
+ const p = record7(response) && response.privatePublishing;
31003
+ if (!record7(response) || response.contractVersion !== 1 || response.apiVersion !== 1 || !exact(p, ["contractVersion", "enabled", "authentication", "maxArchiveBytes", "uploadMaxTtlSeconds", "executionEnabled"]) || p.contractVersion !== 1 || typeof p.enabled !== "boolean" || p.authentication !== "interactive-session" || p.maxArchiveBytes !== PRIVATE_PUBLICATION_MAX_BYTES || p.uploadMaxTtlSeconds !== 300 || p.executionEnabled !== false)
31004
+ throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
31005
+ return Object.freeze({ ...p });
31006
+ }
31007
+ async#gate(enabled, options = {}) {
31008
+ if (!(await this.getCapability(options)).enabled && enabled)
31009
+ throw new PrivatePublicationError("PUBLICATION_CAPABILITY_UNAVAILABLE", failures.PUBLICATION_CAPABILITY_UNAVAILABLE[1]);
31010
+ }
31011
+ #path(skillId, intentId) {
31012
+ if (!publicationUuid(skillId) || intentId !== undefined && !publicationUuid(intentId))
31013
+ return bad();
31014
+ return skillsApiRequestUrl(this.apiOrigin, `/api/v1/skills/${skillId}/publication-uploads${intentId ? `/${intentId}` : ""}`);
31015
+ }
31016
+ async#view(path, method, skillId, intentId, declaration, options = {}) {
31017
+ const value = await boundedJson(path, { method, ...method === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method !== "GET", options.timeoutMs, options.signal);
31018
+ try {
31019
+ if (!record7(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
31020
+ return invalid3();
31021
+ return checkedPublicationView(value.upload, skillId, intentId, declaration);
31022
+ } catch (error2) {
31023
+ if (method !== "GET")
31024
+ throw new PrivatePublicationError("PUBLICATION_UNCONFIRMED", "The publication result could not be confirmed. Reconcile the saved intent before another action.", true);
31025
+ throw error2;
31026
+ }
31027
+ }
31028
+ async begin(skillId, input) {
31029
+ const path = this.#path(skillId), declaration = checkedPublicationDeclaration(input);
31030
+ await this.#gate(true);
31031
+ return this.#view(path, "POST", skillId, undefined, declaration);
31032
+ }
31033
+ async get(skillId, intentId, options = {}) {
31034
+ const path = this.#path(skillId, intentId), until = Date.now() + (options.timeoutMs ?? 15000);
31035
+ await this.#gate(false, options);
31036
+ return this.#view(path, "GET", skillId, intentId, undefined, { ...options, timeoutMs: Math.max(1, until - Date.now()) });
31037
+ }
31038
+ async finalize(skillId, intentId) {
31039
+ const path = this.#path(skillId, intentId);
31040
+ await this.#gate(true);
31041
+ return this.#view(`${path}/finalize`, "POST", skillId, intentId);
31042
+ }
31043
+ async cancel(skillId, intentId) {
31044
+ const path = this.#path(skillId, intentId);
31045
+ await this.#gate(false);
31046
+ return this.#view(path, "DELETE", skillId, intentId);
31047
+ }
31048
+ async upload(skillId, intent, bytes) {
31049
+ const captured = checkedPublicationView(intent, skillId), path = this.#path(skillId, captured.id);
31050
+ if (!(bytes instanceof Uint8Array) || bytes.byteLength !== captured.archiveByteSize)
31051
+ return bad();
31052
+ const owned = Buffer.from(bytes);
31053
+ if (captured.state !== "awaiting_upload" || owned.byteLength !== captured.archiveByteSize || publicationSha256(owned) !== captured.archiveSha256)
31054
+ return bad();
31055
+ await this.#gate(true);
31056
+ const value = await boundedJson(`${path}/upload-url`, { method: "POST", body: "{}" }, this.#token, false);
31057
+ const upload = this.#upload(value, captured);
31058
+ const controller = new AbortController;
31059
+ let timer;
31060
+ const uncertain = () => new PrivatePublicationError("PUBLICATION_UPLOAD_UNCONFIRMED", "Upload acceptance is uncertain. Resume this saved intent to finalize and inspect it; do not upload again.", true);
31061
+ try {
31062
+ await Promise.race([(async () => {
31063
+ const response = await fetch(upload.uploadUrl, { method: "PUT", headers: upload.headers, body: owned, redirect: "error", credentials: "omit", signal: controller.signal });
31064
+ response.body?.cancel().catch(() => {});
31065
+ if (response.status !== 200 || controller.signal.aborted)
31066
+ throw uncertain();
31067
+ })(), new Promise((_, reject) => {
31068
+ timer = setTimeout(() => {
31069
+ controller.abort();
31070
+ reject(uncertain());
31071
+ }, 30000);
31072
+ })]);
31073
+ } catch {
31074
+ throw uncertain();
31075
+ } finally {
31076
+ if (timer)
31077
+ clearTimeout(timer);
31078
+ controller.abort();
31079
+ }
31080
+ }
31081
+ #upload(value, intent) {
31082
+ if (!exact(value, ["upload"]) || !exact(value.upload, ["method", "uploadUrl", "headers", "expiresAt"]))
31083
+ return invalid3();
31084
+ const p = value.upload;
31085
+ if (p.method !== "PUT" || typeof p.uploadUrl !== "string" || p.uploadUrl.length > 8192 || /[\x00-\x20\x7f]/.test(p.uploadUrl) || !date4(p.expiresAt) || Date.parse(p.expiresAt) - Date.now() < 1000 || Date.parse(p.expiresAt) - Date.now() > 300000 || Date.parse(p.expiresAt) > Date.parse(intent.expiresAt) || !exact(p.headers, ["content-type", "content-length", "x-amz-checksum-sha256", "x-amz-expected-bucket-owner"]) || p.headers["content-type"] !== "application/gzip" || p.headers["content-length"] !== String(intent.archiveByteSize) || p.headers["x-amz-checksum-sha256"] !== Buffer.from(intent.archiveSha256, "hex").toString("base64") || typeof p.headers["x-amz-expected-bucket-owner"] !== "string" || !/^\d{12}$/.test(p.headers["x-amz-expected-bucket-owner"]))
31086
+ return invalid3();
31087
+ let url;
31088
+ try {
31089
+ url = new URL(p.uploadUrl);
31090
+ } catch {
31091
+ return invalid3();
31092
+ }
31093
+ if (url.protocol !== "https:" || url.port || url.username || url.password || url.hash || !/^[a-z0-9][a-z0-9-]{1,61}[a-z0-9]\.s3\.[a-z]{2}(?:-[a-z]+)+-[1-9]\.amazonaws\.com$/.test(url.hostname) || url.pathname !== `/private-publication-staging/${this.organizationId}/${intent.id}/bundle.tgz` || !url.search || url.searchParams.get("X-Amz-Algorithm") !== "AWS4-HMAC-SHA256" || url.searchParams.get("X-Amz-SignedHeaders") !== "content-length;content-type;host;x-amz-checksum-sha256;x-amz-expected-bucket-owner" || !/^[a-f0-9]{64}$/.test(url.searchParams.get("X-Amz-Signature") ?? ""))
31094
+ return invalid3();
31095
+ const queryKeys = ["X-Amz-Algorithm", "X-Amz-Credential", "X-Amz-Date", "X-Amz-Expires", "X-Amz-Security-Token", "X-Amz-Signature", "X-Amz-SignedHeaders"];
31096
+ if ([...url.searchParams.keys()].sort().join(",") !== queryKeys.sort().join(","))
31097
+ return invalid3();
31098
+ const issued = url.searchParams.get("X-Amz-Date"), ttl = url.searchParams.get("X-Amz-Expires"), credential = url.searchParams.get("X-Amz-Credential");
31099
+ const timestamp3 = /^(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)Z$/.exec(issued);
31100
+ const region = url.hostname.split(".s3.")[1].split(".amazonaws.com")[0];
31101
+ if (!timestamp3 || !/^[1-9]\d{0,2}$/.test(ttl) || Number(ttl) > 300 || !/^[A-Z0-9]{16,128}\//.test(credential) || credential.split("/").slice(1).join("/") !== `${issued.slice(0, 8)}/${region}/s3/aws4_request` || !/^[\x21-\x7e]{1,4096}$/.test(url.searchParams.get("X-Amz-Security-Token")))
31102
+ return invalid3();
31103
+ const issuedAt = Date.parse(`${timestamp3[1]}-${timestamp3[2]}-${timestamp3[3]}T${timestamp3[4]}:${timestamp3[5]}:${timestamp3[6]}Z`);
31104
+ if (!Number.isFinite(issuedAt) || issuedAt > Date.now() + 1000 || issuedAt + Number(ttl) * 1000 !== Date.parse(p.expiresAt))
31105
+ return invalid3();
31106
+ return { method: "PUT", uploadUrl: url.href, expiresAt: p.expiresAt, headers: Object.freeze({ ...p.headers }) };
31107
+ }
31108
+ async wait(skillId, intentId, options = {}) {
31109
+ const timeout = options.timeoutMs ?? 60000;
31110
+ if (!Number.isSafeInteger(timeout) || timeout < 0 || timeout > 300000)
31111
+ return bad();
31112
+ const until = Date.now() + timeout;
31113
+ let previous;
31114
+ while (true) {
31115
+ if (options.signal?.aborted)
31116
+ throw new PrivatePublicationError("PUBLICATION_WAIT_ABORTED", "Stopped waiting. The server publication continues; inspect the saved intent.");
31117
+ let view;
31118
+ try {
31119
+ view = await this.get(skillId, intentId, { timeoutMs: timeout === 0 ? 15000 : Math.max(1, Math.min(15000, until - Date.now())), signal: options.signal });
31120
+ } catch (error2) {
31121
+ if (previous && Date.now() >= until && !options.signal?.aborted)
31122
+ return previous;
31123
+ throw error2;
31124
+ }
31125
+ previous = view;
31126
+ if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
31127
+ return view;
31128
+ await new Promise((resolve2) => {
31129
+ const timer = setTimeout(done, Math.min(1000, until - Date.now()));
31130
+ function done() {
31131
+ clearTimeout(timer);
31132
+ options.signal?.removeEventListener("abort", done);
31133
+ resolve2();
31134
+ }
31135
+ options.signal?.addEventListener("abort", done, { once: true });
31136
+ });
31137
+ }
31138
+ }
31139
+ }
31140
+ var PRIVATE_PUBLICATION_MAX_BYTES, failures, PrivatePublicationError, bad = () => {
31141
+ throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
31142
+ }, invalid3 = () => {
31143
+ throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
31144
+ }, publicationUuid = (v) => typeof v === "string" && /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(v), hash = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v), record7 = (v) => !!v && typeof v === "object" && !Array.isArray(v), exact = (v, keys) => record7(v) && Object.keys(v).sort().join(",") === keys.sort().join(","), date4 = (v) => typeof v === "string" && /^\d{4}-\d\d-\d\dT[0-9:.]+(?:Z|[+-](?:[01]\d|2[0-3]):[0-5]\d)$/.test(v) && Number.isFinite(Date.parse(v)), publicationSha256 = (bytes) => createHash5("sha256").update(bytes).digest("hex");
31145
+ var init_remote_private_publications = __esm(() => {
31146
+ init_fleet_credentials();
31147
+ init_remote_workspace_selection();
31148
+ init_skill_contract();
31149
+ PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
31150
+ failures = {
31151
+ INVALID_REQUEST: [400, "The publication request is invalid."],
31152
+ SESSION_EXPIRED: [401, "Sign in again to manage this publication."],
31153
+ ACCOUNT_UNAVAILABLE: [403, "The account is unavailable."],
31154
+ INTERACTIVE_SESSION_REQUIRED: [403, "An interactive account session is required."],
31155
+ PUBLICATION_FORBIDDEN: [403, "This session cannot manage the publication."],
31156
+ PUBLICATION_ENTITLEMENT_REQUIRED: [403, "The workspace is not entitled to publish private skills."],
31157
+ PUBLICATION_UNAVAILABLE: [404, "The publication is unavailable to this session."],
31158
+ MANIFEST_NAME_MISMATCH: [409, "The manifest name does not match the selected skill."],
31159
+ IDEMPOTENCY_CONFLICT: [409, "This request key already identifies different publication bytes. Use the saved recovery directory."],
31160
+ CURRENT_VERSION_CHANGED: [409, "The current version changed. Inspect it before explicitly starting another publication."],
31161
+ VERSION_EXISTS: [409, "This version already exists."],
31162
+ VERSION_RESERVED: [409, "This version is reserved by another publication."],
31163
+ PUBLICATION_COMMITTED: [409, "The publication is already committed."],
31164
+ PUBLICATION_UPLOAD_UNAVAILABLE: [409, "This publication cannot receive another upload."],
31165
+ PUBLICATION_LIMIT: [429, "The workspace publication limit has been reached."],
31166
+ PUBLICATION_BUSY: [503, "The publication is busy. Reconcile the saved intent before retrying."],
31167
+ PUBLICATION_UNCERTAIN: [503, "The publication outcome is uncertain. Reconcile the saved intent."],
31168
+ PUBLICATION_CAPABILITY_UNAVAILABLE: [503, "Private publishing is not enabled on this server."],
31169
+ PUBLICATION_SIGNING_UNAVAILABLE: [503, "Upload authorization is temporarily unavailable. Keep the same intent."]
31170
+ };
31171
+ PrivatePublicationError = class PrivatePublicationError extends Error {
31172
+ code;
31173
+ uncertain;
31174
+ status;
31175
+ constructor(code, message, uncertain = false, status) {
31176
+ super(message);
31177
+ this.code = code;
31178
+ this.uncertain = uncertain;
31179
+ this.status = status;
31180
+ this.name = "PrivatePublicationError";
31181
+ }
31182
+ };
31183
+ });
31184
+
30565
31185
  // src/lib/remote-auth.ts
30566
31186
  async function requestAuthApi(instance, path, options) {
30567
31187
  const url = normalizeSkillsApiOrigin(instance);
30568
31188
  const safeUrl = url;
30569
- const endpoint = `${(options?.method || "GET").toUpperCase()} ${safeUrl}${path}`;
31189
+ const requestUrl = skillsApiRequestUrl(url, path);
31190
+ const endpoint = `${(options?.method || "GET").toUpperCase()} ${requestUrl}`;
30570
31191
  let res;
30571
31192
  try {
30572
- res = await fetch(`${url}${path}`, {
31193
+ res = await fetch(requestUrl, {
30573
31194
  ...options,
30574
31195
  redirect: "error",
30575
31196
  signal: options?.signal ?? AbortSignal.timeout(15000),
@@ -30584,10 +31205,10 @@ async function requestAuthApi(instance, path, options) {
30584
31205
  const text2 = await res.text();
30585
31206
  const body = text2 ? parseJsonBody(text2) : {};
30586
31207
  if (!res.ok) {
30587
- const record7 = isRecord5(body) ? body : {};
30588
- const detail = typeof record7.detail === "string" ? record7.detail : undefined;
30589
- const error2 = typeof record7.error === "string" ? record7.error : undefined;
30590
- const code = typeof record7.code === "string" ? record7.code : undefined;
31208
+ const record8 = isRecord5(body) ? body : {};
31209
+ const detail = typeof record8.detail === "string" ? record8.detail : undefined;
31210
+ const error2 = typeof record8.error === "string" ? record8.error : undefined;
31211
+ const code = typeof record8.code === "string" ? record8.code : undefined;
30591
31212
  throw new HostedApiError(detail || error2 || `${res.status} ${res.statusText}`, {
30592
31213
  status: res.status,
30593
31214
  code,
@@ -30621,6 +31242,10 @@ class RemoteSkillsAuthClient {
30621
31242
  constructor(apiUrl) {
30622
31243
  this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
30623
31244
  }
31245
+ async openPrivatePublications(email3, code, context) {
31246
+ const origin = this.apiOrigin, captured = workspaceContext(context);
31247
+ return new RemotePrivatePublicationsClient(origin, await this.switchWorkspace(email3, code, captured));
31248
+ }
30624
31249
  requestInvitationEmailChallenge(input) {
30625
31250
  return requestInvitationEmail(this.apiOrigin, "challenge", input);
30626
31251
  }
@@ -30668,9 +31293,10 @@ class RemoteSkillsAuthClient {
30668
31293
  const apiOrigin = this.apiOrigin;
30669
31294
  if (typeof email3 !== "string" || !email3.includes("@") || typeof code !== "string" || !/^\d{6}$/.test(code))
30670
31295
  throw new Error("Fresh email and six-digit verification code are required to manage this account");
31296
+ const requestUrl = skillsApiRequestUrl(apiOrigin, "/api/auth/verify");
30671
31297
  let response;
30672
31298
  try {
30673
- response = await fetch(`${apiOrigin}/api/auth/verify`, {
31299
+ response = await fetch(requestUrl, {
30674
31300
  method: "POST",
30675
31301
  redirect: "error",
30676
31302
  credentials: "omit",
@@ -30764,6 +31390,7 @@ class RemoteSkillsAuthClient {
30764
31390
  var MAX_ERROR_DETAIL_LENGTH = 200, HostedApiError;
30765
31391
  var init_remote_auth = __esm(() => {
30766
31392
  init_remote_invitation_recovery();
31393
+ init_remote_private_publications();
30767
31394
  init_remote_invitations();
30768
31395
  init_remote_workspace_leave();
30769
31396
  init_remote_workspace_selection();
@@ -30966,9 +31593,824 @@ var init_remote_invitation_tools = __esm(() => {
30966
31593
  init_helpers();
30967
31594
  });
30968
31595
 
31596
+ // src/lib/private-publication-customer.ts
31597
+ async function privatePublicationSession(email3, code, requested) {
31598
+ const target = await captureProfileWorkspace("Manage private publications");
31599
+ const context = requested ?? target.context;
31600
+ if (!context || !publicationUuid(context.userId) || !publicationUuid(context.membershipId) || target.context && (context.userId !== target.context.userId || context.membershipId !== target.context.membershipId))
31601
+ throw new PrivatePublicationError("PUBLICATION_CONTEXT_REQUIRED", "Provide the observed user and membership IDs, or select an enrolled workspace profile.");
31602
+ target.unchanged();
31603
+ const client = await new RemoteSkillsAuthClient(target.origin).openPrivatePublications(email3, code, context);
31604
+ target.unchanged();
31605
+ return client;
31606
+ }
31607
+ function privatePublicationCustomerError(error2) {
31608
+ return error2 instanceof PrivatePublicationError ? { error: error2.message, code: error2.code, uncertain: error2.uncertain } : { error: "The publication action could not be confirmed. Preserve the recovery directory and inspect the same intent; credentials were not changed.", code: "PUBLICATION_ACTION_UNCONFIRMED", uncertain: true };
31609
+ }
31610
+ var init_private_publication_customer = __esm(() => {
31611
+ init_remote_auth();
31612
+ init_remote_private_publications();
31613
+ init_workspace_profile();
31614
+ });
31615
+
31616
+ // src/lib/skill-bundle.ts
31617
+ import { createHash as createHash6 } from "crypto";
31618
+ import { readFileSync as readFileSync16, readdirSync as readdirSync10, statSync as statSync11 } from "fs";
31619
+ import { join as join19, relative as relative4 } from "path";
31620
+ import { createGunzip } from "zlib";
31621
+ function isDotenvFile(lower) {
31622
+ if (lower === ".env" || lower.startsWith(".env."))
31623
+ return true;
31624
+ if (lower === "env")
31625
+ return true;
31626
+ if (lower.startsWith("env.")) {
31627
+ const extension = lower.slice(lower.lastIndexOf(".") + 1);
31628
+ return !NON_DOTENV_EXTENSIONS.has(extension);
31629
+ }
31630
+ return false;
31631
+ }
31632
+ function isCredentialFile(name) {
31633
+ const lower = name.toLowerCase();
31634
+ if (ENV_TEMPLATE_NAMES.has(lower))
31635
+ return false;
31636
+ if (isDotenvFile(lower))
31637
+ return true;
31638
+ if (CREDENTIAL_FILENAMES.has(lower))
31639
+ return true;
31640
+ return CREDENTIAL_EXTENSIONS.some((extension) => lower.endsWith(extension));
31641
+ }
31642
+ function ownBytes(view) {
31643
+ const source = view instanceof ArrayBuffer ? new Uint8Array(view) : view;
31644
+ const out = new Uint8Array(new ArrayBuffer(source.byteLength));
31645
+ out.set(source);
31646
+ return out;
31647
+ }
31648
+ function sha256Hex(bytes) {
31649
+ return createHash6("sha256").update(bytes).digest("hex");
31650
+ }
31651
+ function collectSkillBundleEntries(dir) {
31652
+ const entries = [];
31653
+ walk(dir, dir, entries);
31654
+ return entries.sort((a, b) => a.path < b.path ? -1 : a.path > b.path ? 1 : 0);
31655
+ }
31656
+ function walk(root, current, out) {
31657
+ for (const entry of readdirSync10(current, { withFileTypes: true })) {
31658
+ const absolute = join19(current, entry.name);
31659
+ const rel = relative4(root, absolute).split("\\").join("/");
31660
+ const isRootLevel = !rel.includes("/");
31661
+ if (ANY_SEGMENT_EXCLUDES.has(entry.name.toLowerCase()))
31662
+ continue;
31663
+ if (isRootLevel && ROOT_EXCLUDES.has(entry.name.toLowerCase()))
31664
+ continue;
31665
+ if (isRootLevel && TOOL_SIDECAR_FILENAMES.has(entry.name.toLowerCase()))
31666
+ continue;
31667
+ if (entry.name.startsWith("._"))
31668
+ continue;
31669
+ if (entry.isSymbolicLink())
31670
+ continue;
31671
+ if (entry.isDirectory()) {
31672
+ walk(root, absolute, out);
31673
+ continue;
31674
+ }
31675
+ if (!entry.isFile())
31676
+ continue;
31677
+ if (isCredentialFile(entry.name))
31678
+ continue;
31679
+ const stats = statSync11(absolute);
31680
+ out.push({
31681
+ path: rel,
31682
+ bytes: ownBytes(readFileSync16(absolute)),
31683
+ mode: stats.mode & 64 ? 493 : 420
31684
+ });
31685
+ }
31686
+ }
31687
+ function packSkillBundle(dir, options = {}) {
31688
+ const entries = collectSkillBundleEntries(dir);
31689
+ if (entries.length === 0) {
31690
+ throw new Error(`Nothing to pack: ${dir} contains no files after exclusions (.git, node_modules, dist, .env)`);
31691
+ }
31692
+ const unpackedByteSize = entries.reduce((sum, entry) => sum + entry.bytes.byteLength, 0);
31693
+ const max = options.maxUnpackedBytes ?? 0;
31694
+ if (max > 0 && unpackedByteSize > max) {
31695
+ throw new Error(`Skill sources are ${unpackedByteSize} bytes, over the ${max} byte limit. Remove build output or large fixtures.`);
31696
+ }
31697
+ const tar = writeTar(entries);
31698
+ const bytes = canonicalGzip(tar);
31699
+ return {
31700
+ bytes,
31701
+ sha256: sha256Hex(bytes),
31702
+ fileCount: entries.length,
31703
+ unpackedByteSize,
31704
+ paths: entries.map((entry) => entry.path)
31705
+ };
31706
+ }
31707
+ function canonicalGzip(tar) {
31708
+ const bytes = ownBytes(Bun.gzipSync(tar, { level: 6 }));
31709
+ if (bytes.byteLength >= 10) {
31710
+ bytes[4] = 0;
31711
+ bytes[5] = 0;
31712
+ bytes[6] = 0;
31713
+ bytes[7] = 0;
31714
+ bytes[9] = 255;
31715
+ }
31716
+ return bytes;
31717
+ }
31718
+ function writeTar(entries) {
31719
+ const blocks = [];
31720
+ for (const entry of entries) {
31721
+ blocks.push(ustarHeader(entry));
31722
+ blocks.push(entry.bytes);
31723
+ const remainder = entry.bytes.byteLength % BLOCK;
31724
+ if (remainder !== 0)
31725
+ blocks.push(new Uint8Array(new ArrayBuffer(BLOCK - remainder)));
31726
+ }
31727
+ blocks.push(new Uint8Array(new ArrayBuffer(BLOCK * 2)));
31728
+ return concat(blocks);
31729
+ }
31730
+ function ustarHeader(entry) {
31731
+ const header = new Uint8Array(new ArrayBuffer(BLOCK));
31732
+ const encoder = new TextEncoder;
31733
+ const put = (offset, length, value) => {
31734
+ const encoded = encoder.encode(value);
31735
+ if (encoded.byteLength > length) {
31736
+ throw new Error(`Cannot pack '${entry.path}': field does not fit in a ustar header (${encoded.byteLength} > ${length})`);
31737
+ }
31738
+ header.set(encoded, offset);
31739
+ };
31740
+ if (encoder.encode(entry.path).byteLength > 100) {
31741
+ throw new Error(`Cannot pack '${entry.path}': path is longer than the 100 bytes a ustar header holds`);
31742
+ }
31743
+ put(0, 100, entry.path);
31744
+ put(100, 8, `${entry.mode.toString(8).padStart(7, "0")}\x00`);
31745
+ put(108, 8, "0000000\x00");
31746
+ put(116, 8, "0000000\x00");
31747
+ put(124, 12, `${entry.bytes.byteLength.toString(8).padStart(11, "0")}\x00`);
31748
+ put(136, 12, `${0 .toString(8).padStart(11, "0")}\x00`);
31749
+ put(148, 8, " ");
31750
+ put(156, 1, "0");
31751
+ put(257, 6, "ustar\x00");
31752
+ put(263, 2, "00");
31753
+ let checksum = 0;
31754
+ for (const byte of header)
31755
+ checksum += byte;
31756
+ put(148, 8, `${checksum.toString(8).padStart(6, "0")}\x00 `);
31757
+ return header;
31758
+ }
31759
+ function concat(chunks) {
31760
+ const total = chunks.reduce((sum, chunk) => sum + chunk.byteLength, 0);
31761
+ const merged = new Uint8Array(new ArrayBuffer(total));
31762
+ let offset = 0;
31763
+ for (const chunk of chunks) {
31764
+ merged.set(chunk, offset);
31765
+ offset += chunk.byteLength;
31766
+ }
31767
+ return merged;
31768
+ }
31769
+ function invalidBundle(message) {
31770
+ throw new SkillBundleInspectionError("BUNDLE_INVALID", message);
31771
+ }
31772
+ function inspectionLimits(options) {
31773
+ const limits = { ...SKILL_BUNDLE_INSPECTION_LIMITS };
31774
+ for (const key of Object.keys(options.limits ?? {})) {
31775
+ if (!Object.hasOwn(limits, key))
31776
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Unknown bundle limit");
31777
+ const field = key;
31778
+ const value = options.limits[field];
31779
+ if (!Number.isSafeInteger(value) || value <= 0 || value > limits[field]) {
31780
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle limits must be positive integers within the hard ceilings");
31781
+ }
31782
+ limits[field] = value;
31783
+ }
31784
+ return limits;
31785
+ }
31786
+ async function inspectSkillBundle(bundle, options = {}) {
31787
+ const signal = options.signal;
31788
+ const limits = inspectionLimits(options);
31789
+ const deadline = performance.now() + limits.timeoutMs;
31790
+ const check2 = () => {
31791
+ if (signal?.aborted)
31792
+ throw new SkillBundleInspectionError("BUNDLE_ABORTED", "Bundle inspection aborted");
31793
+ if (performance.now() >= deadline)
31794
+ throw new SkillBundleInspectionError("BUNDLE_TIMEOUT", "Bundle inspection deadline exceeded");
31795
+ };
31796
+ check2();
31797
+ if (bundle.byteLength > limits.compressedBytes)
31798
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Compressed bundle exceeds byte limit");
31799
+ const snapshot = ownBytes(bundle);
31800
+ check2();
31801
+ const sha2562 = sha256Hex(snapshot);
31802
+ check2();
31803
+ const parser = new BoundedTarReader(limits, check2);
31804
+ const streamOptions = { chunkSize: 16 * 1024, highWaterMark: 16 * 1024 };
31805
+ const decoder = createGunzip(streamOptions);
31806
+ let terminalError;
31807
+ const stop = (code) => {
31808
+ terminalError ??= new SkillBundleInspectionError(code, code === "BUNDLE_ABORTED" ? "Bundle inspection aborted" : "Bundle inspection deadline exceeded");
31809
+ decoder.destroy(terminalError);
31810
+ };
31811
+ const onAbort = () => stop("BUNDLE_ABORTED");
31812
+ const timer = setTimeout(() => stop("BUNDLE_TIMEOUT"), Math.max(1, deadline - performance.now()));
31813
+ signal?.addEventListener("abort", onAbort, { once: true });
31814
+ let decompressedByteSize = 0;
31815
+ let bytesSinceYield = 0;
31816
+ try {
31817
+ check2();
31818
+ decoder.end(snapshot);
31819
+ for await (const chunk of decoder) {
31820
+ check2();
31821
+ decompressedByteSize += chunk.byteLength;
31822
+ if (decompressedByteSize > limits.decompressedBytes)
31823
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Decompressed bundle exceeds byte limit");
31824
+ parser.push(chunk);
31825
+ bytesSinceYield += chunk.byteLength;
31826
+ if (bytesSinceYield >= 256 * 1024) {
31827
+ await new Promise((resolve2) => setTimeout(resolve2, 0));
31828
+ bytesSinceYield = 0;
31829
+ check2();
31830
+ }
31831
+ }
31832
+ check2();
31833
+ const entries = parser.finish();
31834
+ return {
31835
+ entries,
31836
+ sha256: sha2562,
31837
+ compressedByteSize: snapshot.byteLength,
31838
+ decompressedByteSize,
31839
+ unpackedByteSize: parser.fileBytes,
31840
+ fileCount: entries.length
31841
+ };
31842
+ } catch (error2) {
31843
+ if (terminalError)
31844
+ throw terminalError;
31845
+ if (error2 instanceof SkillBundleInspectionError)
31846
+ throw error2;
31847
+ throw new SkillBundleInspectionError("BUNDLE_INVALID", "Invalid or truncated gzip bundle");
31848
+ } finally {
31849
+ clearTimeout(timer);
31850
+ signal?.removeEventListener("abort", onAbort);
31851
+ decoder.destroy();
31852
+ }
31853
+ }
31854
+
31855
+ class BoundedTarReader {
31856
+ limits;
31857
+ check;
31858
+ header = new Uint8Array(BLOCK);
31859
+ headerOffset = 0;
31860
+ pending;
31861
+ bodyOffset = 0;
31862
+ padding = 0;
31863
+ zeroBlocks = 0;
31864
+ entries = [];
31865
+ paths = new SkillEntryPaths;
31866
+ fileBytes = 0;
31867
+ constructor(limits, check2) {
31868
+ this.limits = limits;
31869
+ this.check = check2;
31870
+ }
31871
+ push(chunk) {
31872
+ let offset = 0;
31873
+ while (offset < chunk.byteLength) {
31874
+ this.check();
31875
+ if (this.pending) {
31876
+ const count = Math.min(this.pending.bytes.byteLength - this.bodyOffset, chunk.byteLength - offset);
31877
+ this.pending.bytes.set(chunk.subarray(offset, offset + count), this.bodyOffset);
31878
+ offset += count;
31879
+ this.bodyOffset += count;
31880
+ if (this.bodyOffset === this.pending.bytes.byteLength) {
31881
+ this.entries.push(this.pending);
31882
+ this.pending = undefined;
31883
+ }
31884
+ } else if (this.padding) {
31885
+ const count = Math.min(this.padding, chunk.byteLength - offset);
31886
+ if (chunk.subarray(offset, offset + count).some((byte) => byte !== 0))
31887
+ invalidBundle("Nonzero tar body padding");
31888
+ offset += count;
31889
+ this.padding -= count;
31890
+ } else {
31891
+ const count = Math.min(BLOCK - this.headerOffset, chunk.byteLength - offset);
31892
+ this.header.set(chunk.subarray(offset, offset + count), this.headerOffset);
31893
+ offset += count;
31894
+ this.headerOffset += count;
31895
+ if (this.headerOffset === BLOCK) {
31896
+ this.readHeader();
31897
+ this.headerOffset = 0;
31898
+ }
31899
+ }
31900
+ }
31901
+ }
31902
+ finish() {
31903
+ this.check();
31904
+ if (this.pending || this.padding || this.headerOffset || this.zeroBlocks < 2)
31905
+ invalidBundle("Truncated tar bundle");
31906
+ return this.entries;
31907
+ }
31908
+ readHeader() {
31909
+ this.check();
31910
+ const h = this.header;
31911
+ if (h.every((byte) => byte === 0)) {
31912
+ this.zeroBlocks++;
31913
+ return;
31914
+ }
31915
+ if (this.zeroBlocks)
31916
+ invalidBundle("Nonzero tar data after terminator");
31917
+ if (this.entries.length >= this.limits.entries)
31918
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle entry limit exceeded");
31919
+ let checksum = 0;
31920
+ for (let i = 0;i < BLOCK; i++)
31921
+ checksum += i >= 148 && i < 156 ? 32 : h[i];
31922
+ if (tarOctal(h.subarray(148, 156)) !== checksum)
31923
+ invalidBundle("Invalid tar header checksum");
31924
+ if (new TextDecoder().decode(h.subarray(257, 265)) !== "ustar\x00" + "00")
31925
+ invalidBundle("Unsupported tar format");
31926
+ if (h[156] !== 48 && h[156] !== 0 || h.subarray(157, 257).some((b) => b !== 0) || h.subarray(345).some((b) => b !== 0))
31927
+ invalidBundle("Unsupported tar entry or path prefix");
31928
+ const mode = tarOctal(h.subarray(100, 108));
31929
+ if (mode > 511)
31930
+ invalidBundle("Unsupported tar permission bits");
31931
+ tarOctal(h.subarray(108, 116));
31932
+ tarOctal(h.subarray(116, 124));
31933
+ tarOctal(h.subarray(136, 148));
31934
+ const size = tarOctal(h.subarray(124, 136));
31935
+ if (size > this.limits.fileBytes || this.fileBytes + size > this.limits.decompressedBytes) {
31936
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle file byte limit exceeded");
31937
+ }
31938
+ const name = h.subarray(0, 100);
31939
+ const end = name.indexOf(0);
31940
+ if (end !== -1 && name.subarray(end).some((b) => b !== 0))
31941
+ invalidBundle("Invalid tar path padding");
31942
+ const raw = end === -1 ? name : name.subarray(0, end);
31943
+ if (raw.byteLength > this.limits.pathBytes)
31944
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle path byte limit exceeded");
31945
+ let path;
31946
+ try {
31947
+ path = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true }).decode(raw);
31948
+ } catch {
31949
+ return invalidBundle("Invalid UTF-8 bundle path");
31950
+ }
31951
+ this.paths.add(path, this.limits.pathBytes, invalidBundle, () => {
31952
+ throw new SkillBundleInspectionError("BUNDLE_LIMIT", "Bundle path byte limit exceeded");
31953
+ });
31954
+ this.fileBytes += size;
31955
+ this.pending = { path, mode, bytes: new Uint8Array(new ArrayBuffer(size)) };
31956
+ this.bodyOffset = 0;
31957
+ this.padding = (BLOCK - size % BLOCK) % BLOCK;
31958
+ if (!size) {
31959
+ this.entries.push(this.pending);
31960
+ this.pending = undefined;
31961
+ }
31962
+ }
31963
+ }
31964
+ function tarOctal(field) {
31965
+ const text2 = new TextDecoder().decode(field);
31966
+ if (!/^[0-7]+[\0 ]*$/.test(text2))
31967
+ invalidBundle("Invalid tar octal field");
31968
+ const value = Number.parseInt(text2, 8);
31969
+ if (!Number.isSafeInteger(value))
31970
+ invalidBundle("Tar integer is out of range");
31971
+ return value;
31972
+ }
31973
+ var BLOCK = 512, ANY_SEGMENT_EXCLUDES, ROOT_EXCLUDES, TOOL_SIDECAR_FILENAMES, CREDENTIAL_FILENAMES, CREDENTIAL_EXTENSIONS, ENV_TEMPLATE_NAMES, NON_DOTENV_EXTENSIONS, SKILL_BUNDLE_INSPECTION_LIMITS, SkillBundleInspectionError;
31974
+ var init_skill_bundle = __esm(() => {
31975
+ ANY_SEGMENT_EXCLUDES = new Set([
31976
+ ".git",
31977
+ ".ds_store",
31978
+ ".system",
31979
+ "node_modules",
31980
+ ".aws",
31981
+ ".ssh",
31982
+ ".gnupg",
31983
+ ".docker"
31984
+ ]);
31985
+ ROOT_EXCLUDES = new Set(["dist", "build", ".turbo"]);
31986
+ TOOL_SIDECAR_FILENAMES = new Set([".hasna-skills.json"]);
31987
+ CREDENTIAL_FILENAMES = new Set([
31988
+ ".npmrc",
31989
+ ".pypirc",
31990
+ ".netrc",
31991
+ ".envrc",
31992
+ ".pgpass",
31993
+ ".git-credentials",
31994
+ "credentials",
31995
+ "id_rsa",
31996
+ "id_dsa",
31997
+ "id_ecdsa",
31998
+ "id_ed25519"
31999
+ ]);
32000
+ CREDENTIAL_EXTENSIONS = [".pem", ".key", ".p12", ".pfx", ".keystore", ".jks"];
32001
+ ENV_TEMPLATE_NAMES = new Set([".env.example", ".env.sample", ".env.template", ".env.dist"]);
32002
+ NON_DOTENV_EXTENSIONS = new Set([
32003
+ "ts",
32004
+ "tsx",
32005
+ "mts",
32006
+ "cts",
32007
+ "js",
32008
+ "jsx",
32009
+ "mjs",
32010
+ "cjs",
32011
+ "json",
32012
+ "jsonc",
32013
+ "json5",
32014
+ "py",
32015
+ "rb",
32016
+ "go",
32017
+ "rs",
32018
+ "java",
32019
+ "kt",
32020
+ "kts",
32021
+ "swift",
32022
+ "c",
32023
+ "h",
32024
+ "cc",
32025
+ "cpp",
32026
+ "hpp",
32027
+ "cs",
32028
+ "php",
32029
+ "sh",
32030
+ "bash",
32031
+ "zsh",
32032
+ "fish",
32033
+ "ps1",
32034
+ "bat",
32035
+ "cmd",
32036
+ "lua",
32037
+ "pl",
32038
+ "pm",
32039
+ "r",
32040
+ "jl",
32041
+ "dart",
32042
+ "ex",
32043
+ "exs",
32044
+ "scala",
32045
+ "clj",
32046
+ "cljs",
32047
+ "groovy",
32048
+ "gradle",
32049
+ "vb",
32050
+ "fs",
32051
+ "yaml",
32052
+ "yml",
32053
+ "toml",
32054
+ "ini",
32055
+ "xml",
32056
+ "csv",
32057
+ "tsv",
32058
+ "html",
32059
+ "htm",
32060
+ "css",
32061
+ "scss",
32062
+ "sass",
32063
+ "less",
32064
+ "md",
32065
+ "mdx",
32066
+ "txt",
32067
+ "rst",
32068
+ "adoc",
32069
+ "sql",
32070
+ "graphql",
32071
+ "gql",
32072
+ "proto",
32073
+ "d",
32074
+ "png",
32075
+ "jpg",
32076
+ "jpeg",
32077
+ "gif",
32078
+ "svg",
32079
+ "webp",
32080
+ "ico",
32081
+ "bmp",
32082
+ "pdf",
32083
+ "woff",
32084
+ "woff2",
32085
+ "ttf",
32086
+ "otf",
32087
+ "eot",
32088
+ "mp3",
32089
+ "mp4",
32090
+ "wav",
32091
+ "webm",
32092
+ "zip",
32093
+ "gz",
32094
+ "tar",
32095
+ "wasm"
32096
+ ]);
32097
+ SKILL_BUNDLE_INSPECTION_LIMITS = Object.freeze({
32098
+ compressedBytes: 16 * 1024 * 1024,
32099
+ decompressedBytes: 64 * 1024 * 1024,
32100
+ entries: 1024,
32101
+ fileBytes: 16 * 1024 * 1024,
32102
+ pathBytes: 100,
32103
+ timeoutMs: 5000
32104
+ });
32105
+ SkillBundleInspectionError = class SkillBundleInspectionError extends Error {
32106
+ code;
32107
+ constructor(code, message) {
32108
+ super(message);
32109
+ this.code = code;
32110
+ this.name = "SkillBundleInspectionError";
32111
+ }
32112
+ };
32113
+ });
32114
+
32115
+ // src/lib/private-publication-recovery.ts
32116
+ import { constants as constants3, closeSync as closeSync4, fsyncSync, fstatSync as fstatSync4, lstatSync as lstatSync5, mkdirSync as mkdirSync11, openSync as openSync4, readSync as readSync2, realpathSync as realpathSync2, renameSync as renameSync4, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "fs";
32117
+ import { dirname as dirname8, isAbsolute as isAbsolute4, join as join20, resolve as resolve2 } from "path";
32118
+ import { randomUUID } from "crypto";
32119
+ function safeDirectory(directory) {
32120
+ if (!isAbsolute4(directory) || directory !== resolve2(directory) || realpathSync2(directory) !== directory)
32121
+ return fail2();
32122
+ for (let path = directory;; path = dirname8(path)) {
32123
+ const stat2 = lstatSync5(path);
32124
+ if (!stat2.isDirectory() || stat2.isSymbolicLink())
32125
+ return fail2();
32126
+ if (path === dirname8(path))
32127
+ break;
32128
+ }
32129
+ const own = lstatSync5(directory);
32130
+ if ((own.mode & 63) !== 0 || process.getuid && own.uid !== process.getuid())
32131
+ return fail2();
32132
+ return { dev: own.dev, ino: own.ino };
32133
+ }
32134
+ function unchangedDirectory(directory, identity) {
32135
+ const now = safeDirectory(directory);
32136
+ if (now.dev !== identity.dev || now.ino !== identity.ino)
32137
+ return fail2();
32138
+ }
32139
+ function readOwned(directory, name, max) {
32140
+ const identity = safeDirectory(directory), file = join20(directory, name);
32141
+ const fd = openSync4(file, constants3.O_RDONLY | constants3.O_NOFOLLOW);
32142
+ try {
32143
+ const stat2 = fstatSync4(fd);
32144
+ if (!stat2.isFile() || stat2.nlink !== 1 || stat2.size > max || stat2.size < 1 || (stat2.mode & 63) !== 0 || process.getuid && stat2.uid !== process.getuid())
32145
+ return fail2();
32146
+ const buffer = Buffer.alloc(Math.min(max, stat2.size) + 1);
32147
+ let length = 0;
32148
+ while (length < buffer.length) {
32149
+ const count = readSync2(fd, buffer, length, buffer.length - length, length);
32150
+ if (count === 0)
32151
+ break;
32152
+ length += count;
32153
+ }
32154
+ const bytes = buffer.subarray(0, length), after = fstatSync4(fd);
32155
+ unchangedDirectory(directory, identity);
32156
+ if (bytes.length !== stat2.size || stat2.size !== after.size || stat2.mtimeMs !== after.mtimeMs || stat2.ctimeMs !== after.ctimeMs)
32157
+ return fail2();
32158
+ return bytes;
32159
+ } finally {
32160
+ closeSync4(fd);
32161
+ }
32162
+ }
32163
+ function writeOwned(directory, name, bytes) {
32164
+ const fd = openSync4(join20(directory, name), constants3.O_WRONLY | constants3.O_CREAT | constants3.O_EXCL | constants3.O_NOFOLLOW, 384);
32165
+ try {
32166
+ writeFileSync10(fd, bytes);
32167
+ fsyncSync(fd);
32168
+ } finally {
32169
+ closeSync4(fd);
32170
+ }
32171
+ }
32172
+ function save(directory, value) {
32173
+ const identity = safeDirectory(directory), temporary = `.receipt-${randomUUID()}.json`;
32174
+ writeOwned(directory, temporary, JSON.stringify(value) + `
32175
+ `);
32176
+ unchangedDirectory(directory, identity);
32177
+ renameSync4(join20(directory, temporary), join20(directory, "receipt.json"));
32178
+ const fd = openSync4(directory, constants3.O_RDONLY | constants3.O_NOFOLLOW);
32179
+ try {
32180
+ fsyncSync(fd);
32181
+ } finally {
32182
+ closeSync4(fd);
32183
+ }
32184
+ }
32185
+ function bind(client, receipt) {
32186
+ if (["apiOrigin", "organizationId", "userId", "membershipId"].some((k) => client[k] !== receipt[k]))
32187
+ throw new PrivatePublicationError("PUBLICATION_IDENTITY_CHANGED", "The fresh session does not match the recovery directory's server, account and membership.");
32188
+ }
32189
+ async function locked(directory, action) {
32190
+ const identity = safeDirectory(directory), file = join20(directory, "operation.lock");
32191
+ let fd;
32192
+ try {
32193
+ fd = openSync4(file, constants3.O_WRONLY | constants3.O_CREAT | constants3.O_EXCL | constants3.O_NOFOLLOW, 384);
32194
+ } catch {
32195
+ throw new PrivatePublicationError("PUBLICATION_RECOVERY_BUSY", "Another operation holds this recovery directory. If it crashed, confirm that process has stopped before explicitly removing operation.lock and resuming.");
32196
+ }
32197
+ const lock = fstatSync4(fd);
32198
+ try {
32199
+ writeFileSync10(fd, JSON.stringify({ pid: process.pid }) + `
32200
+ `);
32201
+ fsyncSync(fd);
32202
+ return await action();
32203
+ } finally {
32204
+ closeSync4(fd);
32205
+ unchangedDirectory(directory, identity);
32206
+ const now = lstatSync5(file);
32207
+ if (now.dev !== lock.dev || now.ino !== lock.ino || !now.isFile() || now.isSymbolicLink())
32208
+ fail2();
32209
+ unlinkSync2(file);
32210
+ }
32211
+ }
32212
+ function readPrivatePublicationRecovery(directory) {
32213
+ try {
32214
+ const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(readOwned(directory, "receipt.json", 65536)));
32215
+ if (!value || typeof value !== "object" || Array.isArray(value) || Object.keys(value).sort().join(",") !== ["contractVersion", "apiOrigin", "organizationId", "userId", "membershipId", "skillId", "declaration", "phase", "intent"].sort().join(",") || value.contractVersion !== 1 || ![value.organizationId, value.userId, value.membershipId, value.skillId].every(publicationUuid) || typeof value.apiOrigin !== "string" || normalizeSkillsApiOrigin(value.apiOrigin) !== value.apiOrigin || !["prepared", "begin_uncertain", "awaiting_upload", "upload_uncertain", "uploaded", "finalize_uncertain", "observed"].includes(value.phase))
32216
+ return fail2();
32217
+ value.declaration = checkedPublicationDeclaration(value.declaration);
32218
+ if (value.intent !== null)
32219
+ value.intent = checkedPublicationView(value.intent, value.skillId, undefined, value.declaration);
32220
+ if (value.intent === null && !["prepared", "begin_uncertain"].includes(value.phase))
32221
+ return fail2();
32222
+ const bytes = readOwned(directory, "bundle.tgz", PRIVATE_PUBLICATION_MAX_BYTES);
32223
+ if (bytes.length !== value.declaration.archiveByteSize || publicationSha256(bytes) !== value.declaration.archiveSha256)
32224
+ return fail2();
32225
+ return { receipt: value, bytes };
32226
+ } catch {
32227
+ return fail2();
32228
+ }
32229
+ }
32230
+ async function preparePrivatePublication(client, sourceDirectory, recoveryDirectory, input) {
32231
+ if (!publicationUuid(input.skillId) || !(input.expectedCurrentVersionId === null || publicationUuid(input.expectedCurrentVersionId)) || input.idempotencyKey !== undefined && !publicationUuid(input.idempotencyKey))
32232
+ return fail2();
32233
+ const packed = packSkillBundle(sourceDirectory, { maxUnpackedBytes: 32 * 1024 * 1024 });
32234
+ const inspected = await inspectSkillBundle(packed.bytes, { limits: { compressedBytes: PRIVATE_PUBLICATION_MAX_BYTES } });
32235
+ const manifest = inspected.entries.find((entry) => entry.path === "skill.json");
32236
+ if (!manifest || manifest.bytes.length > 16384 || !(await verifyContentHashFromEntries(inspected.entries)).valid)
32237
+ throw new PrivatePublicationError("PUBLICATION_BUNDLE_INVALID", "The skill must have a valid skill.json with its current content hash. Validate the skill before publishing.");
32238
+ const manifestText = new TextDecoder("utf-8", { fatal: true }).decode(manifest.bytes);
32239
+ const declaration = checkedPublicationDeclaration({
32240
+ idempotencyKey: input.idempotencyKey ?? randomUUID(),
32241
+ version: JSON.parse(manifestText).version,
32242
+ expectedCurrentVersionId: input.expectedCurrentVersionId,
32243
+ manifestText,
32244
+ archiveSha256: inspected.sha256,
32245
+ archiveByteSize: packed.bytes.length
32246
+ });
32247
+ const receipt = {
32248
+ contractVersion: 1,
32249
+ apiOrigin: client.apiOrigin,
32250
+ organizationId: client.organizationId,
32251
+ userId: client.userId,
32252
+ membershipId: client.membershipId,
32253
+ skillId: input.skillId,
32254
+ declaration,
32255
+ phase: "prepared",
32256
+ intent: null
32257
+ };
32258
+ if (!isAbsolute4(recoveryDirectory) || resolve2(recoveryDirectory) !== recoveryDirectory || realpathSync2(dirname8(recoveryDirectory)) !== dirname8(recoveryDirectory))
32259
+ return fail2();
32260
+ mkdirSync11(recoveryDirectory, { mode: 448 });
32261
+ safeDirectory(recoveryDirectory);
32262
+ const parent = openSync4(dirname8(recoveryDirectory), constants3.O_RDONLY | constants3.O_NOFOLLOW);
32263
+ try {
32264
+ fsyncSync(parent);
32265
+ } finally {
32266
+ closeSync4(parent);
32267
+ }
32268
+ writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
32269
+ save(recoveryDirectory, receipt);
32270
+ return receipt;
32271
+ }
32272
+ function privatePublicationResult(directory, receipt) {
32273
+ const state = receipt.intent?.state ?? receipt.phase, committed = state === "committed";
32274
+ const nextAction = committed ? "The version is published. Private execution remains unavailable." : ["rejected", "cancelled", "expired"].includes(state) ? "This intent is terminal. Inspect the result before explicitly preparing another version." : state === "needs_attention" ? "Keep this intent and contact the service operator; do not create a replacement or upload again." : receipt.phase === "upload_uncertain" ? "Run publication resume with this recovery directory to finalize the same intent without another upload." : receipt.intent ? "Run publication status or resume with this recovery directory; cancel explicitly if you want to stop." : "Run publication resume with this recovery directory to reconcile the identical request key and declaration.";
32275
+ return {
32276
+ recoveryDirectory: directory,
32277
+ skillId: receipt.skillId,
32278
+ intentId: receipt.intent?.id ?? null,
32279
+ state,
32280
+ versionId: receipt.intent?.versionId ?? null,
32281
+ committed,
32282
+ executionEnabled: false,
32283
+ nextAction
32284
+ };
32285
+ }
32286
+ async function continuePrivatePublication(client, directory, options) {
32287
+ if (options.confirm !== true)
32288
+ throw new PrivatePublicationError("PUBLICATION_CONFIRM_REQUIRED", "Explicit upload confirmation is required.");
32289
+ if (options.waitMs !== undefined && (!Number.isSafeInteger(options.waitMs) || options.waitMs < 0 || options.waitMs > 300000))
32290
+ return fail2();
32291
+ return locked(directory, () => continueLocked(client, directory, options));
32292
+ }
32293
+ async function continueLocked(client, directory, options) {
32294
+ const { receipt, bytes } = readPrivatePublicationRecovery(directory);
32295
+ bind(client, receipt);
32296
+ if (!receipt.intent) {
32297
+ receipt.phase = "begin_uncertain";
32298
+ save(directory, receipt);
32299
+ receipt.intent = await client.begin(receipt.skillId, receipt.declaration);
32300
+ receipt.phase = "awaiting_upload";
32301
+ save(directory, receipt);
32302
+ } else {
32303
+ receipt.intent = checkedPublicationView(await client.get(receipt.skillId, receipt.intent.id), receipt.skillId, receipt.intent.id, receipt.declaration);
32304
+ save(directory, receipt);
32305
+ }
32306
+ if (receipt.intent.state === "awaiting_upload") {
32307
+ if (receipt.phase === "awaiting_upload") {
32308
+ receipt.phase = "upload_uncertain";
32309
+ save(directory, receipt);
32310
+ try {
32311
+ await client.upload(receipt.skillId, receipt.intent, bytes);
32312
+ } catch (error2) {
32313
+ if (error2 instanceof PrivatePublicationError && !error2.uncertain) {
32314
+ receipt.phase = "awaiting_upload";
32315
+ save(directory, receipt);
32316
+ }
32317
+ throw error2;
32318
+ }
32319
+ receipt.phase = "uploaded";
32320
+ save(directory, receipt);
32321
+ }
32322
+ receipt.phase = "finalize_uncertain";
32323
+ save(directory, receipt);
32324
+ receipt.intent = checkedPublicationView(await client.finalize(receipt.skillId, receipt.intent.id), receipt.skillId, receipt.intent.id, receipt.declaration);
32325
+ receipt.phase = "observed";
32326
+ save(directory, receipt);
32327
+ }
32328
+ if (options.waitMs !== undefined && options.waitMs > 0 && ["queued", "verifying"].includes(receipt.intent.state)) {
32329
+ receipt.intent = checkedPublicationView(await client.wait(receipt.skillId, receipt.intent.id, { timeoutMs: options.waitMs }), receipt.skillId, receipt.intent.id, receipt.declaration);
32330
+ receipt.phase = "observed";
32331
+ save(directory, receipt);
32332
+ }
32333
+ return privatePublicationResult(directory, receipt);
32334
+ }
32335
+ async function inspectPrivatePublication(client, directory, cancel = false) {
32336
+ return locked(directory, () => inspectLocked(client, directory, cancel));
32337
+ }
32338
+ async function inspectLocked(client, directory, cancel) {
32339
+ const { receipt } = readPrivatePublicationRecovery(directory);
32340
+ bind(client, receipt);
32341
+ if (receipt.intent) {
32342
+ receipt.intent = checkedPublicationView(await (cancel ? client.cancel(receipt.skillId, receipt.intent.id) : client.get(receipt.skillId, receipt.intent.id)), receipt.skillId, receipt.intent.id, receipt.declaration);
32343
+ save(directory, receipt);
32344
+ } else if (cancel)
32345
+ throw new PrivatePublicationError("PUBLICATION_INTENT_UNKNOWN", "Reconcile the saved begin request with publication resume before cancelling its intent.");
32346
+ return privatePublicationResult(directory, receipt);
32347
+ }
32348
+ var fail2 = () => {
32349
+ throw new PrivatePublicationError("PUBLICATION_RECOVERY_INVALID", "The recovery directory is invalid or changed. Preserve it and inspect the existing intent; do not start a replacement automatically.");
32350
+ };
32351
+ var init_private_publication_recovery = __esm(() => {
32352
+ init_skill_bundle();
32353
+ init_skill_hash();
32354
+ init_remote_private_publications();
32355
+ init_fleet_credentials();
32356
+ });
32357
+
32358
+ // src/mcp/private-publication-tools.ts
32359
+ import { isAbsolute as isAbsolute5 } from "path";
32360
+ function registerPrivatePublicationTools(server) {
32361
+ const uuid6 = exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/);
32362
+ const directory = exports_external.string().max(4096).refine(isAbsolute5, "Use an absolute local directory");
32363
+ const verification = { email: exports_external.string().email().max(254), code: exports_external.string().regex(/^\d{6}$/), userId: uuid6, membershipId: uuid6, recoveryDirectory: directory };
32364
+ const description = "Manage a private source publication using fresh workspace-bound verification and a host-local recovery directory. Publishing requires explicit UUID current-version comparison and upload consent. Resume reuses immutable saved bytes and intent; an uncertain PUT is finalized for server verification, never uploaded twice. Sessions and signed URLs are not returned or persisted. Private execution is unavailable. Host request history may contain the supplied verification code.";
32365
+ const handler = (action) => async (value) => {
32366
+ try {
32367
+ const client = await privatePublicationSession(String(value.email), String(value.code), { userId: String(value.userId), membershipId: String(value.membershipId) });
32368
+ const recovery = String(value.recoveryDirectory);
32369
+ if (action === "publish")
32370
+ await preparePrivatePublication(client, String(value.directory), recovery, { skillId: String(value.skillId), expectedCurrentVersionId: value.expectedCurrentVersionId, idempotencyKey: value.idempotencyKey });
32371
+ const result = action === "publish" || action === "resume" ? await continuePrivatePublication(client, recovery, { confirm: true, waitMs: value.waitMs }) : await inspectPrivatePublication(client, recovery, action === "cancel");
32372
+ return mcpJson(result);
32373
+ } catch (error2) {
32374
+ const result = privatePublicationCustomerError(error2);
32375
+ return mcpError(result.code, result.error);
32376
+ }
32377
+ };
32378
+ server.registerTool("publish_private_skill", {
32379
+ title: "Publish private skill",
32380
+ description,
32381
+ annotations: { destructiveHint: true, readOnlyHint: false, idempotentHint: false },
32382
+ inputSchema: exports_external.object({ ...verification, directory, skillId: uuid6, expectedCurrentVersionId: uuid6.nullable(), idempotencyKey: uuid6.optional(), confirm: exports_external.literal(true), waitMs: exports_external.number().int().min(0).max(300000).optional() }).strict()
32383
+ }, handler("publish"));
32384
+ server.registerTool("get_private_publication", {
32385
+ title: "Get private publication",
32386
+ description,
32387
+ annotations: { destructiveHint: false, readOnlyHint: true, idempotentHint: true },
32388
+ inputSchema: exports_external.object(verification).strict()
32389
+ }, handler("get"));
32390
+ server.registerTool("resume_private_publication", {
32391
+ title: "Resume private publication",
32392
+ description,
32393
+ annotations: { destructiveHint: true, readOnlyHint: false, idempotentHint: true },
32394
+ inputSchema: exports_external.object({ ...verification, confirm: exports_external.literal(true), waitMs: exports_external.number().int().min(0).max(300000).optional() }).strict()
32395
+ }, handler("resume"));
32396
+ server.registerTool("cancel_private_publication", {
32397
+ title: "Cancel private publication",
32398
+ description,
32399
+ annotations: { destructiveHint: true, readOnlyHint: false, idempotentHint: true },
32400
+ inputSchema: exports_external.object({ ...verification, confirm: exports_external.literal(true) }).strict()
32401
+ }, handler("cancel"));
32402
+ }
32403
+ var init_private_publication_tools = __esm(() => {
32404
+ init_zod();
32405
+ init_private_publication_customer();
32406
+ init_private_publication_recovery();
32407
+ init_helpers();
32408
+ });
32409
+
30969
32410
  // src/mcp/remote-customer-tools.ts
30970
32411
  function registerRemoteCustomerTools(server) {
30971
32412
  registerRemoteInvitationTools(server);
32413
+ registerPrivatePublicationTools(server);
30972
32414
  const memberRole = exports_external.enum(["owner", "admin", "member", "viewer"]);
30973
32415
  const memberInput = {
30974
32416
  membershipId: exports_external.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/),
@@ -31086,8 +32528,16 @@ function registerRemoteCustomerTools(server) {
31086
32528
  server.registerTool("quote_skill", {
31087
32529
  title: "Quote Remote Skill",
31088
32530
  description: "Get the configured server's credit quote without submitting a run.",
31089
- inputSchema: { name: exports_external.string(), input: exports_external.record(exports_external.string(), exports_external.unknown()).optional(), args: exports_external.array(exports_external.string()).optional() }
31090
- }, ({ name, input, args }) => callRemote((client) => client.quoteRun(name, input, args)));
32531
+ inputSchema: {
32532
+ name: exports_external.string(),
32533
+ input: exports_external.record(exports_external.string(), exports_external.unknown()).optional(),
32534
+ args: exports_external.array(exports_external.string()).optional(),
32535
+ files: exports_external.array(exports_external.object({ name: exports_external.string(), base64: exports_external.string().max(1398104), contentType: exports_external.string().optional() })).max(10).optional().describe("The same inline files to submit after approval; quoted descriptors bind their exact bytes, names and types.")
32536
+ }
32537
+ }, ({ name, input, args, files }) => callRemote((client) => {
32538
+ const descriptors = describeRemoteFiles(decodeRemoteFiles(files ?? []));
32539
+ return client.quoteRun(name, input, args, descriptors.length ? descriptors : undefined);
32540
+ }));
31091
32541
  server.registerTool("download_run_artifact", {
31092
32542
  title: "Download Verified Run Artifact",
31093
32543
  description: "Return verified artifact bytes as base64 (at most 1 MiB); use the CLI for larger files.",
@@ -31121,6 +32571,7 @@ async function freshAccount(action, operation) {
31121
32571
  }
31122
32572
  var init_remote_customer_tools = __esm(() => {
31123
32573
  init_remote_invitation_tools();
32574
+ init_private_publication_tools();
31124
32575
  init_zod();
31125
32576
  init_remote_auth();
31126
32577
  init_workspace_profile();
@@ -31128,13 +32579,14 @@ var init_remote_customer_tools = __esm(() => {
31128
32579
  init_remote_client();
31129
32580
  init_remote_workspace_leave();
31130
32581
  init_helpers();
32582
+ init_remote_files();
31131
32583
  });
31132
32584
 
31133
32585
  // src/mcp/server.ts
31134
32586
  var exports_server = {};
31135
32587
  __export(exports_server, {
31136
- buildServer: () => buildServer,
31137
- server: () => server
32588
+ server: () => server,
32589
+ buildServer: () => buildServer
31138
32590
  });
31139
32591
  function buildServer() {
31140
32592
  const server = new McpServer({
@@ -31541,7 +32993,7 @@ var RequestError, toRequestError = (e) => {
31541
32993
  });
31542
32994
  if (!chunk) {
31543
32995
  if (i === 1) {
31544
- await new Promise((resolve2) => setTimeout(resolve2));
32996
+ await new Promise((resolve3) => setTimeout(resolve3));
31545
32997
  maxReadCount = 3;
31546
32998
  continue;
31547
32999
  }
@@ -31832,7 +33284,7 @@ var init_dist = __esm(() => {
31832
33284
  });
31833
33285
 
31834
33286
  // ../../node_modules/.bun/content-type@1.0.5/node_modules/content-type/index.js
31835
- var require_content_type = __commonJS(function(exports) {
33287
+ var require_content_type = __commonJS((exports) => {
31836
33288
  /*!
31837
33289
  * content-type
31838
33290
  * Copyright(c) 2015 Douglas Christopher Wilson
@@ -32376,9 +33828,9 @@ data:
32376
33828
  const initRequest = messages.find((m) => isInitializeRequest(m));
32377
33829
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
32378
33830
  if (this._enableJsonResponse) {
32379
- return new Promise((resolve2) => {
33831
+ return new Promise((resolve3) => {
32380
33832
  this._streamMapping.set(streamId, {
32381
- resolveJson: resolve2,
33833
+ resolveJson: resolve3,
32382
33834
  cleanup: () => {
32383
33835
  this._streamMapping.delete(streamId);
32384
33836
  }
@@ -32707,13 +34159,13 @@ var init_streamableHttp = __esm(() => {
32707
34159
  // src/mcp/http.ts
32708
34160
  var exports_http = {};
32709
34161
  __export(exports_http, {
32710
- MCP_HTTP_DEFAULT_PORT: () => MCP_HTTP_DEFAULT_PORT,
32711
- MCP_HTTP_SERVICE_NAME: () => MCP_HTTP_SERVICE_NAME,
32712
- handleMcpHttpNodeRequest: () => handleMcpHttpNodeRequest,
32713
- isMcpHttpMode: () => isMcpHttpMode,
32714
- isMcpStdioMode: () => isMcpStdioMode,
34162
+ startSkillsMcpHttpServer: () => startSkillsMcpHttpServer,
32715
34163
  parseMcpHttpPort: () => parseMcpHttpPort,
32716
- startSkillsMcpHttpServer: () => startSkillsMcpHttpServer
34164
+ isMcpStdioMode: () => isMcpStdioMode,
34165
+ isMcpHttpMode: () => isMcpHttpMode,
34166
+ handleMcpHttpNodeRequest: () => handleMcpHttpNodeRequest,
34167
+ MCP_HTTP_SERVICE_NAME: () => MCP_HTTP_SERVICE_NAME,
34168
+ MCP_HTTP_DEFAULT_PORT: () => MCP_HTTP_DEFAULT_PORT
32717
34169
  });
32718
34170
  import { createServer } from "http";
32719
34171
  function isMcpHttpMode(argv = process.argv.slice(2)) {
@@ -32747,19 +34199,19 @@ async function connectMcpForNode() {
32747
34199
  return { server: server2, transport };
32748
34200
  }
32749
34201
  function readBody(req) {
32750
- return new Promise((resolve2, reject) => {
34202
+ return new Promise((resolve3, reject) => {
32751
34203
  const chunks = [];
32752
34204
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
32753
34205
  req.on("end", () => {
32754
34206
  const raw = Buffer.concat(chunks).toString("utf-8");
32755
34207
  if (!raw.trim()) {
32756
- resolve2(undefined);
34208
+ resolve3(undefined);
32757
34209
  return;
32758
34210
  }
32759
34211
  try {
32760
- resolve2(JSON.parse(raw));
34212
+ resolve3(JSON.parse(raw));
32761
34213
  } catch {
32762
- resolve2(undefined);
34214
+ resolve3(undefined);
32763
34215
  }
32764
34216
  });
32765
34217
  req.on("error", reject);
@@ -32801,9 +34253,9 @@ async function startSkillsMcpHttpServer(options = {}) {
32801
34253
  }
32802
34254
  }
32803
34255
  });
32804
- await new Promise((resolve2, reject) => {
34256
+ await new Promise((resolve3, reject) => {
32805
34257
  httpServer.once("error", reject);
32806
- httpServer.listen(port, hostname2, () => resolve2());
34258
+ httpServer.listen(port, hostname2, () => resolve3());
32807
34259
  });
32808
34260
  const address = httpServer.address();
32809
34261
  const listenPort = typeof address === "object" && address ? address.port : port;
@@ -32885,6 +34337,6 @@ if (import.meta.main) {
32885
34337
  });
32886
34338
  }
32887
34339
  export {
32888
- assertSkillsMcpConfigured,
32889
- startMcpStdio
34340
+ startMcpStdio,
34341
+ assertSkillsMcpConfigured
32890
34342
  };