All deployments

Peter Theill
Peter Theill 
deployed a styling change 20 days ago
Support
Support 
deployed a feature 22 days ago
Support
Support 
deployed a feature 23 days ago
Peter Theill
Peter Theill 
deployed a styling change 23 days ago
Peter Theill
Peter Theill 
deployed a dependency update 24 days ago
24 days ago
⬆️ Upgrade libraries
🔥 Remove domain verification and project claiming
Projects are now owned by their creator from the moment they are made.
The claim/verify flow (meta tag, DNS TXT, file upload, page content),
the ProjectClaim model, the verification columns on projects, and the
verified-owner gate on brand pages are all gone. Existing submitted-but-
unclaimed projects were handed to their submitters in the migration.
Peter Theill
Peter Theill 
deployed a styling change 24 days ago
24 days ago
💄 Inter typography and a headerless sidebar

  • Bundle Inter (variable, latin woff2 from Google Fonts) and use it


throughout with a larger type scale — body 14px, labels 13px,
hints 12px — replacing the system-font 11-13px mix

  • Drop the topbar (logo + name + subtitle): the sidebar's own Chrome


header already identifies the extension. The ⚙ settings toggle
moves into the Package slug section's header row, with the settings
panel opening directly beneath it. Bumps to 1.6.0
Peter Theill
Peter Theill 
deployed a dependency update 25 days ago
25 days ago
⬆️ Update brakeman to 8.0.6
bin/brakeman passes --ensure-latest, which exits 5 without scanning
whenever the gem is behind — the actual reason scan_ruby has failed
in CI since March.
Peter Theill
Peter Theill 
deployed a bug fix 25 days ago
25 days ago
🐛 Repair templates broken by the directory teardown
Brakeman's parser caught three views with orphaned markup left by the
block removals — the admin dashboard's reports card, the admin user
page's comments/reports sections (plus a dead @comments query), and
the profile page's bookmarks tail — all of which would 500 when
rendered. Removed the dangling fragments; Brakeman and RuboCop are
both clean.
Peter Theill
Peter Theill 
deployed a bug fix 25 days ago
25 days ago
🐛 Guard screenshot analysis on analyzed?, not width
When no image library is available the analyzer sets no dimensions,
so the width check re-triggered blob.analyze from the after_commit on
every commit until the stack overflowed (SystemStackError in CI).
Peter Theill
Peter Theill 
deployed a bug fix 25 days ago
25 days ago
🔥 Remove the public directory — Launch to Win is package-first
The listing/browsing product is gone, no legacy fallbacks kept:

  • Public browsing routes and pages deleted: browse/index, project show,


queued, lifetime deals, free, video reviews, user profiles (public),
my-projects, bookmarks; nav collapses to Directories + Extension and
footers drop the community stats and links

  • Community features deleted outright: upvotes, comments, bookmarks,


reports — models, controllers, views, admin screens, and tables
(DropBrowsingTables migration, irreversible)

  • Legacy deal pricing removed: is_free/is_lifetime_deal/deal_price/


original_price/deal_url columns dropped, pricing_display no longer
falls back, admin + launch forms lose the pricing_type radio,
autofill derives freemium as the default

  • ProjectsController keeps only new/create/destroy/claim/verify/


metadata; claim and verify land on the package hub; project sitemap
and seed-time community data removed
Projects remain solely as the record behind a launch package.
✨ Upload every screenshot, not just five
Drops the per-count cap on screenshot uploads — the only limit left
is a 40MB total payload guard for the injection message (8MB per
file, as before). Bumps to 1.5.2
🔥 Retire the listing editor — the package editor is the editor
Launch to Win pivots from being a directory of projects to packaging
products for launch everywhere, so one editor remains:

  • /projects/:slug/edit and its update redirect to the package editor


(old links and bookmarks keep working); the 454-line tabbed listing
view is deleted

  • Package editor gains contact phone (private, like contact email)


and a danger zone with project deletion; contact_phone is permitted

  • All links and post-create/submission redirects point at the package


editor; deleting redirects to the packages dashboard
🐛 Click the real option, not its listbox wrapper
fillCombobox matched '[role=option], [role=listbox] li' in document
order, so an inert <li> wrapper with the same text won as the exact
match and its click set nothing. Prefer [role=option] elements, click
the inner button when a wrapper is all we have, and verify the hidden
input's value actually changed — retrying with the widget opened when
the closed-state click doesn't take. Verified live on Huzzler's
category picker. Bumps to 1.5.1
✨ Fill uploads and custom dropdowns from the package

  • logo/screenshots resolve to asset URLs; the panel fetches the bytes


