apps 0.0.1-beta.32 → 0.0.1-beta.34
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/framework-reference.json +1 -1
- package/js/{chunk-W7F23NQ2.js → chunk-5OM6HBNU.js} +11 -9
- package/js/{chunk-N72RKJ5E.js → chunk-DSUKW6KJ.js} +1 -92
- package/js/{chunk-5DLG2FVN.js → chunk-DXGWKNTQ.js} +91 -0
- package/js/chunk-EPUWF4ZG.js +49 -0
- package/js/{chunk-4OKYLVU4.js → chunk-IU6OK5G2.js} +1 -1
- package/js/{chunk-GG566OOE.js → chunk-MYH3QZ4L.js} +6 -6
- package/js/{chunk-NPGRURDG.js → chunk-O3OAFU7Q.js} +20 -3
- package/js/{chunk-RULZPNGP.js → chunk-O4QOPXQT.js} +8 -47
- package/js/{chunk-WG5DFZFT.js → chunk-PUBNIORL.js} +2 -2
- package/js/{chunk-AYM2FUI5.js → chunk-Q7Q5JTRW.js} +1 -1
- package/js/{chunk-3FJYVAE4.js → chunk-QKVZGWGZ.js} +5 -5
- package/js/{chunk-5XJR4XGW.js → chunk-QUEPZ67T.js} +6 -5
- package/js/{chunk-FULRJSWU.js → chunk-QZD2RZ4S.js} +6 -5
- package/js/{chunk-BGALSHLT.js → chunk-UKMIHP2G.js} +9 -6
- package/js/client.js +1 -1
- package/js/contracts.js +9 -9
- package/js/effect.js +10 -9
- package/js/graphql.js +14 -14
- package/js/host.js +10 -9
- package/js/index.js +8 -8
- package/js/mcp/effect.js +12 -11
- package/js/mcp/stdio.js +12 -11
- package/js/mcp.js +15 -14
- package/js/openapi.js +11 -9
- package/js/skills.js +110 -42
- package/package.json +1 -1
- package/runtime.json +1 -1
- package/types/apps/src/contracts/cache.d.ts +14 -0
- package/types/apps/src/contracts/skills.d.ts +16 -4
- package/types/apps/src/implementation/catalog-cache.d.ts +14 -17
- package/types/apps/src/implementation/schema.d.ts +5 -0
- package/types/apps/src/implementation/skills.d.ts +13 -19
- package/types/apps/src/skills.d.ts +4 -3
package/js/skills.js
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
|
-
catalogCache
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
catalogCache,
|
|
3
|
+
catalogScope
|
|
4
|
+
} from "./chunk-UKMIHP2G.js";
|
|
5
|
+
import "./chunk-Q7Q5JTRW.js";
|
|
6
|
+
import {
|
|
7
|
+
failOnNetworkRefusal
|
|
8
|
+
} from "./chunk-EPUWF4ZG.js";
|
|
5
9
|
import {
|
|
6
10
|
folderSkillsEffect,
|
|
7
11
|
skillFromFiles
|
|
8
12
|
} from "./chunk-OX233L7N.js";
|
|
9
13
|
import {
|
|
14
|
+
accountProviderError,
|
|
10
15
|
httpProviderError
|
|
11
|
-
} from "./chunk-
|
|
12
|
-
import
|
|
16
|
+
} from "./chunk-IU6OK5G2.js";
|
|
17
|
+
import {
|
|
18
|
+
NetworkRefused,
|
|
19
|
+
ProviderError,
|
|
20
|
+
networkRefusalStatus
|
|
21
|
+
} from "./chunk-DXGWKNTQ.js";
|
|
13
22
|
import {
|
|
14
23
|
AppSkillMetadata,
|
|
15
24
|
AppSkillSource,
|
|
@@ -20,12 +29,13 @@ import {
|
|
|
20
29
|
SkillServiceName,
|
|
21
30
|
skillLoadLimits
|
|
22
31
|
} from "./chunk-HW3DPBZR.js";
|
|
32
|
+
import "./chunk-ETLILMHY.js";
|
|
23
33
|
import {
|
|
24
34
|
FetchHttpClient_exports
|
|
25
35
|
} from "./chunk-MFHUR5SB.js";
|
|
26
36
|
import {
|
|
27
37
|
wrap
|
|
28
|
-
} from "./chunk-
|
|
38
|
+
} from "./chunk-O3OAFU7Q.js";
|
|
29
39
|
import "./chunk-FBBXFFFJ.js";
|
|
30
40
|
import "./chunk-QYM4STZW.js";
|
|
31
41
|
import {
|
|
@@ -34,6 +44,7 @@ import {
|
|
|
34
44
|
} from "./chunk-CJY5X26R.js";
|
|
35
45
|
import {
|
|
36
46
|
Effect_exports,
|
|
47
|
+
Encoding_exports,
|
|
37
48
|
Ref_exports,
|
|
38
49
|
Schema_exports,
|
|
39
50
|
Stream_exports
|
|
@@ -600,6 +611,11 @@ var withService = (service) => (effect) => service === void 0 || !Schema_exports
|
|
|
600
611
|
}) : error
|
|
601
612
|
)
|
|
602
613
|
);
|
|
614
|
+
var refusedRequest = (refused) => new SkillLoadFailed({
|
|
615
|
+
reason: "source",
|
|
616
|
+
status: networkRefusalStatus,
|
|
617
|
+
message: refused.message.slice(0, 500)
|
|
618
|
+
});
|
|
603
619
|
var parse = (schema, input) => Schema_exports.decodeUnknownEffect(schema)(input).pipe(Effect_exports.mapError(() => failed("document")));
|
|
604
620
|
var resourcePath = (path) => {
|
|
605
621
|
if (!Schema_exports.is(SkillFilePath)(path)) return false;
|
|
@@ -615,23 +631,31 @@ var resourcePath = (path) => {
|
|
|
615
631
|
var pathUrl = (base, path) => new URL(path.split("/").map(encodeURIComponent).join("/"), base).href;
|
|
616
632
|
var reader = (transport) => Effect_exports.gen(function* () {
|
|
617
633
|
const budget = yield* Ref_exports.make(0);
|
|
618
|
-
const fetchBytes = (url,
|
|
634
|
+
const fetchBytes = (url, request = {}) => Effect_exports.gen(function* () {
|
|
619
635
|
const parsed = yield* Effect_exports.try({
|
|
620
636
|
try: () => new URL(url),
|
|
621
637
|
catch: () => failed("source")
|
|
622
638
|
});
|
|
623
639
|
if (!["https:", "http:"].includes(parsed.protocol) || parsed.username || parsed.password || parsed.hash)
|
|
624
640
|
return yield* failed("source");
|
|
641
|
+
const refused = request.refused ?? refusedRequest;
|
|
625
642
|
const client = HttpClient_exports.withScope(yield* HttpClient_exports.HttpClient);
|
|
626
643
|
const headers = {
|
|
627
644
|
"User-Agent": "executor-skills",
|
|
628
645
|
Accept: "application/json, text/plain",
|
|
629
|
-
"Cache-Control": "no-cache"
|
|
646
|
+
"Cache-Control": "no-cache",
|
|
647
|
+
...request.headers
|
|
630
648
|
};
|
|
631
|
-
const response = yield* (
|
|
632
|
-
headers
|
|
633
|
-
body: HttpBody_exports.uint8Array(
|
|
634
|
-
})).pipe(
|
|
649
|
+
const response = yield* (request.body === void 0 ? client.get(parsed, { headers }) : client.post(parsed, {
|
|
650
|
+
headers,
|
|
651
|
+
body: HttpBody_exports.uint8Array(request.body, request.headers?.["Content-Type"])
|
|
652
|
+
})).pipe(
|
|
653
|
+
// `ctx.fetch` rejects a request Executor's app network refused.
|
|
654
|
+
Effect_exports.mapError(
|
|
655
|
+
(error) => Schema_exports.is(NetworkRefused)(error.cause) ? refused(error.cause) : failed("request")
|
|
656
|
+
)
|
|
657
|
+
);
|
|
658
|
+
yield* failOnNetworkRefusal(response).pipe(Effect_exports.mapError(refused));
|
|
635
659
|
if (response.status < 200 || response.status >= 300)
|
|
636
660
|
return yield* rejected(response.status, response.headers);
|
|
637
661
|
const chunks = [];
|
|
@@ -661,7 +685,7 @@ var reader = (transport) => Effect_exports.gen(function* () {
|
|
|
661
685
|
Effect_exports.provideService(FetchHttpClient_exports.RequestInit, { redirect: "manual" }),
|
|
662
686
|
Effect_exports.provideService(FetchHttpClient_exports.Fetch, transport.fetch ?? globalThis.fetch)
|
|
663
687
|
);
|
|
664
|
-
const read = (url) => fetchBytes(url).pipe(
|
|
688
|
+
const read = (url, request = {}) => fetchBytes(url, request).pipe(
|
|
665
689
|
Effect_exports.flatMap(
|
|
666
690
|
(result) => Effect_exports.try({
|
|
667
691
|
try: () => new TextDecoder("utf-8", { fatal: true }).decode(result),
|
|
@@ -680,21 +704,40 @@ var git = (run) => Effect_exports.tryPromise({
|
|
|
680
704
|
try: async () => run(),
|
|
681
705
|
catch: (error) => error instanceof InflateLimitExceeded ? failed("limit") : unreadable()
|
|
682
706
|
});
|
|
683
|
-
var
|
|
707
|
+
var githubHosts = ["github.com", "raw.githubusercontent.com"];
|
|
708
|
+
var githubRequests = (remote, repo, token) => {
|
|
709
|
+
const refused = (host) => (refusal) => refusal.refusal.reason === "credential_host" ? new SkillLoadFailed({
|
|
710
|
+
reason: "source",
|
|
711
|
+
status: networkRefusalStatus,
|
|
712
|
+
message: `Executor did not send the GitHub token to ${host}. The account's provider must declare hosts ${githubHosts.join(" and ")}; reconnect an account connected with other hosts.`
|
|
713
|
+
}) : refusedRequest(refusal);
|
|
714
|
+
const upload = (body) => remote.fetchBytes(`https://${githubHosts[0]}/${repo}.git/git-upload-pack`, {
|
|
715
|
+
body,
|
|
716
|
+
headers: {
|
|
717
|
+
...gitRequestHeaders,
|
|
718
|
+
...token === void 0 ? {} : { Authorization: `Basic ${Encoding_exports.encodeBase64(`x-access-token:${token}`)}` }
|
|
719
|
+
},
|
|
720
|
+
refused: refused(githubHosts[0])
|
|
721
|
+
});
|
|
722
|
+
const file = (commit, path) => remote.read(pathUrl(`https://${githubHosts[1]}/${repo}/${commit}/`, path), {
|
|
723
|
+
...token === void 0 ? {} : { headers: { Authorization: `token ${token}` } },
|
|
724
|
+
refused: refused(githubHosts[1])
|
|
725
|
+
});
|
|
726
|
+
return { repo, authenticated: token !== void 0, upload, file };
|
|
727
|
+
};
|
|
728
|
+
var resolveCommit = (github, ref) => Effect_exports.gen(function* () {
|
|
729
|
+
const { repo } = github;
|
|
684
730
|
if (ref !== void 0 && /^[a-f0-9]{40}$/.test(ref)) return ref;
|
|
685
731
|
const names = refCandidates(ref);
|
|
686
|
-
const response = yield*
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
// GitHub asks for credentials when a repository is missing or private.
|
|
691
|
-
Effect_exports.mapError(
|
|
692
|
-
(error) => error.status === 401 || error.status === 404 ? new SkillLoadFailed({
|
|
732
|
+
const response = yield* github.upload(lsRefsRequest(names)).pipe(
|
|
733
|
+
Effect_exports.mapError((error) => {
|
|
734
|
+
const hidden = error.reason === "request" && (error.status === 404 || error.status === 401 && !github.authenticated);
|
|
735
|
+
return hidden ? new SkillLoadFailed({
|
|
693
736
|
reason: "source",
|
|
694
|
-
message: `GitHub has no public repository named ${repo}.`,
|
|
737
|
+
message: github.authenticated ? `GitHub has no repository named ${repo} that the account's token can read.` : `GitHub has no public repository named ${repo}. To read a private repository, pass a GitHub account and its token.`,
|
|
695
738
|
status: error.status
|
|
696
|
-
}) : error
|
|
697
|
-
)
|
|
739
|
+
}) : error;
|
|
740
|
+
})
|
|
698
741
|
);
|
|
699
742
|
const refs = yield* git(() => parseLsRefs(response));
|
|
700
743
|
const commit = names.map((name) => refs.get(name)).find((sha) => sha !== void 0);
|
|
@@ -705,10 +748,7 @@ var resolveCommit = (remote, repo, ref) => Effect_exports.gen(function* () {
|
|
|
705
748
|
});
|
|
706
749
|
return commit;
|
|
707
750
|
});
|
|
708
|
-
var listFiles = (
|
|
709
|
-
body: treeFetchRequest(commit),
|
|
710
|
-
headers: gitRequestHeaders
|
|
711
|
-
}).pipe(
|
|
751
|
+
var listFiles = (github, commit, path) => github.upload(treeFetchRequest(commit)).pipe(
|
|
712
752
|
Effect_exports.flatMap(
|
|
713
753
|
(response) => git(
|
|
714
754
|
() => parseTreeFetch(response, commit, path, { objectBytes: skillLoadLimits.fileBytes })
|
|
@@ -721,8 +761,8 @@ var SkillDirectories = Schema_exports.Array(
|
|
|
721
761
|
files: Schema_exports.Array(Schema_exports.Struct({ path: Schema_exports.String, mode: Schema_exports.String }))
|
|
722
762
|
})
|
|
723
763
|
);
|
|
724
|
-
var skillDirectories = (
|
|
725
|
-
const files = yield* listFiles(
|
|
764
|
+
var skillDirectories = (github, commit, path) => Effect_exports.gen(function* () {
|
|
765
|
+
const files = yield* listFiles(github, commit, path);
|
|
726
766
|
const documents = files.filter(
|
|
727
767
|
(file) => file.path === "SKILL.md" || file.path.endsWith("/SKILL.md")
|
|
728
768
|
);
|
|
@@ -734,15 +774,21 @@ var skillDirectories = (remote, repo, commit, path) => Effect_exports.gen(functi
|
|
|
734
774
|
return yield* failed("limit");
|
|
735
775
|
return directories;
|
|
736
776
|
});
|
|
737
|
-
var cachedSkillDirectories = (cache, transport,
|
|
777
|
+
var cachedSkillDirectories = (cache, transport, options, commit) => Effect_exports.tryPromise({
|
|
738
778
|
try: () => cache.get({
|
|
739
|
-
key: ["apps/githubSkills/directories", 1, repo, commit, path ?? null],
|
|
779
|
+
key: ["apps/githubSkills/directories", 1, options.repo, commit, options.path ?? null],
|
|
740
780
|
schema: wrap(SkillDirectories, false),
|
|
741
781
|
freshFor: "7 days",
|
|
742
782
|
load: (context) => Effect_exports.runPromise(
|
|
743
|
-
// Keep the author's fetch, as every other
|
|
783
|
+
// Keep the author's fetch and this read's token, as every other request in it does.
|
|
744
784
|
reader({ fetch: transport.fetch, signal: context.signal }).pipe(
|
|
745
|
-
Effect_exports.flatMap(
|
|
785
|
+
Effect_exports.flatMap(
|
|
786
|
+
(remote) => skillDirectories(
|
|
787
|
+
githubRequests(remote, options.repo, options.token),
|
|
788
|
+
commit,
|
|
789
|
+
options.path
|
|
790
|
+
)
|
|
791
|
+
)
|
|
746
792
|
),
|
|
747
793
|
{ signal: context.signal }
|
|
748
794
|
)
|
|
@@ -769,20 +815,42 @@ var cachedCatalog = (options, prefix, load) => options.cache === void 0 ? load(o
|
|
|
769
815
|
})
|
|
770
816
|
)
|
|
771
817
|
);
|
|
818
|
+
var GitHubToken = Schema_exports.String.check(Schema_exports.isPattern(/^[\x21-\x7e]+$/));
|
|
819
|
+
var scopeMessages = {
|
|
820
|
+
"missing-account": "A GitHub token needs its account. Pass account: ctx.accounts.<slot> with it.",
|
|
821
|
+
"unselected-account": "The GitHub account is not one of this app's selected accounts."
|
|
822
|
+
};
|
|
823
|
+
var githubCache = (options) => options.account !== void 0 && !Schema_exports.is(GitHubToken)(options.token) ? Effect_exports.fail(
|
|
824
|
+
new SkillLoadFailed({
|
|
825
|
+
reason: "source",
|
|
826
|
+
message: "The GitHub account was passed without a valid token."
|
|
827
|
+
})
|
|
828
|
+
) : catalogScope(
|
|
829
|
+
options,
|
|
830
|
+
options.token,
|
|
831
|
+
(problem) => new SkillLoadFailed({ reason: "source", message: scopeMessages[problem] })
|
|
832
|
+
);
|
|
833
|
+
var attributed = (account) => (error) => account !== void 0 && error.reason === "request" && (error.status === 401 || error.status === 403) ? accountProviderError(
|
|
834
|
+
new ProviderError({
|
|
835
|
+
reason: error.status === 401 ? "unauthorized" : "rejected",
|
|
836
|
+
status: error.status
|
|
837
|
+
}),
|
|
838
|
+
account.id
|
|
839
|
+
) : error;
|
|
772
840
|
var githubSkillsEffect = (options) => Effect_exports.gen(function* () {
|
|
773
841
|
if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(options.repo) || options.path !== void 0 && !resourcePath(options.path))
|
|
774
842
|
return yield* failed("source");
|
|
843
|
+
const cache = yield* githubCache(options);
|
|
775
844
|
return yield* cachedCatalog(
|
|
776
|
-
options,
|
|
845
|
+
cache === void 0 ? options : { ...options, cache },
|
|
777
846
|
["apps/githubSkills/catalog", 1, options.repo, options.ref ?? null, options.path ?? null],
|
|
778
|
-
(transport,
|
|
847
|
+
(transport, cache2) => githubCatalog(options, transport, cache2)
|
|
779
848
|
);
|
|
780
|
-
}).pipe(withService("GitHub"));
|
|
849
|
+
}).pipe(withService("GitHub"), Effect_exports.mapError(attributed(options.account)));
|
|
781
850
|
var githubCatalog = (options, transport, cache) => Effect_exports.gen(function* () {
|
|
782
|
-
const
|
|
783
|
-
const commit = yield* resolveCommit(
|
|
784
|
-
const resources = yield* cache === void 0 ? skillDirectories(
|
|
785
|
-
const base = `https://raw.githubusercontent.com/${options.repo}/${commit}/`;
|
|
851
|
+
const github = githubRequests(yield* reader(transport), options.repo, options.token);
|
|
852
|
+
const commit = yield* resolveCommit(github, options.ref);
|
|
853
|
+
const resources = yield* cache === void 0 ? skillDirectories(github, commit, options.path) : cachedSkillDirectories(cache, transport, options, commit);
|
|
786
854
|
const skills = yield* Effect_exports.forEach(
|
|
787
855
|
resources,
|
|
788
856
|
({ directory, files }) => Effect_exports.gen(function* () {
|
|
@@ -792,7 +860,7 @@ var githubCatalog = (options, transport, cache) => Effect_exports.gen(function*
|
|
|
792
860
|
const path = file.path.slice(directory.length);
|
|
793
861
|
if (!resourcePath(file.path) || !resourcePath(path) || file.mode === "120000")
|
|
794
862
|
return yield* failed("source");
|
|
795
|
-
return { path, content: yield*
|
|
863
|
+
return { path, content: yield* github.file(commit, file.path) };
|
|
796
864
|
}),
|
|
797
865
|
{ concurrency: skillLoadLimits.concurrency }
|
|
798
866
|
);
|