@mnemosyne_os/forge 1.2.3 → 1.2.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.
Files changed (2) hide show
  1. package/dist/cli.js +137 -2
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -667,9 +667,144 @@ chronicle
667
667
  }
668
668
  });
669
669
  console.log('\n' + SEP + '\n');
670
- console.log(chalk_1.default.gray(' Tip: ') + chalk_1.default.white('mnemoforge chronicle list -n 20') + chalk_1.default.gray(' to show more\n'));
670
+ console.log(chalk_1.default.gray(' Tip: ') + chalk_1.default.white('mnemoforge chronicle list -n 20') + chalk_1.default.gray(' · ') + chalk_1.default.white('mnemoforge chronicle open') + chalk_1.default.gray(' to browse interactively\n'));
671
+ });
672
+ // ── chronicle open — interactive picker + inline reader ───────────────────
673
+ chronicle
674
+ .command('open')
675
+ .description('Browse and read chronicles interactively (arrow keys + Enter)')
676
+ .option('-n, --count <n>', 'Max chronicles to show in picker', '20')
677
+ .action(async (opts) => {
678
+ const config = (0, vault_js_1.loadVaultConfig)();
679
+ if (!config) {
680
+ console.log(chalk_1.default.red('\n ✖ Not initialized. Run: mnemoforge chronicle init\n'));
681
+ process.exit(1);
682
+ }
683
+ const { resolveChronicleDir } = require('./lib/vault.js');
684
+ const dir = resolveChronicleDir(config);
685
+ const all = (0, vault_js_1.listChronicles)(config);
686
+ if (all.length === 0) {
687
+ console.log(chalk_1.default.yellow('\n No chronicles in vault yet.\n'));
688
+ return;
689
+ }
690
+ // ── Build picker choices ──────────────────────────────
691
+ const TYPE_ICONS = {
692
+ session: '◈', decision: '◆', reflection: '◇', sweep: '↻', narcissus: '✦',
693
+ };
694
+ const getType = (filename) => {
695
+ try {
696
+ const raw = fs_1.default.readFileSync(path_1.default.join(dir, filename), 'utf8').slice(0, 800);
697
+ const m = raw.match(/\*\*Type\*\*:\s*(\w+)/i) || raw.match(/^type:\s*(\w+)/im);
698
+ return m ? m[1].toLowerCase() : 'session';
699
+ }
700
+ catch {
701
+ return 'session';
702
+ }
703
+ };
704
+ const picks = all.slice(0, parseInt(opts.count || '20'));
705
+ const choices = picks.map((filename) => {
706
+ const dateMatch = filename.match(/CHRONICLE-(\d{4}-\d{2}-\d{2})/);
707
+ const date = dateMatch ? dateMatch[1] : '';
708
+ const slug = filename.replace(/^CHRONICLE-\d{4}-\d{2}-\d{2}-/, '').replace(/\.md$/, '').replace(/-/g, ' ');
709
+ const type = getType(filename);
710
+ const icon = TYPE_ICONS[type] ?? '○';
711
+ return {
712
+ name: ` ${icon} ${chalk_1.default.hex('#CBD5E1')(date)} ${chalk_1.default.white(slug)}`,
713
+ value: filename,
714
+ short: slug,
715
+ };
716
+ });
717
+ choices.push({ name: chalk_1.default.gray('\n ✖ Cancel'), value: '__cancel__', short: 'cancel' });
718
+ console.log(chalk_1.default.hex('#8B5CF6').bold('\n ⬡ MnemoChronicle — Open\n'));
719
+ const { selected } = await inquirer_1.default.prompt([{
720
+ type: 'list',
721
+ name: 'selected',
722
+ message: chalk_1.default.hex('#A78BFA')('Select a chronicle to read:'),
723
+ choices,
724
+ pageSize: 15,
725
+ }]);
726
+ if (selected === '__cancel__')
727
+ return;
728
+ // ── Render chronicle ─────────────────────────────────
729
+ const filePath = path_1.default.join(dir, selected);
730
+ const raw = fs_1.default.readFileSync(filePath, 'utf8');
731
+ const resonanceIdx = raw.indexOf('<!--resonance');
732
+ const content = resonanceIdx !== -1 ? raw.slice(0, resonanceIdx) : raw;
733
+ const lines = content.split('\n');
734
+ console.log('\n' + chalk_1.default.hex('#312E81')(' ' + '─'.repeat(72)));
735
+ console.log(chalk_1.default.gray(` ${filePath}`));
736
+ console.log(chalk_1.default.hex('#312E81')(' ' + '─'.repeat(72)) + '\n');
737
+ let inMeta = false;
738
+ let metaDone = false;
739
+ let dividerCount = 0;
740
+ for (const line of lines) {
741
+ const l = line.trim();
742
+ // Title
743
+ if (l.startsWith('# ')) {
744
+ console.log('\n ' + chalk_1.default.hex('#8B5CF6').bold(l.slice(2)));
745
+ continue;
746
+ }
747
+ // Section headers
748
+ if (l.startsWith('## ')) {
749
+ console.log('\n ' + chalk_1.default.hex('#A78BFA').bold(' ' + l.slice(3)));
750
+ continue;
751
+ }
752
+ if (l.startsWith('### ')) {
753
+ console.log(' ' + chalk_1.default.hex('#C084FC')(' ' + l.slice(4)));
754
+ continue;
755
+ }
756
+ // Dividers — dim, show once as meta separator
757
+ if (l === '---') {
758
+ dividerCount++;
759
+ if (dividerCount <= 2)
760
+ console.log(chalk_1.default.hex('#312E81')(' ' + '─'.repeat(60)));
761
+ continue;
762
+ }
763
+ // Bold metadata fields **Key**: value
764
+ if (l.match(/^\*\*[\w\s]+\*\*:/)) {
765
+ const parts = l.match(/^\*\*([\w\s]+)\*\*:\s*(.*)/) ?? [];
766
+ if (parts.length >= 3) {
767
+ console.log(' ' + chalk_1.default.hex('#64748B')(` ${parts[1].padEnd(14)} `) + chalk_1.default.hex('#94A3B8')(parts[2]));
768
+ }
769
+ continue;
770
+ }
771
+ // Blockquotes
772
+ if (l.startsWith('> ')) {
773
+ console.log(' ' + chalk_1.default.hex('#7C3AED')(' │ ') + chalk_1.default.hex('#DDD6FE').italic(l.slice(2)));
774
+ continue;
775
+ }
776
+ // List items
777
+ if (l.startsWith('- ') || l.startsWith('* ')) {
778
+ console.log(' ' + chalk_1.default.hex('#6B7280')(' • ') + chalk_1.default.white(l.slice(2)));
779
+ continue;
780
+ }
781
+ // Numbered list
782
+ if (l.match(/^\d+\. /)) {
783
+ console.log(' ' + chalk_1.default.hex('#6B7280')(' ') + chalk_1.default.white(l));
784
+ continue;
785
+ }
786
+ // Code blocks (single line inline or fence)
787
+ if (l.startsWith('```')) {
788
+ console.log(' ' + chalk_1.default.hex('#312E81')(' ' + '·'.repeat(50)));
789
+ continue;
790
+ }
791
+ // Tags line
792
+ if (l.match(/^#\w/) && !l.startsWith('# ')) {
793
+ const tags = l.match(/#\w+/g) ?? [];
794
+ console.log('\n ' + tags.map(t => chalk_1.default.hex('#7C3AED')(t)).join(' '));
795
+ continue;
796
+ }
797
+ // Regular text
798
+ if (l.length > 0) {
799
+ console.log(' ' + chalk_1.default.hex('#E2E8F0')(' ' + l));
800
+ }
801
+ else {
802
+ console.log();
803
+ }
804
+ }
805
+ console.log('\n' + chalk_1.default.hex('#312E81')(' ' + '─'.repeat(72)));
806
+ console.log(chalk_1.default.gray(`\n Tip: open in editor → `) + chalk_1.default.white(`code "${filePath}"`) + '\n');
671
807
  });
672
- // ── chronicle switch ───────────────────────────────────────────
673
808
  chronicle
674
809
  .command('switch')
675
810
  .description('Switch the active profile to another registered one')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mnemosyne_os/forge",
3
- "version": "1.2.3",
3
+ "version": "1.2.4",
4
4
  "description": "MnemoForge CLI — The AI Inception Engine for the Mnemosyne Neural OS ecosystem. Scaffold sovereign, AI-governed modules in one command.",
5
5
  "files": [
6
6
  "dist/",