-
-
Notifications
You must be signed in to change notification settings - Fork 240
Add AI Agent Skills support using the skills.sh convention #1004
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
benjaminloerincz
wants to merge
9
commits into
jongpie:main
Choose a base branch
from
benjaminloerincz:skills
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
57f5d7e
Add AI Agent Skills documentation and new skills for installation, us…
benjaminloerincz 41e57de
docs(skills): update Apex logging examples to use Logger.exception on…
benjaminloerincz 7335faa
docs(skills): remove contradictory sentence from SKILL.md
benjaminloerincz c3eeb0a
docs(skills): enhance logging level guidance for better performance a…
benjaminloerincz 1550a66
Merge branch 'main' into skills
jongpie 3f14e54
Expanded the Nebula Logger skills.sh catalog
jongpie d143036
Added a new 'installation count' badge (provided by skills.sh) to REA…
jongpie 03ba8a8
Updated some of the build scripts to auto-update the unlocked package…
jongpie 3b7636a
Implemented some changes suggested by @benjaminloerincz + made a few …
jongpie File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| { | ||
| "$schema": "https://skills.sh/schemas/skills.sh.schema.json", | ||
| "notGrouped": "bottom", | ||
| "groupings": [ | ||
| { | ||
| "title": "Setup", | ||
| "description": "Installation and configuration of Nebula Logger in a Salesforce org.", | ||
| "skills": ["nebula-logger-install"] | ||
| }, | ||
| { | ||
| "title": "Usage", | ||
| "description": "Writing logging code across Apex, LWC, Aura, Flow, and OmniStudio, and testing code that uses Nebula Logger.", | ||
| "skills": ["nebula-logger-instrumentation", "nebula-logger-testing-your-code"] | ||
| }, | ||
| { | ||
| "title": "Operations", | ||
| "description": "Day-to-day console navigation and log retention / purging administration.", | ||
| "skills": ["nebula-logger-console", "nebula-logger-purging-and-retention"] | ||
| }, | ||
| { | ||
| "title": "Governance", | ||
| "description": "Best practices, logging levels, and governor limit considerations.", | ||
| "skills": ["nebula-logger-best-practices"] | ||
| }, | ||
| { | ||
| "title": "Extending", | ||
| "description": "Building custom plugins that extend Nebula Logger.", | ||
| "skills": ["nebula-logger-plugin-development"] | ||
| } | ||
| ] | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| # Nebula Logger Skills | ||
|
|
||
| This folder contains Nebula Logger's [skills.sh](https://skills.sh) catalog. Each subfolder is one skill, with a `SKILL.md` file that describes when the skill applies and what it covers. The top-level [`skills.sh.json`](../skills.sh.json) groups the skills into logical categories for the catalog page at [skills.sh/jongpie/NebulaLogger](https://skills.sh/jongpie/NebulaLogger). | ||
|
|
||
| ## Skills | ||
|
|
||
| | Skill | Purpose | | ||
| | ------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | [nebula-logger-install](./nebula-logger-install/SKILL.md) | Installing Nebula Logger, choosing between unlocked and managed packages, permission-set assignment, and initial `LoggerSettings__c` configuration. | | ||
| | [nebula-logger-instrumentation](./nebula-logger-instrumentation/SKILL.md) | Adding Nebula Logger instrumentation in Apex, LWC, Aura, Flow, and OmniStudio. Covers logging APIs, exception handling, record association, tags/scenarios, async transaction linking, and the `CallableLogger` optional-dependency pattern for ISVs. | | ||
| | [nebula-logger-console](./nebula-logger-console/SKILL.md) | Browsing and investigating logs in the Salesforce UI - list views, record pages, home page components, and the live log entry event stream. | | ||
| | [nebula-logger-purging-and-retention](./nebula-logger-purging-and-retention/SKILL.md) | Configuring how long logs live before being purged - `LogRetentionDate__c` semantics, `LogBatchPurger` scheduling, and per-user/profile/scenario overrides. | | ||
| | [nebula-logger-testing-your-code](./nebula-logger-testing-your-code/SKILL.md) | Writing Apex and LWC tests for code that calls Nebula Logger. Global-only APIs and patterns for observing entries without polluting the org. | | ||
| | [nebula-logger-plugin-development](./nebula-logger-plugin-development/SKILL.md) | Building custom plugins that extend Nebula Logger via the `LoggerPlugin.Triggerable` and `LoggerPlugin.Batchable` interfaces. | | ||
| | [nebula-logger-best-practices](./nebula-logger-best-practices/SKILL.md) | Team-wide instrumentation standards, environment-aware logging levels, and governor-limit considerations. | | ||
|
|
||
| ## Supported API Surface | ||
|
|
||
| Every skill in this catalog references only Nebula Logger's `global` Apex surface and the exported `c/logger` LWC module. `public` classes and methods in the unlocked package are technically reachable but are Nebula Logger's internal surface and can change without a deprecation window - see the "Supported API Surface" section in [nebula-logger-instrumentation](./nebula-logger-instrumentation/SKILL.md) for the full policy. | ||
|
|
||
| The plugin framework in [nebula-logger-plugin-development](./nebula-logger-plugin-development/SKILL.md) is a deliberate exception: the extension points are `public` because they exist only inside the unlocked package, and plugin authors interact with them by design. Plugins should pin to a tested Nebula Logger version and re-verify on upgrades. | ||
|
|
||
| ## Publishing | ||
|
|
||
| skills.sh reads this repository directly from GitHub. Landing a change on `main` publishes it - no separate submission or manual crawl trigger is needed. | ||
|
|
||
| ## Contributing | ||
|
|
||
| If you spot something in a skill that no longer matches the code (a renamed field, a removed method, a stale example), please file an issue at https://github.com/jongpie/NebulaLogger/issues or open a PR. See the repo's [CONTRIBUTING.md](../CONTRIBUTING.md) for the general contribution workflow. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| --- | ||
| name: nebula-logger-best-practices | ||
| description: Use this skill when the user wants to review, harden, or standardize Nebula Logger usage across a Salesforce team. Covers operational logging standards, environment-aware settings, limit-aware design, and governance guardrails. | ||
| --- | ||
|
|
||
| # Nebula Logger Best Practices and Governance | ||
|
|
||
| ## Team-Wide Practices | ||
|
|
||
| Use these defaults when reviewing pull requests or designing logging conventions. | ||
|
|
||
| 1. Reserve `ERROR`, `WARN`, and `INFO` for information that is operationally significant. | ||
| 2. Use `DEBUG`, `FINE`, `FINER`, and `FINEST` for high-volume diagnostic detail. Combined with `LoggerSettings__c.LoggingLevel__c`, these can be left in code without adding runtime overhead in production and switched on only when deeper diagnostics are needed. | ||
| 3. Tune `LoggerSettings__c` data by environment. | ||
| - Configure `LoggingLevel__c` to `ERROR`, `WARN`, or `INFO` in production orgs to reduce logging noise (or change to `DEBUG`, `FINE`, `FINER`, or `FINEST` when trying to debug) | ||
| - Configure scheduled purging and retention windows (`DefaultLogPurgeAction__c`, `DefaultNumberOfDaysToRetainLogs__c`) | ||
| 4. Use static method `Logger.setScenario()`, and instance methods `LogEntryEventBuilder.addTag()` and `LogEntryEventBuilder.addTags()` for business-process grouping. | ||
| - Define a controlled naming convention for scenarios & tags that make sense to your team | ||
| 5. Use instance methods on `LogEntryEventBuilder` to further enrich data, instead of embedding extra data directly in message strings. There are several method overloads available: | ||
| - `.setExceptionDetails(...)` | ||
| - `.setApprovalResult(...)` | ||
| - `.setDatabaseResult(...)` | ||
| - `.setRecord(...)` | ||
| - `.setHttpRequestDetails(...)` | ||
| - `.setHttpResponseDetails(...)` | ||
| - `.setRestRequestDetails(...)` | ||
| - `.setRestResponseDetails(...)` | ||
| - `.setField(...)` | ||
| 6. Call `Logger.saveLog()` deliberately - don't call it after every log entry, and never inside a tight loop. Be strategic when calling it, just like when making DML calls in Apex. | ||
| - `Logger.info(...)` / `.error(...)` / etc. only add entries to an in-memory buffer. Nothing persists until `saveLog()` runs. If a transaction ends without calling `saveLog()`, everything that was buffered is lost - so `saveLog()` still has to be called before the transaction commits. | ||
| - Every `saveLog()` call is a real platform operation with real cost. With the default `EVENT_BUS` save method, each call to `saveLog()` calls `System.EventBus.publish(List<LogEntryEvent__e>)` once, which consumes one slot against `System.Limits.getLimitPublishImmediateDML()` (100 per transaction) and one increment against the org's daily platform event publish allocation. The other save methods have their own limits: `QUEUEABLE` consumes an async job slot (`System.Limits.getLimitQueueableJobs()`), `REST` consumes a callout, and `SYNCHRONOUS_DML` consumes regular DML rows and statements. None of them are free. | ||
| - Multiple `saveLog()` calls in a transaction are fine, and often the right choice. Reasonable places to save intermediate state include after each chunk in a batch, at the end of each iteration of a long-running loop's outer scope (never the inner scope - see below), before an async handoff (Queueable / Future / Batchable), and inside a `finally` block that catches an exception you're about to rethrow. Each save publishes only what's in the buffer at that moment, so the entries persist even if the rest of the transaction later blows up. | ||
| - What's wrong is calling `saveLog()` after every single log entry. That turns N log calls into N platform-event publishes, burns through `getLimitPublishImmediateDML()` (100 per transaction) fast, and eats into the org's daily platform event allocation for no operational benefit. If you find yourself typing `Logger.info(...); Logger.saveLog();` repeatedly, buffer the entries and save once after the group. | ||
| - Never call `saveLog()` inside the innermost body of a loop over records. Buffer entries in the loop and call `saveLog()` after the loop (or at safe checkpoints - after N iterations, after a chunk of work, etc.), not after each record. | ||
| - Place a `Logger.saveLog()` call in a `finally` block for transactional code paths so it still runs when an exception escapes the try. Pair it with `Logger.setSaveMethod(...)` at the top of the method if the default `EVENT_BUS` isn't right for that path (see the save-method notes in item 1). | ||
|
|
||
| ## Environment-Aware Logging Levels | ||
|
|
||
| Treat logging verbosity as an operational control, not as a code constant. | ||
|
|
||
| | Environment | Suggested baseline | Reason | | ||
| | ----------- | ------------------------------- | ---------------------------------------------------------------- | | ||
| | Production | `ERROR` or `WARN` | Reduce noise and storage impact while preserving incident signal | | ||
| | UAT | `INFO` | Validate business flows without excessive detail | | ||
| | QA | `DEBUG` or `FINE` | Support defect reproduction and integration testing | | ||
| | Sandbox/Dev | `FINE` to `FINEST` (time-boxed) | Deep diagnostics during active development | | ||
|
|
||
| Use hierarchy overrides (user/profile) for temporary incident windows, then revert. | ||
|
|
||
| ## Review Checklist for Existing Code | ||
|
|
||
| - Does each execution path call `saveLog()` at deliberate checkpoints - and never after every entry or inside a per-record inner loop? | ||
| - Are exceptions logged with stack trace context? | ||
| - Are record references attached via `.setRecord(...)`? | ||
| - Are scenarios and tags consistent with team taxonomy? | ||
| - Is save method choice explicit when not using default `EVENT_BUS`? | ||
|
|
||
| ## Governor and Capacity Considerations | ||
|
|
||
| Nebula Logger helps observability, but it still runs inside Salesforce governor boundaries. | ||
|
|
||
| | Constraint | Impact on logging | Mitigation | | ||
| | -------------------------- | ------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | | ||
| | Data storage | High-volume logs can consume custom object storage quickly | Enforce retention policy and purge schedule; lower verbosity in production | | ||
| | Platform event daily limit | `EVENT_BUS` volume can hit org event allocations | Use selective logging and switch targeted jobs to `QUEUEABLE`/`SYNCHRONOUS_DML` when needed | | ||
| | SOQL queries | Extra enrichment queries in logging paths can compound limits | Reuse queried records and avoid logging-only query fanout | | ||
| | CPU time | Heavy serialization/tagging in loops increases CPU usage | Log aggregate milestones, not every iteration, and prefer async save paths | | ||
| | Async job allocation | Overusing `QUEUEABLE` can compete with business async work | Reserve queueable saves for high-cost or mixed-DML-sensitive contexts | | ||
| | Heap size | Large payloads/exceptions can inflate transaction memory | Truncate oversized payloads and avoid dumping full object graphs | | ||
|
|
||
| ## When Not to Use Nebula Logger | ||
|
|
||
| Nebula Logger is not a substitute for sound architecture. | ||
|
|
||
| - Do not use logging as a workaround for unclear domain design. | ||
| - Do not store secrets, credentials, or unnecessary PII in log messages. | ||
|
|
||
| Use Nebula Logger as a structured observability layer, combined with clean service boundaries, resilient error handling, and purposeful telemetry. | ||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"item 1" has changed due to this commit. Thus, this should be adjusted.