@W-22253778 Improve validate skill action

This commit is contained in:
jasmine.kaur 2026-04-30 08:26:55 +05:30
parent 119dc668d5
commit 9c0ec0805f
No known key found for this signature in database
GPG Key ID: A037296830C500E7
10 changed files with 179 additions and 21 deletions

View File

@ -153,7 +153,7 @@ const CONTENT_CHECKS: ContentCheck[] = [
errors: [
`skills/${dirName}/SKILL.md: frontmatter is not valid YAML.
${detail}
Wrap values that contain \`: \` (colon + space), such as long descriptions with parenthetical hints, in single or double quotes.`,
Ensure the description is wrapped in double quotes. If the value itself contains quotes or backslashes, escape them.`,
],
}
}
@ -189,6 +189,52 @@ Wrap values that contain \`: \` (colon + space), such as long descriptions with
return { errors: [] }
},
},
{
description: 'Frontmatter "description" value must be wrapped in double quotes',
run({ dirName, rawFrontmatter }) {
if (rawFrontmatter === null) return { errors: [] }
const descLine = rawFrontmatter.split(/\r?\n/).find((l) => l.startsWith("description:"))
if (!descLine) return { errors: [] }
const rawValue = descLine.slice(descLine.indexOf(":") + 1).trim()
if (!rawValue.startsWith('"') || !rawValue.endsWith('"')) {
return {
errors: [
`skills/${dirName}/SKILL.md: description value must be wrapped in double quotes — got: ${rawValue.slice(0, 60)}${rawValue.length > 60 ? "…" : ""}`,
],
}
}
return { errors: [] }
},
},
{
description:
'Special characters in description must be escaped (\\\\ and \\")',
run({ dirName, rawFrontmatter }) {
if (rawFrontmatter === null) return { errors: [] }
const descLine = rawFrontmatter.split(/\r?\n/).find((l) => l.startsWith("description:"))
if (!descLine) return { errors: [] }
const rawValue = descLine.slice(descLine.indexOf(":") + 1).trim()
if (!rawValue.startsWith('"') || !rawValue.endsWith('"')) return { errors: [] }
const inner = rawValue.slice(1, -1)
const issues: string[] = []
// Strip valid escape sequences (\\, \") then check for remaining backslashes or unescaped quotes
const stripped = inner.replace(/\\\\|\\"/g, "")
if (stripped.includes('"')) {
issues.push('unescaped " (use \\")')
}
if (stripped.includes("\\")) {
issues.push("unescaped \\ (use \\\\)")
}
if (issues.length > 0) {
return {
errors: [
`skills/${dirName}/SKILL.md: description contains ${issues.join(", ")}`,
],
}
}
return { errors: [] }
},
},
{
description: "SKILL.md must have a non-empty body (instructions after the frontmatter block)",
run({ dirName, body }) {
@ -236,6 +282,89 @@ Wrap values that contain \`: \` (colon + space), such as long descriptions with
return { errors: [] }
},
},
{
description: "Metadata field must be a key-value map (not scalar or array)",
run({ dirName, rawFrontmatter }) {
if (rawFrontmatter === null) return { errors: [] }
const meta = parseMetadataBlock(rawFrontmatter)
if (meta === null) return { errors: [] }
if (meta === "scalar") {
return {
errors: [
`skills/${dirName}/SKILL.md: "metadata" must be a key-value map, not an inline scalar — use indented sub-keys (e.g. metadata:\\n version: "1.0")`,
],
}
}
if (meta === "list") {
return {
errors: [
`skills/${dirName}/SKILL.md: "metadata" must be a key-value map, not a YAML list — use indented key-value pairs instead of "- " list items`,
],
}
}
return { errors: [] }
},
},
{
description: 'Metadata version (if present) must match X.Y pattern',
run({ dirName, rawFrontmatter }) {
if (rawFrontmatter === null) return { errors: [] }
const meta = parseMetadataBlock(rawFrontmatter)
if (meta === null || typeof meta === "string") return { errors: [] }
if (!meta.version) return { errors: [] }
if (!/^\d+\.\d+$/.test(meta.version)) {
return {
errors: [
`skills/${dirName}/SKILL.md: metadata.version "${meta.version}" does not match expected pattern (expected X.Y, e.g. "1.0")`,
],
}
}
return { errors: [] }
},
},
{
description: "Compatibility field (if present) must be at most 500 characters",
run({ dirName, frontmatter }) {
if (!frontmatter) return { errors: [] }
if (!("compatibility" in frontmatter)) return { errors: [] }
const len = frontmatter.compatibility?.length ?? 0
if (len > 500) {
return {
errors: [`skills/${dirName}/SKILL.md: compatibility is ${len} characters (maximum 500)`],
}
}
return { errors: [] }
},
},
{
description: "Allowed-tools field (if present) must be a string (not array or object)",
run({ dirName, rawFrontmatter }) {
if (rawFrontmatter === null) return { errors: [] }
const line = rawFrontmatter.split(/\r?\n/).find((l) => l.startsWith("allowed-tools:"))
if (!line) return { errors: [] }
const rawValue = line.slice(line.indexOf(":") + 1).trim()
if (rawValue.startsWith("[") || rawValue.startsWith("{")) {
return {
errors: [
`skills/${dirName}/SKILL.md: "allowed-tools" must be a plain string (space-separated tool names), not a YAML array or object — got: ${rawValue.slice(0, 60)}`,
],
}
}
const nextLineIdx = rawFrontmatter.split(/\r?\n/).indexOf(line) + 1
const lines = rawFrontmatter.split(/\r?\n/)
if (nextLineIdx < lines.length) {
const nextLine = lines[nextLineIdx]
if (nextLine.match(/^\s+- /)) {
return {
errors: [
`skills/${dirName}/SKILL.md: "allowed-tools" must be a plain string, not a YAML list — use space-separated tool names (e.g. "Bash Read Write")`,
],
}
}
}
return { errors: [] }
},
},
{
description: "Skill body should be under 500 lines for context efficiency",
run({ dirName, body }) {
@ -251,6 +380,35 @@ Wrap values that contain \`: \` (colon + space), such as long descriptions with
},
]
/**
* Extracts nested key-value pairs from the `metadata:` block in raw frontmatter.
* Returns `null` if no metadata block, `"scalar"` if metadata has an inline value,
* `"list"` if it contains YAML list items, or a `Record` of sub-keys.
*/
function parseMetadataBlock(rawFrontmatter: string): Record<string, string> | "scalar" | "list" | null {
const lines = rawFrontmatter.split(/\r?\n/)
const metaIdx = lines.findIndex((l) => /^metadata\s*:/.test(l))
if (metaIdx === -1) return null
const metaLine = lines[metaIdx]
const inlineValue = metaLine.slice(metaLine.indexOf(":") + 1).trim()
if (inlineValue && !inlineValue.startsWith("#")) return "scalar"
const result: Record<string, string> = {}
for (let i = metaIdx + 1; i < lines.length; i++) {
const line = lines[i]
if (!line.startsWith(" ") && !line.startsWith("\t")) break
const trimmed = line.trim()
if (trimmed.startsWith("- ")) return "list"
const colonIdx = trimmed.indexOf(":")
if (colonIdx === -1) continue
const key = trimmed.slice(0, colonIdx).trim()
const raw = trimmed.slice(colonIdx + 1).trim()
result[key] = raw.replace(/^(['"])([\s\S]*)\1$/, "$2")
}
return result
}
/**
* Returns the deduplicated list of top-level skill directory names that have
* changed relative to `base` (e.g. `origin/main`) and still exist on disk.

View File

@ -4,7 +4,7 @@ description: "Build, modify, debug, and deploy agents with Agentforce Agent Scri
license: Apache-2.0
compatibility: "Requires Agentforce license, API v66.0+, Einstein Agent User"
metadata:
version: "0.5.1"
version: "0.13"
last_updated: "2026-04-08"
---

View File

@ -8,16 +8,16 @@ Skill version changelog for developing-agentforce.
| Version | Date | Changes |
|---------|------|---------|
| 0.4.8 | 2026-03-17 | **Agent access guide + merge cleanup**: Adopted `agent-access-guide.md` from sf-permissions (import rules applied). Routed post-activation access step in Create and Deploy domains. Merged `preview-test-loop.md` content (jq trace diagnostics, fix strategies table, context variable limitations, utterance derivation) into `agent-validation-and-debugging.md`. Deleted orphaned `preview-test-loop.md`. Added custom object scanning guidance to Agent Spec creation. Refined post-action output field instructions. |
| 0.4.7 | 2026-03-15 | **Post-action session state fix**: Added explicit post-action instructions to prevent session state corruption by specifying output fields the agent must reference. Driven by T02 run-2026-03-15-vc-02 finding. |
| 0.4.6 | 2026-03-15 | **USER_MODE P0-1 fix**: Added static vs. dynamic SOQL guidelines to backing logic sections in `agent-design-and-spec-creation.md` and invocable Apex template. `AccessLevel.USER_MODE` required for dynamic SOQL. Added "Rules That Always Apply" cardinal rules block to SKILL.md (`--json` first, diagnose before fix, spec approval gate). |
| 0.4.5 | 2026-03-15 | **Full editorial pass + spec approval gate**: Conciseness pass across all 9 SKILL.md domains. Added spec approval hard gate (user must approve Agent Spec before implementation). Added `filter_from_agent` output visibility to Agent Spec template. Restructured Agent Spec inputs/outputs sections. Step 8 redirect to Diagnose Behavioral Issues workflow. |
| 0.4.4 | 2026-03-13 | **Staging + cleanup**: Moved unmerged reference files to `staging/` folder. Clarified live actions command syntax. Refined `agent-user-setup.md` license requirements and USER_MODE documentation. |
| 0.4.3 | 2026-03-12 | **sf-skills merge: production-gotchas + new domain**: Added "Diagnose Production Issues" task domain to SKILL.md (9 domains total). Routed `production-gotchas.md` as primary reference. Added `production-gotchas.md` as secondary reference in Diagnose Compilation (reserved keywords trigger). Added `WITH USER_MODE` object permissions warning to `agent-user-setup.md` Section 6.2. Archived orphan `agent-user-setup-and-perms.md`. Fixed stale SKILL.md reference (Section 2 → Section 6.2). |
| 0.4.2 | 2026-03-12 | **sf-skills merge: known-issues + one-at-a-time deploy**: Integrated `known-issues.md` into 6 of 8 SKILL.md domains with domain-specific loading triggers. Added one-at-a-time Apex stub deploy instruction to SKILL.md Create/Modify domains, `agent-design-and-spec-creation.md`, and `salesforce-cli-for-agents.md`. Moved Issue 16 (`connections:` → `connection messaging:`) to Resolved. |
| 0.4.0 | 2026-03-11 | **T03 test run + type mapping restructure**: Restructured Section 5 type mapping in `agent-design-and-spec-creation.md` into Primitive + Complex tables keyed by `target` type. Added steps 10 (Activate) and 11 (Verify published agent) to Create, Modify, and Deploy domains. |
| 0.3.2 | 2026-03-10 | **T02 post-fix run**: Platform-injected `show_command` tool diagnostic pattern added to `agent-validation-and-debugging.md`. Post-publish preview language strengthened in SKILL.md. |
| 0.3.0 | 2026-03-10 | **T02 first run + test framework**: Created testing framework (README, run structure, scoring rubric). First T02 run: 13/13 SUCCESS. |
| 0.2.0 | 2026-03-09 | **T01 first run**: Created T01 test scenario. First end-to-end test of skill. Identified `agent_type` inference gap. |
| 0.1.0 | 2026-03-08 | **Initial skill**: SKILL.md router with 8 task domains. 7 reference files. Agent Spec template. Asset library. |
| 0.12 | 2026-03-17 | **Agent access guide + merge cleanup**: Adopted `agent-access-guide.md` from sf-permissions (import rules applied). Routed post-activation access step in Create and Deploy domains. Merged `preview-test-loop.md` content (jq trace diagnostics, fix strategies table, context variable limitations, utterance derivation) into `agent-validation-and-debugging.md`. Deleted orphaned `preview-test-loop.md`. Added custom object scanning guidance to Agent Spec creation. Refined post-action output field instructions. |
| 0.11 | 2026-03-15 | **Post-action session state fix**: Added explicit post-action instructions to prevent session state corruption by specifying output fields the agent must reference. Driven by T02 run-2026-03-15-vc-02 finding. |
| 0.10 | 2026-03-15 | **USER_MODE P0-1 fix**: Added static vs. dynamic SOQL guidelines to backing logic sections in `agent-design-and-spec-creation.md` and invocable Apex template. `AccessLevel.USER_MODE` required for dynamic SOQL. Added "Rules That Always Apply" cardinal rules block to SKILL.md (`--json` first, diagnose before fix, spec approval gate). |
| 0.9 | 2026-03-15 | **Full editorial pass + spec approval gate**: Conciseness pass across all 9 SKILL.md domains. Added spec approval hard gate (user must approve Agent Spec before implementation). Added `filter_from_agent` output visibility to Agent Spec template. Restructured Agent Spec inputs/outputs sections. Step 8 redirect to Diagnose Behavioral Issues workflow. |
| 0.8 | 2026-03-13 | **Staging + cleanup**: Moved unmerged reference files to `staging/` folder. Clarified live actions command syntax. Refined `agent-user-setup.md` license requirements and USER_MODE documentation. |
| 0.7 | 2026-03-12 | **sf-skills merge: production-gotchas + new domain**: Added "Diagnose Production Issues" task domain to SKILL.md (9 domains total). Routed `production-gotchas.md` as primary reference. Added `production-gotchas.md` as secondary reference in Diagnose Compilation (reserved keywords trigger). Added `WITH USER_MODE` object permissions warning to `agent-user-setup.md` Section 6.2. Archived orphan `agent-user-setup-and-perms.md`. Fixed stale SKILL.md reference (Section 2 → Section 6.2). |
| 0.6 | 2026-03-12 | **sf-skills merge: known-issues + one-at-a-time deploy**: Integrated `known-issues.md` into 6 of 8 SKILL.md domains with domain-specific loading triggers. Added one-at-a-time Apex stub deploy instruction to SKILL.md Create/Modify domains, `agent-design-and-spec-creation.md`, and `salesforce-cli-for-agents.md`. Moved Issue 16 (`connections:` → `connection messaging:`) to Resolved. |
| 0.5 | 2026-03-11 | **T03 test run + type mapping restructure**: Restructured Section 5 type mapping in `agent-design-and-spec-creation.md` into Primitive + Complex tables keyed by `target` type. Added steps 10 (Activate) and 11 (Verify published agent) to Create, Modify, and Deploy domains. |
| 0.4 | 2026-03-10 | **T02 post-fix run**: Platform-injected `show_command` tool diagnostic pattern added to `agent-validation-and-debugging.md`. Post-publish preview language strengthened in SKILL.md. |
| 0.3 | 2026-03-10 | **T02 first run + test framework**: Created testing framework (README, run structure, scoring rubric). First T02 run: 13/13 SUCCESS. |
| 0.2 | 2026-03-09 | **T01 first run**: Created T01 test scenario. First end-to-end test of skill. Identified `agent_type` inference gap. |
| 0.1 | 2026-03-08 | **Initial skill**: SKILL.md router with 8 task domains. 7 reference files. Agent Spec template. Asset library. |

View File

@ -1,6 +1,6 @@
---
name: generating-apex-test
description: Generate and validate Apex test classes with TestDataFactory patterns, bulk testing (251+ records), mocking strategies, assertion best practices, and disciplined test-fix loops. Use this skill when creating new Apex test classes, improving test coverage, debugging and fixing failing Apex tests, running test execution and coverage analysis, or implementing testing patterns for triggers, services, controllers, batch jobs, queueables, and integrations. Triggers on *Test.cls, *_Test.cls files, sf apex run test workflows, coverage reports, test-fix loops. Do NOT trigger for production Apex code (use generating-apex) or Jest/LWC tests.
description: "Generate and validate Apex test classes with TestDataFactory patterns, bulk testing (251+ records), mocking strategies, assertion best practices, and disciplined test-fix loops. Use this skill when creating new Apex test classes, improving test coverage, debugging and fixing failing Apex tests, running test execution and coverage analysis, or implementing testing patterns for triggers, services, controllers, batch jobs, queueables, and integrations. Triggers on *Test.cls, *_Test.cls files, sf apex run test workflows, coverage reports, test-fix loops. Do NOT trigger for production Apex code (use generating-apex) or Jest/LWC tests."
---
# Generating Apex Tests

View File

@ -1,6 +1,6 @@
---
name: generating-apex
description: Primary Apex authoring skill for class generation, refactoring, and review. ALWAYS ACTIVATE when the user mentions Apex, .cls, triggers, or asks to create/refactor a class (service, selector, domain, batch, queueable, schedulable, invocable, DTO, utility, interface, abstract, exception, REST resource). Use this skill for requests involving SObject CRUD, mapping collections, fetching related records, scheduled jobs, batch jobs, trigger design, @AuraEnabled controllers, @RestResource endpoints, custom REST APIs, or code review of existing Apex.
description: "Primary Apex authoring skill for class generation, refactoring, and review. ALWAYS ACTIVATE when the user mentions Apex, .cls, triggers, or asks to create/refactor a class (service, selector, domain, batch, queueable, schedulable, invocable, DTO, utility, interface, abstract, exception, REST resource). Use this skill for requests involving SObject CRUD, mapping collections, fetching related records, scheduled jobs, batch jobs, trigger design, @AuraEnabled controllers, @RestResource endpoints, custom REST APIs, or code review of existing Apex."
---
# Generating Apex

View File

@ -1,6 +1,6 @@
---
name: generating-lightning-app
description: Build complete Salesforce Lightning Experience applications from natural language descriptions. Use this skill when a user requests a "complete app", "Lightning app", "business solution", "management system", or describes a scenario requiring multiple interconnected Salesforce components (objects, fields, pages, tabs, security). Orchestrates all required metadata types in proper dependency order to produce a deployable application.
description: "Build complete Salesforce Lightning Experience applications from natural language descriptions. Use this skill when a user requests a \"complete app\", \"Lightning app\", \"business solution\", \"management system\", or describes a scenario requiring multiple interconnected Salesforce components (objects, fields, pages, tabs, security). Orchestrates all required metadata types in proper dependency order to produce a deployable application."
metadata:
version: "1.0"
related-skills: generating-custom-object, generating-custom-field, generating-custom-tab, generating-flexipage, generating-custom-application, generating-flow, generating-validation-rule, generating-list-view, generating-permission-set

View File

@ -3,7 +3,7 @@ name: implementing-ui-bundle-agentforce-conversation-client
description: "MUST activate when the project contains a uiBundles/*/src/ directory and the task involves adding or modifying a chat widget, chatbot, or conversational AI. Use this skill when the user asks to add, embed, integrate, configure, style, or remove an agent, chatbot, chat widget, conversation client, or AI assistant. Covers styling (colors, fonts, spacing, borders), layout (inline vs floating, width, height, dimensions), and props (agentId, agentLabel, headerEnabled, showHeaderIcon, showAvatar, styleTokens). Activate when files under uiBundles/*/src/ import AgentforceConversationClient or when adding any chat or agent functionality to a page. Never create a custom agent, chatbot, or chat widget component."
metadata:
author: ACC Components
version: 1.0.1
version: "1.1"
package: "@salesforce/ui-bundle-template-feature-react-agentforce-conversation-client"
sdk-package: "@salesforce/agentforce-conversation-client"
last-updated: 2025-04-01

View File

@ -4,7 +4,7 @@ description: "Analyze production Agentforce agent behavior using session traces
allowed-tools: Bash Read Write Edit Glob Grep
license: Apache-2.0
metadata:
version: "0.5.1"
version: "0.6"
last_updated: "2026-04-08"
argument-hint: "<org-alias> [--agent-file <path>] [--session-id <id>] [--days <n>]"
compatibility: claude-code

View File

@ -1,6 +1,6 @@
---
name: switching-org
description: Switches the active Salesforce org (default target-org) using the Salesforce CLI. Use whenever someone wants to change which org CLI commands run against — whether they say "switch org", "change default org", "set my org to", "use alias", "point to", or describe wanting to work against a specific org, scratch org, sandbox, or production.
description: "Switches the active Salesforce org (default target-org) using the Salesforce CLI. Use whenever someone wants to change which org CLI commands run against — whether they say \"switch org\", \"change default org\", \"set my org to\", \"use alias\", \"point to\", or describe wanting to work against a specific org, scratch org, sandbox, or production."
compatibility: Salesforce CLI (sf) v2+
metadata:
version: "1.0"

View File

@ -4,7 +4,7 @@ description: "Write, run, and analyze structured test suites for Agentforce agen
allowed-tools: Bash Read Write Edit Glob Grep
license: Apache-2.0
metadata:
version: "0.5.1"
version: "0.6"
last_updated: "2026-04-08"
argument-hint: "<org-alias> --authoring-bundle <AgentName> [--utterances <file>] | run <org> --target <flow://Name>"
compatibility: claude-code