@aicf/agent-skills 1.0.0-rc.4

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 (145) hide show
  1. package/.codex-plugin/plugin.json +40 -0
  2. package/CHANGELOG.md +28 -0
  3. package/LICENSE +21 -0
  4. package/README.md +114 -0
  5. package/assets/aicf-agent-skills-icon.svg +7 -0
  6. package/assets/aicf-agent-skills-logo.svg +9 -0
  7. package/docs/codex-plugin-distribution.md +50 -0
  8. package/docs/installation.md +96 -0
  9. package/docs/public-release-checklist.md +57 -0
  10. package/docs/skill-authoring-standard.md +55 -0
  11. package/docs/skill-index.md +157 -0
  12. package/docs/validation.md +50 -0
  13. package/package.json +61 -0
  14. package/scripts/README.md +6 -0
  15. package/scripts/aicf-skills.mjs +51 -0
  16. package/scripts/check-release-readiness.mjs +197 -0
  17. package/scripts/check-skills-public.mjs +12 -0
  18. package/scripts/check-trigger-coverage.mjs +20 -0
  19. package/scripts/generate-skill-index.mjs +30 -0
  20. package/scripts/install-skills.mjs +31 -0
  21. package/scripts/lib/skill-common.mjs +511 -0
  22. package/scripts/validate-skills.mjs +13 -0
  23. package/skills/README.md +12 -0
  24. package/skills/aicf-action-lifecycle/SKILL.md +87 -0
  25. package/skills/aicf-action-lifecycle/assets/action-handler.template.ts +24 -0
  26. package/skills/aicf-action-lifecycle/assets/approval-record.json +9 -0
  27. package/skills/aicf-action-lifecycle/assets/prepared-action-record.json +11 -0
  28. package/skills/aicf-action-lifecycle/references/action-state-machine.md +17 -0
  29. package/skills/aicf-action-lifecycle/references/approval-patterns.md +9 -0
  30. package/skills/aicf-action-lifecycle/references/idempotency-and-audit.md +8 -0
  31. package/skills/aicf-action-lifecycle/references/verification-patterns.md +7 -0
  32. package/skills/aicf-capability-authoring/SKILL.md +100 -0
  33. package/skills/aicf-capability-authoring/assets/capability.manifest.yaml +31 -0
  34. package/skills/aicf-capability-authoring/assets/entity.manifest.yaml +12 -0
  35. package/skills/aicf-capability-authoring/assets/eval-case.yaml +12 -0
  36. package/skills/aicf-capability-authoring/references/checklist.md +13 -0
  37. package/skills/aicf-capability-authoring/references/examples.md +12 -0
  38. package/skills/aicf-capability-authoring/references/field-guide.md +13 -0
  39. package/skills/aicf-capability-authoring/references/manifest-decision-tree.md +10 -0
  40. package/skills/aicf-control-plane-ui/SKILL.md +90 -0
  41. package/skills/aicf-control-plane-ui/assets/control-plane-wireframe.md +29 -0
  42. package/skills/aicf-control-plane-ui/assets/ui-acceptance-checklist.md +11 -0
  43. package/skills/aicf-control-plane-ui/references/api-contracts.md +14 -0
  44. package/skills/aicf-control-plane-ui/references/approval-console.md +12 -0
  45. package/skills/aicf-control-plane-ui/references/control-plane-screens.md +14 -0
  46. package/skills/aicf-control-plane-ui/references/operational-ux.md +7 -0
  47. package/skills/aicf-controls-and-budgets/SKILL.md +88 -0
  48. package/skills/aicf-controls-and-budgets/assets/budget-fixture.json +15 -0
  49. package/skills/aicf-controls-and-budgets/assets/controls-policy.yaml +14 -0
  50. package/skills/aicf-controls-and-budgets/references/budget-policy.md +12 -0
  51. package/skills/aicf-controls-and-budgets/references/circuit-breakers.md +13 -0
  52. package/skills/aicf-controls-and-budgets/references/control-types.md +10 -0
  53. package/skills/aicf-docs-and-examples/SKILL.md +87 -0
  54. package/skills/aicf-docs-and-examples/assets/example-readme-template.md +21 -0
  55. package/skills/aicf-docs-and-examples/assets/provider-guide-template.md +17 -0
  56. package/skills/aicf-docs-and-examples/references/docs-style-guide.md +9 -0
  57. package/skills/aicf-docs-and-examples/references/example-app-checklist.md +9 -0
  58. package/skills/aicf-docs-and-examples/references/public-api-docs.md +11 -0
  59. package/skills/aicf-docs-and-examples/references/quickstart-template.md +17 -0
  60. package/skills/aicf-eval-authoring/SKILL.md +86 -0
  61. package/skills/aicf-eval-authoring/assets/eval-case.yaml +17 -0
  62. package/skills/aicf-eval-authoring/assets/eval-result.json +15 -0
  63. package/skills/aicf-eval-authoring/assets/promptfoo.config.yaml +12 -0
  64. package/skills/aicf-eval-authoring/references/deterministic-scorers.md +13 -0
  65. package/skills/aicf-eval-authoring/references/eval-rubric.md +10 -0
  66. package/skills/aicf-eval-authoring/references/golden-test-patterns.md +8 -0
  67. package/skills/aicf-eval-authoring/references/real-provider-evals.md +8 -0
  68. package/skills/aicf-governance-lifecycle/SKILL.md +91 -0
  69. package/skills/aicf-governance-lifecycle/assets/lifecycle-change-request.md +21 -0
  70. package/skills/aicf-governance-lifecycle/assets/riskwaiver.md +17 -0
  71. package/skills/aicf-governance-lifecycle/references/compatibility-checks.md +21 -0
  72. package/skills/aicf-governance-lifecycle/references/impact-analysis.md +13 -0
  73. package/skills/aicf-governance-lifecycle/references/lifecycle-state-machine.md +15 -0
  74. package/skills/aicf-governance-lifecycle/references/riskcompiler-rules.md +13 -0
  75. package/skills/aicf-migration/SKILL.md +87 -0
  76. package/skills/aicf-migration/assets/legacy-tool-inventory.csv +3 -0
  77. package/skills/aicf-migration/assets/migration-plan.md +19 -0
  78. package/skills/aicf-migration/references/conversion-playbook.md +9 -0
  79. package/skills/aicf-migration/references/legacy-tool-riskmap.md +14 -0
  80. package/skills/aicf-migration/references/migration-inventory.md +12 -0
  81. package/skills/aicf-migration/references/rollout-plan.md +12 -0
  82. package/skills/aicf-observability-replay/SKILL.md +88 -0
  83. package/skills/aicf-observability-replay/assets/replay-fixture.json +23 -0
  84. package/skills/aicf-observability-replay/assets/trace-to-golden-template.yaml +14 -0
  85. package/skills/aicf-observability-replay/references/redacted-telemetry.md +7 -0
  86. package/skills/aicf-observability-replay/references/replay-simulation.md +10 -0
  87. package/skills/aicf-observability-replay/references/trace-span-map.md +17 -0
  88. package/skills/aicf-observability-replay/references/trace-to-golden.md +12 -0
  89. package/skills/aicf-policy-and-risk/SKILL.md +88 -0
  90. package/skills/aicf-policy-and-risk/assets/policy-broker.template.ts +29 -0
  91. package/skills/aicf-policy-and-risk/assets/policy-decision-fixture.json +15 -0
  92. package/skills/aicf-policy-and-risk/references/deny-approval-allow-matrix.md +12 -0
  93. package/skills/aicf-policy-and-risk/references/policy-broker-contract.md +13 -0
  94. package/skills/aicf-policy-and-risk/references/risktier-rules.md +10 -0
  95. package/skills/aicf-policy-and-risk/references/semantic-invariants.md +9 -0
  96. package/skills/aicf-provider-conformance/SKILL.md +88 -0
  97. package/skills/aicf-provider-conformance/assets/provider-conformance-case.yaml +18 -0
  98. package/skills/aicf-provider-conformance/assets/provider-matrix.json +19 -0
  99. package/skills/aicf-provider-conformance/references/provider-normalization-matrix.md +14 -0
  100. package/skills/aicf-provider-conformance/references/provider-runtime-boundaries.md +10 -0
  101. package/skills/aicf-provider-conformance/references/schema-compatibility.md +8 -0
  102. package/skills/aicf-provider-conformance/references/tool-call-mapping.md +8 -0
  103. package/skills/aicf-release-hygiene/SKILL.md +85 -0
  104. package/skills/aicf-release-hygiene/assets/release-report-template.md +19 -0
  105. package/skills/aicf-release-hygiene/references/forbidden-artifacts.md +12 -0
  106. package/skills/aicf-release-hygiene/references/package-smoke-test.md +10 -0
  107. package/skills/aicf-release-hygiene/references/release-checklist.md +10 -0
  108. package/skills/aicf-release-hygiene/references/source-archive-rules.md +8 -0
  109. package/skills/aicf-runtime-integration/SKILL.md +87 -0
  110. package/skills/aicf-runtime-integration/assets/context-builder.template.ts +22 -0
  111. package/skills/aicf-runtime-integration/assets/handler-registry.template.ts +20 -0
  112. package/skills/aicf-runtime-integration/assets/runtime-integration-plan.md +23 -0
  113. package/skills/aicf-runtime-integration/references/capability-router-patterns.md +8 -0
  114. package/skills/aicf-runtime-integration/references/context-builder-patterns.md +8 -0
  115. package/skills/aicf-runtime-integration/references/handler-registry-patterns.md +8 -0
  116. package/skills/aicf-runtime-integration/references/policy-broker-adapter.md +8 -0
  117. package/skills/aicf-runtime-integration/references/runtime-integration-checklist.md +10 -0
  118. package/skills/aicf-security-redteam/SKILL.md +89 -0
  119. package/skills/aicf-security-redteam/assets/promptfoo-redteam.config.yaml +13 -0
  120. package/skills/aicf-security-redteam/assets/redteam-case.yaml +15 -0
  121. package/skills/aicf-security-redteam/references/prompt-injection-patterns.md +12 -0
  122. package/skills/aicf-security-redteam/references/redteam-acceptance.md +11 -0
  123. package/skills/aicf-security-redteam/references/security-test-pack-map.md +11 -0
  124. package/skills/aicf-security-redteam/references/tool-misuse-patterns.md +11 -0
  125. package/skills/aicf-skill-pack-maintenance/SKILL.md +88 -0
  126. package/skills/aicf-skill-pack-maintenance/assets/skill-template.md +52 -0
  127. package/skills/aicf-skill-pack-maintenance/references/overlap-prevention.md +9 -0
  128. package/skills/aicf-skill-pack-maintenance/references/plugin-packaging.md +8 -0
  129. package/skills/aicf-skill-pack-maintenance/references/skill-authoring-rules.md +10 -0
  130. package/skills/aicf-skill-pack-maintenance/references/trigger-evaluation.md +9 -0
  131. package/skills/aicf-storage-and-aws/SKILL.md +86 -0
  132. package/skills/aicf-storage-and-aws/assets/dynamodb-store.template.ts +21 -0
  133. package/skills/aicf-storage-and-aws/assets/postgres-store.template.ts +22 -0
  134. package/skills/aicf-storage-and-aws/assets/step-functions-approval.template.ts +15 -0
  135. package/skills/aicf-storage-and-aws/references/aws-adapter-boundaries.md +8 -0
  136. package/skills/aicf-storage-and-aws/references/least-privilege-iam.md +11 -0
  137. package/skills/aicf-storage-and-aws/references/step-functions-approval.md +10 -0
  138. package/skills/aicf-storage-and-aws/references/store-interface-map.md +10 -0
  139. package/skills/aicf-trust-redaction-retention/SKILL.md +88 -0
  140. package/skills/aicf-trust-redaction-retention/assets/redaction-policy.yaml +15 -0
  141. package/skills/aicf-trust-redaction-retention/assets/trust-labelled-context.json +18 -0
  142. package/skills/aicf-trust-redaction-retention/references/redaction-rules.md +8 -0
  143. package/skills/aicf-trust-redaction-retention/references/retention-rules.md +11 -0
  144. package/skills/aicf-trust-redaction-retention/references/taint-rules.md +9 -0
  145. package/skills/aicf-trust-redaction-retention/references/trust-labels.md +16 -0
