From vnext-ai-toolkit
Use when the user wants to create a vNext Extension — automatic instance data enrichment on workflow reads. Fetches extension.json schema first, walks the type × scope matrix from the schema, warns on performance impact (especially Global × Everywhere).
How this skill is triggered — by the user, by Claude, or both
Slash command
/vnext-ai-toolkit:component-extensionThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
An Extension automatically enriches workflow instance data on read operations. Unlike a Function (client must call), an Extension fires implicitly when the runtime serves an instance read endpoint. Common uses:
An Extension automatically enriches workflow instance data on read operations. Unlike a Function (client must call), an Extension fires implicitly when the runtime serves an instance read endpoint. Common uses:
The goal is to cut client / BFF round-trips — the consumer gets enriched instance data in one
read. An extension can normalize/denormalize or compute over existing instance data, and/or call
remote tasks for additional data. Boundary: for x-lov / x-lookup inputs (dropdown sources,
per-key lookups), use a Function instead — those are request-time, input-bound, not read-time
whole-instance enrichment. See references/concepts/function-vs-extension-vs-task.md.
Before asking about type or scope, fetch
extension.jsonfor the workspace'sschemaVersion. Thetype×scopematrix and the task composition rules come from the schema.
1. Read vnext.config.json → schemaVersion + domain + paths.extensions
2. Fetch https://raw.githubusercontent.com/burgan-tech/vnext-schema/v{schemaVersion}/schemas/extension.json
├─ Fail → master → references/concepts/component-schemas.md snapshot
└─ No snapshot → halt; never guess.
3. Parse:
- properties.attributes.properties.type.enum (typical: 1 Global, 2 GlobalAndRequested, 3 DefinedFlows, 4 DefinedFlowAndRequested)
- properties.attributes.properties.scope.enum (typical: 1 GetInstance, 2 GetAllInstances, 3 Everywhere)
- task or tasks[] composition + mapping shape
- required[]
4. Drive AskUserQuestion + skeleton from this schema.
See references/concepts/function-vs-extension-vs-task.md for the mental model.
From vnext.config.json: componentsRoot, paths.extensions, domain.
Target path: {componentsRoot}/{paths.extensions}/{extension-key}/{extension-key}.json.
Ask:
type 1/2 vs 3/4.)scope 1/2/3.)Render the type enum:
| Value | Name | Effect |
|---|---|---|
| 1 | Global | Fires on every workflow's read endpoints |
| 2 | GlobalAndRequested | Type 1 + can also be explicitly requested |
| 3 | DefinedFlows | Fires only on workflows that reference it |
| 4 | DefinedFlowAndRequested | Type 3 + explicit request |
(Verify the enum from the fetched schema.)
| Value | Name | Endpoints |
|---|---|---|
| 1 | GetInstance | Single-instance read |
| 2 | GetAllInstances | List query |
| 3 | Everywhere | All endpoints |
Before scaffolding, warn the user about the performance cost of broad combinations:
If the user picks a heavy combination, ask them to confirm and document why.
Extensions execute one or more tasks (typically HTTP or Script) to fetch the supplementary data. Two shapes (the schema's oneOf will tell you which):
attributes.task field with order, task reference, mapping.attributes.tasks[] array (or onExecutionTasks[] — verify from schema), aggregated via a single mapping.For each task this extension calls:
component-task; come back when ready..csx mappingThe mapping shapes the upstream task's response into the enrichment object that gets attached to the instance read response. Typical signature:
using System.Threading.Tasks;
using BBT.Workflow.Scripting;
using BBT.Workflow.Definitions;
public class {ClassName}Mapping : IMapping
{
public Task<ScriptResponse> InputHandler(WorkflowTask task, ScriptContext context)
{
// context.Instance.Data is available — use it to build the upstream call
// e.g. HTTP request for the user's customer details by customer ID
return Task.FromResult(new ScriptResponse { /* … */ });
}
public Task<ScriptResponse> OutputHandler(ScriptContext context)
{
// Unwrap context.Body, return the enrichment payload
// The runtime attaches it to the instance read response under `extensions[key]` (or similar)
return Task.FromResult(new ScriptResponse {
Key = "{extension-key}",
Data = context.Body?.data ?? context.Body
});
}
}
Refer to references/concepts/csx-contracts.md for full contract details.
Envelope (single-task variant — multi-task shape comes from the schema):
{
"key": "{extension-key}",
"version": "1.0.0",
"domain": "{domain}",
"flow": "sys-extensions",
"flowVersion": "1.0.0",
"tags": [],
"attributes": {
"type": 3,
"scope": 1,
"task": {
"order": 1,
"task": { "key": "{task-key}", "domain": "{domain}", "flow": "sys-tasks", "version": "1.0.0" },
"mapping": { "location": "./src/{ClassName}Mapping.csx", "code": "" }
}
}
}
mapping.code is empty — the VS Code extension auto-encodes on save.
Path: {componentsRoot}/{paths.extensions}/{extension-key}/{extension-key}.json. .csx mappings go in the adjacent src/.
For Type 1/2 (Global), the extension fires automatically — no wiring needed. For Type 3/4 (DefinedFlows), each target workflow must reference this extension. Edit the workflow JSON's attributes.extensions[] (or equivalent — verify from workflow.json schema) and add:
{ "key": "{extension-key}", "domain": "{domain}", "flow": "sys-extensions", "version": "1.0.0" }
Run npm run validate. Hand failures to validate-and-fix.
extensions[key] or similar). Verify by hitting the runtime endpoint and inspecting the response.Scope: Everywhere are a top cause of slow list endpoints. If the extension is expensive, consider Type 3/4 (DefinedFlows) so only workflows that need it pay the cost.Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub burgan-tech/vnext-ai-toolkit --plugin vnext-ai-toolkit