@hasna/skills 0.5.4 → 0.5.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +72 -7
- package/bin/index.js +2181 -901
- package/bin/mcp.js +1960 -508
- package/bin/migrate.js +176 -4
- package/bin/server.js +419 -195
- package/bin/worker.js +413 -222
- package/dist/admin-contract.js +174 -176
- package/dist/cli/commands/private-publications.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1074 -421
- package/dist/lib/fleet-credentials.d.ts +6 -1
- package/dist/lib/home-adoption.d.ts +2 -7
- package/dist/lib/mcp-contracts.d.ts +1 -0
- package/dist/lib/private-publication-customer.d.ts +10 -0
- package/dist/lib/private-publication-recovery.d.ts +43 -0
- package/dist/lib/remote-account.d.ts +5 -0
- package/dist/lib/remote-auth.d.ts +3 -0
- package/dist/lib/remote-client.d.ts +2 -2
- package/dist/lib/remote-private-publications.d.ts +74 -0
- package/dist/mcp/private-publication-tools.d.ts +2 -0
- package/dist/sdk/execution/dispatchers/ecs.d.ts +25 -14
- package/dist/sdk/index.d.ts +2 -0
- package/dist/sdk/index.js +1291 -617
- package/dist/server/types.d.ts +2 -0
- package/dist/storage.js +39 -37
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -19,14 +19,12 @@ var __toESM = (mod, isNodeMode, target) => {
|
|
|
19
19
|
}
|
|
20
20
|
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
21
21
|
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
});
|
|
29
|
-
}
|
|
22
|
+
for (let key of __getOwnPropNames(mod))
|
|
23
|
+
if (!__hasOwnProp.call(to, key))
|
|
24
|
+
__defProp(to, key, {
|
|
25
|
+
get: __accessProp.bind(mod, key),
|
|
26
|
+
enumerable: true
|
|
27
|
+
});
|
|
30
28
|
if (canCache)
|
|
31
29
|
cache.set(mod, to);
|
|
32
30
|
return to;
|
|
@@ -4728,119 +4726,119 @@ function readIfExists(path) {
|
|
|
4728
4726
|
} catch {}
|
|
4729
4727
|
return null;
|
|
4730
4728
|
}
|
|
4731
|
-
//
|
|
4729
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/external.js
|
|
4732
4730
|
var exports_external = {};
|
|
4733
4731
|
__export(exports_external, {
|
|
4734
|
-
|
|
4735
|
-
DIRTY: () => DIRTY,
|
|
4736
|
-
EMPTY_PATH: () => EMPTY_PATH,
|
|
4737
|
-
INVALID: () => INVALID,
|
|
4738
|
-
NEVER: () => NEVER,
|
|
4739
|
-
OK: () => OK,
|
|
4740
|
-
ParseStatus: () => ParseStatus,
|
|
4741
|
-
Schema: () => ZodType,
|
|
4742
|
-
ZodAny: () => ZodAny,
|
|
4743
|
-
ZodArray: () => ZodArray,
|
|
4744
|
-
ZodBigInt: () => ZodBigInt,
|
|
4745
|
-
ZodBoolean: () => ZodBoolean,
|
|
4746
|
-
ZodBranded: () => ZodBranded,
|
|
4747
|
-
ZodCatch: () => ZodCatch,
|
|
4748
|
-
ZodDate: () => ZodDate,
|
|
4749
|
-
ZodDefault: () => ZodDefault,
|
|
4750
|
-
ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
|
|
4751
|
-
ZodEffects: () => ZodEffects,
|
|
4752
|
-
ZodEnum: () => ZodEnum,
|
|
4753
|
-
ZodError: () => ZodError,
|
|
4754
|
-
ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
|
|
4755
|
-
ZodFunction: () => ZodFunction,
|
|
4756
|
-
ZodIntersection: () => ZodIntersection,
|
|
4757
|
-
ZodIssueCode: () => ZodIssueCode,
|
|
4758
|
-
ZodLazy: () => ZodLazy,
|
|
4759
|
-
ZodLiteral: () => ZodLiteral,
|
|
4760
|
-
ZodMap: () => ZodMap,
|
|
4761
|
-
ZodNaN: () => ZodNaN,
|
|
4762
|
-
ZodNativeEnum: () => ZodNativeEnum,
|
|
4763
|
-
ZodNever: () => ZodNever,
|
|
4764
|
-
ZodNull: () => ZodNull,
|
|
4765
|
-
ZodNullable: () => ZodNullable,
|
|
4766
|
-
ZodNumber: () => ZodNumber,
|
|
4767
|
-
ZodObject: () => ZodObject,
|
|
4768
|
-
ZodOptional: () => ZodOptional,
|
|
4769
|
-
ZodParsedType: () => ZodParsedType,
|
|
4770
|
-
ZodPipeline: () => ZodPipeline,
|
|
4771
|
-
ZodPromise: () => ZodPromise,
|
|
4772
|
-
ZodReadonly: () => ZodReadonly,
|
|
4773
|
-
ZodRecord: () => ZodRecord,
|
|
4774
|
-
ZodSchema: () => ZodType,
|
|
4775
|
-
ZodSet: () => ZodSet,
|
|
4776
|
-
ZodString: () => ZodString,
|
|
4777
|
-
ZodSymbol: () => ZodSymbol,
|
|
4778
|
-
ZodTransformer: () => ZodEffects,
|
|
4779
|
-
ZodTuple: () => ZodTuple,
|
|
4780
|
-
ZodType: () => ZodType,
|
|
4781
|
-
ZodUndefined: () => ZodUndefined,
|
|
4782
|
-
ZodUnion: () => ZodUnion,
|
|
4783
|
-
ZodUnknown: () => ZodUnknown,
|
|
4784
|
-
ZodVoid: () => ZodVoid,
|
|
4785
|
-
addIssueToContext: () => addIssueToContext,
|
|
4786
|
-
any: () => anyType,
|
|
4787
|
-
array: () => arrayType,
|
|
4788
|
-
bigint: () => bigIntType,
|
|
4789
|
-
boolean: () => booleanType,
|
|
4790
|
-
coerce: () => coerce,
|
|
4791
|
-
custom: () => custom,
|
|
4792
|
-
date: () => dateType,
|
|
4793
|
-
datetimeRegex: () => datetimeRegex,
|
|
4794
|
-
defaultErrorMap: () => en_default,
|
|
4795
|
-
discriminatedUnion: () => discriminatedUnionType,
|
|
4796
|
-
effect: () => effectsType,
|
|
4797
|
-
enum: () => enumType,
|
|
4798
|
-
function: () => functionType,
|
|
4799
|
-
getErrorMap: () => getErrorMap,
|
|
4800
|
-
getParsedType: () => getParsedType,
|
|
4801
|
-
instanceof: () => instanceOfType,
|
|
4802
|
-
intersection: () => intersectionType,
|
|
4803
|
-
isAborted: () => isAborted,
|
|
4804
|
-
isAsync: () => isAsync,
|
|
4805
|
-
isDirty: () => isDirty,
|
|
4806
|
-
isValid: () => isValid,
|
|
4807
|
-
late: () => late,
|
|
4808
|
-
lazy: () => lazyType,
|
|
4809
|
-
literal: () => literalType,
|
|
4810
|
-
makeIssue: () => makeIssue,
|
|
4811
|
-
map: () => mapType,
|
|
4812
|
-
nan: () => nanType,
|
|
4813
|
-
nativeEnum: () => nativeEnumType,
|
|
4814
|
-
never: () => neverType,
|
|
4815
|
-
null: () => nullType,
|
|
4816
|
-
nullable: () => nullableType,
|
|
4817
|
-
number: () => numberType,
|
|
4818
|
-
object: () => objectType,
|
|
4819
|
-
objectUtil: () => objectUtil,
|
|
4820
|
-
oboolean: () => oboolean,
|
|
4821
|
-
onumber: () => onumber,
|
|
4822
|
-
optional: () => optionalType,
|
|
4823
|
-
ostring: () => ostring,
|
|
4824
|
-
pipeline: () => pipelineType,
|
|
4825
|
-
preprocess: () => preprocessType,
|
|
4826
|
-
promise: () => promiseType,
|
|
4827
|
-
quotelessJson: () => quotelessJson,
|
|
4828
|
-
record: () => recordType,
|
|
4829
|
-
set: () => setType,
|
|
4830
|
-
setErrorMap: () => setErrorMap,
|
|
4831
|
-
strictObject: () => strictObjectType,
|
|
4832
|
-
string: () => stringType,
|
|
4833
|
-
symbol: () => symbolType,
|
|
4834
|
-
transformer: () => effectsType,
|
|
4835
|
-
tuple: () => tupleType,
|
|
4836
|
-
undefined: () => undefinedType,
|
|
4837
|
-
union: () => unionType,
|
|
4838
|
-
unknown: () => unknownType,
|
|
4732
|
+
void: () => voidType,
|
|
4839
4733
|
util: () => util,
|
|
4840
|
-
|
|
4734
|
+
unknown: () => unknownType,
|
|
4735
|
+
union: () => unionType,
|
|
4736
|
+
undefined: () => undefinedType,
|
|
4737
|
+
tuple: () => tupleType,
|
|
4738
|
+
transformer: () => effectsType,
|
|
4739
|
+
symbol: () => symbolType,
|
|
4740
|
+
string: () => stringType,
|
|
4741
|
+
strictObject: () => strictObjectType,
|
|
4742
|
+
setErrorMap: () => setErrorMap,
|
|
4743
|
+
set: () => setType,
|
|
4744
|
+
record: () => recordType,
|
|
4745
|
+
quotelessJson: () => quotelessJson,
|
|
4746
|
+
promise: () => promiseType,
|
|
4747
|
+
preprocess: () => preprocessType,
|
|
4748
|
+
pipeline: () => pipelineType,
|
|
4749
|
+
ostring: () => ostring,
|
|
4750
|
+
optional: () => optionalType,
|
|
4751
|
+
onumber: () => onumber,
|
|
4752
|
+
oboolean: () => oboolean,
|
|
4753
|
+
objectUtil: () => objectUtil,
|
|
4754
|
+
object: () => objectType,
|
|
4755
|
+
number: () => numberType,
|
|
4756
|
+
nullable: () => nullableType,
|
|
4757
|
+
null: () => nullType,
|
|
4758
|
+
never: () => neverType,
|
|
4759
|
+
nativeEnum: () => nativeEnumType,
|
|
4760
|
+
nan: () => nanType,
|
|
4761
|
+
map: () => mapType,
|
|
4762
|
+
makeIssue: () => makeIssue,
|
|
4763
|
+
literal: () => literalType,
|
|
4764
|
+
lazy: () => lazyType,
|
|
4765
|
+
late: () => late,
|
|
4766
|
+
isValid: () => isValid,
|
|
4767
|
+
isDirty: () => isDirty,
|
|
4768
|
+
isAsync: () => isAsync,
|
|
4769
|
+
isAborted: () => isAborted,
|
|
4770
|
+
intersection: () => intersectionType,
|
|
4771
|
+
instanceof: () => instanceOfType,
|
|
4772
|
+
getParsedType: () => getParsedType,
|
|
4773
|
+
getErrorMap: () => getErrorMap,
|
|
4774
|
+
function: () => functionType,
|
|
4775
|
+
enum: () => enumType,
|
|
4776
|
+
effect: () => effectsType,
|
|
4777
|
+
discriminatedUnion: () => discriminatedUnionType,
|
|
4778
|
+
defaultErrorMap: () => en_default,
|
|
4779
|
+
datetimeRegex: () => datetimeRegex,
|
|
4780
|
+
date: () => dateType,
|
|
4781
|
+
custom: () => custom,
|
|
4782
|
+
coerce: () => coerce,
|
|
4783
|
+
boolean: () => booleanType,
|
|
4784
|
+
bigint: () => bigIntType,
|
|
4785
|
+
array: () => arrayType,
|
|
4786
|
+
any: () => anyType,
|
|
4787
|
+
addIssueToContext: () => addIssueToContext,
|
|
4788
|
+
ZodVoid: () => ZodVoid,
|
|
4789
|
+
ZodUnknown: () => ZodUnknown,
|
|
4790
|
+
ZodUnion: () => ZodUnion,
|
|
4791
|
+
ZodUndefined: () => ZodUndefined,
|
|
4792
|
+
ZodType: () => ZodType,
|
|
4793
|
+
ZodTuple: () => ZodTuple,
|
|
4794
|
+
ZodTransformer: () => ZodEffects,
|
|
4795
|
+
ZodSymbol: () => ZodSymbol,
|
|
4796
|
+
ZodString: () => ZodString,
|
|
4797
|
+
ZodSet: () => ZodSet,
|
|
4798
|
+
ZodSchema: () => ZodType,
|
|
4799
|
+
ZodRecord: () => ZodRecord,
|
|
4800
|
+
ZodReadonly: () => ZodReadonly,
|
|
4801
|
+
ZodPromise: () => ZodPromise,
|
|
4802
|
+
ZodPipeline: () => ZodPipeline,
|
|
4803
|
+
ZodParsedType: () => ZodParsedType,
|
|
4804
|
+
ZodOptional: () => ZodOptional,
|
|
4805
|
+
ZodObject: () => ZodObject,
|
|
4806
|
+
ZodNumber: () => ZodNumber,
|
|
4807
|
+
ZodNullable: () => ZodNullable,
|
|
4808
|
+
ZodNull: () => ZodNull,
|
|
4809
|
+
ZodNever: () => ZodNever,
|
|
4810
|
+
ZodNativeEnum: () => ZodNativeEnum,
|
|
4811
|
+
ZodNaN: () => ZodNaN,
|
|
4812
|
+
ZodMap: () => ZodMap,
|
|
4813
|
+
ZodLiteral: () => ZodLiteral,
|
|
4814
|
+
ZodLazy: () => ZodLazy,
|
|
4815
|
+
ZodIssueCode: () => ZodIssueCode,
|
|
4816
|
+
ZodIntersection: () => ZodIntersection,
|
|
4817
|
+
ZodFunction: () => ZodFunction,
|
|
4818
|
+
ZodFirstPartyTypeKind: () => ZodFirstPartyTypeKind,
|
|
4819
|
+
ZodError: () => ZodError,
|
|
4820
|
+
ZodEnum: () => ZodEnum,
|
|
4821
|
+
ZodEffects: () => ZodEffects,
|
|
4822
|
+
ZodDiscriminatedUnion: () => ZodDiscriminatedUnion,
|
|
4823
|
+
ZodDefault: () => ZodDefault,
|
|
4824
|
+
ZodDate: () => ZodDate,
|
|
4825
|
+
ZodCatch: () => ZodCatch,
|
|
4826
|
+
ZodBranded: () => ZodBranded,
|
|
4827
|
+
ZodBoolean: () => ZodBoolean,
|
|
4828
|
+
ZodBigInt: () => ZodBigInt,
|
|
4829
|
+
ZodArray: () => ZodArray,
|
|
4830
|
+
ZodAny: () => ZodAny,
|
|
4831
|
+
Schema: () => ZodType,
|
|
4832
|
+
ParseStatus: () => ParseStatus,
|
|
4833
|
+
OK: () => OK,
|
|
4834
|
+
NEVER: () => NEVER,
|
|
4835
|
+
INVALID: () => INVALID,
|
|
4836
|
+
EMPTY_PATH: () => EMPTY_PATH,
|
|
4837
|
+
DIRTY: () => DIRTY,
|
|
4838
|
+
BRAND: () => BRAND
|
|
4841
4839
|
});
|
|
4842
4840
|
|
|
4843
|
-
//
|
|
4841
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/util.js
|
|
4844
4842
|
var util;
|
|
4845
4843
|
(function(util2) {
|
|
4846
4844
|
util2.assertEqual = (_) => {};
|
|
@@ -4971,7 +4969,7 @@ var getParsedType = (data) => {
|
|
|
4971
4969
|
}
|
|
4972
4970
|
};
|
|
4973
4971
|
|
|
4974
|
-
//
|
|
4972
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/ZodError.js
|
|
4975
4973
|
var ZodIssueCode = util.arrayToEnum([
|
|
4976
4974
|
"invalid_type",
|
|
4977
4975
|
"invalid_literal",
|
|
@@ -5090,7 +5088,7 @@ ZodError.create = (issues) => {
|
|
|
5090
5088
|
return error;
|
|
5091
5089
|
};
|
|
5092
5090
|
|
|
5093
|
-
//
|
|
5091
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/locales/en.js
|
|
5094
5092
|
var errorMap = (issue, _ctx) => {
|
|
5095
5093
|
let message;
|
|
5096
5094
|
switch (issue.code) {
|
|
@@ -5193,7 +5191,7 @@ var errorMap = (issue, _ctx) => {
|
|
|
5193
5191
|
};
|
|
5194
5192
|
var en_default = errorMap;
|
|
5195
5193
|
|
|
5196
|
-
//
|
|
5194
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/errors.js
|
|
5197
5195
|
var overrideErrorMap = en_default;
|
|
5198
5196
|
function setErrorMap(map) {
|
|
5199
5197
|
overrideErrorMap = map;
|
|
@@ -5201,7 +5199,7 @@ function setErrorMap(map) {
|
|
|
5201
5199
|
function getErrorMap() {
|
|
5202
5200
|
return overrideErrorMap;
|
|
5203
5201
|
}
|
|
5204
|
-
//
|
|
5202
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/parseUtil.js
|
|
5205
5203
|
var makeIssue = (params) => {
|
|
5206
5204
|
const { data, path, errorMaps, issueData } = params;
|
|
5207
5205
|
const fullPath = [...path, ...issueData.path || []];
|
|
@@ -5307,14 +5305,14 @@ var isAborted = (x) => x.status === "aborted";
|
|
|
5307
5305
|
var isDirty = (x) => x.status === "dirty";
|
|
5308
5306
|
var isValid = (x) => x.status === "valid";
|
|
5309
5307
|
var isAsync = (x) => typeof Promise !== "undefined" && x instanceof Promise;
|
|
5310
|
-
//
|
|
5308
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/helpers/errorUtil.js
|
|
5311
5309
|
var errorUtil;
|
|
5312
5310
|
(function(errorUtil2) {
|
|
5313
5311
|
errorUtil2.errToObj = (message) => typeof message === "string" ? { message } : message || {};
|
|
5314
5312
|
errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
|
|
5315
5313
|
})(errorUtil || (errorUtil = {}));
|
|
5316
5314
|
|
|
5317
|
-
//
|
|
5315
|
+
// ../../../skills-release-055-20260909/node_modules/.bun/zod@3.25.76/node_modules/zod/v3/types.js
|
|
5318
5316
|
class ParseInputLazyPath {
|
|
5319
5317
|
constructor(parent, value, path, key) {
|
|
5320
5318
|
this._cachedPath = [];
|
|
@@ -8701,7 +8699,7 @@ var coerce = {
|
|
|
8701
8699
|
date: (arg) => ZodDate.create({ ...arg, coerce: true })
|
|
8702
8700
|
};
|
|
8703
8701
|
var NEVER = INVALID;
|
|
8704
|
-
//
|
|
8702
|
+
// ../../../skills-release-055-20260909/apps/contracts/dist/client/transport.js
|
|
8705
8703
|
import { isIP } from "net";
|
|
8706
8704
|
import { spawnSync } from "child_process";
|
|
8707
8705
|
import { closeSync, fstatSync, openSync, readFileSync as readFileSync12 } from "fs";
|
|
@@ -9530,7 +9528,9 @@ function normalizeSkillsApiOrigin(apiUrl) {
|
|
|
9530
9528
|
throw new SkillsFleetCredentialError("A Skills API URL must use HTTPS (or loopback HTTP), without credentials, query or fragment", "INVALID_API_URL");
|
|
9531
9529
|
}
|
|
9532
9530
|
const pathname = url.pathname.replace(/\/+$/, "");
|
|
9533
|
-
if (
|
|
9531
|
+
if (url.origin === "https://api.hasna.com" && pathname === "/skills/v1") {
|
|
9532
|
+
url.pathname = "/skills";
|
|
9533
|
+
} else if (pathname === "/api" || pathname === "/api/v1") {
|
|
9534
9534
|
url.pathname = "/";
|
|
9535
9535
|
} else if (pathname.endsWith("/api/v1")) {
|
|
9536
9536
|
url.pathname = pathname.slice(0, -"/api/v1".length) || "/";
|
|
@@ -9539,6 +9539,21 @@ function normalizeSkillsApiOrigin(apiUrl) {
|
|
|
9539
9539
|
}
|
|
9540
9540
|
return url.toString().replace(/\/+$/, "");
|
|
9541
9541
|
}
|
|
9542
|
+
function skillsApiRequestUrl(apiUrl, route) {
|
|
9543
|
+
const origin = normalizeSkillsApiOrigin(apiUrl);
|
|
9544
|
+
if (!route.startsWith("/api/") || route.includes("#") || route.includes("\\")) {
|
|
9545
|
+
throw new SkillsFleetCredentialError("Invalid Skills API route", "INVALID_API_URL");
|
|
9546
|
+
}
|
|
9547
|
+
if (origin === "https://api.hasna.com/skills") {
|
|
9548
|
+
if (route === "/api/auth/whoami")
|
|
9549
|
+
return `${origin}/v1/auth/whoami`;
|
|
9550
|
+
if (!route.startsWith("/api/v1/")) {
|
|
9551
|
+
throw new SkillsFleetCredentialError("The internal Skills gateway has no established login contract yet. Select an explicitly configured instance with supported authentication.", "GATEWAY_AUTH_UNAVAILABLE");
|
|
9552
|
+
}
|
|
9553
|
+
return `${origin}${route.slice("/api".length)}`;
|
|
9554
|
+
}
|
|
9555
|
+
return `${origin}${route}`;
|
|
9556
|
+
}
|
|
9542
9557
|
function configuredSkillsApiUrl(env = process.env, keychain, profile) {
|
|
9543
9558
|
const declared = SKILLS_API_URL_ENV_KEYS.filter((key) => env[key] !== undefined).map((key) => ({ key, value: env[key] }));
|
|
9544
9559
|
for (const entry of declared) {
|
|
@@ -9891,7 +9906,14 @@ function getConfiguredApiUrl(env = process.env) {
|
|
|
9891
9906
|
}
|
|
9892
9907
|
function buildSkillsApiUrl(apiUrl, endpoint = "/skills") {
|
|
9893
9908
|
const url = new URL(apiUrl);
|
|
9909
|
+
if (url.origin === "https://api.hasna.com" && /^\/skills\/(?:api\/)?v1\/skills\/?$/.test(url.pathname)) {
|
|
9910
|
+
url.pathname = "/skills";
|
|
9911
|
+
apiUrl = url.toString();
|
|
9912
|
+
}
|
|
9894
9913
|
const cleanEndpoint = endpoint.startsWith("/") ? endpoint : `/${endpoint}`;
|
|
9914
|
+
if (normalizeSkillsApiOrigin(apiUrl) === "https://api.hasna.com/skills") {
|
|
9915
|
+
return skillsApiRequestUrl(apiUrl, `/api/v1${cleanEndpoint}`);
|
|
9916
|
+
}
|
|
9895
9917
|
const pathname = url.pathname.replace(/\/+$/, "");
|
|
9896
9918
|
const apiBase = /\/api(?:\/v1)?\/skills$/.test(pathname) ? pathname.slice(0, -"/skills".length) : pathname;
|
|
9897
9919
|
if (/\/api(?:\/v1)?$/.test(apiBase)) {
|
|
@@ -10992,8 +11014,17 @@ function creditCount(value) {
|
|
|
10992
11014
|
}
|
|
10993
11015
|
return value;
|
|
10994
11016
|
}
|
|
11017
|
+
function runQuoteReceipt(value) {
|
|
11018
|
+
if (value === undefined)
|
|
11019
|
+
return;
|
|
11020
|
+
if (typeof value !== "string" || !value.length || Buffer.byteLength(value, "utf8") > 4096) {
|
|
11021
|
+
throw new Error("Invalid quote receipt");
|
|
11022
|
+
}
|
|
11023
|
+
return value;
|
|
11024
|
+
}
|
|
10995
11025
|
function parseRemoteRunQuote(value) {
|
|
10996
11026
|
const quote = object(value);
|
|
11027
|
+
runQuoteReceipt(quote.quoteReceipt);
|
|
10997
11028
|
const pricing = object(quote.pricing);
|
|
10998
11029
|
if (typeof quote.skill !== "string" || !/^[a-z0-9][a-z0-9-]*$/.test(quote.skill))
|
|
10999
11030
|
throw new Error("Invalid quoted skill");
|
|
@@ -11059,7 +11090,7 @@ function describeRemoteFiles(files) {
|
|
|
11059
11090
|
const names = new Set;
|
|
11060
11091
|
let total = 0;
|
|
11061
11092
|
return files.map((file) => {
|
|
11062
|
-
if (
|
|
11093
|
+
if (typeof file.name !== "string" || file.name.length === 0 || file.name.length > 255 || /[/\\\x00-\x1f\x7f]/.test(file.name) || /[\ud800-\udfff]/u.test(file.name) || file.name === "." || file.name === ".." || names.has(file.name))
|
|
11063
11094
|
throw new Error("Input file names must be unique safe basenames");
|
|
11064
11095
|
names.add(file.name);
|
|
11065
11096
|
total += file.bytes.byteLength;
|
|
@@ -11278,7 +11309,7 @@ class RemoteSkillsClient {
|
|
|
11278
11309
|
this.apiUrl = normalizeSkillsApiOrigin(apiUrl);
|
|
11279
11310
|
}
|
|
11280
11311
|
async request(path, options) {
|
|
11281
|
-
return fetch(
|
|
11312
|
+
return fetch(skillsApiRequestUrl(this.apiUrl, path), {
|
|
11282
11313
|
...options,
|
|
11283
11314
|
redirect: "error",
|
|
11284
11315
|
credentials: "omit",
|
|
@@ -11338,6 +11369,7 @@ class RemoteSkillsClient {
|
|
|
11338
11369
|
return { status: res.status, body };
|
|
11339
11370
|
}
|
|
11340
11371
|
async submitRun(slug, input, args, approval = {}) {
|
|
11372
|
+
const quoteReceipt = runQuoteReceipt(approval.quoteReceipt);
|
|
11341
11373
|
if (approval.idempotencyKey !== undefined && !/^[A-Za-z0-9._:-]{1,128}$/.test(approval.idempotencyKey))
|
|
11342
11374
|
throw new Error("Idempotency key must be 1-128 URL-safe characters");
|
|
11343
11375
|
if (approval.maxCostCents !== undefined)
|
|
@@ -11354,15 +11386,20 @@ class RemoteSkillsClient {
|
|
|
11354
11386
|
...approval.maxCredits !== undefined ? { maxCredits: approval.maxCredits } : {},
|
|
11355
11387
|
...approval.maxCostCents !== undefined ? { maxCostCents: approval.maxCostCents } : {},
|
|
11356
11388
|
...approval.idempotencyKey !== undefined ? { idempotencyKey: approval.idempotencyKey } : {},
|
|
11357
|
-
...approval.inputFiles !== undefined ? { files: approval.inputFiles } : {}
|
|
11389
|
+
...approval.inputFiles !== undefined ? { files: approval.inputFiles } : {},
|
|
11390
|
+
...quoteReceipt !== undefined ? { quoteReceipt } : {}
|
|
11358
11391
|
})
|
|
11359
11392
|
});
|
|
11393
|
+
if (!res.ok) {
|
|
11394
|
+
res.body?.cancel().catch(() => {});
|
|
11395
|
+
throw new RemoteRequestError(`/api/v1/runs/${encodeURIComponent(slug)}`, res.status);
|
|
11396
|
+
}
|
|
11360
11397
|
return normalizeRemoteSkillRunContract(await res.json(), slug);
|
|
11361
11398
|
}
|
|
11362
|
-
async quoteRun(slug, input = {}, args = []) {
|
|
11399
|
+
async quoteRun(slug, input = {}, args = [], files) {
|
|
11363
11400
|
const response = await this.requestNewRoute(`/api/v1/skills/${encodeURIComponent(slug)}/quote`, {
|
|
11364
11401
|
method: "POST",
|
|
11365
|
-
body: JSON.stringify({ input, args })
|
|
11402
|
+
body: JSON.stringify({ input, args, ...files === undefined ? {} : { files } })
|
|
11366
11403
|
}, { quoteRefusal: true });
|
|
11367
11404
|
return parseRemoteRunQuote(await response.json());
|
|
11368
11405
|
}
|
|
@@ -11378,17 +11415,24 @@ class RemoteSkillsClient {
|
|
|
11378
11415
|
return this.capabilities;
|
|
11379
11416
|
}
|
|
11380
11417
|
async submitQuotedRun(slug, input = {}, args = [], approval = {}) {
|
|
11418
|
+
runQuoteReceipt(approval.quoteReceipt);
|
|
11419
|
+
({ input, args, approval } = JSON.parse(JSON.stringify({ input, args, approval })));
|
|
11381
11420
|
const maximum = creditCount(approval.maxCredits ?? approval.maxCostCents ?? 0);
|
|
11382
11421
|
if (approval.maxCostCents !== undefined && approval.maxCostCents !== maximum)
|
|
11383
11422
|
throw new Error("Credit approval fields disagree");
|
|
11384
|
-
const quote = await this.quoteRun(slug, input, args);
|
|
11385
|
-
if (quote.pricing.costCents > maximum)
|
|
11423
|
+
const quote = approval.quoteReceipt === undefined ? await this.quoteRun(slug, input, args, approval.inputFiles?.length ? approval.inputFiles : undefined) : undefined;
|
|
11424
|
+
if (quote && quote.pricing.costCents > maximum)
|
|
11386
11425
|
throw new RemoteCreditApprovalError(quote.pricing.costCents, maximum);
|
|
11387
11426
|
const capabilities = await this.getCapabilities();
|
|
11388
11427
|
if (!capabilities.capabilities.includes("runs.submit") || capabilities.billing?.boundedRunApproval !== true || capabilities.billing.unit !== "credits") {
|
|
11389
11428
|
throw new Error("The configured server does not support bounded credit approval; refusing remote submission");
|
|
11390
11429
|
}
|
|
11391
|
-
return this.submitRun(quote
|
|
11430
|
+
return this.submitRun(quote?.skill ?? slug, input, args, {
|
|
11431
|
+
...approval,
|
|
11432
|
+
maxCredits: maximum,
|
|
11433
|
+
maxCostCents: maximum,
|
|
11434
|
+
...(quote?.quoteReceipt ?? approval.quoteReceipt) === undefined ? {} : { quoteReceipt: quote?.quoteReceipt ?? approval.quoteReceipt }
|
|
11435
|
+
});
|
|
11392
11436
|
}
|
|
11393
11437
|
async getIdentity() {
|
|
11394
11438
|
return (await this.requestNewRoute("/api/auth/whoami")).json();
|
|
@@ -11676,6 +11720,10 @@ class RemoteSkillsClient {
|
|
|
11676
11720
|
return { id: artifactId, fileName: String(artifact.fileName ?? artifactId), bytes, byteSize: bytes.byteLength, sha256: artifact.sha256 };
|
|
11677
11721
|
}
|
|
11678
11722
|
async submitQuotedRunWithFiles(slug, input, args, files, approval = {}) {
|
|
11723
|
+
runQuoteReceipt(approval.quoteReceipt);
|
|
11724
|
+
({ input, args, approval } = JSON.parse(JSON.stringify({ input, args, approval })));
|
|
11725
|
+
describeRemoteFiles(files);
|
|
11726
|
+
files = files.map((file) => ({ name: file.name, contentType: file.contentType, bytes: new Uint8Array(file.bytes) }));
|
|
11679
11727
|
const inputFiles = describeRemoteFiles(files);
|
|
11680
11728
|
if (files.length && !(await this.getCapabilities()).capabilities.includes("runs.uploads"))
|
|
11681
11729
|
throw new Error("The configured server does not support input uploads");
|
|
@@ -11739,7 +11787,7 @@ class RemoteSkillsClient {
|
|
|
11739
11787
|
const headers = { Authorization: `Bearer ${this.apiKey}` };
|
|
11740
11788
|
if (ifMatch)
|
|
11741
11789
|
headers["If-Match"] = ifMatch;
|
|
11742
|
-
return fetch(
|
|
11790
|
+
return fetch(skillsApiRequestUrl(this.apiUrl, "/api/v1/skills"), {
|
|
11743
11791
|
method: "POST",
|
|
11744
11792
|
headers,
|
|
11745
11793
|
body: form,
|
|
@@ -13288,7 +13336,7 @@ import { dirname as dirname7, relative as relative4 } from "path";
|
|
|
13288
13336
|
// package.json
|
|
13289
13337
|
var package_default = {
|
|
13290
13338
|
name: "@hasna/skills",
|
|
13291
|
-
version: "0.5.
|
|
13339
|
+
version: "0.5.6",
|
|
13292
13340
|
description: "Skills library for AI coding agents",
|
|
13293
13341
|
type: "module",
|
|
13294
13342
|
bin: {
|
|
@@ -14022,7 +14070,7 @@ var toolContracts = [
|
|
|
14022
14070
|
name: "run_skill",
|
|
14023
14071
|
title: "Run Skill",
|
|
14024
14072
|
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.",
|
|
14025
|
-
params: ["name", "input?", "args?", "detail?", "remote?", "maxCredits?", "maxCostCents?", "idempotency_key?", "files?"],
|
|
14073
|
+
params: ["name", "input?", "args?", "detail?", "remote?", "maxCredits?", "maxCostCents?", "quoteReceipt?", "idempotency_key?", "files?"],
|
|
14026
14074
|
category: "execution",
|
|
14027
14075
|
sideEffects: "local-process-or-remote-run",
|
|
14028
14076
|
stable: true,
|
|
@@ -14034,6 +14082,7 @@ var toolContracts = [
|
|
|
14034
14082
|
remote: { type: "boolean", description: "Use the configured server catalog." },
|
|
14035
14083
|
maxCredits: { type: "integer", minimum: 0, description: "Maximum explicitly approved integer credits; omitted permits only free remote runs." },
|
|
14036
14084
|
maxCostCents: { type: "integer", minimum: 0, description: "Legacy alias for maxCredits; both must agree." },
|
|
14085
|
+
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." },
|
|
14037
14086
|
idempotency_key: { type: "string", pattern: "^[A-Za-z0-9._:-]{1,128}$", description: "Stable retry key for the same remote submission." },
|
|
14038
14087
|
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." }
|
|
14039
14088
|
}, ["name"]),
|
|
@@ -14317,12 +14366,17 @@ remoteCustomerContracts.push({
|
|
|
14317
14366
|
name: "quote_skill",
|
|
14318
14367
|
title: "Quote Remote Skill",
|
|
14319
14368
|
description: "Get a server credit quote without submitting a run.",
|
|
14320
|
-
params: ["name", "input?", "args?"],
|
|
14369
|
+
params: ["name", "input?", "args?", "files?"],
|
|
14321
14370
|
category: "execution",
|
|
14322
14371
|
sideEffects: "none",
|
|
14323
14372
|
stable: true,
|
|
14324
|
-
inputSchema: objectSchema({
|
|
14325
|
-
|
|
14373
|
+
inputSchema: objectSchema({
|
|
14374
|
+
name: skillNameInput,
|
|
14375
|
+
input: runInputSchema,
|
|
14376
|
+
args: runArgsSchema,
|
|
14377
|
+
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." }
|
|
14378
|
+
}, ["name"]),
|
|
14379
|
+
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)
|
|
14326
14380
|
});
|
|
14327
14381
|
remoteCustomerContracts.push({
|
|
14328
14382
|
name: "download_run_artifact",
|
|
@@ -14335,7 +14389,47 @@ remoteCustomerContracts.push({
|
|
|
14335
14389
|
inputSchema: objectSchema({ run_id: stringSchema("Run identifier."), artifact_id: stringSchema("Artifact identifier.") }, ["run_id", "artifact_id"]),
|
|
14336
14390
|
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"])
|
|
14337
14391
|
});
|
|
14338
|
-
var
|
|
14392
|
+
var publicationUuidSchema = { type: "string", pattern: "^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$" };
|
|
14393
|
+
var publicationVerification = {
|
|
14394
|
+
email: { type: "string", format: "email", maxLength: 254 },
|
|
14395
|
+
code: { type: "string", pattern: "^\\d{6}$" },
|
|
14396
|
+
userId: publicationUuidSchema,
|
|
14397
|
+
membershipId: publicationUuidSchema,
|
|
14398
|
+
recoveryDirectory: { type: "string", maxLength: 4096, description: "Absolute host-local recovery directory without symbolic links." }
|
|
14399
|
+
};
|
|
14400
|
+
var privatePublicationContracts = [
|
|
14401
|
+
{ name: "publish_private_skill", title: "Publish private skill", extras: {
|
|
14402
|
+
directory: { type: "string", maxLength: 4096, description: "Absolute local skill source directory." },
|
|
14403
|
+
skillId: publicationUuidSchema,
|
|
14404
|
+
expectedCurrentVersionId: { oneOf: [publicationUuidSchema, { type: "null" }] },
|
|
14405
|
+
idempotencyKey: publicationUuidSchema,
|
|
14406
|
+
confirm: { const: true },
|
|
14407
|
+
waitMs: { type: "integer", minimum: 0, maximum: 300000 }
|
|
14408
|
+
}, required: ["directory", "skillId", "expectedCurrentVersionId", "confirm"] },
|
|
14409
|
+
{ name: "get_private_publication", title: "Get private publication", extras: {}, required: [] },
|
|
14410
|
+
{ name: "resume_private_publication", title: "Resume private publication", extras: { confirm: { const: true }, waitMs: { type: "integer", minimum: 0, maximum: 300000 } }, required: ["confirm"] },
|
|
14411
|
+
{ name: "cancel_private_publication", title: "Cancel private publication", extras: { confirm: { const: true } }, required: ["confirm"] }
|
|
14412
|
+
].map((operation) => ({
|
|
14413
|
+
name: operation.name,
|
|
14414
|
+
title: operation.title,
|
|
14415
|
+
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.",
|
|
14416
|
+
params: [...Object.keys(publicationVerification), ...Object.keys(operation.extras)],
|
|
14417
|
+
category: "storage",
|
|
14418
|
+
sideEffects: "filesystem",
|
|
14419
|
+
stable: true,
|
|
14420
|
+
inputSchema: objectSchema({ ...publicationVerification, ...operation.extras }, [...Object.keys(publicationVerification), ...operation.required]),
|
|
14421
|
+
outputSchema: objectSchema({
|
|
14422
|
+
recoveryDirectory: { type: "string" },
|
|
14423
|
+
skillId: publicationUuidSchema,
|
|
14424
|
+
intentId: { oneOf: [publicationUuidSchema, { type: "null" }] },
|
|
14425
|
+
state: { type: "string" },
|
|
14426
|
+
versionId: { oneOf: [publicationUuidSchema, { type: "null" }] },
|
|
14427
|
+
committed: { type: "boolean" },
|
|
14428
|
+
executionEnabled: { const: false },
|
|
14429
|
+
nextAction: { type: "string" }
|
|
14430
|
+
}, ["recoveryDirectory", "skillId", "intentId", "state", "versionId", "committed", "executionEnabled", "nextAction"])
|
|
14431
|
+
}));
|
|
14432
|
+
var contracts = [...toolContracts, ...remoteCustomerContracts, ...privatePublicationContracts].sort((a, b) => a.name.localeCompare(b.name));
|
|
14339
14433
|
var resourceContracts = [
|
|
14340
14434
|
{
|
|
14341
14435
|
uri: "skills://mcp/contracts",
|
|
@@ -15096,11 +15190,15 @@ function normalizeHeaders(headers) {
|
|
|
15096
15190
|
}
|
|
15097
15191
|
return result;
|
|
15098
15192
|
}
|
|
15193
|
+
function encodeAwsUriComponent(value) {
|
|
15194
|
+
return encodeURIComponent(value).replace(/[!'()*]/g, (char) => `%${char.charCodeAt(0).toString(16).toUpperCase()}`);
|
|
15195
|
+
}
|
|
15099
15196
|
function canonicalizeQuery(params) {
|
|
15100
|
-
|
|
15197
|
+
const compare = (a, b) => a < b ? -1 : a > b ? 1 : 0;
|
|
15198
|
+
return [...params.entries()].map(([key, value]) => [encodeAwsUriComponent(key), encodeAwsUriComponent(value)]).sort(([aKey, aValue], [bKey, bValue]) => compare(aKey, bKey) || compare(aValue, bValue)).map(([key, value]) => `${key}=${value}`).join("&");
|
|
15101
15199
|
}
|
|
15102
15200
|
function encodeUriPath(pathname) {
|
|
15103
|
-
return pathname.split("/").map((segment) =>
|
|
15201
|
+
return pathname.split("/").map((segment) => encodeAwsUriComponent(decodeURIComponent(segment))).join("/");
|
|
15104
15202
|
}
|
|
15105
15203
|
function toAmzDate(date) {
|
|
15106
15204
|
return date.toISOString().replace(/[:-]|\.\d{3}/g, "");
|
|
@@ -15822,7 +15920,7 @@ async function requestInvitationEmail(origin, action, input) {
|
|
|
15822
15920
|
}
|
|
15823
15921
|
const body = JSON.stringify({ invitationId: value.invitationId, token: value.token, challengeId: value.challengeId, ...action === "accept" ? { code: value.code } : {} });
|
|
15824
15922
|
try {
|
|
15825
|
-
const response = await fetch(
|
|
15923
|
+
const response = await fetch(skillsApiRequestUrl(target, `/api/v1/account/invitations/email-${action}`), {
|
|
15826
15924
|
method: "POST",
|
|
15827
15925
|
headers: { "Content-Type": "application/json" },
|
|
15828
15926
|
body,
|
|
@@ -15853,34 +15951,341 @@ async function requestInvitationEmail(origin, action, input) {
|
|
|
15853
15951
|
throw new RemoteInvitationEmailUnconfirmedError(action);
|
|
15854
15952
|
}
|
|
15855
15953
|
|
|
15856
|
-
// src/lib/remote-
|
|
15857
|
-
|
|
15954
|
+
// src/lib/remote-private-publications.ts
|
|
15955
|
+
import { createHash as createHash9 } from "crypto";
|
|
15956
|
+
var PRIVATE_PUBLICATION_MAX_BYTES = 16 * 1024 * 1024;
|
|
15957
|
+
var failures = {
|
|
15958
|
+
INVALID_REQUEST: [400, "The publication request is invalid."],
|
|
15959
|
+
SESSION_EXPIRED: [401, "Sign in again to manage this publication."],
|
|
15960
|
+
ACCOUNT_UNAVAILABLE: [403, "The account is unavailable."],
|
|
15961
|
+
INTERACTIVE_SESSION_REQUIRED: [403, "An interactive account session is required."],
|
|
15962
|
+
PUBLICATION_FORBIDDEN: [403, "This session cannot manage the publication."],
|
|
15963
|
+
PUBLICATION_ENTITLEMENT_REQUIRED: [403, "The workspace is not entitled to publish private skills."],
|
|
15964
|
+
PUBLICATION_UNAVAILABLE: [404, "The publication is unavailable to this session."],
|
|
15965
|
+
MANIFEST_NAME_MISMATCH: [409, "The manifest name does not match the selected skill."],
|
|
15966
|
+
IDEMPOTENCY_CONFLICT: [409, "This request key already identifies different publication bytes. Use the saved recovery directory."],
|
|
15967
|
+
CURRENT_VERSION_CHANGED: [409, "The current version changed. Inspect it before explicitly starting another publication."],
|
|
15968
|
+
VERSION_EXISTS: [409, "This version already exists."],
|
|
15969
|
+
VERSION_RESERVED: [409, "This version is reserved by another publication."],
|
|
15970
|
+
PUBLICATION_COMMITTED: [409, "The publication is already committed."],
|
|
15971
|
+
PUBLICATION_UPLOAD_UNAVAILABLE: [409, "This publication cannot receive another upload."],
|
|
15972
|
+
PUBLICATION_LIMIT: [429, "The workspace publication limit has been reached."],
|
|
15973
|
+
PUBLICATION_BUSY: [503, "The publication is busy. Reconcile the saved intent before retrying."],
|
|
15974
|
+
PUBLICATION_UNCERTAIN: [503, "The publication outcome is uncertain. Reconcile the saved intent."],
|
|
15975
|
+
PUBLICATION_CAPABILITY_UNAVAILABLE: [503, "Private publishing is not enabled on this server."],
|
|
15976
|
+
PUBLICATION_SIGNING_UNAVAILABLE: [503, "Upload authorization is temporarily unavailable. Keep the same intent."]
|
|
15977
|
+
};
|
|
15858
15978
|
|
|
15859
|
-
class
|
|
15860
|
-
status;
|
|
15979
|
+
class PrivatePublicationError extends Error {
|
|
15861
15980
|
code;
|
|
15862
|
-
|
|
15863
|
-
|
|
15864
|
-
|
|
15865
|
-
constructor(message, options = {}) {
|
|
15981
|
+
uncertain;
|
|
15982
|
+
status;
|
|
15983
|
+
constructor(code, message, uncertain = false, status) {
|
|
15866
15984
|
super(message);
|
|
15867
|
-
this.
|
|
15868
|
-
this.
|
|
15869
|
-
this.
|
|
15870
|
-
this.
|
|
15871
|
-
this.endpoint = options.endpoint;
|
|
15872
|
-
this.apiUrl = options.apiUrl;
|
|
15985
|
+
this.code = code;
|
|
15986
|
+
this.uncertain = uncertain;
|
|
15987
|
+
this.status = status;
|
|
15988
|
+
this.name = "PrivatePublicationError";
|
|
15873
15989
|
}
|
|
15874
15990
|
}
|
|
15875
|
-
|
|
15876
|
-
|
|
15877
|
-
|
|
15878
|
-
|
|
15879
|
-
|
|
15991
|
+
var bad = () => {
|
|
15992
|
+
throw new PrivatePublicationError("INVALID_PUBLICATION_INPUT", "Invalid publication input or recovery data.");
|
|
15993
|
+
};
|
|
15994
|
+
var invalid3 = () => {
|
|
15995
|
+
throw new PrivatePublicationError("INVALID_PUBLICATION_RESPONSE", "The server returned an invalid publication result.");
|
|
15996
|
+
};
|
|
15997
|
+
var 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);
|
|
15998
|
+
var hash = (v) => typeof v === "string" && /^[a-f0-9]{64}$/.test(v);
|
|
15999
|
+
var record5 = (v) => !!v && typeof v === "object" && !Array.isArray(v);
|
|
16000
|
+
var exact = (v, keys) => record5(v) && Object.keys(v).sort().join(",") === keys.sort().join(",");
|
|
16001
|
+
var date = (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));
|
|
16002
|
+
var publicationSha256 = (bytes) => createHash9("sha256").update(bytes).digest("hex");
|
|
16003
|
+
function checkedPublicationDeclaration(value) {
|
|
16004
|
+
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)
|
|
16005
|
+
return bad();
|
|
15880
16006
|
try {
|
|
15881
|
-
|
|
15882
|
-
|
|
15883
|
-
|
|
16007
|
+
const manifest = JSON.parse(value.manifestText);
|
|
16008
|
+
if (!record5(manifest) || manifest.version !== value.version || validatePortableManifestContract(manifest, { strict: true }).length || !hash(manifest.provenance?.content_hash))
|
|
16009
|
+
return bad();
|
|
16010
|
+
} catch {
|
|
16011
|
+
return bad();
|
|
16012
|
+
}
|
|
16013
|
+
return Object.freeze({ ...value });
|
|
16014
|
+
}
|
|
16015
|
+
function checkedPublicationView(value, skillId, intentId, declaration) {
|
|
16016
|
+
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) || !date(value.expiresAt) || !date(value.createdAt) || !(value.versionId === null || publicationUuid(value.versionId)) || value.state === "committed" && value.versionId === null)
|
|
16017
|
+
return invalid3();
|
|
16018
|
+
if (declaration && ["version", "expectedCurrentVersionId", "archiveSha256", "archiveByteSize"].some((k) => value[k] !== declaration[k]))
|
|
16019
|
+
return invalid3();
|
|
16020
|
+
return Object.freeze({ ...value });
|
|
16021
|
+
}
|
|
16022
|
+
async function boundedJson(url, init, token, mutation, budget = 15000, signal) {
|
|
16023
|
+
const controller = new AbortController;
|
|
16024
|
+
let reader;
|
|
16025
|
+
let response;
|
|
16026
|
+
const timeout = new PrivatePublicationError("PUBLICATION_UNCONFIRMED", "No confirmed publication result. Inspect the saved intent before retrying.", mutation);
|
|
16027
|
+
let timer;
|
|
16028
|
+
let abort;
|
|
16029
|
+
try {
|
|
16030
|
+
return await Promise.race([(async () => {
|
|
16031
|
+
if (signal?.aborted)
|
|
16032
|
+
throw timeout;
|
|
16033
|
+
response = await fetch(url, {
|
|
16034
|
+
...init,
|
|
16035
|
+
redirect: "error",
|
|
16036
|
+
credentials: "omit",
|
|
16037
|
+
signal: controller.signal,
|
|
16038
|
+
headers: { "Content-Type": "application/json", Authorization: `Bearer ${token}` }
|
|
16039
|
+
});
|
|
16040
|
+
const length = response.headers.get("content-length");
|
|
16041
|
+
if (length !== null && (!/^\d+$/.test(length) || Number(length) > 65536))
|
|
16042
|
+
return invalid3();
|
|
16043
|
+
reader = response.body?.getReader();
|
|
16044
|
+
const chunks = [];
|
|
16045
|
+
let size = 0;
|
|
16046
|
+
if (reader)
|
|
16047
|
+
while (true) {
|
|
16048
|
+
const part = await reader.read();
|
|
16049
|
+
if (part.done)
|
|
16050
|
+
break;
|
|
16051
|
+
size += part.value.byteLength;
|
|
16052
|
+
if (size > 65536)
|
|
16053
|
+
return invalid3();
|
|
16054
|
+
chunks.push(part.value);
|
|
16055
|
+
}
|
|
16056
|
+
if (controller.signal.aborted)
|
|
16057
|
+
throw timeout;
|
|
16058
|
+
const bytes = Buffer.concat(chunks);
|
|
16059
|
+
let body;
|
|
16060
|
+
try {
|
|
16061
|
+
body = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(bytes));
|
|
16062
|
+
} catch {
|
|
16063
|
+
return invalid3();
|
|
16064
|
+
}
|
|
16065
|
+
if (!response.ok) {
|
|
16066
|
+
const code = record5(body) && typeof body.code === "string" && Object.hasOwn(failures, body.code) ? body.code : null;
|
|
16067
|
+
if (code && failures[code][0] === response.status)
|
|
16068
|
+
throw new PrivatePublicationError(code, failures[code][1], mutation && code === "PUBLICATION_UNCERTAIN", response.status);
|
|
16069
|
+
throw new PrivatePublicationError("PUBLICATION_REQUEST_FAILED", "The publication request was refused. Inspect its status before retrying.", mutation && response.status >= 500, response.status);
|
|
16070
|
+
}
|
|
16071
|
+
return body;
|
|
16072
|
+
})(), new Promise((_, reject) => {
|
|
16073
|
+
abort = () => {
|
|
16074
|
+
controller.abort();
|
|
16075
|
+
reject(timeout);
|
|
16076
|
+
};
|
|
16077
|
+
timer = setTimeout(abort, Math.max(1, Math.min(15000, budget)));
|
|
16078
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
16079
|
+
})]);
|
|
16080
|
+
} catch (error) {
|
|
16081
|
+
if (error instanceof PrivatePublicationError) {
|
|
16082
|
+
if (mutation && error.code === "INVALID_PUBLICATION_RESPONSE")
|
|
16083
|
+
throw timeout;
|
|
16084
|
+
throw error;
|
|
16085
|
+
}
|
|
16086
|
+
throw timeout;
|
|
16087
|
+
} finally {
|
|
16088
|
+
if (timer)
|
|
16089
|
+
clearTimeout(timer);
|
|
16090
|
+
if (abort)
|
|
16091
|
+
signal?.removeEventListener("abort", abort);
|
|
16092
|
+
controller.abort();
|
|
16093
|
+
if (reader)
|
|
16094
|
+
reader.cancel().catch(() => {});
|
|
16095
|
+
else
|
|
16096
|
+
response?.body?.cancel().catch(() => {});
|
|
16097
|
+
}
|
|
16098
|
+
}
|
|
16099
|
+
|
|
16100
|
+
class RemotePrivatePublicationsClient {
|
|
16101
|
+
apiOrigin;
|
|
16102
|
+
organizationId;
|
|
16103
|
+
userId;
|
|
16104
|
+
membershipId;
|
|
16105
|
+
#token;
|
|
16106
|
+
constructor(apiUrl, session) {
|
|
16107
|
+
const checked = parseWorkspaceSession(session, { userId: session?.user?.id, membershipId: session?.user?.membershipId });
|
|
16108
|
+
if (checked.user.role === "viewer")
|
|
16109
|
+
throw new PrivatePublicationError("PUBLICATION_FORBIDDEN", failures.PUBLICATION_FORBIDDEN[1]);
|
|
16110
|
+
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
16111
|
+
this.#token = checked.token;
|
|
16112
|
+
this.organizationId = checked.organization.id;
|
|
16113
|
+
this.userId = checked.user.id;
|
|
16114
|
+
this.membershipId = checked.user.membershipId;
|
|
16115
|
+
Object.freeze(this);
|
|
16116
|
+
}
|
|
16117
|
+
async getCapability(options = {}) {
|
|
16118
|
+
if (options.timeoutMs !== undefined && (!Number.isSafeInteger(options.timeoutMs) || options.timeoutMs < 1 || options.timeoutMs > 15000))
|
|
16119
|
+
return bad();
|
|
16120
|
+
const response = await boundedJson(skillsApiRequestUrl(this.apiOrigin, "/api/v1/capabilities"), {}, this.#token, false, options.timeoutMs, options.signal);
|
|
16121
|
+
const p = record5(response) && response.privatePublishing;
|
|
16122
|
+
if (!record5(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)
|
|
16123
|
+
throw new PrivatePublicationError("PUBLICATION_CONTRACT_UNAVAILABLE", "This server does not support the hosted private publication contract.");
|
|
16124
|
+
return Object.freeze({ ...p });
|
|
16125
|
+
}
|
|
16126
|
+
async#gate(enabled, options = {}) {
|
|
16127
|
+
if (!(await this.getCapability(options)).enabled && enabled)
|
|
16128
|
+
throw new PrivatePublicationError("PUBLICATION_CAPABILITY_UNAVAILABLE", failures.PUBLICATION_CAPABILITY_UNAVAILABLE[1]);
|
|
16129
|
+
}
|
|
16130
|
+
#path(skillId, intentId) {
|
|
16131
|
+
if (!publicationUuid(skillId) || intentId !== undefined && !publicationUuid(intentId))
|
|
16132
|
+
return bad();
|
|
16133
|
+
return skillsApiRequestUrl(this.apiOrigin, `/api/v1/skills/${skillId}/publication-uploads${intentId ? `/${intentId}` : ""}`);
|
|
16134
|
+
}
|
|
16135
|
+
async#view(path, method, skillId, intentId, declaration, options = {}) {
|
|
16136
|
+
const value = await boundedJson(path, { method, ...method === "GET" ? {} : { body: JSON.stringify(declaration ?? {}) } }, this.#token, method !== "GET", options.timeoutMs, options.signal);
|
|
16137
|
+
try {
|
|
16138
|
+
if (!record5(value) || !Object.keys(value).every((k) => k === "upload" || k === "changed") || value.changed !== undefined && typeof value.changed !== "boolean")
|
|
16139
|
+
return invalid3();
|
|
16140
|
+
return checkedPublicationView(value.upload, skillId, intentId, declaration);
|
|
16141
|
+
} catch (error) {
|
|
16142
|
+
if (method !== "GET")
|
|
16143
|
+
throw new PrivatePublicationError("PUBLICATION_UNCONFIRMED", "The publication result could not be confirmed. Reconcile the saved intent before another action.", true);
|
|
16144
|
+
throw error;
|
|
16145
|
+
}
|
|
16146
|
+
}
|
|
16147
|
+
async begin(skillId, input) {
|
|
16148
|
+
const path = this.#path(skillId), declaration = checkedPublicationDeclaration(input);
|
|
16149
|
+
await this.#gate(true);
|
|
16150
|
+
return this.#view(path, "POST", skillId, undefined, declaration);
|
|
16151
|
+
}
|
|
16152
|
+
async get(skillId, intentId, options = {}) {
|
|
16153
|
+
const path = this.#path(skillId, intentId), until = Date.now() + (options.timeoutMs ?? 15000);
|
|
16154
|
+
await this.#gate(false, options);
|
|
16155
|
+
return this.#view(path, "GET", skillId, intentId, undefined, { ...options, timeoutMs: Math.max(1, until - Date.now()) });
|
|
16156
|
+
}
|
|
16157
|
+
async finalize(skillId, intentId) {
|
|
16158
|
+
const path = this.#path(skillId, intentId);
|
|
16159
|
+
await this.#gate(true);
|
|
16160
|
+
return this.#view(`${path}/finalize`, "POST", skillId, intentId);
|
|
16161
|
+
}
|
|
16162
|
+
async cancel(skillId, intentId) {
|
|
16163
|
+
const path = this.#path(skillId, intentId);
|
|
16164
|
+
await this.#gate(false);
|
|
16165
|
+
return this.#view(path, "DELETE", skillId, intentId);
|
|
16166
|
+
}
|
|
16167
|
+
async upload(skillId, intent, bytes) {
|
|
16168
|
+
const captured = checkedPublicationView(intent, skillId), path = this.#path(skillId, captured.id);
|
|
16169
|
+
if (!(bytes instanceof Uint8Array) || bytes.byteLength !== captured.archiveByteSize)
|
|
16170
|
+
return bad();
|
|
16171
|
+
const owned = Buffer.from(bytes);
|
|
16172
|
+
if (captured.state !== "awaiting_upload" || owned.byteLength !== captured.archiveByteSize || publicationSha256(owned) !== captured.archiveSha256)
|
|
16173
|
+
return bad();
|
|
16174
|
+
await this.#gate(true);
|
|
16175
|
+
const value = await boundedJson(`${path}/upload-url`, { method: "POST", body: "{}" }, this.#token, false);
|
|
16176
|
+
const upload = this.#upload(value, captured);
|
|
16177
|
+
const controller = new AbortController;
|
|
16178
|
+
let timer;
|
|
16179
|
+
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);
|
|
16180
|
+
try {
|
|
16181
|
+
await Promise.race([(async () => {
|
|
16182
|
+
const response = await fetch(upload.uploadUrl, { method: "PUT", headers: upload.headers, body: owned, redirect: "error", credentials: "omit", signal: controller.signal });
|
|
16183
|
+
response.body?.cancel().catch(() => {});
|
|
16184
|
+
if (response.status !== 200 || controller.signal.aborted)
|
|
16185
|
+
throw uncertain();
|
|
16186
|
+
})(), new Promise((_, reject) => {
|
|
16187
|
+
timer = setTimeout(() => {
|
|
16188
|
+
controller.abort();
|
|
16189
|
+
reject(uncertain());
|
|
16190
|
+
}, 30000);
|
|
16191
|
+
})]);
|
|
16192
|
+
} catch {
|
|
16193
|
+
throw uncertain();
|
|
16194
|
+
} finally {
|
|
16195
|
+
if (timer)
|
|
16196
|
+
clearTimeout(timer);
|
|
16197
|
+
controller.abort();
|
|
16198
|
+
}
|
|
16199
|
+
}
|
|
16200
|
+
#upload(value, intent) {
|
|
16201
|
+
if (!exact(value, ["upload"]) || !exact(value.upload, ["method", "uploadUrl", "headers", "expiresAt"]))
|
|
16202
|
+
return invalid3();
|
|
16203
|
+
const p = value.upload;
|
|
16204
|
+
if (p.method !== "PUT" || typeof p.uploadUrl !== "string" || p.uploadUrl.length > 8192 || /[\x00-\x20\x7f]/.test(p.uploadUrl) || !date(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"]))
|
|
16205
|
+
return invalid3();
|
|
16206
|
+
let url;
|
|
16207
|
+
try {
|
|
16208
|
+
url = new URL(p.uploadUrl);
|
|
16209
|
+
} catch {
|
|
16210
|
+
return invalid3();
|
|
16211
|
+
}
|
|
16212
|
+
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") ?? ""))
|
|
16213
|
+
return invalid3();
|
|
16214
|
+
const queryKeys = ["X-Amz-Algorithm", "X-Amz-Credential", "X-Amz-Date", "X-Amz-Expires", "X-Amz-Security-Token", "X-Amz-Signature", "X-Amz-SignedHeaders"];
|
|
16215
|
+
if ([...url.searchParams.keys()].sort().join(",") !== queryKeys.sort().join(","))
|
|
16216
|
+
return invalid3();
|
|
16217
|
+
const issued = url.searchParams.get("X-Amz-Date"), ttl = url.searchParams.get("X-Amz-Expires"), credential = url.searchParams.get("X-Amz-Credential");
|
|
16218
|
+
const timestamp3 = /^(\d{4})(\d\d)(\d\d)T(\d\d)(\d\d)(\d\d)Z$/.exec(issued);
|
|
16219
|
+
const region = url.hostname.split(".s3.")[1].split(".amazonaws.com")[0];
|
|
16220
|
+
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")))
|
|
16221
|
+
return invalid3();
|
|
16222
|
+
const issuedAt = Date.parse(`${timestamp3[1]}-${timestamp3[2]}-${timestamp3[3]}T${timestamp3[4]}:${timestamp3[5]}:${timestamp3[6]}Z`);
|
|
16223
|
+
if (!Number.isFinite(issuedAt) || issuedAt > Date.now() + 1000 || issuedAt + Number(ttl) * 1000 !== Date.parse(p.expiresAt))
|
|
16224
|
+
return invalid3();
|
|
16225
|
+
return { method: "PUT", uploadUrl: url.href, expiresAt: p.expiresAt, headers: Object.freeze({ ...p.headers }) };
|
|
16226
|
+
}
|
|
16227
|
+
async wait(skillId, intentId, options = {}) {
|
|
16228
|
+
const timeout = options.timeoutMs ?? 60000;
|
|
16229
|
+
if (!Number.isSafeInteger(timeout) || timeout < 0 || timeout > 300000)
|
|
16230
|
+
return bad();
|
|
16231
|
+
const until = Date.now() + timeout;
|
|
16232
|
+
let previous;
|
|
16233
|
+
while (true) {
|
|
16234
|
+
if (options.signal?.aborted)
|
|
16235
|
+
throw new PrivatePublicationError("PUBLICATION_WAIT_ABORTED", "Stopped waiting. The server publication continues; inspect the saved intent.");
|
|
16236
|
+
let view;
|
|
16237
|
+
try {
|
|
16238
|
+
view = await this.get(skillId, intentId, { timeoutMs: timeout === 0 ? 15000 : Math.max(1, Math.min(15000, until - Date.now())), signal: options.signal });
|
|
16239
|
+
} catch (error) {
|
|
16240
|
+
if (previous && Date.now() >= until && !options.signal?.aborted)
|
|
16241
|
+
return previous;
|
|
16242
|
+
throw error;
|
|
16243
|
+
}
|
|
16244
|
+
previous = view;
|
|
16245
|
+
if (!["queued", "verifying"].includes(view.state) || Date.now() >= until)
|
|
16246
|
+
return view;
|
|
16247
|
+
await new Promise((resolve4) => {
|
|
16248
|
+
const timer = setTimeout(done, Math.min(1000, until - Date.now()));
|
|
16249
|
+
function done() {
|
|
16250
|
+
clearTimeout(timer);
|
|
16251
|
+
options.signal?.removeEventListener("abort", done);
|
|
16252
|
+
resolve4();
|
|
16253
|
+
}
|
|
16254
|
+
options.signal?.addEventListener("abort", done, { once: true });
|
|
16255
|
+
});
|
|
16256
|
+
}
|
|
16257
|
+
}
|
|
16258
|
+
}
|
|
16259
|
+
|
|
16260
|
+
// src/lib/remote-auth.ts
|
|
16261
|
+
var MAX_ERROR_DETAIL_LENGTH = 200;
|
|
16262
|
+
|
|
16263
|
+
class HostedApiError extends Error {
|
|
16264
|
+
status;
|
|
16265
|
+
code;
|
|
16266
|
+
detail;
|
|
16267
|
+
endpoint;
|
|
16268
|
+
apiUrl;
|
|
16269
|
+
constructor(message, options = {}) {
|
|
16270
|
+
super(message);
|
|
16271
|
+
this.name = "HostedApiError";
|
|
16272
|
+
this.status = options.status;
|
|
16273
|
+
this.code = options.code;
|
|
16274
|
+
this.detail = options.detail;
|
|
16275
|
+
this.endpoint = options.endpoint;
|
|
16276
|
+
this.apiUrl = options.apiUrl;
|
|
16277
|
+
}
|
|
16278
|
+
}
|
|
16279
|
+
async function requestAuthApi(instance, path, options) {
|
|
16280
|
+
const url = normalizeSkillsApiOrigin(instance);
|
|
16281
|
+
const safeUrl = url;
|
|
16282
|
+
const requestUrl = skillsApiRequestUrl(url, path);
|
|
16283
|
+
const endpoint = `${(options?.method || "GET").toUpperCase()} ${requestUrl}`;
|
|
16284
|
+
let res;
|
|
16285
|
+
try {
|
|
16286
|
+
res = await fetch(requestUrl, {
|
|
16287
|
+
...options,
|
|
16288
|
+
redirect: "error",
|
|
15884
16289
|
signal: options?.signal ?? AbortSignal.timeout(15000),
|
|
15885
16290
|
headers: { "Content-Type": "application/json", ...options?.headers }
|
|
15886
16291
|
});
|
|
@@ -15893,10 +16298,10 @@ async function requestAuthApi(instance, path, options) {
|
|
|
15893
16298
|
const text2 = await res.text();
|
|
15894
16299
|
const body = text2 ? parseJsonBody(text2) : {};
|
|
15895
16300
|
if (!res.ok) {
|
|
15896
|
-
const
|
|
15897
|
-
const detail = typeof
|
|
15898
|
-
const error = typeof
|
|
15899
|
-
const code = typeof
|
|
16301
|
+
const record6 = isRecord5(body) ? body : {};
|
|
16302
|
+
const detail = typeof record6.detail === "string" ? record6.detail : undefined;
|
|
16303
|
+
const error = typeof record6.error === "string" ? record6.error : undefined;
|
|
16304
|
+
const code = typeof record6.code === "string" ? record6.code : undefined;
|
|
15900
16305
|
throw new HostedApiError(detail || error || `${res.status} ${res.statusText}`, {
|
|
15901
16306
|
status: res.status,
|
|
15902
16307
|
code,
|
|
@@ -15930,6 +16335,10 @@ class RemoteSkillsAuthClient {
|
|
|
15930
16335
|
constructor(apiUrl) {
|
|
15931
16336
|
this.apiOrigin = normalizeSkillsApiOrigin(apiUrl);
|
|
15932
16337
|
}
|
|
16338
|
+
async openPrivatePublications(email2, code, context) {
|
|
16339
|
+
const origin = this.apiOrigin, captured = workspaceContext(context);
|
|
16340
|
+
return new RemotePrivatePublicationsClient(origin, await this.switchWorkspace(email2, code, captured));
|
|
16341
|
+
}
|
|
15933
16342
|
requestInvitationEmailChallenge(input) {
|
|
15934
16343
|
return requestInvitationEmail(this.apiOrigin, "challenge", input);
|
|
15935
16344
|
}
|
|
@@ -15977,9 +16386,10 @@ class RemoteSkillsAuthClient {
|
|
|
15977
16386
|
const apiOrigin = this.apiOrigin;
|
|
15978
16387
|
if (typeof email2 !== "string" || !email2.includes("@") || typeof code !== "string" || !/^\d{6}$/.test(code))
|
|
15979
16388
|
throw new Error("Fresh email and six-digit verification code are required to manage this account");
|
|
16389
|
+
const requestUrl = skillsApiRequestUrl(apiOrigin, "/api/auth/verify");
|
|
15980
16390
|
let response;
|
|
15981
16391
|
try {
|
|
15982
|
-
response = await fetch(
|
|
16392
|
+
response = await fetch(requestUrl, {
|
|
15983
16393
|
method: "POST",
|
|
15984
16394
|
redirect: "error",
|
|
15985
16395
|
credentials: "omit",
|
|
@@ -16070,258 +16480,501 @@ class RemoteSkillsAuthClient {
|
|
|
16070
16480
|
return requestAuthApi(this.apiOrigin, path, options);
|
|
16071
16481
|
}
|
|
16072
16482
|
}
|
|
16483
|
+
// src/lib/private-publication-recovery.ts
|
|
16484
|
+
import { constants as constants2, closeSync as closeSync3, fsyncSync, fstatSync as fstatSync3, lstatSync as lstatSync5, mkdirSync as mkdirSync14, openSync as openSync3, readSync as readSync2, realpathSync as realpathSync2, renameSync as renameSync4, unlinkSync, writeFileSync as writeFileSync13 } from "fs";
|
|
16485
|
+
import { dirname as dirname12, isAbsolute as isAbsolute5, join as join22, resolve as resolve4 } from "path";
|
|
16486
|
+
import { randomUUID } from "crypto";
|
|
16487
|
+
var fail2 = () => {
|
|
16488
|
+
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.");
|
|
16489
|
+
};
|
|
16490
|
+
function safeDirectory(directory) {
|
|
16491
|
+
if (!isAbsolute5(directory) || directory !== resolve4(directory) || realpathSync2(directory) !== directory)
|
|
16492
|
+
return fail2();
|
|
16493
|
+
for (let path = directory;; path = dirname12(path)) {
|
|
16494
|
+
const stat = lstatSync5(path);
|
|
16495
|
+
if (!stat.isDirectory() || stat.isSymbolicLink())
|
|
16496
|
+
return fail2();
|
|
16497
|
+
if (path === dirname12(path))
|
|
16498
|
+
break;
|
|
16499
|
+
}
|
|
16500
|
+
const own = lstatSync5(directory);
|
|
16501
|
+
if ((own.mode & 63) !== 0 || process.getuid && own.uid !== process.getuid())
|
|
16502
|
+
return fail2();
|
|
16503
|
+
return { dev: own.dev, ino: own.ino };
|
|
16504
|
+
}
|
|
16505
|
+
function unchangedDirectory(directory, identity) {
|
|
16506
|
+
const now = safeDirectory(directory);
|
|
16507
|
+
if (now.dev !== identity.dev || now.ino !== identity.ino)
|
|
16508
|
+
return fail2();
|
|
16509
|
+
}
|
|
16510
|
+
function readOwned(directory, name, max) {
|
|
16511
|
+
const identity = safeDirectory(directory), file = join22(directory, name);
|
|
16512
|
+
const fd = openSync3(file, constants2.O_RDONLY | constants2.O_NOFOLLOW);
|
|
16513
|
+
try {
|
|
16514
|
+
const stat = fstatSync3(fd);
|
|
16515
|
+
if (!stat.isFile() || stat.nlink !== 1 || stat.size > max || stat.size < 1 || (stat.mode & 63) !== 0 || process.getuid && stat.uid !== process.getuid())
|
|
16516
|
+
return fail2();
|
|
16517
|
+
const buffer = Buffer.alloc(Math.min(max, stat.size) + 1);
|
|
16518
|
+
let length = 0;
|
|
16519
|
+
while (length < buffer.length) {
|
|
16520
|
+
const count = readSync2(fd, buffer, length, buffer.length - length, length);
|
|
16521
|
+
if (count === 0)
|
|
16522
|
+
break;
|
|
16523
|
+
length += count;
|
|
16524
|
+
}
|
|
16525
|
+
const bytes = buffer.subarray(0, length), after = fstatSync3(fd);
|
|
16526
|
+
unchangedDirectory(directory, identity);
|
|
16527
|
+
if (bytes.length !== stat.size || stat.size !== after.size || stat.mtimeMs !== after.mtimeMs || stat.ctimeMs !== after.ctimeMs)
|
|
16528
|
+
return fail2();
|
|
16529
|
+
return bytes;
|
|
16530
|
+
} finally {
|
|
16531
|
+
closeSync3(fd);
|
|
16532
|
+
}
|
|
16533
|
+
}
|
|
16534
|
+
function writeOwned(directory, name, bytes) {
|
|
16535
|
+
const fd = openSync3(join22(directory, name), constants2.O_WRONLY | constants2.O_CREAT | constants2.O_EXCL | constants2.O_NOFOLLOW, 384);
|
|
16536
|
+
try {
|
|
16537
|
+
writeFileSync13(fd, bytes);
|
|
16538
|
+
fsyncSync(fd);
|
|
16539
|
+
} finally {
|
|
16540
|
+
closeSync3(fd);
|
|
16541
|
+
}
|
|
16542
|
+
}
|
|
16543
|
+
function save(directory, value) {
|
|
16544
|
+
const identity = safeDirectory(directory), temporary = `.receipt-${randomUUID()}.json`;
|
|
16545
|
+
writeOwned(directory, temporary, JSON.stringify(value) + `
|
|
16546
|
+
`);
|
|
16547
|
+
unchangedDirectory(directory, identity);
|
|
16548
|
+
renameSync4(join22(directory, temporary), join22(directory, "receipt.json"));
|
|
16549
|
+
const fd = openSync3(directory, constants2.O_RDONLY | constants2.O_NOFOLLOW);
|
|
16550
|
+
try {
|
|
16551
|
+
fsyncSync(fd);
|
|
16552
|
+
} finally {
|
|
16553
|
+
closeSync3(fd);
|
|
16554
|
+
}
|
|
16555
|
+
}
|
|
16556
|
+
function bind(client, receipt) {
|
|
16557
|
+
if (["apiOrigin", "organizationId", "userId", "membershipId"].some((k) => client[k] !== receipt[k]))
|
|
16558
|
+
throw new PrivatePublicationError("PUBLICATION_IDENTITY_CHANGED", "The fresh session does not match the recovery directory's server, account and membership.");
|
|
16559
|
+
}
|
|
16560
|
+
async function locked(directory, action) {
|
|
16561
|
+
const identity = safeDirectory(directory), file = join22(directory, "operation.lock");
|
|
16562
|
+
let fd;
|
|
16563
|
+
try {
|
|
16564
|
+
fd = openSync3(file, constants2.O_WRONLY | constants2.O_CREAT | constants2.O_EXCL | constants2.O_NOFOLLOW, 384);
|
|
16565
|
+
} catch {
|
|
16566
|
+
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.");
|
|
16567
|
+
}
|
|
16568
|
+
const lock = fstatSync3(fd);
|
|
16569
|
+
try {
|
|
16570
|
+
writeFileSync13(fd, JSON.stringify({ pid: process.pid }) + `
|
|
16571
|
+
`);
|
|
16572
|
+
fsyncSync(fd);
|
|
16573
|
+
return await action();
|
|
16574
|
+
} finally {
|
|
16575
|
+
closeSync3(fd);
|
|
16576
|
+
unchangedDirectory(directory, identity);
|
|
16577
|
+
const now = lstatSync5(file);
|
|
16578
|
+
if (now.dev !== lock.dev || now.ino !== lock.ino || !now.isFile() || now.isSymbolicLink())
|
|
16579
|
+
fail2();
|
|
16580
|
+
unlinkSync(file);
|
|
16581
|
+
}
|
|
16582
|
+
}
|
|
16583
|
+
function readPrivatePublicationRecovery(directory) {
|
|
16584
|
+
try {
|
|
16585
|
+
const value = JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(readOwned(directory, "receipt.json", 65536)));
|
|
16586
|
+
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))
|
|
16587
|
+
return fail2();
|
|
16588
|
+
value.declaration = checkedPublicationDeclaration(value.declaration);
|
|
16589
|
+
if (value.intent !== null)
|
|
16590
|
+
value.intent = checkedPublicationView(value.intent, value.skillId, undefined, value.declaration);
|
|
16591
|
+
if (value.intent === null && !["prepared", "begin_uncertain"].includes(value.phase))
|
|
16592
|
+
return fail2();
|
|
16593
|
+
const bytes = readOwned(directory, "bundle.tgz", PRIVATE_PUBLICATION_MAX_BYTES);
|
|
16594
|
+
if (bytes.length !== value.declaration.archiveByteSize || publicationSha256(bytes) !== value.declaration.archiveSha256)
|
|
16595
|
+
return fail2();
|
|
16596
|
+
return { receipt: value, bytes };
|
|
16597
|
+
} catch {
|
|
16598
|
+
return fail2();
|
|
16599
|
+
}
|
|
16600
|
+
}
|
|
16601
|
+
async function preparePrivatePublication(client, sourceDirectory, recoveryDirectory, input) {
|
|
16602
|
+
if (!publicationUuid(input.skillId) || !(input.expectedCurrentVersionId === null || publicationUuid(input.expectedCurrentVersionId)) || input.idempotencyKey !== undefined && !publicationUuid(input.idempotencyKey))
|
|
16603
|
+
return fail2();
|
|
16604
|
+
const packed = packSkillBundle(sourceDirectory, { maxUnpackedBytes: 32 * 1024 * 1024 });
|
|
16605
|
+
const inspected = await inspectSkillBundle(packed.bytes, { limits: { compressedBytes: PRIVATE_PUBLICATION_MAX_BYTES } });
|
|
16606
|
+
const manifest = inspected.entries.find((entry) => entry.path === "skill.json");
|
|
16607
|
+
if (!manifest || manifest.bytes.length > 16384 || !(await verifyContentHashFromEntries(inspected.entries)).valid)
|
|
16608
|
+
throw new PrivatePublicationError("PUBLICATION_BUNDLE_INVALID", "The skill must have a valid skill.json with its current content hash. Validate the skill before publishing.");
|
|
16609
|
+
const manifestText = new TextDecoder("utf-8", { fatal: true }).decode(manifest.bytes);
|
|
16610
|
+
const declaration = checkedPublicationDeclaration({
|
|
16611
|
+
idempotencyKey: input.idempotencyKey ?? randomUUID(),
|
|
16612
|
+
version: JSON.parse(manifestText).version,
|
|
16613
|
+
expectedCurrentVersionId: input.expectedCurrentVersionId,
|
|
16614
|
+
manifestText,
|
|
16615
|
+
archiveSha256: inspected.sha256,
|
|
16616
|
+
archiveByteSize: packed.bytes.length
|
|
16617
|
+
});
|
|
16618
|
+
const receipt = {
|
|
16619
|
+
contractVersion: 1,
|
|
16620
|
+
apiOrigin: client.apiOrigin,
|
|
16621
|
+
organizationId: client.organizationId,
|
|
16622
|
+
userId: client.userId,
|
|
16623
|
+
membershipId: client.membershipId,
|
|
16624
|
+
skillId: input.skillId,
|
|
16625
|
+
declaration,
|
|
16626
|
+
phase: "prepared",
|
|
16627
|
+
intent: null
|
|
16628
|
+
};
|
|
16629
|
+
if (!isAbsolute5(recoveryDirectory) || resolve4(recoveryDirectory) !== recoveryDirectory || realpathSync2(dirname12(recoveryDirectory)) !== dirname12(recoveryDirectory))
|
|
16630
|
+
return fail2();
|
|
16631
|
+
mkdirSync14(recoveryDirectory, { mode: 448 });
|
|
16632
|
+
safeDirectory(recoveryDirectory);
|
|
16633
|
+
const parent = openSync3(dirname12(recoveryDirectory), constants2.O_RDONLY | constants2.O_NOFOLLOW);
|
|
16634
|
+
try {
|
|
16635
|
+
fsyncSync(parent);
|
|
16636
|
+
} finally {
|
|
16637
|
+
closeSync3(parent);
|
|
16638
|
+
}
|
|
16639
|
+
writeOwned(recoveryDirectory, "bundle.tgz", packed.bytes);
|
|
16640
|
+
save(recoveryDirectory, receipt);
|
|
16641
|
+
return receipt;
|
|
16642
|
+
}
|
|
16643
|
+
function privatePublicationResult(directory, receipt) {
|
|
16644
|
+
const state = receipt.intent?.state ?? receipt.phase, committed = state === "committed";
|
|
16645
|
+
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.";
|
|
16646
|
+
return {
|
|
16647
|
+
recoveryDirectory: directory,
|
|
16648
|
+
skillId: receipt.skillId,
|
|
16649
|
+
intentId: receipt.intent?.id ?? null,
|
|
16650
|
+
state,
|
|
16651
|
+
versionId: receipt.intent?.versionId ?? null,
|
|
16652
|
+
committed,
|
|
16653
|
+
executionEnabled: false,
|
|
16654
|
+
nextAction
|
|
16655
|
+
};
|
|
16656
|
+
}
|
|
16657
|
+
async function continuePrivatePublication(client, directory, options) {
|
|
16658
|
+
if (options.confirm !== true)
|
|
16659
|
+
throw new PrivatePublicationError("PUBLICATION_CONFIRM_REQUIRED", "Explicit upload confirmation is required.");
|
|
16660
|
+
if (options.waitMs !== undefined && (!Number.isSafeInteger(options.waitMs) || options.waitMs < 0 || options.waitMs > 300000))
|
|
16661
|
+
return fail2();
|
|
16662
|
+
return locked(directory, () => continueLocked(client, directory, options));
|
|
16663
|
+
}
|
|
16664
|
+
async function continueLocked(client, directory, options) {
|
|
16665
|
+
const { receipt, bytes } = readPrivatePublicationRecovery(directory);
|
|
16666
|
+
bind(client, receipt);
|
|
16667
|
+
if (!receipt.intent) {
|
|
16668
|
+
receipt.phase = "begin_uncertain";
|
|
16669
|
+
save(directory, receipt);
|
|
16670
|
+
receipt.intent = await client.begin(receipt.skillId, receipt.declaration);
|
|
16671
|
+
receipt.phase = "awaiting_upload";
|
|
16672
|
+
save(directory, receipt);
|
|
16673
|
+
} else {
|
|
16674
|
+
receipt.intent = checkedPublicationView(await client.get(receipt.skillId, receipt.intent.id), receipt.skillId, receipt.intent.id, receipt.declaration);
|
|
16675
|
+
save(directory, receipt);
|
|
16676
|
+
}
|
|
16677
|
+
if (receipt.intent.state === "awaiting_upload") {
|
|
16678
|
+
if (receipt.phase === "awaiting_upload") {
|
|
16679
|
+
receipt.phase = "upload_uncertain";
|
|
16680
|
+
save(directory, receipt);
|
|
16681
|
+
try {
|
|
16682
|
+
await client.upload(receipt.skillId, receipt.intent, bytes);
|
|
16683
|
+
} catch (error) {
|
|
16684
|
+
if (error instanceof PrivatePublicationError && !error.uncertain) {
|
|
16685
|
+
receipt.phase = "awaiting_upload";
|
|
16686
|
+
save(directory, receipt);
|
|
16687
|
+
}
|
|
16688
|
+
throw error;
|
|
16689
|
+
}
|
|
16690
|
+
receipt.phase = "uploaded";
|
|
16691
|
+
save(directory, receipt);
|
|
16692
|
+
}
|
|
16693
|
+
receipt.phase = "finalize_uncertain";
|
|
16694
|
+
save(directory, receipt);
|
|
16695
|
+
receipt.intent = checkedPublicationView(await client.finalize(receipt.skillId, receipt.intent.id), receipt.skillId, receipt.intent.id, receipt.declaration);
|
|
16696
|
+
receipt.phase = "observed";
|
|
16697
|
+
save(directory, receipt);
|
|
16698
|
+
}
|
|
16699
|
+
if (options.waitMs !== undefined && options.waitMs > 0 && ["queued", "verifying"].includes(receipt.intent.state)) {
|
|
16700
|
+
receipt.intent = checkedPublicationView(await client.wait(receipt.skillId, receipt.intent.id, { timeoutMs: options.waitMs }), receipt.skillId, receipt.intent.id, receipt.declaration);
|
|
16701
|
+
receipt.phase = "observed";
|
|
16702
|
+
save(directory, receipt);
|
|
16703
|
+
}
|
|
16704
|
+
return privatePublicationResult(directory, receipt);
|
|
16705
|
+
}
|
|
16706
|
+
async function inspectPrivatePublication(client, directory, cancel = false) {
|
|
16707
|
+
return locked(directory, () => inspectLocked(client, directory, cancel));
|
|
16708
|
+
}
|
|
16709
|
+
async function inspectLocked(client, directory, cancel) {
|
|
16710
|
+
const { receipt } = readPrivatePublicationRecovery(directory);
|
|
16711
|
+
bind(client, receipt);
|
|
16712
|
+
if (receipt.intent) {
|
|
16713
|
+
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);
|
|
16714
|
+
save(directory, receipt);
|
|
16715
|
+
} else if (cancel)
|
|
16716
|
+
throw new PrivatePublicationError("PUBLICATION_INTENT_UNKNOWN", "Reconcile the saved begin request with publication resume before cancelling its intent.");
|
|
16717
|
+
return privatePublicationResult(directory, receipt);
|
|
16718
|
+
}
|
|
16073
16719
|
export {
|
|
16074
|
-
|
|
16075
|
-
ARTICLE_GENERATION_SLUG,
|
|
16076
|
-
BASIC_SKILL_NAMES,
|
|
16077
|
-
CATEGORIES,
|
|
16078
|
-
CONTENT_HASH_LIMITS,
|
|
16079
|
-
ContentHashInputError,
|
|
16080
|
-
DEFAULT_EXPORT_DIR,
|
|
16081
|
-
HostedApiError,
|
|
16082
|
-
InvitationEmailInputError,
|
|
16083
|
-
MCP_CONTRACT_SCHEMA_VERSION,
|
|
16084
|
-
MissingSkillsFleetError,
|
|
16085
|
-
PORTABLE_SKILL_DEFAULT_VERSION,
|
|
16086
|
-
PORTABLE_SKILL_SCHEMA,
|
|
16087
|
-
PORTABLE_SKILL_STANDARD,
|
|
16088
|
-
PROJECT_CONFIG_FILE,
|
|
16089
|
-
PullSkillError,
|
|
16090
|
-
REFUSED_SCANNER_FLAGGED,
|
|
16091
|
-
REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
16092
|
-
RemoteCapabilityUnavailableError,
|
|
16093
|
-
RemoteCreditApprovalError,
|
|
16094
|
-
RemoteInvitationEmailError,
|
|
16095
|
-
RemoteInvitationEmailUnconfirmedError,
|
|
16096
|
-
RemoteQuoteUnavailableError,
|
|
16097
|
-
RemoteRequestError,
|
|
16098
|
-
RemoteRouteUnsupportedError,
|
|
16099
|
-
RemoteSkillsAuthClient,
|
|
16100
|
-
RemoteSkillsClient,
|
|
16101
|
-
RemoteWorkspaceInvitationError,
|
|
16102
|
-
RemoteWorkspaceInvitationReadError,
|
|
16103
|
-
RemoteWorkspaceInvitationUnconfirmedError,
|
|
16104
|
-
RemoteWorkspaceLeaveError,
|
|
16105
|
-
RemoteWorkspaceLeaveUnconfirmedError,
|
|
16106
|
-
RemoteWorkspaceMemberError,
|
|
16107
|
-
RemoteWorkspaceSelectionError,
|
|
16108
|
-
SKILLS,
|
|
16109
|
-
SKILLS_API_KEY_ENV,
|
|
16110
|
-
SKILLS_API_KEY_ENV_KEYS,
|
|
16111
|
-
SKILLS_API_URL_ENV,
|
|
16112
|
-
SKILLS_API_URL_ENV_KEYS,
|
|
16113
|
-
SKILLS_APP,
|
|
16114
|
-
SKILLS_CLI_MCP_PARITY,
|
|
16115
|
-
SKILLS_LOCAL_OPT_IN_ENV_KEYS,
|
|
16116
|
-
SKILLS_NATIVE_STORAGE_ENV,
|
|
16117
|
-
SKILLS_NATIVE_STORAGE_FALLBACK_ENV,
|
|
16118
|
-
SKILLS_PROJECT_DIR,
|
|
16119
|
-
SKILLS_STORAGE_ENV,
|
|
16120
|
-
SKILLS_STORAGE_FALLBACK_ENV,
|
|
16121
|
-
SKILLS_STORAGE_TABLES,
|
|
16122
|
-
SKILL_ALIASES,
|
|
16123
|
-
SKILL_RUNTIMES,
|
|
16124
|
-
SKILL_SANDBOX_MODES,
|
|
16125
|
-
SKILL_SYSTEM_DEPS_ALLOWLIST,
|
|
16126
|
-
STATION_HYDRATION_MANIFEST_SCHEMA,
|
|
16127
|
-
STATION_SYNC_MANIFEST_SCHEMA,
|
|
16128
|
-
STORAGE_TABLES,
|
|
16129
|
-
SYNC_AGENTS,
|
|
16130
|
-
SYNC_HOMES,
|
|
16131
|
-
SYNC_MARKER_FILE,
|
|
16132
|
-
SYNC_MARKER_MANAGED_BY,
|
|
16133
|
-
SkillsFleetCredentialError,
|
|
16134
|
-
SkillsPostgresSyncStore,
|
|
16135
|
-
SkillsS3ObjectStore,
|
|
16136
|
-
StationSnapshotError,
|
|
16137
|
-
TOOL_PRIMITIVES,
|
|
16138
|
-
TOOL_PRIMITIVE_SCHEMA_VERSION,
|
|
16139
|
-
WorkspaceContextInputError,
|
|
16140
|
-
WorkspaceIdentityMismatchError,
|
|
16141
|
-
WorkspaceInvitationInputError,
|
|
16142
|
-
WorkspaceLeaveInputError,
|
|
16143
|
-
adaptSkillMdForAgent,
|
|
16144
|
-
addSchedule,
|
|
16145
|
-
agentGlobalSkillsDir,
|
|
16146
|
-
appendRunEvent,
|
|
16147
|
-
buildSkillsApiUrl,
|
|
16148
|
-
buildSkillsS3ObjectUrl,
|
|
16149
|
-
canonicalizeManifest,
|
|
16150
|
-
clearRegistryCache,
|
|
16151
|
-
completeSkillRun,
|
|
16152
|
-
computeContentHash,
|
|
16153
|
-
computeContentHashFromEntries,
|
|
16154
|
-
configuredSkillsApiUrl,
|
|
16155
|
-
createLocalSkillManifest,
|
|
16156
|
-
createMcpContractManifest,
|
|
16157
|
-
createRegistrySyncArtifact,
|
|
16158
|
-
createRemoteSkillsClient,
|
|
16159
|
-
createSkillMcpMetadata,
|
|
16160
|
-
createSkillRun,
|
|
16161
|
-
createSkillToolDependencies,
|
|
16162
|
-
createSkillsPostgresSyncStore,
|
|
16163
|
-
createSkillsS3ObjectStore,
|
|
16164
|
-
createSkillsSnapshotSyncRecord,
|
|
16165
|
-
describeMcpToolContracts,
|
|
16166
|
-
destinationFor,
|
|
16167
|
-
disableSkill,
|
|
16168
|
-
enableSkill,
|
|
16169
|
-
ensureProjectConfig,
|
|
16170
|
-
exportSkillsLocalSnapshot,
|
|
16171
|
-
findPortableSkill,
|
|
16172
|
-
findSimilarSkills,
|
|
16173
|
-
findSkillRun,
|
|
16174
|
-
findSkillsParityForCliCommand,
|
|
16175
|
-
findSkillsParityForMcpTool,
|
|
16176
|
-
generateEnvExample,
|
|
16177
|
-
generateSkillMd,
|
|
16178
|
-
getAgentSkillPath,
|
|
16179
|
-
getAgentSkillsDir,
|
|
16180
|
-
getAllTags,
|
|
16181
|
-
getCompactSkillDiscovery,
|
|
16182
|
-
getConfigPath,
|
|
16183
|
-
getConfiguredApiUrl,
|
|
16184
|
-
getDisabledProjectSkills,
|
|
16185
|
-
getDisabledSkills,
|
|
16186
|
-
getDueSchedules,
|
|
16187
|
-
getFeedbackDbPath,
|
|
16188
|
-
getInstallMeta,
|
|
16189
|
-
getInstalledSkills,
|
|
16190
|
-
getMcpResourceContracts,
|
|
16191
|
-
getMcpToolDescriptions,
|
|
16192
|
-
getNextRun,
|
|
16193
|
-
getPinnedSkills,
|
|
16194
|
-
getPortableSkillPath,
|
|
16195
|
-
getPortableSkillsRoot,
|
|
16196
|
-
getProjectConfigPath,
|
|
16197
|
-
getProjectStateDir,
|
|
16198
|
-
getPublicSkillDiscovery,
|
|
16199
|
-
getRunExportDir,
|
|
16200
|
-
getSkill,
|
|
16201
|
-
getSkillBestDoc,
|
|
16202
|
-
getSkillDocs,
|
|
16203
|
-
getSkillPath,
|
|
16204
|
-
getSkillRequirements,
|
|
16205
|
-
getSkillToolDependencies,
|
|
16206
|
-
getSkillsByCategory,
|
|
16207
|
-
getSkillsByTag,
|
|
16208
|
-
getSkillsNativeStorageStatus,
|
|
16209
|
-
getSkillsStorageDatabaseEnv,
|
|
16210
|
-
getSkillsStorageDatabaseUrl,
|
|
16211
|
-
getSkillsStorageStatus,
|
|
16212
|
-
getStorageDatabaseEnv,
|
|
16213
|
-
getStorageDatabaseUrl,
|
|
16214
|
-
getStorageStatus,
|
|
16215
|
-
getToolPrimitive,
|
|
16216
|
-
homePathFor,
|
|
16217
|
-
importSkillsLocalSnapshot,
|
|
16218
|
-
installSkill,
|
|
16219
|
-
installSkillForAgent,
|
|
16220
|
-
installSkillManifest,
|
|
16221
|
-
installSkillSource,
|
|
16222
|
-
installSkills,
|
|
16223
|
-
isBasicSkillName,
|
|
16224
|
-
isExcludedSkillFileName,
|
|
16225
|
-
isGatewayBackedSkill,
|
|
16226
|
-
isPortableWithinSkill,
|
|
16227
|
-
isRegularFile,
|
|
16228
|
-
isSkillsLocalOptIn,
|
|
16229
|
-
isSyncAgent,
|
|
16230
|
-
listMcpToolContracts,
|
|
16231
|
-
listPinnedSkills,
|
|
16232
|
-
listPortableSkillMetas,
|
|
16233
|
-
listPortableSkills,
|
|
16234
|
-
listSchedules,
|
|
16235
|
-
listSkillRuns,
|
|
16236
|
-
listToolPrimitives,
|
|
16237
|
-
loadBasicRegistry,
|
|
16238
|
-
loadConfig,
|
|
16239
|
-
loadProjectConfig,
|
|
16240
|
-
loadRegistry,
|
|
16241
|
-
loadRegistryProfile,
|
|
16242
|
-
loadRemoteRegistry,
|
|
16243
|
-
loadRemoteSkill,
|
|
16244
|
-
normalizeLineEndings,
|
|
16245
|
-
normalizePortableSkillName,
|
|
16246
|
-
normalizeRemoteSkillRunContract,
|
|
16247
|
-
normalizeSkillSlug,
|
|
16248
|
-
normalizeSkillsApiOrigin,
|
|
16249
|
-
noticeLocalSkillsMode,
|
|
16250
|
-
parseRemoteRegistryPayload,
|
|
16251
|
-
parseRemoteSkillPayload,
|
|
16252
|
-
parseSkillFrontmatter,
|
|
16253
|
-
pinProjectSkill,
|
|
16254
|
-
pinSkill,
|
|
16255
|
-
planSkillsS3SnapshotUpload,
|
|
16256
|
-
planStationHydration,
|
|
16257
|
-
planStationSnapshot,
|
|
16258
|
-
pointerSkillMd,
|
|
16259
|
-
portPortableSkill,
|
|
16260
|
-
portPortableSkillDirectory,
|
|
16261
|
-
publicDiscoveryDependencies,
|
|
16262
|
-
publicDiscoveryDocumentation,
|
|
16263
|
-
publicDiscoveryEnvVars,
|
|
16264
|
-
pullSkills,
|
|
16265
|
-
readPortableSkillManifest,
|
|
16266
|
-
recordScheduleRun,
|
|
16267
|
-
removeManagedAgentSkill,
|
|
16268
|
-
removeSchedule,
|
|
16269
|
-
removeSkill,
|
|
16270
|
-
removeSkillForAgent,
|
|
16271
|
-
requireSkillsApiKey,
|
|
16272
|
-
requireSkillsApiOrigin,
|
|
16273
|
-
requireSkillsFleet,
|
|
16274
|
-
resolveSkillAlias,
|
|
16275
|
-
resolveSkillsApiKey,
|
|
16276
|
-
resolveSkillsApiOrigin,
|
|
16277
|
-
resolveSkillsFleet,
|
|
16278
|
-
resolveSkillsNativeStorageConfig,
|
|
16279
|
-
resolveStorageConfig,
|
|
16280
|
-
resolveSyncAgents,
|
|
16281
|
-
revisionIdOf,
|
|
16282
|
-
runPortableSkill,
|
|
16283
|
-
runSkill,
|
|
16284
|
-
sanitizePublicDiscoveryText,
|
|
16285
|
-
saveConfig,
|
|
16286
|
-
saveFeedback,
|
|
16287
|
-
saveProjectConfig,
|
|
16288
|
-
scaffoldPortableSkill,
|
|
16289
|
-
searchSkills,
|
|
16290
|
-
selectsSkillsLocalMode,
|
|
16291
|
-
setScheduleEnabled,
|
|
16292
|
-
setSkillDisabled,
|
|
16293
|
-
sha256File,
|
|
16294
|
-
signSkillsAwsV4Request,
|
|
16295
|
-
skillExists,
|
|
16296
|
-
skillsCredentialFilePath,
|
|
16297
|
-
skillsCredentialFiles,
|
|
16298
|
-
skillsCredentialOrReason,
|
|
16299
|
-
skillsPostgresSyncSchemaSql,
|
|
16300
|
-
storageCapabilities,
|
|
16301
|
-
summarizeMcpToolContract,
|
|
16302
|
-
syncSkillsToAgents,
|
|
16303
|
-
unpinProjectSkill,
|
|
16304
|
-
unpinSkill,
|
|
16305
|
-
unsetConfig,
|
|
16306
|
-
updateSkillRun,
|
|
16307
|
-
uploadSkillsSnapshotFilesToS3,
|
|
16308
|
-
validateBlogArticleRunOptions,
|
|
16309
|
-
validateCron,
|
|
16310
|
-
validatePortableManifestContract,
|
|
16311
|
-
validatePortableSkillDirectory,
|
|
16312
|
-
validateRegistryConsistency,
|
|
16313
|
-
validateSkillDirectory,
|
|
16314
|
-
validateSkillsCliMcpParity,
|
|
16315
|
-
validateStationId,
|
|
16316
|
-
validateToolPrimitiveCoverage,
|
|
16317
|
-
verifyContentHash,
|
|
16318
|
-
verifyContentHashFromEntries,
|
|
16319
|
-
walkEntries,
|
|
16320
|
-
writeCorpusSkill,
|
|
16321
|
-
writeManagedAgentSkill,
|
|
16322
|
-
writeManagedSkillDir,
|
|
16323
|
-
writeRegistrySyncArtifact,
|
|
16324
|
-
writeRunLogs,
|
|
16720
|
+
writeStationSnapshot,
|
|
16325
16721
|
writeStationHydration,
|
|
16326
|
-
|
|
16722
|
+
writeRunLogs,
|
|
16723
|
+
writeRegistrySyncArtifact,
|
|
16724
|
+
writeManagedSkillDir,
|
|
16725
|
+
writeManagedAgentSkill,
|
|
16726
|
+
writeCorpusSkill,
|
|
16727
|
+
walkEntries,
|
|
16728
|
+
verifyContentHashFromEntries,
|
|
16729
|
+
verifyContentHash,
|
|
16730
|
+
validateToolPrimitiveCoverage,
|
|
16731
|
+
validateStationId,
|
|
16732
|
+
validateSkillsCliMcpParity,
|
|
16733
|
+
validateSkillDirectory,
|
|
16734
|
+
validateRegistryConsistency,
|
|
16735
|
+
validatePortableSkillDirectory,
|
|
16736
|
+
validatePortableManifestContract,
|
|
16737
|
+
validateCron,
|
|
16738
|
+
validateBlogArticleRunOptions,
|
|
16739
|
+
uploadSkillsSnapshotFilesToS3,
|
|
16740
|
+
updateSkillRun,
|
|
16741
|
+
unsetConfig,
|
|
16742
|
+
unpinSkill,
|
|
16743
|
+
unpinProjectSkill,
|
|
16744
|
+
syncSkillsToAgents,
|
|
16745
|
+
summarizeMcpToolContract,
|
|
16746
|
+
storageCapabilities,
|
|
16747
|
+
skillsPostgresSyncSchemaSql,
|
|
16748
|
+
skillsCredentialOrReason,
|
|
16749
|
+
skillsCredentialFiles,
|
|
16750
|
+
skillsCredentialFilePath,
|
|
16751
|
+
skillExists,
|
|
16752
|
+
signSkillsAwsV4Request,
|
|
16753
|
+
sha256File,
|
|
16754
|
+
setSkillDisabled,
|
|
16755
|
+
setScheduleEnabled,
|
|
16756
|
+
selectsSkillsLocalMode,
|
|
16757
|
+
searchSkills,
|
|
16758
|
+
scaffoldPortableSkill,
|
|
16759
|
+
saveProjectConfig,
|
|
16760
|
+
saveFeedback,
|
|
16761
|
+
saveConfig,
|
|
16762
|
+
sanitizePublicDiscoveryText,
|
|
16763
|
+
runSkill,
|
|
16764
|
+
runPortableSkill,
|
|
16765
|
+
revisionIdOf,
|
|
16766
|
+
resolveSyncAgents,
|
|
16767
|
+
resolveStorageConfig,
|
|
16768
|
+
resolveSkillsNativeStorageConfig,
|
|
16769
|
+
resolveSkillsFleet,
|
|
16770
|
+
resolveSkillsApiOrigin,
|
|
16771
|
+
resolveSkillsApiKey,
|
|
16772
|
+
resolveSkillAlias,
|
|
16773
|
+
requireSkillsFleet,
|
|
16774
|
+
requireSkillsApiOrigin,
|
|
16775
|
+
requireSkillsApiKey,
|
|
16776
|
+
removeSkillForAgent,
|
|
16777
|
+
removeSkill,
|
|
16778
|
+
removeSchedule,
|
|
16779
|
+
removeManagedAgentSkill,
|
|
16780
|
+
recordScheduleRun,
|
|
16781
|
+
readPrivatePublicationRecovery,
|
|
16782
|
+
readPortableSkillManifest,
|
|
16783
|
+
pullSkills,
|
|
16784
|
+
publicDiscoveryEnvVars,
|
|
16785
|
+
publicDiscoveryDocumentation,
|
|
16786
|
+
publicDiscoveryDependencies,
|
|
16787
|
+
preparePrivatePublication,
|
|
16788
|
+
portPortableSkillDirectory,
|
|
16789
|
+
portPortableSkill,
|
|
16790
|
+
pointerSkillMd,
|
|
16791
|
+
planStationSnapshot,
|
|
16792
|
+
planStationHydration,
|
|
16793
|
+
planSkillsS3SnapshotUpload,
|
|
16794
|
+
pinSkill,
|
|
16795
|
+
pinProjectSkill,
|
|
16796
|
+
parseSkillFrontmatter,
|
|
16797
|
+
parseRemoteSkillPayload,
|
|
16798
|
+
parseRemoteRegistryPayload,
|
|
16799
|
+
noticeLocalSkillsMode,
|
|
16800
|
+
normalizeSkillsApiOrigin,
|
|
16801
|
+
normalizeSkillSlug,
|
|
16802
|
+
normalizeRemoteSkillRunContract,
|
|
16803
|
+
normalizePortableSkillName,
|
|
16804
|
+
normalizeLineEndings,
|
|
16805
|
+
loadRemoteSkill,
|
|
16806
|
+
loadRemoteRegistry,
|
|
16807
|
+
loadRegistryProfile,
|
|
16808
|
+
loadRegistry,
|
|
16809
|
+
loadProjectConfig,
|
|
16810
|
+
loadConfig,
|
|
16811
|
+
loadBasicRegistry,
|
|
16812
|
+
listToolPrimitives,
|
|
16813
|
+
listSkillRuns,
|
|
16814
|
+
listSchedules,
|
|
16815
|
+
listPortableSkills,
|
|
16816
|
+
listPortableSkillMetas,
|
|
16817
|
+
listPinnedSkills,
|
|
16818
|
+
listMcpToolContracts,
|
|
16819
|
+
isSyncAgent,
|
|
16820
|
+
isSkillsLocalOptIn,
|
|
16821
|
+
isRegularFile,
|
|
16822
|
+
isPortableWithinSkill,
|
|
16823
|
+
isGatewayBackedSkill,
|
|
16824
|
+
isExcludedSkillFileName,
|
|
16825
|
+
isBasicSkillName,
|
|
16826
|
+
installSkills,
|
|
16827
|
+
installSkillSource,
|
|
16828
|
+
installSkillManifest,
|
|
16829
|
+
installSkillForAgent,
|
|
16830
|
+
installSkill,
|
|
16831
|
+
inspectPrivatePublication,
|
|
16832
|
+
importSkillsLocalSnapshot,
|
|
16833
|
+
homePathFor,
|
|
16834
|
+
getToolPrimitive,
|
|
16835
|
+
getStorageStatus,
|
|
16836
|
+
getStorageDatabaseUrl,
|
|
16837
|
+
getStorageDatabaseEnv,
|
|
16838
|
+
getSkillsStorageStatus,
|
|
16839
|
+
getSkillsStorageDatabaseUrl,
|
|
16840
|
+
getSkillsStorageDatabaseEnv,
|
|
16841
|
+
getSkillsNativeStorageStatus,
|
|
16842
|
+
getSkillsByTag,
|
|
16843
|
+
getSkillsByCategory,
|
|
16844
|
+
getSkillToolDependencies,
|
|
16845
|
+
getSkillRequirements,
|
|
16846
|
+
getSkillPath,
|
|
16847
|
+
getSkillDocs,
|
|
16848
|
+
getSkillBestDoc,
|
|
16849
|
+
getSkill,
|
|
16850
|
+
getRunExportDir,
|
|
16851
|
+
getPublicSkillDiscovery,
|
|
16852
|
+
getProjectStateDir,
|
|
16853
|
+
getProjectConfigPath,
|
|
16854
|
+
getPortableSkillsRoot,
|
|
16855
|
+
getPortableSkillPath,
|
|
16856
|
+
getPinnedSkills,
|
|
16857
|
+
getNextRun,
|
|
16858
|
+
getMcpToolDescriptions,
|
|
16859
|
+
getMcpResourceContracts,
|
|
16860
|
+
getInstalledSkills,
|
|
16861
|
+
getInstallMeta,
|
|
16862
|
+
getFeedbackDbPath,
|
|
16863
|
+
getDueSchedules,
|
|
16864
|
+
getDisabledSkills,
|
|
16865
|
+
getDisabledProjectSkills,
|
|
16866
|
+
getConfiguredApiUrl,
|
|
16867
|
+
getConfigPath,
|
|
16868
|
+
getCompactSkillDiscovery,
|
|
16869
|
+
getAllTags,
|
|
16870
|
+
getAgentSkillsDir,
|
|
16871
|
+
getAgentSkillPath,
|
|
16872
|
+
generateSkillMd,
|
|
16873
|
+
generateEnvExample,
|
|
16874
|
+
findSkillsParityForMcpTool,
|
|
16875
|
+
findSkillsParityForCliCommand,
|
|
16876
|
+
findSkillRun,
|
|
16877
|
+
findSimilarSkills,
|
|
16878
|
+
findPortableSkill,
|
|
16879
|
+
exportSkillsLocalSnapshot,
|
|
16880
|
+
ensureProjectConfig,
|
|
16881
|
+
enableSkill,
|
|
16882
|
+
disableSkill,
|
|
16883
|
+
destinationFor,
|
|
16884
|
+
describeMcpToolContracts,
|
|
16885
|
+
createSkillsSnapshotSyncRecord,
|
|
16886
|
+
createSkillsS3ObjectStore,
|
|
16887
|
+
createSkillsPostgresSyncStore,
|
|
16888
|
+
createSkillToolDependencies,
|
|
16889
|
+
createSkillRun,
|
|
16890
|
+
createSkillMcpMetadata,
|
|
16891
|
+
createRemoteSkillsClient,
|
|
16892
|
+
createRegistrySyncArtifact,
|
|
16893
|
+
createMcpContractManifest,
|
|
16894
|
+
createLocalSkillManifest,
|
|
16895
|
+
continuePrivatePublication,
|
|
16896
|
+
configuredSkillsApiUrl,
|
|
16897
|
+
computeContentHashFromEntries,
|
|
16898
|
+
computeContentHash,
|
|
16899
|
+
completeSkillRun,
|
|
16900
|
+
clearRegistryCache,
|
|
16901
|
+
canonicalizeManifest,
|
|
16902
|
+
buildSkillsS3ObjectUrl,
|
|
16903
|
+
buildSkillsApiUrl,
|
|
16904
|
+
appendRunEvent,
|
|
16905
|
+
agentGlobalSkillsDir,
|
|
16906
|
+
addSchedule,
|
|
16907
|
+
adaptSkillMdForAgent,
|
|
16908
|
+
WorkspaceLeaveInputError,
|
|
16909
|
+
WorkspaceInvitationInputError,
|
|
16910
|
+
WorkspaceIdentityMismatchError,
|
|
16911
|
+
WorkspaceContextInputError,
|
|
16912
|
+
TOOL_PRIMITIVE_SCHEMA_VERSION,
|
|
16913
|
+
TOOL_PRIMITIVES,
|
|
16914
|
+
StationSnapshotError,
|
|
16915
|
+
SkillsS3ObjectStore,
|
|
16916
|
+
SkillsPostgresSyncStore,
|
|
16917
|
+
SkillsFleetCredentialError,
|
|
16918
|
+
SYNC_MARKER_MANAGED_BY,
|
|
16919
|
+
SYNC_MARKER_FILE,
|
|
16920
|
+
SYNC_HOMES,
|
|
16921
|
+
SYNC_AGENTS,
|
|
16922
|
+
STORAGE_TABLES,
|
|
16923
|
+
STATION_SYNC_MANIFEST_SCHEMA,
|
|
16924
|
+
STATION_HYDRATION_MANIFEST_SCHEMA,
|
|
16925
|
+
SKILL_SYSTEM_DEPS_ALLOWLIST,
|
|
16926
|
+
SKILL_SANDBOX_MODES,
|
|
16927
|
+
SKILL_RUNTIMES,
|
|
16928
|
+
SKILL_ALIASES,
|
|
16929
|
+
SKILLS_STORAGE_TABLES,
|
|
16930
|
+
SKILLS_STORAGE_FALLBACK_ENV,
|
|
16931
|
+
SKILLS_STORAGE_ENV,
|
|
16932
|
+
SKILLS_PROJECT_DIR,
|
|
16933
|
+
SKILLS_NATIVE_STORAGE_FALLBACK_ENV,
|
|
16934
|
+
SKILLS_NATIVE_STORAGE_ENV,
|
|
16935
|
+
SKILLS_LOCAL_OPT_IN_ENV_KEYS,
|
|
16936
|
+
SKILLS_CLI_MCP_PARITY,
|
|
16937
|
+
SKILLS_APP,
|
|
16938
|
+
SKILLS_API_URL_ENV_KEYS,
|
|
16939
|
+
SKILLS_API_URL_ENV,
|
|
16940
|
+
SKILLS_API_KEY_ENV_KEYS,
|
|
16941
|
+
SKILLS_API_KEY_ENV,
|
|
16942
|
+
SKILLS,
|
|
16943
|
+
RemoteWorkspaceSelectionError,
|
|
16944
|
+
RemoteWorkspaceMemberError,
|
|
16945
|
+
RemoteWorkspaceLeaveUnconfirmedError,
|
|
16946
|
+
RemoteWorkspaceLeaveError,
|
|
16947
|
+
RemoteWorkspaceInvitationUnconfirmedError,
|
|
16948
|
+
RemoteWorkspaceInvitationReadError,
|
|
16949
|
+
RemoteWorkspaceInvitationError,
|
|
16950
|
+
RemoteSkillsClient,
|
|
16951
|
+
RemoteSkillsAuthClient,
|
|
16952
|
+
RemoteRouteUnsupportedError,
|
|
16953
|
+
RemoteRequestError,
|
|
16954
|
+
RemoteQuoteUnavailableError,
|
|
16955
|
+
RemotePrivatePublicationsClient,
|
|
16956
|
+
RemoteInvitationEmailUnconfirmedError,
|
|
16957
|
+
RemoteInvitationEmailError,
|
|
16958
|
+
RemoteCreditApprovalError,
|
|
16959
|
+
RemoteCapabilityUnavailableError,
|
|
16960
|
+
REMOTE_SKILL_RUN_CONTRACT_VERSION,
|
|
16961
|
+
REFUSED_SCANNER_FLAGGED,
|
|
16962
|
+
PullSkillError,
|
|
16963
|
+
PrivatePublicationError,
|
|
16964
|
+
PROJECT_CONFIG_FILE,
|
|
16965
|
+
PRIVATE_PUBLICATION_MAX_BYTES,
|
|
16966
|
+
PORTABLE_SKILL_STANDARD,
|
|
16967
|
+
PORTABLE_SKILL_SCHEMA,
|
|
16968
|
+
PORTABLE_SKILL_DEFAULT_VERSION,
|
|
16969
|
+
MissingSkillsFleetError,
|
|
16970
|
+
MCP_CONTRACT_SCHEMA_VERSION,
|
|
16971
|
+
InvitationEmailInputError,
|
|
16972
|
+
HostedApiError,
|
|
16973
|
+
DEFAULT_EXPORT_DIR,
|
|
16974
|
+
ContentHashInputError,
|
|
16975
|
+
CONTENT_HASH_LIMITS,
|
|
16976
|
+
CATEGORIES,
|
|
16977
|
+
BASIC_SKILL_NAMES,
|
|
16978
|
+
ARTICLE_GENERATION_SLUG,
|
|
16979
|
+
AGENT_TARGETS
|
|
16327
16980
|
};
|