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.
@@ -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/\`.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "0.8.9",
3
+ "version": "0.8.11",
4
4
  "description": "Persistent autonomy infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",