instar 0.8.9 → 0.8.11
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/dist/commands/server.js
CHANGED
|
@@ -31,6 +31,7 @@ import { registerPort, unregisterPort, startHeartbeat } from '../core/PortRegist
|
|
|
31
31
|
import { TelegraphService } from '../publishing/TelegraphService.js';
|
|
32
32
|
import { PrivateViewer } from '../publishing/PrivateViewer.js';
|
|
33
33
|
import { TunnelManager } from '../tunnel/TunnelManager.js';
|
|
34
|
+
import { PostUpdateMigrator } from '../core/PostUpdateMigrator.js';
|
|
34
35
|
import { EvolutionManager } from '../core/EvolutionManager.js';
|
|
35
36
|
import { QuotaTracker } from '../monitoring/QuotaTracker.js';
|
|
36
37
|
import { AccountSwitcher } from '../monitoring/AccountSwitcher.js';
|
|
@@ -483,6 +484,15 @@ function cleanupTelegramTempFiles() {
|
|
|
483
484
|
* The self-diagnosis job checks .instar/logs/server.log — this ensures it exists.
|
|
484
485
|
* Log is truncated at 5MB to prevent unbounded growth.
|
|
485
486
|
*/
|
|
487
|
+
function getInstalledVersion() {
|
|
488
|
+
try {
|
|
489
|
+
const pkgPath = path.resolve(new URL(import.meta.url).pathname, '../../../package.json');
|
|
490
|
+
return JSON.parse(fs.readFileSync(pkgPath, 'utf-8')).version || '';
|
|
491
|
+
}
|
|
492
|
+
catch {
|
|
493
|
+
return '';
|
|
494
|
+
}
|
|
495
|
+
}
|
|
486
496
|
function setupServerLog(stateDir) {
|
|
487
497
|
const logDir = path.join(stateDir, '..', 'logs');
|
|
488
498
|
fs.mkdirSync(logDir, { recursive: true });
|
|
@@ -529,6 +539,39 @@ export async function startServer(options) {
|
|
|
529
539
|
setupServerLog(config.stateDir);
|
|
530
540
|
// Clean up stale Telegram temp files on startup
|
|
531
541
|
cleanupTelegramTempFiles();
|
|
542
|
+
// Run post-update migration on startup — ensures agent knowledge stays current
|
|
543
|
+
// even if the update was installed externally (e.g., via `npm install -g instar@latest`)
|
|
544
|
+
try {
|
|
545
|
+
const installedVersion = getInstalledVersion();
|
|
546
|
+
const versionFile = path.join(config.stateDir, 'state', 'last-migrated-version.json');
|
|
547
|
+
let lastMigrated = '';
|
|
548
|
+
try {
|
|
549
|
+
lastMigrated = JSON.parse(fs.readFileSync(versionFile, 'utf-8')).version || '';
|
|
550
|
+
}
|
|
551
|
+
catch { /* first run */ }
|
|
552
|
+
if (installedVersion && installedVersion !== lastMigrated) {
|
|
553
|
+
const hasTelegram = config.messaging?.some((m) => m.type === 'telegram') ?? false;
|
|
554
|
+
const migrator = new PostUpdateMigrator({
|
|
555
|
+
projectDir: config.projectDir,
|
|
556
|
+
stateDir: config.stateDir,
|
|
557
|
+
port: config.port,
|
|
558
|
+
hasTelegram,
|
|
559
|
+
projectName: config.projectName,
|
|
560
|
+
});
|
|
561
|
+
const migration = migrator.migrate();
|
|
562
|
+
if (migration.upgraded.length > 0) {
|
|
563
|
+
console.log(pc.green(` Knowledge upgrade (v${lastMigrated || '?'} → v${installedVersion}): ${migration.upgraded.join(', ')}`));
|
|
564
|
+
}
|
|
565
|
+
// Record the migrated version
|
|
566
|
+
const dir = path.dirname(versionFile);
|
|
567
|
+
if (!fs.existsSync(dir))
|
|
568
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
569
|
+
fs.writeFileSync(versionFile, JSON.stringify({ version: installedVersion, migratedAt: new Date().toISOString() }));
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
catch (err) {
|
|
573
|
+
console.log(pc.yellow(` Post-update migration check: ${err instanceof Error ? err.message : String(err)}`));
|
|
574
|
+
}
|
|
532
575
|
// Register this instance in the port registry (multi-instance support)
|
|
533
576
|
try {
|
|
534
577
|
registerPort(config.projectName, config.port, config.projectDir);
|
|
@@ -196,6 +196,30 @@ Strip the \`[telegram:N]\` prefix before interpreting the message. Respond natur
|
|
|
196
196
|
else {
|
|
197
197
|
result.skipped.push('CLAUDE.md: Private Viewer section already present');
|
|
198
198
|
}
|
|
199
|
+
// Dashboard section
|
|
200
|
+
if (!content.includes('**Dashboard**') && !content.includes('/dashboard')) {
|
|
201
|
+
const section = `
|
|
202
|
+
**Dashboard** — Visual web interface for monitoring and managing sessions. Accessible from any device (phone, tablet, laptop) via tunnel.
|
|
203
|
+
- Local: \`http://localhost:${port}/dashboard\`
|
|
204
|
+
- Remote: When a tunnel is running, the dashboard is accessible at \`{tunnelUrl}/dashboard\`
|
|
205
|
+
- Authentication: Uses a 6-digit PIN (configured via \`dashboardPin\` in \`.instar/config.json\`) — no need to enter the full bearer token
|
|
206
|
+
- Features: Real-time terminal streaming of all running sessions, session management, model badges, mobile-responsive
|
|
207
|
+
- **Sharing the dashboard**: When the user wants to check on sessions from their phone, give them the tunnel URL + PIN. Check tunnel status: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/tunnel\`
|
|
208
|
+
`;
|
|
209
|
+
// Insert after Server Status or before Scripts section
|
|
210
|
+
const insertBefore = content.indexOf('**Scripts**');
|
|
211
|
+
if (insertBefore >= 0) {
|
|
212
|
+
content = content.slice(0, insertBefore) + section + '\n' + content.slice(insertBefore);
|
|
213
|
+
}
|
|
214
|
+
else {
|
|
215
|
+
content += '\n' + section;
|
|
216
|
+
}
|
|
217
|
+
patched = true;
|
|
218
|
+
result.upgraded.push('CLAUDE.md: added Dashboard section');
|
|
219
|
+
}
|
|
220
|
+
else {
|
|
221
|
+
result.skipped.push('CLAUDE.md: Dashboard section already present');
|
|
222
|
+
}
|
|
199
223
|
if (patched) {
|
|
200
224
|
try {
|
|
201
225
|
fs.writeFileSync(claudeMdPath, content);
|
|
@@ -268,6 +268,13 @@ This routes feedback to the Instar maintainers automatically. Valid types: \`bug
|
|
|
268
268
|
**Server Status** — Detailed runtime information beyond health checks.
|
|
269
269
|
- Status: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/status\`
|
|
270
270
|
|
|
271
|
+
**Dashboard** — Visual web interface for monitoring and managing sessions. Accessible from any device (phone, tablet, laptop) via tunnel.
|
|
272
|
+
- Local: \`http://localhost:${port}/dashboard\`
|
|
273
|
+
- Remote: When a tunnel is running, the dashboard is accessible at \`{tunnelUrl}/dashboard\`
|
|
274
|
+
- Authentication: Uses a 6-digit PIN (configured via \`dashboardPin\` in \`.instar/config.json\`) — no need to enter the full bearer token
|
|
275
|
+
- Features: Real-time terminal streaming of all running sessions, session management, model badges, mobile-responsive
|
|
276
|
+
- **Sharing the dashboard**: When the user wants to check on sessions from their phone, give them the tunnel URL + PIN. Check tunnel status: \`curl -H "Authorization: Bearer $AUTH" http://localhost:${port}/tunnel\`
|
|
277
|
+
|
|
271
278
|
**Scripts** — Reusable capabilities in \`.claude/scripts/\`.
|
|
272
279
|
|
|
273
280
|
**Skills** — Reusable behavioral capabilities in \`.claude/skills/\`.
|