mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-08-09 00:42:46 +08:00
Merge branch 'main' into feat/agentforce-grid-skill
This commit is contained in:
commit
2c6aefabd7
18
CHANGELOG.md
18
CHANGELOG.md
@ -1,3 +1,21 @@
|
|||||||
|
# [1.29.0](https://github.com/forcedotcom/sf-skills/compare/1.28.0...1.29.0) (2026-07-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Release 2 new skills: platform-value-set-generate, dx-code-analyzer-custom-rule-create @W-23286064@ ([e07b6b3](https://github.com/forcedotcom/sf-skills/commit/e07b6b37b399107249f056213cf73f7e6d469653))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# [1.28.0](https://github.com/forcedotcom/sf-skills/compare/1.27.0...1.28.0) (2026-07-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* Release: Standardize skill folder structure scripts/, references/, assets/ @W-23262449@ ([3a358c3](https://github.com/forcedotcom/sf-skills/commit/3a358c3b1cce0e0df8c6ba09cc7cd48bb0295341))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# [1.27.0](https://github.com/forcedotcom/sf-skills/compare/1.26.0...1.27.0) (2026-06-29)
|
# [1.27.0](https://github.com/forcedotcom/sf-skills/compare/1.26.0...1.27.0) (2026-06-29)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@salesforce/afv-skills",
|
"name": "@salesforce/afv-skills",
|
||||||
"version": "1.27.0",
|
"version": "1.29.0",
|
||||||
"description": "Salesforce skills for Agentforce Vibes",
|
"description": "Salesforce skills for Agentforce Vibes",
|
||||||
"license": "CC-BY-NC-4.0",
|
"license": "CC-BY-NC-4.0",
|
||||||
"files": [
|
"files": [
|
||||||
|
|||||||
@ -73,12 +73,11 @@ agentforce-architecture-analyze/
|
|||||||
│ ├── finalize.py Merge waves → metadata_tree.json
|
│ ├── finalize.py Merge waves → metadata_tree.json
|
||||||
│ ├── render_architecture.py architecture.md + Mermaid graph
|
│ ├── render_architecture.py architecture.md + Mermaid graph
|
||||||
│ ├── resolve_invocation_target.py ID-prefix router for NGA InvocationTargets
|
│ ├── resolve_invocation_target.py ID-prefix router for NGA InvocationTargets
|
||||||
|
│ ├── emit_env.py Env-var emit helper (Phase 0.5)
|
||||||
|
│ ├── emit_result.py Final RESULT block renderer
|
||||||
|
│ ├── sanitize.py Stdin → safe-string filter
|
||||||
|
│ ├── write_emit_ctx.py Per-phase ctx writer
|
||||||
│ └── tests/ Unit + integration tests (unittest)
|
│ └── tests/ Unit + integration tests (unittest)
|
||||||
└── tools/
|
|
||||||
├── emit_env.py Env-var emit helper (Phase 0.5)
|
|
||||||
├── emit_result.py Final RESULT block renderer
|
|
||||||
├── sanitize.py Stdin → safe-string filter
|
|
||||||
└── write_emit_ctx.py Per-phase ctx writer
|
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@ -135,7 +135,7 @@ set -e
|
|||||||
# Final RESULT block is emit_result.py's stdout — MUST be the last thing
|
# Final RESULT block is emit_result.py's stdout — MUST be the last thing
|
||||||
# stdout sees. emit_result exits 0 on render success; the bash harness
|
# stdout sees. emit_result exits 0 on render success; the bash harness
|
||||||
# propagates main.py's rc for the agent's exit status.
|
# propagates main.py's rc for the agent's exit status.
|
||||||
WORK_DIR="$WORK_DIR" python3 "$SKILL_ROOT/tools/emit_result.py"
|
WORK_DIR="$WORK_DIR" python3 "$SKILL_ROOT/scripts/emit_result.py"
|
||||||
exit "$_rc"
|
exit "$_rc"
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -10,7 +10,7 @@ or malformed input could inject fake KEY=VALUE pairs that downstream consumers
|
|||||||
would treat as authoritative.
|
would treat as authoritative.
|
||||||
|
|
||||||
Usage:
|
Usage:
|
||||||
_safe=$(python3 "$SKILL/tools/sanitize.py" "$raw_value")
|
_safe=$(python3 "$SKILL/scripts/sanitize.py" "$raw_value")
|
||||||
|
|
||||||
Arguments:
|
Arguments:
|
||||||
argv[1] raw string (may be empty)
|
argv[1] raw string (may be empty)
|
||||||
@ -6,7 +6,7 @@ does `from config import ...`. Tests mirror that by inserting scripts/
|
|||||||
onto sys.path.
|
onto sys.path.
|
||||||
|
|
||||||
fs_guard is now sourced via ``from config import fs_guard`` (config.py
|
fs_guard is now sourced via ``from config import fs_guard`` (config.py
|
||||||
re-exports it from the plugin _shared/ package). No tools/ entry on
|
re-exports it from the plugin _shared/ package). No separate entry on
|
||||||
sys.path is required — config.py's dev-fallback walks up to the repo's
|
sys.path is required — config.py's dev-fallback walks up to the repo's
|
||||||
``plugins/investigating-agentforce-architecture/shared/`` when ``scripts/_shared/``
|
``plugins/investigating-agentforce-architecture/shared/`` when ``scripts/_shared/``
|
||||||
hasn't yet been mirrored by install.sh / the build script.
|
hasn't yet been mirrored by install.sh / the build script.
|
||||||
|
|||||||
@ -44,10 +44,10 @@ from tests.fixtures import genai_payloads as fx # type: ignore
|
|||||||
_REPO_SOQL_DIR = Path(__file__).resolve().parent.parent.parent / "assets" / "soql"
|
_REPO_SOQL_DIR = Path(__file__).resolve().parent.parent.parent / "assets" / "soql"
|
||||||
soql_loader.SOQL_DIR = _REPO_SOQL_DIR
|
soql_loader.SOQL_DIR = _REPO_SOQL_DIR
|
||||||
|
|
||||||
# emit_result.py lives under tools/; tests invoke it via subprocess so the
|
# emit_result.py lives under scripts/; tests invoke it via subprocess so the
|
||||||
# tool's RESULT-formatting logic is exercised under the same contract the
|
# tool's RESULT-formatting logic is exercised under the same contract the
|
||||||
# SKILL.md Bash wrapper uses.
|
# SKILL.md Bash wrapper uses.
|
||||||
_TOOLS_DIR = Path(__file__).resolve().parent.parent.parent / "tools"
|
_TOOLS_DIR = Path(__file__).resolve().parent.parent
|
||||||
|
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
@ -32,9 +32,9 @@ from . import _bootstrap # noqa: F401
|
|||||||
|
|
||||||
|
|
||||||
def _tools_dir() -> pathlib.Path:
|
def _tools_dir() -> pathlib.Path:
|
||||||
"""Absolute path to the skill's tools/ dir — where the scripts live."""
|
"""Absolute path to the skill's scripts/ dir — where the emit helpers live."""
|
||||||
here = pathlib.Path(__file__).resolve()
|
here = pathlib.Path(__file__).resolve()
|
||||||
return here.parent.parent.parent / "tools"
|
return here.parent.parent
|
||||||
|
|
||||||
|
|
||||||
def _run_script(script_name: str, env: dict) -> subprocess.CompletedProcess:
|
def _run_script(script_name: str, env: dict) -> subprocess.CompletedProcess:
|
||||||
@ -439,7 +439,7 @@ class EmitResultPositionalSafetyTests(unittest.TestCase):
|
|||||||
|
|
||||||
def test_build_block_happy_path_auto_promotes_without_asserting(self):
|
def test_build_block_happy_path_auto_promotes_without_asserting(self):
|
||||||
"""Sanity: the assertion does NOT fire under normal operation."""
|
"""Sanity: the assertion does NOT fire under normal operation."""
|
||||||
# Force import of emit_result from the tools/ dir.
|
# Force import of emit_result from the scripts/ dir.
|
||||||
import importlib.util
|
import importlib.util
|
||||||
spec = importlib.util.spec_from_file_location(
|
spec = importlib.util.spec_from_file_location(
|
||||||
"emit_result_mod", _tools_dir() / "emit_result.py",
|
"emit_result_mod", _tools_dir() / "emit_result.py",
|
||||||
|
|||||||
@ -83,7 +83,7 @@ import sys
|
|||||||
|
|
||||||
# local, dependency-free token scrub mirroring the patterns in
|
# local, dependency-free token scrub mirroring the patterns in
|
||||||
# `scripts/rest_client.redact_text`. Keeping the redactor inline preserves
|
# `scripts/rest_client.redact_text`. Keeping the redactor inline preserves
|
||||||
# the tools/ <-> scripts/ decoupling (tools/ is stdlib-only by policy) and
|
# the scripts/ emit helpers (stdlib-only by policy) and
|
||||||
# avoids adding a sys.path hop on every write_emit_ctx invocation. The two
|
# avoids adding a sys.path hop on every write_emit_ctx invocation. The two
|
||||||
# implementations must stay in sync; the shared regex shapes are:
|
# implementations must stay in sync; the shared regex shapes are:
|
||||||
# * Authorization: Bearer <token>
|
# * Authorization: Bearer <token>
|
||||||
@ -24,9 +24,9 @@ Methods:
|
|||||||
mkdir -p <project-root>/force-app/main/default/classes
|
mkdir -p <project-root>/force-app/main/default/classes
|
||||||
|
|
||||||
# Copy from the skill's apex directory
|
# Copy from the skill's apex directory
|
||||||
cp ../apex/AgentforceOptimizeService.cls \
|
cp ../assets/apex/AgentforceOptimizeService.cls \
|
||||||
<project-root>/force-app/main/default/classes/
|
<project-root>/force-app/main/default/classes/
|
||||||
cp ../apex/AgentforceOptimizeService.cls-meta.xml \
|
cp ../assets/apex/AgentforceOptimizeService.cls-meta.xml \
|
||||||
<project-root>/force-app/main/default/classes/
|
<project-root>/force-app/main/default/classes/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|||||||
@ -189,7 +189,7 @@ When no custom objects needed:
|
|||||||
- `referenceTo`: (Lookup only) The target object API name
|
- `referenceTo`: (Lookup only) The target object API name
|
||||||
- Include only objects and fields that are relevant to the flow being generated
|
- Include only objects and fields that are relevant to the flow being generated
|
||||||
|
|
||||||
## 🎯 Mandatory Enhancement Rules
|
## Mandatory Enhancement Rules
|
||||||
- **userPrompt**: REQUIRED.
|
- **userPrompt**: REQUIRED.
|
||||||
- If the user requests a **single flow**: use the user's prompt as-is.
|
- If the user requests a **single flow**: use the user's prompt as-is.
|
||||||
- If the user requests **multiple flows**: you MUST **split** the request and write a **separate, focused `userPrompt` for each individual flow**. Each `userPrompt` must describe only ONE flow. Do NOT pass the entire multi-flow request as a single `userPrompt`. See the multiple flows section below for examples.
|
- If the user requests **multiple flows**: you MUST **split** the request and write a **separate, focused `userPrompt` for each individual flow**. Each `userPrompt` must describe only ONE flow. Do NOT pass the entire multi-flow request as a single `userPrompt`. See the multiple flows section below for examples.
|
||||||
|
|||||||
@ -85,7 +85,7 @@ If no LBC exists (or not using LWC), select an SLDS Blueprint. See [references/c
|
|||||||
|
|
||||||
## Hook Naming Traps
|
## Hook Naming Traps
|
||||||
|
|
||||||
SLDS hook families do NOT all follow the same naming pattern. Agents frequently invent hooks that don't exist by assuming `{prefix}-{number}` works universally. **Always verify a hook exists** via the bundled `search-hooks.cjs` script or `metadata/hooks-index.json` before using it.
|
SLDS hook families do NOT all follow the same naming pattern. Agents frequently invent hooks that don't exist by assuming `{prefix}-{number}` works universally. **Always verify a hook exists** via the bundled `search-hooks.cjs` script or `assets/hooks-index.json` before using it.
|
||||||
|
|
||||||
### Trap 1: Font size hooks are NOT numbered
|
### Trap 1: Font size hooks are NOT numbered
|
||||||
|
|
||||||
@ -130,10 +130,10 @@ Run the appropriate search command **before** emitting any SLDS artifact:
|
|||||||
|
|
||||||
| Artifact | Verification command | Source of truth |
|
| Artifact | Verification command | Source of truth |
|
||||||
|----------|---------------------|-----------------|
|
|----------|---------------------|-----------------|
|
||||||
| Styling hook (`--slds-g-*`) | `node scripts/search-hooks.cjs --prefix "<hook-name>"` | `metadata/hooks-index.json` |
|
| Styling hook (`--slds-g-*`) | `node scripts/search-hooks.cjs --prefix "<hook-name>"` | `assets/hooks-index.json` |
|
||||||
| Utility class (`slds-*`) | `node scripts/search-utilities.cjs --search "<class-name>"` | `metadata/utilities-index.json` |
|
| Utility class (`slds-*`) | `node scripts/search-utilities.cjs --search "<class-name>"` | `assets/utilities-index.json` |
|
||||||
| Blueprint / CSS class | `node scripts/search-blueprints.cjs --search "<pattern>"` then read the YAML | `metadata/blueprints/components/*.yaml` |
|
| Blueprint / CSS class | `node scripts/search-blueprints.cjs --search "<pattern>"` then read the YAML | `assets/blueprints/components/*.yaml` |
|
||||||
| Icon | `node scripts/search-icons.cjs --query "<description>"` | `metadata/icon-metadata.json` |
|
| Icon | `node scripts/search-icons.cjs --query "<description>"` | `assets/icon-metadata.json` |
|
||||||
|
|
||||||
If the search returns no match: **do not use the artifact.** Find an alternative from the search results or build custom with verified hooks.
|
If the search returns no match: **do not use the artifact.** Find an alternative from the search results or build custom with verified hooks.
|
||||||
|
|
||||||
@ -187,10 +187,10 @@ This skill bundles comprehensive SLDS knowledge. Read files as needed -- don't r
|
|||||||
|
|
||||||
| Folder | Content | Index |
|
| Folder | Content | Index |
|
||||||
|--------|---------|-------|
|
|--------|---------|-------|
|
||||||
| `guidance/overviews/` | Foundational concepts (color, spacing, typography, etc.) | [guidance/README.md](guidance/README.md) |
|
| `references/overviews/` | Foundational concepts (color, spacing, typography, etc.) | [references/README.md](references/README.md) |
|
||||||
| `guidance/styling-hooks/` | Hook categories with detailed usage | [guidance/README.md](guidance/README.md) |
|
| `references/styling-hooks/` | Hook categories with detailed usage | [references/README.md](references/README.md) |
|
||||||
| `guidance/utilities/` | 27 utility class categories | [guidance/README.md](guidance/README.md) |
|
| `references/utilities/` | 27 utility class categories | [references/README.md](references/README.md) |
|
||||||
| `guidance/slds-development-guide.md` | Full SLDS development guide | -- |
|
| `references/slds-development-guide.md` | Full SLDS development guide | -- |
|
||||||
|
|
||||||
### Raw Metadata (structured data for lookup)
|
### Raw Metadata (structured data for lookup)
|
||||||
|
|
||||||
@ -198,10 +198,10 @@ This skill bundles comprehensive SLDS knowledge. Read files as needed -- don't r
|
|||||||
|
|
||||||
| File | Content | Lines |
|
| File | Content | Lines |
|
||||||
|------|---------|-------|
|
|------|---------|-------|
|
||||||
| `metadata/blueprints/components/*.yaml` | 85 blueprint specs (classes, variants, a11y, HTML) | ~50-200 each |
|
| `assets/blueprints/components/*.yaml` | 85 blueprint specs (classes, variants, a11y, HTML) | ~50-200 each |
|
||||||
| `metadata/hooks-index.json` | 523 hooks with values and CSS properties | ~6,300 |
|
| `assets/hooks-index.json` | 523 hooks with values and CSS properties | ~6,300 |
|
||||||
| `metadata/icon-metadata.json` | 1,732 icons with synonyms for search | ~38,500 |
|
| `assets/icon-metadata.json` | 1,732 icons with synonyms for search | ~38,500 |
|
||||||
| `metadata/utilities-index.json` | 1,147 utility classes with CSS rules | ~6,900 |
|
| `assets/utilities-index.json` | 1,147 utility classes with CSS rules | ~6,900 |
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -219,7 +219,7 @@ Identify:
|
|||||||
|
|
||||||
1. **If LWC**: Check the [Lightning Component Library](https://developer.salesforce.com/docs/component-library/overview/components) for an LBC
|
1. **If LWC**: Check the [Lightning Component Library](https://developer.salesforce.com/docs/component-library/overview/components) for an LBC
|
||||||
2. **Search blueprints**: `node scripts/search-blueprints.cjs --search "<pattern>"`
|
2. **Search blueprints**: `node scripts/search-blueprints.cjs --search "<pattern>"`
|
||||||
3. **Read the blueprint YAML**: `metadata/blueprints/components/<name>.yaml` for exact classes, modifiers, states, and accessibility requirements
|
3. **Read the blueprint YAML**: `assets/blueprints/components/<name>.yaml` for exact classes, modifiers, states, and accessibility requirements
|
||||||
4. **No match?** Build custom with hooks (see Phase 3)
|
4. **No match?** Build custom with hooks (see Phase 3)
|
||||||
|
|
||||||
Details: [references/component-selection.md](references/component-selection.md)
|
Details: [references/component-selection.md](references/component-selection.md)
|
||||||
@ -249,7 +249,7 @@ npx @salesforce-ux/slds-linter@latest lint <component-path>
|
|||||||
|
|
||||||
The linter catches hardcoded values, class overrides, and deprecated tokens. **Fix all violations before proceeding.** Do not rationalize violations as acceptable.
|
The linter catches hardcoded values, class overrides, and deprecated tokens. **Fix all violations before proceeding.** Do not rationalize violations as acceptable.
|
||||||
|
|
||||||
**Step 2: Verify no invented hooks.** Confirm every `--slds-g-*` hook in the output exists in `metadata/hooks-index.json`. Cross-reference against the T051 check in [checklists.md](checklists.md).
|
**Step 2: Verify no invented hooks.** Confirm every `--slds-g-*` hook in the output exists in `assets/hooks-index.json`. Cross-reference against the T051 check in [checklists.md](checklists.md).
|
||||||
|
|
||||||
**Step 3: Run through [checklists.md](checklists.md)** for the checks the linter cannot automate:
|
**Step 3: Run through [checklists.md](checklists.md)** for the checks the linter cannot automate:
|
||||||
- All `var(--slds-g-*)` have fallback values (T002)
|
- All `var(--slds-g-*)` have fallback values (T002)
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user