@agentxm/extension-model 0.35.0 → 0.37.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.
- package/dist/src/unstable/agent-capabilities/catalog.d.ts +19197 -4977
- package/dist/src/unstable/agent-capabilities/data/agents/adal.d.ts +31 -3
- package/dist/src/unstable/agent-capabilities/data/agents/adal.js +27 -3
- package/dist/src/unstable/agent-capabilities/data/agents/aider-desk.d.ts +19 -2
- package/dist/src/unstable/agent-capabilities/data/agents/aider-desk.js +17 -2
- package/dist/src/unstable/agent-capabilities/data/agents/amp.d.ts +56 -4
- package/dist/src/unstable/agent-capabilities/data/agents/amp.js +52 -4
- package/dist/src/unstable/agent-capabilities/data/agents/antigravity-cli.d.ts +68 -6
- package/dist/src/unstable/agent-capabilities/data/agents/antigravity-cli.js +61 -6
- package/dist/src/unstable/agent-capabilities/data/agents/antigravity.d.ts +179 -53
- package/dist/src/unstable/agent-capabilities/data/agents/antigravity.js +152 -42
- package/dist/src/unstable/agent-capabilities/data/agents/augment.d.ts +176 -64
- package/dist/src/unstable/agent-capabilities/data/agents/augment.js +162 -64
- package/dist/src/unstable/agent-capabilities/data/agents/chatgpt.d.ts +3 -1
- package/dist/src/unstable/agent-capabilities/data/agents/chatgpt.js +3 -1
- package/dist/src/unstable/agent-capabilities/data/agents/claude-ai.d.ts +2 -0
- package/dist/src/unstable/agent-capabilities/data/agents/claude-ai.js +2 -0
- package/dist/src/unstable/agent-capabilities/data/agents/claude-code.d.ts +238 -75
- package/dist/src/unstable/agent-capabilities/data/agents/claude-code.js +222 -78
- package/dist/src/unstable/agent-capabilities/data/agents/cline.d.ts +115 -55
- package/dist/src/unstable/agent-capabilities/data/agents/cline.js +100 -47
- package/dist/src/unstable/agent-capabilities/data/agents/codearts-agent.d.ts +140 -63
- package/dist/src/unstable/agent-capabilities/data/agents/codearts-agent.js +123 -52
- package/dist/src/unstable/agent-capabilities/data/agents/codebuddy.d.ts +211 -76
- package/dist/src/unstable/agent-capabilities/data/agents/codebuddy.js +197 -79
- package/dist/src/unstable/agent-capabilities/data/agents/codestudio.d.ts +46 -4
- package/dist/src/unstable/agent-capabilities/data/agents/codestudio.js +40 -4
- package/dist/src/unstable/agent-capabilities/data/agents/codex.d.ts +242 -68
- package/dist/src/unstable/agent-capabilities/data/agents/codex.js +213 -59
- package/dist/src/unstable/agent-capabilities/data/agents/command-code.d.ts +169 -68
- package/dist/src/unstable/agent-capabilities/data/agents/command-code.js +156 -64
- package/dist/src/unstable/agent-capabilities/data/agents/continue.d.ts +79 -7
- package/dist/src/unstable/agent-capabilities/data/agents/continue.js +75 -7
- package/dist/src/unstable/agent-capabilities/data/agents/cortex.d.ts +116 -9
- package/dist/src/unstable/agent-capabilities/data/agents/cortex.js +110 -9
- package/dist/src/unstable/agent-capabilities/data/agents/cowork.d.ts +4 -0
- package/dist/src/unstable/agent-capabilities/data/agents/cowork.js +4 -0
- package/dist/src/unstable/agent-capabilities/data/agents/crush.d.ts +165 -60
- package/dist/src/unstable/agent-capabilities/data/agents/crush.js +151 -54
- package/dist/src/unstable/agent-capabilities/data/agents/cursor.d.ts +230 -55
- package/dist/src/unstable/agent-capabilities/data/agents/cursor.js +205 -51
- package/dist/src/unstable/agent-capabilities/data/agents/deepagents.d.ts +100 -5
- package/dist/src/unstable/agent-capabilities/data/agents/deepagents.js +86 -5
- package/dist/src/unstable/agent-capabilities/data/agents/devin.d.ts +224 -77
- package/dist/src/unstable/agent-capabilities/data/agents/devin.js +203 -70
- package/dist/src/unstable/agent-capabilities/data/agents/dexto.d.ts +28 -2
- package/dist/src/unstable/agent-capabilities/data/agents/dexto.js +26 -2
- package/dist/src/unstable/agent-capabilities/data/agents/droid.d.ts +93 -8
- package/dist/src/unstable/agent-capabilities/data/agents/droid.js +87 -8
- package/dist/src/unstable/agent-capabilities/data/agents/firebender.d.ts +119 -8
- package/dist/src/unstable/agent-capabilities/data/agents/firebender.js +112 -13
- package/dist/src/unstable/agent-capabilities/data/agents/forgecode.d.ts +94 -6
- package/dist/src/unstable/agent-capabilities/data/agents/forgecode.js +82 -6
- package/dist/src/unstable/agent-capabilities/data/agents/gemini-app.d.ts +2 -0
- package/dist/src/unstable/agent-capabilities/data/agents/gemini-app.js +2 -0
- package/dist/src/unstable/agent-capabilities/data/agents/gemini-cli.d.ts +218 -56
- package/dist/src/unstable/agent-capabilities/data/agents/gemini-cli.js +193 -55
- package/dist/src/unstable/agent-capabilities/data/agents/github-copilot-cli.d.ts +201 -66
- package/dist/src/unstable/agent-capabilities/data/agents/github-copilot-cli.js +188 -69
- package/dist/src/unstable/agent-capabilities/data/agents/goose.d.ts +37 -3
- package/dist/src/unstable/agent-capabilities/data/agents/goose.js +34 -5
- package/dist/src/unstable/agent-capabilities/data/agents/grok-cli.d.ts +98 -6
- package/dist/src/unstable/agent-capabilities/data/agents/grok-cli.js +83 -6
- package/dist/src/unstable/agent-capabilities/data/agents/hermes.d.ts +105 -42
- package/dist/src/unstable/agent-capabilities/data/agents/hermes.js +87 -28
- package/dist/src/unstable/agent-capabilities/data/agents/ibm-bob.d.ts +173 -61
- package/dist/src/unstable/agent-capabilities/data/agents/ibm-bob.js +152 -52
- package/dist/src/unstable/agent-capabilities/data/agents/iflow-cli.d.ts +47 -5
- package/dist/src/unstable/agent-capabilities/data/agents/iflow-cli.js +41 -5
- package/dist/src/unstable/agent-capabilities/data/agents/junie.d.ts +130 -42
- package/dist/src/unstable/agent-capabilities/data/agents/junie.js +121 -39
- package/dist/src/unstable/agent-capabilities/data/agents/kilo.d.ts +187 -65
- package/dist/src/unstable/agent-capabilities/data/agents/kilo.js +169 -62
- package/dist/src/unstable/agent-capabilities/data/agents/kimi-cli.d.ts +147 -60
- package/dist/src/unstable/agent-capabilities/data/agents/kimi-cli.js +134 -53
- package/dist/src/unstable/agent-capabilities/data/agents/kiro-cli.d.ts +138 -50
- package/dist/src/unstable/agent-capabilities/data/agents/kiro-cli.js +121 -39
- package/dist/src/unstable/agent-capabilities/data/agents/kode.d.ts +45 -5
- package/dist/src/unstable/agent-capabilities/data/agents/kode.js +39 -5
- package/dist/src/unstable/agent-capabilities/data/agents/lingma.d.ts +19 -2
- package/dist/src/unstable/agent-capabilities/data/agents/lingma.js +17 -2
- package/dist/src/unstable/agent-capabilities/data/agents/mcpjam.d.ts +16 -1
- package/dist/src/unstable/agent-capabilities/data/agents/mcpjam.js +14 -1
- package/dist/src/unstable/agent-capabilities/data/agents/mistral-vibe.d.ts +93 -8
- package/dist/src/unstable/agent-capabilities/data/agents/mistral-vibe.js +87 -8
- package/dist/src/unstable/agent-capabilities/data/agents/mux.d.ts +46 -4
- package/dist/src/unstable/agent-capabilities/data/agents/mux.js +40 -4
- package/dist/src/unstable/agent-capabilities/data/agents/neovate.d.ts +111 -59
- package/dist/src/unstable/agent-capabilities/data/agents/neovate.js +97 -50
- package/dist/src/unstable/agent-capabilities/data/agents/ona.d.ts +41 -4
- package/dist/src/unstable/agent-capabilities/data/agents/ona.js +37 -4
- package/dist/src/unstable/agent-capabilities/data/agents/openclaw.d.ts +14 -1
- package/dist/src/unstable/agent-capabilities/data/agents/openclaw.js +12 -1
- package/dist/src/unstable/agent-capabilities/data/agents/opencode.d.ts +286 -14
- package/dist/src/unstable/agent-capabilities/data/agents/opencode.js +261 -16
- package/dist/src/unstable/agent-capabilities/data/agents/openhands.d.ts +53 -4
- package/dist/src/unstable/agent-capabilities/data/agents/openhands.js +49 -4
- package/dist/src/unstable/agent-capabilities/data/agents/pi.d.ts +69 -2
- package/dist/src/unstable/agent-capabilities/data/agents/pi.js +56 -2
- package/dist/src/unstable/agent-capabilities/data/agents/pochi.d.ts +96 -44
- package/dist/src/unstable/agent-capabilities/data/agents/pochi.js +81 -33
- package/dist/src/unstable/agent-capabilities/data/agents/qoder-cn.d.ts +70 -6
- package/dist/src/unstable/agent-capabilities/data/agents/qoder-cn.js +75 -7
- package/dist/src/unstable/agent-capabilities/data/agents/qoder.d.ts +196 -72
- package/dist/src/unstable/agent-capabilities/data/agents/qoder.js +182 -72
- package/dist/src/unstable/agent-capabilities/data/agents/qwen-code.d.ts +169 -57
- package/dist/src/unstable/agent-capabilities/data/agents/qwen-code.js +154 -56
- package/dist/src/unstable/agent-capabilities/data/agents/replit.d.ts +16 -1
- package/dist/src/unstable/agent-capabilities/data/agents/replit.js +14 -1
- package/dist/src/unstable/agent-capabilities/data/agents/roo.d.ts +60 -7
- package/dist/src/unstable/agent-capabilities/data/agents/roo.js +51 -7
- package/dist/src/unstable/agent-capabilities/data/agents/rovodev.d.ts +70 -6
- package/dist/src/unstable/agent-capabilities/data/agents/rovodev.js +64 -6
- package/dist/src/unstable/agent-capabilities/data/agents/tabnine-cli.d.ts +92 -7
- package/dist/src/unstable/agent-capabilities/data/agents/tabnine-cli.js +85 -7
- package/dist/src/unstable/agent-capabilities/data/agents/trae-cn.d.ts +72 -33
- package/dist/src/unstable/agent-capabilities/data/agents/trae-cn.js +64 -29
- package/dist/src/unstable/agent-capabilities/data/agents/trae.d.ts +72 -33
- package/dist/src/unstable/agent-capabilities/data/agents/trae.js +64 -29
- package/dist/src/unstable/agent-capabilities/data/agents/warp.d.ts +31 -3
- package/dist/src/unstable/agent-capabilities/data/agents/warp.js +27 -3
- package/dist/src/unstable/agent-capabilities/data/agents/windsurf.d.ts +126 -41
- package/dist/src/unstable/agent-capabilities/data/agents/windsurf.js +110 -39
- package/dist/src/unstable/agent-capabilities/data/agents/zed.d.ts +31 -3
- package/dist/src/unstable/agent-capabilities/data/agents/zed.js +27 -3
- package/dist/src/unstable/agent-capabilities/data/agents/zencoder.d.ts +41 -5
- package/dist/src/unstable/agent-capabilities/data/agents/zencoder.js +37 -5
- package/dist/src/unstable/agent-capabilities/data/agents/zenflow.d.ts +34 -2
- package/dist/src/unstable/agent-capabilities/data/agents/zenflow.js +31 -4
- package/dist/src/unstable/agent-capabilities/derive.js +37 -60
- package/dist/src/unstable/agent-capabilities/identity.d.ts +2 -0
- package/dist/src/unstable/agent-capabilities/identity.js +3 -0
- package/dist/src/unstable/agent-capabilities/index.d.ts +2 -2
- package/dist/src/unstable/agent-capabilities/index.js +2 -2
- package/dist/src/unstable/agent-capabilities/schema.d.ts +769 -761
- package/dist/src/unstable/agent-capabilities/schema.js +188 -91
- package/dist/src/unstable/agents/registry.d.ts +3 -17
- package/dist/src/unstable/agents/registry.js +2 -29
- package/dist/src/unstable/agents/types.d.ts +19 -53
- package/dist/src/unstable/agents/types.js +2 -4
- package/dist/src/unstable/extensions/common.d.ts +1 -2
- package/dist/src/unstable/extensions/common.js +1 -2
- package/dist/src/unstable/extensions/name-patterns.d.ts +5 -3
- package/dist/src/unstable/extensions/name-patterns.js +31 -32
- package/dist/src/unstable/path-types.d.ts +6 -0
- package/dist/src/unstable/path-types.js +20 -0
- package/dist/src/unstable/sources/forge-grammar.d.ts +46 -10
- package/dist/src/unstable/sources/forge-grammar.js +153 -33
- package/dist/src/unstable/sources/parser.d.ts +3 -5
- package/dist/src/unstable/sources/parser.js +14 -31
- package/dist/src/unstable/sources/printer.js +16 -35
- package/dist/src/unstable/sources/types.d.ts +1 -93
- package/dist/src/unstable/sources/types.js +1 -48
- package/package.json +3 -3
|
@@ -10,8 +10,6 @@ import { CONFIGURABLE_AGENT_IDS, } from "../agent-capabilities/identity.js";
|
|
|
10
10
|
// -----------------------------------------------------------------------------
|
|
11
11
|
/** @experimental This API is unstable and may change without notice. */
|
|
12
12
|
export { CONFIGURABLE_AGENT_IDS };
|
|
13
|
-
/**
|
|
14
|
-
export const
|
|
15
|
-
/** @experimental This API is unstable and may change without notice. */
|
|
16
|
-
export const isConfigurableAgentId = (id) => id !== "universal";
|
|
13
|
+
/** Real agents that can participate in native materialization. @experimental */
|
|
14
|
+
export const MATERIALIZATION_TARGET_IDS = [...CONFIGURABLE_AGENT_IDS];
|
|
17
15
|
//# sourceMappingURL=types.js.map
|
|
@@ -677,8 +677,7 @@ export { AgentIdSchema };
|
|
|
677
677
|
/**
|
|
678
678
|
* Agent identifiers users may persist in `axm.json`.
|
|
679
679
|
*
|
|
680
|
-
*
|
|
681
|
-
* they are injected by repository code rather than configured by users.
|
|
680
|
+
* Shared native locations are policy, not additional agent identities.
|
|
682
681
|
*
|
|
683
682
|
* @experimental This API is unstable and may change without notice.
|
|
684
683
|
*/
|
|
@@ -643,8 +643,7 @@ export { AgentIdSchema };
|
|
|
643
643
|
/**
|
|
644
644
|
* Agent identifiers users may persist in `axm.json`.
|
|
645
645
|
*
|
|
646
|
-
*
|
|
647
|
-
* they are injected by repository code rather than configured by users.
|
|
646
|
+
* Shared native locations are policy, not additional agent identities.
|
|
648
647
|
*
|
|
649
648
|
* @experimental This API is unstable and may change without notice.
|
|
650
649
|
*/
|
|
@@ -7,15 +7,17 @@
|
|
|
7
7
|
* @experimental This API is unstable and may change without notice.
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Match one extension name against a pattern.
|
|
11
11
|
*
|
|
12
12
|
* Only `*` wildcards are supported. All other characters (including `?`, `[`, `]`)
|
|
13
13
|
* are treated as literals. Matching is case-sensitive.
|
|
14
14
|
*
|
|
15
15
|
* @param pattern - The pattern to match (may contain `*`)
|
|
16
|
-
* @param
|
|
17
|
-
* @returns
|
|
16
|
+
* @param name - The name to check
|
|
17
|
+
* @returns Whether the complete name matches
|
|
18
18
|
*/
|
|
19
|
+
export declare const matchesPattern: (pattern: string, name: string) => boolean;
|
|
20
|
+
/** Expand a glob pattern against names, preserving their original order. */
|
|
19
21
|
export declare const expandGlob: (pattern: string, names: ReadonlyArray<string>) => ReadonlyArray<string>;
|
|
20
22
|
/**
|
|
21
23
|
* Expand multiple glob patterns against a list of extension names.
|
|
@@ -7,48 +7,47 @@
|
|
|
7
7
|
* @experimental This API is unstable and may change without notice.
|
|
8
8
|
*/
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Match one extension name against a pattern.
|
|
11
11
|
*
|
|
12
12
|
* Only `*` wildcards are supported. All other characters (including `?`, `[`, `]`)
|
|
13
13
|
* are treated as literals. Matching is case-sensitive.
|
|
14
14
|
*
|
|
15
15
|
* @param pattern - The pattern to match (may contain `*`)
|
|
16
|
-
* @param
|
|
17
|
-
* @returns
|
|
16
|
+
* @param name - The name to check
|
|
17
|
+
* @returns Whether the complete name matches
|
|
18
18
|
*/
|
|
19
|
-
export const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
nameIndex += 1;
|
|
30
|
-
}
|
|
31
|
-
else if (token === "*") {
|
|
32
|
-
wildcardIndex = patternIndex;
|
|
33
|
-
wildcardNameIndex = nameIndex;
|
|
34
|
-
patternIndex += 1;
|
|
35
|
-
}
|
|
36
|
-
else if (wildcardIndex >= 0) {
|
|
37
|
-
patternIndex = wildcardIndex + 1;
|
|
38
|
-
wildcardNameIndex += 1;
|
|
39
|
-
nameIndex = wildcardNameIndex;
|
|
40
|
-
}
|
|
41
|
-
else {
|
|
42
|
-
return false;
|
|
43
|
-
}
|
|
19
|
+
export const matchesPattern = (pattern, name) => {
|
|
20
|
+
let patternIndex = 0;
|
|
21
|
+
let nameIndex = 0;
|
|
22
|
+
let wildcardIndex = -1;
|
|
23
|
+
let wildcardNameIndex = 0;
|
|
24
|
+
while (nameIndex < name.length) {
|
|
25
|
+
const token = pattern[patternIndex];
|
|
26
|
+
if (token !== undefined && token !== "*" && token === name[nameIndex]) {
|
|
27
|
+
patternIndex += 1;
|
|
28
|
+
nameIndex += 1;
|
|
44
29
|
}
|
|
45
|
-
|
|
30
|
+
else if (token === "*") {
|
|
31
|
+
wildcardIndex = patternIndex;
|
|
32
|
+
wildcardNameIndex = nameIndex;
|
|
46
33
|
patternIndex += 1;
|
|
47
34
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
35
|
+
else if (wildcardIndex >= 0) {
|
|
36
|
+
patternIndex = wildcardIndex + 1;
|
|
37
|
+
wildcardNameIndex += 1;
|
|
38
|
+
nameIndex = wildcardNameIndex;
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
while (pattern[patternIndex] === "*") {
|
|
45
|
+
patternIndex += 1;
|
|
46
|
+
}
|
|
47
|
+
return patternIndex === pattern.length;
|
|
51
48
|
};
|
|
49
|
+
/** Expand a glob pattern against names, preserving their original order. */
|
|
50
|
+
export const expandGlob = (pattern, names) => names.filter((name) => matchesPattern(pattern, name));
|
|
52
51
|
/**
|
|
53
52
|
* Expand multiple glob patterns against a list of extension names.
|
|
54
53
|
*
|
|
@@ -26,4 +26,10 @@ export declare const makeWorkspaceRelativeSourcePath: (path: Path.Path, workspac
|
|
|
26
26
|
* prefix is not mistaken for a child.
|
|
27
27
|
*/
|
|
28
28
|
export declare const isPathSafe: (path: Path.Path, base: string, target: string) => boolean;
|
|
29
|
+
/** Resolve a child against its base and reject paths that escape it. */
|
|
30
|
+
export declare const safeChildPath: (path: Path.Path, base: string, target: string) => Option.Option<AbsolutePath>;
|
|
31
|
+
/** Relative-path containment, including the parent itself. */
|
|
32
|
+
export declare const isWithinOrEqual: (path: Path.Path, parent: string, child: string) => boolean;
|
|
33
|
+
/** Relative-path containment that excludes the parent itself. */
|
|
34
|
+
export declare const isStrictlyWithin: (path: Path.Path, parent: string, child: string) => boolean;
|
|
29
35
|
//# sourceMappingURL=path-types.d.ts.map
|
|
@@ -56,4 +56,24 @@ export const isPathSafe = (path, base, target) => {
|
|
|
56
56
|
const resolvedTarget = path.resolve(target);
|
|
57
57
|
return resolvedTarget === resolvedBase || resolvedTarget.startsWith(resolvedBase + path.sep);
|
|
58
58
|
};
|
|
59
|
+
/** Resolve a child against its base and reject paths that escape it. */
|
|
60
|
+
export const safeChildPath = (path, base, target) => {
|
|
61
|
+
const resolvedBase = path.resolve(base);
|
|
62
|
+
const resolvedTarget = path.isAbsolute(target)
|
|
63
|
+
? path.resolve(target)
|
|
64
|
+
: path.resolve(resolvedBase, target);
|
|
65
|
+
return isPathSafe(path, resolvedBase, resolvedTarget)
|
|
66
|
+
? Option.some(makeAbsolutePath(path, resolvedTarget))
|
|
67
|
+
: Option.none();
|
|
68
|
+
};
|
|
69
|
+
/** Relative-path containment, including the parent itself. */
|
|
70
|
+
export const isWithinOrEqual = (path, parent, child) => {
|
|
71
|
+
const relative = path.relative(path.resolve(parent), path.resolve(child));
|
|
72
|
+
return relative === "" || (!relative.startsWith("..") && !path.isAbsolute(relative));
|
|
73
|
+
};
|
|
74
|
+
/** Relative-path containment that excludes the parent itself. */
|
|
75
|
+
export const isStrictlyWithin = (path, parent, child) => {
|
|
76
|
+
const relative = path.relative(path.resolve(parent), path.resolve(child));
|
|
77
|
+
return relative !== "" && !relative.startsWith("..") && !path.isAbsolute(relative);
|
|
78
|
+
};
|
|
59
79
|
//# sourceMappingURL=path-types.js.map
|
|
@@ -1,22 +1,58 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Forge coordinate, clone URL, and browser URL grammar.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* only the string grammar lives here.
|
|
4
|
+
* Probing and acquisition stay with source resolution; the model owns the
|
|
5
|
+
* strings and URLs that identify each forge repository.
|
|
7
6
|
*
|
|
8
7
|
* @experimental This API is unstable and may change without notice.
|
|
9
8
|
* @packageDocumentation
|
|
10
9
|
*/
|
|
11
|
-
import
|
|
10
|
+
import * as Option from "effect/Option";
|
|
11
|
+
import * as Result from "effect/Result";
|
|
12
12
|
/** @experimental */
|
|
13
|
-
export declare const
|
|
13
|
+
export declare const FORGE_PREFIXES: readonly ["github", "gitlab", "bitbucket", "azurerepos"];
|
|
14
14
|
/** @experimental */
|
|
15
|
-
export
|
|
15
|
+
export type ForgePrefix = (typeof FORGE_PREFIXES)[number];
|
|
16
16
|
/** @experimental */
|
|
17
|
-
export declare const
|
|
17
|
+
export declare const isForgePrefix: (value: string) => value is ForgePrefix;
|
|
18
18
|
/** @experimental */
|
|
19
|
-
export
|
|
19
|
+
export interface ForgeCoordinate {
|
|
20
|
+
readonly forge: ForgePrefix;
|
|
21
|
+
readonly repository: string;
|
|
22
|
+
readonly ref: Option.Option<string>;
|
|
23
|
+
readonly subPath: Option.Option<string>;
|
|
24
|
+
}
|
|
25
|
+
interface BrowserPath {
|
|
26
|
+
readonly repository: string;
|
|
27
|
+
readonly ref?: string;
|
|
28
|
+
readonly subPath?: string;
|
|
29
|
+
}
|
|
20
30
|
/** @experimental */
|
|
21
|
-
export
|
|
31
|
+
export interface Forge {
|
|
32
|
+
readonly prefix: ForgePrefix;
|
|
33
|
+
readonly hostname: string;
|
|
34
|
+
readonly repositorySegments: (count: number) => boolean;
|
|
35
|
+
readonly cloneUrl: (repository: string) => URL;
|
|
36
|
+
readonly repositoryFromCloneUrl: (pathname: string) => string | undefined;
|
|
37
|
+
readonly parseBrowserPath: (pathname: string) => BrowserPath | undefined;
|
|
38
|
+
}
|
|
39
|
+
/** @experimental */
|
|
40
|
+
export declare const FORGES: Record<ForgePrefix, Forge>;
|
|
41
|
+
/** @experimental */
|
|
42
|
+
export declare const forgeForHostname: (hostname: string) => Forge | undefined;
|
|
43
|
+
/** @experimental */
|
|
44
|
+
export declare const parseForgeCoordinate: (forge: ForgePrefix, body: string) => Result.Result<ForgeCoordinate, {
|
|
45
|
+
readonly reason: string;
|
|
46
|
+
}>;
|
|
47
|
+
/** @experimental */
|
|
48
|
+
export declare const printForgeCoordinateBody: (coordinate: ForgeCoordinate) => string;
|
|
49
|
+
/** @experimental */
|
|
50
|
+
export declare const printForgeCoordinate: (coordinate: ForgeCoordinate) => string;
|
|
51
|
+
/** @experimental */
|
|
52
|
+
export declare const forgeCloneUrl: (coordinate: ForgeCoordinate) => URL;
|
|
53
|
+
/** @experimental */
|
|
54
|
+
export declare const forgeCoordinateFromGitUrl: (url: URL, ref: Option.Option<string>, subPath: Option.Option<string>) => Option.Option<ForgeCoordinate>;
|
|
55
|
+
/** @experimental */
|
|
56
|
+
export declare const parseForgeBrowserUrl: (url: URL) => Option.Option<ForgeCoordinate>;
|
|
57
|
+
export {};
|
|
22
58
|
//# sourceMappingURL=forge-grammar.d.ts.map
|
|
@@ -1,50 +1,170 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Forge coordinate, clone URL, and browser URL grammar.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
* only the string grammar lives here.
|
|
4
|
+
* Probing and acquisition stay with source resolution; the model owns the
|
|
5
|
+
* strings and URLs that identify each forge repository.
|
|
7
6
|
*
|
|
8
7
|
* @experimental This API is unstable and may change without notice.
|
|
9
8
|
* @packageDocumentation
|
|
10
9
|
*/
|
|
11
10
|
import * as Option from "effect/Option";
|
|
11
|
+
import * as Result from "effect/Result";
|
|
12
|
+
import * as Schema from "effect/Schema";
|
|
13
|
+
import { SourceNamespaceSchema, SourceRefSchema, SourceSubPathSchema } from "./types.js";
|
|
12
14
|
/** @experimental */
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
export const FORGE_PREFIXES = ["github", "gitlab", "bitbucket", "azurerepos"];
|
|
16
|
+
/** @experimental */
|
|
17
|
+
export const isForgePrefix = (value) => FORGE_PREFIXES.some((prefix) => prefix === value);
|
|
18
|
+
const segments = (pathname) => pathname.split("/").filter((segment) => segment.length > 0);
|
|
19
|
+
const withoutGit = (name) => (name.endsWith(".git") ? name.slice(0, -4) : name);
|
|
20
|
+
const hostedRepositoryFromCloneUrl = (pathname) => {
|
|
21
|
+
const parts = segments(pathname);
|
|
22
|
+
const last = parts.at(-1);
|
|
23
|
+
return last === undefined || parts.length < 2
|
|
24
|
+
? undefined
|
|
25
|
+
: [...parts.slice(0, -1), withoutGit(last)].join("/");
|
|
26
|
+
};
|
|
27
|
+
const hostedBrowserPath = (pathname, marker) => {
|
|
28
|
+
const pattern = marker === "tree"
|
|
29
|
+
? /^\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/tree\/([^/]+)(?:\/(.+))?)?$/u
|
|
30
|
+
: /^\/([^/]+)\/([^/]+?)(?:\.git)?(?:\/src\/([^/]+)(?:\/(.+))?)?$/u;
|
|
31
|
+
const match = pattern.exec(pathname);
|
|
32
|
+
if (match?.[1] === undefined || match[2] === undefined)
|
|
33
|
+
return undefined;
|
|
34
|
+
return {
|
|
35
|
+
repository: `${match[1]}/${match[2]}`,
|
|
36
|
+
...(match[3] === undefined ? {} : { ref: match[3] }),
|
|
37
|
+
...(match[4] === undefined ? {} : { subPath: match[4] }),
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const gitlabBrowserPath = (pathname) => {
|
|
41
|
+
const marker = "/-/tree/";
|
|
42
|
+
const markerIndex = pathname.indexOf(marker);
|
|
43
|
+
const repositoryParts = segments(markerIndex < 0 ? pathname : pathname.slice(0, markerIndex));
|
|
44
|
+
const last = repositoryParts.at(-1);
|
|
45
|
+
if (last === undefined || repositoryParts.length < 2)
|
|
46
|
+
return undefined;
|
|
47
|
+
const treePath = markerIndex < 0 ? [] : pathname.slice(markerIndex + marker.length).split("/");
|
|
48
|
+
const subPath = treePath.slice(1).join("/");
|
|
49
|
+
return {
|
|
50
|
+
repository: [...repositoryParts.slice(0, -1), withoutGit(last)].join("/"),
|
|
51
|
+
...(treePath[0] === undefined ? {} : { ref: treePath[0] }),
|
|
52
|
+
...(subPath.length === 0 ? {} : { subPath }),
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
const azureRepositoryFromCloneUrl = (pathname) => {
|
|
56
|
+
const parts = segments(pathname);
|
|
57
|
+
return parts.length === 4 && parts[2] === "_git"
|
|
58
|
+
? `${parts[0]}/${parts[1]}/${withoutGit(parts[3] ?? "")}`
|
|
59
|
+
: undefined;
|
|
60
|
+
};
|
|
61
|
+
const azureBrowserPath = (pathname) => {
|
|
62
|
+
const match = /^\/([^/]+)\/([^/]+)\/_git\/([^/]+?)(?:\.git)?$/u.exec(pathname);
|
|
63
|
+
return match?.[1] === undefined || match[2] === undefined || match[3] === undefined
|
|
64
|
+
? undefined
|
|
65
|
+
: { repository: `${match[1]}/${match[2]}/${match[3]}` };
|
|
66
|
+
};
|
|
67
|
+
const hostedForge = (prefix, hostname, parseBrowserPath) => ({
|
|
68
|
+
prefix,
|
|
69
|
+
hostname,
|
|
70
|
+
repositorySegments: (count) => count >= 2,
|
|
71
|
+
cloneUrl: (repository) => new URL(`https://${hostname}/${repository}.git`),
|
|
72
|
+
repositoryFromCloneUrl: hostedRepositoryFromCloneUrl,
|
|
73
|
+
parseBrowserPath,
|
|
74
|
+
});
|
|
75
|
+
/** @experimental */
|
|
76
|
+
export const FORGES = {
|
|
77
|
+
github: hostedForge("github", "github.com", (pathname) => hostedBrowserPath(pathname, "tree")),
|
|
78
|
+
gitlab: hostedForge("gitlab", "gitlab.com", gitlabBrowserPath),
|
|
79
|
+
bitbucket: hostedForge("bitbucket", "bitbucket.org", (pathname) => hostedBrowserPath(pathname, "src")),
|
|
80
|
+
azurerepos: {
|
|
81
|
+
prefix: "azurerepos",
|
|
82
|
+
hostname: "dev.azure.com",
|
|
83
|
+
repositorySegments: (count) => count === 3,
|
|
84
|
+
cloneUrl: (repository) => {
|
|
85
|
+
const [organization, project, repo] = repository.split("/");
|
|
86
|
+
return new URL(`https://dev.azure.com/${organization}/${project}/_git/${repo}`);
|
|
87
|
+
},
|
|
88
|
+
repositoryFromCloneUrl: azureRepositoryFromCloneUrl,
|
|
89
|
+
parseBrowserPath: azureBrowserPath,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
/** @experimental */
|
|
93
|
+
export const forgeForHostname = (hostname) => Object.values(FORGES).find((forge) => forge.hostname === hostname);
|
|
94
|
+
const decodeNamespace = Schema.decodeUnknownResult(SourceNamespaceSchema);
|
|
95
|
+
const decodeSubPath = Schema.decodeUnknownResult(SourceSubPathSchema);
|
|
96
|
+
const decodeRef = Schema.decodeUnknownResult(SourceRefSchema);
|
|
97
|
+
const validCoordinate = (coordinate) => FORGES[coordinate.forge].repositorySegments(coordinate.repository.split("/").length) &&
|
|
98
|
+
Result.isSuccess(decodeNamespace(coordinate.repository)) &&
|
|
99
|
+
(Option.isNone(coordinate.subPath) ||
|
|
100
|
+
Result.isSuccess(decodeSubPath(coordinate.subPath.value))) &&
|
|
101
|
+
(Option.isNone(coordinate.ref) || Result.isSuccess(decodeRef(coordinate.ref.value)));
|
|
102
|
+
const splitRef = (input) => {
|
|
103
|
+
const refIndex = input.lastIndexOf("@");
|
|
104
|
+
if (refIndex <= 0)
|
|
105
|
+
return { coordinate: input };
|
|
106
|
+
const ref = input.slice(refIndex + 1);
|
|
107
|
+
const subPathMarker = input.indexOf("//");
|
|
108
|
+
const isAtPathSegment = subPathMarker !== -1 &&
|
|
109
|
+
refIndex > subPathMarker + 1 &&
|
|
110
|
+
input[refIndex - 1] === "/" &&
|
|
111
|
+
ref.includes("/");
|
|
112
|
+
return isAtPathSegment ? { coordinate: input } : { coordinate: input.slice(0, refIndex), ref };
|
|
20
113
|
};
|
|
21
114
|
/** @experimental */
|
|
22
|
-
export const
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
115
|
+
export const parseForgeCoordinate = (forge, body) => {
|
|
116
|
+
const { coordinate, ref } = splitRef(body);
|
|
117
|
+
const marker = coordinate.indexOf("//");
|
|
118
|
+
const repository = marker < 0 ? coordinate : coordinate.slice(0, marker);
|
|
119
|
+
const subPath = marker < 0 ? undefined : coordinate.slice(marker + 2);
|
|
120
|
+
const parsed = {
|
|
121
|
+
forge,
|
|
122
|
+
repository,
|
|
123
|
+
ref: Option.fromUndefinedOr(ref),
|
|
124
|
+
subPath: Option.fromUndefinedOr(subPath),
|
|
125
|
+
};
|
|
126
|
+
return validCoordinate(parsed)
|
|
127
|
+
? Result.succeed(parsed)
|
|
128
|
+
: Result.fail({ reason: `Expected valid ${forge} repository[//subpath][@ref]` });
|
|
29
129
|
};
|
|
30
130
|
/** @experimental */
|
|
31
|
-
export const
|
|
32
|
-
let
|
|
33
|
-
if (Option.isSome(
|
|
34
|
-
|
|
35
|
-
if (Option.isSome(
|
|
36
|
-
|
|
37
|
-
return
|
|
131
|
+
export const printForgeCoordinateBody = (coordinate) => {
|
|
132
|
+
let body = coordinate.repository;
|
|
133
|
+
if (Option.isSome(coordinate.subPath))
|
|
134
|
+
body += `//${coordinate.subPath.value}`;
|
|
135
|
+
if (Option.isSome(coordinate.ref))
|
|
136
|
+
body += `@${coordinate.ref.value}`;
|
|
137
|
+
return body;
|
|
38
138
|
};
|
|
39
139
|
/** @experimental */
|
|
40
|
-
export const
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
140
|
+
export const printForgeCoordinate = (coordinate) => `${coordinate.forge}:${printForgeCoordinateBody(coordinate)}`;
|
|
141
|
+
/** @experimental */
|
|
142
|
+
export const forgeCloneUrl = (coordinate) => FORGES[coordinate.forge].cloneUrl(coordinate.repository);
|
|
143
|
+
/** @experimental */
|
|
144
|
+
export const forgeCoordinateFromGitUrl = (url, ref, subPath) => {
|
|
145
|
+
const forge = forgeForHostname(url.hostname);
|
|
146
|
+
if (forge === undefined)
|
|
147
|
+
return Option.none();
|
|
148
|
+
const repository = forge.repositoryFromCloneUrl(url.pathname);
|
|
149
|
+
if (repository === undefined)
|
|
150
|
+
return Option.none();
|
|
151
|
+
const coordinate = { forge: forge.prefix, repository, ref, subPath };
|
|
152
|
+
return validCoordinate(coordinate) ? Option.some(coordinate) : Option.none();
|
|
47
153
|
};
|
|
48
154
|
/** @experimental */
|
|
49
|
-
export const
|
|
155
|
+
export const parseForgeBrowserUrl = (url) => {
|
|
156
|
+
const forge = forgeForHostname(url.hostname);
|
|
157
|
+
if (forge === undefined)
|
|
158
|
+
return Option.none();
|
|
159
|
+
const parsed = forge.parseBrowserPath(url.pathname);
|
|
160
|
+
if (parsed === undefined)
|
|
161
|
+
return Option.none();
|
|
162
|
+
const coordinate = {
|
|
163
|
+
forge: forge.prefix,
|
|
164
|
+
repository: parsed.repository,
|
|
165
|
+
ref: Option.fromUndefinedOr(parsed.ref),
|
|
166
|
+
subPath: Option.fromUndefinedOr(parsed.subPath),
|
|
167
|
+
};
|
|
168
|
+
return validCoordinate(coordinate) ? Option.some(coordinate) : Option.none();
|
|
169
|
+
};
|
|
50
170
|
//# sourceMappingURL=forge-grammar.js.map
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
* @packageDocumentation
|
|
10
10
|
*/
|
|
11
11
|
import * as Option from "effect/Option";
|
|
12
|
+
import { type ForgeCoordinate, type ForgePrefix } from "./forge-grammar.js";
|
|
12
13
|
import type { VersionRange } from "../version-constraints/version-constraints.js";
|
|
13
14
|
import type { ExtensionName, ExtensionType, ExtensionTypePlural } from "../extensions/common.js";
|
|
14
15
|
import type { Handle } from "../extensions/handle.js";
|
|
@@ -45,10 +46,7 @@ type GitScpAddress = {
|
|
|
45
46
|
/** An `owner/repo[//path][@ref]` style pattern containing `/` (not a URL or file path). */
|
|
46
47
|
type SlashPattern = {
|
|
47
48
|
readonly pattern: "slash-pattern";
|
|
48
|
-
readonly
|
|
49
|
-
readonly second: string;
|
|
50
|
-
readonly third: Option.Option<string>;
|
|
51
|
-
readonly ref: Option.Option<string>;
|
|
49
|
+
readonly coordinate: ForgeCoordinate;
|
|
52
50
|
};
|
|
53
51
|
/** A local filesystem path matching `LOCAL_PATH_PATTERN`. */
|
|
54
52
|
type FilePathPattern = {
|
|
@@ -58,7 +56,7 @@ type FilePathPattern = {
|
|
|
58
56
|
/** A shorthand prefixed input: `<prefix>:...` where prefix is a known source provider. */
|
|
59
57
|
export type ShorthandInput = {
|
|
60
58
|
readonly pattern: "shorthand-input";
|
|
61
|
-
readonly prefix:
|
|
59
|
+
readonly prefix: ForgePrefix;
|
|
62
60
|
readonly remainingInput: string;
|
|
63
61
|
};
|
|
64
62
|
/** A glob pattern containing `*` wildcards (e.g. `effect-*`). */
|
|
@@ -10,14 +10,13 @@
|
|
|
10
10
|
*/
|
|
11
11
|
import * as Option from "effect/Option";
|
|
12
12
|
import * as Result from "effect/Result";
|
|
13
|
+
import { isForgePrefix, parseForgeCoordinate, } from "./forge-grammar.js";
|
|
13
14
|
import { parseFqn } from "../extensions/fqn.js";
|
|
14
15
|
import { parseSourceQualifiedRegistrySourcePatternParts } from "../extensions/registry-source.js";
|
|
15
16
|
/** Matches: ./path, ../path, /path, ~/path, ~\path, or Windows paths like C:\path */
|
|
16
17
|
const LOCAL_PATH_PATTERN = /^(?:\.\.?\/|\/|~\/|~\\|[A-Za-z]:[\\/])/;
|
|
17
18
|
/** SCP-style: `user@host:path` — no `://` scheme. */
|
|
18
19
|
const SCP_PATTERN = /^([^@]+)@([^:]+):(.+)$/;
|
|
19
|
-
/** Known shorthand prefixes. */
|
|
20
|
-
const SHORTHAND_PREFIXES = new Set(["github", "gitlab", "bitbucket", "azurerepos"]);
|
|
21
20
|
/** Simple name: alphanumeric with hyphens, no leading/trailing hyphen. */
|
|
22
21
|
const NAME_PATTERN = /^[a-zA-Z0-9](?:[a-zA-Z0-9-]*[a-zA-Z0-9])?$/;
|
|
23
22
|
/**
|
|
@@ -66,10 +65,11 @@ export const parseInputPattern = (input) => {
|
|
|
66
65
|
}
|
|
67
66
|
// 4. Shorthand prefix (github:..., gitlab:..., etc.) — must check before URL
|
|
68
67
|
const colonIndex = input.indexOf(":");
|
|
69
|
-
|
|
68
|
+
const prefix = input.slice(0, colonIndex);
|
|
69
|
+
if (colonIndex > 0 && isForgePrefix(prefix)) {
|
|
70
70
|
return Option.some(wrap({
|
|
71
71
|
pattern: "shorthand-input",
|
|
72
|
-
prefix
|
|
72
|
+
prefix,
|
|
73
73
|
remainingInput: input.slice(colonIndex + 1),
|
|
74
74
|
}));
|
|
75
75
|
}
|
|
@@ -90,34 +90,17 @@ export const parseInputPattern = (input) => {
|
|
|
90
90
|
}
|
|
91
91
|
// 7. Slash pattern (`owner/repo[//path][@ref]`)
|
|
92
92
|
if (input.includes("/")) {
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
const
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
const second = segments.at(1);
|
|
103
|
-
if (first !== undefined &&
|
|
104
|
-
second !== undefined &&
|
|
105
|
-
segments.length === 2 &&
|
|
106
|
-
NAME_PATTERN.test(first) &&
|
|
107
|
-
NAME_PATTERN.test(second) &&
|
|
108
|
-
(ref === undefined || (ref.length > 0 && !ref.includes("/"))) &&
|
|
109
|
-
(subPath === undefined ||
|
|
110
|
-
(subPath.length > 0 &&
|
|
111
|
-
subPath.split("/").every((segment) => segment.length > 0 && segment !== "..")))) {
|
|
112
|
-
return Option.some(wrap({
|
|
113
|
-
pattern: "slash-pattern",
|
|
114
|
-
first,
|
|
115
|
-
second,
|
|
116
|
-
third: Option.fromUndefinedOr(subPath),
|
|
117
|
-
ref: Option.fromUndefinedOr(ref),
|
|
118
|
-
}));
|
|
93
|
+
const parsed = parseForgeCoordinate("github", input);
|
|
94
|
+
if (Result.isFailure(parsed))
|
|
95
|
+
return Option.none();
|
|
96
|
+
const coordinate = parsed.success;
|
|
97
|
+
const segments = coordinate.repository.split("/");
|
|
98
|
+
if (segments.length !== 2 ||
|
|
99
|
+
!segments.every((segment) => NAME_PATTERN.test(segment)) ||
|
|
100
|
+
Option.exists(coordinate.ref, (ref) => ref.includes("/"))) {
|
|
101
|
+
return Option.none();
|
|
119
102
|
}
|
|
120
|
-
return Option.
|
|
103
|
+
return Option.some(wrap({ pattern: "slash-pattern", coordinate }));
|
|
121
104
|
}
|
|
122
105
|
// 8. Glob pattern (contains `*` wildcard)
|
|
123
106
|
if (input.includes("*")) {
|
|
@@ -6,7 +6,14 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import * as Option from "effect/Option";
|
|
8
8
|
import { formatFqn } from "../extensions/fqn.js";
|
|
9
|
-
import {
|
|
9
|
+
import { forgeCoordinateFromGitUrl, printForgeCoordinate } from "./forge-grammar.js";
|
|
10
|
+
const printLocalSource = (source) => {
|
|
11
|
+
if (source.path === "." || source.path === "..")
|
|
12
|
+
return `${source.path}/`;
|
|
13
|
+
return /^(?:\.\.?\/|\/|~[\\/]|[A-Za-z]:[\\/])/.test(source.path)
|
|
14
|
+
? source.path
|
|
15
|
+
: `./${source.path}`;
|
|
16
|
+
};
|
|
10
17
|
/**
|
|
11
18
|
* Print source params as their canonical shorthand string.
|
|
12
19
|
*
|
|
@@ -17,40 +24,14 @@ export const printSourceParams = (source) => {
|
|
|
17
24
|
case "local":
|
|
18
25
|
return printLocalSource(source);
|
|
19
26
|
case "git": {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
shorthand += `//${source.subPath.value}`;
|
|
29
|
-
if (Option.isSome(source.ref))
|
|
30
|
-
shorthand += `@${source.ref.value}`;
|
|
31
|
-
return shorthand;
|
|
32
|
-
}
|
|
33
|
-
const lastSegment = repositorySegments.at(-1);
|
|
34
|
-
const repo = lastSegment?.endsWith(".git") ? lastSegment.slice(0, -4) : lastSegment;
|
|
35
|
-
const sourcePrefix = source.url.hostname === "github.com"
|
|
36
|
-
? "github"
|
|
37
|
-
: source.url.hostname === "gitlab.com"
|
|
38
|
-
? "gitlab"
|
|
39
|
-
: source.url.hostname === "bitbucket.org"
|
|
40
|
-
? "bitbucket"
|
|
41
|
-
: undefined;
|
|
42
|
-
if (sourcePrefix !== undefined && repo !== undefined && repositorySegments.length >= 2) {
|
|
43
|
-
const owner = repositorySegments.slice(0, -1).join("/");
|
|
44
|
-
let shorthand = `${sourcePrefix}:${owner}/${repo}`;
|
|
45
|
-
if (Option.isSome(source.subPath))
|
|
46
|
-
shorthand += `//${source.subPath.value}`;
|
|
47
|
-
if (Option.isSome(source.ref))
|
|
48
|
-
shorthand += `@${source.ref.value}`;
|
|
49
|
-
return shorthand;
|
|
50
|
-
}
|
|
51
|
-
const url = new URL(source.url.href);
|
|
52
|
-
url.hash = Option.getOrElse(source.ref, () => "");
|
|
53
|
-
return url.href;
|
|
27
|
+
return Option.match(forgeCoordinateFromGitUrl(source.url, source.ref, source.subPath), {
|
|
28
|
+
onSome: printForgeCoordinate,
|
|
29
|
+
onNone: () => {
|
|
30
|
+
const url = new URL(source.url.href);
|
|
31
|
+
url.hash = Option.getOrElse(source.ref, () => "");
|
|
32
|
+
return url.href;
|
|
33
|
+
},
|
|
34
|
+
});
|
|
54
35
|
}
|
|
55
36
|
case "registry": {
|
|
56
37
|
return source.sourceName ?? ("name" in source ? String(source.name) : "agentxm");
|