@anythingai/teleprompt 0.1.1 → 0.3.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.
package/dist/index.d.cts CHANGED
@@ -1,12 +1,15 @@
1
- import { P as PromptContext, a as PromptSection } from './types-DXgCksVT.cjs';
1
+ import { P as PromptContext, a as PromptSection } from './types-ow-XbrO7.cjs';
2
2
 
3
+ type PromptFormat = 'text' | 'xml';
4
+ interface BuildOptions {
5
+ /**
6
+ * - `'text'` (default) — sections joined with `\n\n`, groups are transparent.
7
+ * - `'xml'` — each section wrapped in `<id>...</id>` tags, groups
8
+ * wrapped in `<id>...</id>` containing their children.
9
+ */
10
+ format?: PromptFormat;
11
+ }
3
12
  /**
4
- * Declarative, composable prompt builder.
5
- *
6
- * Prompts are composed from discrete {@link PromptSection}s that are
7
- * independently testable pure functions. The builder handles ordering,
8
- * conditional inclusion, and final assembly.
9
- *
10
13
  * @example
11
14
  * ```ts
12
15
  * const prompt = new PromptBuilder()
@@ -16,61 +19,72 @@ import { P as PromptContext, a as PromptSection } from './types-DXgCksVT.cjs';
16
19
  * .build(ctx);
17
20
  * ```
18
21
  */
