Proposal Builder
Sales-proposal and statement-of-work assembly pack for agencies, consultants, and B2B sales: build a structured proposal object from scope, pricing, and terms; generate a scope-of-work (SOW) section...
proposal-builder
Sales-proposal & statement-of-work (SOW) assembly adapter pack for agencies, consultants, and B2B sellers. Turns { scope, pricing, terms } into a structured proposal object and a clean, print-ready HTML document.
Intelligent microservice: every tool has a deterministic template core that runs fully offline. executiveSummary and sowSection additionally try an optional LLM for richer prose and silently fall back to the template when no model is reachable (mode: 'heuristic' | 'llm').
Tools
| Tool | In → Out |
|---|---|
build | { scope, pricing, terms, client, vendor } → complete proposal object (summary + SOW + pricing + terms) |
sowSection | { scope } → scope-of-work narrative + deliverables + assumptions (+ optional LLM narrative) |
pricingTable | { pricing } → line items with subtotal, discount, tax, total + currency-formatted strings |
toHtml | { proposal } (output of build) → print-ready standalone HTML document string |
executiveSummary | { brief, scope } → persuasive opening paragraph (+ optional LLM prose) |
timeline | { phases } → phased schedule with week ranges, dates, and milestones |
Usage
import pack from './index.js';
const built = pack.adapters.build({
scope: { title: 'Website Redesign', deliverables: ['Design', 'Build', 'Launch'], objectives: ['Increase conversion'] },
pricing: { currency: 'USD', items: [{ name: 'Design', qty: 1, rate: 8000 }, { name: 'Build', qty: 1, rate: 12000 }], discount: 0.1, taxRate: 8 },
terms: { paymentSchedule: '50% upfront, 50% on delivery', validUntil: '2026-08-01' },
client: 'Acme Co', vendor: 'Studio X',
});
// built.proposal → { title, executiveSummary, sow, pricing:{ subtotal, discount, tax, total }, terms, ... }
const { html } = pack.adapters.toHtml({ proposal: built }); // standalone HTML string
pack.adapters.pricingTable({ pricing: { items: [{ name: 'Retainer', qty: 3, rate: 2000 }] } });
// → { subtotal: 6000, total: 6000, formatted: { total: '$6,000.00', ... } }
pack.adapters.timeline({ phases: ['Discovery', 'Build', 'Launch'], options: { weeksPerPhase: 2, startDate: '2026-02-01' } });
// → { totalWeeks: 6, phases: [...], milestones: [...] }
Pricing conventions
discount: a value< 1is a fraction (0.1= 10%);>= 1is an absolute amount.taxRate: accepts8or0.08(both = 8%).qtydefaults to1,unitto"each".
DRY boundaries
- Pre-sale proposal / SOW assembly only.
invoiceowns post-sale billing (invoice numbers,
due dates, receipts) — the pricing block here is an estimate inside a proposal, not a payable invoice.
- Money math is inlined; no cross-pack imports except
../_shared/llm.js. Pure ESM, Node built-ins,
zero npm deps.