prose-writer 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.
@@ -0,0 +1 @@
1
+ export { bold, code, image, inline, italic, link, ProseWriter, strike, write, } from './prose-writer';
package/dist/index.js ADDED
@@ -0,0 +1,81 @@
1
+ // @bun
2
+ class E{parts=[];_skipNextPadding=!1;constructor(z){if(z!==void 0)this.parts.push(z.endsWith(`
3
+ `)?z:z+`
4
+ `)}write(...z){let A=z.map((D)=>{if(D instanceof E)return D.toString().trimEnd();return String(D)}).join(" ");if(this.parts.length===0&&A.length===0)return this;let B=this.padding;return this.parts.push(B+A+`
5
+ `),this}nextLine(){return this._skipNextPadding=!0,this}unorderedList(...z){if(z.length===1&&typeof z[0]==="function"){let{builder:D,getItems:F}=this.createListBuilder();return z[0](D),this.unorderedList(...F())}let B=z.map((D)=>{if(D instanceof E)return D.toString().trimEnd().split(`
6
+ `).map((F)=>` ${F}`).join(`
7
+ `);return`- ${D}`}).join(`
8
+ `);return this.parts.push(`${this.padding}${B}
9
+
10
+ `),this}list(...z){if(z.length===1&&typeof z[0]==="function")return this.unorderedList(z[0]);return this.unorderedList(...z)}orderedList(...z){if(z.length===1&&typeof z[0]==="function"){let{builder:F,getItems:G}=this.createListBuilder();return z[0](F),this.orderedList(...G())}let A=1,D=z.map((F)=>{if(F instanceof E)return F.toString().trimEnd().split(`
11
+ `).map((G)=>` ${G}`).join(`
12
+ `);return`${A++}. ${F}`}).join(`
13
+ `);return this.parts.push(`${this.padding}${D}
14
+
15
+ `),this}tasks(...z){if(z.length===1&&typeof z[0]==="function"){let{builder:D,getItems:F}=this.createListBuilder();z[0](D);let H=F().map((J)=>{if(J instanceof E)return J.toString().trimEnd().split(`
16
+ `).map((K)=>` ${K}`).join(`
17
+ `);return`- ${J}`}).join(`
18
+ `);return this.parts.push(`${this.padding}${H}
19
+
20
+ `),this}let B=z.map((D)=>{if(Array.isArray(D)&&D.length===2&&typeof D[1]==="boolean"){let[H,J]=D,K=J?"[x] ":"[ ] ",Y=M(H).toString().trimEnd();return K+Y}let F="[ ] ",G=M(D).toString().trimEnd();return F+G}).map((D)=>`- ${D}`).join(`
21
+ `);return this.parts.push(`${this.padding}${B}
22
+
23
+ `),this}callout(z,A){let B;if(typeof A==="function"){let H=new E;A(H.enhanced),B=H.toString().trimEnd()}else B=A;let D=B.split(`
24
+ `),G=[`[!${z.toUpperCase()}]`,...D].map((H)=>`> ${H}`).join(`
25
+ `);return this.parts.push(`${this.padding}${G}
26
+
27
+ `),this}heading(z,...A){let B="#".repeat(z),D=A.join(" ");return this.parts.push(`${this.padding}${B} ${D}
28
+
29
+ `),this}blockquote(...z){let A=z.map((B)=>`> ${B}`).join(`
30
+ >
31
+ `);return this.parts.push(`${this.padding}${A}
32
+
33
+ `),this}codeblock(z,A){let B;if(typeof A==="function"){let D=new E;A(D.enhanced),B=D.toString().trim()}else B=A;return this.parts.push(`${this.padding}\`\`\`${z}
34
+ ${B}
35
+ \`\`\`
36
+
37
+ `),this}get separator(){return this.parts.push(`${this.padding}---
38
+
39
+ `),this}json(z){let A=typeof z==="string"?z:JSON.stringify(z,null,2);return this.codeblock("json",A)}append(z){let A=z.toString();if(A.length>0)this.parts.push(this.padding+A);return this}get enhanced(){let z={bold:O,italic:Q,code:N,inline:X,link:U,strike:T,image:V};return new Proxy(this,{get(A,B){if(typeof B==="string"&&B in z)return z[B];let D=Reflect.get(A,B,A);if(typeof D==="function")return D.bind(A);return D}})}when(z,A){if(z)A(this.enhanced);return this}with(z){return z(this.enhanced),this}tag(z,A){let B;if(typeof A==="function"){let D=new E;A(D.enhanced),B=D.toString()}else B=A instanceof E?A.toString():A;return this.parts.push(`${this.padding}<${z}>
40
+ ${B.trimEnd()}
41
+ </${z}>
42
+ `),this}code(z){return this.parts.push(this.padding+N(z)+`
43
+ `),this}fill(z){let B=this.toString().replace(/\{\{(\w+)\}\}/g,(D,F)=>{return z[F]??D});return new E(B)}section(z,A,B=2){let D=new E;A(D.enhanced);let F="#".repeat(B);return this.parts.push(`${this.padding}${F} ${z}
44
+
45
+ ${D.toString()}`),this}clone(){let z=new E;return z.parts=[...this.parts],z}table(z,A){let B=`| ${z.join(" | ")} |`,D=`| ${z.map(()=>"---").join(" | ")} |`,F=A.map((G)=>{return`| ${(Array.isArray(G)?G:z.map((J)=>{let K=G[J];if(K instanceof E)return K.toPlainText();return String(K??"")})).join(" | ")} |`}).join(`
46
+ `);return this.parts.push(`${this.padding}${B}
47
+ ${D}
48
+ ${F}
49
+
50
+ `),this}definitions(z){let A=Object.entries(z).map(([B,D])=>`**${B}**: ${D}`).join(`
51
+ `);return this.parts.push(`${this.padding}${A}
52
+
53
+ `),this}bold(z){return this.parts.push(this.padding+O(z)+`
54
+ `),this}italic(z){return this.parts.push(this.padding+Q(z)+`
55
+ `),this}strike(z){return this.parts.push(this.padding+T(z)+`
56
+ `),this}raw(z){return this.parts.push(z),this}link(z,A){return this.parts.push(this.padding+U(z,A)+`
57
+ `),this}image(z,A){return this.parts.push(this.padding+V(z,A)+`
58
+ `),this}comment(z){return this.parts.push(`${this.padding}<!-- ${z} -->
59
+
60
+ `),this}yaml(z){let A=typeof z==="string"?z:this.toYamlString(z);return this.codeblock("yaml",A)}toYamlString(z,A=0){let B=" ".repeat(A);if(z===null||z===void 0)return"null";if(typeof z==="string"){if(/[:\n#"']/.test(z)||z==="")return`"${z.replace(/"/g,"\\\"")}"`;return z}if(typeof z==="number"||typeof z==="boolean")return String(z);if(Array.isArray(z)){if(z.length===0)return"[]";return z.map((D)=>`${B}- ${this.toYamlString(D,A+1)}`).join(`
61
+ `)}if(typeof z==="object"){let D=Object.entries(z);if(D.length===0)return"{}";return D.map(([F,G])=>{let H=this.toYamlString(G,A+1);if(typeof G==="object"&&G!==null&&!Array.isArray(G))return`${B}${F}:
62
+ ${H}`;if(Array.isArray(G))return`${B}${F}:
63
+ ${H}`;return`${B}${F}: ${H}`}).join(`
64
+ `)}return JSON.stringify(z)??"null"}delimit(z,A,B){let D=B instanceof E?B.toString():B;return this.parts.push(`${this.padding}${z}
65
+ ${D}
66
+ ${A}
67
+ `),this}compact(){let z=this.toString().replace(/\n{3,}/g,`
68
+
69
+ `);return new E(z)}trim(){let z=this.toString().trim();return new E(z)}tokens(z){let A=this.toString();if(z)return z(A);return Math.ceil(A.length/4)}each(z,A){return z.forEach((B,D)=>{A(B,this.enhanced,D)}),this}toPlainText(){let z=this.toString();return z=z.replace(/```[\s\S]*?```/g,(A)=>{return A.split(`
70
+ `).slice(1,-1).join(`
71
+ `)}),z=z.replace(/`([^`]+)`/g,"$1"),z=z.replace(/^#{1,6}\s+(.*)$/gm,"$1"),z=z.replace(/\*\*([^*]+)\*\*/g,"$1"),z=z.replace(/\*([^*]+)\*/g,"$1"),z=z.replace(/\[([^\]]+)\]\([^)]+\)/g,"$1"),z=z.replace(/^>\s?/gm,""),z=z.replace(/^---$/gm,""),z=z.replace(/^[-*]\s+/gm,""),z=z.replace(/^\d+\.\s+/gm,""),z=z.replace(/<[^>]+>/g,""),z=z.replace(/\|/g," "),z=z.replace(/^[\s-]+$/gm,""),z=z.replace(/ {2,}/g," "),z=z.replace(/\n{3,}/g,`
72
+
73
+ `),z.trim()}get padding(){if(this._skipNextPadding||this.parts.length===0)return this._skipNextPadding=!1,"";let z=this.parts[this.parts.length-1];if(z.endsWith(`
74
+
75
+ `))return"";if(z.endsWith(`
76
+ `))return`
77
+ `;return`
78
+
79
+ `}createListBuilder(){let z=[],A={item:(...B)=>{return z.push(M(...B).toString().trimEnd()),A},task:(B,...D)=>{let F=B?"[x] ":"[ ] ",G=M(...D).toString().trimEnd();return z.push(F+G),A},todo:(...B)=>A.task(!1,...B),done:(...B)=>A.task(!0,...B),unorderedList:(...B)=>{let D=new E;if(B.length===1&&typeof B[0]==="function")D.unorderedList(B[0]);else D.unorderedList(...B);return z.push(D),A},list:(...B)=>{let D=new E;if(B.length===1&&typeof B[0]==="function")D.list(B[0]);else D.list(...B);return z.push(D),A},orderedList:(...B)=>{let D=new E;if(B.length===1&&typeof B[0]==="function")D.orderedList(B[0]);else D.orderedList(...B);return z.push(D),A},comment:(B)=>{let D=new E;return D.comment(B),z.push(D),A},bold:O,italic:Q,code:N,inline:X,strike:T,link:U,image:V};return{builder:A,getItems:()=>z}}static empty(){return new E}static join(...z){let A=new E;for(let B of z)A.parts.push(B.toString());return A}static fromTemplate(z){return new E(z)}toString(){return this.parts.join("")}[Symbol.toPrimitive](z){if(z==="number")return Number.NaN;return this.toString()}get[Symbol.toStringTag](){return"ProseWriter"}}var M=Object.assign((...z)=>{return new E().write(...z)},{with:(z)=>{return new E().with(z)},unorderedList:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.unorderedList(z[0]);return A.unorderedList(...z)},list:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.list(z[0]);return A.list(...z)},orderedList:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.orderedList(z[0]);return A.orderedList(...z)},tasks:(...z)=>{let A=new E;if(z.length===1&&typeof z[0]==="function")return A.tasks(z[0]);return A.tasks(...z)},callout:(z,A)=>{return new E().callout(z,A)}}),O=(z)=>`**${z instanceof E?z.toString().trim():z}**`,Q=(z)=>`*${z instanceof E?z.toString().trim():z}*`,N=(z)=>`\`${z instanceof E?z.toString().trim():z}\``,X=N,T=(z)=>`~~${z instanceof E?z.toString().trim():z}~~`,U=(z,A)=>`[${z instanceof E?z.toString().trim():z}](${A})`,V=(z,A)=>`![${z instanceof E?z.toString().trim():z}](${A})`;export{M as write,T as strike,U as link,Q as italic,X as inline,V as image,N as code,O as bold,E as ProseWriter};
80
+
81
+ //# debugId=C38FBEE8EEEC812064756E2164756E21
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/prose-writer.ts"],
4
+ "sourcesContent": [
5
+ "/**\n * Inline formatting utilities that can be used within write() or builder functions.\n * These return strings and do not side-effect the writer.\n */\nexport interface InlineUtils {\n bold: (content: string | number | boolean | ProseWriter) => string;\n italic: (content: string | number | boolean | ProseWriter) => string;\n code: (content: string | number | boolean | ProseWriter) => string;\n inline: (content: string | number | boolean | ProseWriter) => string;\n strike: (content: string | number | boolean | ProseWriter) => string;\n link: (text: string | ProseWriter, url: string) => string;\n image: (alt: string | ProseWriter, url: string) => string;\n}\n\n/**\n * Builder for markdown lists.\n */\nexport interface ListBuilder extends InlineUtils {\n item(...content: (string | number | boolean | ProseWriter)[]): this;\n task(checked: boolean, ...content: (string | number | boolean | ProseWriter)[]): this;\n todo(...content: (string | number | boolean | ProseWriter)[]): this;\n done(...content: (string | number | boolean | ProseWriter)[]): this;\n comment(content: string): this;\n unorderedList(builder: (l: ListBuilder) => void): this;\n unorderedList(...items: (string | number | boolean | ProseWriter)[]): this;\n list(builder: (l: ListBuilder) => void): this;\n list(...items: (string | number | boolean | ProseWriter)[]): this;\n orderedList(builder: (l: ListBuilder) => void): this;\n orderedList(...items: (string | number | boolean | ProseWriter)[]): this;\n}\n\n/**\n * A chainable prose writer for building formatted text/markdown strings.\n */\nexport class ProseWriter {\n private parts: string[] = [];\n private _skipNextPadding = false;\n\n constructor(content?: string) {\n if (content !== undefined) {\n this.parts.push(content.endsWith('\\n') ? content : content + '\\n');\n }\n }\n\n /**\n * Appends content to the prose.\n * Multiple arguments are joined with a space.\n * Chaining write() calls creates separate paragraphs by default.\n */\n write(...content: (string | number | boolean | ProseWriter)[]): this {\n const joined = content\n .map((c) => {\n if (c instanceof ProseWriter) {\n return c.toString().trimEnd();\n }\n return String(c);\n })\n .join(' ');\n\n if (this.parts.length === 0 && joined.length === 0) {\n return this;\n }\n\n const p = this.padding;\n this.parts.push(p + joined + '\\n');\n return this;\n }\n\n /**\n * Prevents the next block element or write() call from adding a paragraph break.\n * Useful for placing two write() calls on consecutive lines.\n */\n nextLine(): this {\n this._skipNextPadding = true;\n return this;\n }\n\n /**\n * Appends an unordered list.\n * Each item is prefixed with `- ` on its own line.\n * Supports nesting by passing another ProseWriter instance or a builder function.\n */\n unorderedList(builder: (l: ListBuilder) => void): this;\n unorderedList(...items: (string | number | boolean | ProseWriter)[]): this;\n unorderedList(\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ): this {\n if (args.length === 1 && typeof args[0] === 'function') {\n const { builder, getItems } = this.createListBuilder();\n (args[0] as (l: ListBuilder) => void)(builder);\n return this.unorderedList(...getItems());\n }\n\n const items = args as (string | number | boolean | ProseWriter)[];\n const listContent = items\n .map((item) => {\n if (item instanceof ProseWriter) {\n return item\n .toString()\n .trimEnd()\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n }\n return `- ${item}`;\n })\n .join('\\n');\n this.parts.push(`${this.padding}${listContent}\\n\\n`);\n return this;\n }\n\n /**\n * Alias for unorderedList().\n */\n list(builder: (l: ListBuilder) => void): this;\n list(...items: (string | number | boolean | ProseWriter)[]): this;\n list(\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ): this {\n if (args.length === 1 && typeof args[0] === 'function') {\n return this.unorderedList(args[0] as (l: ListBuilder) => void);\n }\n return this.unorderedList(...(args as (string | number | boolean | ProseWriter)[]));\n }\n\n /**\n * Appends an ordered list.\n * Each item is prefixed with its number on its own line.\n * Supports nesting by passing another ProseWriter instance or a builder function.\n */\n orderedList(builder: (l: ListBuilder) => void): this;\n orderedList(...items: (string | number | boolean | ProseWriter)[]): this;\n orderedList(\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ): this {\n if (args.length === 1 && typeof args[0] === 'function') {\n const { builder, getItems } = this.createListBuilder();\n (args[0] as (l: ListBuilder) => void)(builder);\n return this.orderedList(...getItems());\n }\n\n let index = 1;\n const items = args as (string | number | boolean | ProseWriter)[];\n const listContent = items\n .map((item) => {\n if (item instanceof ProseWriter) {\n return item\n .toString()\n .trimEnd()\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n }\n return `${index++}. ${item}`;\n })\n .join('\\n');\n this.parts.push(`${this.padding}${listContent}\\n\\n`);\n return this;\n }\n\n /**\n * Appends a task list with checkboxes.\n */\n tasks(builder: (l: ListBuilder) => void): this;\n tasks(\n ...items: (\n | string\n | number\n | boolean\n | ProseWriter\n | [string | number | boolean | ProseWriter, boolean]\n )[]\n ): this;\n tasks(\n ...args:\n | [(l: ListBuilder) => void]\n | (\n | string\n | number\n | boolean\n | ProseWriter\n | [string | number | boolean | ProseWriter, boolean]\n )[]\n ): this {\n if (args.length === 1 && typeof args[0] === 'function') {\n const { builder, getItems } = this.createListBuilder();\n (args[0] as (l: ListBuilder) => void)(builder);\n const items = getItems();\n const listContent = items\n .map((item) => {\n if (item instanceof ProseWriter) {\n return item\n .toString()\n .trimEnd()\n .split('\\n')\n .map((line) => ` ${line}`)\n .join('\\n');\n }\n return `- ${item}`;\n })\n .join('\\n');\n this.parts.push(`${this.padding}${listContent}\\n\\n`);\n return this;\n }\n\n const items = (\n args as (\n | string\n | number\n | boolean\n | ProseWriter\n | [string | number | boolean | ProseWriter, boolean]\n )[]\n ).map((arg) => {\n if (Array.isArray(arg) && arg.length === 2 && typeof arg[1] === 'boolean') {\n const [content, checked] = arg;\n const checkbox = checked ? '[x] ' : '[ ] ';\n const text = write(content).toString().trimEnd();\n return checkbox + text;\n }\n const checkbox = '[ ] ';\n const text = write(arg as string | number | boolean | ProseWriter)\n .toString()\n .trimEnd();\n return checkbox + text;\n });\n\n const listContent = items.map((item) => `- ${item}`).join('\\n');\n this.parts.push(`${this.padding}${listContent}\\n\\n`);\n return this;\n }\n\n /**\n * Appends a GitHub Alert (callout).\n */\n callout(\n type: 'NOTE' | 'TIP' | 'IMPORTANT' | 'WARNING' | 'CAUTION',\n content: string | ((writer: ProseWriter & InlineUtils) => void),\n ): this {\n let contentString: string;\n if (typeof content === 'function') {\n const writer = new ProseWriter();\n content(writer.enhanced);\n contentString = writer.toString().trimEnd();\n } else {\n contentString = content;\n }\n\n const lines = contentString.split('\\n');\n const alertLines = [`[!${type.toUpperCase()}]`, ...lines];\n const alertContent = alertLines.map((line) => `> ${line}`).join('\\n');\n\n this.parts.push(`${this.padding}${alertContent}\\n\\n`);\n return this;\n }\n\n /**\n * Appends a markdown heading at the specified level.\n */\n heading(level: 1 | 2 | 3 | 4 | 5 | 6, ...content: string[]): this {\n const hashes = '#'.repeat(level);\n const joined = content.join(' ');\n this.parts.push(`${this.padding}${hashes} ${joined}\\n\\n`);\n return this;\n }\n\n /**\n * Appends a blockquote with the given lines.\n * Lines are separated by an empty blockquote line.\n */\n blockquote(...lines: string[]): this {\n const quotedLines = lines.map((line) => `> ${line}`).join('\\n>\\n');\n this.parts.push(`${this.padding}${quotedLines}\\n\\n`);\n return this;\n }\n\n /**\n * Appends a fenced code block with the specified language.\n */\n codeblock(\n language: string,\n content: string | ((writer: ProseWriter & InlineUtils) => void),\n ): this {\n let code: string;\n if (typeof content === 'function') {\n const writer = new ProseWriter();\n content(writer.enhanced);\n code = writer.toString().trim();\n } else {\n code = content;\n }\n this.parts.push(`${this.padding}\\`\\`\\`${language}\\n${code}\\n\\`\\`\\`\\n\\n`);\n return this;\n }\n\n /**\n * Appends a horizontal separator.\n */\n get separator(): this {\n this.parts.push(`${this.padding}---\\n\\n`);\n return this;\n }\n\n /**\n * Appends a JSON code block.\n * If data is not a string, it will be stringified with formatting.\n */\n json(data: unknown): this {\n const jsonString = typeof data === 'string' ? data : JSON.stringify(data, null, 2);\n return this.codeblock('json', jsonString);\n }\n\n /**\n * Appends the content from another ProseWriter instance.\n * Enables composition of prompts from reusable pieces.\n */\n append(writer: ProseWriter): this {\n const content = writer.toString();\n if (content.length > 0) {\n this.parts.push(this.padding + content);\n }\n return this;\n }\n\n /**\n * Returns a version of this writer with inline formatters as methods.\n * This is passed to builder functions to allow using formatters without imports.\n */\n private get enhanced(): this & InlineUtils {\n const formatters: Record<string, unknown> = {\n bold,\n italic,\n code,\n inline,\n link,\n strike,\n image,\n };\n return new Proxy(this, {\n get(target, prop) {\n if (typeof prop === 'string' && prop in formatters) {\n return formatters[prop];\n }\n const val = Reflect.get(target, prop, target) as unknown;\n if (typeof val === 'function') {\n return (val as (...args: unknown[]) => unknown).bind(target);\n }\n return val;\n },\n }) as this & InlineUtils;\n }\n\n /**\n * Conditionally executes a builder function.\n * If the condition is truthy, the builder is called with this instance.\n */\n when(condition: unknown, builder: (writer: this & InlineUtils) => void): this {\n if (condition) {\n builder(this.enhanced);\n }\n return this;\n }\n\n /**\n * Executes a builder function with this instance.\n * Useful for logical grouping in chains.\n */\n with(builder: (writer: this & InlineUtils) => void): this {\n builder(this.enhanced);\n return this;\n }\n\n /**\n * Wraps content in XML-style tags.\n * Useful for Claude and other models that respond well to XML delimiters.\n */\n tag(\n name: string,\n content: string | ProseWriter | ((writer: ProseWriter & InlineUtils) => void),\n ): this {\n let contentString: string;\n if (typeof content === 'function') {\n const writer = new ProseWriter();\n content(writer.enhanced);\n contentString = writer.toString();\n } else {\n contentString = content instanceof ProseWriter ? content.toString() : content;\n }\n this.parts.push(`${this.padding}<${name}>\\n${contentString.trimEnd()}\\n</${name}>\\n`);\n return this;\n }\n\n /**\n * Appends inline code (wrapped in backticks).\n */\n code(content: string | number | boolean | ProseWriter): this {\n this.parts.push(this.padding + code(content) + '\\n');\n return this;\n }\n\n /**\n * Replaces template variables in the format {{variableName}} with provided values.\n * Returns a new ProseWriter with the substitutions applied.\n */\n fill(variables: Record<string, string>): ProseWriter {\n const content = this.toString();\n const filled = content.replace(/\\{\\{(\\w+)\\}\\}/g, (match, key: string): string => {\n return variables[key] ?? match;\n });\n return new ProseWriter(filled);\n }\n\n /**\n * Creates a semantic section with a heading and content built by the builder function.\n * @param name - The section heading text\n * @param builder - A function that receives a fresh ProseWriter to build section content\n * @param level - Optional heading level (defaults to 2)\n */\n section(\n name: string,\n builder: (writer: ProseWriter & InlineUtils) => void,\n level: 1 | 2 | 3 | 4 | 5 | 6 = 2,\n ): this {\n const sectionWriter = new ProseWriter();\n builder(sectionWriter.enhanced);\n const hashes = '#'.repeat(level);\n this.parts.push(`${this.padding}${hashes} ${name}\\n\\n${sectionWriter.toString()}`);\n return this;\n }\n\n /**\n * Creates a copy of this ProseWriter with the same content.\n * Useful for creating variations of a base prompt.\n */\n clone(): ProseWriter {\n const cloned = new ProseWriter();\n cloned.parts = [...this.parts];\n return cloned;\n }\n\n /**\n * Appends a markdown table with headers and rows.\n * Type-safe: Each row can be an array of strings matching the header length,\n * or an object where keys match the header names.\n */\n table<T extends string>(\n headers: [...T[]],\n rows: (string[] | Record<T, string | number | boolean | ProseWriter>)[],\n ): this {\n const headerRow = `| ${headers.join(' | ')} |`;\n const separatorRow = `| ${headers.map(() => '---').join(' | ')} |`;\n\n const dataRows = rows\n .map((row) => {\n const values = Array.isArray(row)\n ? row\n : headers.map((h) => {\n const val = row[h];\n if (val instanceof ProseWriter) return val.toPlainText();\n return String(val ?? '');\n });\n return `| ${values.join(' | ')} |`;\n })\n .join('\\n');\n\n this.parts.push(`${this.padding}${headerRow}\\n${separatorRow}\\n${dataRows}\\n\\n`);\n return this;\n }\n\n /**\n * Appends a definition list with key-value pairs.\n * Each key is bolded, followed by a colon and the value.\n */\n definitions(obj: Record<string, string>): this {\n const entries = Object.entries(obj)\n .map(([key, value]) => `**${key}**: ${value}`)\n .join('\\n');\n this.parts.push(`${this.padding}${entries}\\n\\n`);\n return this;\n }\n\n /**\n * Appends bold text.\n */\n bold(content: string | number | boolean | ProseWriter): this {\n this.parts.push(this.padding + bold(content) + '\\n');\n return this;\n }\n\n /**\n * Appends italic text.\n */\n italic(content: string | number | boolean | ProseWriter): this {\n this.parts.push(this.padding + italic(content) + '\\n');\n return this;\n }\n\n /**\n * Appends strikethrough text.\n */\n strike(content: string | number | boolean | ProseWriter): this {\n this.parts.push(this.padding + strike(content) + '\\n');\n return this;\n }\n\n /**\n * Appends raw content without any processing.\n */\n raw(content: string): this {\n this.parts.push(content);\n return this;\n }\n\n /**\n * Appends a markdown link.\n */\n link(text: string | ProseWriter, url: string): this {\n this.parts.push(this.padding + link(text, url) + '\\n');\n return this;\n }\n\n /**\n * Appends a markdown image.\n */\n image(alt: string | ProseWriter, url: string): this {\n this.parts.push(this.padding + image(alt, url) + '\\n');\n return this;\n }\n\n /**\n * Appends an HTML comment.\n */\n comment(content: string): this {\n this.parts.push(`${this.padding}<!-- ${content} -->\\n\\n`);\n return this;\n }\n\n /**\n * Appends a YAML code block.\n * If data is not a string, it will be converted to YAML format.\n */\n yaml(data: unknown): this {\n const yamlString = typeof data === 'string' ? data : this.toYamlString(data);\n return this.codeblock('yaml', yamlString);\n }\n\n /**\n * Converts a value to a simple YAML string representation.\n */\n private toYamlString(data: unknown, indent: number = 0): string {\n const prefix = ' '.repeat(indent);\n\n if (data === null || data === undefined) {\n return 'null';\n }\n\n if (typeof data === 'string') {\n // Quote strings that contain special characters\n if (/[:\\n#\"']/.test(data) || data === '') {\n return `\"${data.replace(/\"/g, '\\\\\"')}\"`;\n }\n return data;\n }\n\n if (typeof data === 'number' || typeof data === 'boolean') {\n return String(data);\n }\n\n if (Array.isArray(data)) {\n if (data.length === 0) return '[]';\n return data\n .map((item) => `${prefix}- ${this.toYamlString(item, indent + 1)}`)\n .join('\\n');\n }\n\n if (typeof data === 'object') {\n const entries = Object.entries(data as Record<string, unknown>);\n if (entries.length === 0) return '{}';\n return entries\n .map(([key, value]) => {\n const valueStr = this.toYamlString(value, indent + 1);\n if (typeof value === 'object' && value !== null && !Array.isArray(value)) {\n return `${prefix}${key}:\\n${valueStr}`;\n }\n if (Array.isArray(value)) {\n return `${prefix}${key}:\\n${valueStr}`;\n }\n return `${prefix}${key}: ${valueStr}`;\n })\n .join('\\n');\n }\n\n // Fallback for any other types - use JSON stringify\n return JSON.stringify(data) ?? 'null';\n }\n\n /**\n * Wraps content with custom delimiters.\n */\n delimit(open: string, close: string, content: string | ProseWriter): this {\n const contentString = content instanceof ProseWriter ? content.toString() : content;\n this.parts.push(`${this.padding}${open}\\n${contentString}\\n${close}\\n`);\n return this;\n }\n\n /**\n * Returns a new ProseWriter with consecutive newlines collapsed to double newlines.\n */\n compact(): ProseWriter {\n const content = this.toString().replace(/\\n{3,}/g, '\\n\\n');\n return new ProseWriter(content);\n }\n\n /**\n * Returns a new ProseWriter with leading and trailing whitespace removed.\n */\n trim(): ProseWriter {\n const content = this.toString().trim();\n return new ProseWriter(content);\n }\n\n /**\n * Estimates the number of tokens in the prose.\n * By default, uses a rough approximation of ~4 characters per token.\n * An optional counter function can be provided for more accurate counting.\n */\n tokens(counter?: (content: string) => number): number {\n const content = this.toString();\n if (counter) {\n return counter(content);\n }\n // Rough estimation: ~4 characters per token for English text\n return Math.ceil(content.length / 4);\n }\n\n /**\n * Iterates over items and applies a builder function for each.\n */\n each<T>(\n items: T[],\n builder: (item: T, writer: this & InlineUtils, index: number) => void,\n ): this {\n items.forEach((item, index) => {\n builder(item, this.enhanced, index);\n });\n return this;\n }\n\n /**\n * Converts the prose to plain text by stripping markdown formatting.\n */\n toPlainText(): string {\n let text = this.toString();\n\n // Remove code blocks (preserve content)\n text = text.replace(/```[\\s\\S]*?```/g, (match) => {\n const lines = match.split('\\n');\n return lines.slice(1, -1).join('\\n');\n });\n\n // Remove inline code backticks\n text = text.replace(/`([^`]+)`/g, '$1');\n\n // Remove headings (keep text)\n text = text.replace(/^#{1,6}\\s+(.*)$/gm, '$1');\n\n // Remove bold\n text = text.replace(/\\*\\*([^*]+)\\*\\*/g, '$1');\n\n // Remove italic\n text = text.replace(/\\*([^*]+)\\*/g, '$1');\n\n // Remove links (keep text)\n text = text.replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1');\n\n // Remove blockquote markers\n text = text.replace(/^>\\s?/gm, '');\n\n // Remove horizontal rules\n text = text.replace(/^---$/gm, '');\n\n // Remove list markers\n text = text.replace(/^[-*]\\s+/gm, '');\n text = text.replace(/^\\d+\\.\\s+/gm, '');\n\n // Remove XML tags (keep content)\n text = text.replace(/<[^>]+>/g, '');\n\n // Remove table formatting\n text = text.replace(/\\|/g, ' ');\n text = text.replace(/^[\\s-]+$/gm, '');\n\n // Collapse multiple spaces\n text = text.replace(/ {2,}/g, ' ');\n\n // Collapse multiple newlines\n text = text.replace(/\\n{3,}/g, '\\n\\n');\n\n return text.trim();\n }\n\n /**\n * Returns necessary newline padding if there is existing content.\n * Ensures exactly two newlines (a paragraph break) before a block element.\n */\n private get padding(): string {\n if (this._skipNextPadding || this.parts.length === 0) {\n this._skipNextPadding = false;\n return '';\n }\n const lastPart = this.parts[this.parts.length - 1]!;\n if (lastPart.endsWith('\\n\\n')) return '';\n if (lastPart.endsWith('\\n')) return '\\n';\n return '\\n\\n';\n }\n\n /**\n * Internal helper to create a list builder.\n */\n private createListBuilder(): {\n builder: ListBuilder;\n getItems: () => (string | number | boolean | ProseWriter)[];\n } {\n const items: (string | number | boolean | ProseWriter)[] = [];\n const lb: ListBuilder = {\n item: (...content: (string | number | boolean | ProseWriter)[]) => {\n items.push(\n write(...content)\n .toString()\n .trimEnd(),\n );\n return lb;\n },\n task: (\n checked: boolean,\n ...content: (string | number | boolean | ProseWriter)[]\n ) => {\n const checkbox = checked ? '[x] ' : '[ ] ';\n const text = write(...content)\n .toString()\n .trimEnd();\n items.push(checkbox + text);\n return lb;\n },\n todo: (...content: (string | number | boolean | ProseWriter)[]) =>\n lb.task(false, ...content),\n done: (...content: (string | number | boolean | ProseWriter)[]) =>\n lb.task(true, ...content),\n unorderedList: (\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ) => {\n const sub = new ProseWriter();\n if (args.length === 1 && typeof args[0] === 'function') {\n sub.unorderedList(args[0] as (l: ListBuilder) => void);\n } else {\n sub.unorderedList(...(args as (string | number | boolean | ProseWriter)[]));\n }\n items.push(sub);\n return lb;\n },\n list: (\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ) => {\n const sub = new ProseWriter();\n if (args.length === 1 && typeof args[0] === 'function') {\n sub.list(args[0] as (l: ListBuilder) => void);\n } else {\n sub.list(...(args as (string | number | boolean | ProseWriter)[]));\n }\n items.push(sub);\n return lb;\n },\n orderedList: (\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ) => {\n const sub = new ProseWriter();\n if (args.length === 1 && typeof args[0] === 'function') {\n sub.orderedList(args[0] as (l: ListBuilder) => void);\n } else {\n sub.orderedList(...(args as (string | number | boolean | ProseWriter)[]));\n }\n items.push(sub);\n return lb;\n },\n comment: (content: string) => {\n const sub = new ProseWriter();\n sub.comment(content);\n items.push(sub);\n return lb;\n },\n bold,\n italic,\n code,\n inline,\n strike,\n link,\n image,\n };\n return { builder: lb, getItems: () => items };\n }\n\n /**\n * Creates an empty ProseWriter instance.\n */\n static empty(): ProseWriter {\n return new ProseWriter();\n }\n\n /**\n * Joins multiple ProseWriter instances into one.\n */\n static join(...writers: ProseWriter[]): ProseWriter {\n const result = new ProseWriter();\n for (const writer of writers) {\n result.parts.push(writer.toString());\n }\n return result;\n }\n\n /**\n * Creates a ProseWriter from a template string.\n */\n static fromTemplate(template: string): ProseWriter {\n return new ProseWriter(template);\n }\n\n /**\n * Converts the accumulated prose to a string.\n */\n toString(): string {\n return this.parts.join('');\n }\n\n /**\n * Returns the primitive value (string) for type coercion.\n */\n [Symbol.toPrimitive](hint: string): string | number {\n if (hint === 'number') {\n return Number.NaN;\n }\n return this.toString();\n }\n\n /**\n * Returns the string tag for the object.\n */\n get [Symbol.toStringTag](): string {\n return 'ProseWriter';\n }\n}\n\n/**\n * Creates a new ProseWriter instance with the given content.\n */\nexport const write = Object.assign(\n (...content: (string | number | boolean | ProseWriter)[]): ProseWriter => {\n return new ProseWriter().write(...content);\n },\n {\n with: (builder: (writer: ProseWriter & InlineUtils) => void): ProseWriter => {\n return new ProseWriter().with(builder);\n },\n unorderedList: (\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ): ProseWriter => {\n const pw = new ProseWriter();\n if (args.length === 1 && typeof args[0] === 'function') {\n return pw.unorderedList(args[0] as (l: ListBuilder) => void);\n }\n return pw.unorderedList(...(args as (string | number | boolean | ProseWriter)[]));\n },\n list: (\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ): ProseWriter => {\n const pw = new ProseWriter();\n if (args.length === 1 && typeof args[0] === 'function') {\n return pw.list(args[0] as (l: ListBuilder) => void);\n }\n return pw.list(...(args as (string | number | boolean | ProseWriter)[]));\n },\n orderedList: (\n ...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]\n ): ProseWriter => {\n const pw = new ProseWriter();\n if (args.length === 1 && typeof args[0] === 'function') {\n return pw.orderedList(args[0] as (l: ListBuilder) => void);\n }\n return pw.orderedList(...(args as (string | number | boolean | ProseWriter)[]));\n },\n tasks: (\n ...args:\n | [(l: ListBuilder) => void]\n | (\n | string\n | number\n | boolean\n | ProseWriter\n | [string | number | boolean | ProseWriter, boolean]\n )[]\n ): ProseWriter => {\n const pw = new ProseWriter();\n if (args.length === 1 && typeof args[0] === 'function') {\n return pw.tasks(args[0] as (l: ListBuilder) => void);\n }\n return pw.tasks(\n ...(args as (\n | string\n | number\n | boolean\n | ProseWriter\n | [string | number | boolean | ProseWriter, boolean]\n )[]),\n );\n },\n callout: (\n type: 'NOTE' | 'TIP' | 'IMPORTANT' | 'WARNING' | 'CAUTION',\n content: string | ((writer: ProseWriter & InlineUtils) => void),\n ): ProseWriter => {\n return new ProseWriter().callout(type, content);\n },\n },\n);\n\n/**\n * Appends bold formatting to a string.\n */\nexport const bold = (content: string | number | boolean | ProseWriter): string =>\n `**${content instanceof ProseWriter ? content.toString().trim() : content}**`;\n\n/**\n * Appends italic formatting to a string.\n */\nexport const italic = (content: string | number | boolean | ProseWriter): string =>\n `*${content instanceof ProseWriter ? content.toString().trim() : content}*`;\n\n/**\n * Appends inline code formatting to a string.\n */\nexport const code = (content: string | number | boolean | ProseWriter): string =>\n `\\`${content instanceof ProseWriter ? content.toString().trim() : content}\\``;\n\n/**\n * Alias for code().\n */\nexport const inline = code;\n\n/**\n * Appends strikethrough formatting to a string.\n */\nexport const strike = (content: string | number | boolean | ProseWriter): string =>\n `~~${content instanceof ProseWriter ? content.toString().trim() : content}~~`;\n\n/**\n * Creates a markdown link string.\n */\nexport const link = (text: string | ProseWriter, url: string): string =>\n `[${text instanceof ProseWriter ? text.toString().trim() : text}](${url})`;\n\n/**\n * Creates a markdown image string.\n */\nexport const image = (alt: string | ProseWriter, url: string): string =>\n `![${alt instanceof ProseWriter ? alt.toString().trim() : alt}](${url})`;\n"
6
+ ],
7
+ "mappings": "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",
8
+ "debugId": "C38FBEE8EEEC812064756E2164756E21",
9
+ "names": []
10
+ }
@@ -0,0 +1,290 @@
1
+ /**
2
+ * Inline formatting utilities that can be used within write() or builder functions.
3
+ * These return strings and do not side-effect the writer.
4
+ */
5
+ export interface InlineUtils {
6
+ bold: (content: string | number | boolean | ProseWriter) => string;
7
+ italic: (content: string | number | boolean | ProseWriter) => string;
8
+ code: (content: string | number | boolean | ProseWriter) => string;
9
+ inline: (content: string | number | boolean | ProseWriter) => string;
10
+ strike: (content: string | number | boolean | ProseWriter) => string;
11
+ link: (text: string | ProseWriter, url: string) => string;
12
+ image: (alt: string | ProseWriter, url: string) => string;
13
+ }
14
+ /**
15
+ * Builder for markdown lists.
16
+ */
17
+ export interface ListBuilder extends InlineUtils {
18
+ item(...content: (string | number | boolean | ProseWriter)[]): this;
19
+ task(checked: boolean, ...content: (string | number | boolean | ProseWriter)[]): this;
20
+ todo(...content: (string | number | boolean | ProseWriter)[]): this;
21
+ done(...content: (string | number | boolean | ProseWriter)[]): this;
22
+ comment(content: string): this;
23
+ unorderedList(builder: (l: ListBuilder) => void): this;
24
+ unorderedList(...items: (string | number | boolean | ProseWriter)[]): this;
25
+ list(builder: (l: ListBuilder) => void): this;
26
+ list(...items: (string | number | boolean | ProseWriter)[]): this;
27
+ orderedList(builder: (l: ListBuilder) => void): this;
28
+ orderedList(...items: (string | number | boolean | ProseWriter)[]): this;
29
+ }
30
+ /**
31
+ * A chainable prose writer for building formatted text/markdown strings.
32
+ */
33
+ export declare class ProseWriter {
34
+ private parts;
35
+ private _skipNextPadding;
36
+ constructor(content?: string);
37
+ /**
38
+ * Appends content to the prose.
39
+ * Multiple arguments are joined with a space.
40
+ * Chaining write() calls creates separate paragraphs by default.
41
+ */
42
+ write(...content: (string | number | boolean | ProseWriter)[]): this;
43
+ /**
44
+ * Prevents the next block element or write() call from adding a paragraph break.
45
+ * Useful for placing two write() calls on consecutive lines.
46
+ */
47
+ nextLine(): this;
48
+ /**
49
+ * Appends an unordered list.
50
+ * Each item is prefixed with `- ` on its own line.
51
+ * Supports nesting by passing another ProseWriter instance or a builder function.
52
+ */
53
+ unorderedList(builder: (l: ListBuilder) => void): this;
54
+ unorderedList(...items: (string | number | boolean | ProseWriter)[]): this;
55
+ /**
56
+ * Alias for unorderedList().
57
+ */
58
+ list(builder: (l: ListBuilder) => void): this;
59
+ list(...items: (string | number | boolean | ProseWriter)[]): this;
60
+ /**
61
+ * Appends an ordered list.
62
+ * Each item is prefixed with its number on its own line.
63
+ * Supports nesting by passing another ProseWriter instance or a builder function.
64
+ */
65
+ orderedList(builder: (l: ListBuilder) => void): this;
66
+ orderedList(...items: (string | number | boolean | ProseWriter)[]): this;
67
+ /**
68
+ * Appends a task list with checkboxes.
69
+ */
70
+ tasks(builder: (l: ListBuilder) => void): this;
71
+ tasks(...items: (string | number | boolean | ProseWriter | [string | number | boolean | ProseWriter, boolean])[]): this;
72
+ /**
73
+ * Appends a GitHub Alert (callout).
74
+ */
75
+ callout(type: 'NOTE' | 'TIP' | 'IMPORTANT' | 'WARNING' | 'CAUTION', content: string | ((writer: ProseWriter & InlineUtils) => void)): this;
76
+ /**
77
+ * Appends a markdown heading at the specified level.
78
+ */
79
+ heading(level: 1 | 2 | 3 | 4 | 5 | 6, ...content: string[]): this;
80
+ /**
81
+ * Appends a blockquote with the given lines.
82
+ * Lines are separated by an empty blockquote line.
83
+ */
84
+ blockquote(...lines: string[]): this;
85
+ /**
86
+ * Appends a fenced code block with the specified language.
87
+ */
88
+ codeblock(language: string, content: string | ((writer: ProseWriter & InlineUtils) => void)): this;
89
+ /**
90
+ * Appends a horizontal separator.
91
+ */
92
+ get separator(): this;
93
+ /**
94
+ * Appends a JSON code block.
95
+ * If data is not a string, it will be stringified with formatting.
96
+ */
97
+ json(data: unknown): this;
98
+ /**
99
+ * Appends the content from another ProseWriter instance.
100
+ * Enables composition of prompts from reusable pieces.
101
+ */
102
+ append(writer: ProseWriter): this;
103
+ /**
104
+ * Returns a version of this writer with inline formatters as methods.
105
+ * This is passed to builder functions to allow using formatters without imports.
106
+ */
107
+ private get enhanced();
108
+ /**
109
+ * Conditionally executes a builder function.
110
+ * If the condition is truthy, the builder is called with this instance.
111
+ */
112
+ when(condition: unknown, builder: (writer: this & InlineUtils) => void): this;
113
+ /**
114
+ * Executes a builder function with this instance.
115
+ * Useful for logical grouping in chains.
116
+ */
117
+ with(builder: (writer: this & InlineUtils) => void): this;
118
+ /**
119
+ * Wraps content in XML-style tags.
120
+ * Useful for Claude and other models that respond well to XML delimiters.
121
+ */
122
+ tag(name: string, content: string | ProseWriter | ((writer: ProseWriter & InlineUtils) => void)): this;
123
+ /**
124
+ * Appends inline code (wrapped in backticks).
125
+ */
126
+ code(content: string | number | boolean | ProseWriter): this;
127
+ /**
128
+ * Replaces template variables in the format {{variableName}} with provided values.
129
+ * Returns a new ProseWriter with the substitutions applied.
130
+ */
131
+ fill(variables: Record<string, string>): ProseWriter;
132
+ /**
133
+ * Creates a semantic section with a heading and content built by the builder function.
134
+ * @param name - The section heading text
135
+ * @param builder - A function that receives a fresh ProseWriter to build section content
136
+ * @param level - Optional heading level (defaults to 2)
137
+ */
138
+ section(name: string, builder: (writer: ProseWriter & InlineUtils) => void, level?: 1 | 2 | 3 | 4 | 5 | 6): this;
139
+ /**
140
+ * Creates a copy of this ProseWriter with the same content.
141
+ * Useful for creating variations of a base prompt.
142
+ */
143
+ clone(): ProseWriter;
144
+ /**
145
+ * Appends a markdown table with headers and rows.
146
+ * Type-safe: Each row can be an array of strings matching the header length,
147
+ * or an object where keys match the header names.
148
+ */
149
+ table<T extends string>(headers: [...T[]], rows: (string[] | Record<T, string | number | boolean | ProseWriter>)[]): this;
150
+ /**
151
+ * Appends a definition list with key-value pairs.
152
+ * Each key is bolded, followed by a colon and the value.
153
+ */
154
+ definitions(obj: Record<string, string>): this;
155
+ /**
156
+ * Appends bold text.
157
+ */
158
+ bold(content: string | number | boolean | ProseWriter): this;
159
+ /**
160
+ * Appends italic text.
161
+ */
162
+ italic(content: string | number | boolean | ProseWriter): this;
163
+ /**
164
+ * Appends strikethrough text.
165
+ */
166
+ strike(content: string | number | boolean | ProseWriter): this;
167
+ /**
168
+ * Appends raw content without any processing.
169
+ */
170
+ raw(content: string): this;
171
+ /**
172
+ * Appends a markdown link.
173
+ */
174
+ link(text: string | ProseWriter, url: string): this;
175
+ /**
176
+ * Appends a markdown image.
177
+ */
178
+ image(alt: string | ProseWriter, url: string): this;
179
+ /**
180
+ * Appends an HTML comment.
181
+ */
182
+ comment(content: string): this;
183
+ /**
184
+ * Appends a YAML code block.
185
+ * If data is not a string, it will be converted to YAML format.
186
+ */
187
+ yaml(data: unknown): this;
188
+ /**
189
+ * Converts a value to a simple YAML string representation.
190
+ */
191
+ private toYamlString;
192
+ /**
193
+ * Wraps content with custom delimiters.
194
+ */
195
+ delimit(open: string, close: string, content: string | ProseWriter): this;
196
+ /**
197
+ * Returns a new ProseWriter with consecutive newlines collapsed to double newlines.
198
+ */
199
+ compact(): ProseWriter;
200
+ /**
201
+ * Returns a new ProseWriter with leading and trailing whitespace removed.
202
+ */
203
+ trim(): ProseWriter;
204
+ /**
205
+ * Estimates the number of tokens in the prose.
206
+ * By default, uses a rough approximation of ~4 characters per token.
207
+ * An optional counter function can be provided for more accurate counting.
208
+ */
209
+ tokens(counter?: (content: string) => number): number;
210
+ /**
211
+ * Iterates over items and applies a builder function for each.
212
+ */
213
+ each<T>(items: T[], builder: (item: T, writer: this & InlineUtils, index: number) => void): this;
214
+ /**
215
+ * Converts the prose to plain text by stripping markdown formatting.
216
+ */
217
+ toPlainText(): string;
218
+ /**
219
+ * Returns necessary newline padding if there is existing content.
220
+ * Ensures exactly two newlines (a paragraph break) before a block element.
221
+ */
222
+ private get padding();
223
+ /**
224
+ * Internal helper to create a list builder.
225
+ */
226
+ private createListBuilder;
227
+ /**
228
+ * Creates an empty ProseWriter instance.
229
+ */
230
+ static empty(): ProseWriter;
231
+ /**
232
+ * Joins multiple ProseWriter instances into one.
233
+ */
234
+ static join(...writers: ProseWriter[]): ProseWriter;
235
+ /**
236
+ * Creates a ProseWriter from a template string.
237
+ */
238
+ static fromTemplate(template: string): ProseWriter;
239
+ /**
240
+ * Converts the accumulated prose to a string.
241
+ */
242
+ toString(): string;
243
+ /**
244
+ * Returns the primitive value (string) for type coercion.
245
+ */
246
+ [Symbol.toPrimitive](hint: string): string | number;
247
+ /**
248
+ * Returns the string tag for the object.
249
+ */
250
+ get [Symbol.toStringTag](): string;
251
+ }
252
+ /**
253
+ * Creates a new ProseWriter instance with the given content.
254
+ */
255
+ export declare const write: ((...content: (string | number | boolean | ProseWriter)[]) => ProseWriter) & {
256
+ with: (builder: (writer: ProseWriter & InlineUtils) => void) => ProseWriter;
257
+ unorderedList: (...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]) => ProseWriter;
258
+ list: (...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]) => ProseWriter;
259
+ orderedList: (...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter)[]) => ProseWriter;
260
+ tasks: (...args: [(l: ListBuilder) => void] | (string | number | boolean | ProseWriter | [string | number | boolean | ProseWriter, boolean])[]) => ProseWriter;
261
+ callout: (type: "NOTE" | "TIP" | "IMPORTANT" | "WARNING" | "CAUTION", content: string | ((writer: ProseWriter & InlineUtils) => void)) => ProseWriter;
262
+ };
263
+ /**
264
+ * Appends bold formatting to a string.
265
+ */
266
+ export declare const bold: (content: string | number | boolean | ProseWriter) => string;
267
+ /**
268
+ * Appends italic formatting to a string.
269
+ */
270
+ export declare const italic: (content: string | number | boolean | ProseWriter) => string;
271
+ /**
272
+ * Appends inline code formatting to a string.
273
+ */
274
+ export declare const code: (content: string | number | boolean | ProseWriter) => string;
275
+ /**
276
+ * Alias for code().
277
+ */
278
+ export declare const inline: (content: string | number | boolean | ProseWriter) => string;
279
+ /**
280
+ * Appends strikethrough formatting to a string.
281
+ */
282
+ export declare const strike: (content: string | number | boolean | ProseWriter) => string;
283
+ /**
284
+ * Creates a markdown link string.
285
+ */
286
+ export declare const link: (text: string | ProseWriter, url: string) => string;
287
+ /**
288
+ * Creates a markdown image string.
289
+ */
290
+ export declare const image: (alt: string | ProseWriter, url: string) => string;
package/package.json ADDED
@@ -0,0 +1,105 @@
1
+ {
2
+ "name": "prose-writer",
3
+ "version": "0.1.0",
4
+ "description": "A chainable TypeScript library for building formatted text and markdown strings",
5
+ "keywords": [
6
+ "markdown",
7
+ "prose",
8
+ "text",
9
+ "template",
10
+ "prompt",
11
+ "llm",
12
+ "ai",
13
+ "chainable",
14
+ "builder"
15
+ ],
16
+ "license": "MIT",
17
+ "author": "",
18
+ "type": "module",
19
+ "exports": {
20
+ ".": {
21
+ "types": "./dist/index.d.ts",
22
+ "bun": "./dist/index.js",
23
+ "import": "./dist/index.js",
24
+ "default": "./dist/index.js"
25
+ }
26
+ },
27
+ "main": "./dist/index.js",
28
+ "module": "./dist/index.js",
29
+ "types": "./dist/index.d.ts",
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
35
+ "scripts": {
36
+ "build": "bun build --target=bun --outdir=dist --minify --sourcemap=external ./src/index.ts && bun run build:types",
37
+ "build:types": "tsc -p tsconfig.build.json",
38
+ "clean": "rm -rf dist coverage .eslintcache",
39
+ "dev": "bun --watch run src/index.ts",
40
+ "format": "prettier --write \"**/*.{ts,tsx,js,jsx,json,md}\"",
41
+ "format:check": "prettier --check \"**/*.{ts,tsx,js,jsx,json,md}\"",
42
+ "lint": "eslint .",
43
+ "lint:fix": "eslint . --fix",
44
+ "prepare": "husky",
45
+ "prepublishOnly": "bun run validate && bun run build",
46
+ "start": "bun run src/index.ts",
47
+ "test": "bun test",
48
+ "test:coverage": "bun test --coverage",
49
+ "typecheck": "tsc --noEmit",
50
+ "validate": "bun run lint && bun run typecheck && bun run test"
51
+ },
52
+ "lint-staged": {
53
+ "src/**/*.{js,ts,tsx,jsx,mjs,cjs}": [
54
+ "eslint --fix",
55
+ "prettier --write"
56
+ ],
57
+ "scripts/**/*.{js,ts,tsx,jsx,mjs,cjs}": [
58
+ "eslint --fix",
59
+ "prettier --write"
60
+ ],
61
+ "**/*.{json,md,css,scss}": [
62
+ "prettier --write"
63
+ ],
64
+ "package.json": [
65
+ "sort-package-json"
66
+ ]
67
+ },
68
+ "dependencies": {},
69
+ "devDependencies": {
70
+ "@eslint/eslintrc": "^3.3.3",
71
+ "@eslint/js": "^9.39.2",
72
+ "@eslint/markdown": "^7.5.1",
73
+ "@types/bun": "^1.3.5",
74
+ "@types/mdast": "^4.0.4",
75
+ "@typescript-eslint/eslint-plugin": "^8.50.0",
76
+ "@typescript-eslint/parser": "^8.50.0",
77
+ "chalk": "^5.6.2",
78
+ "change-case": "^5.4.4",
79
+ "eslint": "^9.39.2",
80
+ "eslint-config-prettier": "^10.1.8",
81
+ "eslint-import-resolver-typescript": "^4.4.4",
82
+ "eslint-plugin-eslint-comments": "^3.2.0",
83
+ "eslint-plugin-import": "^2.32.0",
84
+ "eslint-plugin-prettier": "^5.5.4",
85
+ "eslint-plugin-promise": "^7.2.1",
86
+ "eslint-plugin-regexp": "^2.10.0",
87
+ "eslint-plugin-simple-import-sort": "^12.1.1",
88
+ "eslint-plugin-unicorn": "^62.0.0",
89
+ "eslint-plugin-unused-imports": "^4.3.0",
90
+ "globals": "^16.5.0",
91
+ "husky": "^9.1.7",
92
+ "lint-staged": "^16.2.7",
93
+ "prettier": "^3.7.4",
94
+ "remark": "^15.0.1",
95
+ "remark-parse": "^11.0.0",
96
+ "remark-stringify": "^11.0.0",
97
+ "sort-package-json": "^3.6.0",
98
+ "typescript-eslint": "^8.50.0",
99
+ "unified": "^11.0.5",
100
+ "unist-util-remove": "^4.0.0"
101
+ },
102
+ "engines": {
103
+ "bun": ">=1.3.0"
104
+ }
105
+ }