@ia-ccun/code-agent-claw 0.0.1 → 0.0.4

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/bin/cli.js CHANGED
@@ -2,6 +2,26 @@
2
2
 
3
3
  const { spawn } = require('child_process');
4
4
  const path = require('path');
5
+ const fs = require('fs');
6
+
7
+ const args = process.argv.slice(2);
8
+
9
+ // 获取版本号
10
+ if (args.includes('--version') || args.includes('-v')) {
11
+ const packageJson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json'), 'utf-8'));
12
+ console.log(packageJson.version);
13
+ process.exit(0);
14
+ }
15
+
16
+ // 显示帮助
17
+ if (args.includes('--help') || args.includes('-h')) {
18
+ console.log('Usage: code-agent-claw [options]');
19
+ console.log('');
20
+ console.log('Options:');
21
+ console.log(' --version, -v Show version number');
22
+ console.log(' --help, -h Show this help message');
23
+ process.exit(0);
24
+ }
5
25
 
6
26
  const distPath = path.join(__dirname, '..', 'dist', 'index.js');
7
27
 
@@ -3,12 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>AICode Agent</title>
7
- <link rel="preconnect" href="https://fonts.googleapis.com">
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
10
- <link rel="stylesheet" href="juejin.css">
11
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
6
+ <title>AICode Claw</title>
12
7
  <style>
13
8
  /* ========================================
14
9
  ANTHROPIC STYLE - AI Agent Console
@@ -64,8 +59,8 @@
64
59
  --space-2xl: 32px;
65
60
 
66
61
  /* Typography - Inter for clean readability */
67
- --font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
68
- --font-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
62
+ --font-display: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
63
+ --font-mono: 'SF Mono', Consolas, 'PingFang SC', 'Microsoft YaHei Mono', monospace;
69
64
 
70
65
  /* Effects */
71
66
  --shadow-sm: 0 1px 3px rgba(61, 61, 58, 0.08);
@@ -262,7 +257,7 @@
262
257
  background: var(--bg-tertiary);
263
258
  padding: 2px 6px;
264
259
  border-radius: 4px;
265
- font-family: 'JetBrains Mono', monospace;
260
+ font-family: var(--font-mono);
266
261
  font-size: 0.75rem;
267
262
  color: var(--accent-green);
268
263
  }
@@ -387,11 +382,22 @@
387
382
  animation: pulse 2s ease-in-out infinite;
388
383
  }
389
384
 
385
+ .status-dot.disconnected {
386
+ background: var(--error);
387
+ box-shadow: 0 0 8px rgba(201, 74, 74, 0.5);
388
+ animation: pulse-red 1.5s ease-in-out infinite;
389
+ }
390
+
390
391
  @keyframes pulse {
391
392
  0%, 100% { opacity: 1; }
392
393
  50% { opacity: 0.6; }
393
394
  }
394
395
 
396
+ @keyframes pulse-red {
397
+ 0%, 100% { opacity: 1; box-shadow: 0 0 8px rgba(201, 74, 74, 0.5); }
398
+ 50% { opacity: 0.5; box-shadow: 0 0 16px rgba(201, 74, 74, 0.8); }
399
+ }
400
+
395
401
  /* Action buttons */