(8MB cap, up to 5 screenshots) and the page fill hands the input
real File objects via DataTransfer, firing input/change

  • Hidden inputs backing custom dropdowns are filled by opening the


widget and clicking the option matching one of the package's
categories (verified against Huzzler's Alpine combobox)

  • Scraper now includes file inputs (even behind styled dropzones) and


named hidden inputs, skipping csrf/honeypot names. Bumps to 1.5.0
✨ Map logo, screenshots and custom category pickers

  • FormFieldMapperService gains logo/screenshots as mappable targets


(file inputs) and allows category on hidden inputs backing custom
dropdowns; accept/multiple pass through to the model

  • PackageSerializer serves assets as storage proxy URLs so the


extension can fetch the bytes from our own host to fill uploads

  • Huzzler curated map now covers category, logo and media uploads

🐛 Clear error when the API base lacks the map endpoint
A 404 from POST /api/directories/map now says the configured API runs
an older server instead of a bare 'Not Found'. Stored-mapping hits
report source 'cache' so the sidebar can say a mapping was learned
earlier vs mapped just now. Dev hints corrected to port 3109 (bin/dev).
Bumps to 1.4.1
📝 Describe AI form mapping on the site
/extension feature card and the privacy policy now cover on-demand AI
mapping: only form structure is sent, never page values, and learned
mappings are stored and shared.
✨ Autofill any directory via AI mapping

  • Autofill is enabled on every http(s) page once a package is loaded:


curated mappings fill directly, otherwise the sidebar scrapes the
form's field structure (labels, names, attributes — never values),
posts it to /api/directories/map and fills from the answer

  • scrapeFormFields computes verified-unique selectors (#id, [name],


class, nth-of-type path) in the page, so the AI only picks by index

  • Zero fills from a stored mapping trigger one forced AI remap —


self-healing when a site redesigns its form

  • Multi-step forms: each step scrapes differently, so clicking


Autofill per step maps and remembers each step separately

  • Result notes the mapping source. Bumps to 1.4.0

✨ Learn form mappings on demand with AI
POST /api/directories/map answers with a curated Directory mapping,
a stored FormMapping learned earlier, or a fresh AI mapping (Gemini
flash) that is stored and shared by every user and package.

  • FormMapping keys on host + a signature of the form's fields, so a


redesign gets a new mapping and each step of a multi-step form gets
its own row

  • The model only assigns canonical fields to descriptor indexes; the


selectors come verbatim from the page, so it can't hallucinate them

  • force: true skips the stores and remaps (self-healing after a site


redesign); AI calls are throttled per host and per IP and gated on
a valid package slug

  • Verified against Gemini with the real Huzzler form: 4/4 fields,


including the maxlength and the Quill editor, category correctly
skipped
✨ Fill rich-text editors and report unmapped directories honestly

  • fillFormInPage handles contenteditable editors (Quill etc.): builds


paragraphs and fires an input event so the editor syncs

  • A directory that matches but has zero field mappings now reads


'no autofill mapping yet, copy fields below' with autofill disabled
and the copy panel opened, instead of the misleading 'your package
fields for this site are empty'. Bumps to 1.3.0
✨ Add tailored Huzzler field mapping
Selectors verified against huzzler.so/products/create: #name, #url,
#short_description (max 100) and the Quill .ql-editor full description.
Category (custom combobox) and logo/media uploads stay manual.
📝 Update site copy for the sidebar extension
Promo card, /extension page and privacy policy now describe the
sidebar behavior, the per-site access grant, and active-tab hostname
use; ships the 1.2.0 zip.
✨ Move the extension from popup to Chrome side panel

  • Toolbar icon now opens a sidebar (sidePanel API, Chrome 114+) that


stays open while browsing; src/popup.* renamed to src/panel.*

  • The panel follows the active tab via tabs.onActivated/onUpdated and


clears the previous page's fill report on site change

  • Page access is a per-site optional host permission requested on the


first autofill there (no activeTab grant exists in a sidebar)

  • Fluid panel width instead of the fixed 340px popup. Bumps to 1.2.0

✨ Promote the Chrome extension on the site

  • /extension page with features, install steps (load unpacked for


now), and a download of the packaged zip

  • script/package-extension --publish copies the zip to public/

  • My Packages page links to the extension so makers discover it

✨ Add copy panel to the extension popup
Every package field gets a copy button (plus Copy all), so the
extension is useful on directories without an autofill mapping —
the panel auto-expands on unmapped sites and stays collapsed where
autofill works. CANONICAL_FIELDS mirrors DEFAULT_LABELS and the sync
test now enforces the field list and labels too. Bumps to 1.1.0.
🔧 Prepare extension for the Chrome Web Store

  • script/package-extension builds a store-ready zip (manifest, icons,


src only) with optional MAJOR.MINOR.PATCH version bump

  • /privacy gains a Chrome-extension section for the store listing's


privacy policy URL
⚡️ Cache directory host lookup
Directory.find_by_host resolves a host through a cached host -> id map
keyed on maximum(:updated_at) + count, replacing the per-request scan
that loaded and URI-parsed every active directory in the API lookup.
✅ Enforce resolver.js / PackageFieldResolver sync
Runs a fully-populated project through PackageSerializer + the
extension's resolver.js (via node) and through PackageFieldResolver,
asserting every canonical field resolves identically and that no key
falls through to null in the extension. Skips when node is absent.
✨ Improve extension autofill feedback

  • Warn when values exceed a directory's character limits (max/over_by,


mirroring PackageFieldResolver#rows_for)

  • List required-but-empty package fields and prompt for a missing


contact email after filling

  • Distinguish an unreachable API from an unmapped directory

  • Try each comma-separated candidate when matching <select> options

  • Cache package/lookup responses in storage.session (5 min TTL);


explicit Load bypasses the cache, 404 lookups are never cached

  • Escape API-sourced strings before rendering them in the popup

Peter Theill
Peter Theill 
deployed a styling change 25 days ago
Support
Support 
deployed a feature 25 days ago
25 days ago
✨ Add pinned chat selected conversation title logic ✨ Introduce GuideDanmark image sharing warning ✨ Introduce gallery navigation button component ✨ Introduce new conversation features and agent tools
Support
Support 
deployed a feature 26 days ago
26 days ago
✨ Enhance agent and conversation features ✨ Introduce GuideDanmark publish job management ✨ Introduce automation status management
Peter Theill
Peter Theill 
deployed a refactoring 28 days ago
Peter Theill
Peter Theill 
deployed a styling change 28 days ago
Peter Theill
Peter Theill 
deployed a CI/build change 28 days ago
28 days ago
💚 Pin Docker build to Ruby 3.4.7
The deploy got past setup-ruby but failed inside the image build with the
same error: parallel 2.1.0 requires Ruby >= 3.3, but the build ran on
3.2.3.
Two places still pinned the old version. config/deploy.yml is the
decisive one, since kamal passes RUBY_VERSION as a build arg that
overrides the Dockerfile default, so fixing the Dockerfile alone would
not have changed the build.
Both now match .ruby-version (3.4.7), as the comment above the ARG
already asked for.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HCxJUTQkwwSCMoJpmuiZep
Support
Support 
deployed a feature 29 days ago
29 days ago
🐛 Add entity support to automation settings 🐛 Introduce generateShortId for ID generation ✨ Enhance AgentBatchActivity and ToolActivityDetails ✨ Enhance InputReadOnly component and UI ✨ Enhance agent run status and progress messaging ✨ Introduce Create Place feature with AI support ✨ Introduce GuideDanmark import functionality ✨ Introduce Supplier Event Periods and Prices Cards ✨ Introduce agent email address and update UI elements ✨ Introduce booking and social media links ✨ Introduce conversation title updates ✨ Introduce entity chat attachment owner functionality ✨ Introduce event creation chat feature ✨ Introduce hours periods management feature ✨ Introduce new features for entity change proposals ✨ Introduce period display helper functions ✨ Introduce scope click functionality ✨ Introduce supplier entity and related updates ✨ Introduce support for web search functionality ✨ Update postinstall script for templ8-ui ✨ Add automation pause controls
Peter Theill
Peter Theill 
deployed a bug fix about 1 month ago
Support
Support 
deployed a feature about 1 month ago
Support
Support 
deployed a feature about 1 month ago