instar 0.8.10 → 0.8.12

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/cli.js CHANGED
@@ -624,5 +624,34 @@ autostartCmd
624
624
  console.log(pc.yellow(`Auto-start is not supported on ${process.platform}.`));
625
625
  }
626
626
  });
627
+ // Hidden command: run post-update migration from the NEW binary
628
+ // Called by the auto-updater after `npm install -g` to ensure
629
+ // migrations use the latest code, not the old in-memory modules.
630
+ program
631
+ .command('migrate')
632
+ .description('Run post-update knowledge migration')
633
+ .option('-d, --dir <path>', 'Project directory')
634
+ .action(async (opts) => {
635
+ try {
636
+ const { loadConfig } = await import('./core/Config.js');
637
+ const { PostUpdateMigrator } = await import('./core/PostUpdateMigrator.js');
638
+ const config = loadConfig(opts.dir);
639
+ const hasTelegram = config.messaging?.some((m) => m.type === 'telegram') ?? false;
640
+ const migrator = new PostUpdateMigrator({
641
+ projectDir: config.projectDir,
642
+ stateDir: config.stateDir,
643
+ port: config.port,
644
+ hasTelegram,
645
+ projectName: config.projectName,
646
+ });
647
+ const result = migrator.migrate();
648
+ // Output as JSON for the calling process to parse
649
+ console.log(JSON.stringify(result));
650
+ }
651
+ catch (err) {
652
+ console.error(JSON.stringify({ error: err instanceof Error ? err.message : String(err) }));
653
+ process.exit(1);
654
+ }
655
+ });
627
656
  program.parse();
628
657
  //# sourceMappingURL=cli.js.map
@@ -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);
@@ -128,21 +128,34 @@ export class UpdateChecker {
128
128
  if (success) {
129
129
  this.saveRollbackInfo(previousVersion, newVersion);
130
130
  }
131
- // Post-update migration: upgrade hooks, CLAUDE.md, scripts
131
+ // Post-update migration: spawn the NEW binary to run migrations.
132
+ // Critical: the old process has stale modules in memory — only the
133
+ // new binary on disk has the latest PostUpdateMigrator entries.
132
134
  let migrationSummary = '';
133
135
  if (success && this.migratorConfig) {
134
136
  try {
135
- const migrator = new PostUpdateMigrator(this.migratorConfig);
136
- const migration = migrator.migrate();
137
- if (migration.upgraded.length > 0) {
137
+ const dirFlag = this.migratorConfig.projectDir ? `--dir ${this.migratorConfig.projectDir}` : '';
138
+ const output = await this.execAsync('instar', ['migrate', ...(dirFlag ? ['--dir', this.migratorConfig.projectDir] : [])], 30000);
139
+ const migration = JSON.parse(output);
140
+ if (migration.upgraded && migration.upgraded.length > 0) {
138
141
  migrationSummary = ` Intelligence download: ${migration.upgraded.length} files upgraded (${migration.upgraded.join(', ')}).`;
139
142
  }
140
- if (migration.errors.length > 0) {
143
+ if (migration.errors && migration.errors.length > 0) {
141
144
  migrationSummary += ` Migration warnings: ${migration.errors.join('; ')}.`;
142
145
  }
143
146
  }
144
147
  catch (err) {
145
- migrationSummary = ` Post-update migration failed: ${err instanceof Error ? err.message : String(err)}.`;
148
+ // Fallback: run in-memory migrator (better than nothing)
149
+ try {
150
+ const migrator = new PostUpdateMigrator(this.migratorConfig);
151
+ const migration = migrator.migrate();
152
+ if (migration.upgraded.length > 0) {
153
+ migrationSummary = ` Intelligence download (fallback): ${migration.upgraded.length} files upgraded (${migration.upgraded.join(', ')}).`;
154
+ }
155
+ }
156
+ catch (fallbackErr) {
157
+ migrationSummary = ` Post-update migration failed: ${err instanceof Error ? err.message : String(err)}.`;
158
+ }
146
159
  }
147
160
  }
148
161
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "0.8.10",
3
+ "version": "0.8.12",
4
4
  "description": "Persistent autonomy infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",