@agentxm/extension-sources 0.28.4-bootstrap.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (101) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +9 -0
  3. package/dist/src/axm-skill-gate.d.ts +64 -0
  4. package/dist/src/axm-skill-gate.js +25 -0
  5. package/dist/src/errors.d.ts +116 -0
  6. package/dist/src/errors.js +98 -0
  7. package/dist/src/failure-category.d.ts +10 -0
  8. package/dist/src/failure-category.js +2 -0
  9. package/dist/src/file-url.d.ts +9 -0
  10. package/dist/src/file-url.js +12 -0
  11. package/dist/src/git/detect.d.ts +7 -0
  12. package/dist/src/git/detect.js +23 -0
  13. package/dist/src/git/operations.d.ts +37 -0
  14. package/dist/src/git/operations.js +101 -0
  15. package/dist/src/glob.d.ts +39 -0
  16. package/dist/src/glob.js +79 -0
  17. package/dist/src/hook-package-discovery.d.ts +19 -0
  18. package/dist/src/hook-package-discovery.js +14 -0
  19. package/dist/src/index.d.ts +30 -0
  20. package/dist/src/index.js +35 -0
  21. package/dist/src/integrity.d.ts +13 -0
  22. package/dist/src/integrity.js +17 -0
  23. package/dist/src/live.d.ts +29 -0
  24. package/dist/src/live.js +131 -0
  25. package/dist/src/manifest-package-discovery.d.ts +28 -0
  26. package/dist/src/manifest-package-discovery.js +96 -0
  27. package/dist/src/package-discovery.d.ts +19 -0
  28. package/dist/src/package-discovery.js +137 -0
  29. package/dist/src/package-sources.d.ts +25 -0
  30. package/dist/src/package-sources.js +102 -0
  31. package/dist/src/providers/azurerepos/index.d.ts +11 -0
  32. package/dist/src/providers/azurerepos/index.js +11 -0
  33. package/dist/src/providers/azurerepos/repo-exists.d.ts +5 -0
  34. package/dist/src/providers/azurerepos/repo-exists.js +21 -0
  35. package/dist/src/providers/azurerepos/scp.d.ts +12 -0
  36. package/dist/src/providers/azurerepos/scp.js +29 -0
  37. package/dist/src/providers/azurerepos/shorthand.d.ts +12 -0
  38. package/dist/src/providers/azurerepos/shorthand.js +45 -0
  39. package/dist/src/providers/azurerepos/url.d.ts +14 -0
  40. package/dist/src/providers/azurerepos/url.js +38 -0
  41. package/dist/src/providers/bitbucket/index.d.ts +11 -0
  42. package/dist/src/providers/bitbucket/index.js +11 -0
  43. package/dist/src/providers/bitbucket/resolve-repo.d.ts +11 -0
  44. package/dist/src/providers/bitbucket/resolve-repo.js +33 -0
  45. package/dist/src/providers/bitbucket/scp.d.ts +11 -0
  46. package/dist/src/providers/bitbucket/scp.js +28 -0
  47. package/dist/src/providers/bitbucket/shorthand.d.ts +10 -0
  48. package/dist/src/providers/bitbucket/shorthand.js +11 -0
  49. package/dist/src/providers/bitbucket/url.d.ts +13 -0
  50. package/dist/src/providers/bitbucket/url.js +42 -0
  51. package/dist/src/providers/convention-discovery.d.ts +11 -0
  52. package/dist/src/providers/convention-discovery.js +473 -0
  53. package/dist/src/providers/git-hosting.d.ts +31 -0
  54. package/dist/src/providers/git-hosting.js +73 -0
  55. package/dist/src/providers/git.d.ts +22 -0
  56. package/dist/src/providers/git.js +46 -0
  57. package/dist/src/providers/github/index.d.ts +11 -0
  58. package/dist/src/providers/github/index.js +11 -0
  59. package/dist/src/providers/github/resolve-repo.d.ts +11 -0
  60. package/dist/src/providers/github/resolve-repo.js +34 -0
  61. package/dist/src/providers/github/scp.d.ts +11 -0
  62. package/dist/src/providers/github/scp.js +28 -0
  63. package/dist/src/providers/github/shorthand.d.ts +10 -0
  64. package/dist/src/providers/github/shorthand.js +11 -0
  65. package/dist/src/providers/github/url.d.ts +13 -0
  66. package/dist/src/providers/github/url.js +42 -0
  67. package/dist/src/providers/gitlab/index.d.ts +11 -0
  68. package/dist/src/providers/gitlab/index.js +11 -0
  69. package/dist/src/providers/gitlab/resolve-repo.d.ts +11 -0
  70. package/dist/src/providers/gitlab/resolve-repo.js +33 -0
  71. package/dist/src/providers/gitlab/scp.d.ts +11 -0
  72. package/dist/src/providers/gitlab/scp.js +28 -0
  73. package/dist/src/providers/gitlab/shorthand.d.ts +10 -0
  74. package/dist/src/providers/gitlab/shorthand.js +11 -0
  75. package/dist/src/providers/gitlab/url.d.ts +13 -0
  76. package/dist/src/providers/gitlab/url.js +42 -0
  77. package/dist/src/providers/local-parser/index.d.ts +8 -0
  78. package/dist/src/providers/local-parser/index.js +8 -0
  79. package/dist/src/providers/local-parser/parser.d.ts +13 -0
  80. package/dist/src/providers/local-parser/parser.js +14 -0
  81. package/dist/src/providers/local.d.ts +23 -0
  82. package/dist/src/providers/local.js +39 -0
  83. package/dist/src/providers/parse-provider-shorthand.d.ts +18 -0
  84. package/dist/src/providers/parse-provider-shorthand.js +74 -0
  85. package/dist/src/providers/registry/host-provider.d.ts +47 -0
  86. package/dist/src/providers/registry/host-provider.js +584 -0
  87. package/dist/src/resolve-identifier.d.ts +73 -0
  88. package/dist/src/resolve-identifier.js +273 -0
  89. package/dist/src/resolve-source-pattern.d.ts +29 -0
  90. package/dist/src/resolve-source-pattern.js +77 -0
  91. package/dist/src/resolve-source.d.ts +79 -0
  92. package/dist/src/resolve-source.js +503 -0
  93. package/dist/src/rule-package-discovery.d.ts +19 -0
  94. package/dist/src/rule-package-discovery.js +14 -0
  95. package/dist/src/service.d.ts +72 -0
  96. package/dist/src/service.js +109 -0
  97. package/dist/src/url-fragment.d.ts +5 -0
  98. package/dist/src/url-fragment.js +19 -0
  99. package/dist/src/workspace-catalog.d.ts +79 -0
  100. package/dist/src/workspace-catalog.js +26 -0
  101. package/package.json +57 -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,9 @@