19
- declare class PromptBuilder<TCtx extends PromptContext<Record<string, boolean>, Record<string, unknown>>> {
20
- private sections;
22
+ declare class PromptBuilder<TCtx extends PromptContext = PromptContext> {
23
+ private nodes;
24
+ /** Replaces an existing section with the same id. */
25
+ use(section: PromptSection<TCtx>): this;
26
+ /**
27
+ * First candidate that renders a non-empty string wins.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * builder.useOneOf(activeTasks, noActiveTasks)
32
+ * ```
33
+ */
34
+ useOneOf(...candidates: PromptSection<TCtx>[]): this;
21
35
  /**
22
- * Add a section to the prompt.
36
+ * In `xml` format, wraps children in `<id>` tags. Transparent in `text` format.
23
37
  *
24
- * If a section with the same `id` already exists, it is replaced.
25
- * This makes `.use()` idempotent — you can safely call it multiple
26
- * times with the same section without creating duplicates.
38
+ * @example
39
+ * ```ts
40
+ * builder.group('tools', b => b
41
+ * .use(bashSection)
42
+ * .use(gitSection)
43
+ * )
44
+ * ```
27
45
  */
28
- use(section: PromptSection<TCtx>): this;
29
- /** Remove a section. Accepts an id string or a section object. */
46
+ group(id: string, configure: (builder: PromptBuilder<TCtx>) => void): this;
47
+ /** Searches recursively into groups and oneOf candidates. */
30
48
  without(ref: string | {
31
49
  id: string;
32
50
  }): this;
33
- /** Check if a section exists. Accepts an id string or a section object. */
51
+ /** Searches recursively into groups and oneOf candidates. */
34
52
  has(ref: string | {
35
53
  id: string;
36
54
  }): boolean;
37
- /** Get the ids of all registered sections (in insertion order). */
38
55
  ids(): string[];
39
56
  /**
40
- * Create an independent copy of this builder.
41
- *
42
- * Use this to create mode-specific or model-specific variants
43
- * without mutating the base builder.
57
+ * Creates an independent copy. Modifications to the fork don't affect the original.
44
58
  *
45
59
  * @example
46
60
  * ```ts
47
61
  * const base = new PromptBuilder().use(a).use(b);
48
- * const variant = base.fork().use(c); // base is unchanged
62
+ * const variant = base.fork().use(c);
49
63
  * ```
50
64
  */
51
65
  fork(): PromptBuilder<TCtx>;
52
- /**
53
- * Build the final prompt string.
54
- *
55
- * 1. Filters out sections whose `when` guard returns false
56
- * 2. Renders each section
57
- * 3. Filters out empty strings
58
- * 4. Joins with separator and trims
59
- */
60
- build(ctx: TCtx): string;
61
- /**
62
- * Build the prompt and return metadata about which sections were
63
- * included/excluded. Useful for debugging and logging.
64
- *
65
- * A section is "excluded" if its `when` guard returns false.
66
- * A section is "included" only if it passes the guard and renders
67
- * a non-empty string.
68
- */
69
- buildWithMeta(ctx: TCtx): {
66
+ build(ctx: TCtx, options?: BuildOptions): string;
67
+ /** Like `build`, but also returns which section ids were included/excluded. */
68
+ buildWithMeta(ctx: TCtx, options?: BuildOptions): {
70
69
  prompt: string;
71
70
  included: string[];
72
71
  excluded: string[];
73
72
  };
74
73
  }
75
74
 
76
- export { PromptBuilder, PromptContext, PromptSection };
75
+ /**
76
+ * Create a prompt section. Return a string to include, `null` to exclude.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * section('identity', () => 'You are Coworker.')
81
+ *
82
+ * section('prod', (ctx: SandboxCtx) => {
83
+ * if (ctx.vars.prodContext == null) return null;
84
+ * return `## Prod\n\n${ctx.vars.prodContext}`;
85
+ * })
86
+ * ```
87
+ */
88
+ declare function section<TCtx extends PromptContext = PromptContext>(id: string, render: (ctx: TCtx) => string | null): PromptSection<TCtx>;
89
+
90
+ export { type BuildOptions, PromptBuilder, PromptContext, type PromptFormat, PromptSection, section };
package/dist/index.d.ts CHANGED
@@ -1,12 +1,15 @@
1
- import { P as PromptContext, a as PromptSection } from './types-DXgCksVT.js';
1
+ import { P as PromptContext, a as PromptSection } from './types-ow-XbrO7.js';
2
2
 
3
+ type PromptFormat = 'text' | 'xml';
4
+ interface BuildOptions {
5
+ /**
6
+ * - `'text'` (default) — sections joined with `\n\n`, groups are transparent.
7
+ * - `'xml'` — each section wrapped in `<id>...</id>` tags, groups
8
+ * wrapped in `<id>...</id>` containing their children.
9
+ */
10
+ format?: PromptFormat;
11
+ }
3
12
  /**
4
- * Declarative, composable prompt builder.
5
- *
6
- * Prompts are composed from discrete {@link PromptSection}s that are
7
- * independently testable pure functions. The builder handles ordering,
8
- * conditional inclusion, and final assembly.
9
- *
10
13
  * @example
11
14
  * ```ts
12
15
  * const prompt = new PromptBuilder()
@@ -16,61 +19,72 @@ import { P as PromptContext, a as PromptSection } from './types-DXgCksVT.js';
16
19
  * .build(ctx);
17
20
  * ```
18
21
  */
19
- declare class PromptBuilder<TCtx extends PromptContext<Record<string, boolean>, Record<string, unknown>>> {
20
- private sections;
22
+ declare class PromptBuilder<TCtx extends PromptContext = PromptContext> {
23
+ private nodes;
24
+ /** Replaces an existing section with the same id. */
25
+ use(section: PromptSection<TCtx>): this;
26
+ /**
27
+ * First candidate that renders a non-empty string wins.
28
+ *
29
+ * @example
30
+ * ```ts
31
+ * builder.useOneOf(activeTasks, noActiveTasks)
32
+ * ```
33
+ */
34
+ useOneOf(...candidates: PromptSection<TCtx>[]): this;
21
35
  /**
22
- * Add a section to the prompt.
36
+ * In `xml` format, wraps children in `<id>` tags. Transparent in `text` format.
23
37
  *
24
- * If a section with the same `id` already exists, it is replaced.
25
- * This makes `.use()` idempotent — you can safely call it multiple
26
- * times with the same section without creating duplicates.
38
+ * @example
39
+ * ```ts
40
+ * builder.group('tools', b => b
41
+ * .use(bashSection)
42
+ * .use(gitSection)
43
+ * )
44
+ * ```
27
45
  */
28
- use(section: PromptSection<TCtx>): this;
29
- /** Remove a section. Accepts an id string or a section object. */
46
+ group(id: string, configure: (builder: PromptBuilder<TCtx>) => void): this;
47
+ /** Searches recursively into groups and oneOf candidates. */
30
48
  without(ref: string | {
31
49
  id: string;
32
50
  }): this;
33
- /** Check if a section exists. Accepts an id string or a section object. */
51
+ /** Searches recursively into groups and oneOf candidates. */
34
52
  has(ref: string | {
35
53
  id: string;
36
54
  }): boolean;
37
- /** Get the ids of all registered sections (in insertion order). */
38
55
  ids(): string[];
39
56
  /**
40
- * Create an independent copy of this builder.
41
- *
42
- * Use this to create mode-specific or model-specific variants
43
- * without mutating the base builder.
57
+ * Creates an independent copy. Modifications to the fork don't affect the original.
44
58
  *
45
59
  * @example
46
60
  * ```ts
47
61
  * const base = new PromptBuilder().use(a).use(b);
48
- * const variant = base.fork().use(c); // base is unchanged
62
+ * const variant = base.fork().use(c);
49
63
  * ```
50
64
  */
51
65
  fork(): PromptBuilder<TCtx>;
52
- /**
53
- * Build the final prompt string.
54
- *
55
- * 1. Filters out sections whose `when` guard returns false
56
- * 2. Renders each section
57
- * 3. Filters out empty strings
58
- * 4. Joins with separator and trims
59
- */
60
- build(ctx: TCtx): string;
61
- /**
62
- * Build the prompt and return metadata about which sections were
63
- * included/excluded. Useful for debugging and logging.
64
- *
65
- * A section is "excluded" if its `when` guard returns false.
66
- * A section is "included" only if it passes the guard and renders
67
- * a non-empty string.
68
- */
69
- buildWithMeta(ctx: TCtx): {
66
+ build(ctx: TCtx, options?: BuildOptions): string;
67
+ /** Like `build`, but also returns which section ids were included/excluded. */
68
+ buildWithMeta(ctx: TCtx, options?: BuildOptions): {
70
69
  prompt: string;
71
70
  included: string[];
72
71
  excluded: string[];
73
72
  };
74
73
  }
75
74
 
76
- export { PromptBuilder, PromptContext, PromptSection };
75
+ /**
76
+ * Create a prompt section. Return a string to include, `null` to exclude.
77
+ *
78
+ * @example
79
+ * ```ts
80
+ * section('identity', () => 'You are Coworker.')
81
+ *
82
+ * section('prod', (ctx: SandboxCtx) => {
83
+ * if (ctx.vars.prodContext == null) return null;
84
+ * return `## Prod\n\n${ctx.vars.prodContext}`;
85
+ * })
86
+ * ```
87
+ */
88
+ declare function section<TCtx extends PromptContext = PromptContext>(id: string, render: (ctx: TCtx) => string | null): PromptSection<TCtx>;
89
+
90
+ export { type BuildOptions, PromptBuilder, PromptContext, type PromptFormat, PromptSection, section };
package/dist/index.js CHANGED
@@ -1,95 +1,238 @@
1
1
  // src/builder.ts
2
2
  var PromptBuilder = class _PromptBuilder {
3
- sections = [];
3
+ nodes = [];
4
+ /** Replaces an existing section with the same id. */
5
+ use(section2) {
6
+ const idx = this.nodes.findIndex((n) => !isOneOf(n) && n.id === section2.id);
7
+ if (idx >= 0) {
8
+ this.nodes[idx] = section2;
9
+ } else {
10
+ this.nodes.push(section2);
11
+ }
12
+ return this;
13
+ }
14
+ /**
15
+ * First candidate that renders a non-empty string wins.
16
+ *
17
+ * @example
18
+ * ```ts
19
+ * builder.useOneOf(activeTasks, noActiveTasks)
20
+ * ```
21
+ */
22
+ useOneOf(...candidates) {
23
+ this.nodes.push({ candidates });
24
+ return this;
25
+ }
4
26
  /**
5
- * Add a section to the prompt.
27
+ * In `xml` format, wraps children in `<id>` tags. Transparent in `text` format.
6
28
  *
7
- * If a section with the same `id` already exists, it is replaced.
8
- * This makes `.use()` idempotent — you can safely call it multiple
9
- * times with the same section without creating duplicates.
29
+ * @example
30
+ * ```ts
31
+ * builder.group('tools', b => b
32
+ * .use(bashSection)
33
+ * .use(gitSection)
34
+ * )
35
+ * ```
10
36
  */
11
- use(section) {
12
- const existingIdx = this.sections.findIndex((s) => s.id === section.id);
13
- if (existingIdx >= 0) {
14
- this.sections[existingIdx] = section;
37
+ group(id, configure) {
38
+ const inner = new _PromptBuilder();
39
+ configure(inner);
40
+ const group = { id, children: inner.nodes };
41
+ const idx = this.nodes.findIndex((n) => !isOneOf(n) && n.id === id);
42
+ if (idx >= 0) {
43
+ this.nodes[idx] = group;
15
44
  } else {
16
- this.sections.push(section);
45
+ this.nodes.push(group);
17
46
  }
18
47
  return this;
19
48
  }
20
- /** Remove a section. Accepts an id string or a section object. */
49
+ /** Searches recursively into groups and oneOf candidates. */
21
50
  without(ref) {
22
51
  const id = typeof ref === "string" ? ref : ref.id;
23
- this.sections = this.sections.filter((s) => s.id !== id);
52
+ this.nodes = removeNode(this.nodes, id);
24
53
  return this;
25
54
  }
26
- /** Check if a section exists. Accepts an id string or a section object. */
55
+ /** Searches recursively into groups and oneOf candidates. */
27
56
  has(ref) {
28
57
  const id = typeof ref === "string" ? ref : ref.id;
29
- return this.sections.some((s) => s.id === id);
58
+ return hasNode(this.nodes, id);
30
59
  }
31
- /** Get the ids of all registered sections (in insertion order). */
32
60
  ids() {
33
- return this.sections.map((s) => s.id);
61
+ return collectIds(this.nodes);
34
62
  }
35
63
  /**
36
- * Create an independent copy of this builder.
37
- *
38
- * Use this to create mode-specific or model-specific variants
39
- * without mutating the base builder.
64
+ * Creates an independent copy. Modifications to the fork don't affect the original.
40
65
  *
41
66
  * @example
42
67
  * ```ts
43
68
  * const base = new PromptBuilder().use(a).use(b);
44
- * const variant = base.fork().use(c); // base is unchanged
69
+ * const variant = base.fork().use(c);
45
70
  * ```
46
71
  */
47
72
  fork() {
48
73
  const forked = new _PromptBuilder();
49
- forked.sections = [...this.sections];
74
+ forked.nodes = deepCopy(this.nodes);
50
75
  return forked;
51
76
  }
52
- /**
53
- * Build the final prompt string.
54
- *
55
- * 1. Filters out sections whose `when` guard returns false
56
- * 2. Renders each section
57
- * 3. Filters out empty strings
58
- * 4. Joins with separator and trims
59
- */
60
- build(ctx) {
61
- return this.buildWithMeta(ctx).prompt;
77
+ build(ctx, options) {
78
+ return this.buildWithMeta(ctx, options).prompt;
62
79
  }
63
- /**
64
- * Build the prompt and return metadata about which sections were
65
- * included/excluded. Useful for debugging and logging.
66
- *
67
- * A section is "excluded" if its `when` guard returns false.
68
- * A section is "included" only if it passes the guard and renders
69
- * a non-empty string.
70
- */
71
- buildWithMeta(ctx) {
80
+ /** Like `build`, but also returns which section ids were included/excluded. */
81
+ buildWithMeta(ctx, options) {
72
82
  const included = [];
73
83
  const excluded = [];
74
- const rendered = this.sections.filter((s) => {
75
- if (s.when && !s.when(ctx)) {
76
- excluded.push(s.id);
77
- return false;
84
+ const format = options?.format ?? "text";
85
+ const parts = renderNodes(this.nodes, ctx, format, included, excluded);
86
+ const prompt = parts.join("\n\n").trim();
87
+ return { prompt, included, excluded };
88
+ }
89
+ };
90
+ function isSection(node) {
91
+ return "render" in node;
92
+ }
93
+ function isGroup(node) {
94
+ return "children" in node;
95
+ }
96
+ function isOneOf(node) {
97
+ return "candidates" in node;
98
+ }
99
+ function assertNever(value) {
100
+ throw new Error(`Unexpected format: ${value}`);
101
+ }
102
+ function formatSection(id, content, format) {
103
+ switch (format) {
104
+ case "text":
105
+ return content;
106
+ case "xml":
107
+ return `<${id}>
108
+ ${content}
109
+ </${id}>`;
110
+ default:
111
+ return assertNever(format);
112
+ }
113
+ }
114
+ function formatGroup(id, childParts, format) {
115
+ switch (format) {
116
+ case "text":
117
+ return childParts;
118
+ case "xml":
119
+ return [`<${id}>
120
+ ${childParts.join("\n\n")}
121
+ </${id}>`];
122
+ default:
123
+ return assertNever(format);
124
+ }
125
+ }
126
+ function renderSection(section2, ctx, format, parts, included, excluded) {
127
+ if (section2.when && !section2.when(ctx)) {
128
+ excluded.push(section2.id);
129
+ return false;
130
+ }
131
+ const output = section2.render(ctx);
132
+ if (output) {
133
+ included.push(section2.id);
134
+ parts.push(formatSection(section2.id, output, format));
135
+ return true;
136
+ }
137
+ excluded.push(section2.id);
138
+ return false;
139
+ }
140
+ function renderOneOf(node, ctx, format, parts, included, excluded) {
141
+ let found = false;
142
+ for (const candidate of node.candidates) {
143
+ if (found) {
144
+ excluded.push(candidate.id);
145
+ continue;
146
+ }
147
+ if (renderSection(candidate, ctx, format, parts, included, excluded)) {
148
+ found = true;
149
+ }
150
+ }
151
+ }
152
+ function renderNodes(nodes, ctx, format, included, excluded) {
153
+ const parts = [];
154
+ for (const node of nodes) {
155
+ if (isSection(node)) {
156
+ renderSection(node, ctx, format, parts, included, excluded);
157
+ } else if (isGroup(node)) {
158
+ const childParts = renderNodes(node.children, ctx, format, included, excluded);
159
+ if (childParts.length > 0) {
160
+ parts.push(...formatGroup(node.id, childParts, format));
78
161
  }
79
- return true;
80
- }).map((s) => {
81
- const output = s.render(ctx);
82
- if (output) {
83
- included.push(s.id);
84
- } else {
85
- excluded.push(s.id);
162
+ } else {
163
+ renderOneOf(node, ctx, format, parts, included, excluded);
164
+ }
165
+ }
166
+ return parts;
167
+ }
168
+ function hasNode(nodes, id) {
169
+ for (const node of nodes) {
170
+ if (isSection(node)) {
171
+ if (node.id === id) return true;
172
+ } else if (isGroup(node)) {
173
+ if (node.id === id) return true;
174
+ if (hasNode(node.children, id)) return true;
175
+ } else {
176
+ for (const c of node.candidates) {
177
+ if (c.id === id) return true;
86
178
  }
87
- return output;
88
- }).filter(Boolean).join("\n\n").trim();
89
- return { prompt: rendered, included, excluded };
179
+ }
90
180
  }
91
- };
181
+ return false;
182
+ }
183
+ function removeNode(nodes, id) {
184
+ const result = [];
185
+ for (const n of nodes) {
186
+ if (isSection(n)) {
187
+ if (n.id !== id) result.push(n);
188
+ } else if (isGroup(n)) {
189
+ if (n.id !== id) {
190
+ result.push({ ...n, children: removeNode(n.children, id) });
191
+ }
192
+ } else {
193
+ const remaining = n.candidates.filter((c) => c.id !== id);
194
+ if (remaining.length > 0) {
195
+ result.push({ candidates: remaining });
196
+ }
197
+ }
198
+ }
199
+ return result;
200
+ }
201
+ function collectIds(nodes) {
202
+ const ids = [];
203
+ for (const node of nodes) {
204
+ if (isSection(node)) {
205
+ ids.push(node.id);
206
+ } else if (isGroup(node)) {
207
+ ids.push(node.id);
208
+ ids.push(...collectIds(node.children));
209
+ } else {
210
+ ids.push(...node.candidates.map((c) => c.id));
211
+ }
212
+ }
213
+ return ids;
214
+ }
215
+ function deepCopy(nodes) {
216
+ return nodes.map((n) => {
217
+ if (isGroup(n)) {
218
+ return { ...n, children: deepCopy(n.children) };
219
+ }
220
+ if (isOneOf(n)) {
221
+ return { candidates: [...n.candidates] };
222
+ }
223
+ return n;
224
+ });
225
+ }
226
+
227
+ // src/section.ts
228
+ function section(id, render) {
229
+ return {
230
+ id,
231
+ render: (ctx) => render(ctx) ?? ""
232
+ };
233
+ }
92
234
  export {
93
- PromptBuilder
235
+ PromptBuilder,
236
+ section
94
237
  };
95
238
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/builder.ts"],"sourcesContent":["import type { PromptContext, PromptSection } from './types';\n\n/**\n * Declarative, composable prompt builder.\n *\n * Prompts are composed from discrete {@link PromptSection}s that are\n * independently testable pure functions. The builder handles ordering,\n * conditional inclusion, and final assembly.\n *\n * @example\n * ```ts\n * const prompt = new PromptBuilder()\n * .use(identitySection)\n * .use(rulesSection)\n * .use(featureSection)\n * .build(ctx);\n * ```\n */\nexport class PromptBuilder<\n TCtx extends PromptContext<Record<string, boolean>, Record<string, unknown>>,\n> {\n private sections: PromptSection<TCtx>[] = [];\n\n /**\n * Add a section to the prompt.\n *\n * If a section with the same `id` already exists, it is replaced.\n * This makes `.use()` idempotent — you can safely call it multiple\n * times with the same section without creating duplicates.\n */\n use(section: PromptSection<TCtx>): this {\n const existingIdx = this.sections.findIndex((s) => s.id === section.id);\n if (existingIdx >= 0) {\n this.sections[existingIdx] = section;\n } else {\n this.sections.push(section);\n }\n return this;\n }\n\n /** Remove a section. Accepts an id string or a section object. */\n without(ref: string | { id: string }): this {\n const id = typeof ref === 'string' ? ref : ref.id;\n this.sections = this.sections.filter((s) => s.id !== id);\n return this;\n }\n\n /** Check if a section exists. Accepts an id string or a section object. */\n has(ref: string | { id: string }): boolean {\n const id = typeof ref === 'string' ? ref : ref.id;\n return this.sections.some((s) => s.id === id);\n }\n\n /** Get the ids of all registered sections (in insertion order). */\n ids(): string[] {\n return this.sections.map((s) => s.id);\n }\n\n /**\n * Create an independent copy of this builder.\n *\n * Use this to create mode-specific or model-specific variants\n * without mutating the base builder.\n *\n * @example\n * ```ts\n * const base = new PromptBuilder().use(a).use(b);\n * const variant = base.fork().use(c); // base is unchanged\n * ```\n */\n fork(): PromptBuilder<TCtx> {\n const forked = new PromptBuilder<TCtx>();\n forked.sections = [...this.sections];\n return forked;\n }\n\n /**\n * Build the final prompt string.\n *\n * 1. Filters out sections whose `when` guard returns false\n * 2. Renders each section\n * 3. Filters out empty strings\n * 4. Joins with separator and trims\n */\n build(ctx: TCtx): string {\n return this.buildWithMeta(ctx).prompt;\n }\n\n /**\n * Build the prompt and return metadata about which sections were\n * included/excluded. Useful for debugging and logging.\n *\n * A section is \"excluded\" if its `when` guard returns false.\n * A section is \"included\" only if it passes the guard and renders\n * a non-empty string.\n */\n buildWithMeta(ctx: TCtx): {\n prompt: string;\n included: string[];\n excluded: string[];\n } {\n const included: string[] = [];\n const excluded: string[] = [];\n\n const rendered = this.sections\n .filter((s) => {\n if (s.when && !s.when(ctx)) {\n excluded.push(s.id);\n return false;\n }\n return true;\n })\n .map((s) => {\n const output = s.render(ctx);\n if (output) {\n included.push(s.id);\n } else {\n excluded.push(s.id);\n }\n return output;\n })\n .filter(Boolean)\n .join('\\n\\n')\n .trim();\n\n return { prompt: rendered, included, excluded };\n }\n}\n"],"mappings":";AAkBO,IAAM,gBAAN,MAAM,eAEX;AAAA,EACQ,WAAkC,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS3C,IAAI,SAAoC;AACtC,UAAM,cAAc,KAAK,SAAS,UAAU,CAAC,MAAM,EAAE,OAAO,QAAQ,EAAE;AACtE,QAAI,eAAe,GAAG;AACpB,WAAK,SAAS,WAAW,IAAI;AAAA,IAC/B,OAAO;AACL,WAAK,SAAS,KAAK,OAAO;AAAA,IAC5B;AACA,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,QAAQ,KAAoC;AAC1C,UAAM,KAAK,OAAO,QAAQ,WAAW,MAAM,IAAI;AAC/C,SAAK,WAAW,KAAK,SAAS,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE;AACvD,WAAO;AAAA,EACT;AAAA;AAAA,EAGA,IAAI,KAAuC;AACzC,UAAM,KAAK,OAAO,QAAQ,WAAW,MAAM,IAAI;AAC/C,WAAO,KAAK,SAAS,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AAAA,EAC9C;AAAA;AAAA,EAGA,MAAgB;AACd,WAAO,KAAK,SAAS,IAAI,CAAC,MAAM,EAAE,EAAE;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAcA,OAA4B;AAC1B,UAAM,SAAS,IAAI,eAAoB;AACvC,WAAO,WAAW,CAAC,GAAG,KAAK,QAAQ;AACnC,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,MAAM,KAAmB;AACvB,WAAO,KAAK,cAAc,GAAG,EAAE;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,cAAc,KAIZ;AACA,UAAM,WAAqB,CAAC;AAC5B,UAAM,WAAqB,CAAC;AAE5B,UAAM,WAAW,KAAK,SACnB,OAAO,CAAC,MAAM;AACb,UAAI,EAAE,QAAQ,CAAC,EAAE,KAAK,GAAG,GAAG;AAC1B,iBAAS,KAAK,EAAE,EAAE;AAClB,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT,CAAC,EACA,IAAI,CAAC,MAAM;AACV,YAAM,SAAS,EAAE,OAAO,GAAG;AAC3B,UAAI,QAAQ;AACV,iBAAS,KAAK,EAAE,EAAE;AAAA,MACpB,OAAO;AACL,iBAAS,KAAK,EAAE,EAAE;AAAA,MACpB;AACA,aAAO;AAAA,IACT,CAAC,EACA,OAAO,OAAO,EACd,KAAK,MAAM,EACX,KAAK;AAER,WAAO,EAAE,QAAQ,UAAU,UAAU,SAAS;AAAA,EAChD;AACF;","names":[]}
1
+ {"version":3,"sources":["../src/builder.ts","../src/section.ts"],"sourcesContent":["import type { PromptContext, PromptSection } from './types';\n\nexport type PromptFormat = 'text' | 'xml';\n\nexport interface BuildOptions {\n /**\n * - `'text'` (default) — sections joined with `\\n\\n`, groups are transparent.\n * - `'xml'` — each section wrapped in `<id>...</id>` tags, groups\n * wrapped in `<id>...</id>` containing their children.\n */\n format?: PromptFormat;\n}\n\n/**\n * @example\n * ```ts\n * const prompt = new PromptBuilder()\n * .use(identitySection)\n * .use(rulesSection)\n * .use(featureSection)\n * .build(ctx);\n * ```\n */\nexport class PromptBuilder<TCtx extends PromptContext = PromptContext> {\n private nodes: PromptNode<TCtx>[] = [];\n\n /** Replaces an existing section with the same id. */\n use(section: PromptSection<TCtx>): this {\n const idx = this.nodes.findIndex((n) => !isOneOf(n) && n.id === section.id);\n if (idx >= 0) {\n this.nodes[idx] = section;\n } else {\n this.nodes.push(section);\n }\n return this;\n }\n\n /**\n * First candidate that renders a non-empty string wins.\n *\n * @example\n * ```ts\n * builder.useOneOf(activeTasks, noActiveTasks)\n * ```\n */\n useOneOf(...candidates: PromptSection<TCtx>[]): this {\n this.nodes.push({ candidates });\n return this;\n }\n\n /**\n * In `xml` format, wraps children in `<id>` tags. Transparent in `text` format.\n *\n * @example\n * ```ts\n * builder.group('tools', b => b\n * .use(bashSection)\n * .use(gitSection)\n * )\n * ```\n */\n group(id: string, configure: (builder: PromptBuilder<TCtx>) => void): this {\n const inner = new PromptBuilder<TCtx>();\n configure(inner);\n const group: PromptGroup<TCtx> = { id, children: inner.nodes };\n const idx = this.nodes.findIndex((n) => !isOneOf(n) && n.id === id);\n if (idx >= 0) {\n this.nodes[idx] = group;\n } else {\n this.nodes.push(group);\n }\n return this;\n }\n\n /** Searches recursively into groups and oneOf candidates. */\n without(ref: string | { id: string }): this {\n const id = typeof ref === 'string' ? ref : ref.id;\n this.nodes = removeNode(this.nodes, id);\n return this;\n }\n\n /** Searches recursively into groups and oneOf candidates. */\n has(ref: string | { id: string }): boolean {\n const id = typeof ref === 'string' ? ref : ref.id;\n return hasNode(this.nodes, id);\n }\n\n ids(): string[] {\n return collectIds(this.nodes);\n }\n\n /**\n * Creates an independent copy. Modifications to the fork don't affect the original.\n *\n * @example\n * ```ts\n * const base = new PromptBuilder().use(a).use(b);\n * const variant = base.fork().use(c);\n * ```\n */\n fork(): PromptBuilder<TCtx> {\n const forked = new PromptBuilder<TCtx>();\n forked.nodes = deepCopy(this.nodes);\n return forked;\n }\n\n build(ctx: TCtx, options?: BuildOptions): string {\n return this.buildWithMeta(ctx, options).prompt;\n }\n\n /** Like `build`, but also returns which section ids were included/excluded. */\n buildWithMeta(\n ctx: TCtx,\n options?: BuildOptions,\n ): {\n prompt: string;\n included: string[];\n excluded: string[];\n } {\n const included: string[] = [];\n const excluded: string[] = [];\n const format = options?.format ?? 'text';\n\n const parts = renderNodes(this.nodes, ctx, format, included, excluded);\n const prompt = parts.join('\\n\\n').trim();\n\n return { prompt, included, excluded };\n }\n}\n\ninterface PromptGroup<TCtx extends PromptContext> {\n id: string;\n children: PromptNode<TCtx>[];\n}\n\ninterface PromptOneOf<TCtx extends PromptContext> {\n candidates: PromptSection<TCtx>[];\n}\n\ntype PromptNode<TCtx extends PromptContext> =\n | PromptSection<TCtx>\n | PromptGroup<TCtx>\n | PromptOneOf<TCtx>;\n\nfunction isSection<TCtx extends PromptContext>(\n node: PromptNode<TCtx>,\n): node is PromptSection<TCtx> {\n return 'render' in node;\n}\n\nfunction isGroup<TCtx extends PromptContext>(node: PromptNode<TCtx>): node is PromptGroup<TCtx> {\n return 'children' in node;\n}\n\nfunction isOneOf<TCtx extends PromptContext>(node: PromptNode<TCtx>): node is PromptOneOf<TCtx> {\n return 'candidates' in node;\n}\n\nfunction assertNever(value: never): never {\n throw new Error(`Unexpected format: ${value}`);\n}\n\nfunction formatSection(id: string, content: string, format: PromptFormat): string {\n switch (format) {\n case 'text':\n return content;\n case 'xml':\n return `<${id}>\\n${content}\\n</${id}>`;\n default:\n return assertNever(format);\n }\n}\n\nfunction formatGroup(id: string, childParts: string[], format: PromptFormat): string[] {\n switch (format) {\n case 'text':\n return childParts;\n case 'xml':\n return [`<${id}>\\n${childParts.join('\\n\\n')}\\n</${id}>`];\n default:\n return assertNever(format);\n }\n}\n\nfunction renderSection<TCtx extends PromptContext>(\n section: PromptSection<TCtx>,\n ctx: TCtx,\n format: PromptFormat,\n parts: string[],\n included: string[],\n excluded: string[],\n): boolean {\n if (section.when && !section.when(ctx)) {\n excluded.push(section.id);\n return false;\n }\n const output = section.render(ctx);\n if (output) {\n included.push(section.id);\n parts.push(formatSection(section.id, output, format));\n return true;\n }\n excluded.push(section.id);\n return false;\n}\n\nfunction renderOneOf<TCtx extends PromptContext>(\n node: PromptOneOf<TCtx>,\n ctx: TCtx,\n format: PromptFormat,\n parts: string[],\n included: string[],\n excluded: string[],\n): void {\n let found = false;\n for (const candidate of node.candidates) {\n if (found) {\n excluded.push(candidate.id);\n continue;\n }\n if (renderSection(candidate, ctx, format, parts, included, excluded)) {\n found = true;\n }\n }\n}\n\nfunction renderNodes<TCtx extends PromptContext>(\n nodes: PromptNode<TCtx>[],\n ctx: TCtx,\n format: PromptFormat,\n included: string[],\n excluded: string[],\n): string[] {\n const parts: string[] = [];\n\n for (const node of nodes) {\n if (isSection(node)) {\n renderSection(node, ctx, format, parts, included, excluded);\n } else if (isGroup(node)) {\n const childParts = renderNodes(node.children, ctx, format, included, excluded);\n if (childParts.length > 0) {\n parts.push(...formatGroup(node.id, childParts, format));\n }\n } else {\n renderOneOf(node, ctx, format, parts, included, excluded);\n }\n }\n\n return parts;\n}\n\nfunction hasNode<TCtx extends PromptContext>(nodes: PromptNode<TCtx>[], id: string): boolean {\n for (const node of nodes) {\n if (isSection(node)) {\n if (node.id === id) return true;\n } else if (isGroup(node)) {\n if (node.id === id) return true;\n if (hasNode(node.children, id)) return true;\n } else {\n for (const c of node.candidates) {\n if (c.id === id) return true;\n }\n }\n }\n return false;\n}\n\nfunction removeNode<TCtx extends PromptContext>(\n nodes: PromptNode<TCtx>[],\n id: string,\n): PromptNode<TCtx>[] {\n const result: PromptNode<TCtx>[] = [];\n for (const n of nodes) {\n if (isSection(n)) {\n if (n.id !== id) result.push(n);\n } else if (isGroup(n)) {\n if (n.id !== id) {\n result.push({ ...n, children: removeNode(n.children, id) });\n }\n } else {\n const remaining = n.candidates.filter((c) => c.id !== id);\n if (remaining.length > 0) {\n result.push({ candidates: remaining });\n }\n }\n }\n return result;\n}\n\nfunction collectIds<TCtx extends PromptContext>(nodes: PromptNode<TCtx>[]): string[] {\n const ids: string[] = [];\n for (const node of nodes) {\n if (isSection(node)) {\n ids.push(node.id);\n } else if (isGroup(node)) {\n ids.push(node.id);\n ids.push(...collectIds(node.children));\n } else {\n ids.push(...node.candidates.map((c) => c.id));\n }\n }\n return ids;\n}\n\nfunction deepCopy<TCtx extends PromptContext>(nodes: PromptNode<TCtx>[]): PromptNode<TCtx>[] {\n return nodes.map((n) => {\n if (isGroup(n)) {\n return { ...n, children: deepCopy(n.children) };\n }\n if (isOneOf(n)) {\n return { candidates: [...n.candidates] };\n }\n return n;\n });\n}\n","import type { PromptContext, PromptSection } from './types';\n\n/**\n * Create a prompt section. Return a string to include, `null` to exclude.\n *\n * @example\n * ```ts\n * section('identity', () => 'You are Coworker.')\n *\n * section('prod', (ctx: SandboxCtx) => {\n * if (ctx.vars.prodContext == null) return null;\n * return `## Prod\\n\\n${ctx.vars.prodContext}`;\n * })\n * ```\n */\nexport function section<TCtx extends PromptContext = PromptContext>(\n id: string,\n render: (ctx: TCtx) => string | null,\n): PromptSection<TCtx> {\n return {\n id,\n render: (ctx) => render(ctx) ?? '',\n };\n}\n"],"mappings":"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","names":["section"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["/Users/asurve/dev/teleprompt/dist/testing.cjs","../src/testing.ts"],"names":[],"mappings":"AAAA;ACYO,SAAS,WAAA,CAGd,SAAA,EAAiF;AACjF,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAC,CAAA;AAAA,IACR,IAAA,EAAM,CAAC,CAAA;AAAA,IACP,GAAG;AAAA,EACL,CAAA;AACF;AAYO,SAAS,aAAA,CAEd,OAAA,EAA8B,gBAAA,EAAiD;AAC/E,EAAA,MAAM,IAAA,EAAM,WAAA,CAAY,gBAAgB,CAAA;AACxC,EAAA,GAAA,CAAI,OAAA,CAAQ,KAAA,GAAQ,CAAC,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,EAAG;AACtC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAA;AAC3B;AD1BA;AACE;AACA;AACF,yEAAC","file":"/Users/asurve/dev/teleprompt/dist/testing.cjs","sourcesContent":[null,"import type { PromptContext, PromptSection } from './types';\n\n/**\n * Create a minimal PromptContext for testing.\n * All fields have sensible defaults that can be overridden.\n *\n * @example\n * ```ts\n * const ctx = mockContext({ flags: { myFlag: true } });\n * const output = mySection.render(ctx);\n * ```\n */\nexport function mockContext<\n TFlags extends Record<string, boolean> = Record<string, boolean>,\n TVars extends Record<string, unknown> = Record<string, unknown>,\n>(overrides?: Partial<PromptContext<TFlags, TVars>>): PromptContext<TFlags, TVars> {\n return {\n flags: {} as TFlags,\n vars: {} as TVars,\n ...overrides,\n };\n}\n\n/**\n * Render a single section in isolation with a mock context.\n * Respects the section's `when` guard — returns `null` if excluded.\n *\n * @example\n * ```ts\n * const output = renderSection(mySection, { flags: { enabled: true } });\n * expect(output).toContain('expected text');\n * ```\n */\nexport function renderSection<\n TCtx extends PromptContext<Record<string, boolean>, Record<string, unknown>>,\n>(section: PromptSection<TCtx>, contextOverrides?: Partial<TCtx>): string | null {\n const ctx = mockContext(contextOverrides) as TCtx;\n if (section.when && !section.when(ctx)) {\n return null;\n }\n return section.render(ctx);\n}\n"]}
1
+ {"version":3,"sources":["/Users/asurve/dev/teleprompt/main/dist/testing.cjs","../src/testing.ts"],"names":[],"mappings":"AAAA;ACEO,SAAS,WAAA,CAGd,SAAA,EAAiF;AACjF,EAAA,OAAO;AAAA,IACL,KAAA,EAAO,CAAC,CAAA;AAAA,IACR,IAAA,EAAM,CAAC,CAAA;AAAA,IACP,GAAG;AAAA,EACL,CAAA;AACF;AAGO,SAAS,aAAA,CACd,OAAA,EACA,gBAAA,EACe;AACf,EAAA,MAAM,IAAA,EAAM,WAAA,CAAY,gBAAgB,CAAA;AACxC,EAAA,GAAA,CAAI,OAAA,CAAQ,KAAA,GAAQ,CAAC,OAAA,CAAQ,IAAA,CAAK,GAAG,CAAA,EAAG;AACtC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,OAAA,CAAQ,MAAA,CAAO,GAAG,CAAA;AAC3B;ADRA;AACE;AACA;AACF,yEAAC","file":"/Users/asurve/dev/teleprompt/main/dist/testing.cjs","sourcesContent":[null,"import type { PromptContext, PromptSection } from './types';\n\nexport function mockContext<\n TFlags extends Record<string, boolean> = Record<string, boolean>,\n TVars extends object = Record<string, unknown>,\n>(overrides?: Partial<PromptContext<TFlags, TVars>>): PromptContext<TFlags, TVars> {\n return {\n flags: {} as TFlags,\n vars: {} as TVars,\n ...overrides,\n };\n}\n\n/** Renders a section in isolation. Returns `null` if excluded by `when` guard. */\nexport function renderSection<TCtx extends PromptContext>(\n section: PromptSection<TCtx>,\n contextOverrides?: Partial<TCtx>,\n): string | null {\n const ctx = mockContext(contextOverrides) as TCtx;\n if (section.when && !section.when(ctx)) {\n return null;\n }\n return section.render(ctx);\n}\n"]}
@@ -1,26 +1,7 @@
1
- import { P as PromptContext, a as PromptSection } from './types-DXgCksVT.cjs';
1
+ import { P as PromptContext, a as PromptSection } from './types-ow-XbrO7.cjs';
2
2
 
3
- /**
4
- * Create a minimal PromptContext for testing.
5
- * All fields have sensible defaults that can be overridden.
6
- *
7
- * @example
8
- * ```ts
9
- * const ctx = mockContext({ flags: { myFlag: true } });
10
- * const output = mySection.render(ctx);
11
- * ```
12
- */
13
- declare function mockContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends Record<string, unknown> = Record<string, unknown>>(overrides?: Partial<PromptContext<TFlags, TVars>>): PromptContext<TFlags, TVars>;
14
- /**
15
- * Render a single section in isolation with a mock context.
16
- * Respects the section's `when` guard — returns `null` if excluded.
17
- *
18
- * @example
19
- * ```ts
20
- * const output = renderSection(mySection, { flags: { enabled: true } });
21
- * expect(output).toContain('expected text');
22
- * ```
23
- */
24
- declare function renderSection<TCtx extends PromptContext<Record<string, boolean>, Record<string, unknown>>>(section: PromptSection<TCtx>, contextOverrides?: Partial<TCtx>): string | null;
3
+ declare function mockContext<TFlags extends Record<string, boolean> = Record<string, boolean>, TVars extends object = Record<string, unknown>>(overrides?: Partial<PromptContext<TFlags, TVars>>): PromptContext<TFlags, TVars>;
4
+ /** Renders a section in isolation. Returns `null` if excluded by `when` guard. */
5
+ declare function renderSection<TCtx extends PromptContext>(section: PromptSection<TCtx>, contextOverrides?: Partial<TCtx>): string | null;
25
6
 
26
7
  export { mockContext, renderSection };