x-ipe 1.0.24__py3-none-any.whl → 1.0.25__py3-none-any.whl

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.
Files changed (139) hide show
  1. x_ipe/app.py +25 -3
  2. x_ipe/handlers/terminal_handlers.py +6 -0
  3. x_ipe/handlers/voice_handlers.py +5 -0
  4. x_ipe/resources/copilot-instructions.md +19 -6
  5. x_ipe/resources/skills/lesson-learned/SKILL.md +208 -0
  6. x_ipe/resources/skills/lesson-learned/references/examples.md +238 -0
  7. x_ipe/resources/skills/project-quality-board-management/SKILL.md +135 -298
  8. x_ipe/resources/skills/project-quality-board-management/references/evaluation-principles.md +213 -0
  9. x_ipe/resources/skills/project-quality-board-management/references/evaluation-procedures.md +214 -0
  10. x_ipe/resources/skills/project-quality-board-management/templates/quality-report.md +70 -18
  11. x_ipe/resources/skills/task-execution-guideline/SKILL.md +2 -2
  12. x_ipe/resources/skills/task-execution-guideline/templates/task-record.yaml +1 -1
  13. x_ipe/resources/skills/task-type-code-implementation/SKILL.md +72 -270
  14. x_ipe/resources/skills/task-type-code-implementation/references/implementation-guidelines.md +432 -0
  15. x_ipe/resources/skills/task-type-code-refactor-v2/SKILL.md +127 -353
  16. x_ipe/resources/skills/task-type-code-refactor-v2/references/refactoring-techniques.md +373 -0
  17. x_ipe/resources/skills/task-type-feature-breakdown/SKILL.md +31 -243
  18. x_ipe/resources/skills/task-type-feature-breakdown/references/breakdown-guidelines.md +330 -0
  19. x_ipe/resources/skills/task-type-feature-refinement/SKILL.md +27 -180
  20. x_ipe/resources/skills/task-type-feature-refinement/references/specification-writing-guide.md +267 -0
  21. x_ipe/resources/skills/task-type-idea-mockup/SKILL.md +38 -276
  22. x_ipe/resources/skills/task-type-idea-mockup/references/mockup-guidelines.md +299 -0
  23. x_ipe/resources/skills/task-type-idea-to-architecture/SKILL.md +20 -218
  24. x_ipe/resources/skills/task-type-idea-to-architecture/references/architecture-patterns.md +342 -0
  25. x_ipe/resources/skills/task-type-ideation/SKILL.md +10 -266
  26. x_ipe/resources/skills/task-type-ideation/references/folder-naming-guide.md +55 -0
  27. x_ipe/resources/skills/task-type-ideation/references/tool-usage-guide.md +236 -0
  28. x_ipe/resources/skills/task-type-ideation-v2/SKILL.md +488 -0
  29. x_ipe/resources/skills/task-type-ideation-v2/references/examples.md +377 -0
  30. x_ipe/resources/skills/task-type-ideation-v2/references/folder-naming-guide.md +74 -0
  31. x_ipe/resources/skills/task-type-ideation-v2/references/tool-usage-guide.md +145 -0
  32. x_ipe/resources/skills/task-type-ideation-v2/references/visualization-guide.md +160 -0
  33. x_ipe/resources/skills/task-type-ideation-v2/templates/idea-summary.md +86 -0
  34. x_ipe/resources/skills/task-type-refactoring-analysis/SKILL.md +83 -145
  35. x_ipe/resources/skills/task-type-refactoring-analysis/references/output-schema.md +172 -0
  36. x_ipe/resources/skills/task-type-technical-design/SKILL.md +28 -214
  37. x_ipe/resources/skills/task-type-technical-design/references/design-templates.md +422 -0
  38. x_ipe/resources/skills/task-type-test-generation/SKILL.md +47 -332
  39. x_ipe/resources/skills/task-type-test-generation/references/test-patterns.md +368 -0
  40. x_ipe/resources/skills/tool-tracing-creator/SKILL.md +312 -0
  41. x_ipe/resources/skills/tool-tracing-creator/references/examples.md +324 -0
  42. x_ipe/resources/skills/tool-tracing-instrumentation/SKILL.md +373 -0
  43. x_ipe/resources/skills/tool-tracing-instrumentation/references/examples.md +264 -0
  44. x_ipe/resources/skills/x-ipe-skill-creator-v3/SKILL.md +486 -0
  45. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/10. example-gate-conditions.md +73 -0
  46. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/11. reference-quality-standards.md +127 -0
  47. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/2. reference-section-order.md +127 -0
  48. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/3. example-step-based-code-review.md +84 -0
  49. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/4. example-step-based-feature-implementation.md +113 -0
  50. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/5. example-function-based-validation.md +73 -0
  51. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/6. example-function-based-analysis.md +94 -0
  52. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/7. example-task-io-code-implementation.md +36 -0
  53. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/8. example-structured-summary.md +43 -0
  54. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/9. example-dor-dod.md +77 -0
  55. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/examples.md +429 -0
  56. x_ipe/resources/skills/x-ipe-skill-creator-v3/references/skill-general-guidelines-v2.md +611 -0
  57. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-meta.md +153 -0
  58. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-task-based.md +324 -0
  59. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-task-category.md +109 -0
  60. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/skill-meta-x-ipe-tool.md +205 -0
  61. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-meta.md +334 -0
  62. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-task-based.md +279 -0
  63. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-tool.md +175 -0
  64. x_ipe/resources/skills/x-ipe-skill-creator-v3/templates/x-ipe-workflow-orchestration.md +329 -0
  65. x_ipe/resources/skills/x-ipe-task-based-ideation/SKILL.md +487 -0
  66. x_ipe/resources/skills/x-ipe-task-based-ideation/references/examples.md +377 -0
  67. x_ipe/resources/skills/x-ipe-task-based-ideation/references/folder-naming-guide.md +74 -0
  68. x_ipe/resources/skills/x-ipe-task-based-ideation/references/tool-usage-guide.md +145 -0
  69. x_ipe/resources/skills/x-ipe-task-based-ideation/references/visualization-guide.md +160 -0
  70. x_ipe/resources/skills/x-ipe-task-based-ideation/templates/idea-summary.md +86 -0
  71. x_ipe/routes/__init__.py +2 -0
  72. x_ipe/routes/ideas_routes.py +17 -0
  73. x_ipe/routes/kb_routes.py +80 -0
  74. x_ipe/routes/main_routes.py +18 -0
  75. x_ipe/routes/project_routes.py +7 -0
  76. x_ipe/routes/proxy_routes.py +2 -0
  77. x_ipe/routes/quality_evaluation_routes.py +193 -0
  78. x_ipe/routes/settings_routes.py +6 -0
  79. x_ipe/routes/tools_routes.py +6 -0
  80. x_ipe/routes/tracing_routes.py +232 -0
  81. x_ipe/routes/uiux_feedback_routes.py +30 -0
  82. x_ipe/services/__init__.py +5 -0
  83. x_ipe/services/config_service.py +6 -0
  84. x_ipe/services/file_service.py +20 -0
  85. x_ipe/services/homepage_service.py +160 -0
  86. x_ipe/services/ideas_service.py +19 -0
  87. x_ipe/services/kb_service.py +378 -0
  88. x_ipe/services/proxy_service.py +4 -0
  89. x_ipe/services/settings_service.py +13 -0
  90. x_ipe/services/skills_service.py +4 -0
  91. x_ipe/services/terminal_service.py +24 -0
  92. x_ipe/services/themes_service.py +4 -0
  93. x_ipe/services/tools_config_service.py +4 -0
  94. x_ipe/services/tracing_service.py +333 -0
  95. x_ipe/services/uiux_feedback_service.py +32 -0
  96. x_ipe/services/voice_input_service_v2.py +11 -0
  97. x_ipe/static/css/base.css +7 -0
  98. x_ipe/static/css/homepage-infinity.css +330 -0
  99. x_ipe/static/css/kb-core.css +301 -0
  100. x_ipe/static/css/quality-evaluation.css +345 -0
  101. x_ipe/static/css/sidebar.css +14 -4
  102. x_ipe/static/css/terminal.css +1 -0
  103. x_ipe/static/css/tracing-dashboard.css +796 -0
  104. x_ipe/static/css/workplace.css +20 -0
  105. x_ipe/static/img/homepage-infinity-loop.png +0 -0
  106. x_ipe/static/js/features/homepage-infinity.js +314 -0
  107. x_ipe/static/js/features/kb-core.js +371 -0
  108. x_ipe/static/js/features/quality-evaluation.js +387 -0
  109. x_ipe/static/js/features/sidebar.js +255 -12
  110. x_ipe/static/js/features/tracing-dashboard.js +855 -0
  111. x_ipe/static/js/features/tracing-graph.js +1031 -0
  112. x_ipe/static/js/features/tree-search.js +6 -2
  113. x_ipe/static/js/features/workplace.js +200 -6
  114. x_ipe/static/js/init.js +76 -0
  115. x_ipe/static/js/uiux-feedback.js +18 -2
  116. x_ipe/templates/base.html +19 -0
  117. x_ipe/templates/index.html +7 -1
  118. x_ipe/templates/knowledge-base.html +110 -0
  119. x_ipe/templates/workplace.html +4 -0
  120. x_ipe/tracing/__init__.py +37 -0
  121. x_ipe/tracing/buffer.py +135 -0
  122. x_ipe/tracing/context.py +125 -0
  123. x_ipe/tracing/decorator.py +288 -0
  124. x_ipe/tracing/middleware.py +197 -0
  125. x_ipe/tracing/parser.py +235 -0
  126. x_ipe/tracing/redactor.py +111 -0
  127. x_ipe/tracing/writer.py +122 -0
  128. {x_ipe-1.0.24.dist-info → x_ipe-1.0.25.dist-info}/METADATA +2 -2
  129. {x_ipe-1.0.24.dist-info → x_ipe-1.0.25.dist-info}/RECORD +132 -62
  130. x_ipe/resources/skills/x-ipe-skill-creator/SKILL.md +0 -329
  131. x_ipe/resources/skills/x-ipe-skill-creator/references/output-patterns.md +0 -169
  132. x_ipe/resources/skills/x-ipe-skill-creator/references/skill-structure.md +0 -162
  133. x_ipe/resources/skills/x-ipe-skill-creator/references/workflows.md +0 -110
  134. x_ipe/resources/skills/x-ipe-skill-creator/templates/references/examples.md +0 -113
  135. x_ipe/resources/skills/x-ipe-skill-creator/templates/skill-category-skill.md +0 -296
  136. x_ipe/resources/skills/x-ipe-skill-creator/templates/task-type-skill.md +0 -269
  137. {x_ipe-1.0.24.dist-info → x_ipe-1.0.25.dist-info}/WHEEL +0 -0
  138. {x_ipe-1.0.24.dist-info → x_ipe-1.0.25.dist-info}/entry_points.txt +0 -0
  139. {x_ipe-1.0.24.dist-info → x_ipe-1.0.25.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,387 @@
1
+ /**
2
+ * FEATURE-024: Project Quality Evaluation UI
3
+ *
4
+ * Quality Evaluation View component for viewing and acting on project quality reports.
5
+ * Integrates with Workplace sidebar and provides action bar, version timeline, and markdown preview.
6
+ */
7
+ class QualityEvaluationView {
8
+ constructor(container) {
9
+ this.container = container;
10
+ this.config = null;
11
+ this.status = null;
12
+ this.currentVersion = null;
13
+ }
14
+
15
+ // -------------------------------------------------------------------------
16
+ // Lifecycle
17
+ // -------------------------------------------------------------------------
18
+
19
+ async init() {
20
+ this.renderLoading();
21
+ try {
22
+ await Promise.all([
23
+ this.loadConfig(),
24
+ this.loadStatus()
25
+ ]);
26
+
27
+ if (this.status.exists) {
28
+ await this.loadContent();
29
+ this.renderWithData();
30
+ } else {
31
+ this.renderEmptyState();
32
+ }
33
+ } catch (error) {
34
+ console.error('[QualityEval] Init error:', error);
35
+ this.renderError('Failed to load quality evaluation data');
36
+ }
37
+ }
38
+
39
+ destroy() {
40
+ this.container.innerHTML = '';
41
+ }
42
+
43
+ // -------------------------------------------------------------------------
44
+ // API Methods
45
+ // -------------------------------------------------------------------------
46
+
47
+ async loadConfig() {
48
+ try {
49
+ const response = await fetch('/api/config/copilot-prompt');
50
+ if (response.ok) {
51
+ this.config = await response.json();
52
+ } else {
53
+ this.config = this.getDefaultConfig();
54
+ }
55
+ } catch (error) {
56
+ console.warn('[QualityEval] Failed to load config:', error);
57
+ this.config = this.getDefaultConfig();
58
+ }
59
+ }
60
+
61
+ async loadStatus() {
62
+ const response = await fetch('/api/quality-evaluation/status');
63
+ if (response.ok) {
64
+ this.status = await response.json();
65
+ } else {
66
+ this.status = { exists: false, versions: [] };
67
+ }
68
+ }
69
+
70
+ async loadContent(version = null) {
71
+ const url = version
72
+ ? `/api/quality-evaluation/content?version=${version}`
73
+ : '/api/quality-evaluation/content';
74
+
75
+ const response = await fetch(url);
76
+ if (response.ok) {
77
+ const data = await response.json();
78
+ this.currentVersion = data.version;
79
+ this.currentContent = data.content;
80
+ return data;
81
+ }
82
+ throw new Error('Failed to load content');
83
+ }
84
+
85
+ getDefaultConfig() {
86
+ return {
87
+ version: '2.0',
88
+ evaluation: {
89
+ evaluate: {
90
+ label: 'Evaluate Project Quality',
91
+ icon: 'bi-clipboard-check',
92
+ command: 'Evaluate project quality and generate report to x-ipe-docs/quality-evaluation/project-quality-evaluation.md'
93
+ },
94
+ refactoring: []
95
+ },
96
+ placeholder: {
97
+ 'evaluation-file': 'x-ipe-docs/quality-evaluation/project-quality-evaluation.md'
98
+ }
99
+ };
100
+ }
101
+
102
+ // -------------------------------------------------------------------------
103
+ // Rendering
104
+ // -------------------------------------------------------------------------
105
+
106
+ renderLoading() {
107
+ this.container.innerHTML = `
108
+ <div class="quality-eval-view">
109
+ <div class="quality-loading">
110
+ <div class="spinner-border" role="status">
111
+ <span class="visually-hidden">Loading...</span>
112
+ </div>
113
+ </div>
114
+ </div>
115
+ `;
116
+ }
117
+
118
+ renderError(message) {
119
+ this.container.innerHTML = `
120
+ <div class="quality-eval-view">
121
+ <div class="quality-empty-state">
122
+ <div class="quality-empty-icon">
123
+ <i class="bi bi-exclamation-triangle"></i>
124
+ </div>
125
+ <h5 class="quality-empty-title">Error</h5>
126
+ <p class="quality-empty-desc">${message}</p>
127
+ <button class="btn btn-evaluate" onclick="window.qualityEvaluationView.init()">
128
+ <i class="bi bi-arrow-clockwise"></i>
129
+ Retry
130
+ </button>
131
+ </div>
132
+ </div>
133
+ `;
134
+ }
135
+
136
+ renderEmptyState() {
137
+ const evaluateConfig = this.config?.evaluation?.evaluate || this.getDefaultConfig().evaluation.evaluate;
138
+
139
+ this.container.innerHTML = `
140
+ <div class="quality-eval-view">
141
+ <div class="quality-empty-state">
142
+ <div class="quality-empty-icon">
143
+ <i class="bi bi-clipboard-check"></i>
144
+ </div>
145
+ <h5 class="quality-empty-title">No Evaluation Yet</h5>
146
+ <p class="quality-empty-desc">
147
+ Run your first project quality evaluation to get insights on requirements coverage,
148
+ feature alignment, and test completeness.
149
+ </p>
150
+ <button class="btn btn-evaluate" id="quality-empty-cta">
151
+ <i class="bi ${evaluateConfig.icon}"></i>
152
+ ${evaluateConfig.label}
153
+ </button>
154
+ </div>
155
+ </div>
156
+ `;
157
+
158
+ this.bindEmptyStateEvents();
159
+ }
160
+
161
+ renderWithData() {
162
+ this.container.innerHTML = `
163
+ <div class="quality-eval-view">
164
+ ${this.renderActionBar()}
165
+ ${this.renderVersionTimeline()}
166
+ <div class="quality-markdown-preview">
167
+ <div class="quality-markdown-content" id="quality-markdown-content">
168
+ ${this.renderMarkdown(this.currentContent)}
169
+ </div>
170
+ </div>
171
+ </div>
172
+ `;
173
+
174
+ this.bindEvents();
175
+ }
176
+
177
+ renderActionBar() {
178
+ const evaluateConfig = this.config?.evaluation?.evaluate || this.getDefaultConfig().evaluation.evaluate;
179
+ const refactoringOptions = this.config?.evaluation?.refactoring || [];
180
+
181
+ return `
182
+ <div class="quality-action-bar">
183
+ ${refactoringOptions.length > 0 ? this.renderRefactoringDropdown(refactoringOptions) : ''}
184
+ <button class="btn btn-evaluate" id="quality-evaluate-btn">
185
+ <i class="bi ${evaluateConfig.icon}"></i>
186
+ Evaluate
187
+ </button>
188
+ </div>
189
+ `;
190
+ }
191
+
192
+ renderRefactoringDropdown(options) {
193
+ const items = options.map(opt => `
194
+ <div class="dropdown-item" data-command="${this.escapeHtml(opt.command)}">
195
+ <i class="bi ${opt.icon}"></i>
196
+ <span>${this.escapeHtml(opt.label)}</span>
197
+ </div>
198
+ `).join('');
199
+
200
+ return `
201
+ <div class="dropdown-refactoring">
202
+ <button class="btn btn-refactoring">
203
+ <i class="bi bi-arrow-repeat"></i>
204
+ Refactoring
205
+ <i class="bi bi-chevron-down" style="font-size: 0.75rem;"></i>
206
+ </button>
207
+ <div class="dropdown-menu">
208
+ ${items}
209
+ </div>
210
+ </div>
211
+ `;
212
+ }
213
+
214
+ renderVersionTimeline() {
215
+ if (!this.status.versions || this.status.versions.length === 0) {
216
+ return '';
217
+ }
218
+
219
+ const tabs = this.status.versions.map(v => `
220
+ <div class="quality-version-tab ${v.version === this.currentVersion ? 'active' : ''}"
221
+ data-version="${v.version}">
222
+ <span class="version-number">${v.version}</span>
223
+ <span class="version-date">${v.date}</span>
224
+ </div>
225
+ `).join('');
226
+
227
+ return `
228
+ <div class="quality-version-timeline">
229
+ ${tabs}
230
+ </div>
231
+ `;
232
+ }
233
+
234
+ renderMarkdown(content) {
235
+ if (!content) {
236
+ return '<p class="text-muted">No content available.</p>';
237
+ }
238
+
239
+ // Use marked.js if available, otherwise basic conversion
240
+ if (typeof marked !== 'undefined') {
241
+ return marked.parse(content);
242
+ }
243
+
244
+ // Basic markdown conversion fallback
245
+ return this.basicMarkdownToHtml(content);
246
+ }
247
+
248
+ basicMarkdownToHtml(content) {
249
+ let html = content
250
+ // Headers
251
+ .replace(/^### (.*$)/gm, '<h3>$1</h3>')
252
+ .replace(/^## (.*$)/gm, '<h2>$1</h2>')
253
+ .replace(/^# (.*$)/gm, '<h1>$1</h1>')
254
+ // Bold and italic
255
+ .replace(/\*\*\*(.*?)\*\*\*/g, '<strong><em>$1</em></strong>')
256
+ .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
257
+ .replace(/\*(.*?)\*/g, '<em>$1</em>')
258
+ // Inline code
259
+ .replace(/`([^`]+)`/g, '<code>$1</code>')
260
+ // Lists
261
+ .replace(/^\- (.*$)/gm, '<li>$1</li>')
262
+ .replace(/^\d+\. (.*$)/gm, '<li>$1</li>')
263
+ // Paragraphs
264
+ .replace(/\n\n/g, '</p><p>')
265
+ .replace(/\n/g, '<br>');
266
+
267
+ return `<p>${html}</p>`;
268
+ }
269
+
270
+ // -------------------------------------------------------------------------
271
+ // Event Handling
272
+ // -------------------------------------------------------------------------
273
+
274
+ bindEmptyStateEvents() {
275
+ const ctaBtn = document.getElementById('quality-empty-cta');
276
+ if (ctaBtn) {
277
+ ctaBtn.addEventListener('click', () => this.handleEvaluateClick());
278
+ }
279
+ }
280
+
281
+ bindEvents() {
282
+ // Evaluate button
283
+ const evaluateBtn = document.getElementById('quality-evaluate-btn');
284
+ if (evaluateBtn) {
285
+ evaluateBtn.addEventListener('click', () => this.handleEvaluateClick());
286
+ }
287
+
288
+ // Refactoring dropdown items
289
+ const refactoringItems = this.container.querySelectorAll('.dropdown-item[data-command]');
290
+ refactoringItems.forEach(item => {
291
+ item.addEventListener('click', (e) => {
292
+ const command = e.currentTarget.dataset.command;
293
+ this.handleRefactoringClick(command);
294
+ });
295
+ });
296
+
297
+ // Version tabs
298
+ const versionTabs = this.container.querySelectorAll('.quality-version-tab');
299
+ versionTabs.forEach(tab => {
300
+ tab.addEventListener('click', (e) => {
301
+ const version = e.currentTarget.dataset.version;
302
+ this.handleVersionClick(version);
303
+ });
304
+ });
305
+ }
306
+
307
+ handleEvaluateClick() {
308
+ const evaluateConfig = this.config?.evaluation?.evaluate || this.getDefaultConfig().evaluation.evaluate;
309
+ const command = this.replacePlaceholders(evaluateConfig.command);
310
+ this.sendToConsole(command);
311
+ }
312
+
313
+ handleRefactoringClick(command) {
314
+ const resolvedCommand = this.replacePlaceholders(command);
315
+ this.sendToConsole(resolvedCommand);
316
+ }
317
+
318
+ async handleVersionClick(version) {
319
+ if (version === this.currentVersion) return;
320
+
321
+ try {
322
+ await this.loadContent(version);
323
+
324
+ // Update active tab
325
+ const tabs = this.container.querySelectorAll('.quality-version-tab');
326
+ tabs.forEach(tab => {
327
+ tab.classList.toggle('active', tab.dataset.version === version);
328
+ });
329
+
330
+ // Update content
331
+ const contentEl = document.getElementById('quality-markdown-content');
332
+ if (contentEl) {
333
+ contentEl.innerHTML = this.renderMarkdown(this.currentContent);
334
+ }
335
+ } catch (error) {
336
+ console.error('[QualityEval] Failed to load version:', error);
337
+ }
338
+ }
339
+
340
+ // -------------------------------------------------------------------------
341
+ // Helpers
342
+ // -------------------------------------------------------------------------
343
+
344
+ replacePlaceholders(command) {
345
+ if (!command) return command;
346
+
347
+ const placeholders = this.config?.placeholder || {};
348
+ let result = command;
349
+
350
+ // Replace known placeholders
351
+ if (placeholders['evaluation-file']) {
352
+ result = result.replace(/<evaluation-file>/g, placeholders['evaluation-file']);
353
+ }
354
+
355
+ return result;
356
+ }
357
+
358
+ sendToConsole(command) {
359
+ // Expand terminal panel first
360
+ if (window.terminalPanel) {
361
+ window.terminalPanel.expand();
362
+ }
363
+
364
+ // Use terminalManager to type command (user can review/edit before pressing Enter)
365
+ if (window.terminalManager && window.terminalManager.sendCopilotPromptCommandNoEnter) {
366
+ window.terminalManager.sendCopilotPromptCommandNoEnter(command);
367
+ } else {
368
+ // Fallback: copy to clipboard and show alert
369
+ navigator.clipboard.writeText(command).then(() => {
370
+ console.log('[QualityEval] Command copied to clipboard:', command);
371
+ alert(`Command copied to clipboard:\n${command}`);
372
+ }).catch(() => {
373
+ console.log('[QualityEval] Command:', command);
374
+ alert(`Copy this command to console:\n${command}`);
375
+ });
376
+ }
377
+ }
378
+
379
+ escapeHtml(text) {
380
+ const div = document.createElement('div');
381
+ div.textContent = text;
382
+ return div.innerHTML;
383
+ }
384
+ }
385
+
386
+ // Export for global access
387
+ window.QualityEvaluationView = QualityEvaluationView;