@agentxm/extension-resolution 0.28.14-preview.1789139351.5cd4595aa

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.
Files changed (47) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +56 -0
  3. package/dist/src/accepted-pack-dependency-resolver.d.ts +23 -0
  4. package/dist/src/accepted-pack-dependency-resolver.js +31 -0
  5. package/dist/src/accepted-pack-hydration.d.ts +33 -0
  6. package/dist/src/accepted-pack-hydration.js +93 -0
  7. package/dist/src/axm-skill-candidate.d.ts +16 -0
  8. package/dist/src/axm-skill-candidate.js +80 -0
  9. package/dist/src/axm-skill-compatibility.d.ts +87 -0
  10. package/dist/src/axm-skill-compatibility.js +248 -0
  11. package/dist/src/axm-skill-workspace-compatibility.d.ts +23 -0
  12. package/dist/src/axm-skill-workspace-compatibility.js +110 -0
  13. package/dist/src/configured-entry-resolution.d.ts +118 -0
  14. package/dist/src/configured-entry-resolution.js +735 -0
  15. package/dist/src/configured-entry.d.ts +38 -0
  16. package/dist/src/configured-entry.js +8 -0
  17. package/dist/src/errors.d.ts +113 -0
  18. package/dist/src/errors.js +71 -0
  19. package/dist/src/index.d.ts +34 -0
  20. package/dist/src/index.js +45 -0
  21. package/dist/src/live.d.ts +25 -0
  22. package/dist/src/live.js +47 -0
  23. package/dist/src/named-registry-resolution.d.ts +26 -0
  24. package/dist/src/named-registry-resolution.js +110 -0
  25. package/dist/src/pack-dependency-resolution.d.ts +73 -0
  26. package/dist/src/pack-dependency-resolution.js +422 -0
  27. package/dist/src/publisher-binding.d.ts +66 -0
  28. package/dist/src/publisher-binding.js +75 -0
  29. package/dist/src/release-age-policy.d.ts +55 -0
  30. package/dist/src/release-age-policy.js +115 -0
  31. package/dist/src/release-age-posture.d.ts +23 -0
  32. package/dist/src/release-age-posture.js +15 -0
  33. package/dist/src/resolution-timeout.d.ts +11 -0
  34. package/dist/src/resolution-timeout.js +17 -0
  35. package/dist/src/resolved-pack-dependency.d.ts +32 -0
  36. package/dist/src/resolved-pack-dependency.js +28 -0
  37. package/dist/src/source-authority.d.ts +60 -0
  38. package/dist/src/source-authority.js +70 -0
  39. package/dist/src/testing.d.ts +40 -0
  40. package/dist/src/testing.js +40 -0
  41. package/dist/src/update/constraint-precedence.d.ts +75 -0
  42. package/dist/src/update/constraint-precedence.js +99 -0
  43. package/dist/src/update/targeted-update-context.d.ts +101 -0
  44. package/dist/src/update/targeted-update-context.js +217 -0
  45. package/dist/src/version-resolution.d.ts +39 -0
  46. package/dist/src/version-resolution.js +76 -0
  47. package/package.json +66 -0
