Progressive Skills Editor
Visualize, navigate, and edit progressive-disclosure agent projects right inside VS Code.
Progressive Skills Editor is a left-sidebar tree explorer for any progressive-load skills
project (the kind used with watsonx Orchestrate native agents). It reads your project's agent
and skill YAML files directly from disk and makes the entire dependency graph visible at a
glance: which agent declares which tools, how each intent maps to exactly one skill cell, which
tools are always-on utilities, and which guardrail plugins fire in what order.
It is client-agnostic — point it at any workspace that follows the layout below and it
adapts. No backend, no telemetry, no hardcoded tenant paths.
Try it in 60 seconds: this extension ships a self-contained, anonymized sample. Open the
bundled sample/lumen-utilities folder in VS Code and the explorer lights up immediately.
See Try the sample.
Features
- 5-layer tree explorer — AGENT (dispatcher + intents it serves + exposed utility tools) ·
CELL-SKILLS (the cells, grouped by skill-function) · SKILL-FUNCTIONS (the executables, the
intent→function merge) · BASE/PERSONA (base_rules + utility tools vs the never-exposed
session tool) · GUARDRAILS (pre + post).
- Dependency graph made visible — see
skill → tool (loads) and skill → skill
(next-intention) edges; compose an agent-wide Flow Map (Mermaid) that walks every flow
reachable from a dispatcher.
- Direct YAML editing — open any skill cell, edit
rule / keywords / tools, save, and
the file watcher refreshes the tree.
- Message Manager (i18n grid) — a
category × key × [locales] webview to edit externalized
user-facing strings, flag missing translations, find usages, and lint against a configurable
forbidden-word list.
- Auto-detection — finds the workspace root by looking for
agents/native/*.yaml and
skills/*.yaml, searching up to 3 levels of subdirectories. Override paths per-workspace via
settings.
- Fully localizable — the extension's own UI is English by default and translatable via
VS Code l10n (a Portuguese sample bundle is included).
Try the sample
This extension ships a complete, anonymized demo project — zero real client data — so you
can explore every feature without wiring anything up.
- Install the extension.
- In VS Code: File → Open Folder… and choose the bundled
sample/lumen-utilities folder (inside the installed extension, or copy it out to a
workspace of your own).
- Click the skills icon in the Activity Bar to open the Skills Explorer.
- Expand
AGENTS → lumen_assist, then the SKILLS and MESSAGES (i18n) nodes.
The sample is lumen-utilities: a fictional utilities-company assistant with a single-tool
dispatcher agent (lumen_assist), a set of intent cells under skills/, and a bilingual
(en/es) message catalog under messages/. It demonstrates the progressive-load pattern,
transversal cells, and the i18n grid end to end.
sample/lumen-utilities/
agents/native/lumen_assist.yaml # single-tool DISPATCHER agent (deterministic routing)
skills/_base.yaml # base_rules (persona) + utility_tools
skills/<intent>.yaml # one cell per intent
messages/en/*.yaml # English catalog (complete)
messages/es/*.yaml # Spanish catalog (representative subset)
README.md # sample walkthrough
How to use it on your own project
- Open your project folder in VS Code — the one containing
agents/native/ and skills/.
- Click the skills icon in the Activity Bar to open the Skills Explorer.
- Browse the tree, edit cells inline, compose a Flow Map, and manage i18n messages.
Project structure this extension expects
<your-project>/
agents/
native/
<umbrella-agent>.yaml ← main agent with tools + guardrail plugins
<sub-agent>.yaml ← additional agents (optional)
skills/
_base.yaml ← base_rules (persona) + utility_tools list
<intent>.yaml ← one skill cell per intent
_build_index.py ← optional index rebuild script
Skill cells live in skills/. The legacy tools/guardrails/skills/ layout is still
accepted as a fallback so older trees open unchanged.
The umbrella agent is auto-detected as the agent that runs the progressive pipeline
(progressive_rules_preinvoke). Tie-break: most guardrail plugins (pre + post); then
alphabetical by name.
Icon legend (agent nodes)
| Icon |
Meaning |
★ |
the umbrella / progressive agent (runs progressive_rules pre-invoke) |
⚙ (gear) |
a dev agent — binds DEV-only identity tools; never deployed to prod |
{} |
a plain agent |
Each agent's dispatcher expands to Serves (N intents) — the skills are served by the
dispatcher, not bound to the agent. The exposed utility tools are distinct from the
session tool, which is used internally by the skill-functions and is never exposed to
the model. Both appear under the BASE / PERSONA section, alongside the single base_rules
persona (shown once).
What the tree shows
AGENTS (N)
└─ <umbrella-agent> ★ auto-detected
├─ Tools (N) every tool declared in the agent YAML
│ ├─ <tool-a> [utility]
│ ├─ <tool-b> [skill-tool]
│ └─ …
└─ Guardrail pipeline (N pre + N post)
├─ PRE-INVOKE
│ ├─ scope_guard_preinvoke
│ ├─ progressive_rules_preinvoke ← lazy-loads intent rules
│ └─ …
└─ POST-INVOKE
├─ render_enforcement_postinvoke
└─ …
SKILLS (N intents)
└─ <intent> → loads: <skill-tool>
├─ <skill-tool> [lazy-loaded tool]
├─ keywords: foo, bar, …
└─ rule (edit) ← click to open the cell YAML
TOOLS (N unique)
├─ <utility-tool> utility — always active
└─ <skill-tool> skill-tool · <intent>
INDEX (N intents)
└─ <intent> "keyword1, keyword2, …"
GUARDRAILS (N pre + N post)
├─ PRE-INVOKE
└─ POST-INVOKE
ENVIRONMENT
├─ Environment: <env-label> resolved from ORCHESTRATE_ENV / .orchestrate-env
├─ Skills dir: skills/
└─ Agents dir: agents/native/
How the progressive-load pattern works
The architecture keeps a minimal base prompt in the agent. Detailed rules for each intent
are NOT embedded in the agent's instructions — they are injected at runtime by the
progressive_rules_preinvoke plugin only when the router matches that intent.
Each SKILLS node makes this explicit:
<intent> → loads: <skill-tool> — the skill tool is declared in the agent YAML but only
becomes "the active tool" when the classifier returns that intent.
(transversal) — skills with cross_cutting: true have no dedicated tool; they operate
through the always-on utilities plus injected rules.
- Utility tools (TOOLS section) fire on every turn regardless of intent.
ENVIRONMENT node — resolved layout (editable)
The ENVIRONMENT node shows the resolved locations the extension actually reads from
(not a hardcoded path), plus the active environment. Each line has an Edit… (pencil)
action that opens an input box and persists the matching setting, so you can point the
extension at your own layout:
| Line |
Resolved by |
Setting (Edit…) |
| Environment |
progressiveSkills.activeEnv → ORCHESTRATE_ENV → .orchestrate-env → neutral |
progressiveSkills.activeEnv |
| Skills dir |
progressiveSkills.skillsDir → skills/ → legacy tools/guardrails/skills/ |
progressiveSkills.skillsDir |
| Agents dir |
progressiveSkills.agentsDir → agents/native/ |
progressiveSkills.agentsDir |
progressiveSkills.skillsDir / progressiveSkills.agentsDir accept a path relative to the
workspace root or an absolute path; when set and the directory exists they override
auto-detection. Leave a setting empty to fall back to auto-detection. Changing any of these
settings refreshes the tree immediately.
To pin an environment without using the setting, create a .orchestrate-env file in your
project root containing a single line with the environment name (e.g. my-org-dev).
Commands
| Command |
UI / Palette |
What it does |
Progressive Skills: Refresh |
Toolbar icon |
Re-reads all YAML files from disk |
Progressive Skills: Edit Rule (open cell YAML) |
Click rule (edit) node |
Opens the skill cell YAML for direct editing |
Progressive Skills: Add Skill… |
Toolbar + icon |
Scaffolds a new skill cell YAML and opens it |
Progressive Skills: Rebuild Index |
Toolbar run icon |
Runs skills/_build_index.py in a terminal |
Progressive Skills: Show Agent Flow Map |
Context menu on an agent |
Composes EVERY flow reachable from the agent into one Mermaid diagram |
Progressive Skills: Unbind from Agent |
Context menu on a tool / guardrail under an agent |
Removes it from THAT agent's list only — the artifact file is NOT moved |
Progressive Skills: Open Message Manager |
Context menu on MESSAGES (i18n) |
Opens the Message Manager webview — a category × key × [locales] grid |
Message Manager (i18n grid)
The Message Manager is a CSP-locked, theme-aware webview that edits the project's
externalized user-facing strings — the messages/<locale>/<category>.yaml tree. It is
client-agnostic: it discovers whatever messages/ directory the open workspace has (no
hardcoded tenant path).
Open it from the MESSAGES (i18n) tree node (inline icon) or from any message-category node.
The grid has one row per key and one column per locale, grouped by category. From it you can:
- Edit each locale inline — type a value in a cell; it is saved to that locale's category
YAML on blur.
- Add / rename / delete keys — rename and delete apply across every locale file in the
category; add seeds the key in the default (reference) locale.
- Flag missing translations — a cell present in one locale but absent in another is
highlighted, with a per-category and per-row "missing" count; filter to show only such rows.
- Find usages — locates which source files reference a key (a project-wide scan); click a
result to open it beside the grid.
- Lint vs the counter-rules — runs a forbidden-in-output word list over every cell and
flags violations (e.g. emoji, banned phrasings). The default rule set can be overridden by a
counter_rules.json next to the messages/ directory ([{label, pattern, flags?, why}]).
The reference (default) locale is en if present, else pt*, else the first locale sorted.
Internationalization (the extension's own UI)
The extension's own command titles, view names, and runtime UI strings are English by
default and fully localizable via VS Code's l10n:
- Contributed strings (commands, views, descriptions) live in
package.nls.json
(English) — add package.nls.<locale>.json for another locale (a package.nls.pt-br.json
sample is included).
- Runtime strings (Message Manager, dialogs) go through
vscode.l10n.t(...) with the
bundle in l10n/bundle.l10n.json (English) — add l10n/bundle.l10n.<locale>.json for
another locale (a bundle.l10n.pt-br.json sample is included).
VS Code picks the bundle matching the editor display language automatically. No extension
strings hardcode any specific client.
Architecture mapping
| Tree section |
Source file(s) |
Mechanism |
| Agents |
agents/native/*.yaml |
Loaded at startup; umbrella auto-detected |
| Skills |
skills/<intent>.yaml |
One cell per intent; direct YAML read |
| Tools |
_base.yaml utility_tools + skill cell tools: |
Deduplicated union |
| Index |
skills/<intent>.yaml keywords |
Read-only routing map view |
| Guardrails |
Umbrella agent YAML plugins: section |
Deterministic pipeline; fires every turn |
| Environment |
ORCHESTRATE_ENV / .orchestrate-env / neutral |
Priority-ordered resolution |
Requirements
- VS Code
^1.85.0.
- The YAML extension
(
redhat.vscode-yaml) — installed automatically as an extension dependency.
Building from source
npm install
npm run compile # type-check
npm run bundle # esbuild -> out/extension.js
npx vsce package # produce the .vsix
Press F5 in VS Code to launch an Extension Development Host for live debugging.
License
MIT.