@lyy0709/contextweaver 1.0.0 → 1.0.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.en.md CHANGED
@@ -134,6 +134,10 @@ cw search --information-request "Database connection logic" --technical-terms "D
134
134
 
135
135
  ### Prompt Enhancement
136
136
 
137
+ <p align="center">
138
+ <img src="docs/prompt-enhancer-ui.png" alt="Prompt Enhancer Web UI" width="800" />
139
+ </p>
140
+
137
141
  ```bash
138
142
  # Launch Web UI for interactive editing (default)
139
143
  cw enhance "Implement a cached semantic search"
package/README.md CHANGED
@@ -134,6 +134,10 @@ cw search --information-request "数据库连接逻辑" --technical-terms "Datab
134
134
 
135
135
  ### 提示词增强
136
136
 
137
+ <p align="center">
138
+ <img src="docs/prompt-enhancer-ui.png" alt="Prompt Enhancer Web UI" width="800" />
139
+ </p>
140
+
137
141
  ```bash
138
142
  # 默认启动 Web UI 交互式编辑
139
143
  cw enhance "帮我实现一个带缓存的语义搜索"
package/dist/index.js CHANGED
@@ -153,7 +153,7 @@ cli.command("enhance <prompt>", "\u589E\u5F3A\u63D0\u793A\u8BCD").option("--no-b
153
153
  }
154
154
  return;
155
155
  }
156
- const { startEnhanceServer } = await import("./server-276GGS5G.js");
156
+ const { startEnhanceServer } = await import("./server-RFAVT7XG.js");
157
157
  const { openBrowser } = await import("./browser-VC5772XM.js");