396
402
  .action-btn {
397
403
  width: 36px;
@@ -860,8 +866,9 @@
860
866
  /* Quick questions */
861
867
  .quick-questions {
862
868
  display: flex;
863
- flex-wrap: wrap;
869
+ flex-wrap: nowrap;
864
870
  gap: var(--space-sm);
871
+ overflow-x: auto;
865
872
  }
866
873
 
867
874
  .quick-question {
@@ -874,6 +881,8 @@
874
881
  color: var(--text-secondary);
875
882
  cursor: pointer;
876
883
  transition: all 0.2s ease;
884
+ white-space: nowrap;
885
+ flex-shrink: 0;
877
886
  }
878
887
 
879
888
  .quick-question:hover {
@@ -1068,14 +1077,14 @@
1068
1077
  }
1069
1078
  </style>
1070
1079
  </head>
1071
- <body class="light">
1080
+ <body class="dark">
1072
1081
  <div class="container">
1073
1082
  <!-- Header -->
1074
1083
  <header class="header">
1075
1084
  <div class="header-left">
1076
1085
  <div class="logo">
1077
1086
  <img class="logo-icon" src="aicode.svg" alt="AICode">
1078
- <span class="logo-text">AICode Agent</span>
1087
+ <span class="logo-text">AICode Claw</span>
1079
1088
  </div>
1080
1089
  <div class="status-badge">
1081
1090
  <div class="status-dot" id="statusDot"></div>
@@ -1163,7 +1172,7 @@
1163
1172
  <div id="responseTab" class="panel-content">
1164
1173
  <div class="empty-state" id="emptyState">
1165
1174
  <img class="empty-logo" src="aicode.svg" alt="AICode">
1166
- <div class="empty-title">你好,我是 AICode Agent</div>
1175
+ <div class="empty-title">你好,我是 AICode Claw</div>
1167
1176
  <div class="empty-desc">我可以帮助你完成以下任务:</div>
1168
1177
  <div class="empty-features">
1169
1178
  <div class="feature-item"><span class="feature-icon">📝</span> 代码编写与调试</div>
@@ -1189,7 +1198,7 @@
1189
1198
  <aside class="input-panel">
1190
1199
  <!-- Quick Questions Card -->
1191
1200
  <div class="card">
1192
- <div class="card-title">Quick Commands</div>
1201
+ <div class="card-title">快捷命令</div>
1193
1202
  <div class="quick-questions">
1194
1203
  <span class="quick-question" onclick="setPrompt('你好,请介绍一下你自己')">👋 自我介绍</span>
1195
1204
  <span class="quick-question" onclick="setPrompt('帮我写一个 Hello World')">Hello World</span>
@@ -1200,19 +1209,19 @@
1200
1209
 
1201
1210
  <!-- Message Type Card -->
1202
1211
  <div class="card">
1203
- <div class="card-title">Message Type</div>
1212
+ <div class="card-title">消息类型</div>
1204
1213
  <div class="msg-type-group">
1205
1214
  <input type="radio" id="type-prompt" name="msgType" value="prompt" checked onchange="onMsgTypeChange()">
1206
- <label for="type-prompt">Prompt</label>
1215
+ <label for="type-prompt" title="发送新的任务请求,AI 会从头开始处理">对话</label>
1207
1216
 
1208
1217
  <input type="radio" id="type-steer" name="msgType" value="steer" onchange="onMsgTypeChange()">
1209
- <label for="type-steer">Steer</label>
1218
+ <label for="type-steer" title="引导或干预当前正在执行的任务,AI 会中断并响应你的引导">引导</label>
1210
1219
 
1211
1220
  <input type="radio" id="type-follow" name="msgType" value="follow_up" onchange="onMsgTypeChange()">
1212
- <label for="type-follow">Follow</label>
1221
+ <label for="type-follow" title="在当前对话基础上继续交流,AI 记得之前的上下文">追问</label>
1213
1222
 
1214
1223
  <input type="radio" id="type-abort" name="msgType" value="abort" onchange="onMsgTypeChange()">
1215
- <label for="type-abort">Abort</label>
1224
+ <label for="type-abort" title="立即终止当前正在执行的任务">中止</label>
1216
1225
  </div>
1217
1226
  </div>
1218
1227
 
@@ -1236,12 +1245,6 @@
1236
1245
  <script>
1237
1246
  const API_BASE = '';
1238
1247
  let messages = [];
1239
-
1240
- // Configure marked
1241
- marked.setOptions({
1242
- breaks: true,
1243
- gfm: true
1244
- });
1245
1248
  let isStreaming = false;
1246
1249
  let lastRenderTime = 0;
1247
1250
  const RENDER_THROTTLE = 100;
@@ -1257,9 +1260,9 @@
1257
1260
 
1258
1261
  // Toggle theme
1259
1262
  function toggleTheme() {
1260
- document.body.classList.toggle('light');
1263
+ document.body.classList.toggle('dark');
1261
1264
  const icon = document.getElementById('themeIcon');
1262
- icon.textContent = document.body.classList.contains('light') ? '' : '';
1265
+ icon.textContent = document.body.classList.contains('dark') ? '' : '';
1263
1266
  }
1264
1267
 
1265
1268
  // Toggle width
@@ -1450,11 +1453,12 @@
1450
1453
 
1451
1454
  if (data.success && data.data && data.data.running) {
1452
1455
  statusDot.classList.add('active');
1453
- statusText.textContent = 'Connected';
1456
+ statusDot.classList.remove('disconnected');
1457
+ statusText.textContent = '已连接';
1454
1458
  } else {
1455
1459
  statusDot.classList.remove('active');
1456
- statusText.textContent = 'Not Connected';
1457
- openConfigModal();
1460
+ statusDot.classList.add('disconnected');
1461
+ statusText.textContent = '未连接';
1458
1462
  }
1459
1463
  } catch (e) {
1460
1464
  console.error('Check status error:', e);
@@ -1482,13 +1486,19 @@
1482
1486
 
1483
1487
  if (data.running) {
1484
1488
  statusDot.classList.add('active');
1485
- statusText.textContent = 'Connected';
1489
+ statusDot.classList.remove('disconnected');
1490
+ statusText.textContent = '已连接';
1486
1491
  } else {
1487
1492
  statusDot.classList.remove('active');
1488
- statusText.textContent = 'Disconnected';
1493
+ statusDot.classList.add('disconnected');
1494
+ statusText.textContent = '未连接';
1489
1495
  }
1490
1496
  } catch (e) {
1491
- document.getElementById('statusText').textContent = 'Error';
1497
+ const statusDot = document.getElementById('statusDot');
1498
+ const statusText = document.getElementById('statusText');
1499
+ statusDot.classList.remove('active');
1500
+ statusDot.classList.add('disconnected');
1501
+ statusText.textContent = '连接错误';
1492
1502
  }
