@kuttl/js
v0.1.2
Published
Kuttl — a non-destructive DOM intercept layer with AI-powered patching
Maintainers
Readme
@kuttl/js
A non-destructive DOM intercept layer with AI-powered patching.
Kuttl captures a snapshot of your live DOM and applies changes as a layer of
patches on top of it, without mutating your original markup. Patches can be
created programmatically, previewed before they are applied, persisted to
localStorage, exported, re-imported, and undone. An optional AI layer lets you
describe changes in plain language and have Kuttl generate the patches for you.
The AI features talk to a hosted backend proxy that owns the LLM credentials, so no API keys are ever exposed in the browser.
Install
npm install @kuttl/jsOr load it directly from a CDN, no build step required:
<!-- Core library (programmatic API) -->
<script src="https://cdn.jsdelivr.net/npm/@kuttl/js"></script>
<!-- or the drop-in widget with the floating UI -->
<script src="https://cdn.jsdelivr.net/npm/@kuttl/js/dist/kuttl-widget.iife.js"
data-website-key="your_website_key"></script>The same files are available on unpkg (https://unpkg.com/@kuttl/js).
Quick start
Drop-in widget
The widget is the fastest way to get started. Add one script tag with your website key and Kuttl validates the key against the backend, then mounts a floating button that opens the editing UI. If the key is missing or invalid, nothing is rendered.
<script src="https://cdn.jsdelivr.net/npm/@kuttl/js/dist/kuttl-widget.iife.js"
data-website-key="your_website_key"></script>
<script>
Kuttl.init({
persistKey: 'my-app', // optional: persist patches in localStorage
root: document.getElementById('app'), // optional: defaults to document.body
})
</script>Programmatic API
For full control, import the library and drive it yourself. init() returns an
instance that exposes the patch, preview, persistence, and AI methods.
import { init } from '@kuttl/js'
const kuttl = init({
root: document.body, // element to intercept (default: document.body)
persistKey: 'my-app', // optional: persist patches across reloads
debug: false,
})
// Apply a patch (non-destructive)
await kuttl.patch({ /* patch definition */ })
// Preview without committing
const preview = kuttl.preview({ /* patch definition */ })
// Undo the last change, or reset everything back to the captured source
await kuttl.undo()
kuttl.reset()
// Persist / restore
const json = kuttl.export()
await kuttl.import(json)AI-powered patching
Pass an ai config at init, then describe the change you want. Kuttl serializes
the relevant part of the DOM, sends it through the backend proxy, and applies the
patches it returns.
const kuttl = init({
ai: {
provider: 'anthropic',
apiKey: 'your_key', // forwarded to the backend proxy, not used in-browser
},
})
// Optional: turn on click-to-select so the clicked element is used as context
kuttl.toggleSelect()
const { result, status } = await kuttl.prompt('make the header background dark blue')API reference
init(config) returns an instance with the following members.
| Member | Description |
| --- | --- |
| patch(patches) | Apply one or more patches. Resolves with any warnings. |
| unpatch(patchId) | Remove a single patch by id. |
| undo() | Undo the most recent change. |
| reset() | Discard all patches and restore the captured source. |
| preview(patches) | Compute the result of patches without applying them. |
| export() | Serialize the current patch set to a JSON string. |
| import(json) | Load a previously exported patch set. |
| prompt(text) | Generate and apply patches from natural language (requires ai). |
| toggleSelect() | Toggle click-to-select mode. Returns the new active state. |
| clearSelection() | Clear the current selection. |
| selection | The currently selected element, or null. |
| store | The underlying patch store. |
| sourceSnapshot | The frozen snapshot captured at init. |
init options
| Option | Type | Default | Description |
| --- | --- | --- | --- |
| root | Element | document.body | Element subtree to intercept. |
| persistKey | string | none | localStorage key. Enables persistence when set. |
| uidAttribute | string | data-uid | Attribute used as stable element identity. |
| descriptionAttribute | string | data-description | Attribute used as an element label for AI context. |
| skipTags | string[] | none | Tag names to exclude from capture. |
| ai | AIProviderConfig | none | AI provider config. Required for prompt(). |
| onSelect | (el) => void | none | Called when the click-to-select target changes. |
| debug | boolean | false | Verbose logging. |
| snapshot | object | see below | Automatic website snapshotting config. |
TypeScript type definitions are included.
License
MIT © Samuel Isirima
