@patchedcodes/hackathon-widget
v0.1.4
Published
AI-powered frontend editor widget — modify live web interfaces using natural language
Downloads
530
Maintainers
Readme
@patchedcodes/hackathon-widget
AI-powered frontend editor widget — modify live web interfaces using natural language.
Renders a floating chat button on your page. Users type a natural-language command, the widget captures a screenshot, sends it to your backend, and applies the resulting code changes live.
Install
npm install @patchedcodes/hackathon-widgetor
pnpm add @patchedcodes/hackathon-widgetQuick Start
import { init } from "@patchedcodes/hackathon-widget";
init({
endpoint: "https://your-backend.com/api/command",
apiKey: "your-api-key",
});A floating button appears in the bottom-right corner of your page. Click it to open the chat panel, describe a visual change, and the widget handles the rest.
Configuration
init() accepts a WidgetConfig object:
| Option | Type | Default | Description |
|---|---|---|---|
| endpoint | string | (required) | Backend URL that receives command POST requests. |
| apiKey | string | (required) | API key sent in the request body to authenticate with the backend. |
| position | "bottom-right" \| "bottom-left" \| "top-right" \| "top-left" | "bottom-right" | Position of the floating widget button. |
| theme | "light" \| "dark" | "light" | Widget color theme. |
| headers | Record<string, string> | {} | Custom headers sent with backend requests (e.g. auth tokens). |
| onDeployReady | (branch: string, previewUrl: string) => void | — | Called when a deployment is ready, before the user clicks "Apply". |
| onError | (error: Error) => void | — | Called when an error occurs. |
| onOpen | () => void | — | Called when the widget panel is opened. |
| onClose | () => void | — | Called when the widget panel is closed. |
Callbacks
init({
endpoint: "https://your-backend.com/api/command",
apiKey: "your-api-key",
onDeployReady: (branch, previewUrl) => {
console.log(`Deploy ready on branch ${branch}: ${previewUrl}`);
},
onError: (error) => {
console.error("Widget error:", error);
},
onOpen: () => console.log("Widget opened"),
onClose: () => console.log("Widget closed"),
});Programmatic Control
init() returns the underlying DevloyedWidget custom element, which exposes methods for programmatic control:
const widget = init({
endpoint: "https://your-backend.com/api/command",
apiKey: "your-api-key",
});
// Open, close, or toggle the chat panel
widget.open();
widget.close();
widget.toggle();Architecture
The widget is a vanilla TypeScript Web Component (<devloyed-widget>) that renders inside a Shadow DOM. This means:
- Full style encapsulation — widget styles cannot leak into or be affected by the host page.
- Framework-agnostic — works with React, Vue, Svelte, plain HTML, or any other framework.
- Single bundle — ships as one ES module (
dist/devloyed-widget.js) with no external runtime dependencies beyondhtml2canvas(bundled).
How It Works
- User opens the widget and types a natural-language command (e.g. "Make the header blue").
- The widget captures a screenshot of the page using
html2canvas. - A multi-step loader plays with randomized progress labels while the request is in flight.
- The command and API key are sent to your backend via a single
POSTrequest. - On response, the loader cascades to completion and the AI's response is shown in the chat.
- If the backend returns a
commitId, a deploy toast appears with an "Apply" button that reloads the page to pick up the changes.
Backend Contract
The widget sends a POST request to your endpoint with the following JSON body:
interface CommandRequest {
apiKey: string; // The API key from config
prompt: string; // The user's natural-language command
}Your backend should return:
interface CommandResponse {
commitId: string; // The commit SHA that was pushed
transcript: string; // AI's explanation of what was changed
}Routing Utilities
The package exports cookie-based routing helpers for reverse-proxy branch switching. These are standalone utilities — not wired into the widget automatically — for consumers who want to implement branch preview routing.
import {
setRoutingCookie,
getRoutingCookie,
clearRoutingCookie,
isOnPreview,
} from "@patchedcodes/hackathon-widget";
// Set cookie to route traffic to a preview branch (reloads by default)
setRoutingCookie("feature/new-header");
// Check current branch
const branch = getRoutingCookie(); // "feature/new-header" or null
// Check if viewing a preview
if (isOnPreview()) {
// show "return to production" button
}
// Clear and return to production
clearRoutingCookie();Options can be passed to setRoutingCookie and clearRoutingCookie:
| Option | Type | Default | Description |
|---|---|---|---|
| cookieName | string | "devloyed_branch" | Cookie name. |
| maxAge | number | 3600 | Cookie max-age in seconds. |
| path | string | "/" | Cookie path. |
| reload | boolean | true | Whether to reload the page after setting/clearing. |
Development
# Start dev server with mock backend
npm run dev
# Or run them separately:
npm run dev:mock # Mock backend on port 3001
npm run dev:vite # Vite dev server
# Type-check
npm run typecheck
# Build
npm run buildThe mock server (dev/mock-server.mjs) simulates a ~10-second AI processing delay and returns fake commit/branch data for any command.
TypeScript
Types are shipped with the package — no separate @types/ install needed. You can import them directly:
import type { WidgetConfig } from "@patchedcodes/hackathon-widget";
import type { CommandRequest, CommandResponse } from "@patchedcodes/hackathon-widget";The package also exports DevloyedWidget and TransportClient classes for advanced usage.
License
MIT