1
+ # @agentxm/extension-sources
2
+
3
+ The AXM extension-source integration: source locator routing over the
4
+ contract grammar, source host providers for the Registry, GitHub, GitLab,
5
+ Bitbucket, Azure Repos, generic Git, and local paths, convention and manifest
6
+ package discovery, installed/registry identifier resolution, and shallow git
7
+ acquisition.
8
+
9
+ Unstable and unsupported — use the [axm.sh](https://axm.sh) CLI.
@@ -0,0 +1,64 @@
1
+ /**
2
+ * Official AXM skill candidate gate for registry resolution.
3
+ *
4
+ * Resolving the official AXM skill from a registry is gated on whether the
5
+ * candidate release is compatible with the running CLI. That policy is owned
6
+ * above this integration, so the registry host provider consumes it through
7
+ * this port: candidate bytes in, a rendered verdict out. The composition
8
+ * root implements it from the extension-workspace compatibility policy (see
9
+ * the application runtime's axm-skill gate Live).
10
+ *
11
+ * @experimental This API is unstable and may change without notice.
12
+ * @packageDocumentation
13
+ */
14
+ import type * as Effect from "effect/Effect";
15
+ import type * as FileSystem from "effect/FileSystem";
16
+ import type * as Path from "effect/Path";
17
+ import * as ServiceMap from "effect/Context";
18
+ import type { SkillExtensionRef } from "@agentxm/extension-model/unstable/extensions/refs/skill";
19
+ import type { SuggestedAction } from "@agentxm/registry-protocol/unstable/suggested-action";
20
+ import type { CarriedFailureCategory } from "./failure-category.js";
21
+ declare const AxmSkillGateUnavailable_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
22
+ readonly _tag: "AxmSkillGateUnavailable";
23
+ } & Readonly<A>;
24
+ /**
25
+ * The gate implementation could not produce a verdict. The implementation
26
+ * owns the category and wording at construction; the provider transports the
27
+ * failure without re-rendering it.
28
+ */
29
+ export declare class AxmSkillGateUnavailable extends AxmSkillGateUnavailable_base<{
30
+ readonly category: CarriedFailureCategory;
31
+ readonly detail: string;
32
+ readonly suggestions?: ReadonlyArray<SuggestedAction>;
33
+ readonly cause?: unknown;
34
+ }> {
35
+ }
36
+ /** A candidate extracted to disk for evaluation. */
37
+ export interface AxmSkillCandidate {
38
+ readonly ref: SkillExtensionRef;
39
+ readonly packageRoot: string;
40
+ readonly skillSourcePath: string;
41
+ }
42
+ /**
43
+ * The rendered compatibility verdict for one official AXM skill candidate:
44
+ * the incompatibility sentence and the recovery command and target already
45
+ * rendered by the policy owner.
46
+ */
47
+ export interface AxmSkillCandidateVerdict {
48
+ readonly status: "compatible" | "incompatible";
49
+ readonly detail: string | null;
50
+ readonly recoveryCommand: string | null;
51
+ readonly recoveryTarget: string;
52
+ }
53
+ export interface AxmSkillCandidateGateService {
54
+ /**
55
+ * Evaluate one extracted candidate. `null` means the candidate is not the
56
+ * official AXM skill and the gate does not apply.
57
+ */
58
+ readonly evaluate: (candidate: AxmSkillCandidate) => Effect.Effect<AxmSkillCandidateVerdict | null, AxmSkillGateUnavailable, FileSystem.FileSystem | Path.Path>;
59
+ }
60
+ declare const AxmSkillCandidateGate_base: ServiceMap.ServiceClass<AxmSkillCandidateGate, "@agentxm/extension-sources/axm-skill-gate/AxmSkillCandidateGate", AxmSkillCandidateGateService>;
61
+ export declare class AxmSkillCandidateGate extends AxmSkillCandidateGate_base {
62
+ }
63
+ export {};
64
+ //# sourceMappingURL=axm-skill-gate.d.ts.map
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Official AXM skill candidate gate for registry resolution.
3
+ *
4
+ * Resolving the official AXM skill from a registry is gated on whether the
5
+ * candidate release is compatible with the running CLI. That policy is owned
6
+ * above this integration, so the registry host provider consumes it through
7
+ * this port: candidate bytes in, a rendered verdict out. The composition
8
+ * root implements it from the extension-workspace compatibility policy (see
9
+ * the application runtime's axm-skill gate Live).
10
+ *
11
+ * @experimental This API is unstable and may change without notice.
12
+ * @packageDocumentation
13
+ */
14
+ import * as Data from "effect/Data";
15
+ import * as ServiceMap from "effect/Context";
16
+ /**
17
+ * The gate implementation could not produce a verdict. The implementation
18
+ * owns the category and wording at construction; the provider transports the
19
+ * failure without re-rendering it.
20
+ */
21
+ export class AxmSkillGateUnavailable extends Data.TaggedError("AxmSkillGateUnavailable") {
22
+ }
23
+ export class AxmSkillCandidateGate extends ServiceMap.Service()("@agentxm/extension-sources/axm-skill-gate/AxmSkillCandidateGate") {
24
+ }
25
+ //# sourceMappingURL=axm-skill-gate.js.map
@@ -0,0 +1,116 @@
1
+ /**
2
+ * Failure vocabulary for the extension-sources layer.
3
+ *
4
+ * Source resolution interprets user-supplied locators against configured
5
+ * hosts and external systems, so its failures carry the deciding facts as
6
+ * typed fields plus the user-facing sentence the resolution site owns. The
7
+ * category vocabulary uses the same strings as the application error codes so
8
+ * the boundary conversion is a field copy; the application asserts the parity
9
+ * at compile time. Suggestions carried here are display data in the shared
10
+ * `SuggestedAction` contract shape, and `recover`/`cmd` reproduce the
11
+ * application envelope's recovery sugar verbatim.
12
+ *
13
+ * @experimental This API is unstable and may change without notice.
14
+ */
15
+ import type { SuggestedAction } from "@agentxm/registry-protocol/unstable/suggested-action";
16
+ import { type RegistryClientFailure } from "@agentxm/registry-client";
17
+ import { AxmSkillGateUnavailable } from "./axm-skill-gate.js";
18
+ import { WorkspaceCatalogUnavailable } from "./workspace-catalog.js";
19
+ /** Every category a source-resolution failure can carry. Identical strings to the CLI error codes. */
20
+ export declare const SOURCE_ERROR_CATEGORIES: readonly ["conflict", "internal", "network", "not_found", "validation"];
21
+ export type SourceErrorCategory = (typeof SOURCE_ERROR_CATEGORIES)[number];
22
+ declare const SourceSyntaxInvalid_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
23
+ readonly _tag: "SourceSyntaxInvalid";
24
+ } & Readonly<A>;
25
+ /**
26
+ * Input that does not parse as any source locator grammar the resolver
27
+ * understands: malformed URLs, SCP addresses, provider shorthands, or empty
28
+ * input. Always a validation failure.
29
+ */
30
+ export declare class SourceSyntaxInvalid extends SourceSyntaxInvalid_base<{
31
+ readonly detail: string;
32
+ readonly suggestions?: ReadonlyArray<SuggestedAction>;
33
+ readonly cause?: unknown;
34
+ }> {
35
+ }
36
+ declare const SourceHostNotConfigured_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
37
+ readonly _tag: "SourceHostNotConfigured";
38
+ } & Readonly<A>;
39
+ /**
40
+ * Syntactically valid input that no configured source host serves: an
41
+ * unmatched hostname, an unknown source name, a host/params type mismatch, or
42
+ * an ambiguous match across configured hosts. Always a validation failure.
43
+ */
44
+ export declare class SourceHostNotConfigured extends SourceHostNotConfigured_base<{
45
+ readonly detail: string;
46
+ readonly suggestions?: ReadonlyArray<SuggestedAction>;
47
+ readonly cause?: unknown;
48
+ }> {
49
+ }
50
+ declare const SourceNotResolvable_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
51
+ readonly _tag: "SourceNotResolvable";
52
+ } & Readonly<A>;
53
+ /**
54
+ * A well-formed locator or identifier that did not resolve to a usable
55
+ * extension source: nothing matched, the match was ambiguous, discovered
56
+ * content was invalid, or resolution was refused. The constructing site owns
57
+ * the category and the sentence; `recover`/`cmd` reproduce the application
58
+ * envelope's recovery sugar.
59
+ */
60
+ export declare class SourceNotResolvable extends SourceNotResolvable_base<{
61
+ readonly category: SourceErrorCategory;
62
+ readonly detail: string;
63
+ readonly recover?: string;
64
+ readonly cmd?: string;
65
+ readonly suggestions?: ReadonlyArray<SuggestedAction>;
66
+ readonly cause?: unknown;
67
+ }> {
68
+ }
69
+ declare const SourceNetworkFailure_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
70
+ readonly _tag: "SourceNetworkFailure";
71
+ } & Readonly<A>;
72
+ /**
73
+ * A network-facing acquisition step failed: temp-dir staging for a clone or
74
+ * archive, an integrity mismatch, or a ref that carries no fetchable
75
+ * location. Always a network failure; `retryable` is carried only when the
76
+ * failing step established it.
77
+ */
78
+ export declare class SourceNetworkFailure extends SourceNetworkFailure_base<{
79
+ readonly detail: string;
80
+ readonly retryable?: boolean;
81
+ readonly cause?: unknown;
82
+ }> {
83
+ }
84
+ /** The git subprocess operations this package performs. */
85
+ export type GitOperation = "clone" | "get-commit-sha" | "get-tree-sha";
86
+ declare const GitOperationFailed_base: new <A extends Record<string, any> = {}>(args: import("effect/Types").VoidIfEmpty<{ readonly [P in keyof A as P extends "_tag" ? never : P]: A[P]; }>) => import("effect/Cause").YieldableError & {
87
+ readonly _tag: "GitOperationFailed";
88
+ } & Readonly<A>;
89
+ /**
90
+ * A git subprocess operation failed. Clones are network failures; SHA reads
91
+ * over an existing checkout are validation failures.
92
+ */
93
+ export declare class GitOperationFailed extends GitOperationFailed_base<{
94
+ readonly operation: GitOperation;
95
+ readonly detail: string;
96
+ readonly cause?: unknown;
97
+ }> {
98
+ }
99
+ /** Every typed failure constructed by this package's own modules. */
100
+ export type SourceError = SourceSyntaxInvalid | SourceHostNotConfigured | SourceNotResolvable | SourceNetworkFailure | GitOperationFailed;
101
+ /**
102
+ * Every failure a source-resolution effect can surface: this package's own
103
+ * families, the two composition-root port failures, and registry-client
104
+ * failures propagated from registry-backed providers.
105
+ */
106
+ export type SourceResolutionFailure = SourceError | WorkspaceCatalogUnavailable | AxmSkillGateUnavailable | RegistryClientFailure;
107
+ export declare const isSourceError: (error: unknown) => error is SourceError;
108
+ export declare const isSourceResolutionFailure: (error: unknown) => error is SourceResolutionFailure;
109
+ /**
110
+ * The category a source-resolution failure resolves to at the application
111
+ * boundary. Fallback branches key typed decisions on this instead of
112
+ * sniffing the rendered envelope.
113
+ */
114
+ export declare const sourceResolutionFailureCategory: (error: SourceResolutionFailure) => string;
115
+ export {};
116
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Failure vocabulary for the extension-sources layer.
3
+ *
4
+ * Source resolution interprets user-supplied locators against configured
5
+ * hosts and external systems, so its failures carry the deciding facts as
6
+ * typed fields plus the user-facing sentence the resolution site owns. The
7
+ * category vocabulary uses the same strings as the application error codes so
8
+ * the boundary conversion is a field copy; the application asserts the parity
9
+ * at compile time. Suggestions carried here are display data in the shared
10
+ * `SuggestedAction` contract shape, and `recover`/`cmd` reproduce the
11
+ * application envelope's recovery sugar verbatim.
12
+ *
13
+ * @experimental This API is unstable and may change without notice.
14
+ */
15
+ import * as Data from "effect/Data";
16
+ import { isRegistryClientFailure } from "@agentxm/registry-client";
17
+ import { AxmSkillGateUnavailable } from "./axm-skill-gate.js";
18
+ import { WorkspaceCatalogUnavailable } from "./workspace-catalog.js";
19
+ /** Every category a source-resolution failure can carry. Identical strings to the CLI error codes. */
20
+ export const SOURCE_ERROR_CATEGORIES = [
21
+ "conflict",
22
+ "internal",
23
+ "network",
24
+ "not_found",
25
+ "validation",
26
+ ];
27
+ /**
28
+ * Input that does not parse as any source locator grammar the resolver
29
+ * understands: malformed URLs, SCP addresses, provider shorthands, or empty
30
+ * input. Always a validation failure.
31
+ */
32
+ export class SourceSyntaxInvalid extends Data.TaggedError("SourceSyntaxInvalid") {
33
+ }
34
+ /**
35
+ * Syntactically valid input that no configured source host serves: an
36
+ * unmatched hostname, an unknown source name, a host/params type mismatch, or
37
+ * an ambiguous match across configured hosts. Always a validation failure.
38
+ */
39
+ export class SourceHostNotConfigured extends Data.TaggedError("SourceHostNotConfigured") {
40
+ }
41
+ /**
42
+ * A well-formed locator or identifier that did not resolve to a usable
43
+ * extension source: nothing matched, the match was ambiguous, discovered
44
+ * content was invalid, or resolution was refused. The constructing site owns
45
+ * the category and the sentence; `recover`/`cmd` reproduce the application
46
+ * envelope's recovery sugar.
47
+ */
48
+ export class SourceNotResolvable extends Data.TaggedError("SourceNotResolvable") {
49
+ }
50
+ /**
51
+ * A network-facing acquisition step failed: temp-dir staging for a clone or
52
+ * archive, an integrity mismatch, or a ref that carries no fetchable
53
+ * location. Always a network failure; `retryable` is carried only when the
54
+ * failing step established it.
55
+ */
56
+ export class SourceNetworkFailure extends Data.TaggedError("SourceNetworkFailure") {
57
+ }
58
+ /**
59
+ * A git subprocess operation failed. Clones are network failures; SHA reads
60
+ * over an existing checkout are validation failures.
61
+ */
62
+ export class GitOperationFailed extends Data.TaggedError("GitOperationFailed") {
63
+ }
64
+ export const isSourceError = (error) => error instanceof SourceSyntaxInvalid ||
65
+ error instanceof SourceHostNotConfigured ||
66
+ error instanceof SourceNotResolvable ||
67
+ error instanceof SourceNetworkFailure ||
68
+ error instanceof GitOperationFailed;
69
+ export const isSourceResolutionFailure = (error) => isSourceError(error) ||
70
+ error instanceof WorkspaceCatalogUnavailable ||
71
+ error instanceof AxmSkillGateUnavailable ||
72
+ isRegistryClientFailure(error);
73
+ /**
74
+ * The category a source-resolution failure resolves to at the application
75
+ * boundary. Fallback branches key typed decisions on this instead of
76
+ * sniffing the rendered envelope.
77
+ */
78
+ export const sourceResolutionFailureCategory = (error) => {
79
+ switch (error._tag) {
80
+ case "SourceSyntaxInvalid":
81
+ case "SourceHostNotConfigured":
82
+ return "validation";
83
+ case "SourceNotResolvable":
84
+ return error.category;
85
+ case "SourceNetworkFailure":
86
+ return "network";
87
+ case "GitOperationFailed":
88
+ return error.operation === "clone" ? "network" : "validation";
89
+ case "WorkspaceCatalogUnavailable":
90
+ case "AxmSkillGateUnavailable":
91
+ return error.category;
92
+ case "RegistryProblem":
93
+ case "RegistryRequestFailed":
94
+ case "RegistryOperationFailed":
95
+ return error.category;
96
+ }
97
+ };
98
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Failure category vocabulary carried by this package's composition-root
3
+ * ports. The literals are the same strings as the CLI's `AppErrorCode`; the
4
+ * application's conversion site asserts the parity at compile time by
5
+ * assigning this type to its own.
6
+ *
7
+ * @experimental This API is unstable and may change without notice.
8
+ */
9
+ export type CarriedFailureCategory = "issues" | "usage" | "not_found" | "auth" | "forbidden" | "conflict" | "rate_limit" | "network" | "validation" | "internal" | "unavailable" | "quota" | "auth_required" | "auth_expired" | "auth_denied" | "timeout";
10
+ //# sourceMappingURL=failure-category.d.ts.map
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=failure-category.js.map
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Shared utility functions for source parsing.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ /** Convert a `file://` URL to a local filesystem path. */
8
+ export declare const fileUrlToPath: (fileUrl: string) => string;
9
+ //# sourceMappingURL=file-url.d.ts.map
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Shared utility functions for source parsing.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ // Intentional escape hatch: node:url fileURLToPath has no @effect/platform equivalent.
8
+ // This is a pure string transform (no I/O) so wrapping in Effect adds no value.
9
+ import { fileURLToPath as nodeFileUrlToPath } from "node:url";
10
+ /** Convert a `file://` URL to a local filesystem path. */
11
+ export const fileUrlToPath = (fileUrl) => nodeFileUrlToPath(fileUrl);
12
+ //# sourceMappingURL=file-url.js.map
@@ -0,0 +1,7 @@
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
+ export declare const findGitRoot: (workspaceRoot: string) => Effect.Effect<Option.Option<string>, never, FileSystem.FileSystem | Path.Path>;
6
+ export declare const isGitManaged: (workspaceRoot: string) => Effect.Effect<boolean, never, FileSystem.FileSystem | Path.Path>;
7
+ //# sourceMappingURL=detect.d.ts.map
@@ -0,0 +1,23 @@
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
+ const entryExists = (filePath) => Effect.gen(function* () {
6
+ const fs = yield* FileSystem.FileSystem;
7
+ return yield* fs.exists(filePath).pipe(Effect.catch(() => Effect.succeed(false)));
8
+ });
9
+ export const findGitRoot = (workspaceRoot) => Effect.gen(function* () {
10
+ const path = yield* Path.Path;
11
+ const walk = (current) => Effect.gen(function* () {
12
+ const hasGitEntry = yield* entryExists(path.join(current, ".git"));
13
+ if (hasGitEntry)
14
+ return Option.some(current);
15
+ const parent = path.dirname(current);
16
+ if (parent === current)
17
+ return Option.none();
18
+ return yield* walk(parent);
19
+ });
20
+ return yield* walk(path.resolve(workspaceRoot));
21
+ });
22
+ export const isGitManaged = (workspaceRoot) => findGitRoot(workspaceRoot).pipe(Effect.map(Option.isSome));
23
+ //# sourceMappingURL=detect.js.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Git operations for cloning repositories at specific refs.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ import * as Effect from "effect/Effect";
8
+ import * as Path from "effect/Path";
9
+ import { GitOperationFailed } from "../errors.js";
10
+ /**
11
+ * Shallow clone a git repository (depth 1, single branch).
12
+ * Significantly faster than a full clone for read-only use cases like skill discovery.
13
+ *
14
+ * @param url - Repository URL (HTTPS or SSH)
15
+ * @param destination - Local path to clone to
16
+ * @param ref - Optional git ref (branch or tag) to clone
17
+ * @returns Effect that resolves on success or fails with GitError
18
+ *
19
+ * @experimental This API is unstable and may change without notice.
20
+ */
21
+ export declare const shallowClone: (url: string, destination: string, ref?: string) => Effect.Effect<string, GitOperationFailed, Path.Path>;
22
+ /** Get the immutable commit checked out at HEAD. */
23
+ export declare const getCommitSha: (repoPath: string) => Effect.Effect<string, GitOperationFailed, never>;
24
+ /**
25
+ * Get the git tree SHA for a path within a repository.
26
+ *
27
+ * The tree SHA is a hash of the directory's contents at the current commit.
28
+ * Unlike commit SHA, it is stable across rebases that don't change content.
29
+ *
30
+ * @param repoPath - Path to the git repository root
31
+ * @param subPath - Optional subpath within the repository (defaults to root ".")
32
+ * @returns Effect that resolves to the tree SHA, or fails if path is not in a git repo
33
+ *
34
+ * @experimental This API is unstable and may change without notice.
35
+ */
36
+ export declare const getTreeSha: (repoPath: string, subPath?: string) => Effect.Effect<string, GitOperationFailed, never>;
37
+ //# sourceMappingURL=operations.d.ts.map
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Git operations for cloning repositories at specific refs.
3
+ *
4
+ * @experimental This API is unstable and may change without notice.
5
+ * @packageDocumentation
6
+ */
7
+ import * as Array from "effect/Array";
8
+ import * as Effect from "effect/Effect";
9
+ import * as Option from "effect/Option";
10
+ import * as Path from "effect/Path";
11
+ import { simpleGit } from "simple-git";
12
+ import { GitOperationFailed } from "../errors.js";
13
+ // -----------------------------------------------------------------------------
14
+ // Internal Helpers
15
+ // -----------------------------------------------------------------------------
16
+ const createGit = (baseDir, abort) => {
17
+ const options = {
18
+ baseDir,
19
+ binary: "git",
20
+ maxConcurrentProcesses: 1,
21
+ ...(abort === undefined ? {} : { abort }),
22
+ };
23
+ return simpleGit(options).env("GIT_TERMINAL_PROMPT", "0").env("GIT_LFS_SKIP_SMUDGE", "1");
24
+ };
25
+ /**
26
+ * Maps unknown errors to the typed git failure with appropriate context.
27
+ */
28
+ const mapGitError = (operation, context) => (error) => {
29
+ const baseMessage = context ?? `Git ${operation} failed`;
30
+ return new GitOperationFailed({
31
+ operation,
32
+ detail: baseMessage,
33
+ cause: error,
34
+ });
35
+ };
36
+ // -----------------------------------------------------------------------------
37
+ // Git Operations
38
+ // -----------------------------------------------------------------------------
39
+ /**
40
+ * Shallow clone a git repository (depth 1, single branch).
41
+ * Significantly faster than a full clone for read-only use cases like skill discovery.
42
+ *
43
+ * @param url - Repository URL (HTTPS or SSH)
44
+ * @param destination - Local path to clone to
45
+ * @param ref - Optional git ref (branch or tag) to clone
46
+ * @returns Effect that resolves on success or fails with GitError
47
+ *
48
+ * @experimental This API is unstable and may change without notice.
49
+ */
50
+ export const shallowClone = (url, destination, ref) => Effect.gen(function* () {
51
+ const path = yield* Path.Path;
52
+ return yield* Effect.tryPromise({
53
+ try: (signal) => createGit(path.dirname(destination), signal).clone(url, destination, [
54
+ "--depth",
55
+ "1",
56
+ "--single-branch",
57
+ ...(ref ? ["--branch", ref] : []),
58
+ ]),
59
+ catch: mapGitError("clone", `Failed to shallow clone ${url}`),
60
+ });
61
+ }).pipe(Effect.withSpan("Git.shallowClone"));
62
+ /** Get the immutable commit checked out at HEAD. */
63
+ export const getCommitSha = (repoPath) => Effect.tryPromise({
64
+ try: async (signal) => (await createGit(repoPath, signal).revparse(["HEAD"])).trim(),
65
+ catch: mapGitError("get-commit-sha", "Failed to get checked-out commit SHA"),
66
+ }).pipe(Effect.withSpan("Git.getCommitSha"));
67
+ /**
68
+ * Get the git tree SHA for a path within a repository.
69
+ *
70
+ * The tree SHA is a hash of the directory's contents at the current commit.
71
+ * Unlike commit SHA, it is stable across rebases that don't change content.
72
+ *
73
+ * @param repoPath - Path to the git repository root
74
+ * @param subPath - Optional subpath within the repository (defaults to root ".")
75
+ * @returns Effect that resolves to the tree SHA, or fails if path is not in a git repo
76
+ *
77
+ * @experimental This API is unstable and may change without notice.
78
+ */
79
+ export const getTreeSha = (repoPath, subPath = ".") => Effect.tryPromise({
80
+ try: async (signal) => {
81
+ const git = createGit(repoPath, signal);
82
+ // For root directory, use rev-parse HEAD^{tree}
83
+ if (subPath === "." || subPath === "") {
84
+ const result = await git.revparse(["HEAD^{tree}"]);
85
+ return result.trim();
86
+ }
87
+ // For subdirectories, use ls-tree to get the tree object SHA
88
+ // ls-tree returns: <mode> <type> <sha>\t<path>
89
+ const result = await git.raw(["ls-tree", "HEAD", subPath]);
90
+ const trimmed = result.trim();
91
+ if (!trimmed) {
92
+ throw new Error(`Path '${subPath}' not found in repository`);
93
+ }
94
+ // Parse the output: "040000 tree <sha>\t<path>" or "100644 blob <sha>\t<path>"
95
+ const parts = trimmed.split(/\s+/);
96
+ const sha = Option.getOrThrowWith(Array.get(parts, 2), () => new Error(`Unexpected ls-tree output: ${trimmed}`));
97
+ return sha;
98
+ },
99
+ catch: mapGitError("get-tree-sha", `Failed to get tree SHA for '${subPath}'`),
100
+ }).pipe(Effect.withSpan("Git.getTreeSha"));
101
+ //# sourceMappingURL=operations.js.map