giorgigrdzelidze/laravel-stringer
A Laravel package for fluent, chainable string manipulation, offering convenient helpers to transform, format, and inspect strings. Simplifies common text tasks in your apps with a clean, expressive API.
Build vs. buy for the content pipeline. This release turns "should we assemble our own AI drafting stack?" into a scoped decision. The package now covers the full loop — topic queue → LLM draft → per-locale translation → SEO/social metadata → cover image → operator notification → publish handoff — behind contracts (ImageGenerator, PromptBuilder, ContentTarget::attachCover). The real question stops being "can we build it?" and becomes "do we want to own the prompts, API keys, and cost curve?"
Roadmap sequencing for content/localization bets. The 5 → 12 seeded content field expansion (slug, og_*, twitter_*) makes channel coverage a config decision rather than an engineering project. PMs can now sequence: launch EN long-form → add KA/RU locales → layer social distribution, without a rebuild between each phase.
Distribution strategy, made explicit. Distinct LLM-authored copy per channel (search-keyword-first meta, curiosity-baiting OG, timeline-punchy Twitter) is a product stance: we treat each surface as its own audience, not as a truncation of the same string. That is a decision worth stating in the PRD, because it changes the editorial bar and the QA checklist.
Localization quality bar. Explicit per-locale slugs (semantic translation for EN, Latin transliteration for KA/RU) signal that i18n is treated as first-class SEO, not a fallback. Decide whether that matches your market entry plan before promising locale coverage.
Cost governance and abuse limits. STRINGER_IMAGE_MAX_REGENERATES=3 and the six-driver abstraction give PMs a real cost lever: Picsum for smoke tests, Unsplash for free real photography (with attribution obligations), Gemini-image free tier for early volume, DALL-E/FLUX/Imagen for production quality. Driver choice becomes a per-stage product decision with a known price and quality trade-off, not an engineering default.
Brand and visual consistency. The art-director prompt template (scene-picking rules, composition constraints, tone calibration matrix, hard exclusions like no-text/no-logos/no-cliché-imagery) plus DB-editable prompts in Filament means brand voice and visual style are operator-tunable without a deploy. That is a meaningful reduction in release coupling for content experiments.
Operational model and headcount assumptions. The Telegram photo-card pipeline and "every error surfaces in chat" humanizer materially change the ops story: a non-engineer can monitor drafts and diagnose failures from a phone. If your plan assumed an ops hire to babysit the queue, this release weakens that assumption — validate it, don't assume it.
Reliability as a product promise. The JSON repair pipeline, the retry-guard fix (previously silent-skip retries meant failed() never fired and no notification was sent), and pinned maxOutputTokens remove a class of silent failures. Silent failure is the worst outcome for a content pipeline, because the team trusts a queue that has quietly stopped producing.
Adoption safety for existing installs. No new tables, idempotent by-name/by-key seeders, and prompt resources made read-only-with-edit (duplicate rows could silently win a LIMIT 1 lookup). Upgrades are low-risk, which lowers the cost of the "should we try this?" decision.
Consider it when most of the following hold:
--limit let you stage rollout. If you can't attribute spend to article/locale/driver, don't turn on all six drivers at once.localhost — the package handles these, but they exist and will resurface with new providers.Look elsewhere or wait when:
custom_properties on the image DTO gives you.attachCover() deliberately never imports one — hosts must route bytes. If you don't have Spatie Media Library or S3 plumbing, that's real integration work you'll fund.Also note: package-shipped Blade views don't inherit host Tailwind classes (their build doesn't scan vendor/). Cosmetic, but it signals that UI polish inside the package's admin screens is partly your responsibility.
One-liner. Stringer is a Laravel package that turns a topic queue into reviewed, multi-locale, SEO-and-social-ready articles with cover images — and tells the team in Telegram when a draft is ready or something broke.
For executives. It compresses the cost and cycle time of programmatic content without locking us into a SaaS vendor. We own the prompts, the keys, and the data; the output lands in our existing admin (Filament) and our existing notification surface (Telegram), so there is no new tool for the team to learn. The v0.3.0 release adds the pieces that make it operationally credible rather than a demo: automatic cover imagery with a per-driver cost dial, per-channel SEO and social copy, per-locale slugs, and a notification pipeline where every failure reaches a human in chat. Cost exposure is capped by design (limited regenerate taps, backfill limits) and upgrades are non-disruptive — no new tables, idempotent seeding. The decision we're being asked to make is small and reversible: pilot on one locale and a bounded article count, measure cost-per-published-article and review time, then decide on expansion.
For engineering. It's a self-contained package with clean seams: ImageGenerator for drivers, PromptBuilder for prompt construction, ContentTarget::attachCover() as the host hook so we never inherit a media library. Jobs chain (GenerateDraftJob → GenerateCoverImageJob), errors route through a shared humanizer that unwraps Laravel HTTP exception bodies (including Guzzle's truncation marker), and the LLM parser has a real repair pipeline for production malformations, covered by regression tests. Quality signals are concrete: 175 tests / 470 assertions, PHPStan level 6, Pint clean. Schema impact is zero; seeders upsert by name so our operator edits survive. Known friction to budget for: no Tailwind inheritance in package views, host-owned cover storage, and API-key/cost plumbing.
Objections to pre-empt. "Is this just a ChatGPT wrapper?" — No: the value is the pipeline, the guardrails, and the operator surface around the model, and the model is swappable. "What if output quality disappoints?" — Prompts are DB-editable in Filament, so tuning is an operator action, not a release. "What if it breaks silently?" — That's the specific failure mode this release targets; retries now actually retry and failures now actually notify. "What's the lock-in?" — Contracts and host hooks, plus zero schema footprint.
Ask. Approve a bounded pilot: one locale, one image driver, a fixed article count, and a named editorial reviewer. Success criteria: review time per draft, cost per published article, and zero silent pipeline failures over the pilot window.
How can I help you explore Laravel packages today?