X-Ways X-Tension Authoring
Author and maintain X-Ways Forensics X-Tensions — the xways-<name> DLLs that live in an x-tensions/ working folder — quickly and correctly. Scaffold new X-Tensions by copying and parameterizing a starter template, port the documented conventions into existing ones, audit untested ones for API validity, and route every API question to the authoritative reference so generated code never invents XWF_ calls.
This skill owns the X-Ways-specific how. For open-ended "what should this new tool do" ideation, brainstorm the tool's purpose first (the superpowers:brainstorming skill helps if you have it), then return here for template choice, scaffolding, conventions, and build.
Everything this skill needs is bundled with it — every path below is relative to this file.
Hard gates (never violate)
- Never edit
templates/x-tensions/ in place — it is the pristine source. Scaffold a copy into <project>/x-tensions/xways-<name>/ first (the script does this).
- Never edit or commit a user-acquired SDK tree. It lives at
references/api/ in their project — read-only, and never committed (copyright). That tree, not this skill's own references/ flow guides, is what "never edit references/" means. See getting-the-sdk.
- Never invent
XWF_ functions or flags. Verify every call against, in order: (1) the distilled notes in docs/; (2) the live https://www.x-ways.net/forensics/x-tensions/XWF_functions.html, which carries post-SDK additions; (3) a locally-downloaded SDK header, if present. Route API questions through api-guardrail.
x-tensions/ (hyphen) is the source tree; xtensions\ (no hyphen) is the build-output / deploy folder. The build scripts stage, verify, and mirror the no-hyphen path, so a wrong spelling breaks the tooling. It is a project convention, not an X-Ways discovery mechanism — how X-Ways actually finds a DLL is in naming-deployment.
- Close X-Ways before building. The DLL is locked while X-Ways is open; there is no hot reload.
- Events API ⇒ C++ template only.
XT_Python.dll does not expose XWF_AddEvent / XWF_GetEvent.
- Subprocess ⇒ open
\NUL + STARTF_USESTDHANDLES. X-Ways is a GUI-subsystem process with no console attached, so a child inherits null std handles and any helper writing to stdout/stderr can hard-crash. Hand the child real handles — \NUL, or a pipe if you capture output. See subprocess-stdio.
0x01 delivers each item to every per-item callback you export. Export both XT_ProcessItem and XT_ProcessItemEx and each item hits both — the empirically verified "2N" double-count. Do per-item work in one callback (XT_ProcessItemEx for hItem), or route both through one deduping collector. RVS is multi-threaded, so shared state needs a mutex. 0x04 is EXPECTMOREITEMS, not "call Ex". See item-collection.
- Never call
XWF_* from a worker thread you spawned — run synchronously on X-Ways' thread. XWF_AddEvent off-thread can corrupt the event store or crash the host. A settings dialog should request a run, then run it in XT_Finalize. See threading-model.
- Output writers: sanitise to valid UTF-8/XML, propagate I/O errors, bound memory. Raw log bytes break an
encoding="UTF-8" XLSX; a silent write error truncates evidence; buffering every row OOMs. Spill + stream + split. See output-writers.
- Never commit credentials, live
.cfg, local paths (C:\Users\…), case data, or compiled binaries — binaries ship via GitHub Releases. Run prepublish-scan.ps1 before a public push. See repo-hygiene.
Choose the flow, then load its reference
| To… |
Flow |
Load |
| scaffold a brand-new X-Tension |
new |
scaffold-new |
| wrap an external CLI tool |
wrap |
wrapper-generator |
| inject a convention into an existing X-Tension |
port |
port-convention |
| audit / modernize an untested X-Tension |
audit |
audit-modernize |
| answer an X-Ways API/behavior question correctly |
guardrail |
api-guardrail |
| record a new finding / mark a rollout item done |
docs-loop |
docs-loop |
| pick template vs exemplar, or decide on a dialog |
(any) |
decision-tables |
| debug a build / encoding / DLL-loading failure |
(any) |
build-and-iteration-gotchas |
| look up a script's full parameters or deploy behavior |
(any) |
scripts |
The guardrail row is an always-on correctness layer applied during every flow.
Scaffold from a starter template under templates/x-tensions/ (cpp, python, or the CLI-wrapper wrapper template). For a CLI-tool wrapper, prefer the wrapper template (-Template wrapper) — it already wires helper-exe verification, Ctrl-to-save, output-dir, and subprocess stdio. exemplars is a registry of community exemplars (with X-Ways 21+ verdicts and attribution) to read and port patterns from; none are bundled here.
Scripts (the deterministic core)
In scripts/, runnable from any working directory. For the scaffold/build scripts, output lands under the current directory by default, or a project passed via -DestRoot — never the skill install. (backfill-standards.ps1 is the exception: it operates on a repo working copy in place and has no -DestRoot.) Full parameters, deploy-target resolution, and the plugin-mode invocation: scripts.
| Script |
Does |
| new-xtension.ps1 |
copy a starter template into <DestRoot>/x-tensions/xways-<name>/, rename to the xways-<name> stem, set identity constants, generate LICENSE / README / CLAUDE.md.example |
| build-xtension.ps1 |
run build.bat, verify the DLL, deploy into the X-Ways install |
| prepublish-scan.ps1 |
hygiene scan over git-tracked files before a public push |
| backfill-standards.ps1 |
backfill a missing LICENSE + CLAUDE.md.example |
Two rules that always apply:
-DryRun first on new-xtension.ps1 — review the planned copies, renames, and edits before committing to them.
build-xtension.ps1 is the build gate — never claim a scaffold "works" without pasting its success output. Close X-Ways first, and pass the same -DestRoot used to scaffold. On a user's first build, ask them for their X-Ways install path and pass it via -DeployRoot.
Convention library
The reusable patterns live in docs/conventions/ — the single source of truth. The pages cite the wrapper template's code (templates/x-tensions/wrapper/), so nothing drifts. Load the one you need:
- Correctness — item-collection · threading-model · output-writers · subprocess-stdio · events-emission
- Wrapping a CLI tool — wrapper-anatomy · tool-resolution · helper-exe-verification · ctrl-to-save
- Settings dialogs — xtension-dialog-conventions, the long-form UI companion (
.rc layout, ID ranges, fonts, validation, cancel safety, progress, pickers). Load it when an X-Tension grows a dialog.
- Output — output-dir · add-output-to-case · verbose-logging
- Naming + release — naming-deployment · licensing · versioning · readme-roadmap · xtension-claude-md · repo-hygiene
Close the loop
After learning something new about the API/behavior, record it: update the relevant docs/ page (and INDEX / exemplars as needed), using absolute dates. See docs-loop.
Examples
- "Wrap yara in an X-Tension" → wrap flow: load wrapper-generator; scaffold with
new-xtension.ps1 -Name yara -Template wrapper -DryRun, then for real; fill the // TODO stubs (the tool's command line + result-to-item mapping); build-gate with build-xtension.ps1 -Name xways-yara. Result: a deployable xtensions\xways-yara\ bundle.
- "How do I read a file's bytes from an X-Tension?" → guardrail flow: answer from xways-reading-events-and-items (
XWF_OpenItem → XWF_Read → XWF_Close), citing the nFlags table in xways-openitem-flags; verify anything uncertain against the live XWF_functions.html.
- "Audit my old X-Tension for 21.8" → audit flow: load audit-modernize; check
XT_Prepare return flags, deprecated calls (XWF_AddToReportTable → XWF_Label), action-code constants, and convention gaps; output a prioritized TODO list — do not change code until asked.
Invocation
Reachable as the slash command /xtension <new|wrap|port|audit|docs> [name] (namespaced as /xways-xtension-authoring:xtension when installed as a plugin), which routes to the same flows. guardrail is deliberately absent from that list — it is a correctness layer, not a subcommand.
1---2name: xways-xtension-authoring3description: This skill should be used when the user asks to "create/scaffold a new X-Tension", "wrap a CLI tool in an X-Tension", "port a convention into an X-Tension" (helper-exe verification, Ctrl-to-save, output-dir), "audit/modernize an X-Tension", "build/compile an X-Tension", "prep an X-Tension for public release", or asks which XWF_* API call, flag, or property number to use, for X-Ways Forensics. Covers template selection, the PowerShell scaffold/build scripts, the convention library, and verifying every XWF_ call against distilled API reference notes. Does NOT handle general X-Ways usage questions or open-ended "what tool should I build" ideation.4license: MIT5---67# X-Ways X-Tension Authoring89Author and maintain X-Ways Forensics X-Tensions — the `xways-<name>` DLLs that live in an `x-tensions/` working folder — quickly and correctly. Scaffold new X-Tensions by copying and parameterizing a starter template, port the documented conventions into existing ones, audit untested ones for API validity, and route every API question to the authoritative reference so generated code never invents `XWF_` calls.1011This skill owns the X-Ways-specific *how*. For open-ended "what should this new tool do" ideation, brainstorm the tool's purpose first (the `superpowers:brainstorming` skill helps if you have it), then return here for template choice, scaffolding, conventions, and build.1213Everything this skill needs is bundled with it — every path below is relative to this file.1415## Hard gates (never violate)1617- **Never edit [`templates/x-tensions/`](templates/x-tensions/) in place** — it is the pristine source. Scaffold a copy into `<project>/x-tensions/xways-<name>/` first (the script does this).18- **Never edit or commit a user-acquired SDK tree.** It lives at `references/api/` in *their* project — read-only, and never committed (copyright). That tree, not this skill's own [`references/`](references/) flow guides, is what "never edit `references/`" means. See [getting-the-sdk](docs/getting-the-sdk.md).19- **Never invent `XWF_` functions or flags.** Verify every call against, in order: (1) the distilled notes in [`docs/`](docs/INDEX.md); (2) the live `https://www.x-ways.net/forensics/x-tensions/XWF_functions.html`, which carries post-SDK additions; (3) a locally-downloaded SDK header, if present. Route API questions through [api-guardrail](references/api-guardrail.md).20- **`x-tensions/` (hyphen) is the source tree; `xtensions\` (no hyphen) is the build-output / deploy folder.** The build scripts stage, verify, and mirror the no-hyphen path, so a wrong spelling breaks the tooling. It is a project convention, not an X-Ways discovery mechanism — how X-Ways actually finds a DLL is in [naming-deployment](docs/conventions/naming-deployment.md).21- **Close X-Ways before building.** The DLL is locked while X-Ways is open; there is no hot reload.22- **Events API ⇒ C++ template only.** `XT_Python.dll` does not expose `XWF_AddEvent` / `XWF_GetEvent`.23- **Subprocess ⇒ open `\NUL` + `STARTF_USESTDHANDLES`.** X-Ways is a GUI-subsystem process with no console attached, so a child inherits null std handles and any helper writing to stdout/stderr can hard-crash. Hand the child real handles — `\NUL`, or a pipe if you capture output. See [subprocess-stdio](docs/conventions/subprocess-stdio.md).24- **`0x01` delivers each item to *every* per-item callback you export.** Export both `XT_ProcessItem` and `XT_ProcessItemEx` and each item hits both — the empirically verified "2N" double-count. Do per-item work in **one** callback (`XT_ProcessItemEx` for `hItem`), or route both through one deduping collector. RVS is multi-threaded, so shared state needs a mutex. `0x04` is `EXPECTMOREITEMS`, *not* "call `Ex`". See [item-collection](docs/conventions/item-collection.md).25- **Never call `XWF_*` from a worker thread you spawned** — run synchronously on X-Ways' thread. `XWF_AddEvent` off-thread can corrupt the event store or crash the host. A settings dialog should *request* a run, then run it in `XT_Finalize`. See [threading-model](docs/conventions/threading-model.md).26- **Output writers: sanitise to valid UTF-8/XML, propagate I/O errors, bound memory.** Raw log bytes break an `encoding="UTF-8"` XLSX; a silent write error truncates evidence; buffering every row OOMs. Spill + stream + split. See [output-writers](docs/conventions/output-writers.md).27- **Never commit credentials, live `.cfg`, local paths (`C:\Users\…`), case data, or compiled binaries** — binaries ship via GitHub Releases. Run [prepublish-scan.ps1](scripts/prepublish-scan.ps1) before a public push. See [repo-hygiene](docs/conventions/repo-hygiene.md).2829## Choose the flow, then load its reference3031| To… | Flow | Load |32|---|---|---|33| scaffold a brand-new X-Tension | new | [scaffold-new](references/scaffold-new.md) |34| wrap an external CLI tool | wrap | [wrapper-generator](references/wrapper-generator.md) |35| inject a convention into an existing X-Tension | port | [port-convention](references/port-convention.md) |36| audit / modernize an untested X-Tension | audit | [audit-modernize](references/audit-modernize.md) |37| answer an X-Ways API/behavior question correctly | guardrail | [api-guardrail](references/api-guardrail.md) |38| record a new finding / mark a rollout item done | docs-loop | [docs-loop](references/docs-loop.md) |39| pick template vs exemplar, or decide on a dialog | (any) | [decision-tables](references/decision-tables.md) |40| debug a build / encoding / DLL-loading failure | (any) | [build-and-iteration-gotchas](docs/build-and-iteration-gotchas.md) |41| look up a script's full parameters or deploy behavior | (any) | [scripts](references/scripts.md) |4243The `guardrail` row is an always-on correctness layer applied during every flow.4445Scaffold from a starter template under [`templates/x-tensions/`](templates/x-tensions/) (`cpp`, `python`, or the CLI-wrapper `wrapper` template). For a CLI-tool wrapper, prefer the `wrapper` template (`-Template wrapper`) — it already wires helper-exe verification, Ctrl-to-save, output-dir, and subprocess stdio. [exemplars](docs/exemplars.md) is a registry of **community** exemplars (with X-Ways 21+ verdicts and attribution) to **read and port patterns from**; none are bundled here.4647## Scripts (the deterministic core)4849In [`scripts/`](scripts/), runnable from any working directory. For the scaffold/build scripts, output lands under the **current directory** by default, or a project passed via `-DestRoot` — never the skill install. (`backfill-standards.ps1` is the exception: it operates on a repo working copy in place and has no `-DestRoot`.) Full parameters, deploy-target resolution, and the plugin-mode invocation: [scripts](references/scripts.md).5051| Script | Does |52|---|---|53| [new-xtension.ps1](scripts/new-xtension.ps1) | copy a starter template into `<DestRoot>/x-tensions/xways-<name>/`, rename to the `xways-<name>` stem, set identity constants, generate LICENSE / README / CLAUDE.md.example |54| [build-xtension.ps1](scripts/build-xtension.ps1) | run `build.bat`, verify the DLL, deploy into the X-Ways install |55| [prepublish-scan.ps1](scripts/prepublish-scan.ps1) | hygiene scan over git-tracked files before a public push |56| [backfill-standards.ps1](scripts/backfill-standards.ps1) | backfill a missing LICENSE + CLAUDE.md.example |5758Two rules that always apply:5960- **`-DryRun` first** on `new-xtension.ps1` — review the planned copies, renames, and edits before committing to them.61- **`build-xtension.ps1` is the build gate** — never claim a scaffold "works" without pasting its success output. Close X-Ways first, and pass the same `-DestRoot` used to scaffold. On a user's first build, ask them for their X-Ways install path and pass it via `-DeployRoot`.6263## Convention library6465The reusable patterns live in [`docs/conventions/`](docs/conventions/index.md) — the single source of truth. The pages cite the `wrapper` template's code ([`templates/x-tensions/wrapper/`](templates/x-tensions/wrapper/)), so nothing drifts. Load the one you need:6667- **Correctness** — [item-collection](docs/conventions/item-collection.md) · [threading-model](docs/conventions/threading-model.md) · [output-writers](docs/conventions/output-writers.md) · [subprocess-stdio](docs/conventions/subprocess-stdio.md) · [events-emission](docs/conventions/events-emission.md)68- **Wrapping a CLI tool** — [wrapper-anatomy](docs/conventions/wrapper-anatomy.md) · [tool-resolution](docs/conventions/tool-resolution.md) · [helper-exe-verification](docs/conventions/helper-exe-verification.md) · [ctrl-to-save](docs/conventions/ctrl-to-save.md)69- **Settings dialogs** — [xtension-dialog-conventions](docs/xtension-dialog-conventions.md), the long-form UI companion (`.rc` layout, ID ranges, fonts, validation, cancel safety, progress, pickers). Load it when an X-Tension grows a dialog.70- **Output** — [output-dir](docs/conventions/output-dir.md) · [add-output-to-case](docs/conventions/add-output-to-case.md) · [verbose-logging](docs/conventions/verbose-logging.md)71- **Naming + release** — [naming-deployment](docs/conventions/naming-deployment.md) · [licensing](docs/conventions/licensing.md) · [versioning](docs/conventions/versioning.md) · [readme-roadmap](docs/conventions/readme-roadmap.md) · [xtension-claude-md](docs/conventions/xtension-claude-md.md) · [repo-hygiene](docs/conventions/repo-hygiene.md)7273## Close the loop7475After learning something new about the API/behavior, record it: update the relevant [`docs/`](docs/INDEX.md) page (and [INDEX](docs/INDEX.md) / [exemplars](docs/exemplars.md) as needed), using absolute dates. See [docs-loop](references/docs-loop.md).7677## Examples7879- **"Wrap yara in an X-Tension"** → wrap flow: load [wrapper-generator](references/wrapper-generator.md); scaffold with `new-xtension.ps1 -Name yara -Template wrapper -DryRun`, then for real; fill the `// TODO` stubs (the tool's command line + result-to-item mapping); build-gate with `build-xtension.ps1 -Name xways-yara`. Result: a deployable `xtensions\xways-yara\` bundle.80- **"How do I read a file's bytes from an X-Tension?"** → guardrail flow: answer from [xways-reading-events-and-items](docs/xways-reading-events-and-items.md) (`XWF_OpenItem` → `XWF_Read` → `XWF_Close`), citing the `nFlags` table in [xways-openitem-flags](docs/xways-openitem-flags.md); verify anything uncertain against the live `XWF_functions.html`.81- **"Audit my old X-Tension for 21.8"** → audit flow: load [audit-modernize](references/audit-modernize.md); check `XT_Prepare` return flags, deprecated calls (`XWF_AddToReportTable` → `XWF_Label`), action-code constants, and convention gaps; output a prioritized TODO list — do not change code until asked.8283## Invocation8485Reachable as the slash command **`/xtension <new|wrap|port|audit|docs> [name]`** (namespaced as `/xways-xtension-authoring:xtension` when installed as a plugin), which routes to the same flows. `guardrail` is deliberately absent from that list — it is a correctness layer, not a subcommand.