@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.
Files changed (154) hide show
  1. package/dist/src/unstable/agent-capabilities/catalog.d.ts +19197 -4977
  2. package/dist/src/unstable/agent-capabilities/data/agents/adal.d.ts +31 -3
  3. package/dist/src/unstable/agent-capabilities/data/agents/adal.js +27 -3
  4. package/dist/src/unstable/agent-capabilities/data/agents/aider-desk.d.ts +19 -2
  5. package/dist/src/unstable/agent-capabilities/data/agents/aider-desk.js +17 -2
  6. package/dist/src/unstable/agent-capabilities/data/agents/amp.d.ts +56 -4
  7. package/dist/src/unstable/agent-capabilities/data/agents/amp.js +52 -4
  8. package/dist/src/unstable/agent-capabilities/data/agents/antigravity-cli.d.ts +68 -6
  9. package/dist/src/unstable/agent-capabilities/data/agents/antigravity-cli.js +61 -6
  10. package/dist/src/unstable/agent-capabilities/data/agents/antigravity.d.ts +179 -53
  11. package/dist/src/unstable/agent-capabilities/data/agents/antigravity.js +152 -42
  12. package/dist/src/unstable/agent-capabilities/data/agents/augment.d.ts +176 -64
  13. package/dist/src/unstable/agent-capabilities/data/agents/augment.js +162 -64
  14. package/dist/src/unstable/agent-capabilities/data/agents/chatgpt.d.ts +3 -1
  15. package/dist/src/unstable/agent-capabilities/data/agents/chatgpt.js +3 -1
  16. package/dist/src/unstable/agent-capabilities/data/agents/claude-ai.d.ts +2 -0
  17. package/dist/src/unstable/agent-capabilities/data/agents/claude-ai.js +2 -0
  18. package/dist/src/unstable/agent-capabilities/data/agents/claude-code.d.ts +238 -75
  19. package/dist/src/unstable/agent-capabilities/data/agents/claude-code.js +222 -78
  20. package/dist/src/unstable/agent-capabilities/data/agents/cline.d.ts +115 -55
  21. package/dist/src/unstable/agent-capabilities/data/agents/cline.js +100 -47
  22. package/dist/src/unstable/agent-capabilities/data/agents/codearts-agent.d.ts +140 -63
  23. package/dist/src/unstable/agent-capabilities/data/agents/codearts-agent.js +123 -52
  24. package/dist/src/unstable/agent-capabilities/data/agents/codebuddy.d.ts +211 -76
  25. package/dist/src/unstable/agent-capabilities/data/agents/codebuddy.js +197 -79
  26. package/dist/src/unstable/agent-capabilities/data/agents/codestudio.d.ts +46 -4
  27. package/dist/src/unstable/agent-capabilities/data/agents/codestudio.js +40 -4
  28. package/dist/src/unstable/agent-capabilities/data/agents/codex.d.ts +242 -68
  29. package/dist/src/unstable/agent-capabilities/data/agents/codex.js +213 -59
  30. package/dist/src/unstable/agent-capabilities/data/agents/command-code.d.ts +169 -68
  31. package/dist/src/unstable/agent-capabilities/data/agents/command-code.js +156 -64
  32. package/dist/src/unstable/agent-capabilities/data/agents/continue.d.ts +79 -7
  33. package/dist/src/unstable/agent-capabilities/data/agents/continue.js +75 -7
  34. package/dist/src/unstable/agent-capabilities/data/agents/cortex.d.ts +116 -9
  35. package/dist/src/unstable/agent-capabilities/data/agents/cortex.js +110 -9
  36. package/dist/src/unstable/agent-capabilities/data/agents/cowork.d.ts +4 -0
  37. package/dist/src/unstable/agent-capabilities/data/agents/cowork.js +4 -0
  38. package/dist/src/unstable/agent-capabilities/data/agents/crush.d.ts +165 -60
  39. package/dist/src/unstable/agent-capabilities/data/agents/crush.js +151 -54
  40. package/dist/src/unstable/agent-capabilities/data/agents/cursor.d.ts +230 -55
  41. package/dist/src/unstable/agent-capabilities/data/agents/cursor.js +205 -51
  42. package/dist/src/unstable/agent-capabilities/data/agents/deepagents.d.ts +100 -5
  43. package/dist/src/unstable/agent-capabilities/data/agents/deepagents.js +86 -5
  44. package/dist/src/unstable/agent-capabilities/data/agents/devin.d.ts +224 -77
  45. package/dist/src/unstable/agent-capabilities/data/agents/devin.js +203 -70
  46. package/dist/src/unstable/agent-capabilities/data/agents/dexto.d.ts +28 -2
  47. package/dist/src/unstable/agent-capabilities/data/agents/dexto.js +26 -2
  48. package/dist/src/unstable/agent-capabilities/data/agents/droid.d.ts +93 -8
  49. package/dist/src/unstable/agent-capabilities/data/agents/droid.js +87 -8
  50. package/dist/src/unstable/agent-capabilities/data/agents/firebender.d.ts +119 -8
  51. package/dist/src/unstable/agent-capabilities/data/agents/firebender.js +112 -13
  52. package/dist/src/unstable/agent-capabilities/data/agents/forgecode.d.ts +94 -6
  53. package/dist/src/unstable/agent-capabilities/data/agents/forgecode.js +82 -6
  54. package/dist/src/unstable/agent-capabilities/data/agents/gemini-app.d.ts +2 -0
  55. package/dist/src/unstable/agent-capabilities/data/agents/gemini-app.js +2 -0
  56. package/dist/src/unstable/agent-capabilities/data/agents/gemini-cli.d.ts +218 -56
  57. package/dist/src/unstable/agent-capabilities/data/agents/gemini-cli.js +193 -55
  58. package/dist/src/unstable/agent-capabilities/data/agents/github-copilot-cli.d.ts +201 -66
  59. package/dist/src/unstable/agent-capabilities/data/agents/github-copilot-cli.js +188 -69
  60. package/dist/src/unstable/agent-capabilities/data/agents/goose.d.ts +37 -3
  61. package/dist/src/unstable/agent-capabilities/data/agents/goose.js +34 -5
  62. package/dist/src/unstable/agent-capabilities/data/agents/grok-cli.d.ts +98 -6
  63. package/dist/src/unstable/agent-capabilities/data/agents/grok-cli.js +83 -6
  64. package/dist/src/unstable/agent-capabilities/data/agents/hermes.d.ts +105 -42
  65. package/dist/src/unstable/agent-capabilities/data/agents/hermes.js +87 -28
  66. package/dist/src/unstable/agent-capabilities/data/agents/ibm-bob.d.ts +173 -61
  67. package/dist/src/unstable/agent-capabilities/data/agents/ibm-bob.js +152 -52
  68. package/dist/src/unstable/agent-capabilities/data/agents/iflow-cli.d.ts +47 -5
  69. package/dist/src/unstable/agent-capabilities/data/agents/iflow-cli.js +41 -5
  70. package/dist/src/unstable/agent-capabilities/data/agents/junie.d.ts +130 -42
  71. package/dist/src/unstable/agent-capabilities/data/agents/junie.js +121 -39
  72. package/dist/src/unstable/agent-capabilities/data/agents/kilo.d.ts +187 -65
  73. package/dist/src/unstable/agent-capabilities/data/agents/kilo.js +169 -62
  74. package/dist/src/unstable/agent-capabilities/data/agents/kimi-cli.d.ts +147 -60
  75. package/dist/src/unstable/agent-capabilities/data/agents/kimi-cli.js +134 -53
  76. package/dist/src/unstable/agent-capabilities/data/agents/kiro-cli.d.ts +138 -50
  77. package/dist/src/unstable/agent-capabilities/data/agents/kiro-cli.js +121 -39
  78. package/dist/src/unstable/agent-capabilities/data/agents/kode.d.ts +45 -5
  79. package/dist/src/unstable/agent-capabilities/data/agents/kode.js +39 -5
  80. package/dist/src/unstable/agent-capabilities/data/agents/lingma.d.ts +19 -2
  81. package/dist/src/unstable/agent-capabilities/data/agents/lingma.js +17 -2
  82. package/dist/src/unstable/agent-capabilities/data/agents/mcpjam.d.ts +16 -1
  83. package/dist/src/unstable/agent-capabilities/data/agents/mcpjam.js +14 -1
  84. package/dist/src/unstable/agent-capabilities/data/agents/mistral-vibe.d.ts +93 -8
  85. package/dist/src/unstable/agent-capabilities/data/agents/mistral-vibe.js +87 -8
  86. package/dist/src/unstable/agent-capabilities/data/agents/mux.d.ts +46 -4
  87. package/dist/src/unstable/agent-capabilities/data/agents/mux.js +40 -4
  88. package/dist/src/unstable/agent-capabilities/data/agents/neovate.d.ts +111 -59
  89. package/dist/src/unstable/agent-capabilities/data/agents/neovate.js +97 -50
  90. package/dist/src/unstable/agent-capabilities/data/agents/ona.d.ts +41 -4
  91. package/dist/src/unstable/agent-capabilities/data/agents/ona.js +37 -4
  92. package/dist/src/unstable/agent-capabilities/data/agents/openclaw.d.ts +14 -1
  93. package/dist/src/unstable/agent-capabilities/data/agents/openclaw.js +12 -1
  94. package/dist/src/unstable/agent-capabilities/data/agents/opencode.d.ts +286 -14
  95. package/dist/src/unstable/agent-capabilities/data/agents/opencode.js +261 -16
  96. package/dist/src/unstable/agent-capabilities/data/agents/openhands.d.ts +53 -4
  97. package/dist/src/unstable/agent-capabilities/data/agents/openhands.js +49 -4
  98. package/dist/src/unstable/agent-capabilities/data/agents/pi.d.ts +69 -2
  99. package/dist/src/unstable/agent-capabilities/data/agents/pi.js +56 -2
  100. package/dist/src/unstable/agent-capabilities/data/agents/pochi.d.ts +96 -44
  101. package/dist/src/unstable/agent-capabilities/data/agents/pochi.js +81 -33
  102. package/dist/src/unstable/agent-capabilities/data/agents/qoder-cn.d.ts +70 -6
  103. package/dist/src/unstable/agent-capabilities/data/agents/qoder-cn.js +75 -7
  104. package/dist/src/unstable/agent-capabilities/data/agents/qoder.d.ts +196 -72
  105. package/dist/src/unstable/agent-capabilities/data/agents/qoder.js +182 -72
  106. package/dist/src/unstable/agent-capabilities/data/agents/qwen-code.d.ts +169 -57
  107. package/dist/src/unstable/agent-capabilities/data/agents/qwen-code.js +154 -56
  108. package/dist/src/unstable/agent-capabilities/data/agents/replit.d.ts +16 -1
  109. package/dist/src/unstable/agent-capabilities/data/agents/replit.js +14 -1
  110. package/dist/src/unstable/agent-capabilities/data/agents/roo.d.ts +60 -7
  111. package/dist/src/unstable/agent-capabilities/data/agents/roo.js +51 -7
  112. package/dist/src/unstable/agent-capabilities/data/agents/rovodev.d.ts +70 -6
  113. package/dist/src/unstable/agent-capabilities/data/agents/rovodev.js +64 -6
  114. package/dist/src/unstable/agent-capabilities/data/agents/tabnine-cli.d.ts +92 -7
  115. package/dist/src/unstable/agent-capabilities/data/agents/tabnine-cli.js +85 -7
  116. package/dist/src/unstable/agent-capabilities/data/agents/trae-cn.d.ts +72 -33
  117. package/dist/src/unstable/agent-capabilities/data/agents/trae-cn.js +64 -29
  118. package/dist/src/unstable/agent-capabilities/data/agents/trae.d.ts +72 -33
  119. package/dist/src/unstable/agent-capabilities/data/agents/trae.js +64 -29
  120. package/dist/src/unstable/agent-capabilities/data/agents/warp.d.ts +31 -3
  121. package/dist/src/unstable/agent-capabilities/data/agents/warp.js +27 -3
  122. package/dist/src/unstable/agent-capabilities/data/agents/windsurf.d.ts +126 -41
  123. package/dist/src/unstable/agent-capabilities/data/agents/windsurf.js +110 -39
  124. package/dist/src/unstable/agent-capabilities/data/agents/zed.d.ts +31 -3
  125. package/dist/src/unstable/agent-capabilities/data/agents/zed.js +27 -3
  126. package/dist/src/unstable/agent-capabilities/data/agents/zencoder.d.ts +41 -5
  127. package/dist/src/unstable/agent-capabilities/data/agents/zencoder.js +37 -5
  128. package/dist/src/unstable/agent-capabilities/data/agents/zenflow.d.ts +34 -2
  129. package/dist/src/unstable/agent-capabilities/data/agents/zenflow.js +31 -4
  130. package/dist/src/unstable/agent-capabilities/derive.js +37 -60
  131. package/dist/src/unstable/agent-capabilities/identity.d.ts +2 -0
  132. package/dist/src/unstable/agent-capabilities/identity.js +3 -0
  133. package/dist/src/unstable/agent-capabilities/index.d.ts +2 -2
  134. package/dist/src/unstable/agent-capabilities/index.js +2 -2
  135. package/dist/src/unstable/agent-capabilities/schema.d.ts +769 -761
  136. package/dist/src/unstable/agent-capabilities/schema.js +188 -91
  137. package/dist/src/unstable/agents/registry.d.ts +3 -17
  138. package/dist/src/unstable/agents/registry.js +2 -29
  139. package/dist/src/unstable/agents/types.d.ts +19 -53
  140. package/dist/src/unstable/agents/types.js +2 -4
  141. package/dist/src/unstable/extensions/common.d.ts +1 -2
  142. package/dist/src/unstable/extensions/common.js +1 -2
  143. package/dist/src/unstable/extensions/name-patterns.d.ts +5 -3
  144. package/dist/src/unstable/extensions/name-patterns.js +31 -32
  145. package/dist/src/unstable/path-types.d.ts +6 -0
  146. package/dist/src/unstable/path-types.js +20 -0
  147. package/dist/src/unstable/sources/forge-grammar.d.ts +46 -10
  148. package/dist/src/unstable/sources/forge-grammar.js +153 -33
  149. package/dist/src/unstable/sources/parser.d.ts +3 -5
  150. package/dist/src/unstable/sources/parser.js +14 -31
  151. package/dist/src/unstable/sources/printer.js +16 -35
  152. package/dist/src/unstable/sources/types.d.ts +1 -93
  153. package/dist/src/unstable/sources/types.js +1 -48
  154. 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
