Kaiju one-file app
{esc(spec.headline)}
Built for business owners who need a working tool now: form entry, saved records, clear status, and CSV export without a backend.
Add record
Records
| Created | Action |
|---|
#!/usr/bin/env python3 """Interactive app harness for simple business-owner apps. This creates complete one-file web apps with local persistence. The goal is not to replace real engineering for complex SaaS products. It is to make common small-business utility apps fast, complete, and demonstrable. """ from __future__ import annotations import html import json import re from dataclasses import dataclass, field from pathlib import Path from typing import Any @dataclass class AppSpec: app_name: str app_type: str headline: str entities: list[str] = field(default_factory=list) fields: list[str] = field(default_factory=list) actions: list[str] = field(default_factory=list) accent: str = "#f4ad32" APP_DEFAULTS: dict[str, dict[str, list[str] | str]] = { "booking": { "headline": "Book appointments and keep the day organized.", "entities": ["appointments"], "fields": ["Customer", "Service", "Date", "Time", "Phone"], "actions": ["Add appointment", "Mark complete", "Export CSV"], }, "crm": { "headline": "Track leads from first message to paid customer.", "entities": ["leads"], "fields": ["Name", "Company", "Need", "Status", "Next Follow-up"], "actions": ["Add lead", "Update status", "Export CSV"], }, "invoice_tracker": { "headline": "Track invoices, payment status, and follow-ups.", "entities": ["invoices"], "fields": ["Client", "Invoice #", "Amount", "Status", "Due Date"], "actions": ["Add invoice", "Mark paid", "Export CSV"], }, "inventory": { "headline": "Keep inventory clear without a heavy system.", "entities": ["items"], "fields": ["Item", "Category", "Quantity", "Reorder At", "Supplier"], "actions": ["Add item", "Update quantity", "Export CSV"], }, "task_board": { "headline": "Turn scattered work into a clear action board.", "entities": ["tasks"], "fields": ["Task", "Owner", "Priority", "Status", "Due Date"], "actions": ["Add task", "Mark complete", "Export CSV"], }, "estimate_builder": { "headline": "Build quotes and estimates without losing the details.", "entities": ["estimates"], "fields": ["Client", "Service", "Labor Hours", "Materials", "Estimate Total", "Status"], "actions": ["Add estimate", "Mark approved", "Export CSV"], }, "content_calendar": { "headline": "Plan posts, hooks, channels, and publish dates in one place.", "entities": ["content ideas"], "fields": ["Idea", "Channel", "Hook", "Publish Date", "Status", "Owner"], "actions": ["Add idea", "Mark published", "Export CSV"], }, "expense_tracker": { "headline": "Track expenses and cash movement before it gets messy.", "entities": ["expenses"], "fields": ["Vendor", "Category", "Amount", "Payment Method", "Date", "Status"], "actions": ["Add expense", "Mark reviewed", "Export CSV"], }, } def clean_text(value: Any, fallback: str) -> str: if not isinstance(value, str): return fallback value = re.sub(r"\s+", " ", value).strip() return value or fallback def infer_app_type(prompt: str) -> str: lower = prompt.lower() if any(term in lower for term in ["content calendar", "post calendar", "social calendar", "marketing calendar", "content planner", "post flow"]): return "content_calendar" if any(term in lower for term in ["expense", "budget", "cash flow", "spend", "receipt", "payment method"]): return "expense_tracker" if any(term in lower for term in ["estimate", "quote", "bid", "proposal calculator", "price calculator"]): return "estimate_builder" if any(term in lower for term in ["inventory", "stock", "reorder"]): return "inventory" if any(term in lower for term in ["crm", "lead", "prospect", "pipeline"]): return "crm" if any(term in lower for term in ["invoice", "paid", "payment"]): return "invoice_tracker" if any(term in lower for term in ["booking", "appointment", "calendar", "schedule"]): return "booking" return "task_board" def infer_app_name(prompt: str, app_type: str) -> str: stop_words = r"\s+(?:for|with|to|that|using|include|including|built|as)\b" patterns = [ rf"named\s+([A-Z][A-Za-z0-9 &'&-]{{2,70}}?)(?:\.|,|{stop_words}|$)", rf"called\s+([A-Z][A-Za-z0-9 &'&-]{{2,70}}?)(?:\.|,|{stop_words}|$)", ] for pattern in patterns: match = re.search(pattern, prompt, flags=re.IGNORECASE) if match: return clean_text(match.group(1), "Business App").rstrip(".") names = { "booking": "Booking Desk", "crm": "Lead Desk", "invoice_tracker": "Invoice Desk", "inventory": "Inventory Desk", "task_board": "Work Desk", "estimate_builder": "Estimate Desk", "content_calendar": "Content Desk", "expense_tracker": "Expense Desk", } return names.get(app_type, "Business App") def spec_from_prompt(prompt: str) -> AppSpec: app_type = infer_app_type(prompt) defaults = APP_DEFAULTS[app_type] return AppSpec( app_name=infer_app_name(prompt, app_type), app_type=app_type, headline=str(defaults["headline"]), entities=list(defaults["entities"]), fields=list(defaults["fields"]), actions=list(defaults["actions"]), accent="#38bdf8" if app_type in {"crm", "invoice_tracker", "content_calendar"} else "#f4ad32", ) def normalize_spec(raw: dict[str, Any] | AppSpec, prompt: str = "") -> AppSpec: if isinstance(raw, AppSpec): spec = raw else: fallback = spec_from_prompt(prompt) fields = raw.get("fields") if isinstance(raw.get("fields"), list) else fallback.fields actions = raw.get("actions") if isinstance(raw.get("actions"), list) else fallback.actions entities = raw.get("entities") if isinstance(raw.get("entities"), list) else fallback.entities spec = AppSpec( app_name=clean_text(raw.get("app_name"), fallback.app_name), app_type=clean_text(raw.get("app_type"), fallback.app_type).lower(), headline=clean_text(raw.get("headline"), fallback.headline), entities=[clean_text(item, "") for item in entities if isinstance(item, str)][:4] or fallback.entities, fields=[clean_text(item, "") for item in fields if isinstance(item, str)][:8] or fallback.fields, actions=[clean_text(item, "") for item in actions if isinstance(item, str)][:6] or fallback.actions, accent=clean_text(raw.get("accent"), fallback.accent), ) if spec.app_type not in APP_DEFAULTS: spec.app_type = infer_app_type(prompt) inferred_app_type = infer_app_type(prompt) if prompt and inferred_app_type != spec.app_type: previous_defaults = APP_DEFAULTS.get(spec.app_type, {}) previous_headline = str(previous_defaults.get("headline", "")) spec.app_type = inferred_app_type if spec.headline == previous_headline or "book appointments" in spec.headline.lower(): spec.headline = str(APP_DEFAULTS[spec.app_type]["headline"]) if len(spec.fields) < 3: spec.fields = list(APP_DEFAULTS[spec.app_type]["fields"]) if len(spec.actions) < 2: spec.actions = list(APP_DEFAULTS[spec.app_type]["actions"]) return spec def esc(value: str) -> str: return html.escape(value, quote=True) def slugify(value: str) -> str: return re.sub(r"[^a-z0-9]+", "-", value.lower()).strip("-") or "kaiju-app" def sample_value(field: str, app_type: str) -> str: lower = field.lower() if "name" in lower or "client" in lower or "customer" in lower: return "Jordan Lee" if "company" in lower: return "Bright Path Studio" if "service" in lower: return "Premium package" if "date" in lower or "due" in lower or "follow" in lower or "publish" in lower: return "2026-05-15" if "time" in lower: return "10:30 AM" if "phone" in lower: return "(404) 555-0199" if "amount" in lower or "total" in lower or "materials" in lower: return "$450" if "hour" in lower: return "4" if "status" in lower: return "Open" if "priority" in lower: return "High" if "owner" in lower: return "Richard" if "category" in lower: return "Retail" if "quantity" in lower: return "24" if "reorder" in lower: return "10" if "supplier" in lower or "vendor" in lower: return "Main Street Supply" if "item" in lower: return "Signature candles" if "idea" in lower: return "Before-and-after demo" if "hook" in lower: return "Stop losing leads in your notes" if "channel" in lower: return "YouTube" if "payment" in lower: return "Business card" if "invoice" in lower: return "INV-1007" if "task" in lower: return "Call warm leads" if "need" in lower: return "Website and checkout" return f"{app_type.replace('_', ' ').title()} sample" def render_field_inputs(fields: list[str]) -> str: return "\n".join( f'' for field in fields ) def render_table_headers(fields: list[str]) -> str: return "\n".join(f"
Kaiju one-file app
Built for business owners who need a working tool now: form entry, saved records, clear status, and CSV export without a backend.
| Created | Action |
|---|