@farazirfan/costar-server-executor 1.7.0 → 1.7.1

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 (2) hide show
  1. package/package.json +1 -1
  2. package/public/index.html +116 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farazirfan/costar-server-executor",
3
- "version": "1.7.0",
3
+ "version": "1.7.1",
4
4
  "description": "CoStar Server Executor - 24/7 autonomous agent in TypeScript (cloned from OpenClaw)",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/public/index.html CHANGED
@@ -93,6 +93,51 @@
93
93
  margin-top: 2px;
94
94
  }
95
95
 
96
+ .sidebar-logo .version span {
97
+ color: var(--accent);
98
+ font-family: var(--mono);
99
+ font-size: 10px;
100
+ }
101
+
102
+ .update-banner {
103
+ display: flex;
104
+ align-items: center;
105
+ justify-content: space-between;
106
+ background: var(--accent-dim);
107
+ border: 1px solid rgba(99,102,241,.3);
108
+ border-radius: var(--radius);
109
+ padding: 10px 14px;
110
+ margin-bottom: 16px;
111
+ }
112
+
113
+ .update-banner .update-info {
114
+ font-size: 13px;
115
+ color: var(--text-primary);
116
+ }
117
+
118
+ .update-banner .update-info small {
119
+ display: block;
120
+ color: var(--text-secondary);
121
+ font-size: 11px;
122
+ margin-top: 2px;
123
+ }
124
+
125
+ .update-btn {
126
+ background: var(--accent);
127
+ color: white;
128
+ border: none;
129
+ padding: 6px 14px;
130
+ border-radius: var(--radius);
131
+ font-size: 12px;
132
+ font-weight: 600;
133
+ cursor: pointer;
134
+ white-space: nowrap;
135
+ transition: background .15s;
136
+ }
137
+
138
+ .update-btn:hover { background: var(--accent-hover); }
139
+ .update-btn:disabled { opacity: .5; cursor: not-allowed; }
140
+
96
141
  .sidebar-nav {
97
142
  flex: 1;
98
143
  padding: 12px 10px;
@@ -751,7 +796,7 @@
751
796
  <div class="logo-icon">C</div>
752
797
  <div>
753
798
  <h1>CoStar</h1>
754
- <div class="version">Server Executor</div>
799
+ <div class="version">Server Executor <span id="sidebar-version"></span></div>
755
800
  </div>
756
801
  </div>
757
802
 
@@ -816,6 +861,7 @@
816
861
 
817
862
  <!-- ═══ Dashboard Page ═══ -->
818
863
  <div class="page active" id="page-dashboard">
864
+ <div id="update-banner-container"></div>
819
865
  <div class="stat-grid" id="stats-grid">
820
866
  <div class="stat-card">
821
867
  <div class="stat-label">Uptime</div>
@@ -1090,9 +1136,20 @@
1090
1136
  // ─── Dashboard ───────────────────────────────────
1091
1137
  async function loadDashboard() {
1092
1138
  try {
1093
- const status = await api('/api/status');
1139
+ const [status, versionInfo] = await Promise.all([
1140
+ api('/api/status'),
1141
+ api('/api/version').catch(() => null),
1142
+ ]);
1094
1143
  const a = status.agent;
1095
1144
 
1145
+ // Show version in sidebar
1146
+ if (versionInfo?.version) {
1147
+ document.getElementById('sidebar-version').textContent = `v${versionInfo.version}`;
1148
+ }
1149
+
1150
+ // Update banner — check for newer version on npm
1151
+ renderUpdateBanner(versionInfo);
1152
+
1096
1153
  // Stats
1097
1154
  const uptime = formatUptime(a.uptime);
1098
1155
  document.getElementById('stat-uptime').textContent = uptime;
@@ -1113,6 +1170,8 @@
1113
1170
  // System info
1114
1171
  const info = document.getElementById('system-info');
1115
1172
  info.innerHTML = [
1173
+ row('Version', versionInfo?.version ? `v${versionInfo.version}` : '--'),
1174
+ row('Auto-Update', versionInfo?.autoUpdateEnabled ? 'Enabled' : 'Disabled'),
1116
1175
  row('User ID', a.userId),
1117
1176
  row('Workspace', a.workspaceDir),
1118
1177
  row('Node', a.nodeVersion),
@@ -1126,6 +1185,61 @@
1126
1185
  }
1127
1186
  }
1128
1187
 
1188
+ // ─── Update Banner ────────────────────────────────
1189
+ async function renderUpdateBanner(versionInfo) {
1190
+ const container = document.getElementById('update-banner-container');
1191
+ if (!container) return;
1192
+
1193
+ // Always show version + manual update button
1194
+ if (!versionInfo) {
1195
+ container.innerHTML = '';
1196
+ return;
1197
+ }
1198
+
1199
+ const v = esc(versionInfo.version || 'unknown');
1200
+ const autoUpdate = versionInfo.autoUpdateEnabled;
1201
+ const updating = versionInfo.updateInProgress;
1202
+
1203
+ container.innerHTML = `
1204
+ <div class="update-banner">
1205
+ <div class="update-info">
1206
+ Running <strong>v${v}</strong>
1207
+ <small>${autoUpdate ? 'Auto-update enabled — checks every 24h' : 'Auto-update disabled'}</small>
1208
+ </div>
1209
+ <button class="update-btn" id="manual-update-btn" onclick="triggerManualUpdate()" ${updating ? 'disabled' : ''}>
1210
+ ${updating ? 'Updating...' : 'Update Now'}
1211
+ </button>
1212
+ </div>
1213
+ `;
1214
+ }
1215
+
1216
+ async function triggerManualUpdate() {
1217
+ const btn = document.getElementById('manual-update-btn');
1218
+ if (!btn) return;
1219
+
1220
+ btn.disabled = true;
1221
+ btn.textContent = 'Updating...';
1222
+
1223
+ try {
1224
+ const result = await api('/api/update', {
1225
+ method: 'POST',
1226
+ headers: { 'Content-Type': 'application/json' },
1227
+ body: JSON.stringify({ version: 'latest' }),
1228
+ });
1229
+ btn.textContent = 'Restarting...';
1230
+ // The server will restart, so the page will lose connection
1231
+ setTimeout(() => {
1232
+ btn.textContent = 'Reconnecting...';
1233
+ // Try to reload after a delay to reconnect to the new version
1234
+ setTimeout(() => location.reload(), 8000);
1235
+ }, 5000);
1236
+ } catch (err) {
1237
+ btn.disabled = false;
1238
+ btn.textContent = 'Update Failed — Retry';
1239
+ console.error('Update failed:', err);
1240
+ }
1241
+ }
1242
+
1129
1243
  function row(key, value) {
1130
1244
  return `<div class="config-row"><span class="config-key">${esc(key)}</span><span class="config-value">${esc(String(value || '--'))}</span></div>`;
1131
1245
  }