| 197 | * This is deliberately compact: headers + fenced slices, no prose padding. |
| 198 | */ |
| 199 | export function renderContextPrompt(ctx: TaskContext): string { |
| 200 | const out: string[] = []; |
| 201 | out.push('# Your task (isolated)'); |
| 202 | out.push(ctx.instruction); |
| 203 | out.push(''); |
| 204 | out.push('You are a worker node. You see ONLY the context below — it is everything you need.'); |
| 205 | out.push(`You may write ONLY these files: ${ctx.allowedWrites.join(', ') || '(new files as instructed)'}.`); |
| 206 | out.push('Do not ask for more context; if a type is missing, infer a minimal local definition.'); |
| 207 | out.push(''); |
| 208 | |
| 209 | if (ctx.typeDefs.length > 0) { |
| 210 | out.push('## Types & contracts you depend on'); |
| 211 | for (const s of ctx.typeDefs) { |
| 212 | out.push(`### ${s.symbol ?? path.basename(s.file)} — from ${s.file}`); |
| 213 | out.push('```ts'); |
| 214 | out.push(s.text); |
| 215 | out.push('```'); |
| 216 | } |
| 217 | out.push(''); |
| 218 | } |
| 219 | |
| 220 | if (ctx.slices.length > 0) { |
| 221 | out.push('## Current code you are editing / signatures you call'); |
| 222 | for (const s of ctx.slices) { |
| 223 | const loc = s.startLine ? ` (lines ${s.startLine}-${s.endLine})` : ''; |
| 224 | out.push(`### ${s.file}${loc}${s.reason === 'signature' ? ' [signature only]' : ''}`); |
| 225 | out.push('```'); |
| 226 | out.push(s.text); |
| 227 | out.push('```'); |
| 228 | } |
| 229 | out.push(''); |
| 230 | } |
| 231 | |
| 232 | if (ctx.designTokens) { |
| 233 | out.push('## Design tokens — match these exactly'); |
| 234 | out.push('```css'); |
| 235 | out.push(ctx.designTokens); |
| 236 | out.push('```'); |
| 237 | out.push(''); |
| 238 | } |
| 239 | |
| 240 | out.push('Produce the complete file(s). Output working code, not placeholders.'); |
| 241 | return out.join('\n'); |
| 242 | } |
| 243 | |
| 244 | /** |
| 245 | * Estimate what a NAIVE orchestrator would have spent (full touched-file content |