@agentxm/extension-model 0.34.0 → 0.36.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/derive.js +1 -3
- 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 +1 -1
- package/dist/src/unstable/agent-capabilities/index.js +1 -1
- package/dist/src/unstable/agents/registry.d.ts +3 -17
- package/dist/src/unstable/agents/registry.js +2 -17
- package/dist/src/unstable/agents/types.d.ts +5 -7
- package/dist/src/unstable/agents/types.js +2 -4
- package/dist/src/unstable/extensions/common.d.ts +20 -8
- package/dist/src/unstable/extensions/common.js +29 -32
- package/dist/src/unstable/extensions/deprecation.d.ts +24 -3
- package/dist/src/unstable/extensions/deprecation.js +22 -3
- package/dist/src/unstable/extensions/index.d.ts +1 -1
- package/dist/src/unstable/extensions/index.js +1 -1
- 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/extensions/refs/extension-ref.d.ts +9 -0
- package/dist/src/unstable/extensions/refs/extension-ref.js +25 -1
- package/dist/src/unstable/extensions/registry-source.d.ts +12 -2
- package/dist/src/unstable/extensions/registry-source.js +17 -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 +9 -7
- package/dist/src/unstable/sources/parser.js +14 -31
- package/dist/src/unstable/sources/printer.js +10 -35
- package/dist/src/unstable/sources/source-host-provider.d.ts +10 -6
- package/dist/src/unstable/sources/types.d.ts +1 -93
- package/dist/src/unstable/sources/types.js +1 -48
- package/dist/src/unstable/version-constraints/version-constraints.d.ts +9 -11
- package/dist/src/unstable/version-constraints/version-constraints.js +14 -43
- package/package.json +3 -3
|
@@ -29,7 +29,7 @@ export type SourceType = Schema.Schema.Type<typeof SourceTypeSchema>;
|
|
|
29
29
|
/**
|
|
30
30
|
* Ref type discriminator for extension ref hosting categories.
|
|
31
31
|
*
|
|
32
|
-
* - `"git-hosted"` - Git-based sources
|
|
32
|
+
* - `"git-hosted"` - Git-based sources, including the built-in forges
|
|
33
33
|
* - `"registry"` - Package registry source
|
|
34
34
|
* - `"local"` - Local filesystem path source
|
|
35
35
|
* - `"workspace"` - Intrinsic managed workspace package
|
|
@@ -43,60 +43,9 @@ export declare const RefTypeSchema: Schema.Literals<readonly ["git-hosted", "reg
|
|
|
43
43
|
* @experimental This API is unstable and may change without notice.
|
|
44
44
|
*/
|
|
45
45
|
export type RefType = Schema.Schema.Type<typeof RefTypeSchema>;
|
|
46
|
-
export declare const SourceSegmentSchema: Schema.NonEmptyString;
|
|
47
46
|
export declare const SourceRefSchema: Schema.NonEmptyString;
|
|
48
47
|
export declare const SourceNamespaceSchema: Schema.NonEmptyString;
|
|
49
48
|
export declare const SourceSubPathSchema: Schema.NonEmptyString;
|
|
50
|
-
export declare const GitHostedSourceParamPartsSchema: Schema.Struct<{
|
|
51
|
-
sourceName: Schema.optional<Schema.String>;
|
|
52
|
-
owner: Schema.NonEmptyString;
|
|
53
|
-
repo: Schema.NonEmptyString;
|
|
54
|
-
ref: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
55
|
-
subPath: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
56
|
-
}>;
|
|
57
|
-
export type GitHostedSourceParamParts = Schema.Schema.Type<typeof GitHostedSourceParamPartsSchema>;
|
|
58
|
-
export declare const AzureReposSourceParamPartsSchema: Schema.Struct<{
|
|
59
|
-
sourceName: Schema.optional<Schema.String>;
|
|
60
|
-
organization: Schema.NonEmptyString;
|
|
61
|
-
project: Schema.NonEmptyString;
|
|
62
|
-
repo: Schema.NonEmptyString;
|
|
63
|
-
ref: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
64
|
-
subPath: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
65
|
-
}>;
|
|
66
|
-
export type AzureReposSourceParamParts = Schema.Schema.Type<typeof AzureReposSourceParamPartsSchema>;
|
|
67
|
-
export declare const GitHubSourceParamsSchema: Schema.Struct<{
|
|
68
|
-
readonly sourceName: Schema.optional<Schema.String>;
|
|
69
|
-
readonly owner: Schema.NonEmptyString;
|
|
70
|
-
readonly repo: Schema.NonEmptyString;
|
|
71
|
-
readonly ref: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
72
|
-
readonly subPath: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
73
|
-
readonly type: Schema.Literal<"github">;
|
|
74
|
-
}>;
|
|
75
|
-
export declare const GitLabSourceParamsSchema: Schema.Struct<{
|
|
76
|
-
readonly sourceName: Schema.optional<Schema.String>;
|
|
77
|
-
readonly owner: Schema.NonEmptyString;
|
|
78
|
-
readonly repo: Schema.NonEmptyString;
|
|
79
|
-
readonly ref: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
80
|
-
readonly subPath: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
81
|
-
readonly type: Schema.Literal<"gitlab">;
|
|
82
|
-
}>;
|
|
83
|
-
export declare const BitbucketSourceParamsSchema: Schema.Struct<{
|
|
84
|
-
readonly sourceName: Schema.optional<Schema.String>;
|
|
85
|
-
readonly owner: Schema.NonEmptyString;
|
|
86
|
-
readonly repo: Schema.NonEmptyString;
|
|
87
|
-
readonly ref: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
88
|
-
readonly subPath: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
89
|
-
readonly type: Schema.Literal<"bitbucket">;
|
|
90
|
-
}>;
|
|
91
|
-
export declare const AzureReposSourceParamsSchema: Schema.Struct<{
|
|
92
|
-
readonly sourceName: Schema.optional<Schema.String>;
|
|
93
|
-
readonly organization: Schema.NonEmptyString;
|
|
94
|
-
readonly project: Schema.NonEmptyString;
|
|
95
|
-
readonly repo: Schema.NonEmptyString;
|
|
96
|
-
readonly ref: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
97
|
-
readonly subPath: Schema.OptionFromOptionalKey<Schema.NonEmptyString>;
|
|
98
|
-
readonly type: Schema.Literal<"azurerepos">;
|
|
99
|
-
}>;
|
|
100
49
|
/** @experimental */
|
|
101
50
|
/** Self-describing — the git URL lives in SourceParams. @experimental */
|
|
102
51
|
export interface GitSourceHost {
|
|
@@ -126,47 +75,6 @@ export interface WorkspaceSourceHost {
|
|
|
126
75
|
/** @experimental */
|
|
127
76
|
export type SourceHost = GitSourceHost | RegistrySourceHost | LocalSourceHost | InlineSourceHost | WorkspaceSourceHost;
|
|
128
77
|
/** @experimental */
|
|
129
|
-
export interface GitHubSourceParams {
|
|
130
|
-
readonly type: "github";
|
|
131
|
-
readonly sourceName?: string | undefined;
|
|
132
|
-
readonly owner: string;
|
|
133
|
-
readonly repo: string;
|
|
134
|
-
readonly ref: Option.Option<string>;
|
|
135
|
-
readonly subPath: Option.Option<string>;
|
|
136
|
-
readonly cloneUrl?: Option.Option<string>;
|
|
137
|
-
}
|
|
138
|
-
/** @experimental */
|
|
139
|
-
export interface GitLabSourceParams {
|
|
140
|
-
readonly type: "gitlab";
|
|
141
|
-
readonly sourceName?: string | undefined;
|
|
142
|
-
readonly owner: string;
|
|
143
|
-
readonly repo: string;
|
|
144
|
-
readonly ref: Option.Option<string>;
|
|
145
|
-
readonly subPath: Option.Option<string>;
|
|
146
|
-
readonly cloneUrl?: Option.Option<string>;
|
|
147
|
-
}
|
|
148
|
-
/** @experimental */
|
|
149
|
-
export interface BitbucketSourceParams {
|
|
150
|
-
readonly type: "bitbucket";
|
|
151
|
-
readonly sourceName?: string | undefined;
|
|
152
|
-
readonly owner: string;
|
|
153
|
-
readonly repo: string;
|
|
154
|
-
readonly ref: Option.Option<string>;
|
|
155
|
-
readonly subPath: Option.Option<string>;
|
|
156
|
-
readonly cloneUrl?: Option.Option<string>;
|
|
157
|
-
}
|
|
158
|
-
/** @experimental */
|
|
159
|
-
export interface AzureReposSourceParams {
|
|
160
|
-
readonly type: "azurerepos";
|
|
161
|
-
readonly sourceName?: string | undefined;
|
|
162
|
-
readonly organization: string;
|
|
163
|
-
readonly project: string;
|
|
164
|
-
readonly repo: string;
|
|
165
|
-
readonly ref: Option.Option<string>;
|
|
166
|
-
readonly subPath: Option.Option<string>;
|
|
167
|
-
readonly cloneUrl?: Option.Option<string>;
|
|
168
|
-
}
|
|
169
|
-
/** @experimental */
|
|
170
78
|
export interface GitSourceParams {
|
|
171
79
|
readonly type: "git";
|
|
172
80
|
readonly url: URL;
|
|
@@ -36,7 +36,7 @@ export const SourceTypeSchema = Schema.Literals([
|
|
|
36
36
|
/**
|
|
37
37
|
* Ref type discriminator for extension ref hosting categories.
|
|
38
38
|
*
|
|
39
|
-
* - `"git-hosted"` - Git-based sources
|
|
39
|
+
* - `"git-hosted"` - Git-based sources, including the built-in forges
|
|
40
40
|
* - `"registry"` - Package registry source
|
|
41
41
|
* - `"local"` - Local filesystem path source
|
|
42
42
|
* - `"workspace"` - Intrinsic managed workspace package
|
|
@@ -53,13 +53,7 @@ export const RefTypeSchema = Schema.Literals([
|
|
|
53
53
|
title: "Ref Type",
|
|
54
54
|
description: "Ref type category: git-hosted, registry, local, or workspace.",
|
|
55
55
|
});
|
|
56
|
-
const noSlashSegmentMessage = "Expected non-empty segment without '/' characters";
|
|
57
56
|
const noTraversalSegmentMessage = "Expected subpath without '..' traversal segments";
|
|
58
|
-
export const SourceSegmentSchema = Schema.NonEmptyString.pipe(Schema.check(Schema.makeFilter((value) => (value.includes("/") ? noSlashSegmentMessage : undefined)))).annotate({
|
|
59
|
-
identifier: "SourceSegment",
|
|
60
|
-
title: "Source Segment",
|
|
61
|
-
description: "A non-empty path segment without slash characters, used for owner/repo identifiers.",
|
|
62
|
-
});
|
|
63
57
|
export const SourceRefSchema = Schema.NonEmptyString;
|
|
64
58
|
export const SourceNamespaceSchema = Schema.NonEmptyString.pipe(Schema.check(Schema.makeFilter((value) => value.split("/").some((segment) => segment.length === 0 || segment === "..")
|
|
65
59
|
? "Expected non-empty namespace path segments without '..' traversal"
|
|
@@ -75,45 +69,4 @@ export const SourceSubPathSchema = Schema.NonEmptyString.pipe(Schema.check(Schem
|
|
|
75
69
|
title: "Source Subpath",
|
|
76
70
|
description: "A non-empty repository subpath without empty or '..' traversal segments.",
|
|
77
71
|
});
|
|
78
|
-
const GitHostedSourceParamFields = {
|
|
79
|
-
sourceName: Schema.optional(Schema.String),
|
|
80
|
-
owner: SourceNamespaceSchema,
|
|
81
|
-
repo: SourceSegmentSchema,
|
|
82
|
-
ref: Schema.OptionFromOptionalKey(SourceRefSchema),
|
|
83
|
-
subPath: Schema.OptionFromOptionalKey(SourceSubPathSchema),
|
|
84
|
-
};
|
|
85
|
-
export const GitHostedSourceParamPartsSchema = Schema.Struct(GitHostedSourceParamFields).annotate({
|
|
86
|
-
identifier: "GitHostedSourceParamParts",
|
|
87
|
-
title: "Git Hosted Source Params",
|
|
88
|
-
description: "Parameters for a git-hosted source: owner, repo, optional ref and sub-path.",
|
|
89
|
-
});
|
|
90
|
-
const AzureReposSourceParamFields = {
|
|
91
|
-
sourceName: Schema.optional(Schema.String),
|
|
92
|
-
organization: SourceSegmentSchema,
|
|
93
|
-
project: SourceSegmentSchema,
|
|
94
|
-
repo: SourceSegmentSchema,
|
|
95
|
-
ref: Schema.OptionFromOptionalKey(SourceRefSchema),
|
|
96
|
-
subPath: Schema.OptionFromOptionalKey(SourceSubPathSchema),
|
|
97
|
-
};
|
|
98
|
-
export const AzureReposSourceParamPartsSchema = Schema.Struct(AzureReposSourceParamFields).annotate({
|
|
99
|
-
identifier: "AzureReposSourceParamParts",
|
|
100
|
-
title: "Azure Repos Source Params",
|
|
101
|
-
description: "Parameters for an Azure Repos source: organization, project, repo, optional ref and sub-path.",
|
|
102
|
-
});
|
|
103
|
-
export const GitHubSourceParamsSchema = Schema.Struct({
|
|
104
|
-
type: Schema.Literal("github"),
|
|
105
|
-
...GitHostedSourceParamFields,
|
|
106
|
-
});
|
|
107
|
-
export const GitLabSourceParamsSchema = Schema.Struct({
|
|
108
|
-
type: Schema.Literal("gitlab"),
|
|
109
|
-
...GitHostedSourceParamFields,
|
|
110
|
-
});
|
|
111
|
-
export const BitbucketSourceParamsSchema = Schema.Struct({
|
|
112
|
-
type: Schema.Literal("bitbucket"),
|
|
113
|
-
...GitHostedSourceParamFields,
|
|
114
|
-
});
|
|
115
|
-
export const AzureReposSourceParamsSchema = Schema.Struct({
|
|
116
|
-
type: Schema.Literal("azurerepos"),
|
|
117
|
-
...AzureReposSourceParamFields,
|
|
118
|
-
});
|
|
119
72
|
//# sourceMappingURL=types.js.map
|
|
@@ -39,12 +39,9 @@ export declare const decodeVersionSync: (input: unknown, options?: import("effec
|
|
|
39
39
|
*/
|
|
40
40
|
export declare const decodeVersionRangeSync: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => string & import("effect/Brand").Brand<"VersionRange">;
|
|
41
41
|
/**
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* Handles both namespaced (`@handle/name@^1.0.0`) and non-namespaced (`name@^1.0.0`) names.
|
|
45
|
-
* Returns `Option.none()` when no version suffix is present.
|
|
42
|
+
* Decode a value as a semver version range, or none when it is not one.
|
|
46
43
|
*/
|
|
47
|
-
export declare const
|
|
44
|
+
export declare const decodeVersionRangeOption: (input: unknown, options?: import("effect/SchemaAST").ParseOptions) => Option.Option<string & import("effect/Brand").Brand<"VersionRange">>;
|
|
48
45
|
/**
|
|
49
46
|
* Check whether a string is a valid semver version range.
|
|
50
47
|
*/
|
|
@@ -57,15 +54,16 @@ export declare const intersectVersionConstraints: (constraints: ReadonlyArray<st
|
|
|
57
54
|
*/
|
|
58
55
|
export declare const hasMinorOrMajorVersionBump: (previousVersion: string, currentVersion: string) => boolean;
|
|
59
56
|
/**
|
|
60
|
-
*
|
|
57
|
+
* Whether a version is one the range admits: the one predicate every
|
|
58
|
+
* selection and every satisfaction check applies, so a range admits the same
|
|
59
|
+
* versions wherever it is asked. It follows semver exactly, so `*` and an
|
|
60
|
+
* absent range admit every stable version and no prerelease; a prerelease is
|
|
61
|
+
* admitted only by a range that names its version tuple.
|
|
61
62
|
*/
|
|
62
63
|
export declare const versionSatisfiesRange: (version: Version, range: VersionRange) => boolean;
|
|
63
64
|
/**
|
|
64
|
-
* Select the
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* - `Option.none()` range or `"*"` matches any version.
|
|
68
|
-
* - Invalid ranges match nothing.
|
|
65
|
+
* Select the highest version the range admits, independent of input order.
|
|
66
|
+
* An absent range admits what `*` admits; an invalid range admits nothing.
|
|
69
67
|
*/
|
|
70
68
|
export declare const resolveVersionInRange: <T extends VersionEntryLike>(versions: ReadonlyArray<T>, range: Option.Option<string>) => Option.Option<T>;
|
|
71
69
|
//# sourceMappingURL=version-constraints.d.ts.map
|
|
@@ -46,36 +46,9 @@ export const decodeVersionSync = Schema.decodeUnknownSync(VersionSchema);
|
|
|
46
46
|
export const decodeVersionRangeSync = Schema.decodeUnknownSync(VersionRangeSchema);
|
|
47
47
|
const parseSemverVersion = (version) => semver.parse(version);
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
50
|
-
*
|
|
51
|
-
* Handles both namespaced (`@handle/name@^1.0.0`) and non-namespaced (`name@^1.0.0`) names.
|
|
52
|
-
* Returns `Option.none()` when no version suffix is present.
|
|
49
|
+
* Decode a value as a semver version range, or none when it is not one.
|
|
53
50
|
*/
|
|
54
|
-
export const
|
|
55
|
-
const decodeRange = (value) => {
|
|
56
|
-
try {
|
|
57
|
-
return Option.some(decodeVersionRangeSync(value));
|
|
58
|
-
}
|
|
59
|
-
catch {
|
|
60
|
-
return Option.none();
|
|
61
|
-
}
|
|
62
|
-
};
|
|
63
|
-
// For namespaced packages (@handle/name@range), find the @ after the handle
|
|
64
|
-
if (sourceString.startsWith("@")) {
|
|
65
|
-
const slashIndex = sourceString.indexOf("/");
|
|
66
|
-
if (slashIndex === -1)
|
|
67
|
-
return Option.none();
|
|
68
|
-
const afterHandle = sourceString.indexOf("@", slashIndex + 1);
|
|
69
|
-
if (afterHandle === -1)
|
|
70
|
-
return Option.none();
|
|
71
|
-
return decodeRange(sourceString.slice(afterHandle + 1));
|
|
72
|
-
}
|
|
73
|
-
// For non-namespaced packages (name@range)
|
|
74
|
-
const atIndex = sourceString.indexOf("@");
|
|
75
|
-
if (atIndex === -1)
|
|
76
|
-
return Option.none();
|
|
77
|
-
return decodeRange(sourceString.slice(atIndex + 1));
|
|
78
|
-
};
|
|
51
|
+
export const decodeVersionRangeOption = Schema.decodeUnknownOption(VersionRangeSchema);
|
|
79
52
|
/**
|
|
80
53
|
* Check whether a string is a valid semver version range.
|
|
81
54
|
*/
|
|
@@ -159,29 +132,27 @@ export const hasMinorOrMajorVersionBump = (previousVersion, currentVersion) => {
|
|
|
159
132
|
return current.major > previous.major || current.minor > previous.minor;
|
|
160
133
|
};
|
|
161
134
|
/**
|
|
162
|
-
*
|
|
135
|
+
* Whether a version is one the range admits: the one predicate every
|
|
136
|
+
* selection and every satisfaction check applies, so a range admits the same
|
|
137
|
+
* versions wherever it is asked. It follows semver exactly, so `*` and an
|
|
138
|
+
* absent range admit every stable version and no prerelease; a prerelease is
|
|
139
|
+
* admitted only by a range that names its version tuple.
|
|
163
140
|
*/
|
|
164
141
|
export const versionSatisfiesRange = (version, range) => semver.satisfies(version, range);
|
|
142
|
+
/** The range an absent constraint stands for: every stable version. */
|
|
143
|
+
const UNCONSTRAINED_RANGE = "*";
|
|
165
144
|
/**
|
|
166
|
-
* Select the
|
|
167
|
-
*
|
|
168
|
-
*
|
|
169
|
-
* - `Option.none()` range or `"*"` matches any version.
|
|
170
|
-
* - Invalid ranges match nothing.
|
|
145
|
+
* Select the highest version the range admits, independent of input order.
|
|
146
|
+
* An absent range admits what `*` admits; an invalid range admits nothing.
|
|
171
147
|
*/
|
|
172
148
|
export const resolveVersionInRange = (versions, range) => {
|
|
173
|
-
const
|
|
174
|
-
|
|
175
|
-
const isWildcard = rangeStr === "*";
|
|
176
|
-
// Validate the range early
|
|
177
|
-
if (!isWildcard && !isValidVersionRange(rangeStr)) {
|
|
149
|
+
const decoded = decodeVersionRangeOption(Option.getOrElse(range, () => UNCONSTRAINED_RANGE));
|
|
150
|
+
if (Option.isNone(decoded))
|
|
178
151
|
return Option.none();
|
|
179
|
-
}
|
|
180
152
|
let selected;
|
|
181
153
|
for (const version of versions) {
|
|
182
|
-
if (!
|
|
154
|
+
if (!versionSatisfiesRange(version.version, decoded.value))
|
|
183
155
|
continue;
|
|
184
|
-
}
|
|
185
156
|
if (selected === undefined || semver.compareBuild(version.version, selected.version) > 0) {
|
|
186
157
|
selected = version;
|
|
187
158
|
}
|
package/package.json
CHANGED
|
@@ -11,14 +11,14 @@
|
|
|
11
11
|
},
|
|
12
12
|
"description": "Shared AgentXM extension model: identities, manifests, version constraints, and agent capabilities. Unstable and unsupported — use the axm.sh CLI.",
|
|
13
13
|
"devDependencies": {
|
|
14
|
-
"@agentxm/specification-metadata": "0.
|
|
14
|
+
"@agentxm/specification-metadata": "0.36.0",
|
|
15
15
|
"@effect/vitest": "4.0.0-rc.117",
|
|
16
16
|
"@fast-check/vitest": "^0.5.0",
|
|
17
17
|
"@types/semver": "^7.7.1",
|
|
18
18
|
"@types/spdx-expression-parse": "4.0.0",
|
|
19
19
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
20
20
|
"typescript": "npm:@typescript/typescript6@^6.0.2",
|
|
21
|
-
"vitest": "^5.0.
|
|
21
|
+
"vitest": "^5.0.1"
|
|
22
22
|
},
|
|
23
23
|
"engines": {
|
|
24
24
|
"node": ">=24.19.0"
|
|
@@ -305,5 +305,5 @@
|
|
|
305
305
|
},
|
|
306
306
|
"sideEffects": false,
|
|
307
307
|
"type": "module",
|
|
308
|
-
"version": "0.
|
|
308
|
+
"version": "0.36.0"
|
|
309
309
|
}
|