@agentxm/extension-content 0.28.14-preview.1789139351.5cd4595aa
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +110 -0
- package/README.md +17 -0
- package/dist/src/content/agent-skills-standard.d.ts +17 -0
- package/dist/src/content/agent-skills-standard.js +24 -0
- package/dist/src/content/frontmatter.d.ts +52 -0
- package/dist/src/content/frontmatter.js +115 -0
- package/dist/src/content/index.d.ts +11 -0
- package/dist/src/content/index.js +11 -0
- package/dist/src/content/skill-content.d.ts +43 -0
- package/dist/src/content/skill-content.js +184 -0
- package/dist/src/content/skill-types.d.ts +22 -0
- package/dist/src/content/skill-types.js +9 -0
- package/dist/src/content/subagent-content.d.ts +58 -0
- package/dist/src/content/subagent-content.js +101 -0
- package/dist/src/index.d.ts +23 -0
- package/dist/src/index.js +23 -0
- package/dist/src/knowledge/index.d.ts +9 -0
- package/dist/src/knowledge/index.js +9 -0
- package/dist/src/knowledge/knowledge-search.d.ts +32 -0
- package/dist/src/knowledge/knowledge-search.js +147 -0
- package/dist/src/knowledge/okf.d.ts +86 -0
- package/dist/src/knowledge/okf.js +1090 -0
- package/dist/src/knowledge/package-inspection.d.ts +125 -0
- package/dist/src/knowledge/package-inspection.js +45 -0
- package/dist/src/lint/catalog/hook/decision-portability.d.ts +4 -0
- package/dist/src/lint/catalog/hook/decision-portability.js +40 -0
- package/dist/src/lint/catalog/hook/entrypoint-exists.d.ts +4 -0
- package/dist/src/lint/catalog/hook/entrypoint-exists.js +39 -0
- package/dist/src/lint/catalog/hook/envelope.d.ts +6 -0
- package/dist/src/lint/catalog/hook/envelope.js +15 -0
- package/dist/src/lint/catalog/hook/matcher-raw-portability.d.ts +4 -0
- package/dist/src/lint/catalog/hook/matcher-raw-portability.js +51 -0
- package/dist/src/lint/catalog/hook.d.ts +4 -0
- package/dist/src/lint/catalog/hook.js +15 -0
- package/dist/src/lint/catalog/knowledge/diagnostics.d.ts +128 -0
- package/dist/src/lint/catalog/knowledge/diagnostics.js +78 -0
- package/dist/src/lint/catalog/knowledge/envelope.d.ts +6 -0
- package/dist/src/lint/catalog/knowledge/envelope.js +15 -0
- package/dist/src/lint/catalog/knowledge.d.ts +11 -0
- package/dist/src/lint/catalog/knowledge.js +15 -0
- package/dist/src/lint/catalog/mcp-server/envelope.d.ts +6 -0
- package/dist/src/lint/catalog/mcp-server/envelope.js +15 -0
- package/dist/src/lint/catalog/mcp-server.d.ts +4 -0
- package/dist/src/lint/catalog/mcp-server.js +4 -0
- package/dist/src/lint/catalog/pack/manifest-keys-recognized.d.ts +28 -0
- package/dist/src/lint/catalog/pack/manifest-keys-recognized.js +38 -0
- package/dist/src/lint/catalog/pack/manifest-present.d.ts +17 -0
- package/dist/src/lint/catalog/pack/manifest-present.js +24 -0
- package/dist/src/lint/catalog/pack/manifest-schema-valid.d.ts +25 -0
- package/dist/src/lint/catalog/pack/manifest-schema-valid.js +33 -0
- package/dist/src/lint/catalog/pack-accessor/contexts.d.ts +51 -0
- package/dist/src/lint/catalog/pack-accessor/contexts.js +45 -0
- package/dist/src/lint/catalog/pack-accessor/platform.d.ts +56 -0
- package/dist/src/lint/catalog/pack-accessor/platform.js +93 -0
- package/dist/src/lint/catalog/pack-accessor/vft.d.ts +60 -0
- package/dist/src/lint/catalog/pack-accessor/vft.js +85 -0
- package/dist/src/lint/catalog/pack.d.ts +31 -0
- package/dist/src/lint/catalog/pack.js +36 -0
- package/dist/src/lint/catalog/rule/envelope.d.ts +6 -0
- package/dist/src/lint/catalog/rule/envelope.js +15 -0
- package/dist/src/lint/catalog/rule.d.ts +4 -0
- package/dist/src/lint/catalog/rule.js +4 -0
- package/dist/src/lint/catalog/shared/envelope-rules.d.ts +88 -0
- package/dist/src/lint/catalog/shared/envelope-rules.js +84 -0
- package/dist/src/lint/catalog/shared/manifest-json.d.ts +18 -0
- package/dist/src/lint/catalog/shared/manifest-json.js +28 -0
- package/dist/src/lint/catalog/shared/manifest-present.d.ts +25 -0
- package/dist/src/lint/catalog/shared/manifest-present.js +37 -0
- package/dist/src/lint/catalog/shared/recommended-packs-rules.d.ts +70 -0
- package/dist/src/lint/catalog/shared/recommended-packs-rules.js +139 -0
- package/dist/src/lint/catalog/shared/schema-rule.d.ts +57 -0
- package/dist/src/lint/catalog/shared/schema-rule.js +102 -0
- package/dist/src/lint/catalog/skill/frontmatter-parseable.d.ts +31 -0
- package/dist/src/lint/catalog/skill/frontmatter-parseable.js +148 -0
- package/dist/src/lint/catalog/skill/frontmatter-standard-valid.d.ts +13 -0
- package/dist/src/lint/catalog/skill/frontmatter-standard-valid.js +61 -0
- package/dist/src/lint/catalog/skill/manifest-keys-recognized.d.ts +26 -0
- package/dist/src/lint/catalog/skill/manifest-keys-recognized.js +41 -0
- package/dist/src/lint/catalog/skill/manifest-present.d.ts +23 -0
- package/dist/src/lint/catalog/skill/manifest-present.js +32 -0
- package/dist/src/lint/catalog/skill/manifest-schema-valid.d.ts +21 -0
- package/dist/src/lint/catalog/skill/manifest-schema-valid.js +36 -0
- package/dist/src/lint/catalog/skill/recommended-packs-valid.d.ts +8 -0
- package/dist/src/lint/catalog/skill/recommended-packs-valid.js +12 -0
- package/dist/src/lint/catalog/skill/skill-md-present.d.ts +17 -0
- package/dist/src/lint/catalog/skill/skill-md-present.js +37 -0
- package/dist/src/lint/catalog/skill/standalone-declaration-valid.d.ts +8 -0
- package/dist/src/lint/catalog/skill/standalone-declaration-valid.js +12 -0
- package/dist/src/lint/catalog/skill-accessor/contexts.d.ts +61 -0
- package/dist/src/lint/catalog/skill-accessor/contexts.js +55 -0
- package/dist/src/lint/catalog/skill-accessor/platform.d.ts +53 -0
- package/dist/src/lint/catalog/skill-accessor/platform.js +90 -0
- package/dist/src/lint/catalog/skill-accessor/vft.d.ts +77 -0
- package/dist/src/lint/catalog/skill-accessor/vft.js +135 -0
- package/dist/src/lint/catalog/skill.d.ts +38 -0
- package/dist/src/lint/catalog/skill.js +53 -0
- package/dist/src/lint/catalog/subagent/envelope.d.ts +6 -0
- package/dist/src/lint/catalog/subagent/envelope.js +15 -0
- package/dist/src/lint/catalog/subagent.d.ts +4 -0
- package/dist/src/lint/catalog/subagent.js +4 -0
- package/dist/src/lint/catalog-metadata.d.ts +125 -0
- package/dist/src/lint/catalog-metadata.js +642 -0
- package/dist/src/lint/compose-path.d.ts +28 -0
- package/dist/src/lint/compose-path.js +64 -0
- package/dist/src/lint/config.d.ts +77 -0
- package/dist/src/lint/config.js +99 -0
- package/dist/src/lint/context.d.ts +239 -0
- package/dist/src/lint/context.js +17 -0
- package/dist/src/lint/describe-document.d.ts +31 -0
- package/dist/src/lint/describe-document.js +50 -0
- package/dist/src/lint/evaluate.d.ts +47 -0
- package/dist/src/lint/evaluate.js +73 -0
- package/dist/src/lint/index.d.ts +36 -0
- package/dist/src/lint/index.js +34 -0
- package/dist/src/lint/issues-to-findings.d.ts +35 -0
- package/dist/src/lint/issues-to-findings.js +149 -0
- package/dist/src/lint/rule.d.ts +97 -0
- package/dist/src/lint/rule.js +17 -0
- package/dist/src/packaging/archive-guardrails.d.ts +39 -0
- package/dist/src/packaging/archive-guardrails.js +250 -0
- package/dist/src/packaging/filtered-package-validation.d.ts +24 -0
- package/dist/src/packaging/filtered-package-validation.js +117 -0
- package/dist/src/packaging/ingest-limits.d.ts +25 -0
- package/dist/src/packaging/ingest-limits.js +41 -0
- package/dist/src/packaging/input-normalization.d.ts +40 -0
- package/dist/src/packaging/input-normalization.js +125 -0
- package/dist/src/packaging/manifest-policy.d.ts +611 -0
- package/dist/src/packaging/manifest-policy.js +196 -0
- package/dist/src/packaging/test-zip-helpers.d.ts +13 -0
- package/dist/src/packaging/test-zip-helpers.js +117 -0
- package/dist/src/testing.d.ts +9 -0
- package/dist/src/testing.js +9 -0
- package/package.json +65 -0
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `rule/*` manifest envelope — see `../shared/envelope-rules.ts`.
|
|
3
|
+
*/
|
|
4
|
+
import { RuleManifestSchema, RULE_MANIFEST_FILENAME, } from "@agentxm/extension-model/unstable/rules/manifest-schema";
|
|
5
|
+
import { makeManifestEnvelopeRules } from "../shared/envelope-rules.js";
|
|
6
|
+
export const ruleEnvelopeRules = makeManifestEnvelopeRules({
|
|
7
|
+
namespace: "rule",
|
|
8
|
+
manifestFile: RULE_MANIFEST_FILENAME,
|
|
9
|
+
schema: RuleManifestSchema,
|
|
10
|
+
manifestJson: (context) => context.subject.ruleJson,
|
|
11
|
+
presentDescription: "Rules include a root rule.json manifest.",
|
|
12
|
+
presentMissingMessage: "rule.json is missing. Create rule.json with the required manifest fields (`owner`, `type`, `name`, `version`).",
|
|
13
|
+
schemaDescription: "rule.json defines a valid rule manifest.",
|
|
14
|
+
});
|
|
15
|
+
//# sourceMappingURL=envelope.js.map
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The five-rule manifest envelope every non-pack per-extension catalog ships.
|
|
3
|
+
*
|
|
4
|
+
* `skill`, `subagent`, `mcp-server`, `hook`, `rule`, and `knowledge` each
|
|
5
|
+
* enforce the same five invariants against their own
|
|
6
|
+
* manifest:
|
|
7
|
+
*
|
|
8
|
+
* 1. `<ns>/manifest-present` — the manifest file exists.
|
|
9
|
+
* 2. `<ns>/manifest-schema-valid` — it decodes against the canonical schema.
|
|
10
|
+
* 3. `<ns>/manifest-keys-recognized` — it carries no unknown top-level keys.
|
|
11
|
+
* 4. `<ns>/standalone-declaration-valid` — `standalone: false` names its packs.
|
|
12
|
+
* 5. `<ns>/recommended-packs-valid` — recommended packs are bare FQNs.
|
|
13
|
+
*
|
|
14
|
+
* Rules 1, 4, and 5 already had factories; rules 2 and 3 were hand-copied per
|
|
15
|
+
* type. This module composes all five so a new extension type's envelope is
|
|
16
|
+
* one call, and so the publish-safe barrel (`lint/publish.ts`) and the
|
|
17
|
+
* `axm lint` catalog (`catalog/<type>.ts`) build from the same definitions.
|
|
18
|
+
*
|
|
19
|
+
* @experimental This API is unstable and may change without notice.
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
import * as Effect from "effect/Effect";
|
|
23
|
+
import type * as Schema from "effect/Schema";
|
|
24
|
+
import type { AdvisoryRule } from "../../rule.js";
|
|
25
|
+
/**
|
|
26
|
+
* A manifest schema usable by the envelope: decodable, and introspectable for
|
|
27
|
+
* its declared top-level field names.
|
|
28
|
+
*
|
|
29
|
+
* @experimental This API is unstable and may change without notice.
|
|
30
|
+
*/
|
|
31
|
+
export type ManifestEnvelopeSchema<A, I> = Schema.Codec<A, I> & {
|
|
32
|
+
readonly fields: Readonly<Record<string, unknown>>;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Per-catalog parameters for {@link makeManifestEnvelopeRules}.
|
|
36
|
+
*
|
|
37
|
+
* @experimental This API is unstable and may change without notice.
|
|
38
|
+
*/
|
|
39
|
+
export interface ManifestEnvelopeOptions<C, A, I> {
|
|
40
|
+
/** Rule-id namespace; matches the context kind (`skill`, `hook`, ...). */
|
|
41
|
+
readonly namespace: string;
|
|
42
|
+
/** Accessor-relative manifest filename stamped on `location.file`. */
|
|
43
|
+
readonly manifestFile: string;
|
|
44
|
+
/** Canonical manifest schema for this type. */
|
|
45
|
+
readonly schema: ManifestEnvelopeSchema<A, I>;
|
|
46
|
+
/** Reads the caller-decoded manifest JSON off the rule context. */
|
|
47
|
+
readonly manifestJson: (context: C) => unknown;
|
|
48
|
+
/** `description` for `<ns>/manifest-present`. */
|
|
49
|
+
readonly presentDescription: string;
|
|
50
|
+
/** Finding message emitted when the manifest file is absent. */
|
|
51
|
+
readonly presentMissingMessage: string;
|
|
52
|
+
/** `description` for `<ns>/manifest-schema-valid`. */
|
|
53
|
+
readonly schemaDescription: string;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The five envelope rules, named so callers can order them alongside their own
|
|
57
|
+
* bespoke rules rather than splicing an opaque array.
|
|
58
|
+
*
|
|
59
|
+
* @experimental This API is unstable and may change without notice.
|
|
60
|
+
*/
|
|
61
|
+
export interface ManifestEnvelopeRules<C> {
|
|
62
|
+
readonly manifestPresent: AdvisoryRule<C>;
|
|
63
|
+
readonly manifestSchemaValid: AdvisoryRule<C>;
|
|
64
|
+
readonly manifestKeysRecognized: AdvisoryRule<C>;
|
|
65
|
+
readonly standaloneDeclarationValid: AdvisoryRule<C>;
|
|
66
|
+
readonly recommendedPacksValid: AdvisoryRule<C>;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Build one catalog's five manifest envelope rules.
|
|
70
|
+
*
|
|
71
|
+
* The context only has to expose a `files` accessor with `exists`; the
|
|
72
|
+
* manifest value itself is read through `options.manifestJson`, so the factory
|
|
73
|
+
* never assumes a subject field name.
|
|
74
|
+
*
|
|
75
|
+
* @experimental This API is unstable and may change without notice.
|
|
76
|
+
*/
|
|
77
|
+
export declare const makeManifestEnvelopeRules: <C extends {
|
|
78
|
+
readonly files: {
|
|
79
|
+
readonly exists: (path: string) => Effect.Effect<boolean>;
|
|
80
|
+
};
|
|
81
|
+
}, A, I>(options: ManifestEnvelopeOptions<C, A, I>) => ManifestEnvelopeRules<C>;
|
|
82
|
+
/**
|
|
83
|
+
* The envelope rules in canonical catalog order.
|
|
84
|
+
*
|
|
85
|
+
* @experimental This API is unstable and may change without notice.
|
|
86
|
+
*/
|
|
87
|
+
export declare const orderedEnvelopeRules: <C>(rules: ManifestEnvelopeRules<C>) => ReadonlyArray<AdvisoryRule<C>>;
|
|
88
|
+
//# sourceMappingURL=envelope-rules.d.ts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The five-rule manifest envelope every non-pack per-extension catalog ships.
|
|
3
|
+
*
|
|
4
|
+
* `skill`, `subagent`, `mcp-server`, `hook`, `rule`, and `knowledge` each
|
|
5
|
+
* enforce the same five invariants against their own
|
|
6
|
+
* manifest:
|
|
7
|
+
*
|
|
8
|
+
* 1. `<ns>/manifest-present` — the manifest file exists.
|
|
9
|
+
* 2. `<ns>/manifest-schema-valid` — it decodes against the canonical schema.
|
|
10
|
+
* 3. `<ns>/manifest-keys-recognized` — it carries no unknown top-level keys.
|
|
11
|
+
* 4. `<ns>/standalone-declaration-valid` — `standalone: false` names its packs.
|
|
12
|
+
* 5. `<ns>/recommended-packs-valid` — recommended packs are bare FQNs.
|
|
13
|
+
*
|
|
14
|
+
* Rules 1, 4, and 5 already had factories; rules 2 and 3 were hand-copied per
|
|
15
|
+
* type. This module composes all five so a new extension type's envelope is
|
|
16
|
+
* one call, and so the publish-safe barrel (`lint/publish.ts`) and the
|
|
17
|
+
* `axm lint` catalog (`catalog/<type>.ts`) build from the same definitions.
|
|
18
|
+
*
|
|
19
|
+
* @experimental This API is unstable and may change without notice.
|
|
20
|
+
* @packageDocumentation
|
|
21
|
+
*/
|
|
22
|
+
import * as Effect from "effect/Effect";
|
|
23
|
+
import { makeManifestPresentRule } from "./manifest-present.js";
|
|
24
|
+
import { makeRecommendedPacksValidRule, makeStandaloneDeclarationValidRule, } from "./recommended-packs-rules.js";
|
|
25
|
+
import { enumerateUnknownTopLevelKeys, schemaDecodeFindings, structFieldKeys, } from "./schema-rule.js";
|
|
26
|
+
/**
|
|
27
|
+
* Build one catalog's five manifest envelope rules.
|
|
28
|
+
*
|
|
29
|
+
* The context only has to expose a `files` accessor with `exists`; the
|
|
30
|
+
* manifest value itself is read through `options.manifestJson`, so the factory
|
|
31
|
+
* never assumes a subject field name.
|
|
32
|
+
*
|
|
33
|
+
* @experimental This API is unstable and may change without notice.
|
|
34
|
+
*/
|
|
35
|
+
export const makeManifestEnvelopeRules = (options) => {
|
|
36
|
+
const schemaValidRuleId = `${options.namespace}/manifest-schema-valid`;
|
|
37
|
+
const keysRecognizedRuleId = `${options.namespace}/manifest-keys-recognized`;
|
|
38
|
+
const allowedKeys = structFieldKeys(options.schema);
|
|
39
|
+
return {
|
|
40
|
+
manifestPresent: makeManifestPresentRule({
|
|
41
|
+
ruleId: `${options.namespace}/manifest-present`,
|
|
42
|
+
description: options.presentDescription,
|
|
43
|
+
manifestFile: options.manifestFile,
|
|
44
|
+
missingMessage: options.presentMissingMessage,
|
|
45
|
+
}),
|
|
46
|
+
manifestSchemaValid: {
|
|
47
|
+
id: schemaValidRuleId,
|
|
48
|
+
description: options.schemaDescription,
|
|
49
|
+
kind: "advisory",
|
|
50
|
+
severity: "error",
|
|
51
|
+
check: (context) => schemaDecodeFindings(schemaValidRuleId, "error", options.manifestFile, options.schema, options.manifestJson(context)),
|
|
52
|
+
},
|
|
53
|
+
manifestKeysRecognized: {
|
|
54
|
+
id: keysRecognizedRuleId,
|
|
55
|
+
description: `${options.manifestFile} uses only supported top-level fields.`,
|
|
56
|
+
kind: "advisory",
|
|
57
|
+
severity: "error",
|
|
58
|
+
check: (context) => Effect.succeed(enumerateUnknownTopLevelKeys(keysRecognizedRuleId, "error", options.manifestFile, allowedKeys, options.manifestJson(context))),
|
|
59
|
+
},
|
|
60
|
+
standaloneDeclarationValid: makeStandaloneDeclarationValidRule({
|
|
61
|
+
namespace: options.namespace,
|
|
62
|
+
manifestFile: options.manifestFile,
|
|
63
|
+
manifestJson: options.manifestJson,
|
|
64
|
+
}),
|
|
65
|
+
recommendedPacksValid: makeRecommendedPacksValidRule({
|
|
66
|
+
namespace: options.namespace,
|
|
67
|
+
manifestFile: options.manifestFile,
|
|
68
|
+
manifestJson: options.manifestJson,
|
|
69
|
+
}),
|
|
70
|
+
};
|
|
71
|
+
};
|
|
72
|
+
/**
|
|
73
|
+
* The envelope rules in canonical catalog order.
|
|
74
|
+
*
|
|
75
|
+
* @experimental This API is unstable and may change without notice.
|
|
76
|
+
*/
|
|
77
|
+
export const orderedEnvelopeRules = (rules) => [
|
|
78
|
+
rules.manifestPresent,
|
|
79
|
+
rules.manifestSchemaValid,
|
|
80
|
+
rules.manifestKeysRecognized,
|
|
81
|
+
rules.standaloneDeclarationValid,
|
|
82
|
+
rules.recommendedPacksValid,
|
|
83
|
+
];
|
|
84
|
+
//# sourceMappingURL=envelope-rules.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared loose-manifest JSON helpers.
|
|
3
|
+
*
|
|
4
|
+
* Workspace lint parses installed manifests before per-extension rules run.
|
|
5
|
+
* The parsed value must stay raw JSON, not a schema-decoded manifest, so
|
|
6
|
+
* `*-keys-recognized` rules can still see excess top-level fields.
|
|
7
|
+
*
|
|
8
|
+
* @experimental This API is unstable and may change without notice.
|
|
9
|
+
*/
|
|
10
|
+
import type { AdvisoryFinding, Severity } from "../../rule.js";
|
|
11
|
+
export interface ManifestJsonParseFailure {
|
|
12
|
+
readonly _tag: "ManifestJsonParseFailure";
|
|
13
|
+
readonly file: string;
|
|
14
|
+
}
|
|
15
|
+
export declare const makeManifestJsonParseFailure: (file: string) => ManifestJsonParseFailure;
|
|
16
|
+
export declare const isManifestJsonParseFailure: (value: unknown) => value is ManifestJsonParseFailure;
|
|
17
|
+
export declare const manifestJsonParseFailureToFinding: (ruleId: string, severity: Severity, file: string, input: ManifestJsonParseFailure) => AdvisoryFinding;
|
|
18
|
+
//# sourceMappingURL=manifest-json.d.ts.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared loose-manifest JSON helpers.
|
|
3
|
+
*
|
|
4
|
+
* Workspace lint parses installed manifests before per-extension rules run.
|
|
5
|
+
* The parsed value must stay raw JSON, not a schema-decoded manifest, so
|
|
6
|
+
* `*-keys-recognized` rules can still see excess top-level fields.
|
|
7
|
+
*
|
|
8
|
+
* @experimental This API is unstable and may change without notice.
|
|
9
|
+
*/
|
|
10
|
+
import { describeSchemaDocument } from "../../describe-document.js";
|
|
11
|
+
export const makeManifestJsonParseFailure = (file) => ({
|
|
12
|
+
_tag: "ManifestJsonParseFailure",
|
|
13
|
+
file,
|
|
14
|
+
});
|
|
15
|
+
export const isManifestJsonParseFailure = (value) => {
|
|
16
|
+
if (value === null || typeof value !== "object") {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
return "_tag" in value && value._tag === "ManifestJsonParseFailure";
|
|
20
|
+
};
|
|
21
|
+
export const manifestJsonParseFailureToFinding = (ruleId, severity, file, input) => ({
|
|
22
|
+
kind: "advisory",
|
|
23
|
+
ruleId,
|
|
24
|
+
severity,
|
|
25
|
+
message: `${describeSchemaDocument(file)} contains invalid JSON. Edit \`${input.file}\` and fix the JSON syntax.`,
|
|
26
|
+
location: { file },
|
|
27
|
+
});
|
|
28
|
+
//# sourceMappingURL=manifest-json.js.map
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared factory for `manifest-present` advisory rules.
|
|
3
|
+
*
|
|
4
|
+
* @experimental This API is unstable and may change without notice.
|
|
5
|
+
*/
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
import type { AdvisoryRule, Severity } from "../../rule.js";
|
|
8
|
+
interface ManifestFileAccessor {
|
|
9
|
+
readonly exists: (path: string) => Effect.Effect<boolean>;
|
|
10
|
+
}
|
|
11
|
+
interface ManifestPresentRuleContext {
|
|
12
|
+
readonly files: ManifestFileAccessor;
|
|
13
|
+
}
|
|
14
|
+
interface ManifestPresentRuleArgs<C> {
|
|
15
|
+
readonly ruleId: string;
|
|
16
|
+
readonly description: string;
|
|
17
|
+
readonly manifestFile: string;
|
|
18
|
+
readonly missingMessage: string;
|
|
19
|
+
readonly severity?: Severity;
|
|
20
|
+
readonly getFiles?: (context: C) => ManifestFileAccessor;
|
|
21
|
+
readonly applies?: (context: C) => boolean;
|
|
22
|
+
}
|
|
23
|
+
export declare const makeManifestPresentRule: <C extends ManifestPresentRuleContext>(args: ManifestPresentRuleArgs<C>) => AdvisoryRule<C>;
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=manifest-present.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared factory for `manifest-present` advisory rules.
|
|
3
|
+
*
|
|
4
|
+
* @experimental This API is unstable and may change without notice.
|
|
5
|
+
*/
|
|
6
|
+
import * as Effect from "effect/Effect";
|
|
7
|
+
export const makeManifestPresentRule = (args) => {
|
|
8
|
+
const severity = args.severity ?? "error";
|
|
9
|
+
const getFiles = args.getFiles ?? ((context) => context.files);
|
|
10
|
+
const applies = args.applies ?? (() => true);
|
|
11
|
+
return {
|
|
12
|
+
id: args.ruleId,
|
|
13
|
+
description: args.description,
|
|
14
|
+
kind: "advisory",
|
|
15
|
+
severity,
|
|
16
|
+
check: (context) => {
|
|
17
|
+
if (!applies(context)) {
|
|
18
|
+
return Effect.succeed([]);
|
|
19
|
+
}
|
|
20
|
+
return Effect.map(getFiles(context).exists(args.manifestFile), (present) => {
|
|
21
|
+
if (present) {
|
|
22
|
+
return [];
|
|
23
|
+
}
|
|
24
|
+
return [
|
|
25
|
+
{
|
|
26
|
+
kind: "advisory",
|
|
27
|
+
ruleId: args.ruleId,
|
|
28
|
+
severity,
|
|
29
|
+
message: args.missingMessage,
|
|
30
|
+
location: { file: args.manifestFile },
|
|
31
|
+
},
|
|
32
|
+
];
|
|
33
|
+
});
|
|
34
|
+
},
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
//# sourceMappingURL=manifest-present.js.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared factories for the `standalone` / `recommendedPacks` coherence rules.
|
|
3
|
+
*
|
|
4
|
+
* Both fields come from `NonPackManifestFields` in
|
|
5
|
+
* `extensions/common.ts`, so every non-pack catalog (`skill`, `subagent`,
|
|
6
|
+
* `mcp-server`, `rule`, `hook`, `knowledge`) enforces the same two invariants
|
|
7
|
+
* against its own manifest. Rather than copy twelve near-identical rule
|
|
8
|
+
* bodies, each catalog registers a rule produced here and parameterized by
|
|
9
|
+
* namespace and manifest accessor — the same shape `shared/schema-rule.ts`
|
|
10
|
+
* establishes for the `-schema-valid` rules.
|
|
11
|
+
*
|
|
12
|
+
* Both rules ship at `warning`. They would otherwise retroactively reject
|
|
13
|
+
* manifests published before the rules existed, which the rule-authoring
|
|
14
|
+
* guide's "new rules start soft" clause forbids.
|
|
15
|
+
*
|
|
16
|
+
* @experimental This API is unstable and may change without notice.
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
import type { AdvisoryRule } from "../../rule.js";
|
|
20
|
+
/**
|
|
21
|
+
* Per-catalog parameters for the shared non-pack manifest rules.
|
|
22
|
+
*
|
|
23
|
+
* @experimental This API is unstable and may change without notice.
|
|
24
|
+
*/
|
|
25
|
+
export interface RecommendedPacksRuleOptions<C> {
|
|
26
|
+
/** Rule-id namespace; matches the context kind (`skill`, `hook`, ...). */
|
|
27
|
+
readonly namespace: string;
|
|
28
|
+
/** Accessor-relative manifest filename stamped on `location.file`. */
|
|
29
|
+
readonly manifestFile: string;
|
|
30
|
+
/** Reads the caller-decoded manifest JSON off the rule context. */
|
|
31
|
+
readonly manifestJson: (context: C) => unknown;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Split a `recommendedPacks` entry into its FQN and optional version range.
|
|
35
|
+
*
|
|
36
|
+
* Mirrors the separator search in `PackSpecSchema`: the range delimiter is the
|
|
37
|
+
* first `@` after the last `/`, since the owner segment also starts with `@`.
|
|
38
|
+
*
|
|
39
|
+
* @experimental This API is unstable and may change without notice.
|
|
40
|
+
*/
|
|
41
|
+
export declare const splitPackSpec: (spec: string) => {
|
|
42
|
+
readonly fqn: string;
|
|
43
|
+
readonly range: string | undefined;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* Build the `<namespace>/standalone-declaration-valid` rule for one catalog.
|
|
47
|
+
*
|
|
48
|
+
* A manifest with `standalone: false` declares that it is meaningless without
|
|
49
|
+
* one of its recommended packs. With `recommendedPacks` absent or empty that
|
|
50
|
+
* declaration is self-contradictory and nothing downstream — registry, Library
|
|
51
|
+
* UI, or `workspace/recommended-packs-retained` — can act on it.
|
|
52
|
+
*
|
|
53
|
+
* @experimental This API is unstable and may change without notice.
|
|
54
|
+
*/
|
|
55
|
+
export declare const makeStandaloneDeclarationValidRule: <C>(options: RecommendedPacksRuleOptions<C>) => AdvisoryRule<C>;
|
|
56
|
+
/**
|
|
57
|
+
* Build the `<namespace>/recommended-packs-valid` rule for one catalog.
|
|
58
|
+
*
|
|
59
|
+
* `recommendedPacks` is typed `PackSpecSchema`, which permits a trailing
|
|
60
|
+
* version range, but nothing consumes one — recommendations are matched by
|
|
61
|
+
* name — and `axm help packs` tells authors to use the bare reference. One
|
|
62
|
+
* finding per offending entry.
|
|
63
|
+
*
|
|
64
|
+
* When published manifests have drained, the field can move to
|
|
65
|
+
* `PackFqnSchema` and this rule retires: decoding takes over.
|
|
66
|
+
*
|
|
67
|
+
* @experimental This API is unstable and may change without notice.
|
|
68
|
+
*/
|
|
69
|
+
export declare const makeRecommendedPacksValidRule: <C>(options: RecommendedPacksRuleOptions<C>) => AdvisoryRule<C>;
|
|
70
|
+
//# sourceMappingURL=recommended-packs-rules.d.ts.map
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared factories for the `standalone` / `recommendedPacks` coherence rules.
|
|
3
|
+
*
|
|
4
|
+
* Both fields come from `NonPackManifestFields` in
|
|
5
|
+
* `extensions/common.ts`, so every non-pack catalog (`skill`, `subagent`,
|
|
6
|
+
* `mcp-server`, `rule`, `hook`, `knowledge`) enforces the same two invariants
|
|
7
|
+
* against its own manifest. Rather than copy twelve near-identical rule
|
|
8
|
+
* bodies, each catalog registers a rule produced here and parameterized by
|
|
9
|
+
* namespace and manifest accessor — the same shape `shared/schema-rule.ts`
|
|
10
|
+
* establishes for the `-schema-valid` rules.
|
|
11
|
+
*
|
|
12
|
+
* Both rules ship at `warning`. They would otherwise retroactively reject
|
|
13
|
+
* manifests published before the rules existed, which the rule-authoring
|
|
14
|
+
* guide's "new rules start soft" clause forbids.
|
|
15
|
+
*
|
|
16
|
+
* @experimental This API is unstable and may change without notice.
|
|
17
|
+
* @packageDocumentation
|
|
18
|
+
*/
|
|
19
|
+
import * as Effect from "effect/Effect";
|
|
20
|
+
import { isManifestJsonParseFailure } from "./manifest-json.js";
|
|
21
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
22
|
+
/**
|
|
23
|
+
* Narrow a caller-decoded manifest value to a plain record, or `undefined`
|
|
24
|
+
* when there is nothing for these rules to read. Absent manifests are the
|
|
25
|
+
* `-present` rule's problem; unparseable ones are the `-schema-valid` rule's.
|
|
26
|
+
*/
|
|
27
|
+
const manifestRecord = (input) => {
|
|
28
|
+
if (input === undefined || isManifestJsonParseFailure(input) || !isRecord(input)) {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
return input;
|
|
32
|
+
};
|
|
33
|
+
const stringEntries = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : [];
|
|
34
|
+
/**
|
|
35
|
+
* Split a `recommendedPacks` entry into its FQN and optional version range.
|
|
36
|
+
*
|
|
37
|
+
* Mirrors the separator search in `PackSpecSchema`: the range delimiter is the
|
|
38
|
+
* first `@` after the last `/`, since the owner segment also starts with `@`.
|
|
39
|
+
*
|
|
40
|
+
* @experimental This API is unstable and may change without notice.
|
|
41
|
+
*/
|
|
42
|
+
export const splitPackSpec = (spec) => {
|
|
43
|
+
const lastSlash = spec.lastIndexOf("/");
|
|
44
|
+
const rangeAt = lastSlash > 0 ? spec.indexOf("@", lastSlash + 1) : -1;
|
|
45
|
+
if (rangeAt <= 0) {
|
|
46
|
+
return { fqn: spec, range: undefined };
|
|
47
|
+
}
|
|
48
|
+
return { fqn: spec.slice(0, rangeAt), range: spec.slice(rangeAt + 1) };
|
|
49
|
+
};
|
|
50
|
+
// -----------------------------------------------------------------------------
|
|
51
|
+
// <namespace>/standalone-declaration-valid
|
|
52
|
+
// -----------------------------------------------------------------------------
|
|
53
|
+
/**
|
|
54
|
+
* Build the `<namespace>/standalone-declaration-valid` rule for one catalog.
|
|
55
|
+
*
|
|
56
|
+
* A manifest with `standalone: false` declares that it is meaningless without
|
|
57
|
+
* one of its recommended packs. With `recommendedPacks` absent or empty that
|
|
58
|
+
* declaration is self-contradictory and nothing downstream — registry, Library
|
|
59
|
+
* UI, or `workspace/recommended-packs-retained` — can act on it.
|
|
60
|
+
*
|
|
61
|
+
* @experimental This API is unstable and may change without notice.
|
|
62
|
+
*/
|
|
63
|
+
export const makeStandaloneDeclarationValidRule = (options) => {
|
|
64
|
+
const ruleId = `${options.namespace}/standalone-declaration-valid`;
|
|
65
|
+
return {
|
|
66
|
+
id: ruleId,
|
|
67
|
+
description: "Extensions that are not standalone recommend at least one pack.",
|
|
68
|
+
kind: "advisory",
|
|
69
|
+
severity: "warning",
|
|
70
|
+
check: (context) => {
|
|
71
|
+
const manifest = manifestRecord(options.manifestJson(context));
|
|
72
|
+
if (manifest === undefined || manifest["standalone"] !== false) {
|
|
73
|
+
return Effect.succeed([]);
|
|
74
|
+
}
|
|
75
|
+
if (stringEntries(manifest["recommendedPacks"]).length > 0) {
|
|
76
|
+
return Effect.succeed([]);
|
|
77
|
+
}
|
|
78
|
+
return Effect.succeed([
|
|
79
|
+
{
|
|
80
|
+
kind: "advisory",
|
|
81
|
+
ruleId,
|
|
82
|
+
severity: "warning",
|
|
83
|
+
message: "`standalone` is set to false, which says this extension only works alongside one of its recommended packs, but no `recommendedPacks` are declared. " +
|
|
84
|
+
`To keep the restriction, add each pack's fully qualified name (\`@owner/packs/<name>\`) under \`recommendedPacks\` in \`${options.manifestFile}\`. ` +
|
|
85
|
+
`If the extension does work on its own, remove the \`standalone\` key from \`${options.manifestFile}\`.`,
|
|
86
|
+
location: { file: options.manifestFile },
|
|
87
|
+
},
|
|
88
|
+
]);
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
// -----------------------------------------------------------------------------
|
|
93
|
+
// <namespace>/recommended-packs-valid
|
|
94
|
+
// -----------------------------------------------------------------------------
|
|
95
|
+
/**
|
|
96
|
+
* Build the `<namespace>/recommended-packs-valid` rule for one catalog.
|
|
97
|
+
*
|
|
98
|
+
* `recommendedPacks` is typed `PackSpecSchema`, which permits a trailing
|
|
99
|
+
* version range, but nothing consumes one — recommendations are matched by
|
|
100
|
+
* name — and `axm help packs` tells authors to use the bare reference. One
|
|
101
|
+
* finding per offending entry.
|
|
102
|
+
*
|
|
103
|
+
* When published manifests have drained, the field can move to
|
|
104
|
+
* `PackFqnSchema` and this rule retires: decoding takes over.
|
|
105
|
+
*
|
|
106
|
+
* @experimental This API is unstable and may change without notice.
|
|
107
|
+
*/
|
|
108
|
+
export const makeRecommendedPacksValidRule = (options) => {
|
|
109
|
+
const ruleId = `${options.namespace}/recommended-packs-valid`;
|
|
110
|
+
return {
|
|
111
|
+
id: ruleId,
|
|
112
|
+
description: "Recommended packs are referenced by name without a version range.",
|
|
113
|
+
kind: "advisory",
|
|
114
|
+
severity: "warning",
|
|
115
|
+
check: (context) => {
|
|
116
|
+
const manifest = manifestRecord(options.manifestJson(context));
|
|
117
|
+
if (manifest === undefined) {
|
|
118
|
+
return Effect.succeed([]);
|
|
119
|
+
}
|
|
120
|
+
const findings = [];
|
|
121
|
+
for (const entry of stringEntries(manifest["recommendedPacks"])) {
|
|
122
|
+
const { fqn, range } = splitPackSpec(entry);
|
|
123
|
+
if (range === undefined) {
|
|
124
|
+
continue;
|
|
125
|
+
}
|
|
126
|
+
findings.push({
|
|
127
|
+
kind: "advisory",
|
|
128
|
+
ruleId,
|
|
129
|
+
severity: "warning",
|
|
130
|
+
message: `\`recommendedPacks\` entry '${entry}' pins a version range, but recommended packs are matched by name only, so the range is ignored. ` +
|
|
131
|
+
`Replace it with the bare pack reference '${fqn}' under \`recommendedPacks\` in \`${options.manifestFile}\`.`,
|
|
132
|
+
location: { file: options.manifestFile },
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
return Effect.succeed(findings);
|
|
136
|
+
},
|
|
137
|
+
};
|
|
138
|
+
};
|
|
139
|
+
//# sourceMappingURL=recommended-packs-rules.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared schema-delegation plumbing for `-schema-valid` rules.
|
|
3
|
+
*
|
|
4
|
+
* Every rule whose id ends in `-schema-valid` implements `check` by
|
|
5
|
+
* running the canonical schema through `Schema.decodeUnknownResult` with
|
|
6
|
+
* `onExcessProperty: "ignore"` and `errors: "all"`, then mapping the issues
|
|
7
|
+
* through `issuesToFindings`.
|
|
8
|
+
*
|
|
9
|
+
* The helper is intentionally narrow — only the surface the `-schema-valid`
|
|
10
|
+
* rules need.
|
|
11
|
+
*
|
|
12
|
+
* @experimental This API is unstable and may change without notice.
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
import * as Effect from "effect/Effect";
|
|
16
|
+
import * as Schema from "effect/Schema";
|
|
17
|
+
import type { AdvisoryFinding, Severity } from "../../rule.js";
|
|
18
|
+
/**
|
|
19
|
+
* Decode `input` against `schema` (excess keys ignored, all issues collected)
|
|
20
|
+
* and return one advisory finding per leaf issue. Success produces `[]`.
|
|
21
|
+
*
|
|
22
|
+
* `input` of `undefined` short-circuits to `[]` — the caller is expected to
|
|
23
|
+
* have already guarded on "manifest exists" via the complementary
|
|
24
|
+
* `-present` rule.
|
|
25
|
+
*
|
|
26
|
+
* @param ruleId - `<namespace>/<name>` id of the calling rule.
|
|
27
|
+
* @param severity - Severity to stamp on each emitted finding.
|
|
28
|
+
* @param file - Accessor-relative file path to stamp on `location.file`.
|
|
29
|
+
* @param schema - Canonical Effect schema; `Schema.decodeUnknownResult`
|
|
30
|
+
* runs with `onExcessProperty: "ignore"` and `errors: "all"`.
|
|
31
|
+
* @param input - Raw decoded JSON value to check (typically `subject.*Json`).
|
|
32
|
+
*
|
|
33
|
+
* @experimental This API is unstable and may change without notice.
|
|
34
|
+
*/
|
|
35
|
+
export declare const schemaDecodeFindings: <A, I>(ruleId: string, severity: Severity, file: string, schema: Schema.Codec<A, I>, input: unknown) => Effect.Effect<ReadonlyArray<AdvisoryFinding>>;
|
|
36
|
+
/**
|
|
37
|
+
* Read the top-level field names of a `Schema.Struct` value.
|
|
38
|
+
*
|
|
39
|
+
* Callers produce an `allowedKeys` set in one place, driven by the schema
|
|
40
|
+
* itself — no copy-paste of field names into rule bodies. If the schema
|
|
41
|
+
* gains a field the allowed-keys set grows by construction.
|
|
42
|
+
*
|
|
43
|
+
* @experimental This API is unstable and may change without notice.
|
|
44
|
+
*/
|
|
45
|
+
export declare const structFieldKeys: (struct: {
|
|
46
|
+
readonly fields: Readonly<Record<string, unknown>>;
|
|
47
|
+
}) => ReadonlySet<string>;
|
|
48
|
+
/**
|
|
49
|
+
* Enumerate top-level keys present on `input` that are not declared by
|
|
50
|
+
* `allowedKeys`. Returns one advisory finding per unknown key.
|
|
51
|
+
*
|
|
52
|
+
* `input` of `undefined` or non-object short-circuits to `[]`.
|
|
53
|
+
*
|
|
54
|
+
* @experimental This API is unstable and may change without notice.
|
|
55
|
+
*/
|
|
56
|
+
export declare const enumerateUnknownTopLevelKeys: (ruleId: string, severity: Severity, file: string, allowedKeys: ReadonlySet<string>, input: unknown) => ReadonlyArray<AdvisoryFinding>;
|
|
57
|
+
//# sourceMappingURL=schema-rule.d.ts.map
|