- /** @experimental This API is unstable and may change without notice. */
14
- export const AGENT_IDS = [...CONFIGURABLE_AGENT_IDS, "universal"];
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
- * Synthetic materialization targets such as `universal` are known agents, but
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
- * Synthetic materialization targets such as `universal` are known agents, but
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
- * Expand a glob pattern against a list of names.
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 names - Available names to match against
17
- * @returns Matching names in their original order
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
- * Expand a glob pattern against a list of names.
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 names - Available names to match against
17
- * @returns Matching names in their original order
16
+ * @param name - The name to check
17
+ * @returns Whether the complete name matches
18
18
  */
19
- export const expandGlob = (pattern, names) => {
20
- const matches = (name) => {
21
- let patternIndex = 0;
22
- let nameIndex = 0;
23
- let wildcardIndex = -1;
24
- let wildcardNameIndex = 0;
25
- while (nameIndex < name.length) {
26
- const token = pattern[patternIndex];
27
- if (token !== undefined && token !== "*" && token === name[nameIndex]) {
28
- patternIndex += 1;
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
- while (pattern[patternIndex] === "*") {
30
+ else if (token === "*") {
31
+ wildcardIndex = patternIndex;
32
+ wildcardNameIndex = nameIndex;
46
33
  patternIndex += 1;
47
34
  }
48
- return patternIndex === pattern.length;
49
- };
50
- return names.filter(matches);
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
- * Pure per-forge source shorthand printing grammar.
2
+ * Forge coordinate, clone URL, and browser URL grammar.
3
3
  *
4
- * Each printer formats source params as the forge's canonical shorthand
5
- * string. Probing and acquisition stay with the source-resolution providers;
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 type { AzureReposSourceParams, BitbucketSourceParams, GitHubSourceParams, GitLabSourceParams, LocalSourceParams } from "./types.js";
10
+ import * as Option from "effect/Option";
11
+ import * as Result from "effect/Result";
12
12
  /** @experimental */
13
- export declare const printGitHubSource: (source: GitHubSourceParams, sourceName?: string) => string;
13
+ export declare const FORGE_PREFIXES: readonly ["github", "gitlab", "bitbucket", "azurerepos"];
14
14
  /** @experimental */
15
- export declare const printGitLabSource: (source: GitLabSourceParams, sourceName?: string) => string;
15
+ export type ForgePrefix = (typeof FORGE_PREFIXES)[number];
16
16
  /** @experimental */
17
- export declare const printBitbucketSource: (source: BitbucketSourceParams, sourceName?: string) => string;
17
+ export declare const isForgePrefix: (value: string) => value is ForgePrefix;
18
18
  /** @experimental */
19
- export declare const printAzureReposSource: (source: AzureReposSourceParams, sourceName?: string) => string;
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 declare const printLocalSource: (source: LocalSourceParams) => string;
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
- * Pure per-forge source shorthand printing grammar.
2
+ * Forge coordinate, clone URL, and browser URL grammar.
3
3
  *
4
- * Each printer formats source params as the forge's canonical shorthand
5
- * string. Probing and acquisition stay with the source-resolution providers;
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 printGitHubSource = (source, sourceName = source.sourceName ?? "github") => {
14
- let s = `${sourceName}:${source.owner}/${source.repo}`;
15
- if (Option.isSome(source.subPath))
16
- s += `//${source.subPath.value}`;
17
- if (Option.isSome(source.ref))
18
- s += `@${source.ref.value}`;
19
- return s;
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 printGitLabSource = (source, sourceName = source.sourceName ?? "gitlab") => {
23
- let s = `${sourceName}:${source.owner}/${source.repo}`;
24
- if (Option.isSome(source.subPath))
25
- s += `//${source.subPath.value}`;
26
- if (Option.isSome(source.ref))
27
- s += `@${source.ref.value}`;
28
- return s;
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 printBitbucketSource = (source, sourceName = source.sourceName ?? "bitbucket") => {
32
- let s = `${sourceName}:${source.owner}/${source.repo}`;
33
- if (Option.isSome(source.subPath))
34
- s += `//${source.subPath.value}`;
35
- if (Option.isSome(source.ref))
36
- s += `@${source.ref.value}`;
37
- return s;
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 printAzureReposSource = (source, sourceName = source.sourceName ?? "azurerepos") => {
41
- let s = `${sourceName}:${source.organization}/${source.project}/${source.repo}`;
42
- if (Option.isSome(source.subPath))
43
- s += `//${source.subPath.value}`;
44
- if (Option.isSome(source.ref))
45
- s += `@${source.ref.value}`;
46
- return s;
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 printLocalSource = (source) => source.path.startsWith("/") || source.path.startsWith(".") ? source.path : `./${source.path}`;
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 first: string;
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: string;
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
- if (colonIndex > 0 && SHORTHAND_PREFIXES.has(input.slice(0, colonIndex))) {
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: input.slice(0, colonIndex),
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 refIndex = input.lastIndexOf("@");
94
- const hasRef = refIndex > 0 && refIndex < input.length - 1;
95
- const coordinate = hasRef ? input.slice(0, refIndex) : input;
96
- const ref = hasRef ? input.slice(refIndex + 1) : undefined;
97
- const subPathIndex = coordinate.indexOf("//");
98
- const repositoryCoordinate = subPathIndex < 0 ? coordinate : coordinate.slice(0, subPathIndex);
99
- const subPath = subPathIndex < 0 ? undefined : coordinate.slice(subPathIndex + 2);
100
- const segments = repositoryCoordinate.split("/");
101
- const first = segments.at(0);
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.none();
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 { printLocalSource } from "./forge-grammar.js";
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
- const repositorySegments = source.url.pathname
21
- .split("/")
22
- .filter((segment) => segment.length > 0);
23
- if (source.url.hostname === "dev.azure.com" &&
24
- repositorySegments.length === 4 &&
25
- repositorySegments[2] === "_git") {
26
- let shorthand = `azurerepos:${repositorySegments[0]}/${repositorySegments[1]}/${repositorySegments[3]}`;
27
- if (Option.isSome(source.subPath))
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");