1493
1503
  }
1494
1504
 
@@ -1502,12 +1512,12 @@
1502
1512
  const msgType = getMsgType();
1503
1513
  const input = document.getElementById('promptInput');
1504
1514
  const placeholder = {
1505
- 'prompt': 'Enter your message...',
1506
- 'steer': 'Enter steer message (interrupts current operation)...',
1507
- 'follow_up': 'Enter follow-up message...',
1508
- 'abort': 'Confirm abort?'
1515
+ 'prompt': '输入你的任务描述,AI 会从头开始处理...',
1516
+ 'steer': '输入引导信息,干预当前正在执行的任务...',
1517
+ 'follow_up': '输入追问内容,AI 会基于之前的上下文继续...',
1518
+ 'abort': '点击发送即可立即终止当前任务'
1509
1519
  };
1510
- input.placeholder = placeholder[msgType] || 'Enter your message...';
1520
+ input.placeholder = placeholder[msgType] || '输入你的任务描述...';
1511
1521
 
1512
1522
  if (msgType === 'abort') {
1513
1523
  input.value = '';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ia-ccun/code-agent-claw",
3
- "version": "0.0.1",
3
+ "version": "0.0.4",
4
4
  "description": "Code Agent Claw WebUI - Node.js implementation with frontend configuration",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
package/public/index.html CHANGED
@@ -3,12 +3,7 @@
3
3
  <head>
4
4
  <meta charset="UTF-8">
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>AICode Agent</title>
7
- <link rel="preconnect" href="https://fonts.googleapis.com">
8
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
9
- <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
10
- <link rel="stylesheet" href="juejin.css">
11
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
6
+ <title>AICode Claw</title>
12
7
  <style>
13
8
  /* ========================================
14
9
  ANTHROPIC STYLE - AI Agent Console
@@ -64,8 +59,8 @@
64
59
  --space-2xl: 32px;
65
60
 
66
61
  /* Typography - Inter for clean readability */
67
- --font-display: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
68
- --font-mono: 'JetBrains Mono', 'SF Mono', Consolas, monospace;
62
+ --font-display: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'PingFang SC', 'Microsoft YaHei', sans-serif;
63
+ --font-mono: 'SF Mono', Consolas, 'PingFang SC', 'Microsoft YaHei Mono', monospace;
69
64
 
70
65
  /* Effects */
71
66
  --shadow-sm: 0 1px 3px rgba(61, 61, 58, 0.08);
@@ -262,7 +257,7 @@
262
257
  background: var(--bg-tertiary);
263
258
  padding: 2px 6px;
264
259
  border-radius: 4px;
265
- font-family: 'JetBrains Mono', monospace;
260
+ font-family: var(--font-mono);
266
261
  font-size: 0.75rem;
267
262
  color: var(--accent-green);
268
263
  }
@@ -387,11 +382,22 @@
387
382
  animation: pulse 2s ease-in-out infinite;
388
383
  }
389
384
 
