prose-writer 0.1.0 → 0.1.2
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.
- package/README.md +229 -97
- package/dist/index.d.ts +1 -1
- package/dist/index.js +76 -62
- package/dist/index.js.map +3 -3
- package/dist/markdown.d.ts +1 -0
- package/dist/markdown.js +95 -0
- package/dist/markdown.js.map +10 -0
- package/dist/prose-writer.d.ts +68 -25
- package/dist/safe.d.ts +9 -0
- package/dist/safe.js +95 -0
- package/dist/safe.js.map +11 -0
- package/dist/schema.d.ts +1 -0
- package/dist/schema.js +3 -0
- package/dist/schema.js.map +9 -0
- package/dist/validation.d.ts +2 -0
- package/dist/validation.js +95 -0
- package/dist/validation.js.map +10 -0
- package/package.json +26 -3
package/README.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
A zero-dependency, chainable TypeScript library for building formatted text and markdown strings. Perfect for constructing LLM prompts, generating documentation, or any scenario where you need to programmatically build structured text.
|
|
4
4
|
|
|
5
|
+
## In one sentence
|
|
6
|
+
|
|
7
|
+
Prose Writer is a fluent builder for producing markdown-friendly strings without template literal sprawl.
|
|
8
|
+
|
|
9
|
+
## When to use it
|
|
10
|
+
|
|
11
|
+
- You need readable, composable prompt or document builders in code
|
|
12
|
+
- You want conditionals, loops, and reusable pieces without `.map().join()` or manual concatenation
|
|
13
|
+
- You need safe handling of untrusted input or structured output sections (JSON/YAML)
|
|
14
|
+
|
|
15
|
+
## How it works (3 steps)
|
|
16
|
+
|
|
17
|
+
1. `write()` creates a builder (optionally with initial text).
|
|
18
|
+
2. Chain block helpers like `.section()`, `.list()`, `.tag()`, `.codeblock()`, `.json()`.
|
|
19
|
+
3. Call `.toString()` or `String(writer)` to get the final text.
|
|
20
|
+
|
|
21
|
+
```typescript
|
|
22
|
+
import { write } from 'prose-writer';
|
|
23
|
+
|
|
24
|
+
const prompt = write('You are a helpful assistant.')
|
|
25
|
+
.section('Guidelines', (w) => w.list('Be concise', 'Cite sources'))
|
|
26
|
+
.tag('input', userText)
|
|
27
|
+
.toString();
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Each `write()` call ends with a newline, so chained calls become separate paragraphs (a blank line between). To keep content on the same line, pass multiple strings to a single `write()` call. Most block helpers add blank lines around themselves so the output reads like markdown paragraphs. Use `write()` with no args to insert an extra blank line.
|
|
31
|
+
|
|
5
32
|
## Why Prose Writer?
|
|
6
33
|
|
|
7
34
|
Building prompts for LLMs in code is _painful_. You end up with wild stuff like this.
|
|
@@ -23,7 +50,27 @@ ${context}
|
|
|
23
50
|
|
|
24
51
|
Template literals become unreadable. String concatenation is worse. And when you need conditionals, variables, or reusable pieces? Good luck.
|
|
25
52
|
|
|
26
|
-
|
|
53
|
+
Compared to concatenating arrays of strings, Prose Writer keeps structure and spacing inside the builder instead of scattering `join()` logic, manual newlines, and nested maps across your code. Compared to giant template strings, it avoids brittle whitespace and makes conditional or reusable sections readable and composable.
|
|
54
|
+
|
|
55
|
+
Array concatenation version:
|
|
56
|
+
|
|
57
|
+
```typescript
|
|
58
|
+
const prompt = [
|
|
59
|
+
`You are a ${role}.`,
|
|
60
|
+
'',
|
|
61
|
+
'## Guidelines',
|
|
62
|
+
...guidelines.map((g) => `- ${g}`),
|
|
63
|
+
'',
|
|
64
|
+
'## Examples',
|
|
65
|
+
...examples.map((ex, i) => `### Example ${i + 1}\n${ex}`),
|
|
66
|
+
'',
|
|
67
|
+
'<context>',
|
|
68
|
+
context,
|
|
69
|
+
'</context>',
|
|
70
|
+
].join('\n');
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Prose Writer version:
|
|
27
74
|
|
|
28
75
|
```typescript
|
|
29
76
|
const prompt = write(`You are a ${role}.`)
|
|
@@ -42,7 +89,6 @@ const prompt = write(`You are a ${role}.`)
|
|
|
42
89
|
- **Composable** - Build prompts from reusable pieces with `.append()` and `.clone()`
|
|
43
90
|
- **Logical grouping** - Use `.with(builder)` to group related operations
|
|
44
91
|
- **Conditional logic** - Add sections conditionally with `.when(condition, builder)`
|
|
45
|
-
- **Template variables** - Use `{{placeholders}}` and `.fill()` for dynamic content
|
|
46
92
|
- **LLM-optimized** - Built-in `.tag()` for XML delimiters (Claude loves these), `.json()` and `.yaml()` for structured output instructions
|
|
47
93
|
- **Batch operations** - Iterate with `.each()` instead of awkward `.map().join()` chains
|
|
48
94
|
- **Token awareness** - Estimate prompt size with `.tokens()`
|
|
@@ -52,7 +98,8 @@ const prompt = write(`You are a ${role}.`)
|
|
|
52
98
|
### Real-world example
|
|
53
99
|
|
|
54
100
|
```typescript
|
|
55
|
-
import { write
|
|
101
|
+
import { write } from 'prose-writer';
|
|
102
|
+
import { bold, code } from 'prose-writer/markdown';
|
|
56
103
|
|
|
57
104
|
// Define reusable components
|
|
58
105
|
const codeReviewPersona = write('You are a', bold('senior software engineer.')).write(
|
|
@@ -65,6 +112,9 @@ const outputFormat = write('').definitions({
|
|
|
65
112
|
suggestions: 'Recommended improvements',
|
|
66
113
|
});
|
|
67
114
|
|
|
115
|
+
const language = 'TypeScript';
|
|
116
|
+
const framework = 'React';
|
|
117
|
+
|
|
68
118
|
// Build the prompt
|
|
69
119
|
const reviewPrompt = write('')
|
|
70
120
|
.append(codeReviewPersona)
|
|
@@ -78,7 +128,8 @@ const reviewPrompt = write('')
|
|
|
78
128
|
.when(strictMode, (w) => w.write('Be extremely thorough. Miss nothing.'))
|
|
79
129
|
.section('Output Format', (w) => w.append(outputFormat))
|
|
80
130
|
.tag('code', userCode)
|
|
81
|
-
.
|
|
131
|
+
.write('Language:', language)
|
|
132
|
+
.write('Framework:', framework);
|
|
82
133
|
```
|
|
83
134
|
|
|
84
135
|
Stop fighting with template strings. Start writing prompts that are readable, maintainable, and composable.
|
|
@@ -96,10 +147,47 @@ npm install prose-writer
|
|
|
96
147
|
pnpm add prose-writer
|
|
97
148
|
```
|
|
98
149
|
|
|
150
|
+
## Exports
|
|
151
|
+
|
|
152
|
+
Core:
|
|
153
|
+
|
|
154
|
+
```typescript
|
|
155
|
+
import { write, ProseWriter } from 'prose-writer';
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
Markdown utilities:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
import { bold, italic, code, strike, link, image } from 'prose-writer/markdown';
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Validation helpers:
|
|
165
|
+
|
|
166
|
+
```typescript
|
|
167
|
+
import {
|
|
168
|
+
createJsonSchemaValidator,
|
|
169
|
+
createYamlParserAdapter,
|
|
170
|
+
ValidationError,
|
|
171
|
+
} from 'prose-writer/validation';
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Schema types:
|
|
175
|
+
|
|
176
|
+
```typescript
|
|
177
|
+
import type { SchemaEmbedOptions } from 'prose-writer/schema';
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Safe writer:
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
import { write } from 'prose-writer/safe';
|
|
184
|
+
```
|
|
185
|
+
|
|
99
186
|
## Quick Start
|
|
100
187
|
|
|
101
188
|
```typescript
|
|
102
|
-
import { write
|
|
189
|
+
import { write } from 'prose-writer';
|
|
190
|
+
import { bold } from 'prose-writer/markdown';
|
|
103
191
|
|
|
104
192
|
const prompt = write('You are a', bold('helpful assistant.'))
|
|
105
193
|
.write('Please help the user with their request.')
|
|
@@ -122,7 +210,8 @@ Please help the user with their request.
|
|
|
122
210
|
Creates a new `ProseWriter` instance. Multiple arguments are joined with a space, and a newline is added at the end. Can be called with zero arguments to add a blank line between other `write()` calls.
|
|
123
211
|
|
|
124
212
|
```typescript
|
|
125
|
-
import { write
|
|
213
|
+
import { write } from 'prose-writer';
|
|
214
|
+
import { bold, code } from 'prose-writer/markdown';
|
|
126
215
|
|
|
127
216
|
const text = write('Hello', bold('World')).toString();
|
|
128
217
|
```
|
|
@@ -133,6 +222,26 @@ Output:
|
|
|
133
222
|
Hello **World**
|
|
134
223
|
```
|
|
135
224
|
|
|
225
|
+
### `write.safe(...content: string[])`
|
|
226
|
+
|
|
227
|
+
Creates a `ProseWriter` that escapes untrusted input. Safe mode:
|
|
228
|
+
|
|
229
|
+
- Escapes Markdown punctuation and line-leading markers (lists, headings, blockquotes)
|
|
230
|
+
- Escapes XML-sensitive characters (`&`, `<`, `>`) in text and tags
|
|
231
|
+
- Sanitizes link text + destinations
|
|
232
|
+
- Wraps inline code with a backtick fence that can't be broken by user input
|
|
233
|
+
|
|
234
|
+
Use this when inserting user-generated content. To intentionally include raw Markdown, pass a `ProseWriter` instance or call `.raw()` to bypass escaping.
|
|
235
|
+
You can also import a safe-first writer: `import { write } from 'prose-writer/safe'`.
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
const prompt = write
|
|
239
|
+
.safe('User input:', userInput)
|
|
240
|
+
.tag('context', userInput)
|
|
241
|
+
.link('Source', userUrl)
|
|
242
|
+
.toString();
|
|
243
|
+
```
|
|
244
|
+
|
|
136
245
|
You can also start a chain using `write.with()` if you want to use the builder pattern immediately:
|
|
137
246
|
|
|
138
247
|
```typescript
|
|
@@ -150,20 +259,21 @@ Hello **World**
|
|
|
150
259
|
```
|
|
151
260
|
|
|
152
261
|
```typescript
|
|
153
|
-
const
|
|
262
|
+
const multiParagraph = write('First line').write('Second line').toString();
|
|
154
263
|
```
|
|
155
264
|
|
|
156
265
|
Output:
|
|
157
266
|
|
|
158
267
|
```markdown
|
|
159
268
|
First line
|
|
269
|
+
|
|
160
270
|
Second line
|
|
161
271
|
```
|
|
162
272
|
|
|
163
|
-
Adding
|
|
273
|
+
Adding an extra blank line between paragraphs:
|
|
164
274
|
|
|
165
275
|
```typescript
|
|
166
|
-
const
|
|
276
|
+
const spacedParagraphs = write('Paragraph 1').write().write('Paragraph 2').toString();
|
|
167
277
|
```
|
|
168
278
|
|
|
169
279
|
Output:
|
|
@@ -176,7 +286,7 @@ Paragraph 2
|
|
|
176
286
|
|
|
177
287
|
### `.write(...content: string[])`
|
|
178
288
|
|
|
179
|
-
Appends content to the prose. Multiple arguments are joined with a space, and a newline is added at the end.
|
|
289
|
+
Appends content to the prose. Multiple arguments are joined with a space, and a newline is added at the end. Each chained call starts a new paragraph (blank line), so use a single `write()` call when you want one line.
|
|
180
290
|
|
|
181
291
|
```typescript
|
|
182
292
|
write('User:').write('Hello', 'Assistant').toString();
|
|
@@ -189,6 +299,18 @@ User:
|
|
|
189
299
|
Hello Assistant
|
|
190
300
|
```
|
|
191
301
|
|
|
302
|
+
Same line by passing multiple strings:
|
|
303
|
+
|
|
304
|
+
```typescript
|
|
305
|
+
write('User:', 'Hello', 'Assistant').toString();
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
Output:
|
|
309
|
+
|
|
310
|
+
```markdown
|
|
311
|
+
User: Hello Assistant
|
|
312
|
+
```
|
|
313
|
+
|
|
192
314
|
### Inline Utilities
|
|
193
315
|
|
|
194
316
|
The following utilities return formatted strings and can be used within `write()` calls or anywhere else.
|
|
@@ -202,7 +324,8 @@ The following utilities return formatted strings and can be used within `write()
|
|
|
202
324
|
- `image(alt: string, url: string)` - ``
|
|
203
325
|
|
|
204
326
|
```typescript
|
|
205
|
-
import { write
|
|
327
|
+
import { write } from 'prose-writer';
|
|
328
|
+
import { bold, italic, code, link } from 'prose-writer/markdown';
|
|
206
329
|
|
|
207
330
|
write(
|
|
208
331
|
'Check out',
|
|
@@ -218,21 +341,6 @@ write(
|
|
|
218
341
|
|
|
219
342
|
Obviously, you can just write regular Markdown here as well.
|
|
220
343
|
|
|
221
|
-
### `.nextLine()`
|
|
222
|
-
|
|
223
|
-
Prevents the next block element or `write()` call from adding a paragraph break. Useful for placing content on consecutive lines.
|
|
224
|
-
|
|
225
|
-
```typescript
|
|
226
|
-
write('Line 1').nextLine().write('Line 2').toString();
|
|
227
|
-
```
|
|
228
|
-
|
|
229
|
-
Output:
|
|
230
|
-
|
|
231
|
-
```markdown
|
|
232
|
-
Line 1
|
|
233
|
-
Line 2
|
|
234
|
-
```
|
|
235
|
-
|
|
236
344
|
### `.unorderedList(...items: string[] | number[] | boolean[] | ProseWriter[])`
|
|
237
345
|
|
|
238
346
|
### `.list(...items: string[] | number[] | boolean[] | ProseWriter[])`
|
|
@@ -552,7 +660,7 @@ Section 1
|
|
|
552
660
|
Section 2
|
|
553
661
|
```
|
|
554
662
|
|
|
555
|
-
### `.json(data: unknown)`
|
|
663
|
+
### `.json(data: unknown, options?: ValidationOptions)`
|
|
556
664
|
|
|
557
665
|
Appends a JSON code block. If the data is not a string, it will be stringified with formatting.
|
|
558
666
|
|
|
@@ -587,6 +695,17 @@ Output:
|
|
|
587
695
|
```
|
|
588
696
|
````
|
|
589
697
|
|
|
698
|
+
You can pass validation hooks via `options`:
|
|
699
|
+
|
|
700
|
+
```typescript
|
|
701
|
+
write('').json(data, {
|
|
702
|
+
schema: outputSchema,
|
|
703
|
+
validate: ({ format, data, schema }) => {
|
|
704
|
+
// return { valid: true } or { valid: false, issues: [...] }
|
|
705
|
+
},
|
|
706
|
+
});
|
|
707
|
+
```
|
|
708
|
+
|
|
590
709
|
### `.append(writer: ProseWriter)`
|
|
591
710
|
|
|
592
711
|
Appends the content from another `ProseWriter` instance. Enables composition of prompts from reusable pieces.
|
|
@@ -694,7 +813,8 @@ function.
|
|
|
694
813
|
// Recommended:
|
|
695
814
|
|
|
696
815
|
```typescript
|
|
697
|
-
import { write
|
|
816
|
+
import { write } from 'prose-writer';
|
|
817
|
+
import { code } from 'prose-writer/markdown';
|
|
698
818
|
write('Use the', code('calculateTotal'), 'function.').toString();
|
|
699
819
|
```
|
|
700
820
|
|
|
@@ -704,21 +824,6 @@ Output:
|
|
|
704
824
|
Use the `calculateTotal` function.
|
|
705
825
|
```
|
|
706
826
|
|
|
707
|
-
### `.fill(variables: Record<string, string>)`
|
|
708
|
-
|
|
709
|
-
Replaces template variables in the format `{{variableName}}` with provided values. Returns a new `ProseWriter` with the substitutions applied (does not modify the original).
|
|
710
|
-
|
|
711
|
-
```typescript
|
|
712
|
-
const template = write('Hello, {{name}}! Welcome to {{place}}.');
|
|
713
|
-
const result = template.fill({ name: 'Alice', place: 'Wonderland' }).toString();
|
|
714
|
-
```
|
|
715
|
-
|
|
716
|
-
Output:
|
|
717
|
-
|
|
718
|
-
```markdown
|
|
719
|
-
Hello, Alice! Welcome to Wonderland.
|
|
720
|
-
```
|
|
721
|
-
|
|
722
827
|
### `.section(name: string, builder: (writer) => void, level?: 1-6)`
|
|
723
828
|
|
|
724
829
|
Creates a semantic section with a heading and content built by the builder function. The optional `level` parameter defaults to 2.
|
|
@@ -815,7 +920,8 @@ information.
|
|
|
815
920
|
// Recommended:
|
|
816
921
|
|
|
817
922
|
```typescript
|
|
818
|
-
import { write
|
|
923
|
+
import { write } from 'prose-writer';
|
|
924
|
+
import { bold } from 'prose-writer/markdown';
|
|
819
925
|
write('This is', bold('important'), 'information.').toString();
|
|
820
926
|
```
|
|
821
927
|
|
|
@@ -844,7 +950,8 @@ the following.
|
|
|
844
950
|
// Recommended:
|
|
845
951
|
|
|
846
952
|
```typescript
|
|
847
|
-
import { write
|
|
953
|
+
import { write } from 'prose-writer';
|
|
954
|
+
import { italic } from 'prose-writer/markdown';
|
|
848
955
|
write('Please', italic('note'), 'the following.').toString();
|
|
849
956
|
```
|
|
850
957
|
|
|
@@ -893,7 +1000,8 @@ New
|
|
|
893
1000
|
// Recommended:
|
|
894
1001
|
|
|
895
1002
|
```typescript
|
|
896
|
-
import { write
|
|
1003
|
+
import { write } from 'prose-writer';
|
|
1004
|
+
import { strike } from 'prose-writer/markdown';
|
|
897
1005
|
write('Price:', strike('$100'), '$80').toString();
|
|
898
1006
|
```
|
|
899
1007
|
|
|
@@ -949,7 +1057,8 @@ for details.
|
|
|
949
1057
|
// Recommended:
|
|
950
1058
|
|
|
951
1059
|
```typescript
|
|
952
|
-
import { write
|
|
1060
|
+
import { write } from 'prose-writer';
|
|
1061
|
+
import { link } from 'prose-writer/markdown';
|
|
953
1062
|
write('See the', link('documentation', 'https://example.com'), 'for details.').toString();
|
|
954
1063
|
```
|
|
955
1064
|
|
|
@@ -959,7 +1068,7 @@ Output:
|
|
|
959
1068
|
See the [documentation](https://example.com) for details.
|
|
960
1069
|
```
|
|
961
1070
|
|
|
962
|
-
### `.yaml(data: unknown)`
|
|
1071
|
+
### `.yaml(data: unknown, options?: ValidationOptions)`
|
|
963
1072
|
|
|
964
1073
|
Appends a YAML code block. If data is not a string, it will be converted to YAML format.
|
|
965
1074
|
|
|
@@ -996,6 +1105,74 @@ Wraps content with custom delimiters. Useful for models that respond to specific
|
|
|
996
1105
|
write('Input:').delimit('###', '###', 'content here').toString();
|
|
997
1106
|
```
|
|
998
1107
|
|
|
1108
|
+
### Structured Output Validation
|
|
1109
|
+
|
|
1110
|
+
`json()` and `yaml()` accept a `validate` hook. If validation fails, a `ValidationError` is thrown with diagnostic details.
|
|
1111
|
+
When validating JSON, string inputs are parsed first and will throw a `ValidationError` if they are invalid JSON. For YAML, you can supply a parser via `parseYaml` to parse strings before validation.
|
|
1112
|
+
|
|
1113
|
+
```typescript
|
|
1114
|
+
import type { OutputValidator } from 'prose-writer/validation';
|
|
1115
|
+
|
|
1116
|
+
const validate: OutputValidator = ({ format, data, schema }) => {
|
|
1117
|
+
if (format !== 'json') return { valid: true };
|
|
1118
|
+
if (!schema) return { valid: true };
|
|
1119
|
+
// Your validation logic here
|
|
1120
|
+
return { valid: true };
|
|
1121
|
+
};
|
|
1122
|
+
|
|
1123
|
+
write('').json(payload, { schema: outputSchema, validate });
|
|
1124
|
+
```
|
|
1125
|
+
|
|
1126
|
+
For YAML string inputs, pass a parser adapter:
|
|
1127
|
+
|
|
1128
|
+
```typescript
|
|
1129
|
+
import { parse as parseYaml } from 'yaml';
|
|
1130
|
+
import { createYamlParserAdapter } from 'prose-writer/validation';
|
|
1131
|
+
|
|
1132
|
+
write('').yaml(payloadString, {
|
|
1133
|
+
validate,
|
|
1134
|
+
parseYaml: createYamlParserAdapter(parseYaml),
|
|
1135
|
+
});
|
|
1136
|
+
```
|
|
1137
|
+
|
|
1138
|
+
#### JSON Schema via Adapter
|
|
1139
|
+
|
|
1140
|
+
`prose-writer` stays zero-deps, but you can plug in Ajv (or any validator) through an adapter.
|
|
1141
|
+
|
|
1142
|
+
```typescript
|
|
1143
|
+
import Ajv from 'ajv';
|
|
1144
|
+
import { createJsonSchemaValidator } from 'prose-writer/validation';
|
|
1145
|
+
|
|
1146
|
+
const ajv = new Ajv();
|
|
1147
|
+
const validate = createJsonSchemaValidator((schema, data) => {
|
|
1148
|
+
const valid = ajv.validate(schema, data);
|
|
1149
|
+
if (valid) return { valid: true };
|
|
1150
|
+
return {
|
|
1151
|
+
valid: false,
|
|
1152
|
+
issues: (ajv.errors ?? []).map((error) => ({
|
|
1153
|
+
path: error.instancePath || '$',
|
|
1154
|
+
message: error.message ?? 'Invalid value',
|
|
1155
|
+
})),
|
|
1156
|
+
};
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1159
|
+
write('').json(payload, { schema: outputSchema, validate });
|
|
1160
|
+
```
|
|
1161
|
+
|
|
1162
|
+
#### Embedding Schemas in Prompts
|
|
1163
|
+
|
|
1164
|
+
```typescript
|
|
1165
|
+
write('Return JSON that matches this schema:')
|
|
1166
|
+
.schema(outputSchema, { title: 'Output Schema', tag: 'output_schema' })
|
|
1167
|
+
.toString();
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
Recommended usage:
|
|
1171
|
+
|
|
1172
|
+
- Prefer JSON Schema for structured output formats.
|
|
1173
|
+
- Store schemas alongside prompt builders and include them in the prompt with `.schema()`.
|
|
1174
|
+
- Validate the object you send or receive, not just the stringified output.
|
|
1175
|
+
|
|
999
1176
|
### `.compact()`
|
|
1000
1177
|
|
|
1001
1178
|
Returns a new ProseWriter with consecutive newlines (3+) collapsed to double newlines.
|
|
@@ -1080,7 +1257,8 @@ Features:
|
|
|
1080
1257
|
Converts the prose to plain text by stripping all markdown formatting.
|
|
1081
1258
|
|
|
1082
1259
|
```typescript
|
|
1083
|
-
import { write
|
|
1260
|
+
import { write } from 'prose-writer';
|
|
1261
|
+
import { bold } from 'prose-writer/markdown';
|
|
1084
1262
|
|
|
1085
1263
|
const prose = write('')
|
|
1086
1264
|
.heading(1, 'Title')
|
|
@@ -1111,17 +1289,6 @@ const conclusion = write('').heading(2, 'Conclusion').write('Summary');
|
|
|
1111
1289
|
const document = ProseWriter.join(intro, body, conclusion);
|
|
1112
1290
|
```
|
|
1113
1291
|
|
|
1114
|
-
### `ProseWriter.fromTemplate(template: string)`
|
|
1115
|
-
|
|
1116
|
-
Static method that creates a ProseWriter from a template string.
|
|
1117
|
-
|
|
1118
|
-
```typescript
|
|
1119
|
-
const prompt = ProseWriter.fromTemplate('Hello {{name}}, your role is {{role}}.').fill({
|
|
1120
|
-
name: 'Alice',
|
|
1121
|
-
role: 'developer',
|
|
1122
|
-
});
|
|
1123
|
-
```
|
|
1124
|
-
|
|
1125
1292
|
### `.toString()`
|
|
1126
1293
|
|
|
1127
1294
|
Converts the accumulated prose to a string.
|
|
@@ -1248,48 +1415,13 @@ const userPrompt = write('Please review the following code:')
|
|
|
1248
1415
|
.toString();
|
|
1249
1416
|
```
|
|
1250
1417
|
|
|
1251
|
-
## Prompt
|
|
1418
|
+
## Prompt Variations
|
|
1252
1419
|
|
|
1253
|
-
Use `
|
|
1420
|
+
Use `clone()` to create variations without mutating the original prompt:
|
|
1254
1421
|
|
|
1255
1422
|
```typescript
|
|
1256
1423
|
import { write } from 'prose-writer';
|
|
1257
1424
|
|
|
1258
|
-
// Create a reusable template
|
|
1259
|
-
const promptTemplate = write('You are a {{role}}.')
|
|
1260
|
-
.section('Task', (w) => {
|
|
1261
|
-
w.write('Help the user with {{task}}.');
|
|
1262
|
-
})
|
|
1263
|
-
.section('Guidelines', (w) => {
|
|
1264
|
-
w.list('Be {{style}}', 'Focus on {{focus}}');
|
|
1265
|
-
})
|
|
1266
|
-
.section('Output', (w) => {
|
|
1267
|
-
w.table(
|
|
1268
|
-
['Format', 'When to use'],
|
|
1269
|
-
[
|
|
1270
|
-
['Code blocks', 'For code examples'],
|
|
1271
|
-
['Bullet points', 'For lists of items'],
|
|
1272
|
-
['Tables', 'For structured data'],
|
|
1273
|
-
],
|
|
1274
|
-
);
|
|
1275
|
-
});
|
|
1276
|
-
|
|
1277
|
-
// Create variations for different use cases
|
|
1278
|
-
const codeReviewPrompt = promptTemplate.fill({
|
|
1279
|
-
role: 'senior software engineer',
|
|
1280
|
-
task: 'code review',
|
|
1281
|
-
style: 'thorough and constructive',
|
|
1282
|
-
focus: 'code quality and best practices',
|
|
1283
|
-
});
|
|
1284
|
-
|
|
1285
|
-
const debuggingPrompt = promptTemplate.fill({
|
|
1286
|
-
role: 'debugging expert',
|
|
1287
|
-
task: 'finding and fixing bugs',
|
|
1288
|
-
style: 'systematic and methodical',
|
|
1289
|
-
focus: 'root cause analysis',
|
|
1290
|
-
});
|
|
1291
|
-
|
|
1292
|
-
// Or use clone() for structural variations
|
|
1293
1425
|
const basePrompt = write('You are an AI assistant.').section('Core Guidelines', (w) => {
|
|
1294
1426
|
w.list('Be helpful', 'Be accurate');
|
|
1295
1427
|
});
|
package/dist/index.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export { ProseWriter, write } from './prose-writer';
|