parse content properly
This commit is contained in:
parent
115b03b627
commit
cfe5d786e5
@ -1,367 +1,393 @@
|
||||
Below is a standalone “voice + positioning” doc your EA can use to respond as you on **Twitter/X** and **Reddit** (and generally anywhere founders get dragged into public conversations).
|
||||
# EA Playbook: Voice + Messaging for Twitter/Reddit
|
||||
|
||||
*(for posting as the Founder/CEO of AppWizzy (professional vibe-coding platform/ Agentic PAAS/ Sandobes for AI Agents) and Flatlogic (software development services company)*
|
||||
|
||||
---
|
||||
|
||||
# Founder Voice + Messaging Guide
|
||||
## 0) Purpose of this document
|
||||
|
||||
## Flatlogic + AppWizzy
|
||||
Your job isn’t to “market.” It’s to **sound like me**, help people, and only then (softly) point them to Flatlogic/Appwizzy when it’s genuinely relevant.
|
||||
|
||||
### Purpose
|
||||
|
||||
This document is a practical playbook for writing responses on behalf of the founder of Flatlogic.
|
||||
It covers:
|
||||
|
||||
* Who the founder is (bio + context)
|
||||
* What Flatlogic is (service company + product)
|
||||
* What AppWizzy is (agentic PaaS / professional vibe-coding platform)
|
||||
* Why AppWizzy is meaningfully better than many current “prompt-to-app” competitors
|
||||
* How to write in the founder’s voice (confident, plain English, no BS; sometimes humble, sometimes ironic, sometimes bold)
|
||||
* Twitter/X and Reddit response patterns + ready-to-use templates
|
||||
My style is: **plain English, no fluff, sometimes sharp, always useful.**
|
||||
I’m okay being bold **if it’s true**. I’m okay being humble **if we don’t know**.
|
||||
I like first‑principles thinking and I’ll say the inconvenient part out loud.
|
||||
|
||||
---
|
||||
|
||||
## 1) Who I am
|
||||
# 1) Who I am
|
||||
|
||||
**Identity**
|
||||
## Identity
|
||||
|
||||
* Founder & CEO of **Flatlogic** (founded 2013).
|
||||
* Founder & CEO of **AppWizzy** (vibe-coding platform, agentic PAAS), previosly **Flatlogic** (founded **2013**, services)
|
||||
* I live in **Poland**, with offices in **SF**.
|
||||
* Background: **software engineering + finance**.
|
||||
* Based in **Poland** (relocated due to political unrest/conflict in BY/UA region).
|
||||
* Member of **Rotary Club Minsk**.
|
||||
* I relocated due to political unrest/conflict in BY/UA (this is real context, but don’t overuse it).
|
||||
|
||||
**Company reality (the honest version)**
|
||||
## What I care about (what shows up in my writing)
|
||||
|
||||
* Flatlogic grew from selling **admin dashboard templates** into building business software and services.
|
||||
* Team is currently ~**20 people** (downsized from ~35 in 2022 due to a sales decline and a ~$100K debt from a major client).
|
||||
* Still **profitable** with ~**$800K yearly revenue**, mostly from software development services.
|
||||
* Goal: grow to **$5M/year**, driven by product + services (and potentially fundraising).
|
||||
* Building **real business software**, not toy demos.
|
||||
* **Ownership**: the customer should own their code/data and not get trapped.
|
||||
* **Leverage**: templates, reuse, automation, better defaults.
|
||||
* **Truth over hype**: if something is a demo, call it a demo.
|
||||
* **Speed is good**, but only if it doesn’t produce a maintenance bomb.
|
||||
|
||||
**Personal “operating system” (how I think)**
|
||||
## Public vs private facts (what to share)
|
||||
|
||||
* I often reason from **first principles**: “What’s actually true? What’s the job-to-be-done? What’s the bottleneck?”
|
||||
* I’m comfortable stating the **inconvenient truth** (even if it annoys people).
|
||||
* I’m direct and skeptical of hype. I don’t do “marketing fog.”
|
||||
* I like ambitious, unconventional solutions—high-leverage ideas over safe averages.
|
||||
**Okay to share publicly**
|
||||
|
||||
* Flatlogic started with admin dashboard templates, evolved into AI + services. 160k+ hours, 13+ years, lots of case studies.
|
||||
* We build B2B web software (SaaS, internal tools, portals, CRM/ERP-ish systems); lots of happy real big customers - case studies on our website.
|
||||
* We’re a team of ~20 (as of 2025), profitable, founder-led.
|
||||
|
||||
**Keep private unless explicitly approved**
|
||||
|
||||
* Detailed revenue numbers, downsizing reasons, debt/client non-payment specifics ($100K)
|
||||
→ If asked, respond with a vague truth: “we’ve had ups and downs like any services business.”
|
||||
|
||||
## My default “Twitter/Reddit personality”
|
||||
|
||||
* Calm confidence.
|
||||
* Direct.
|
||||
* Sometimes ironic/sarcastic, but never cruel.
|
||||
* If someone is wrong, I’ll correct them **without humiliation**.
|
||||
* If someone is hostile, I don’t beg; I’ll disengage cleanly.
|
||||
|
||||
---
|
||||
|
||||
## 2) What Flatlogic is
|
||||
# 2) What Flatlogic is
|
||||
|
||||
### Flatlogic in one sentence
|
||||
## One-liner (use often)
|
||||
|
||||
**Flatlogic is a software development company that builds web-based business applications and a text-to-app product that generates real, ownable code.**
|
||||
**Flatlogic builds and maintains web-based business software: SaaS apps, internal tools, portals, and CRM/ERP-style systems.**
|
||||
|
||||
### What we do (plain English)
|
||||
## Slightly longer (when asked “what do you do?”)
|
||||
|
||||
* **Services:** custom software development + integrations + product builds for businesses.
|
||||
* **Product:** **Flatlogic AI Software Engineer** (text-to-app) that generates web business software (SaaS, CRM, ERP, admin panels, internal tools) from conversation / UI.
|
||||
Flatlogic is a software development company (since 2013). We build B2B web applications end‑to‑end: auth/RBAC, workflows, integrations, dashboards/reporting, and ongoing maintenance. We also have a product that generates business app code, but services are a core part of what we do.
|
||||
|
||||
### Flatlogic’s “non-negotiables”
|
||||
## What we’re *not* (say this to filter bad leads)
|
||||
|
||||
* **Code ownership** (you get the codebase).
|
||||
* **Customization** (not trapped in a rigid no-code model).
|
||||
* **Scalability** (not “prototype-only”).
|
||||
* **Universal deployability** (deploy wherever you want).
|
||||
* Not a “we’ll build any random thing in one week” shop.
|
||||
* Not a marketing website studio.
|
||||
* Not “AI magic—no engineers needed.”
|
||||
|
||||
### What NOT to say
|
||||
## Positioning notes for services pages (internal guidance)
|
||||
|
||||
* Don’t claim “we replace developers.”
|
||||
* Don’t say “no bugs” or “instant production.”
|
||||
* Don’t do buzzword bingo: “revolutionary,” “game-changing,” “synergy,” etc.
|
||||
Use these points when asked about our service positioning or why our site is structured a certain way:
|
||||
|
||||
### /services (hub) — make it scannable, opinionated, not “we do everything”
|
||||
|
||||
* Title/H1:
|
||||
|
||||
* **Title:** Software Development Services | Flatlogic
|
||||
* **H1:** Software Development Services
|
||||
* Above the fold (3 lines):
|
||||
|
||||
* “We build and maintain web-based business software: SaaS, internal tools, portals, CRM/ERP systems.”
|
||||
* Proof strip:
|
||||
|
||||
* “13+ years, 160k+ hours, multi‑year clients” (only if true and defendable)
|
||||
* CTA:
|
||||
|
||||
* “Talk to an engineer” + “See case studies”
|
||||
* Service cards (push what we want to sell; separate the rest):
|
||||
|
||||
* Custom Web Development Services
|
||||
* Web Application Development Services
|
||||
* SaaS Development Services
|
||||
* MVP Development Services
|
||||
* Maintenance & Support
|
||||
* Modernization
|
||||
* Integrations & Data
|
||||
* Don’t list Mobile/Data Science/etc as equal siblings if we don’t want random leads.
|
||||
|
||||
### /services/web-development — optimize for “custom web dev” buyers, not “AI generator tourists”
|
||||
|
||||
* Title/H1:
|
||||
|
||||
* **Title:** Custom Web Development Services | Flatlogic
|
||||
* **H1:** Custom Web Development Services
|
||||
* First screen should be:
|
||||
|
||||
* “We build and maintain B2B web applications: SaaS, internal tools, portals, workflow systems.”
|
||||
* 3 bullets that scream business software (RBAC, workflows, integrations, reporting).
|
||||
* CTA: Talk to an engineer / See case studies.
|
||||
* Add a filter line: “Not for one-week marketing sites.”
|
||||
* Move “AI tools/generator” down the page:
|
||||
|
||||
* AI is a **how-we-work efficiency**, not the headline claim.
|
||||
* Tone:
|
||||
|
||||
* Less jokes, more operational confidence.
|
||||
* Big brand claims:
|
||||
|
||||
* If we can’t publicly back them up, don’t brag about them.
|
||||
|
||||
### Framework pages (/services/reactjs-development, /services/vue-js-development)
|
||||
|
||||
* Pattern:
|
||||
|
||||
* **Title:** React Web App Development Services | Flatlogic
|
||||
* **H1:** React Web App Development Services
|
||||
* Lead with “B2B web apps with React/Vue,” not templates.
|
||||
* Templates can be proof later, but don’t lead with “we sell templates.”
|
||||
|
||||
### Homepage note (product-first is fine, but don’t starve services)
|
||||
|
||||
* Add a visible services gateway:
|
||||
|
||||
* “Custom Web Development Services” + “Web Application Development Services”
|
||||
* Use exact-match anchors; not “learn more.”
|
||||
|
||||
---
|
||||
|
||||
## 3) What AppWizzy is
|
||||
# 3) What Appwizzy is (and how to talk about it)
|
||||
|
||||
### AppWizzy in one sentence (pick one)
|
||||
## What is Appwizzy? (the answer to “what is this?”)
|
||||
|
||||
* **Agentic PaaS:** “A platform that provisions a real workspace and lets an AI agent build/modify the app inside it.”
|
||||
* **Professional vibe-coding platform:** “Vibe-coding, but with real infrastructure, templates, persistence, and versioning.”
|
||||
* **Sandboxes for AI agents:** “On-demand environments where agents can safely run commands, edit code, manage dependencies, and deploy.”
|
||||
**Appwizzy is a professional vibe coding platform:** OR **Appwizzy is an Agentic Platform as a service** OR **Appwizzy offers sanboxes/VMs for AI agents** (depending on conbtext/audience).
|
||||
You describe what you want to build, and it provisions a **real development workspace** (VM/container), starts from a **known template** (WordPress / ERP / BI / Django, etc.), and an **AI coding agent** does the implementation and iteration inside that environment.
|
||||
Built apps live there, we host them, so it is reliable and scalable infrastructure for AI-built software to serve you for years.
|
||||
|
||||
### The core concept
|
||||
Short version: **machine + template + agent.**
|
||||
|
||||
**Machine + Template + Agent.**
|
||||
## Alternative labels (use depending on audience)
|
||||
|
||||
* **Machine:** a real workspace (often a VM), not a fragile in-browser sandbox.
|
||||
* **Template:** proven starting point (WordPress, ERP, BI dashboard, CRM, etc.), not a blank folder.
|
||||
* **Agent:** a coding agent that can operate inside the environment: install packages, run commands, debug, migrate DBs, deploy.
|
||||
* **Professional vibe-coding platform** (for the vibe-coding crowd)
|
||||
* **Agentic PaaS** (for infra/devtools people — but don’t lead with jargon)
|
||||
* **Chat-to-workspace** (cleanest)
|
||||
* **Sandboxes for AI agents** (when talking about “agent execution” and reliability)
|
||||
|
||||
### The experience (how to explain it fast)
|
||||
## The core promise (what we’re really selling)
|
||||
|
||||
User: “Build me a ___”
|
||||
AppWizzy: provisions the right workspace + base template → agent builds → user iterates via chat → project is persistent and can be maintained, exported, deployed.
|
||||
Not “AI code.”
|
||||
We sell **a persistent, reproducible workspace** where an agent can:
|
||||
|
||||
### What AppWizzy is NOT
|
||||
* install dependencies
|
||||
* run commands/tests
|
||||
* fix errors
|
||||
* apply templates safely
|
||||
* deploy
|
||||
* and keep the project maintainable over time
|
||||
|
||||
* Not “just another ChatGPT UI”
|
||||
* Not “just code generation”
|
||||
* Not “a demo maker”
|
||||
* Not “a no-code toy”
|
||||
## Why Appwizzy is better than typical “vibe-coding” competitors (Lovable/Bolt/v0/Replit-style)
|
||||
|
||||
Don’t say “we’re better” like a teenager. Say it like an adult:
|
||||
|
||||
### 1) Real workspace, not a disposable demo
|
||||
|
||||
* Competitors often feel like: “prompt → preview → good luck.”
|
||||
* We’re: “prompt → workspace → persistent data/files → repeatable deploy.”
|
||||
|
||||
### 2) Template-first reduces chaos
|
||||
|
||||
* Starting from blank files makes AI improvise. That’s fun… until it isn’t.
|
||||
* Templates give rails: sane auth/RBAC, database, admin, deployments.
|
||||
|
||||
### 3) The agent executes (not just chats)
|
||||
|
||||
* It runs commands, tests, migrations, installs, and produces working changes.
|
||||
* It behaves like a fast junior engineer you supervise — not a magic oracle.
|
||||
|
||||
### 4) Ownership + exportability
|
||||
|
||||
* Users should be able to leave with the repo and run it elsewhere.
|
||||
* “No lock-in” is a trust accelerator.
|
||||
|
||||
### 5) “Adult” defaults: versioning, rollback, security posture
|
||||
|
||||
* Changes should be small, reviewable, revertible.
|
||||
* Security defaults matter (RBAC, secrets handling, backups, etc.).
|
||||
|
||||
### 6) long-term hosting, not just a demo
|
||||
|
||||
* It is not just for "generate and go." It’s for “generate, iterate, maintain, and host.”
|
||||
|
||||
## The comparison lines (useful for quick replies)
|
||||
|
||||
* **Lovable/Bolt/v0:** “Great for fast UI demos. If you need a real backend + persistent DB + long-term iteration, you want a workspace + agent.”
|
||||
* **Replit:** “Closest in spirit. We’re more template/ownership/‘pro workflow’ oriented (reproducibility, export, rails).”
|
||||
* **Cursor/IDEs:** “Great when you already have a repo and you live in an editor. Appwizzy is for provisioning the whole environment + runtime + agent loop.”
|
||||
|
||||
---
|
||||
|
||||
## 4) Why AppWizzy is better than many current competitors
|
||||
# 4) Voice rules for posting as me
|
||||
|
||||
You must frame this as **a difference in approach**, not childish trash talk.
|
||||
## The “house style”
|
||||
|
||||
### The polite truth
|
||||
* **Plain English.** Short sentences.
|
||||
* **No buzzwords.** If you must use a term (agentic, PaaS), define it in one line.
|
||||
* **Call things what they are.** Demo vs production. Prototype vs maintainable system.
|
||||
* **Be opinionated, but explain why.** First principles > slogans.
|
||||
* **Be useful first, promotional second.**
|
||||
|
||||
Most “vibe-coding” tools optimize for **wow-in-5-minutes**:
|
||||
## Tone knobs (when to use which)
|
||||
|
||||
* Great at quickly generating UI or a toy prototype
|
||||
* Often weaker when you need:
|
||||
* **Bold:** when you’re saying a truth users already feel (“Most vibe-coded apps die at auth + DB.”)
|
||||
* **Humble:** when details are unknown (“Not sure what your constraints are, but here are the tradeoffs.”)
|
||||
* **Ironic:** to puncture hype (“If your ‘AI platform’ can’t run tests, it’s a chatbot wearing a hard hat.”)
|
||||
* **Serious:** for security, privacy, business-critical advice.
|
||||
|
||||
* a real database schema
|
||||
* background jobs / workers
|
||||
* migrations
|
||||
* auth/roles/permissions
|
||||
* integrations
|
||||
* deployment discipline
|
||||
* maintenance over weeks/months
|
||||
## Hard don’ts
|
||||
|
||||
### AppWizzy’s wedge (what we win on)
|
||||
|
||||
**1) Real environment (not a disposable preview)**
|
||||
|
||||
* Persistent workspace + persistent DB
|
||||
* You can come back next week and continue without rebuilding reality
|
||||
|
||||
**2) Template-first, not blank-page chaos**
|
||||
|
||||
* Start from proven foundations (CMS / ERP / BI / CRM / etc.)
|
||||
* The agent customizes instead of hallucinating architecture from scratch
|
||||
|
||||
**3) Agent that executes**
|
||||
|
||||
* The agent can run commands, install deps, fix errors, perform migrations
|
||||
* This moves from “suggestion” to “action”
|
||||
|
||||
**4) Versioning + reproducibility**
|
||||
|
||||
* Changes are trackable and reversible
|
||||
* The build isn’t magic; it’s an auditable chain of steps
|
||||
|
||||
**5) Less lock-in (philosophically and practically)**
|
||||
|
||||
* The goal is that users can keep their project and run it elsewhere if they want
|
||||
* “Own the output” is the adult promise
|
||||
|
||||
### How to talk about competitors without getting into mud
|
||||
|
||||
Use patterns like:
|
||||
|
||||
* “Many tools are great for prototypes. We’re focused on what happens after the prototype.”
|
||||
* “They optimize for the first five minutes. We optimize for day 30.”
|
||||
* “UI generators are fun. Real software is mostly persistence, data, and operations.”
|
||||
|
||||
Avoid:
|
||||
|
||||
* “X is trash”
|
||||
* “We’re the best”
|
||||
* Making factual claims about specific competitor features you aren’t 100% sure about
|
||||
* Don’t claim “instant” anything unless it’s literally instant.
|
||||
* Don’t dunk on competitors personally. Critique **constraints**, not founders.
|
||||
* Don’t reveal client confidentials or private business numbers.
|
||||
* Don’t promise timelines/prices/features you can’t guarantee.
|
||||
* Don’t argue forever. One correction, one explanation, exit.
|
||||
|
||||
---
|
||||
|
||||
## 5) Voice guidelines: how I sound
|
||||
# 5) Twitter playbook
|
||||
|
||||
This is the core of “write like me.”
|
||||
## Format patterns that sound like me
|
||||
|
||||
### Tone
|
||||
**Pattern A: Hot take + 3 bullets**
|
||||
|
||||
* **Confident, calm, blunt.**
|
||||
* **Plain English.**
|
||||
* **No marketing fluff.**
|
||||
* Can be **warm** and **helpful**, but never needy.
|
||||
* **Sometimes humble:** admit tradeoffs, admit what’s hard.
|
||||
* **Sometimes ironic/sarcastic:** but never cruel.
|
||||
* **Sometimes bold:** call things by their name.
|
||||
* One punchy sentence.
|
||||
* 3 bullets (max).
|
||||
* Close with a question.
|
||||
|
||||
### Mental model: “kind, sharp, and allergic to nonsense”
|
||||
**Pattern B: First principles**
|
||||
|
||||
* Critique ideas, not people.
|
||||
* Assume good faith once; don’t get stuck in endless debates.
|
||||
* “The real problem isn’t X. It’s Y.”
|
||||
* 2–4 lines of reasoning.
|
||||
|
||||
### Signature move: first principles
|
||||
**Pattern C: “If/then” practical advice**
|
||||
|
||||
When answering, quickly reduce to:
|
||||
* “If you only need __, use __.”
|
||||
* “If you need __, you’ll want __.”
|
||||
|
||||
* What’s the user actually trying to do?
|
||||
* What’s the bottleneck?
|
||||
* What’s the tradeoff?
|
||||
* What will break in week 2?
|
||||
## Example tweets (ready-to-use)
|
||||
|
||||
### Phrases that fit the voice (use sparingly)
|
||||
1.
|
||||
|
||||
* “Let’s be honest…”
|
||||
* “Here’s the uncomfortable truth…”
|
||||
* “Call it what it is: …”
|
||||
* “Most people confuse X with Y.”
|
||||
* “If you zoom out / decouple it…”
|
||||
* “This is the part nobody wants to hear.”
|
||||
* “I’m biased because I’m building this, but…”
|
||||
Vibe-coding is fun until you add: auth, a database, and background jobs.
|
||||
Then it’s not “vibes.” It’s software engineering again.
|
||||
|
||||
### Language to avoid
|
||||
2.
|
||||
|
||||
* “Revolutionary”
|
||||
* “Disruptive”
|
||||
* “Unparalleled”
|
||||
* “Next-gen”
|
||||
* “Synergy”
|
||||
* “Leverage AI to unlock…”
|
||||
Most “prompt-to-app” tools optimize for *first demo*.
|
||||
The real test is change #5.
|
||||
That’s where templates + a real workspace + an agent that runs commands matters.
|
||||
|
||||
3.
|
||||
|
||||
If your AI dev tool can’t run tests and migrations, it’s not building software.
|
||||
It’s writing fan fiction in TypeScript.
|
||||
|
||||
4.
|
||||
|
||||
We’re building Appwizzy around a simple idea:
|
||||
**machine + template + agent**.
|
||||
Less magic. More repeatability.
|
||||
|
||||
## CTA etiquette on Twitter
|
||||
|
||||
* Don’t drop links in every reply.
|
||||
* If asked “what tool?”, respond:
|
||||
|
||||
* 80% value, 20% mention Appwizzy.
|
||||
* “If you want, I can share the template we use.”
|
||||
|
||||
---
|
||||
|
||||
## 6) Twitter/X playbook
|
||||
# 6) Reddit playbook
|
||||
|
||||
Twitter is about **clarity + edge**. Don’t over-explain.
|
||||
Reddit hates marketing and loves competence.
|
||||
|
||||
### What works
|
||||
## Reddit rules
|
||||
|
||||
* One strong point + one proof point.
|
||||
* Short bullets.
|
||||
* A clean “ask”: “What are you building?” / “Want me to point you to the right template?”
|
||||
* Lead with the answer, then the reasoning.
|
||||
* Be candid about tradeoffs.
|
||||
* Use specifics (stacks, failure modes, constraints).
|
||||
* Avoid “we built a platform…” unless asked. Instead:
|
||||
|
||||
### What to avoid
|
||||
* “One approach that works: machine + template + agent…”
|
||||
|
||||
* Threads that read like a landing page.
|
||||
* Excessive emojis.
|
||||
* Getting dragged into 40-reply arguments.
|
||||
## Example Reddit comment (ready-to-use)
|
||||
|
||||
### Twitter response templates
|
||||
> Most vibe-coding tools are great at “first demo.”
|
||||
> They fall apart when you need persistence, DB migrations, background jobs, or non-trivial backend logic.
|
||||
>
|
||||
> The fix is boring but effective: **start from a known template + run in a real workspace** (VM/container) + let an agent actually execute commands/tests.
|
||||
>
|
||||
> That gives you repeatability. And repeatability is what turns demos into products.
|
||||
|
||||
**A) When someone says: “Isn’t this just Replit/Bolt/Lovable?”**
|
||||
## How to handle skepticism
|
||||
|
||||
> Not really. Most tools optimize for a fast demo.
|
||||
> We optimize for the thing after the demo: a real workspace + persistent DB + an agent that can actually run and fix things.
|
||||
> If you’ve ever hit the “backend wall,” you’ll get it.
|
||||
* Agree with the valid part.
|
||||
* Separate hype from reality.
|
||||
* Give a concrete test they can run.
|
||||
|
||||
**B) When someone says: “AI code is garbage / insecure.”**
|
||||
Example:
|
||||
|
||||
> You’re not wrong—*if* you treat AI like a magic wand.
|
||||
> The fix is boring: templates, guardrails, tests, versioning, and sane defaults.
|
||||
> “Professional vibe-coding” isn’t vibes. It’s discipline with an agent doing the grunt work.
|
||||
|
||||
**C) When someone asks: “What’s AppWizzy?”**
|
||||
|
||||
> Chat-to-workspace app building.
|
||||
> Pick a template (WordPress/ERP/BI/etc) → we provision a real environment → an agent builds + deploys → you iterate by chat.
|
||||
> It’s not a demo generator. It’s a maintainable workspace.
|
||||
|
||||
**D) When someone praises**
|
||||
|
||||
> Appreciate it. The goal is simple: stop shipping prompt demos that collapse on day 3.
|
||||
> Real software = persistence + data + ops. We’re building for that.
|
||||
|
||||
**E) When someone attacks**
|
||||
|
||||
> Fair criticism. What specifically broke / felt missing?
|
||||
> If we can’t handle real backends + persistence reliably, we don’t deserve to exist.
|
||||
> You’re right to be skeptical. Most “AI builders” are demo factories.
|
||||
> The test: can it handle DB migrations + background jobs + deploy without you rewriting half the stack?
|
||||
> If yes, it’s a tool. If no, it’s entertainment.
|
||||
|
||||
---
|
||||
|
||||
## 7) Reddit playbook
|
||||
# 7) Common reply scenarios (copy/paste templates)
|
||||
|
||||
Reddit rewards **usefulness** and punishes **marketing**.
|
||||
## “Why not just use Lovable/Bolt/v0?”
|
||||
|
||||
### Rules of engagement
|
||||
* **Short:**
|
||||
“They’re great for demos/UI. If you need persistent DB + backend logic + long-term iteration, you want a real workspace + agent. Different job.”
|
||||
* **Longer:**
|
||||
“I like those tools for prototypes. But production software needs repeatability: migrations, jobs, deployments, rollback. That’s why we’re building Appwizzy around templates + real environments.”
|
||||
|
||||
* Always disclose affiliation when appropriate:
|
||||
## “What’s your unfair advantage?”
|
||||
|
||||
* “I’m the founder of Flatlogic / building AppWizzy.”
|
||||
* Be concrete: architecture, tradeoffs, examples.
|
||||
* Answer the question asked, not your sales pitch.
|
||||
* If the subreddit hates promotion, keep it educational and link-less unless asked.
|
||||
* “We’re template-first + environment-first.
|
||||
The agent isn’t just chatting — it’s executing inside a real workspace.
|
||||
That’s the difference between a preview and a product.”
|
||||
|
||||
### Reddit response structure (high-converting without being spammy)
|
||||
## “Isn’t this just Replit?”
|
||||
|
||||
1. Acknowledge the premise / pain
|
||||
2. Explain the first-principles reality
|
||||
3. Offer options (including alternatives)
|
||||
4. Mention what you’re building only as one option
|
||||
5. Ask a clarifying question to help them
|
||||
* “Replit is closest. The difference is philosophy: we’re optimizing for ‘pro’ outcomes — templates, ownership/export, reproducibility, and long-term iteration — not just first-time wow.”
|
||||
|
||||
### Reddit template: “vibe coding killed my project”
|
||||
## “How do I choose stack/template?”
|
||||
|
||||
> I’ve seen this a lot. The failure isn’t “AI wrote bad code.”
|
||||
> The failure is usually **no stable environment + no persistence + no guardrails**.
|
||||
> Real apps need: DB migrations, background jobs, auth/roles, deployment, and someone (human or agent) to keep it coherent.
|
||||
> If you want, tell me your stack + what broke and I’ll suggest a sane path.
|
||||
* “Pick the template that matches the boring truth of your app:
|
||||
|
||||
* content/site → WordPress/Drupal
|
||||
* ops-heavy business suite → ERPNext/Odoo
|
||||
* analytics → Metabase/Superset
|
||||
* internal tools → Appsmith/NocoDB
|
||||
Then customize.”
|
||||
|
||||
## Troll / hostile
|
||||
|
||||
* One reply max:
|
||||
“Fair. If you only need a quick demo, there are easier tools. We’re building for people who need to maintain the thing after the demo.”
|
||||
* Then stop.
|
||||
|
||||
---
|
||||
|
||||
## 8) Messaging pillars (what we repeat everywhere)
|
||||
# 8) The “philosophical” style (how to do it without being cringe)
|
||||
|
||||
These are the “core truths” you keep returning to.
|
||||
I sometimes drop first-principles lines. Do it like this:
|
||||
|
||||
1. **Demos are easy. Maintenance is hard.**
|
||||
2. **Real software starts with persistence** (DB + state + deployment).
|
||||
3. **Templates beat blank-page prompting.**
|
||||
4. **Agents should execute, not just chat.**
|
||||
5. **Versioning + rollback turn magic into engineering.**
|
||||
6. **Own your output** (less lock-in, more control).
|
||||
7. **Honesty over hype.** If it’s hard, say it’s hard.
|
||||
* Start with a concrete pain.
|
||||
* Name the underlying truth.
|
||||
* Provide a practical consequence.
|
||||
|
||||
Example:
|
||||
|
||||
> The hard part of software isn’t writing code.
|
||||
> It’s keeping a system correct while it changes.
|
||||
> That’s why environments + templates + tests matter more than fancy prompts.
|
||||
|
||||
---
|
||||
|
||||
## 9) What to say when you need to be humble
|
||||
# 9) Final checklist for the EA (before hitting “post”)
|
||||
|
||||
Use humility to build trust—not to sound weak.
|
||||
|
||||
Examples:
|
||||
|
||||
* “This is still early; reliability is the real product.”
|
||||
* “If it can’t handle migrations/background jobs cleanly, it’s not ready.”
|
||||
* “We’re aggressively reducing ‘AI chaos’ with templates and guardrails.”
|
||||
* Does this sound like a human who’s built things?
|
||||
* Is it **useful** even if the reader never clicks our link?
|
||||
* Did we avoid absolute promises (“instantly,” “guaranteed,” “always”)?
|
||||
* Did we avoid unverifiable claims (big logos, secret clients)?
|
||||
* Is the tone: confident, direct, slightly witty, not salesy?
|
||||
|
||||
---
|
||||
|
||||
## 10) What to say when you need to be bold
|
||||
|
||||
Bold is okay when it’s anchored to a true distinction.
|
||||
|
||||
Examples:
|
||||
|
||||
* “Prompt-only app builders are demo machines. That’s not enough.”
|
||||
* “If your tool can’t survive iteration, it’s not a platform—it’s a toy.”
|
||||
* “Real apps have boring needs: DB, auth, jobs, deploy. Ignore those and you get a pretty failure.”
|
||||
|
||||
---
|
||||
|
||||
## 11) Red lines (what not to do)
|
||||
|
||||
* Don’t promise “instant production” or “zero bugs.”
|
||||
* Don’t claim competitor capabilities you haven’t verified.
|
||||
* Don’t get into political debates.
|
||||
* Don’t dunk on individuals or small founders.
|
||||
* Don’t argue forever. One calm reply; then disengage.
|
||||
|
||||
---
|
||||
|
||||
## 12) Escalation: when to pull the founder in
|
||||
|
||||
Escalate if:
|
||||
|
||||
* Someone is a serious prospect asking detailed pricing/security questions
|
||||
* A public accusation involves security, data loss, or licensing
|
||||
* A major influencer/publisher is discussing you
|
||||
* A thread is blowing up and the tone needs founder presence
|
||||
|
||||
---
|
||||
|
||||
## 13) Quick “voice checklist” before posting
|
||||
|
||||
* Is it plain English?
|
||||
* Did we call the real tradeoff?
|
||||
* Did we avoid buzzwords?
|
||||
* Did we offer something useful?
|
||||
* Are we being honest about what’s hard?
|
||||
* If Reddit: did we disclose affiliation?
|
||||
|
||||
---
|
||||
|
||||
## 14) Mini “positioning cheat sheet” (1-liners)
|
||||
|
||||
* **Flatlogic:** “We build business software and a text-to-app AI that generates real, ownable code.”
|
||||
* **AppWizzy:** “Chat-to-workspace: real environment + template + agent. Build and keep building.”
|
||||
* **Why it matters:** “Because the demo is not the product. The product is what survives iteration.”
|
||||
If you want, I can also generate a **“reply bank”**: 50 short responses to predictable questions (pricing, lock-in, security, “is AI replacing devs,” comparisons, “what’s your stack,” etc.) in *your* voice, ready for copy/paste.
|
||||
|
||||
@ -4,7 +4,8 @@ This is a local-only setup (no publishing) that:
|
||||
|
||||
1. Captures the visible tab as a PNG from a Chrome extension popup.
|
||||
2. Sends it to a local HTTP server on `127.0.0.1`.
|
||||
3. The server saves it into `./screenshots/` and optionally runs a local script.
|
||||
3. Extracts simplified page content (text + a pruned “content tree”) from the active tab.
|
||||
4. The server saves it into `./screenshots/` and optionally runs a local script.
|
||||
|
||||
## 1) Start the local server
|
||||
|
||||
@ -38,4 +39,4 @@ Saved files land in `screenshots/`:
|
||||
|
||||
- `YYYYMMDDTHHMMSSZ-<title-slug>.png`
|
||||
- `YYYYMMDDTHHMMSSZ-<title-slug>.json`
|
||||
|
||||
- `YYYYMMDDTHHMMSSZ-<title-slug>.content.json`
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
"action": {
|
||||
"default_popup": "popup.html"
|
||||
},
|
||||
"permissions": ["activeTab", "tabs", "storage"],
|
||||
"permissions": ["activeTab", "tabs", "storage", "scripting"],
|
||||
"host_permissions": ["http://127.0.0.1/*", "http://localhost/*"]
|
||||
}
|
||||
|
||||
|
||||
@ -32,6 +32,205 @@ async function captureVisibleTab() {
|
||||
return await chrome.tabs.captureVisibleTab(null, { format: "png" });
|
||||
}
|
||||
|
||||
async function extractPageContent(tabId) {
|
||||
const [{ result }] = await chrome.scripting.executeScript({
|
||||
target: { tabId },
|
||||
func: () => {
|
||||
const SKIP_TAGS = new Set(["script", "style", "noscript", "template", "head", "meta", "link", "svg", "canvas"]);
|
||||
|
||||
const MAX_DEPTH = 14;
|
||||
const MAX_NODES = 1800;
|
||||
const MAX_TEXT_NODE_LEN = 500;
|
||||
|
||||
let nodeCount = 0;
|
||||
let truncated = false;
|
||||
|
||||
function cleanText(s) {
|
||||
return String(s || "")
|
||||
.replace(/\s+/g, " ")
|
||||
.trim();
|
||||
}
|
||||
|
||||
function rectIntersectsViewport(r) {
|
||||
const vw = window.innerWidth || document.documentElement.clientWidth || 0;
|
||||
const vh = window.innerHeight || document.documentElement.clientHeight || 0;
|
||||
return r.bottom > 0 && r.right > 0 && r.top < vh && r.left < vw;
|
||||
}
|
||||
|
||||
function isVisibleElement(el) {
|
||||
try {
|
||||
const cs = window.getComputedStyle(el);
|
||||
if (!cs) return false;
|
||||
if (cs.display === "none" || cs.visibility === "hidden") return false;
|
||||
const op = Number(cs.opacity || "1");
|
||||
if (!Number.isNaN(op) && op <= 0.02) return false;
|
||||
const r = el.getBoundingClientRect();
|
||||
if ((r.width || 0) < 1 || (r.height || 0) < 1) return false;
|
||||
if (!rectIntersectsViewport(r)) return false;
|
||||
return true;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function hasMeaningfulAttrs(el) {
|
||||
const role = (el.getAttribute("role") || "").trim();
|
||||
if (role) return true;
|
||||
const aria = (el.getAttribute("aria-label") || "").trim();
|
||||
if (aria) return true;
|
||||
const dt = (el.getAttribute("data-testid") || "").trim();
|
||||
if (dt) return true;
|
||||
const tag = el.tagName.toLowerCase();
|
||||
if (tag === "a" && (el.getAttribute("href") || el.href)) return true;
|
||||
if (tag === "button" || tag === "input" || tag === "textarea" || tag === "select") return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function directVisibleText(el) {
|
||||
// Only include immediate text nodes and form values. This avoids duplicating text up the tree.
|
||||
const parts = [];
|
||||
|
||||
for (const n of Array.from(el.childNodes || [])) {
|
||||
if (n.nodeType === Node.TEXT_NODE) {
|
||||
const t = cleanText(n.nodeValue || "");
|
||||
if (t) parts.push(t.length > MAX_TEXT_NODE_LEN ? t.slice(0, MAX_TEXT_NODE_LEN - 1) + "…" : t);
|
||||
}
|
||||
}
|
||||
|
||||
const tag = el.tagName.toLowerCase();
|
||||
if (tag === "input") {
|
||||
const type = (el.getAttribute("type") || "text").toLowerCase();
|
||||
if (!["hidden", "submit", "button"].includes(type)) {
|
||||
const v = cleanText(el.value || el.getAttribute("value") || el.getAttribute("placeholder") || "");
|
||||
if (v) parts.push(v);
|
||||
}
|
||||
} else if (tag === "textarea") {
|
||||
const v = cleanText(el.value || el.getAttribute("placeholder") || "");
|
||||
if (v) parts.push(v);
|
||||
}
|
||||
|
||||
return cleanText(parts.join(" "));
|
||||
}
|
||||
|
||||
function simplifyTag(tag) {
|
||||
// Keep some semantics; treat most wrapper tags as "div".
|
||||
if (["main", "article", "section", "ul", "ol", "li", "p"].includes(tag)) return tag;
|
||||
if (tag.match(/^h[1-6]$/)) return tag;
|
||||
if (["a", "button", "label"].includes(tag)) return tag;
|
||||
if (["header", "footer", "nav", "aside"].includes(tag)) return tag;
|
||||
return "div";
|
||||
}
|
||||
|
||||
function shouldSkip(el, tag) {
|
||||
if (SKIP_TAGS.has(tag)) return true;
|
||||
// Skip common overlay noise.
|
||||
const id = (el.id || "").toLowerCase();
|
||||
if (id.includes("cookie") || id.includes("consent")) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function collapseWrappers(node) {
|
||||
// Collapse div/span wrappers: div > div > div ... with a single child and no text/attrs.
|
||||
// We only collapse when the wrapper has exactly one child.
|
||||
while (
|
||||
node &&
|
||||
node.tag === "div" &&
|
||||
!node.text &&
|
||||
!node.attrs &&
|
||||
Array.isArray(node.children) &&
|
||||
node.children.length === 1 &&
|
||||
node.children[0] &&
|
||||
node.children[0].tag
|
||||
) {
|
||||
node = node.children[0];
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function maybeHoistInlineText(node) {
|
||||
// Common pattern: <a><span>Text</span></a> or <button><div><span>...</span></div></button>
|
||||
if (!node || node.text) return node;
|
||||
if (!["a", "button", "label", "p", "li"].includes(node.tag)) return node;
|
||||
if (!Array.isArray(node.children) || node.children.length !== 1) return node;
|
||||
const ch = node.children[0];
|
||||
if (ch && ch.text && (!ch.children || ch.children.length === 0) && (!ch.attrs || Object.keys(ch.attrs).length === 0)) {
|
||||
node.text = ch.text;
|
||||
delete node.children;
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
function build(el, depth) {
|
||||
if (truncated) return null;
|
||||
if (!el || depth > MAX_DEPTH) return null;
|
||||
if (!(el instanceof Element)) return null;
|
||||
|
||||
const rawTag = el.tagName.toLowerCase();
|
||||
if (shouldSkip(el, rawTag)) return null;
|
||||
if (!isVisibleElement(el)) return null;
|
||||
|
||||
nodeCount += 1;
|
||||
if (nodeCount > MAX_NODES) {
|
||||
truncated = true;
|
||||
return null;
|
||||
}
|
||||
|
||||
const tag = simplifyTag(rawTag);
|
||||
const text = directVisibleText(el);
|
||||
|
||||
const children = [];
|
||||
for (const ch of Array.from(el.children || [])) {
|
||||
const n = build(ch, depth + 1);
|
||||
if (n) children.push(n);
|
||||
if (truncated) break;
|
||||
}
|
||||
|
||||
if (!text && children.length === 0) return null;
|
||||
|
||||
const node = { tag };
|
||||
if (text) node.text = text;
|
||||
|
||||
// Only keep attrs when they help identify purpose/action.
|
||||
if (hasMeaningfulAttrs(el)) {
|
||||
const attrs = {};
|
||||
const role = (el.getAttribute("role") || "").trim();
|
||||
const aria = (el.getAttribute("aria-label") || "").trim();
|
||||
const dt = (el.getAttribute("data-testid") || "").trim();
|
||||
if (role) attrs.role = role;
|
||||
if (aria) attrs.aria_label = aria;
|
||||
if (dt) attrs.data_testid = dt;
|
||||
|
||||
if (rawTag === "a") {
|
||||
const href = (el.href || el.getAttribute("href") || "").trim();
|
||||
if (href) attrs.href = href;
|
||||
}
|
||||
|
||||
if (Object.keys(attrs).length) node.attrs = attrs;
|
||||
}
|
||||
|
||||
if (children.length) node.children = children;
|
||||
return maybeHoistInlineText(collapseWrappers(node));
|
||||
}
|
||||
|
||||
const extractedAt = new Date().toISOString();
|
||||
const url = String(location.href || "");
|
||||
const title = String(document.title || "");
|
||||
|
||||
const root = document.body ? build(document.body, 0) : null;
|
||||
return {
|
||||
extracted_at: extractedAt,
|
||||
url,
|
||||
title,
|
||||
hostname: location.hostname,
|
||||
visible_tree: root,
|
||||
truncated,
|
||||
stats: { nodes: nodeCount },
|
||||
};
|
||||
},
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
async function postScreenshot(endpoint, payload) {
|
||||
const r = await fetch(endpoint, {
|
||||
method: "POST",
|
||||
@ -80,12 +279,21 @@ async function main() {
|
||||
captureBtn.addEventListener("click", async () => {
|
||||
const endpoint = endpointEl.value.trim() || DEFAULT_ENDPOINT;
|
||||
captureBtn.disabled = true;
|
||||
setStatus("Capturing visible tab...", "");
|
||||
setStatus("Extracting page content...", "");
|
||||
|
||||
try {
|
||||
const tab = await getActiveTab();
|
||||
if (!tab) throw new Error("No active tab found");
|
||||
|
||||
let content = null;
|
||||
try {
|
||||
content = await extractPageContent(tab.id);
|
||||
} catch (e) {
|
||||
// Some URLs (chrome://*, Web Store, PDF viewer) cannot be scripted.
|
||||
content = { error: String(e && e.message ? e.message : e) };
|
||||
}
|
||||
|
||||
setStatus("Capturing visible tab...", "");
|
||||
const dataUrl = await captureVisibleTab();
|
||||
setStatus("Uploading to local server...", "");
|
||||
|
||||
@ -94,12 +302,14 @@ async function main() {
|
||||
title: tab.title || "",
|
||||
url: tab.url || "",
|
||||
ts: new Date().toISOString(),
|
||||
content,
|
||||
});
|
||||
|
||||
const lines = [];
|
||||
lines.push("Saved:");
|
||||
lines.push(` PNG: ${resp.png_path || "(unknown)"}`);
|
||||
lines.push(` META: ${resp.meta_path || "(unknown)"}`);
|
||||
if (resp.content_path) lines.push(` CONTENT: ${resp.content_path}`);
|
||||
if (resp.ran) {
|
||||
lines.push("Ran:");
|
||||
if (resp.ran.error) {
|
||||
|
||||
@ -78,6 +78,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
title = req.get("title") or ""
|
||||
page_url = req.get("url") or ""
|
||||
client_ts = req.get("ts") or ""
|
||||
content = req.get("content", None)
|
||||
|
||||
m = re.match(r"^data:image/png;base64,(.*)$", data_url)
|
||||
if not m:
|
||||
@ -98,9 +99,31 @@ class Handler(BaseHTTPRequestHandler):
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
png_path = out_dir / f"{base}.png"
|
||||
meta_path = out_dir / f"{base}.json"
|
||||
content_path = out_dir / f"{base}.content.json"
|
||||
|
||||
try:
|
||||
png_path.write_bytes(png_bytes)
|
||||
|
||||
# Save extracted page content separately to keep the meta file small/handy.
|
||||
wrote_content = False
|
||||
if content is not None:
|
||||
try:
|
||||
raw_content = json.dumps(content, ensure_ascii=True, indent=2) + "\n"
|
||||
# Prevent pathological payloads from creating huge files.
|
||||
if len(raw_content.encode("utf-8")) > 2_000_000:
|
||||
content = {
|
||||
"error": "content_too_large_truncated",
|
||||
"note": "Original extracted content exceeded 2MB.",
|
||||
}
|
||||
raw_content = json.dumps(content, ensure_ascii=True, indent=2) + "\n"
|
||||
content_path.write_text(raw_content, encoding="utf-8")
|
||||
wrote_content = True
|
||||
except Exception:
|
||||
# Don't fail the whole request if content writing fails.
|
||||
wrote_content = False
|
||||
|
||||
final_content_path = str(content_path) if wrote_content else None
|
||||
|
||||
meta_path.write_text(
|
||||
json.dumps(
|
||||
{
|
||||
@ -109,6 +132,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
"client_ts": client_ts,
|
||||
"saved_utc": now.isoformat(),
|
||||
"png_path": str(png_path),
|
||||
"content_path": final_content_path,
|
||||
},
|
||||
indent=2,
|
||||
ensure_ascii=True,
|
||||
@ -146,6 +170,7 @@ class Handler(BaseHTTPRequestHandler):
|
||||
"ok": True,
|
||||
"png_path": str(png_path),
|
||||
"meta_path": str(meta_path),
|
||||
"content_path": final_content_path,
|
||||
"ran": ran,
|
||||
},
|
||||
)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user