prjct-cli 0.10.6 → 0.10.9

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.
@@ -20,6 +20,9 @@ class PromptBuilder {
20
20
  */
21
21
  build(template, context, state, agent = null, learnedPatterns = null, thinkBlock = null, relevantMemories = null, planInfo = null) {
22
22
  const parts = []
23
+
24
+ // Store context for use in helper methods
25
+ this._currentContext = context
23
26
 
24
27
  // Agent assignment (if applicable)
25
28
  // CRITICAL: Include full agent content, not just name
@@ -85,13 +88,60 @@ class PromptBuilder {
85
88
  // Current state (only if exists and relevant)
86
89
  const relevantState = this.filterRelevantState(state)
87
90
  if (relevantState) {
88
- parts.push('\nSTATE:\n')
91
+ parts.push('\n## PRJCT STATE (Project Management Data)\n')
89
92
  parts.push(relevantState)
90
93
  parts.push('\n')
91
94
  }
92
95
 
93
- // Enforcement (Strict Mode)
94
- parts.push(this.buildEnforcement());
96
+ // CRITICAL: Include available project files for context
97
+ if (context.files && context.files.length > 0) {
98
+ parts.push('\n## AVAILABLE PROJECT FILES\n')
99
+ parts.push(`You have ${context.files.length} relevant files available in this project.\n`)
100
+ parts.push('**USE Read TOOL TO LOAD FILES BEFORE MODIFYING THEM.**\n')
101
+ parts.push('\nTop relevant files:\n')
102
+ const topFiles = context.files.slice(0, 20).map(f => `- ${f}`).join('\n')
103
+ parts.push(topFiles)
104
+ if (context.files.length > 20) {
105
+ parts.push(`\n... and ${context.files.length - 20} more files. Use Read tool to access them.\n`)
106
+ }
107
+ parts.push('\n')
108
+ } else if (context.projectPath) {
109
+ parts.push('\n## PROJECT FILES\n')
110
+ parts.push(`Project path: ${context.projectPath}\n`)
111
+ parts.push('**USE Read TOOL TO LOAD FILES YOU NEED TO UNDERSTAND OR MODIFY.**\n')
112
+ parts.push('**NEVER MODIFY CODE WITHOUT READING IT FIRST.**\n\n')
113
+ }
114
+
115
+ // OPTIMIZED: Only include patterns for code-modifying commands
116
+ // Commands like done, ship, recap, next don't need full patterns
117
+ const codeCommands = ['now', 'build', 'feature', 'design', 'cleanup', 'fix', 'bug', 'test', 'init', 'spec', 'work']
118
+ const commandName = template.frontmatter?.name?.replace('p:', '') || ''
119
+ const needsPatterns = codeCommands.includes(commandName)
120
+
121
+ // Include code patterns analysis for code-modifying commands
122
+ const codePatternsContent = state?.codePatterns || ''
123
+ if (needsPatterns && codePatternsContent && codePatternsContent.trim()) {
124
+ parts.push('\n## CODE PATTERNS (MUST FOLLOW)\n')
125
+ // Include the full patterns file - it contains critical conventions
126
+ parts.push(codePatternsContent)
127
+ parts.push('\n**ALL new code MUST respect these patterns. NO anti-patterns allowed.**\n')
128
+ }
129
+
130
+ const analysisContent = state?.analysis || ''
131
+ if (needsPatterns && analysisContent && analysisContent.trim()) {
132
+ // Extract stack info compactly
133
+ const stackMatch = analysisContent.match(/Stack[:\s]+([^\n]+)/i) ||
134
+ analysisContent.match(/Technology[:\s]+([^\n]+)/i)
135
+ const stack = stackMatch ? stackMatch[1].trim() : 'detected'
136
+
137
+ parts.push(`\n## STACK\nStack: ${stack}\n`)
138
+ if (!codePatternsContent) {
139
+ parts.push('Read analysis/repo-summary.md + similar files before coding. Match patterns exactly.\n')
140
+ }
141
+ }
142
+
143
+ // CRITICAL: Compressed rules (replaces 78 lines with 12)
144
+ parts.push(this.buildCriticalRules());
95
145
 
96
146
  // P1.1: Learned Patterns (avoid asking user questions we already know)
97
147
  if (learnedPatterns && Object.keys(learnedPatterns).some(k => learnedPatterns[k])) {
@@ -126,37 +176,13 @@ class PromptBuilder {
126
176
  }
127
177
  }
128
178
 
129
- // P3.4: Plan Mode instructions
130
- if (planInfo) {
131
- if (planInfo.isPlanning) {
132
- parts.push('\n## PLAN MODE ACTIVE\n')
133
- parts.push('You are in PLANNING mode. Follow these constraints:\n')
134
- parts.push('1. **READ-ONLY**: Only use read tools (Read, Glob, Grep)\n')
135
- parts.push('2. **GATHER INFO**: Collect all necessary information\n')
136
- parts.push('3. **ANALYZE**: Understand the context and implications\n')
137
- parts.push('4. **PROPOSE**: Generate a plan with clear steps\n')
138
- parts.push('5. **WAIT FOR APPROVAL**: Do NOT execute until user approves\n')
139
-
140
- if (planInfo.active) {
141
- parts.push(`\nCurrent Status: ${planInfo.active.status}\n`)
142
- if (planInfo.active.gatheredInfo?.length > 0) {
143
- parts.push(`Info gathered: ${planInfo.active.gatheredInfo.length} items\n`)
144
- }
145
- }
146
- }
147
-
148
- if (planInfo.requiresApproval) {
149
- parts.push('\n## APPROVAL REQUIRED\n')
150
- parts.push('This command is DESTRUCTIVE. You MUST:\n')
151
- parts.push('1. Show exactly what will change\n')
152
- parts.push('2. List affected files/resources\n')
153
- parts.push('3. Ask for explicit user confirmation (y/n)\n')
154
- parts.push('4. Only proceed after approval\n')
155
- }
156
-
157
- if (planInfo.allowedTools) {
158
- parts.push(`\nAllowed tools: ${planInfo.allowedTools.join(', ')}\n`)
159
- }
179
+ // P3.4: Plan Mode (OPTIMIZED: 30 lines → 5 lines)
180
+ if (planInfo?.isPlanning) {
181
+ parts.push(`\n## PLAN MODE\nRead-only. Gather info → Analyze → Propose plan → Wait for approval.\n`)
182
+ if (planInfo.allowedTools) parts.push(`Tools: ${planInfo.allowedTools.join(', ')}\n`)
183
+ }
184
+ if (planInfo?.requiresApproval) {
185
+ parts.push(`\n## APPROVAL REQUIRED\nShow changes, list affected files, ask for confirmation.\n`)
160
186
  }
161
187
 
162
188
  // Simple execution directive
@@ -167,18 +193,33 @@ class PromptBuilder {
167
193
 
168
194
  /**
169
195
  * Filter only relevant state data
196
+ * IMPROVED: Include more context, don't truncate critical info
170
197
  */
171
198
  filterRelevantState(state) {
172
199
  if (!state || Object.keys(state).length === 0) return null
173
200
 
174
201
  const relevant = []
175
202
  for (const [key, content] of Object.entries(state)) {
176
- if (content && content.trim() && content.length < 500) {
177
- relevant.push(`${key}: ${content.substring(0, 200)}`)
203
+ if (content && content.trim()) {
204
+ // Include full content for critical files (now, next, context, patterns)
205
+ const criticalFiles = ['now', 'next', 'context', 'analysis', 'codePatterns']
206
+ if (criticalFiles.includes(key)) {
207
+ // Include full content for critical files (up to 2000 chars)
208
+ const display = content.length > 2000
209
+ ? content.substring(0, 2000) + '\n... (truncated)'
210
+ : content
211
+ relevant.push(`### ${key}\n${display}`)
212
+ } else if (content.length < 1000) {
213
+ // Include full content for small files
214
+ relevant.push(`### ${key}\n${content}`)
215
+ } else {
216
+ // Truncate large files but show more context
217
+ relevant.push(`### ${key}\n${content.substring(0, 500)}... (truncated, use Read tool for full content)`)
218
+ }
178
219
  }
179
220
  }
180
221
 
181
- return relevant.length > 0 ? relevant.join('\n') : null
222
+ return relevant.length > 0 ? relevant.join('\n\n') : null
182
223
  }
183
224
 
184
225
  /**
@@ -203,19 +244,22 @@ class PromptBuilder {
203
244
  }
204
245
 
205
246
  /**
206
- * Build enforcement section
207
- * Forces Claude to follow the process strictly
247
+ * Build critical rules - compressed anti-hallucination
248
+ * OPTIMIZED: From 66 lines to 12 lines (~82% reduction)
208
249
  */
209
- buildEnforcement() {
250
+ buildCriticalRules() {
251
+ const fileCount = this._currentContext?.files?.length || this._currentContext?.filteredSize || 0
210
252
  return `
211
- ## PROCESS ENFORCEMENT
212
- 1. FOLLOW the Flow strictly. Do not skip steps.
213
- 2. USE the allowed tools only.
214
- 3. IF you are stuck, use the "Ask" tool or stop.
215
- 4. DO NOT hallucinate files or commands.
216
- 5. ALWAYS verify your changes.
253
+ ## RULES (CRITICAL)
254
+ 1. **READ FIRST**: Use Read tool BEFORE modifying any file. Never assume code structure.
255
+ 2. **MATCH PATTERNS**: Follow existing style, architecture, naming, imports exactly.
256
+ 3. **NO HALLUCINATIONS**: Don't invent files, functions, or paths. If unsure, READ first.
257
+ 4. **GIT SAFETY**: Never use checkout/reset --hard/clean. Always check status first.
258
+ 5. **VERIFY**: After writing, confirm code matches project patterns.
259
+ Context: ${fileCount} files available. Read what you need.
217
260
  `;
218
261
  }
262
+
219
263
  }
220
264
 
221
265
  module.exports = new PromptBuilder()