158
158
  try {
159
159
  const result = await startEnhanceServer(prompt, {
@@ -14,25 +14,25 @@ import net from "net";
14
14
  // src/enhancer/ui.ts
15
15
  function getEnhancePageHtml() {
16
16
  return `<!DOCTYPE html>
17
- <html lang="en">
17
+ <html lang="zh-CN">
18
18
  <head>
19
19
  <meta charset="UTF-8" />
20
20
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
21
- <title>ContextWeaver Prompt Enhancer</title>
21
+ <title>ContextWeaver \u63D0\u793A\u8BCD\u589E\u5F3A</title>
22
22
  <style>
23
23
  :root {
24
- --bg: #0b0f19;
25
- --panel: #111827;
26
- --border: rgba(255, 255, 255, 0.12);
24
+ --bg: #000;
25
+ --panel: #0a0a0a;
26
+ --border: rgba(255, 255, 255, 0.15);
27
27
  --text: rgba(255, 255, 255, 0.92);
28
- --muted: rgba(255, 255, 255, 0.72);
29
- --muted2: rgba(255, 255, 255, 0.56);
30
- --btn: rgba(255, 255, 255, 0.14);
31
- --btnHover: rgba(255, 255, 255, 0.22);
32
- --primary: #2563eb;
33
- --primaryHover: #1d4ed8;
34
- --danger: #ef4444;
35
- --dangerHover: #dc2626;
28
+ --muted: rgba(255, 255, 255, 0.6);
29
+ --muted2: rgba(255, 255, 255, 0.4);
30
+ --btn: rgba(255, 255, 255, 0.1);
31
+ --btnHover: rgba(255, 255, 255, 0.18);
32
+ --primary: #fff;
33
+ --primaryText: #000;
34
+ --danger: rgba(255, 255, 255, 0.06);
35
+ --dangerBorder: rgba(255, 255, 255, 0.25);
36
36
  }
37
37
 
38
38
  * {
@@ -42,10 +42,8 @@ function getEnhancePageHtml() {
42
42
  body {
43
43
  margin: 0;
44
44
  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial,
45
- 'Noto Sans', 'Apple Color Emoji', 'Segoe UI Emoji';
46
- background: radial-gradient(800px circle at 0% 0%, rgba(37, 99, 235, 0.25), transparent 45%),
47
- radial-gradient(800px circle at 100% 0%, rgba(99, 102, 241, 0.18), transparent 45%),
48
- var(--bg);
45
+ 'PingFang SC', 'Microsoft YaHei', 'Noto Sans SC', sans-serif;
46
+ background: var(--bg);
49
47
  color: var(--text);
50
48
  }
51
49
 
@@ -69,6 +67,24 @@ function getEnhancePageHtml() {
69
67
  letter-spacing: 0.2px;
70
68
  }
71
69
 
70
+ .header-right {
71
+ display: flex;
72
+ align-items: center;
73
+ gap: 14px;
74
+ }
75
+
76
+ .countdown {
77
+ font-size: 12px;
78
+ color: var(--muted2);
79
+ font-variant-numeric: tabular-nums;
80
+ white-space: nowrap;
81
+ }
82
+
83
+ .countdown.warn {
84
+ color: rgba(255, 255, 255, 0.85);
85
+ font-weight: 600;
86
+ }
87
+
72
88
  .meta {
73
89
  font-size: 12px;
74
90
  color: var(--muted2);
@@ -77,11 +93,11 @@ function getEnhancePageHtml() {
77
93
  }
78
94
 
79
95
  .panel {
80
- background: rgba(17, 24, 39, 0.92);
96
+ background: var(--panel);
81
97
  border: 1px solid var(--border);
82
98
  border-radius: 14px;
83
99
  overflow: hidden;
84
- box-shadow: 0 18px 60px rgba(0, 0, 0, 0.45);
100
+ box-shadow: 0 18px 60px rgba(0, 0, 0, 0.6);
85
101
  }
86
102
 
87
103
  .grid {
@@ -113,8 +129,7 @@ function getEnhancePageHtml() {
113
129
  font-size: 12px;
114
130
  color: var(--muted);
115
131
  margin: 4px 2px 10px;
116
- text-transform: uppercase;
117
- letter-spacing: 0.8px;
132
+ letter-spacing: 0.5px;
118
133
  }
119
134
 
120
135
  textarea {
@@ -124,7 +139,7 @@ function getEnhancePageHtml() {
124
139
  padding: 12px 12px;
125
140
  border: 1px solid var(--border);
126
141
  border-radius: 10px;
127
- background: rgba(0, 0, 0, 0.28);
142
+ background: rgba(255, 255, 255, 0.04);
128
143
  color: var(--text);
129
144
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, 'Liberation Mono',
130
145
  'Courier New', monospace;
@@ -135,8 +150,8 @@ function getEnhancePageHtml() {
135
150
  }
136
151
 
137
152
  textarea:focus {
138
- border-color: rgba(37, 99, 235, 0.7);
139
- box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.22);
153
+ border-color: rgba(255, 255, 255, 0.45);
154
+ box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.08);
140
155
  }
141
156
 
142
157
  .footer {
@@ -146,7 +161,7 @@ function getEnhancePageHtml() {
146
161
  gap: 12px;
147
162
  padding: 12px 14px;
148
163
  border-top: 1px solid var(--border);
149
- background: rgba(17, 24, 39, 0.98);
164
+ background: rgba(0, 0, 0, 0.5);
150
165
  }
151
166
 
152
167
  .hint {
@@ -186,19 +201,19 @@ function getEnhancePageHtml() {
186
201
 
187
202
  .primary {
188
203
  background: var(--primary);
189
- border-color: rgba(255, 255, 255, 0.15);
204
+ color: var(--primaryText);
205
+ border-color: var(--primary);
190
206
  }
191
207
  .primary:hover {
192
- background: var(--primaryHover);
208
+ background: rgba(255, 255, 255, 0.85);
193
209
  }
194
210
 
195
211
  .danger {
196
- background: rgba(239, 68, 68, 0.12);
197
- border-color: rgba(239, 68, 68, 0.4);
212
+ background: var(--danger);
213
+ border-color: var(--dangerBorder);
198
214
  }
199
215
  .danger:hover {
200
- background: rgba(239, 68, 68, 0.18);
201
- border-color: rgba(239, 68, 68, 0.5);
216
+ background: rgba(255, 255, 255, 0.12);
202
217
  }
203
218
 
204
219
  .status {
@@ -208,11 +223,11 @@ function getEnhancePageHtml() {
208
223
  }
209
224
 
210
225
  .status.error {
211
- color: rgba(248, 113, 113, 0.98);
226
+ color: rgba(255, 120, 120, 0.95);
212
227
  }
213
228
 
214
229
  .status.success {
215
- color: rgba(34, 197, 94, 0.98);
230
+ color: rgba(255, 255, 255, 0.8);
216
231
  }
217
232
 
218
233
  .loading {
@@ -223,39 +238,42 @@ function getEnhancePageHtml() {
223
238
  <body>
224
239
  <div class="container">
225
240
  <div class="header">
226
- <div class="title">ContextWeaver Prompt Enhancer</div>
227
- <div class="meta" id="meta">Loading\u2026</div>
241
+ <div class="title">ContextWeaver \u63D0\u793A\u8BCD\u589E\u5F3A</div>
242
+ <div class="header-right">
243
+ <div class="countdown" id="countdown"></div>
244
+ <div class="meta" id="meta">\u52A0\u8F7D\u4E2D\u2026</div>
245
+ </div>
228
246
  </div>
229
247
 
230
248
  <div class="panel">
231
249
  <div class="grid">
232
250
  <div class="col">
233
251
  <div class="label">
234
- <span>Original prompt (editable)</span>
235
- <span id="origCount">0 chars</span>
252
+ <span>\u539F\u59CB\u63D0\u793A\u8BCD\uFF08\u53EF\u7F16\u8F91\uFF09</span>
253
+ <span id="origCount">0 \u5B57\u7B26</span>
236
254
  </div>
237
- <textarea id="original" spellcheck="false" aria-label="Original prompt"></textarea>
255
+ <textarea id="original" spellcheck="false" aria-label="\u539F\u59CB\u63D0\u793A\u8BCD"></textarea>
238
256
  </div>
239
257
  <div class="col">
240
258
  <div class="label">
241
- <span>Enhanced prompt (editable)</span>
242
- <span id="enhCount">0 chars</span>
259
+ <span>\u589E\u5F3A\u540E\u63D0\u793A\u8BCD\uFF08\u53EF\u7F16\u8F91\uFF09</span>
260
+ <span id="enhCount">0 \u5B57\u7B26</span>
243
261
  </div>
244
- <textarea id="enhanced" spellcheck="false" aria-label="Enhanced prompt"></textarea>
262
+ <textarea id="enhanced" spellcheck="false" aria-label="\u589E\u5F3A\u540E\u63D0\u793A\u8BCD"></textarea>
245
263
  </div>
246
264
  </div>
247
265
 
248
266
  <div class="footer">
249
267
  <div class="hint">
250
- Tip: edit left box, click Re-enhance; tweak right box, click Use Edited.
268
+ \u63D0\u793A\uFF1A\u7F16\u8F91\u5DE6\u680F\u540E\u70B9\u51FB\u300C\u91CD\u65B0\u589E\u5F3A\u300D\uFF1B\u5FAE\u8C03\u53F3\u680F\u540E\u70B9\u51FB\u300C\u4F7F\u7528\u7F16\u8F91\u7248\u300D\u3002
251
269
  <div class="status" id="status"></div>
252
270
  </div>
253
271
  <div class="buttons">
254
- <button id="useOriginalBtn">Use Original</button>
255
- <button id="reEnhanceBtn">Re-enhance</button>
256
- <button class="danger" id="cancelBtn">Cancel</button>
257
- <button id="useEditedBtn" style="display: none">Use Edited</button>
258
- <button class="primary" id="useEnhancedBtn">Use Enhanced</button>
272
+ <button id="useOriginalBtn">\u4F7F\u7528\u539F\u59CB</button>
273
+ <button id="reEnhanceBtn">\u91CD\u65B0\u589E\u5F3A</button>
274
+ <button class="danger" id="cancelBtn">\u53D6\u6D88</button>
275
+ <button id="useEditedBtn" style="display: none">\u4F7F\u7528\u7F16\u8F91\u7248</button>
276
+ <button class="primary" id="useEnhancedBtn">\u4F7F\u7528\u589E\u5F3A\u7248</button>
259
277
  </div>
260
278
  </div>
261
279
  </div>
@@ -273,8 +291,30 @@ function getEnhancePageHtml() {
273
291
  const origCountEl = document.getElementById('origCount');
274
292
  const enhCountEl = document.getElementById('enhCount');
275
293
  const cancelBtn = document.getElementById('cancelBtn');
294
+ const countdownEl = document.getElementById('countdown');
276
295
 
277
296
  let baselineEnhanced = '';
297
+ const TIMEOUT_MS = 8 * 60 * 1000;
298
+ const startTime = Date.now();
299
+ let countdownTimer;
300
+
301
+ function updateCountdown() {
302
+ const elapsed = Date.now() - startTime;
303
+ const remaining = Math.max(0, TIMEOUT_MS - elapsed);
304
+ const mins = Math.floor(remaining / 60000);
305
+ const secs = Math.floor((remaining % 60000) / 1000);
306
+ const str = String(mins).padStart(2, '0') + ':' + String(secs).padStart(2, '0');
307
+ countdownEl.textContent = '\u5269\u4F59 ' + str;
308
+ countdownEl.className = remaining <= 60000 ? 'countdown warn' : 'countdown';
309
+ if (remaining <= 0) {
310
+ clearInterval(countdownTimer);
311
+ countdownEl.textContent = '\u5DF2\u8D85\u65F6';
312
+ setStatus('\u4F1A\u8BDD\u5DF2\u8D85\u65F6\uFF0C\u9875\u9762\u5373\u5C06\u5173\u95ED\u3002', 'error');
313
+ }
314
+ }
315
+
316
+ countdownTimer = setInterval(updateCountdown, 1000);
317
+ updateCountdown();
278
318
 
279
319
  function setStatus(message, kind) {
280
320
  statusEl.textContent = message || '';
@@ -282,8 +322,8 @@ function getEnhancePageHtml() {
282
322
  }
283
323
 
284
324
  function updateCounts() {
285
- origCountEl.textContent = (originalEl.value || '').length + ' chars';
286
- enhCountEl.textContent = (enhancedEl.value || '').length + ' chars';
325
+ origCountEl.textContent = (originalEl.value || '').length + ' \u5B57\u7B26';
326
+ enhCountEl.textContent = (enhancedEl.value || '').length + ' \u5B57\u7B26';
287
327
 
288
328
  const edited = (enhancedEl.value || '').trim() && enhancedEl.value !== baselineEnhanced;
289
329
  useEditedBtn.style.display = edited ? 'inline-block' : 'none';
@@ -300,28 +340,26 @@ function getEnhancePageHtml() {
300
340
  });
301
341
  const data = await res.json();
302
342
  if (!res.ok || data.error) {
303
- throw new Error(data.error || 'Request failed');
343
+ throw new Error(data.error || '\u8BF7\u6C42\u5931\u8D25');
304
344
  }
305
345
  return data;
306
346
  }
307
347
 
308
-
309
348
  async function loadSession() {
310
- setStatus('Loading session\u2026');
349
+ setStatus('\u6B63\u5728\u52A0\u8F7D\u4F1A\u8BDD\u2026');
311
350
  const res = await fetch('/api/session');
312
351
  const data = await res.json();
313
352
  if (!res.ok || data.error) {
314
- throw new Error(data.error || 'Load failed');
353
+ throw new Error(data.error || '\u52A0\u8F7D\u5931\u8D25');
315
354
  }
316
355
 
317
356
  originalEl.value = data.original || '';
318
357
  enhancedEl.value = data.enhanced || '';
319
358
  baselineEnhanced = enhancedEl.value;
320
359
 
321
-
322
360
  metaEl.textContent =
323
- 'Endpoint: ' + (data.endpoint || '-') + ' | Model: ' + (data.model || '-');
324
- setStatus('Ready.');
361
+ '\u7AEF\u70B9: ' + (data.endpoint || '-') + ' | \u6A21\u578B: ' + (data.model || '-');
362
+ setStatus('\u5C31\u7EEA\u3002');
325
363
  updateCounts();
326
364
  }
327
365
 
@@ -333,9 +371,10 @@ function getEnhancePageHtml() {
333
371
  cancelBtn.disabled = true;
334
372
 
335
373
  try {
336
- setStatus('Submitting\u2026');
374
+ setStatus('\u6B63\u5728\u63D0\u4EA4\u2026');
337
375
  await jsonFetch('/api/submit', { action, text });
338
- setStatus('Done! You can close this tab.', 'success');
376
+ clearInterval(countdownTimer);
377
+ setStatus('\u5B8C\u6210\uFF01\u53EF\u4EE5\u5173\u95ED\u6B64\u9875\u9762\u3002', 'success');
339
378
  } catch (e) {
340
379
  const message = e && e.message ? e.message : String(e);
341
380
  setStatus(message, 'error');
@@ -356,7 +395,7 @@ function getEnhancePageHtml() {
356
395
  reEnhanceBtn.addEventListener('click', async () => {
357
396
  const current = (originalEl.value || '').trim();
358
397
  if (!current) {
359
- setStatus('Original prompt is empty.', 'error');
398
+ setStatus('\u539F\u59CB\u63D0\u793A\u8BCD\u4E3A\u7A7A\u3002', 'error');
360
399
  return;
361
400
  }
362
401
 
@@ -366,13 +405,13 @@ function getEnhancePageHtml() {
366
405
  reEnhanceBtn.disabled = true;
367
406
  cancelBtn.disabled = true;
368
407
  document.body.classList.add('loading');
369
- setStatus('Enhancing\u2026');
408
+ setStatus('\u6B63\u5728\u589E\u5F3A\u2026');
370
409
 
371
410
  try {
372
411
  const data = await jsonFetch('/api/re-enhance', { prompt: current });
373
412
  enhancedEl.value = data.enhanced;
374
413
  baselineEnhanced = enhancedEl.value;
375
- setStatus('Enhanced. You can keep editing or submit.', 'success');
414
+ setStatus('\u589E\u5F3A\u5B8C\u6210\uFF0C\u53EF\u7EE7\u7EED\u7F16\u8F91\u6216\u63D0\u4EA4\u3002', 'success');
376
415
  updateCounts();
377
416
  } catch (e) {
378
417
  const message = e && e.message ? e.message : String(e);
@@ -390,7 +429,7 @@ function getEnhancePageHtml() {
390
429
  loadSession().catch((e) => {
391
430
  const message = e && e.message ? e.message : String(e);
392
431
  setStatus(message, 'error');
393
- metaEl.textContent = 'Failed to load.';
432
+ metaEl.textContent = '\u52A0\u8F7D\u5931\u8D25';
394
433
  });
395
434
  </script>
396
435
  </body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lyy0709/contextweaver",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "A context weaving tool for LLMs — with Prompt Enhancer",
5
5
  "license": "MIT",
6
6
  "author": "lyy0709",