@salesforce/capg-client
v1.4.1
Published
TypeScript client library for CAPG (Coding Agent Policy Governance) data fetching
Readme
CAPG Client Library
TypeScript client library for fetching governance policies from CAPG (Coding Agent Policy Governance) Hub Org.
Overview
The CAPG Client Library provides a simple, type-safe interface for Salesforce coding agents (AFV, VaaS, Codey) to fetch governance policies and tool configurations from the CAPG Hub Org.
Features
- Simple unified API via
CAPGClientclass - Fetch governance policies from Salesforce orgs via Connect API
- Fetch enforcement mechanisms as ready-to-dispatch commands, with automatic client-side consolidation (dedup + sort + join) for
CODE_ANALYZER - Fetch policies and enforcement mechanisms together in parallel via a single batch call
- Check if governance is enabled (first gate for performance)
- Explicit org alias required for all operations (no auto-detection)
Result<T, E>pattern for type-safe error handling (no thrown exceptions)- AFV pattern support (early return optimization)
- Comprehensive input validation
- Credential redaction in logs and errors
- 96%+ test coverage
Installation
npm install @salesforce/capg-clientQuick Start
The library provides a simple unified API via CAPGClient. All operations use the Result<T, E> pattern for type-safe error handling.
import { CAPGClient, isOk, isErr } from '@salesforce/capg-client';
const client = new CAPGClient();
// Step 1: Check if governance is enabled (FIRST GATE - early return optimization)
const isEnabled = await client.checkGovernanceEnabled('myHubOrg');
if (!isEnabled) {
console.log('Governance disabled, skipping policy fetch');
return; // Early return - 75% faster when governance is disabled
}
// Step 2: Fetch policies (only if governance is enabled)
const result = await client.fetchPolicies({}, 'myHubOrg');
if (isOk(result)) {
const { policies } = result.value;
console.log(`Fetched ${policies.length} policies`);
// Access policy data
policies.forEach((policy) => {
console.log(`${policy.policyCode}: ${policy.name}`);
console.log(policy.ruleContent); // Markdown rule for LLM
});
} else {
console.error(`Error: ${result.error.message}`);
console.error(`Suggested action: ${result.error.suggestedAction}`);
}AFV Pattern (Recommended)
Always check governance first to enable early returns:
const client = new CAPGClient();
// FIRST GATE: Check governance (never throws)
const isEnabled = await client.checkGovernanceEnabled(orgAlias);
if (!isEnabled) return; // Skip policy fetch if disabled
// Only fetch if enabled
const result = await client.fetchPolicies({}, orgAlias);
if (isOk(result)) {
// Use policies
console.log(result.value.policies);
}Enforcement Mechanisms
Fetch dispatchable commands (e.g. Code Analyzer invocations) derived from an org's enforcement mechanisms. Consolidation (dedup, sort, join) happens inside the call — consumers just get back ready-to-run commands:
const client = new CAPGClient();
const isEnabled = await client.checkGovernanceEnabled(orgAlias);
if (!isEnabled) return;
const result = await client.getEnforcementMechanisms(orgAlias, {
toolType: 'CODE_ANALYZER',
includeDisabled: false,
});
if (isOk(result)) {
result.value.forEach((command) => {
console.log(`${command.tool}: ${command.command}`);
});
} else {
console.error(`Error: ${result.error.message}`);
}Or fetch policies and enforcement mechanisms together in one batch call (runs in parallel; each half succeeds or fails independently):
const { policies, enforcementMechanisms } = await client.getPoliciesAndEnforcementMechanisms(orgAlias);
if (isOk(policies)) {
console.log(`Fetched ${policies.value.policies.length} policies`);
}
if (isOk(enforcementMechanisms)) {
console.log(`Fetched ${enforcementMechanisms.value.length} enforcement mechanism commands`);
}Governance Policy Graph (Unified API)
Fetch the complete governance policy graph with nested members (policies + rules + models + skills) in a single call via Connect API:
import { ConnectAPIClient } from '@salesforce/capg-client';
// Create client with Salesforce connection
const connection = await Connection.create({ authInfo: await AuthInfo.create({ username: orgAlias }) });
const client = new ConnectAPIClient(connection);
// Fetch complete governance policy graph
const result = await client.fetchGovernancePolicyGraph();
if (result.ok) {
console.log(`Fetched ${result.value.policies.length} policies`);
console.log(`Total count: ${result.value.totalCount}`);
// Access policies with nested members
result.value.policies.forEach((policy) => {
console.log(`\nPolicy: ${policy.Name} (${policy.Category})`);
// Process members by type
policy.members.forEach((member) => {
if (member.MemberType === 'Rule') {
console.log(` Rule: ${member.aiRule.InstructionCode}`);
console.log(` Category: ${member.aiRule.Category}`);
console.log(` Validation specs: ${member.aiRule.validationSpecs.length}`);
} else if (member.MemberType === 'AIModel') {
console.log(` AI Model: ${member.aiModel.ModelIdentifier}`);
} else if (member.MemberType === 'AISkill') {
console.log(` AI Skill: ${member.aiSkill.Name}`);
}
});
});
// Use cache metadata
console.log(`Cache key: ${result.value.cacheKey}`);
console.log(`Fetched at: ${result.value.fetchedAt}`);
} else {
console.error(`Failed: ${result.error.message}`);
}Key Features:
- Single API call fetches policies WITH nested members (rules, models, skills)
- Feature flag support: Returns fallback data when backend API not ready
- Type-safe discriminated unions for member types (
Rule | AIModel | AISkill) - Cache metadata included (
cacheKey,expiresAt,etag) - Source indicator (
'rest'for live data,'fallback'for hardcoded sample)
With Custom Logger
const client = new CAPGClient({
logger: {
debug: (msg) => console.log(`[DEBUG] ${msg}`),
error: (msg) => console.error(`[ERROR] ${msg}`),
},
});Documentation
Development
See DEVELOPMENT.md for detailed setup instructions, workflow, and contributing guidelines.
Running Tests
# Unit tests (automated, with mocks)
npm test
# Coverage report
npm run test:coverage
# Manual integration tests (requires SF CLI auth)
npm run build
node manual-tests/test-org-pref-checker.jsManual Tests: Integration tests that validate library functionality against real Salesforce orgs. See docs/testing/MANUAL_TESTS.md for comprehensive documentation.
License
See LICENSE file.