package/LICENSE ADDED
@@ -0,0 +1,110 @@
1
+ # Functional Source License, Version 1.1, MIT Future License
2
+
3
+ ## Abbreviation
4
+
5
+ FSL-1.1-MIT
6
+
7
+ ## Notice
8
+
9
+ Copyright 2025-2026 AgentXM, Inc.
10
+
11
+ ## Terms and Conditions
12
+
13
+ ### Licensor ("We")
14
+
15
+ The party offering the Software under these Terms and Conditions.
16
+
17
+ ### The Software
18
+
19
+ The "Software" is each version of the software that we make available under
20
+ these Terms and Conditions, as indicated by our inclusion of these Terms and
21
+ Conditions with the Software.
22
+
23
+ ### License Grant
24
+
25
+ Subject to your compliance with this License Grant and the Patents,
26
+ Redistribution and Trademark clauses below, we hereby grant you the right to
27
+ use, copy, modify, create derivative works, publicly perform, publicly display
28
+ and redistribute the Software for any Permitted Purpose identified below.
29
+
30
+ ### Permitted Purpose
31
+
32
+ A Permitted Purpose is any purpose other than a Competing Use. A Competing Use
33
+ means making the Software available to others in a commercial product or
34
+ service that:
35
+
36
+ 1. substitutes for the Software;
37
+
38
+ 2. substitutes for any other product or service we offer using the Software
39
+ that exists as of the date we make the Software available; or
40
+
41
+ 3. offers the same or substantially similar functionality as the Software.
42
+
43
+ Permitted Purposes specifically include using the Software:
44
+
45
+ 1. for your internal use and access;
46
+
47
+ 2. for non-commercial education;
48
+
49
+ 3. for non-commercial research; and
50
+
51
+ 4. in connection with professional services that you provide to a licensee
52
+ using the Software in accordance with these Terms and Conditions.
53
+
54
+ ### Patents
55
+
56
+ To the extent your use for a Permitted Purpose would necessarily infringe our
57
+ patents, the license grant above includes a license under our patents. If you
58
+ make a claim against any party that the Software infringes or contributes to
59
+ the infringement of any patent, then your patent license to the Software ends
60
+ immediately.
61
+
62
+ ### Redistribution
63
+
64
+ The Terms and Conditions apply to all copies, modifications and derivatives of
65
+ the Software.
66
+
67
+ If you redistribute any copies, modifications or derivatives of the Software,
68
+ you must include a copy of or a link to these Terms and Conditions and not
69
+ remove any copyright notices provided in or with the Software.
70
+
71
+ ### Disclaimer
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS" AND WITHOUT WARRANTIES OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING WITHOUT LIMITATION WARRANTIES OF FITNESS FOR A PARTICULAR
75
+ PURPOSE, MERCHANTABILITY, TITLE OR NON-INFRINGEMENT.
76
+
77
+ IN NO EVENT WILL WE HAVE ANY LIABILITY TO YOU ARISING OUT OF OR RELATED TO THE
78
+ SOFTWARE, INCLUDING INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES,
79
+ EVEN IF WE HAVE BEEN INFORMED OF THEIR POSSIBILITY IN ADVANCE.
80
+
81
+ ### Trademarks
82
+
83
+ Except for displaying the License Details and identifying us as the origin of
84
+ the Software, you have no right under these Terms and Conditions to use our
85
+ trademarks, trade names, service marks or product names.
86
+
87
+ ## Grant of Future License
88
+
89
+ We hereby irrevocably grant you an additional license to use the Software under
90
+ the MIT license that is effective on the second anniversary of the date we make
91
+ the Software available. On or after that date, you may use the Software under
92
+ the MIT license, in which case the following will apply:
93
+
94
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
95
+ this software and associated documentation files (the "Software"), to deal in
96
+ the Software without restriction, including without limitation the rights to
97
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
98
+ of the Software, and to permit persons to whom the Software is furnished to do
99
+ so, subject to the following conditions:
100
+
101
+ The above copyright notice and this permission notice shall be included in all
102
+ copies or substantial portions of the Software.
103
+
104
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
105
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
106
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
107
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
108
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
109
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
110
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,56 @@
1
+ # @agentxm/extension-resolution
2
+
3
+ Extension resolution policy for the AXM client: what a configured or requested
4
+ extension resolves to, and whether that resolution may be accepted.
5
+
6
+ - **Minimum release age** — `parseMinimumReleaseAge`,
7
+ `isVersionEntryEligibleAt`, `releaseAgeEvidence`, exemption and holdback
8
+ records, and the operator's per-invocation `ReleaseAgePosture`.
9
+ - **Version selection under that policy** — `resolveVersionEntryWithReleaseAge`,
10
+ `resolveVersionEntryForReleaseAge`, and the named Registry target decisions
11
+ `decideNamedRegistryVersion` and `namedRegistryCandidates`.
12
+ - **Configured-entry resolution** — `resolveConfiguredSkill` and its six
13
+ siblings, `resolveConfiguredRegistryEntry`, and the
14
+ `ResolvedConfiguredEntry` vocabulary the lockfile and plans carry.
15
+ - **Pack dependency resolution** — `resolvePackDependencies`,
16
+ `resolvePackDependenciesWithReleaseAge`, the resolved-dependency map schema,
17
+ and `acceptedPackDependencyResolver` for deterministic recovery.
18
+ - **Source authority** — `evaluateSourceAuthority`: whether a requested source
19
+ may replace the configured one for the same target.
20
+ - **Publisher-binding trust** — `classifyPublisherBindingTransition` and the
21
+ proposal vocabulary. Shaping the resulting plan risk condition belongs to
22
+ the feature that owns the plan, not here.
23
+ - **Official AXM skill compatibility** — `evaluateAxmSkillCompatibility`,
24
+ `evaluateAxmSkillCandidate`, `readAxmSkillWorkspaceCompatibility`.
25
+
26
+ Exports `.` and `./live`.
27
+
28
+ Dependency budget: `@agentxm/extension-model`, `@agentxm/registry-protocol`,
29
+ `@agentxm/extension-content`, `@agentxm/extension-sources`, and
30
+ `@agentxm/workspace-state`. Deciding what a configured entry resolves to needs
31
+ workspace facts and source acquisition, so this package sits **above**
32
+ `@agentxm/workspace-state`: state must never depend on it.
33
+
34
+ ## Provider contract
35
+
36
+ `@agentxm/extension-sources` (an integration) fetches the Registry index, maps
37
+ entries to refs, and probes archives, but it may not import this core package.
38
+ It therefore declares ports whose vocabulary lives in
39
+ `@agentxm/extension-model/unstable/sources/source-host-provider`:
40
+
41
+ - `RegistryResolutionPolicy` — implemented structurally by this package's
42
+ decision functions and bound by the application composition root
43
+ (`apps/cli/src/cli-runtime/registry-resolution-policy-live.ts`).
44
+ - `AxmSkillCandidateGate` — implemented by `AxmSkillCandidateGateLive` in this
45
+ package's `./live`.
46
+ - `WorkspaceCatalog` — implemented by `@agentxm/workspace-projection`, which
47
+ owns the agent-selection facts the catalog reports.
48
+
49
+ Selection semantics that the Registry itself defines (`selectVersion`,
50
+ `resolveVersionEntry`: yanked handling and range maxima) stay in
51
+ `@agentxm/registry-protocol/unstable/registry/version-selection`, which both
52
+ the client integration and this package consume.
53
+
54
+ Unstable and unsupported — use the [axm.sh](https://axm.sh) CLI.
55
+
56
+ FSL-1.1-MIT © 2025-2026 AgentXM, Inc.
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Pack member resolution from already accepted state.
3
+ *
4
+ * Recovering an accepted Pack must not re-select its members: every member
5
+ * ref comes from the accepted resolution recorded for that member's
6
+ * configured name, and a member without one is a conflict rather than a new
7
+ * selection. That is resolution authority, so the resolver is built here and
8
+ * the application only chooses when to use it.
9
+ *
10
+ * @experimental This API is unstable and may change without notice.
11
+ */
12
+ import type * as FileSystem from "effect/FileSystem";
13
+ import type * as Path from "effect/Path";
14
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
15
+ import type { AcceptedCanonicalRefError } from "@agentxm/workspace-state";
16
+ import { ExtensionResolutionFailed } from "./errors.js";
17
+ import type { PackDependencyRefResolver } from "./pack-dependency-resolution.js";
18
+ /**
19
+ * Resolve every Pack member from the accepted resolution recorded for its
20
+ * configured name, refusing the recovery when a member has none.
21
+ */
22
+ export declare const acceptedPackDependencyResolver: () => PackDependencyRefResolver<AcceptedCanonicalRefError | ExtensionResolutionFailed, WorkspaceMutations | FileSystem.FileSystem | Path.Path>;
23
+ //# sourceMappingURL=accepted-pack-dependency-resolver.d.ts.map
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Pack member resolution from already accepted state.
3
+ *
4
+ * Recovering an accepted Pack must not re-select its members: every member
5
+ * ref comes from the accepted resolution recorded for that member's
6
+ * configured name, and a member without one is a conflict rather than a new
7
+ * selection. That is resolution authority, so the resolver is built here and
8
+ * the application only chooses when to use it.
9
+ *
10
+ * @experimental This API is unstable and may change without notice.
11
+ */
12
+ import * as Effect from "effect/Effect";
13
+ import * as Option from "effect/Option";
14
+ import { acceptedLockedResolutionRef, WorkspaceMutations } from "@agentxm/workspace-state";
15
+ import { ExtensionResolutionFailed } from "./errors.js";
16
+ /**
17
+ * Resolve every Pack member from the accepted resolution recorded for its
18
+ * configured name, refusing the recovery when a member has none.
19
+ */
20
+ export const acceptedPackDependencyResolver = () => ({ owner, type, name, root }) => Effect.gen(function* () {
21
+ const workspace = yield* WorkspaceMutations;
22
+ const accepted = yield* acceptedLockedResolutionRef({ workspace, type, name });
23
+ if (Option.isNone(accepted)) {
24
+ return yield* new ExtensionResolutionFailed({
25
+ category: "conflict",
26
+ detail: `Accepted Pack recovery for ${root} has no accepted ${type} resolution for ${owner}/${name}`,
27
+ });
28
+ }
29
+ return accepted.value;
30
+ });
31
+ //# sourceMappingURL=accepted-pack-dependency-resolver.js.map
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Recovering the accepted Pack reference a lock entry records.
3
+ *
4
+ * A lock row carries the accepted version and its manifest content identity,
5
+ * but not the member constraints the manifest declares, so a reference rebuilt
6
+ * from the lock alone would expand to an empty closure and record the wrong
7
+ * content identity. Fetching the accepted archive and decoding its manifest is
8
+ * the only way to recover those constraints without re-resolving — and
9
+ * re-resolving is exactly what an operation restoring accepted state must not
10
+ * do.
11
+ *
12
+ * This lives with resolution rather than with either feature because both the
13
+ * configured install closure and the reconciliation sweep's Pack recovery
14
+ * restore from the same accepted authority.
15
+ *
16
+ * @experimental This API is unstable and may change without notice.
17
+ */
18
+ import * as Effect from "effect/Effect";
19
+ import * as FileSystem from "effect/FileSystem";
20
+ import * as Path from "effect/Path";
21
+ import type { PackRef } from "@agentxm/extension-model/unstable/extensions/refs/pack";
22
+ import { SourceHostProviders } from "@agentxm/extension-sources";
23
+ import { WorkspaceMutations } from "@agentxm/workspace-state";
24
+ import { ExtensionResolutionFailed } from "./errors.js";
25
+ /**
26
+ * Complete an accepted Pack reference with the member constraints its accepted
27
+ * archive declares. The archive is fetched, its manifest decoded, and its
28
+ * identity and content checked against the lock before any member resolves
29
+ * from it, so a divergent archive refuses instead of silently reshaping the
30
+ * closure.
31
+ */
32
+ export declare const hydrateAcceptedPackRef: (name: string, ref: PackRef) => Effect.Effect<PackRef, ExtensionResolutionFailed, WorkspaceMutations | SourceHostProviders | FileSystem.FileSystem | Path.Path>;
33
+ //# sourceMappingURL=accepted-pack-hydration.d.ts.map
@@ -0,0 +1,93 @@
1
+ /**
2
+ * Recovering the accepted Pack reference a lock entry records.
3
+ *
4
+ * A lock row carries the accepted version and its manifest content identity,
5
+ * but not the member constraints the manifest declares, so a reference rebuilt
6
+ * from the lock alone would expand to an empty closure and record the wrong
7
+ * content identity. Fetching the accepted archive and decoding its manifest is
8
+ * the only way to recover those constraints without re-resolving — and
9
+ * re-resolving is exactly what an operation restoring accepted state must not
10
+ * do.
11
+ *
12
+ * This lives with resolution rather than with either feature because both the
13
+ * configured install closure and the reconciliation sweep's Pack recovery
14
+ * restore from the same accepted authority.
15
+ *
16
+ * @experimental This API is unstable and may change without notice.
17
+ */
18
+ import * as Effect from "effect/Effect";
19
+ import * as FileSystem from "effect/FileSystem";
20
+ import * as Option from "effect/Option";
21
+ import * as Path from "effect/Path";
22
+ import * as Schema from "effect/Schema";
23
+ import { PACK_MANIFEST_FILENAME, PackManifestSchema, } from "@agentxm/extension-model/unstable/packs/manifest-schema";
24
+ import { SourceHostProviders } from "@agentxm/extension-sources";
25
+ import { WorkspaceMutations, computePackManifestContentIdentity } from "@agentxm/workspace-state";
26
+ import { ExtensionResolutionFailed } from "./errors.js";
27
+ const refused = (fields) => new ExtensionResolutionFailed({
28
+ category: fields.category,
29
+ detail: fields.detail,
30
+ ...(fields.cause === undefined ? {} : { cause: fields.cause }),
31
+ });
32
+ /**
33
+ * Complete an accepted Pack reference with the member constraints its accepted
34
+ * archive declares. The archive is fetched, its manifest decoded, and its
35
+ * identity and content checked against the lock before any member resolves
36
+ * from it, so a divergent archive refuses instead of silently reshaping the
37
+ * closure.
38
+ */
39
+ export const hydrateAcceptedPackRef = Effect.fn("ExtensionResolution.hydrateAcceptedPackRef")(function* (name, ref) {
40
+ const ws = yield* WorkspaceMutations;
41
+ const sources = yield* SourceHostProviders;
42
+ const fs = yield* FileSystem.FileSystem;
43
+ const path = yield* Path.Path;
44
+ const locked = yield* ws.getLockedPack(name).pipe(Effect.mapError((cause) => refused({
45
+ category: "internal",
46
+ detail: `Accepted Pack lock for ${name} could not be read`,
47
+ cause,
48
+ })));
49
+ if (Option.isNone(locked)) {
50
+ return yield* refused({
51
+ category: "conflict",
52
+ detail: `Accepted Pack recovery has no lock authority for ${name}`,
53
+ });
54
+ }
55
+ const manifest = yield* Effect.scoped(Effect.gen(function* () {
56
+ const fetched = yield* sources.fetch(ref).pipe(Effect.mapError((cause) => refused({
57
+ category: "network",
58
+ detail: `Failed to fetch accepted Pack ${ref.owner}/packs/${ref.name}@${ref.version}`,
59
+ cause,
60
+ })));
61
+ const manifestPath = path.join(fetched.directory, PACK_MANIFEST_FILENAME);
62
+ const manifestText = yield* fs.readFileString(manifestPath).pipe(Effect.mapError((cause) => refused({
63
+ category: "validation",
64
+ detail: `Accepted Pack archive has no readable manifest at ${manifestPath}`,
65
+ cause,
66
+ })));
67
+ const manifestJson = yield* Effect.try({
68
+ try: () => JSON.parse(manifestText),
69
+ catch: (cause) => refused({
70
+ category: "validation",
71
+ detail: `Accepted Pack archive manifest is not valid JSON: ${manifestPath}`,
72
+ cause,
73
+ }),
74
+ });
75
+ return yield* Schema.decodeUnknownEffect(PackManifestSchema)(manifestJson).pipe(Effect.mapError((cause) => refused({
76
+ category: "validation",
77
+ detail: `Accepted Pack archive manifest is invalid: ${manifestPath}`,
78
+ cause,
79
+ })));
80
+ }));
81
+ const observedContentIdentity = computePackManifestContentIdentity(manifest);
82
+ if (manifest.owner !== ref.owner ||
83
+ manifest.name !== ref.name ||
84
+ manifest.version !== ref.version ||
85
+ observedContentIdentity !== locked.value.manifestContentIdentity) {
86
+ return yield* refused({
87
+ category: "conflict",
88
+ detail: `Accepted Pack ${ref.owner}/packs/${ref.name}@${ref.version} content ${locked.value.manifestContentIdentity} does not match fetched archive ${manifest.owner}/packs/${manifest.name}@${manifest.version} content ${observedContentIdentity}`,
89
+ });
90
+ }
91
+ return { ...ref, pack: { name: ref.pack.name, dependencies: manifest.dependencies } };
92
+ });
93
+ //# sourceMappingURL=accepted-pack-hydration.js.map
@@ -0,0 +1,16 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as FileSystem from "effect/FileSystem";
3
+ import * as Path from "effect/Path";
4
+ import { AxmSkillCompatibilityUnavailable, AxmSkillIncompatible } from "./errors.js";
5
+ import { type AxmSkillCompatibility } from "./axm-skill-compatibility.js";
6
+ import type { SkillExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/skill";
7
+ export interface ValidateAxmSkillCandidateArgs {
8
+ readonly ref: SkillExtensionRef;
9
+ readonly packageRoot: string;
10
+ readonly skillSourcePath: string;
11
+ }
12
+ /** Inspect candidate bytes and evaluate official AXM skill compatibility. */
13
+ export declare const evaluateAxmSkillCandidate: (args: ValidateAxmSkillCandidateArgs) => Effect.Effect<AxmSkillCompatibility | null, AxmSkillCompatibilityUnavailable, FileSystem.FileSystem | Path.Path>;
14
+ /** Validate official AXM skill bytes before any workspace state is changed. */
15
+ export declare const validateAxmSkillCandidate: (args: ValidateAxmSkillCandidateArgs) => Effect.Effect<AxmSkillCompatibility | null, AxmSkillCompatibilityUnavailable | AxmSkillIncompatible, FileSystem.FileSystem | Path.Path>;
16
+ //# sourceMappingURL=axm-skill-candidate.d.ts.map
@@ -0,0 +1,80 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as FileSystem from "effect/FileSystem";
3
+ import * as Option from "effect/Option";
4
+ import * as Path from "effect/Path";
5
+ import { AxmSkillCompatibilityUnavailable, AxmSkillIncompatible } from "./errors.js";
6
+ import { AXM_SKILL_FQN, AxmSkillCompatibilityPolicy, evaluateAxmSkillCompatibility, } from "./axm-skill-compatibility.js";
7
+ import { parseSkillMd } from "@agentxm/extension-content";
8
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
9
+ const parseManifest = (content) => Option.match(content, {
10
+ onNone: () => ({ official: false, version: null }),
11
+ onSome: (text) => {
12
+ try {
13
+ const value = JSON.parse(text);
14
+ if (!isRecord(value))
15
+ return { official: false, version: null };
16
+ return {
17
+ official: value["owner"] === "@agentxm" && value["type"] === "skill" && value["name"] === "axm",
18
+ version: typeof value["version"] === "string" ? value["version"] : null,
19
+ };
20
+ }
21
+ catch {
22
+ return { official: false, version: null };
23
+ }
24
+ },
25
+ });
26
+ const isKnownOfficialRef = (ref) => (ref.refType === "registry" || ref.refType === "workspace") &&
27
+ ref.owner === "@agentxm" &&
28
+ ref.name === "axm";
29
+ const sourceForRef = (ref) => {
30
+ switch (ref.refType) {
31
+ case "registry":
32
+ return `${ref.owner}/skills/${ref.name}@${ref.version}`;
33
+ case "workspace":
34
+ return `workspace:${ref.owner}/skills/${ref.name}`;
35
+ case "git-hosted":
36
+ case "local":
37
+ return ref.location;
38
+ }
39
+ };
40
+ /** Inspect candidate bytes and evaluate official AXM skill compatibility. */
41
+ export const evaluateAxmSkillCandidate = (args) => Effect.gen(function* () {
42
+ const fs = yield* FileSystem.FileSystem;
43
+ const path = yield* Path.Path;
44
+ const [manifestContent, skillContent] = yield* Effect.all([
45
+ fs.readFileString(path.join(args.packageRoot, "skill.json")).pipe(Effect.option),
46
+ fs.readFileString(path.join(args.skillSourcePath, "SKILL.md")).pipe(Effect.option),
47
+ ]);
48
+ const manifest = parseManifest(manifestContent);
49
+ if (!isKnownOfficialRef(args.ref) && !manifest.official)
50
+ return null;
51
+ const parsedSkill = Option.flatMap(skillContent, (content) => parseSkillMd(content, "axm"));
52
+ const candidate = {
53
+ manifestVersion: manifest.version,
54
+ metadata: Option.match(parsedSkill, {
55
+ onNone: () => null,
56
+ onSome: (skill) => Option.getOrNull(skill.metadata),
57
+ }),
58
+ source: sourceForRef(args.ref),
59
+ };
60
+ const policy = yield* Effect.serviceOption(AxmSkillCompatibilityPolicy);
61
+ const result = Option.match(policy, {
62
+ onNone: () => evaluateAxmSkillCompatibility({ cliVersion: null, skill: candidate }),
63
+ onSome: (service) => service.evaluate({ fqn: AXM_SKILL_FQN, candidate }),
64
+ });
65
+ if (result === null) {
66
+ return yield* new AxmSkillCompatibilityUnavailable();
67
+ }
68
+ return result;
69
+ });
70
+ /** Validate official AXM skill bytes before any workspace state is changed. */
71
+ export const validateAxmSkillCandidate = (args) => Effect.gen(function* () {
72
+ const result = yield* evaluateAxmSkillCandidate(args);
73
+ if (result === null)
74
+ return null;
75
+ if (result.status === "incompatible") {
76
+ return yield* new AxmSkillIncompatible({ compatibility: result });
77
+ }
78
+ return result;
79
+ });
80
+ //# sourceMappingURL=axm-skill-candidate.js.map
@@ -0,0 +1,87 @@
1
+ import * as Layer from "effect/Layer";
2
+ import * as Schema from "effect/Schema";
3
+ import * as ServiceMap from "effect/Context";
4
+ export declare const AXM_SKILL_FQN = "@agentxm/skills/axm";
5
+ export declare const AXM_SKILL_CLI_VERSION_METADATA_KEY = "axm.sh/cli-version";
6
+ export declare const AXM_SKILL_CLI_VERSION_RANGE_METADATA_KEY = "axm.sh/cli-version-range";
7
+ export declare const AXM_SKILL_BUNDLED_PREVIEW_COMMAND = "axm skills install @agentxm/skills/axm --bundled --preview";
8
+ export declare const AXM_SKILL_BUNDLED_APPLY_COMMAND = "axm skills install @agentxm/skills/axm --bundled";
9
+ export declare const AXM_SKILL_REGISTRY_PREVIEW_COMMAND = "axm skills update --name axm --preview";
10
+ export declare const AXM_SKILL_REGISTRY_APPLY_COMMAND = "axm skills update --name axm";
11
+ export declare const AxmSkillCompatibilityReasonSchema: Schema.Literals<readonly ["cli-version-unavailable", "axm-skill-missing", "axm-skill-manifest-invalid", "compatibility-metadata-missing", "compatibility-metadata-malformed", "skill-release-mismatch", "skill-release-range-mismatch", "cli-version-incompatible"]>;
12
+ export type AxmSkillCompatibilityReason = typeof AxmSkillCompatibilityReasonSchema.Type;
13
+ export declare const AxmSkillCompatibilityRecoveryActionSchema: Schema.Literals<readonly ["none", "inspect-cli", "upgrade-cli", "update-registry-skill", "install-bundled-skill", "preserve-authored-skill"]>;
14
+ export type AxmSkillCompatibilityRecoveryAction = typeof AxmSkillCompatibilityRecoveryActionSchema.Type;
15
+ export declare const AxmSkillCompatibilityRecoveryStepSchema: Schema.Struct<{
16
+ readonly boundary: Schema.Literals<readonly ["executable", "workspace", "verification"]>;
17
+ readonly command: Schema.String;
18
+ readonly preview: Schema.Boolean;
19
+ }>;
20
+ export type AxmSkillCompatibilityRecoveryStep = typeof AxmSkillCompatibilityRecoveryStepSchema.Type;
21
+ export declare const AxmSkillCompatibilityRecoverySchema: Schema.Struct<{
22
+ readonly action: Schema.Literals<readonly ["none", "inspect-cli", "upgrade-cli", "update-registry-skill", "install-bundled-skill", "preserve-authored-skill"]>;
23
+ readonly targetCliVersion: Schema.NullOr<Schema.String>;
24
+ readonly targetSkillVersion: Schema.NullOr<Schema.String>;
25
+ readonly nextAction: Schema.NullOr<Schema.String>;
26
+ readonly steps: Schema.$Array<Schema.Struct<{
27
+ readonly boundary: Schema.Literals<readonly ["executable", "workspace", "verification"]>;
28
+ readonly command: Schema.String;
29
+ readonly preview: Schema.Boolean;
30
+ }>>;
31
+ }>;
32
+ export type AxmSkillCompatibilityRecovery = typeof AxmSkillCompatibilityRecoverySchema.Type;
33
+ export declare const formatAxmSkillCompatibilityTarget: (target: {
34
+ readonly targetCliVersion: string | null;
35
+ readonly targetSkillVersion: string | null;
36
+ }) => string;
37
+ export declare const AxmSkillCompatibilitySchema: Schema.Struct<{
38
+ readonly status: Schema.Literals<readonly ["compatible", "incompatible"]>;
39
+ readonly cliVersion: Schema.NullOr<Schema.String>;
40
+ readonly skillVersion: Schema.NullOr<Schema.String>;
41
+ readonly source: Schema.NullOr<Schema.String>;
42
+ readonly declaredCliVersion: Schema.NullOr<Schema.String>;
43
+ readonly declaredCliVersionRange: Schema.NullOr<Schema.String>;
44
+ readonly reasonCode: Schema.NullOr<Schema.Literals<readonly ["cli-version-unavailable", "axm-skill-missing", "axm-skill-manifest-invalid", "compatibility-metadata-missing", "compatibility-metadata-malformed", "skill-release-mismatch", "skill-release-range-mismatch", "cli-version-incompatible"]>>;
45
+ readonly detail: Schema.NullOr<Schema.String>;
46
+ readonly recovery: Schema.Struct<{
47
+ readonly action: Schema.Literals<readonly ["none", "inspect-cli", "upgrade-cli", "update-registry-skill", "install-bundled-skill", "preserve-authored-skill"]>;
48
+ readonly targetCliVersion: Schema.NullOr<Schema.String>;
49
+ readonly targetSkillVersion: Schema.NullOr<Schema.String>;
50
+ readonly nextAction: Schema.NullOr<Schema.String>;
51
+ readonly steps: Schema.$Array<Schema.Struct<{
52
+ readonly boundary: Schema.Literals<readonly ["executable", "workspace", "verification"]>;
53
+ readonly command: Schema.String;
54
+ readonly preview: Schema.Boolean;
55
+ }>>;
56
+ }>;
57
+ }>;
58
+ export type AxmSkillCompatibility = typeof AxmSkillCompatibilitySchema.Type;
59
+ export interface AxmSkillCompatibilityCandidate {
60
+ readonly manifestVersion: string | null;
61
+ readonly metadata: Readonly<Record<string, string>> | null;
62
+ readonly source: string | null;
63
+ }
64
+ export interface AxmSkillCompatibilityInput {
65
+ readonly cliVersion: string | null;
66
+ readonly skill: AxmSkillCompatibilityCandidate | null;
67
+ }
68
+ export interface AxmSkillCompatibilityPolicyInput {
69
+ readonly fqn: string;
70
+ readonly candidate: AxmSkillCompatibilityCandidate | null;
71
+ }
72
+ export interface AxmSkillCompatibilityPolicyService {
73
+ readonly evaluate: (input: AxmSkillCompatibilityPolicyInput) => AxmSkillCompatibility | null;
74
+ }
75
+ declare const AxmSkillCompatibilityPolicy_base: ServiceMap.ServiceClass<AxmSkillCompatibilityPolicy, "@agentxm/extension-resolution/axm-skill-compatibility/AxmSkillCompatibilityPolicy", AxmSkillCompatibilityPolicyService>;
76
+ export declare class AxmSkillCompatibilityPolicy extends AxmSkillCompatibilityPolicy_base {
77
+ }
78
+ export type AxmSkillCliVersionRangeValidation = {
79
+ readonly valid: true;
80
+ } | {
81
+ readonly valid: false;
82
+ };
83
+ export declare const validateAxmSkillCliVersionRange: (value: string) => AxmSkillCliVersionRangeValidation;
84
+ export declare const evaluateAxmSkillCompatibility: (input: AxmSkillCompatibilityInput) => AxmSkillCompatibility;
85
+ export declare const makeAxmSkillCompatibilityPolicyLayer: (cliVersion: string | null) => Layer.Layer<AxmSkillCompatibilityPolicy>;
86
+ export {};
87
+ //# sourceMappingURL=axm-skill-compatibility.d.ts.map