@weactive8/8contentpro 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +33 -0
  2. package/dist/agent.js +115 -0
  3. package/dist/agent.js.map +1 -0
  4. package/dist/attach.js +144 -0
  5. package/dist/attach.js.map +1 -0
  6. package/dist/auth.js +49 -0
  7. package/dist/auth.js.map +1 -0
  8. package/dist/brand.js +110 -0
  9. package/dist/brand.js.map +1 -0
  10. package/dist/brandgen.js +76 -0
  11. package/dist/brandgen.js.map +1 -0
  12. package/dist/build-info.js +3 -0
  13. package/dist/build-info.js.map +1 -0
  14. package/dist/detect.js +163 -0
  15. package/dist/detect.js.map +1 -0
  16. package/dist/index.js +334 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/ink/App.js +733 -0
  19. package/dist/ink/App.js.map +1 -0
  20. package/dist/ink/components.js +214 -0
  21. package/dist/ink/components.js.map +1 -0
  22. package/dist/ink/run.js +9 -0
  23. package/dist/ink/run.js.map +1 -0
  24. package/dist/intel.js +110 -0
  25. package/dist/intel.js.map +1 -0
  26. package/dist/login.js +99 -0
  27. package/dist/login.js.map +1 -0
  28. package/dist/metering.js +53 -0
  29. package/dist/metering.js.map +1 -0
  30. package/dist/methodology/loader.js +68 -0
  31. package/dist/methodology/loader.js.map +1 -0
  32. package/dist/models.js +24 -0
  33. package/dist/models.js.map +1 -0
  34. package/dist/onboarding/onboard.js +102 -0
  35. package/dist/onboarding/onboard.js.map +1 -0
  36. package/dist/onboarding/schema.js +25 -0
  37. package/dist/onboarding/schema.js.map +1 -0
  38. package/dist/onboarding/setup.js +324 -0
  39. package/dist/onboarding/setup.js.map +1 -0
  40. package/dist/output/callouts.js +81 -0
  41. package/dist/output/callouts.js.map +1 -0
  42. package/dist/output/docx.js +155 -0
  43. package/dist/output/docx.js.map +1 -0
  44. package/dist/output/pdf.js +195 -0
  45. package/dist/output/pdf.js.map +1 -0
  46. package/dist/pipeline.js +140 -0
  47. package/dist/pipeline.js.map +1 -0
  48. package/dist/plan/targeting.js +165 -0
  49. package/dist/plan/targeting.js.map +1 -0
  50. package/dist/shell.js +286 -0
  51. package/dist/shell.js.map +1 -0
  52. package/dist/site/resources.js +88 -0
  53. package/dist/site/resources.js.map +1 -0
  54. package/dist/site/sitemap.js +92 -0
  55. package/dist/site/sitemap.js.map +1 -0
  56. package/dist/store.js +110 -0
  57. package/dist/store.js.map +1 -0
  58. package/dist/topics.js +50 -0
  59. package/dist/topics.js.map +1 -0
  60. package/dist/ui/spinner.js +111 -0
  61. package/dist/ui/spinner.js.map +1 -0
  62. package/dist/ui/statusbar.js +90 -0
  63. package/dist/ui/statusbar.js.map +1 -0
  64. package/dist/update.js +45 -0
  65. package/dist/update.js.map +1 -0
  66. package/package.json +47 -0
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Callout devices — the visual half of the product. The model emits markdown-native
3
+ * admonitions (`> [!TIP] ...`, `> [!STAT] ...`, `> [!LEADMAGNET] ...`) and BOTH the
4
+ * .docx and .pdf renderers paint them as styled boxes (shaded fill, colored left bar,
5
+ * a label). This is what makes the output land like a designed content asset instead
6
+ * of a text dump. Same syntax, two renderers, one source of truth here.
7
+ */
8
+ export const CALLOUTS = {
9
+ TIP: { label: "Tip", accent: "1A7F4B", bg: "E8F5EE" },
10
+ NOTE: { label: "Note", accent: "1F5FA8", bg: "E9F0FA" },
11
+ STAT: { label: "By the numbers", accent: "7A3FD1", bg: "F1EAFB" },
12
+ QUOTE: { label: "", accent: "6B7280", bg: "F3F4F6", italic: true },
13
+ WARNING: { label: "Watch out", accent: "B45309", bg: "FCF1E2" },
14
+ CTA: { label: "Next step", accent: "0D9488", bg: "E4F5F2" },
15
+ LEADMAGNET: { label: "Free download", accent: "0B6E8A", bg: "E4F1F5" },
16
+ };
17
+ /** The list the model is told to use, for the operating prompt. */
18
+ export const CALLOUT_TYPES = Object.keys(CALLOUTS);
19
+ /**
20
+ * Detect a `[!TYPE] ...` admonition inside a blockquote's raw text. The type is the
21
+ * only label; ALL text after it (tag line + following lines) is the body, kept in
22
+ * normal case. Returns null for a plain blockquote (rendered normally).
23
+ */
24
+ export function parseCallout(raw) {
25
+ const lines = raw.replace(/\r/g, "").split("\n");
26
+ const first = (lines[0] || "").replace(/^>\s?/, "").trim();
27
+ const m = first.match(/^\[!(\w+)\]\s*(.*)$/);
28
+ if (!m)
29
+ return null;
30
+ const type = m[1].toUpperCase();
31
+ const style = CALLOUTS[type] || CALLOUTS.NOTE;
32
+ const rest = lines
33
+ .slice(1)
34
+ .map((l) => l.replace(/^>\s?/, ""))
35
+ .join("\n");
36
+ const body = [m[2], rest].filter((s) => s && s.trim()).join("\n").trim();
37
+ return { type, style, body };
38
+ }
39
+ /**
40
+ * Split a LEADMAGNET / CTA callout body into its three parts so the renderers can paint
41
+ * a real offer: a bold headline, a one-line pitch, and a DISTINCT button. The button is
42
+ * the last line when it's arrow-marked (`→ Get the guide`); its arrow/marker is stripped.
43
+ * Falls back gracefully when the model didn't mark a CTA.
44
+ */
45
+ export function splitOffer(body) {
46
+ const lines = body
47
+ .split("\n")
48
+ .map((l) => l.trim())
49
+ .filter(Boolean);
50
+ let cta;
51
+ const last = lines[lines.length - 1];
52
+ if (last && /^(?:→|»|>>|→)\s*/.test(last)) {
53
+ cta = last.replace(/^(?:→|»|>>|→)\s*/, "").trim();
54
+ lines.pop();
55
+ }
56
+ const headline = lines.shift() ?? "";
57
+ return { headline, description: lines.join(" "), cta };
58
+ }
59
+ /**
60
+ * Convert any HTML/XML link tag the model emits into a proper markdown link, so links
61
+ * ALWAYS render as real hyperlinks — never as raw `<ExternalLink …>` / `<a …>` text.
62
+ * The model occasionally invents `<ExternalLink href="url">text</ExternalLink>` (the docx
63
+ * library's class name) or `<a href>` instead of `[text](url)`; this makes the renderers
64
+ * bulletproof regardless.
65
+ */
66
+ export function normalizeLinks(md) {
67
+ return md
68
+ .replace(/<(?:ExternalLink|a)\b[^>]*\bhref\s*=\s*["']([^"']+)["'][^>]*>([\s\S]*?)<\/(?:ExternalLink|a)>/gi, (_m, url, text) => `[${text.replace(/<[^>]+>/g, "").replace(/\s+/g, " ").trim()}](${url.trim()})`)
69
+ .replace(/<\/?(?:ExternalLink|a)\b[^>]*>/gi, ""); // drop any stray/empty link tags
70
+ }
71
+ /** marked HTML-escapes text tokens (' → &#39; etc.); undo it for Word/PDF output. */
72
+ export function decodeEntities(s) {
73
+ return s
74
+ .replace(/&#(\d+);/g, (_, n) => String.fromCharCode(Number(n)))
75
+ .replace(/&#x([0-9a-f]+);/gi, (_, h) => String.fromCharCode(parseInt(h, 16)))
76
+ .replace(/&quot;/g, '"')
77
+ .replace(/&lt;/g, "<")
78
+ .replace(/&gt;/g, ">")
79
+ .replace(/&amp;/g, "&");
80
+ }
81
+ //# sourceMappingURL=callouts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"callouts.js","sourceRoot":"","sources":["../../src/output/callouts.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { marked } from "marked";
3
+ import { Document, Packer, Paragraph, TextRun, ExternalHyperlink, HeadingLevel, ShadingType, BorderStyle, UnderlineType, } from "docx";
4
+ import { parseCallout, decodeEntities, splitOffer, normalizeLinks } from "./callouts.js";
5
+ /**
6
+ * Convert the Blog Protocol's Markdown draft into a reviewable Word document.
7
+ * This is the client deliverable: the piece lands as a .docx they open, read,
8
+ * and mark up, then come back to the CLI to revise. Pure-JS (docx + marked) so
9
+ * the CLI stays cross-platform with no native deps.
10
+ */
11
+ const HEADING = [
12
+ HeadingLevel.HEADING_1,
13
+ HeadingLevel.HEADING_2,
14
+ HeadingLevel.HEADING_3,
15
+ HeadingLevel.HEADING_4,
16
+ HeadingLevel.HEADING_5,
17
+ HeadingLevel.HEADING_6,
18
+ ];
19
+ /** Map inline Markdown tokens to docx runs (bold / italic / code / links). */
20
+ function inlineRuns(tokens, base = {}) {
21
+ if (!tokens)
22
+ return [];
23
+ const out = [];
24
+ for (const t of tokens) {
25
+ switch (t.type) {
26
+ case "strong":
27
+ out.push(...inlineRuns(t.tokens, { ...base, bold: true }));
28
+ break;
29
+ case "em":
30
+ out.push(...inlineRuns(t.tokens, { ...base, italics: true }));
31
+ break;
32
+ case "codespan":
33
+ out.push(new TextRun({ text: decodeEntities(t.text), font: "Courier New", ...base }));
34
+ break;
35
+ case "link": {
36
+ const link = t;
37
+ // Style like a real Word hyperlink: blue + underline (else it looks like plain text).
38
+ out.push(new ExternalHyperlink({
39
+ link: link.href,
40
+ children: [new TextRun({ text: decodeEntities(link.text), color: "0563C1", underline: { type: UnderlineType.SINGLE }, ...base })],
41
+ }));
42
+ break;
43
+ }
44
+ case "br":
45
+ out.push(new TextRun({ break: 1 }));
46
+ break;
47
+ default:
48
+ out.push(new TextRun({ text: decodeEntities(t.text ?? ""), ...base }));
49
+ }
50
+ }
51
+ return out;
52
+ }
53
+ function listItems(list) {
54
+ return list.items.map((item, i) => {
55
+ const runs = inlineRuns(item.tokens?.[0]?.tokens ?? [{ type: "text", raw: item.text, text: item.text }]);
56
+ return new Paragraph({
57
+ children: list.ordered ? [new TextRun({ text: `${(Number(list.start) || 1) + i}. ` }), ...runs] : runs,
58
+ bullet: list.ordered ? undefined : { level: 0 },
59
+ spacing: { after: 80 },
60
+ });
61
+ });
62
+ }
63
+ /** Lex a single line/string to its inline markdown tokens (links, bold, etc.). */
64
+ function inlineTokens(s) {
65
+ return marked.lexer(s || "")[0]?.tokens ?? [{ type: "text", text: s }];
66
+ }
67
+ /** The CTA button: an arrow + the label, rendered as a clickable link when the label is a
68
+ * markdown link (styled in the accent color, bold — a button, not a blue body link). */
69
+ function ctaButtonRuns(cta, accent) {
70
+ const arrow = new TextRun({ text: "→ ", bold: true, color: accent, size: 22 });
71
+ const link = inlineTokens(cta).find((t) => t.type === "link");
72
+ if (link) {
73
+ return [arrow, new ExternalHyperlink({ link: link.href, children: [new TextRun({ text: decodeEntities(link.text), bold: true, color: accent, size: 22, underline: { type: UnderlineType.SINGLE } })] })];
74
+ }
75
+ return [new TextRun({ text: `→ ${decodeEntities(cta.replace(/^\s*/, ""))}`, bold: true, color: accent, size: 22 })];
76
+ }
77
+ /** A styled callout box: shaded fill + colored left bar + a label, then the body. */
78
+ function calloutParagraphs(c) {
79
+ const shading = { type: ShadingType.CLEAR, fill: c.style.bg, color: "auto" };
80
+ const border = { left: { style: BorderStyle.SINGLE, size: 24, color: c.style.accent, space: 12 } };
81
+ const para = [];
82
+ if (c.style.label) {
83
+ para.push(new TextRun({ text: c.style.label.toUpperCase(), bold: true, color: c.style.accent, size: 16 }), new TextRun({ break: 1 }));
84
+ }
85
+ // Offer callouts (lead-magnet / CTA) render as a structured offer: bold headline,
86
+ // one-line pitch, then a DISTINCT accent button on its own line. The button IS the
87
+ // clickable link (the reader clicks the button, not the title).
88
+ if (c.type === "LEADMAGNET" || c.type === "CTA") {
89
+ const { headline, description, cta } = splitOffer(c.body);
90
+ if (headline)
91
+ para.push(...inlineRuns(inlineTokens(headline), { bold: true }));
92
+ if (description) {
93
+ para.push(new TextRun({ break: 1 }));
94
+ para.push(...inlineRuns(inlineTokens(description)));
95
+ }
96
+ if (cta) {
97
+ para.push(new TextRun({ break: 1 }), ...ctaButtonRuns(cta, c.style.accent));
98
+ }
99
+ return [new Paragraph({ children: para, shading, border, spacing: { before: 120, after: 160 }, indent: { left: 120, right: 120 } })];
100
+ }
101
+ para.push(...inlineRuns(inlineTokens(c.body), { italics: c.style.italic }));
102
+ return [new Paragraph({ children: para, shading, border, spacing: { before: 120, after: 160 }, indent: { left: 120, right: 120 } })];
103
+ }
104
+ function blocksFor(tokens) {
105
+ const paras = [];
106
+ for (const t of tokens) {
107
+ switch (t.type) {
108
+ case "heading": {
109
+ const h = t;
110
+ paras.push(new Paragraph({ heading: HEADING[h.depth - 1], children: inlineRuns(h.tokens), spacing: { before: 240, after: 120 } }));
111
+ break;
112
+ }
113
+ case "paragraph":
114
+ paras.push(new Paragraph({ children: inlineRuns(t.tokens), spacing: { after: 160 } }));
115
+ break;
116
+ case "list":
117
+ paras.push(...listItems(t));
118
+ break;
119
+ case "blockquote": {
120
+ const callout = parseCallout(t.text ?? "");
121
+ if (callout) {
122
+ paras.push(...calloutParagraphs(callout));
123
+ break;
124
+ }
125
+ paras.push(new Paragraph({ children: inlineRuns(t.tokens?.flatMap((b) => b.tokens ?? [])), indent: { left: 480 }, spacing: { after: 160 } }));
126
+ break;
127
+ }
128
+ case "code":
129
+ paras.push(new Paragraph({ children: [new TextRun({ text: t.text, font: "Courier New" })], spacing: { after: 160 } }));
130
+ break;
131
+ case "hr":
132
+ paras.push(new Paragraph({ thematicBreak: true }));
133
+ break;
134
+ case "space":
135
+ break;
136
+ default:
137
+ if (t.text)
138
+ paras.push(new Paragraph({ children: inlineRuns(t.tokens ?? []) }));
139
+ }
140
+ }
141
+ return paras;
142
+ }
143
+ export async function markdownToDocx(md) {
144
+ const tokens = marked.lexer(normalizeLinks(md));
145
+ const doc = new Document({
146
+ styles: { default: { document: { run: { font: "Calibri", size: 22 } } } },
147
+ sections: [{ children: blocksFor(tokens) }],
148
+ });
149
+ return Packer.toBuffer(doc);
150
+ }
151
+ /** Render Markdown to a .docx at the given path. */
152
+ export async function writeDocx(md, path) {
153
+ writeFileSync(path, await markdownToDocx(md));
154
+ }
155
+ //# sourceMappingURL=docx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"docx.js","sourceRoot":"","sources":["../../src/output/docx.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,195 @@
1
+ import { createWriteStream } from "node:fs";
2
+ import PDFDocument from "pdfkit";
3
+ import { marked } from "marked";
4
+ import { parseCallout, decodeEntities, splitOffer, normalizeLinks } from "./callouts.js";
5
+ /**
6
+ * Render a Markdown resource guide / ebook into a polished, downloadable PDF —
7
+ * the gated-asset deliverable. Pure-JS (pdfkit + marked), no chromium, so it
8
+ * ships inside a cross-platform CLI. No model calls: formatting is free.
9
+ *
10
+ * Blog posts go to .docx (reviewable/editable); gated guides go to PDF
11
+ * (downloadable, branded, what a lead actually receives).
12
+ */
13
+ const REG = "Helvetica";
14
+ const BOLD = "Helvetica-Bold";
15
+ const ITAL = "Helvetica-Oblique";
16
+ function inlineText(tokens) {
17
+ if (!tokens)
18
+ return [];
19
+ const runs = [];
20
+ for (const t of tokens) {
21
+ if (t.type === "strong")
22
+ runs.push(...inlineText(t.tokens).map((r) => ({ ...r, bold: true })));
23
+ else if (t.type === "em")
24
+ runs.push(...inlineText(t.tokens).map((r) => ({ ...r, italic: true })));
25
+ else if (t.type === "link")
26
+ runs.push(...inlineText(t.tokens));
27
+ else if (t.type === "codespan")
28
+ runs.push({ text: decodeEntities(t.text) });
29
+ else
30
+ runs.push({ text: decodeEntities(t.text ?? "") });
31
+ }
32
+ return runs;
33
+ }
34
+ function writeRuns(doc, runs, size = 11) {
35
+ runs.forEach((r, i) => {
36
+ doc
37
+ .font(r.bold ? BOLD : r.italic ? ITAL : REG)
38
+ .fontSize(size)
39
+ .fillColor("#1a1a1a")
40
+ .text(r.text, { continued: i < runs.length - 1 });
41
+ });
42
+ if (runs.length === 0)
43
+ doc.text("");
44
+ }
45
+ /** Flatten a markdown line to plain display text (link text kept, syntax dropped). */
46
+ function plainInline(s) {
47
+ const toks = marked.lexer(s || "")[0]?.tokens ?? [{ type: "text", text: s }];
48
+ return inlineText(toks)
49
+ .map((r) => r.text)
50
+ .join("");
51
+ }
52
+ /** Pull the link out of a CTA label (`[Get the guide](url)`), for a clickable PDF button. */
53
+ function ctaLink(s) {
54
+ const toks = marked.lexer(s || "")[0]?.tokens ?? [];
55
+ const link = toks.find((t) => t.type === "link");
56
+ return link ? { label: plainInline(s), href: link.href } : { label: plainInline(s) };
57
+ }
58
+ /** Draw a styled callout box: shaded rounded rect + colored left bar + label + body.
59
+ * Offer callouts (lead-magnet / CTA) render structured: bold headline, one-line pitch,
60
+ * and a distinct accent CTA button. */
61
+ function drawCallout(doc, c) {
62
+ const left = doc.page.margins.left;
63
+ const boxW = doc.page.width - left - doc.page.margins.right;
64
+ const padX = 12;
65
+ const padY = 10;
66
+ const barW = 4;
67
+ const textX = left + barW + padX;
68
+ const textW = boxW - barW - padX * 2;
69
+ const labelText = c.style.label.toUpperCase();
70
+ const hasLabel = Boolean(c.style.label);
71
+ const labelH = hasLabel ? doc.font(BOLD).fontSize(9).heightOfString(labelText, { width: textW }) : 0;
72
+ const isOffer = c.type === "LEADMAGNET" || c.type === "CTA";
73
+ let boxH;
74
+ let offer = null;
75
+ const H = (font, size, s) => (s ? doc.font(font).fontSize(size).heightOfString(s, { width: textW }) : 0);
76
+ if (isOffer) {
77
+ const o = splitOffer(c.body);
78
+ const cta = o.cta ? ctaLink(o.cta) : null;
79
+ offer = { headline: plainInline(o.headline), description: plainInline(o.description), cta: cta ? `→ ${cta.label}` : undefined, ctaHref: cta?.href };
80
+ const hH = H(BOLD, 13, offer.headline);
81
+ const dH = H(REG, 11, offer.description);
82
+ const cH = offer.cta ? H(BOLD, 12, offer.cta) + 10 : 0; // + pill padding
83
+ boxH = padY * 2 + labelH + (labelH ? 6 : 0) + hH + (hH && dH ? 4 : 0) + dH + (cH ? 10 + cH : 0);
84
+ }
85
+ else {
86
+ const body = decodeEntities(c.body);
87
+ const bodyH = H(c.style.italic ? ITAL : REG, 11, body);
88
+ boxH = padY * 2 + labelH + (labelH && bodyH ? 4 : 0) + bodyH;
89
+ }
90
+ doc.moveDown(0.4);
91
+ if (doc.y + boxH > doc.page.height - doc.page.margins.bottom)
92
+ doc.addPage();
93
+ const top = doc.y;
94
+ doc.save();
95
+ doc.roundedRect(left, top, boxW, boxH, 4).fill(`#${c.style.bg}`);
96
+ doc.rect(left, top, barW, boxH).fill(`#${c.style.accent}`);
97
+ doc.restore();
98
+ let y = top + padY;
99
+ if (hasLabel) {
100
+ doc.font(BOLD).fontSize(9).fillColor(`#${c.style.accent}`).text(labelText, textX, y, { width: textW });
101
+ y = doc.y + 6;
102
+ }
103
+ if (isOffer && offer) {
104
+ if (offer.headline) {
105
+ doc.font(BOLD).fontSize(13).fillColor("#111").text(offer.headline, textX, y, { width: textW });
106
+ y = doc.y + 4;
107
+ }
108
+ if (offer.description) {
109
+ doc.font(REG).fontSize(11).fillColor("#1a1a1a").text(offer.description, textX, y, { width: textW });
110
+ y = doc.y + 10;
111
+ }
112
+ if (offer.cta) {
113
+ doc.font(BOLD).fontSize(12).fillColor(`#${c.style.accent}`).text(offer.cta, textX, y, { width: textW, link: offer.ctaHref, underline: Boolean(offer.ctaHref) });
114
+ }
115
+ }
116
+ else {
117
+ doc.font(c.style.italic ? ITAL : REG).fontSize(11).fillColor("#1a1a1a").text(decodeEntities(c.body), textX, y, { width: textW });
118
+ }
119
+ doc.x = left;
120
+ doc.y = top + boxH;
121
+ doc.moveDown(0.5);
122
+ }
123
+ /** Render Markdown to a PDF Buffer. `title`/`subtitle` produce a simple cover. */
124
+ export function markdownToPdf(md, opts = {}) {
125
+ return new Promise((resolve) => {
126
+ const doc = new PDFDocument({ size: "A4", margins: { top: 64, bottom: 64, left: 64, right: 64 } });
127
+ const chunks = [];
128
+ doc.on("data", (c) => chunks.push(c));
129
+ doc.on("end", () => resolve(Buffer.concat(chunks)));
130
+ if (opts.title) {
131
+ doc.moveDown(6);
132
+ doc.font(BOLD).fontSize(30).fillColor("#111").text(opts.title, { align: "left" });
133
+ if (opts.subtitle)
134
+ doc.moveDown(0.5).font(REG).fontSize(14).fillColor("#555").text(opts.subtitle);
135
+ doc.addPage();
136
+ }
137
+ for (const t of marked.lexer(normalizeLinks(md))) {
138
+ switch (t.type) {
139
+ case "heading": {
140
+ const h = t;
141
+ const size = h.depth === 1 ? 22 : h.depth === 2 ? 16 : 13;
142
+ doc.moveDown(0.8).font(BOLD).fontSize(size).fillColor("#111");
143
+ writeRuns(doc, inlineText(h.tokens), size);
144
+ doc.moveDown(0.3);
145
+ break;
146
+ }
147
+ case "paragraph":
148
+ doc.moveDown(0.4);
149
+ writeRuns(doc, inlineText(t.tokens));
150
+ break;
151
+ case "list":
152
+ doc.moveDown(0.3);
153
+ t.items.forEach((it, i) => {
154
+ const marker = t.ordered ? `${(Number(t.start) || 1) + i}. ` : "• ";
155
+ doc.font(REG).fontSize(11).fillColor("#1a1a1a").text(marker, { continued: true });
156
+ writeRuns(doc, inlineText(it.tokens?.[0]?.tokens ?? [{ type: "text", text: it.text }]));
157
+ });
158
+ break;
159
+ case "blockquote": {
160
+ const callout = parseCallout(t.text ?? "");
161
+ if (callout) {
162
+ drawCallout(doc, callout);
163
+ break;
164
+ }
165
+ doc.moveDown(0.4).font(ITAL).fontSize(11).fillColor("#444");
166
+ doc.text(decodeEntities(t.text), { indent: 20 });
167
+ break;
168
+ }
169
+ case "hr":
170
+ doc.moveDown(0.5).strokeColor("#ddd").moveTo(64, doc.y).lineTo(531, doc.y).stroke();
171
+ break;
172
+ case "space":
173
+ break;
174
+ default:
175
+ if (t.text)
176
+ doc.moveDown(0.3).font(REG).fontSize(11).fillColor("#1a1a1a").text(decodeEntities(t.text));
177
+ }
178
+ }
179
+ doc.end();
180
+ });
181
+ }
182
+ /** Write a Markdown guide to a .pdf at `path`. */
183
+ export function writePdf(md, path, opts = {}) {
184
+ return new Promise((resolve, reject) => {
185
+ markdownToPdf(md, opts)
186
+ .then((buf) => {
187
+ const ws = createWriteStream(path);
188
+ ws.on("finish", () => resolve());
189
+ ws.on("error", reject);
190
+ ws.end(buf);
191
+ })
192
+ .catch(reject);
193
+ });
194
+ }
195
+ //# sourceMappingURL=pdf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf.js","sourceRoot":"","sources":["../../src/output/pdf.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,140 @@
1
+ import { writeFileSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { run, revise } from "./agent.js";
4
+ import { detectAI, formatReport, detectSapling, formatExternalReport } from "./detect.js";
5
+ import { writeDocx } from "./output/docx.js";
6
+ import { writePdf } from "./output/pdf.js";
7
+ import { normalizeLinks } from "./output/callouts.js";
8
+ import { reportUsage } from "./store.js";
9
+ /** Shared generation pipeline used by both the CLI commands and the guided shell. */
10
+ export function stripPreamble(md) {
11
+ const i = md.search(/^#\s+/m);
12
+ return i > 0 ? md.slice(i) : md;
13
+ }
14
+ export function titleOf(md) {
15
+ return md.match(/^#\s+(.+)$/m)?.[1]?.replace(/[*_`]/g, "").trim();
16
+ }
17
+ const usd = (n) => "$" + n.toFixed(4);
18
+ /** Readable per-piece cost breakdown (API-equivalent; the number to price on). */
19
+ function costBreakdown(kind, parts, total) {
20
+ const lines = [
21
+ "",
22
+ `── Cost this ${kind} (API-equivalent) ────────────`,
23
+ ...Object.entries(parts)
24
+ .filter(([, v]) => v > 0)
25
+ .map(([k, v]) => ` ${k.padEnd(18)} ${usd(v)}`),
26
+ ` ${"TOTAL".padEnd(18)} ${usd(total)}`,
27
+ "──────────────────────────────────────────────",
28
+ ];
29
+ return lines.join("\n");
30
+ }
31
+ // The soft guide: below this % AI (Sapling) we ship as-is; above it we try ONE gentle
32
+ // humanize pass, and only keep it if it genuinely improves — quality is the real target.
33
+ export const AI_THRESHOLD = Number(process.env.CONTENTPRO_AI_THRESHOLD) || 40;
34
+ // Max operator-driven revises offered per article (also cost-bounded).
35
+ export const MAX_REVISES = 3;
36
+ /** The targeted humanize instruction: sharpen the human voice at the flagged sentences
37
+ * WITHOUT degrading quality — a voice pass, never a dumb "humanizer". */
38
+ function humanizeInstruction(e) {
39
+ const flagged = e.topFlagged.length ? `\nThe sentences that read most machine-like (rework these hardest, keep their meaning):\n${e.topFlagged.map((s) => `- "${s}"`).join("\n")}` : "";
40
+ return [
41
+ `An AI-content detector scored this draft ${e.aiPct}% AI-generated. Our hard bar is UNDER ${AI_THRESHOLD}%. Rewrite it to read unmistakably like one sharp human wrote it, WITHOUT losing any facts, citations, sources, internal links, callouts, the lead-magnet, structure, or length/quality. This is a VOICE pass, not a dumb humanizer: never add errors, filler, or hedging, and never weaken an argument.`,
42
+ "Improve it by making abstractions concrete and specific (named firms, exact numbers, real scenes), cutting filler and connective tissue, and letting sentence length vary naturally like an essayist.",
43
+ "CRITICAL — do NOT introduce the tells a professional editor catches, even though they lower a detector score: NO staccato / choppy fragment runs, NO one- or two-word sentences, NO contrast-or-negation framing ('not X, it's Y' / 'The goal is not X, it's Y'), NO the word 'quietly'. Keep the register professional (B2B legal/financial), not chatty. A human editor is the judge, not the detector.",
44
+ flagged,
45
+ ].join("\n");
46
+ }
47
+ /**
48
+ * Quality-first gate. If the draft already reads under the threshold, ship it untouched.
49
+ * If it's over, run ONE gentle humanize pass — and keep it ONLY if it genuinely improves
50
+ * the score. If the pass doesn't help (or errors), REVERT to the original so the humanizer
51
+ * can never degrade quality. Never grind: above-threshold drafts ship with an honest note
52
+ * telling the writer to edit the flagged spots themselves. Quality is the target, not the number.
53
+ */
54
+ async function gateToHuman(md, opts, genCost) {
55
+ const status = opts.onProgress ?? (() => { });
56
+ status("Testing for AI-detection");
57
+ const original = md;
58
+ const before = await detectSapling(original);
59
+ if (!before)
60
+ return { md: original, external: null }; // no detector → nothing to gate on
61
+ if (before.aiPct < AI_THRESHOLD)
62
+ return { md: original, external: before }; // already good — ship, quality intact
63
+ status(`AI-content ${before.aiPct}% (over ${AI_THRESHOLD}%) — one careful humanize pass…`);
64
+ try {
65
+ const { output, costUsd } = await revise({ current: original, instruction: humanizeInstruction(before), profile: opts.profile, model: opts.model });
66
+ genCost.generation += costUsd ?? 0;
67
+ const revised = stripPreamble(output);
68
+ const after = await detectSapling(revised);
69
+ if (after && after.aiPct < before.aiPct) {
70
+ status(`Improved to ${after.aiPct}% AI — keeping the humanized draft.`);
71
+ return { md: revised, external: after };
72
+ }
73
+ status("Humanize pass didn't improve it — reverting to the original to protect quality.");
74
+ }
75
+ catch {
76
+ /* revise failed — keep the original */
77
+ }
78
+ return { md: original, external: before };
79
+ }
80
+ /** Stamp the attribution, write the .docx, meter, and hand back the paths + markdown. */
81
+ async function finalizeArticle(md, external, opts, genCost, meterCredit) {
82
+ const result = opts.onResult ?? opts.onProgress ?? (() => { });
83
+ const DEV = process.env.CONTENTPRO_SHOW_COST === "1";
84
+ let stamped = normalizeLinks(md); // convert any HTML link tags the model emitted to real markdown links
85
+ if (external) {
86
+ // The ONE panel customers see — real third-party numbers, verifiable, off our shoulders.
87
+ result(formatExternalReport(external));
88
+ if (external.aiPct >= AI_THRESHOLD)
89
+ result(`Heads up: this reads ${external.aiPct}% AI, a bit over our ${AI_THRESHOLD}% guide. We kept the draft's quality intact rather than over-processing it — give the flagged spots a quick human edit, or use Revise with specific feedback.`);
90
+ stamped += `\n\n---\n\n*AI-content check: ${external.humanPct}% human · ${external.aiPct}% AI-generated — reviewed by ${external.source} (sapling.ai/ai-content-detector).*\n`;
91
+ }
92
+ if (DEV) {
93
+ const report = await detectAI(md); // internal Haiku lens — DEV-ONLY, never shown to customers
94
+ genCost.detection += report.costUsd;
95
+ result(formatReport(report));
96
+ }
97
+ const total = genCost.generation + genCost.detection;
98
+ if (DEV)
99
+ result(costBreakdown("article", genCost, total)); // internal dev-only
100
+ const base = join(opts.workdir, `draft-${Date.now()}`);
101
+ writeFileSync(`${base}.md`, stamped, "utf8");
102
+ await writeDocx(stamped, `${base}.docx`);
103
+ if (meterCredit)
104
+ await reportUsage("article", total); // 1 credit for a new article; revisions are included
105
+ return { docxPath: `${base}.docx`, md: stamped, costUsd: total };
106
+ }
107
+ /** Article: generate → gate to <40% AI (auto-improve) → stamp → .docx. */
108
+ export async function generateArticle(brief, opts) {
109
+ const status = opts.onProgress ?? (() => { });
110
+ const genCost = { generation: 0, detection: 0 };
111
+ const { output, costUsd } = await run({ brief, workdir: opts.workdir, model: opts.model, profile: opts.profile, onProgress: status, onTokens: opts.onTokens, abortController: opts.abortController });
112
+ genCost.generation += costUsd ?? 0;
113
+ const gated = await gateToHuman(stripPreamble(output), opts, genCost);
114
+ return finalizeArticle(gated.md, gated.external, opts, genCost, true);
115
+ }
116
+ /** Revise an existing draft with the operator's own feedback, then re-run the <40% gate. */
117
+ export async function reviseArticle(current, feedback, opts) {
118
+ const status = opts.onProgress ?? (() => { });
119
+ const genCost = { generation: 0, detection: 0 };
120
+ status("Applying your changes");
121
+ const { output, costUsd } = await revise({ current, instruction: feedback, profile: opts.profile, model: opts.model, onProgress: (l) => status(l.slice(0, 60)) });
122
+ genCost.generation += costUsd ?? 0;
123
+ const gated = await gateToHuman(stripPreamble(output), opts, genCost);
124
+ return finalizeArticle(gated.md, gated.external, opts, genCost, false);
125
+ }
126
+ /** Gated asset: generate a resource guide/ebook → downloadable .pdf. */
127
+ export async function generateGuide(brief, opts) {
128
+ const status = opts.onProgress ?? (() => { });
129
+ const result = opts.onResult ?? status;
130
+ const { output, costUsd } = await run({ brief, workdir: opts.workdir, model: opts.model, profile: opts.profile, onProgress: status, onTokens: opts.onTokens, abortController: opts.abortController });
131
+ const md = stripPreamble(output);
132
+ if (process.env.CONTENTPRO_SHOW_COST === "1")
133
+ result(costBreakdown("guide", { generation: costUsd ?? 0 }, costUsd ?? 0)); // internal dev-only
134
+ const base = join(opts.workdir, `guide-${Date.now()}`);
135
+ writeFileSync(`${base}.md`, md, "utf8");
136
+ await writePdf(md, `${base}.pdf`, { title: titleOf(md), subtitle: opts.subtitle }); // PDF formatting = free (pure code)
137
+ await reportUsage("guide", costUsd ?? 0); // meters 2 credits + cost (managed mode only)
138
+ return { pdfPath: `${base}.pdf`, costUsd };
139
+ }
140
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}