385
+ .status-dot.disconnected {
386
+ background: var(--error);
387
+ box-shadow: 0 0 8px rgba(201, 74, 74, 0.5);
388
+ animation: pulse-red 1.5s ease-in-out infinite;
389
+ }
390
+
390
391
  @keyframes pulse {
391
392
  0%, 100% { opacity: 1; }
392
393
  50% { opacity: 0.6; }
393
394
  }
394
395
 
396
+ @keyframes pulse-red {
397
+ 0%, 100% { opacity: 1; box-shadow: 0 0 8px rgba(201, 74, 74, 0.5); }
398
+ 50% { opacity: 0.5; box-shadow: 0 0 16px rgba(201, 74, 74, 0.8); }
399
+ }
400
+
395
401
  /* Action buttons */
396
402
  .action-btn {
397
403
  width: 36px;
@@ -860,8 +866,9 @@
860
866
  /* Quick questions */
861
867
  .quick-questions {
862
868
  display: flex;
863
- flex-wrap: wrap;
869
+ flex-wrap: nowrap;
864
870
  gap: var(--space-sm);
871
+ overflow-x: auto;
865
872
  }
866
873
 
867
874
  .quick-question {
@@ -874,6 +881,8 @@
874
881
  color: var(--text-secondary);
875
882
  cursor: pointer;
876
883
  transition: all 0.2s ease;
884
+ white-space: nowrap;
885
+ flex-shrink: 0;
877
886
  }
878
887
 
879
888
  .quick-question:hover {
@@ -1068,14 +1077,14 @@
1068
1077
  }
1069
1078
  </style>
1070
1079
  </head>
1071
- <body class="light">
1080
+ <body class="dark">
1072
1081
  <div class="container">
1073
1082
  <!-- Header -->
1074
1083
  <header class="header">
1075
1084
  <div class="header-left">
1076
1085
  <div class="logo">
1077
1086
  <img class="logo-icon" src="aicode.svg" alt="AICode">
1078
- <span class="logo-text">AICode Agent</span>
1087
+ <span class="logo-text">AICode Claw</span>
1079
1088
  </div>
1080
1089
  <div class="status-badge">
1081
1090
  <div class="status-dot" id="statusDot"></div>
@@ -1163,7 +1172,7 @@
1163
1172
  <div id="responseTab" class="panel-content">
1164
1173
  <div class="empty-state" id="emptyState">
1165
1174
  <img class="empty-logo" src="aicode.svg" alt="AICode">
1166
- <div class="empty-title">你好,我是 AICode Agent</div>
1175
+ <div class="empty-title">你好,我是 AICode Claw</div>
1167
1176
  <div class="empty-desc">我可以帮助你完成以下任务:</div>
1168
1177
  <div class="empty-features">
1169
1178
  <div class="feature-item"><span class="feature-icon">📝</span> 代码编写与调试</div>
@@ -1189,7 +1198,7 @@
1189
1198
  <aside class="input-panel">
1190
1199
  <!-- Quick Questions Card -->
1191
1200
  <div class="card">
1192
- <div class="card-title">Quick Commands</div>
1201
+ <div class="card-title">快捷命令</div>
1193
1202
  <div class="quick-questions">
1194
1203
  <span class="quick-question" onclick="setPrompt('你好,请介绍一下你自己')">👋 自我介绍</span>
1195
1204
  <span class="quick-question" onclick="setPrompt('帮我写一个 Hello World')">Hello World</span>
@@ -1200,19 +1209,19 @@
1200
1209
 
1201
1210
  <!-- Message Type Card -->
1202
1211
  <div class="card">
1203
- <div class="card-title">Message Type</div>
1212
+ <div class="card-title">消息类型</div>
1204
1213
  <div class="msg-type-group">
1205
1214
  <input type="radio" id="type-prompt" name="msgType" value="prompt" checked onchange="onMsgTypeChange()">
1206
- <label for="type-prompt">Prompt</label>
1215
+ <label for="type-prompt" title="发送新的任务请求,AI 会从头开始处理">对话</label>
1207
1216
 
1208
1217
  <input type="radio" id="type-steer" name="msgType" value="steer" onchange="onMsgTypeChange()">
1209
- <label for="type-steer">Steer</label>
1218
+ <label for="type-steer" title="引导或干预当前正在执行的任务,AI 会中断并响应你的引导">引导</label>
1210
1219
 
1211
1220
  <input type="radio" id="type-follow" name="msgType" value="follow_up" onchange="onMsgTypeChange()">
1212
- <label for="type-follow">Follow</label>
1221
+ <label for="type-follow" title="在当前对话基础上继续交流,AI 记得之前的上下文">追问</label>
1213
1222
 
1214
1223
  <input type="radio" id="type-abort" name="msgType" value="abort" onchange="onMsgTypeChange()">
1215
- <label for="type-abort">Abort</label>
1224
+ <label for="type-abort" title="立即终止当前正在执行的任务">中止</label>
1216
1225
  </div>
1217
1226
  </div>
1218
1227
 
@@ -1236,12 +1245,6 @@
1236
1245
  <script>
1237
1246
  const API_BASE = '';
1238
1247
  let messages = [];
1239
-
1240
- // Configure marked
1241
- marked.setOptions({
1242
- breaks: true,
1243
- gfm: true
1244
- });
1245
1248
  let isStreaming = false;
1246
1249
  let lastRenderTime = 0;
1247
1250
  const RENDER_THROTTLE = 100;
@@ -1257,9 +1260,9 @@
1257
1260
 
1258
1261
  // Toggle theme
1259
1262
  function toggleTheme() {
1260
- document.body.classList.toggle('light');
1263
+ document.body.classList.toggle('dark');
1261
1264
  const icon = document.getElementById('themeIcon');
1262
- icon.textContent = document.body.classList.contains('light') ? '' : '';
1265
+ icon.textContent = document.body.classList.contains('dark') ? '' : '';
1263
1266
  }
1264
1267
 
1265
1268
  // Toggle width
@@ -1450,11 +1453,12 @@
1450
1453
 
1451
1454
  if (data.success && data.data && data.data.running) {
1452
1455
  statusDot.classList.add('active');
1453
- statusText.textContent = 'Connected';
1456
+ statusDot.classList.remove('disconnected');
1457
+ statusText.textContent = '已连接';
1454
1458
  } else {
1455
1459
  statusDot.classList.remove('active');
1456
- statusText.textContent = 'Not Connected';
1457
- openConfigModal();
1460
+ statusDot.classList.add('disconnected');
1461
+ statusText.textContent = '未连接';
1458
1462
  }
1459
1463
  } catch (e) {
1460
1464
  console.error('Check status error:', e);
@@ -1482,13 +1486,19 @@
1482
1486
 
1483
1487
  if (data.running) {
1484
1488
  statusDot.classList.add('active');
1485
- statusText.textContent = 'Connected';
1489
+ statusDot.classList.remove('disconnected');
1490
+ statusText.textContent = '已连接';
1486
1491
  } else {
1487
1492
  statusDot.classList.remove('active');
1488
- statusText.textContent = 'Disconnected';
1493
+ statusDot.classList.add('disconnected');
1494
+ statusText.textContent = '未连接';
1489
1495
  }
1490
1496
  } catch (e) {
1491
- document.getElementById('statusText').textContent = 'Error';
1497
+ const statusDot = document.getElementById('statusDot');
1498
+ const statusText = document.getElementById('statusText');
1499
+ statusDot.classList.remove('active');
1500
+ statusDot.classList.add('disconnected');
1501
+ statusText.textContent = '连接错误';
1492
1502
  }
1493
1503
  }
1494
1504
 
@@ -1502,12 +1512,12 @@
1502
1512
  const msgType = getMsgType();
1503
1513
  const input = document.getElementById('promptInput');
1504
1514
  const placeholder = {
1505
- 'prompt': 'Enter your message...',
1506
- 'steer': 'Enter steer message (interrupts current operation)...',
1507
- 'follow_up': 'Enter follow-up message...',
1508
- 'abort': 'Confirm abort?'
1515
+ 'prompt': '输入你的任务描述,AI 会从头开始处理...',
1516
+ 'steer': '输入引导信息,干预当前正在执行的任务...',
1517
+ 'follow_up': '输入追问内容,AI 会基于之前的上下文继续...',
1518
+ 'abort': '点击发送即可立即终止当前任务'
1509
1519
  };
1510
- input.placeholder = placeholder[msgType] || 'Enter your message...';
1520
+ input.placeholder = placeholder[msgType] || '输入你的任务描述...';
1511
1521
 
1512
1522
  if (msgType === 'abort') {
1513
1523
  input.value = '';