@@ -0,0 +1,50 @@
1
+ # Validation
2
+
3
+ Run validation from `agent-skills/`.
4
+
5
+ ```bash
6
+ npm run validate
7
+ npm run check:triggers
8
+ npm run index
9
+ npm run check:index
10
+ npm run test
11
+ npm run check:public
12
+ npm run check:release
13
+ npm run check
14
+ ```
15
+
16
+ Expected output from a healthy package includes:
17
+
18
+ - `Skill validation passed`
19
+ - `Trigger coverage passed`
20
+ - `Generated ... docs/skill-index.md`
21
+ - `Skill index is current`
22
+ - `Agent skills release readiness passed`
23
+
24
+ ## What Each Check Covers
25
+
26
+ - `validate`: skill folder names, `SKILL.md` frontmatter, MIT license, AICF metadata,
27
+ required sections, one-level references/assets, parseable JSON/YAML, and public-safety
28
+ markers.
29
+ - `check:triggers`: every real skill has positive and negative trigger examples, and
30
+ fixture description terms match the skill descriptions.
31
+ - `index`: regenerates `docs/skill-index.md` from skill metadata and trigger fixtures.
32
+ - `check:index`: verifies `docs/skill-index.md` is current without writing files.
33
+ - `test`: runs deterministic Node tests for validation, trigger coverage, package
34
+ metadata, npm dry-run contents, and install behavior.
35
+ - `check:public`: scans npm dry-run contents for forbidden paths, archives, generated
36
+ output, dependency folders, and high-confidence credential markers.
37
+ - `check:release`: verifies the final 17-skill inventory, plugin metadata, docs, package
38
+ scripts, relative asset paths, trigger fixtures, npm dry-run contents, and public
39
+ package hygiene.
40
+
41
+ ## Common Failures
42
+
43
+ - Stale index: run `npm run index`, then `npm run check:index`.
44
+ - Missing trigger coverage: update `tests/fixtures/trigger-prompts.json`.
45
+ - Broken reference link: link only to one-level `references/`, `assets/`, or `scripts/`
46
+ files inside the skill folder.
47
+ - Package public-safety failure: remove the unsafe text or move local/private material
48
+ to an ignored path outside the package.
49
+ - Pack content failure: update `package.json` `files`, package docs, or the
50
+ public-safety rules so dry-run contents match the release boundary.
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@aicf/agent-skills",
3
+ "version": "1.0.0-rc.4",
4
+ "description": "Agent Skills for building, integrating, testing, auditing, and releasing AICF-based AI capability systems.",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "private": false,
8
+ "homepage": "https://github.com/xennon101/ai-capability-framework/tree/main/agent-skills#readme",
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/xennon101/ai-capability-framework.git",
12
+ "directory": "agent-skills"
13
+ },
14
+ "bugs": {
15
+ "url": "https://github.com/xennon101/ai-capability-framework/issues"
16
+ },
17
+ "keywords": [
18
+ "aicf",
19
+ "agent-skills",
20
+ "codex",
21
+ "capabilities",
22
+ "evals",
23
+ "governance",
24
+ "runtime",
25
+ "tool-calling"
26
+ ],
27
+ "files": [
28
+ ".codex-plugin",
29
+ "skills",
30
+ "scripts",
31
+ "docs",
32
+ "assets",
33
+ "README.md",
34
+ "LICENSE",
35
+ "CHANGELOG.md"
36
+ ],
37
+ "bin": {
38
+ "aicf-skills": "scripts/aicf-skills.mjs"
39
+ },
40
+ "scripts": {
41
+ "validate": "node scripts/validate-skills.mjs ./skills",
42
+ "check:public": "node scripts/check-skills-public.mjs .",
43
+ "check:triggers": "node scripts/check-trigger-coverage.mjs ./skills ./tests/fixtures/trigger-prompts.json",
44
+ "index": "node scripts/generate-skill-index.mjs ./skills ./docs/skill-index.md",
45
+ "check:index": "node scripts/generate-skill-index.mjs ./skills ./docs/skill-index.md --check",
46
+ "test": "node --test tests/*.test.mjs",
47
+ "check:release": "node scripts/check-release-readiness.mjs",
48
+ "check": "npm run validate && npm run check:triggers && npm run check:index && npm run test && npm run check:public && npm run check:release",
49
+ "pack:dry": "npm pack --dry-run"
50
+ },
51
+ "engines": {
52
+ "node": ">=20"
53
+ },
54
+ "dependencies": {
55
+ "yaml": "^2.8.0"
56
+ },
57
+ "devDependencies": {},
58
+ "publishConfig": {
59
+ "access": "public"
60
+ }
61
+ }
@@ -0,0 +1,6 @@
1
+ # Scripts
2
+
3
+ Validation, trigger coverage, indexing, install, and CLI scripts are added in
4
+ S2.
5
+
6
+ S1 reserves this directory for the package skeleton.
@@ -0,0 +1,51 @@
1
+ #!/usr/bin/env node
2
+ import { spawnSync } from "node:child_process";
3
+ import {
4
+ packageRoot,
5
+ resolvePath,
6
+ skillSummaries
7
+ } from "./lib/skill-common.mjs";
8
+
9
+ const command = process.argv[2] ?? "help";
10
+ const root = packageRoot();
11
+
12
+ switch (command) {
13
+ case "validate":
14
+ run("validate-skills.mjs", ["./skills"]);
15
+ break;
16
+ case "check-public":
17
+ run("check-skills-public.mjs", ["."]);
18
+ break;
19
+ case "check-triggers":
20
+ run("check-trigger-coverage.mjs", ["./skills", "./tests/fixtures/trigger-prompts.json"]);
21
+ break;
22
+ case "index":
23
+ run("generate-skill-index.mjs", ["./skills", "./docs/skill-index.md"]);
24
+ break;
25
+ case "install":
26
+ run("install-skills.mjs", process.argv.slice(3));
27
+ break;
28
+ case "list":
29
+ list();
30
+ break;
31
+ default:
32
+ console.log("Usage: aicf-skills <validate|check-public|check-triggers|index|install|list>");
33
+ process.exitCode = command === "help" ? 0 : 1;
34
+ }
35
+
36
+ function run(script, args) {
37
+ const result = spawnSync(process.execPath, [resolvePath(root, `./scripts/${script}`), ...args], {
38
+ cwd: root,
39
+ stdio: "inherit"
40
+ });
41
+ process.exitCode = result.status ?? 1;
42
+ }
43
+
44
+ function list() {
45
+ const skills = skillSummaries(resolvePath(root, "./skills"));
46
+ if (skills.length === 0) {
47
+ console.log("No AICF Agent Skills are installed in this package yet.");
48
+ return;
49
+ }
50
+ for (const skill of skills) console.log(`${skill.name}\t${skill.description}`);
51
+ }
@@ -0,0 +1,197 @@
1
+ #!/usr/bin/env node
2
+ import { existsSync } from "node:fs";
3
+ import path from "node:path";
4
+ import {
5
+ expectedSkillNames,
6
+ forbiddenPathFailures,
7
+ listSkillDirs,
8
+ loadTriggerFixture,
9
+ normalizePath,
10
+ npmPackFiles,
11
+ packageRoot,
12
+ parseSkillFile,
13
+ publicPackageFailures,
14
+ readJson,
15
+ readText,
16
+ validateSkills
17
+ } from "./lib/skill-common.mjs";
18
+
19
+ const root = packageRoot();
20
+ const failures = [];
21
+
22
+ checkPackageMetadata();
23
+ checkPluginMetadata();
24
+ checkSkills();
25
+ checkTriggerFixtures();
26
+ checkDocs();
27
+ checkPackContents();
28
+ checkPublicScan();
29
+
30
+ if (failures.length > 0) {
31
+ console.error(failures.join("\n"));
32
+ process.exitCode = 1;
33
+ } else {
34
+ console.log("Agent skills release readiness passed.");
35
+ }
36
+
37
+ function checkPackageMetadata() {
38
+ const pkg = readJson(path.join(root, "package.json"));
39
+ expect(pkg.name === "@aicf/agent-skills", "package.json: name must be @aicf/agent-skills.");
40
+ expect(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(pkg.version), "package.json: version must be semver-like.");
41
+ expect(pkg.private === false, "package.json: private must be false.");
42
+ expect(pkg.license === "MIT", "package.json: license must be MIT.");
43
+ expect(pkg.publishConfig?.access === "public", "package.json: publishConfig.access must be public.");
44
+ expect(pkg.type === "module", "package.json: type must be module.");
45
+ expect(pkg.bin?.["aicf-skills"] === "scripts/aicf-skills.mjs", "package.json: bin.aicf-skills must point to scripts/aicf-skills.mjs.");
46
+
47
+ for (const rel of [
48
+ "scripts/validate-skills.mjs",
49
+ "scripts/check-skills-public.mjs",
50
+ "scripts/check-trigger-coverage.mjs",
51
+ "scripts/generate-skill-index.mjs",
52
+ "scripts/install-skills.mjs",
53
+ "scripts/aicf-skills.mjs",
54
+ "scripts/check-release-readiness.mjs"
55
+ ]) {
56
+ requireFile(rel);
57
+ }
58
+
59
+ const requiredScripts = {
60
+ validate: "node scripts/validate-skills.mjs ./skills",
61
+ "check:public": "node scripts/check-skills-public.mjs .",
62
+ "check:triggers": "node scripts/check-trigger-coverage.mjs ./skills ./tests/fixtures/trigger-prompts.json",
63
+ index: "node scripts/generate-skill-index.mjs ./skills ./docs/skill-index.md",
64
+ "check:index": "node scripts/generate-skill-index.mjs ./skills ./docs/skill-index.md --check",
65
+ test: "node --test tests/*.test.mjs",
66
+ "check:release": "node scripts/check-release-readiness.mjs",
67
+ "pack:dry": "npm pack --dry-run"
68
+ };
69
+ for (const [scriptName, expected] of Object.entries(requiredScripts)) {
70
+ expect(pkg.scripts?.[scriptName] === expected, `package.json: script ${scriptName} must be "${expected}".`);
71
+ }
72
+ expect(String(pkg.scripts?.check ?? "").includes("npm run check:index"), "package.json: check must include check:index.");
73
+ expect(String(pkg.scripts?.check ?? "").includes("npm run check:release"), "package.json: check must include check:release.");
74
+
75
+ for (const requiredFileEntry of [".codex-plugin", "skills", "scripts", "docs", "assets", "README.md", "LICENSE", "CHANGELOG.md"]) {
76
+ expect(pkg.files?.includes(requiredFileEntry), `package.json: files must include ${requiredFileEntry}.`);
77
+ }
78
+ }
79
+
80
+ function checkPluginMetadata() {
81
+ const pkg = readJson(path.join(root, "package.json"));
82
+ const plugin = readJson(path.join(root, ".codex-plugin", "plugin.json"));
83
+ expect(plugin.name === "aicf-agent-skills", ".codex-plugin/plugin.json: name must be aicf-agent-skills.");
84
+ expect(plugin.version === pkg.version, ".codex-plugin/plugin.json: version must match package.json.");
85
+ expect(plugin.license === "MIT", ".codex-plugin/plugin.json: license must be MIT.");
86
+ expect(plugin.skills === "./skills/", ".codex-plugin/plugin.json: skills must be ./skills/.");
87
+ checkRelativeExistingPath(plugin.interface?.composerIcon, "composerIcon");
88
+ checkRelativeExistingPath(plugin.interface?.logo, "logo");
89
+ }
90
+
91
+ function checkSkills() {
92
+ const skillsRoot = path.join(root, "skills");
93
+ const actualNames = listSkillDirs(skillsRoot).map((skillDir) => path.basename(skillDir)).sort();
94
+ const expectedNames = [...expectedSkillNames].sort();
95
+ expect(JSON.stringify(actualNames) === JSON.stringify(expectedNames), `skills/: expected exactly ${expectedNames.length} skills.`);
96
+
97
+ for (const failure of validateSkills(skillsRoot, { root })) failures.push(failure);
98
+
99
+ const pkg = readJson(path.join(root, "package.json"));
100
+ for (const skillName of expectedNames) {
101
+ const parsed = parseSkillFile(path.join(skillsRoot, skillName, "SKILL.md"));
102
+ expect(parsed.frontmatter.license === "MIT", `${skillName}: license must be MIT.`);
103
+ expect(parsed.frontmatter.metadata?.["aicf.skill.package"] === pkg.name, `${skillName}: metadata package must match package.json.`);
104
+ expect(parsed.frontmatter.metadata?.["aicf.skill.version"] === pkg.version, `${skillName}: metadata version must match package.json.`);
105
+ }
106
+ }
107
+
108
+ function checkTriggerFixtures() {
109
+ const fixture = loadTriggerFixture(path.join(root, "tests", "fixtures", "trigger-prompts.json"));
110
+ const byName = new Map(fixture.skills.map((entry) => [entry.name, entry]));
111
+ for (const skillName of expectedSkillNames) {
112
+ const entry = byName.get(skillName);
113
+ expect(Boolean(entry), `${skillName}: trigger fixture is required.`);
114
+ expect(Array.isArray(entry?.positive) && entry.positive.length > 0, `${skillName}: positive trigger fixtures are required.`);
115
+ expect(Array.isArray(entry?.negative) && entry.negative.length > 0, `${skillName}: negative trigger fixtures are required.`);
116
+ }
117
+ }
118
+
119
+ function checkDocs() {
120
+ const requiredDocs = {
121
+ "README.md": ["builder skills", "not AICF runtime capabilities", "npm run check", "https://developers.openai.com/codex/skills"],
122
+ "docs/installation.md": ["../.agents/skills", "$HOME/.agents/skills", "codex plugin marketplace add", "npm package"],
123
+ "docs/skill-authoring-standard.md": ["frontmatter", "required sections", "one-level", "public-safe"],
124
+ "docs/validation.md": ["npm run check:index", "npm run check:release", "common failures", "expected output"],
125
+ "docs/public-release-checklist.md": ["npm run check", "npm run pack:dry", "plugin manifest", "version consistency"],
126
+ "docs/codex-plugin-distribution.md": [".codex-plugin/plugin.json", "./skills/", "relative asset paths", "Codex plugin"],
127
+ "docs/skill-index.md": expectedSkillNames,
128
+ "skills/README.md": ["17", "source of truth", "install script"]
129
+ };
130
+
131
+ for (const [rel, terms] of Object.entries(requiredDocs)) {
132
+ requireFile(rel);
133
+ const content = readText(path.join(root, rel));
134
+ const lowerContent = content.toLowerCase();
135
+ for (const term of terms) {
136
+ expect(lowerContent.includes(String(term).toLowerCase()), `${rel}: must mention ${term}.`);
137
+ }
138
+ }
139
+ }
140
+
141
+ function checkPackContents() {
142
+ const files = npmPackFiles(root);
143
+ const fileSet = new Set(files);
144
+ const requiredFiles = [
145
+ "README.md",
146
+ "LICENSE",
147
+ "CHANGELOG.md",
148
+ "package.json",
149
+ ".codex-plugin/plugin.json",
150
+ "docs/installation.md",
151
+ "docs/validation.md",
152
+ "docs/public-release-checklist.md",
153
+ "docs/codex-plugin-distribution.md",
154
+ "docs/skill-authoring-standard.md",
155
+ "docs/skill-index.md",
156
+ "assets/aicf-agent-skills-icon.svg",
157
+ "assets/aicf-agent-skills-logo.svg",
158
+ "scripts/aicf-skills.mjs",
159
+ "scripts/check-release-readiness.mjs"
160
+ ];
161
+
162
+ for (const skillName of expectedSkillNames) {
163
+ requiredFiles.push(`skills/${skillName}/SKILL.md`);
164
+ }
165
+ for (const rel of requiredFiles) {
166
+ expect(fileSet.has(rel), `npm dry-run package must include ${rel}.`);
167
+ }
168
+
169
+ for (const file of files) {
170
+ for (const failure of forbiddenPathFailures(file, "npm package")) failures.push(failure);
171
+ expect(!file.startsWith("tests/"), `npm dry-run package must not include tests: ${file}.`);
172
+ expect(!file.startsWith(".agents/"), `npm dry-run package must not include a local skill mirror: ${file}.`);
173
+ expect(!file.includes("node_modules/"), `npm dry-run package must not include dependencies: ${file}.`);
174
+ }
175
+ }
176
+
177
+ function checkPublicScan() {
178
+ for (const failure of publicPackageFailures(root)) failures.push(failure);
179
+ }
180
+
181
+ function checkRelativeExistingPath(value, label) {
182
+ expect(typeof value === "string" && value.length > 0, `.codex-plugin/plugin.json: ${label} is required.`);
183
+ if (typeof value !== "string") return;
184
+ expect(!path.isAbsolute(value), `.codex-plugin/plugin.json: ${label} must be relative.`);
185
+ expect(!/^[a-z]+:/i.test(value), `.codex-plugin/plugin.json: ${label} must not be a URL.`);
186
+ const normalized = normalizePath(value);
187
+ expect(!normalized.startsWith("../"), `.codex-plugin/plugin.json: ${label} must stay inside the package.`);
188
+ requireFile(normalized);
189
+ }
190
+
191
+ function requireFile(rel) {
192
+ expect(existsSync(path.join(root, rel)), `${rel}: required file is missing.`);
193
+ }
194
+
195
+ function expect(condition, message) {
196
+ if (!condition) failures.push(message);
197
+ }
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ import { packageRoot, publicPackageFailures, resolvePath } from "./lib/skill-common.mjs";
3
+
4
+ const root = resolvePath(packageRoot(), process.argv[2] ?? ".");
5
+ const failures = publicPackageFailures(root);
6
+
7
+ if (failures.length > 0) {
8
+ console.error(failures.join("\n"));
9
+ process.exitCode = 1;
10
+ } else {
11
+ console.log(`Skills package public hygiene passed for ${root}.`);
12
+ }
@@ -0,0 +1,20 @@
1
+ #!/usr/bin/env node
2
+ import { checkTriggerCoverage, packageRoot, resolvePath } from "./lib/skill-common.mjs";
3
+
4
+ const root = packageRoot();
5
+ const skillsRoot = resolvePath(root, process.argv[2] ?? "./skills");
6
+ const fixturePath = resolvePath(root, process.argv[3] ?? "./tests/fixtures/trigger-prompts.json");
7
+
8
+ try {
9
+ const { failures, warnings } = checkTriggerCoverage(skillsRoot, fixturePath);
10
+ for (const warning of warnings) console.warn(`warning: ${warning}`);
11
+ if (failures.length > 0) {
12
+ console.error(failures.join("\n"));
13
+ process.exitCode = 1;
14
+ } else {
15
+ console.log("Trigger coverage check passed.");
16
+ }
17
+ } catch (error) {
18
+ console.error(error.message);
19
+ process.exitCode = 1;
20
+ }
@@ -0,0 +1,30 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ generateSkillIndex,
4
+ packageRoot,
5
+ readText,
6
+ resolvePath,
7
+ writeText
8
+ } from "./lib/skill-common.mjs";
9
+
10
+ const root = packageRoot();
11
+ const args = process.argv.slice(2);
12
+ const checkOnly = args.includes("--check");
13
+ const positional = args.filter((arg) => arg !== "--check");
14
+ const skillsRoot = resolvePath(root, positional[0] ?? "./skills");
15
+ const outputPath = resolvePath(root, positional[1] ?? "./docs/skill-index.md");
16
+ const fixturePath = resolvePath(root, "./tests/fixtures/trigger-prompts.json");
17
+ const expected = generateSkillIndex(skillsRoot, fixturePath);
18
+
19
+ if (checkOnly) {
20
+ const actual = readText(outputPath);
21
+ if (actual !== expected) {
22
+ console.error(`${outputPath} is stale. Run npm run index.`);
23
+ process.exitCode = 1;
24
+ } else {
25
+ console.log(`Skill index is current: ${outputPath}.`);
26
+ }
27
+ } else {
28
+ writeText(outputPath, expected);
29
+ console.log(`Generated ${outputPath}.`);
30
+ }
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env node
2
+ import { installSkills, packageRoot, resolvePath } from "./lib/skill-common.mjs";
3
+
4
+ const args = process.argv.slice(2);
5
+ const target = valueAfter(args, "--target");
6
+ const force = args.includes("--force");
7
+ const allowOutside = args.includes("--allow-outside");
8
+ const root = packageRoot();
9
+
10
+ try {
11
+ const result = installSkills({
12
+ skillsRoot: resolvePath(root, "./skills"),
13
+ target,
14
+ force,
15
+ allowOutside,
16
+ root
17
+ });
18
+ if (result.installed.length === 0) {
19
+ console.log(`No skills to install into ${result.target}.`);
20
+ } else {
21
+ console.log(`Installed ${result.installed.length} skill(s) into ${result.target}: ${result.installed.join(", ")}`);
22
+ }
23
+ } catch (error) {
24
+ console.error(error.message);
25
+ process.exitCode = 1;
26
+ }
27
+
28
+ function valueAfter(args, flag) {
29
+ const index = args.indexOf(flag);
30
+ return index >= 0 ? args[index + 1] : undefined;
31
+ }