@mnemosyne_os/forge 1.2.4 → 1.2.5
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 +32 -890
- package/dist/commands/canvas.js +153 -0
- package/dist/commands/chronicle/index.js +17 -0
- package/dist/commands/chronicle/reader.js +99 -0
- package/dist/commands/chronicle/vault.js +120 -0
- package/dist/commands/chronicle/writer.js +147 -0
- package/dist/commands/chronicle.js +514 -0
- package/dist/commands/workspace.js +129 -0
- package/dist/lib/canvas/canvas.js +92 -0
- package/dist/lib/canvas/renderer.js +40 -0
- package/dist/lib/canvas/templates/cli/files.js +288 -0
- package/dist/lib/chronicle-parser.js +90 -0
- package/dist/lib/chronicle-render.js +76 -0
- package/dist/lib/ui.js +67 -0
- package/package.json +1 -1
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// MnemoCanvas — Orchestrator
|
|
4
|
+
// Handles template discovery, scaffolding, and project initialization
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
7
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
8
|
+
};
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.CANVAS_TEMPLATES = void 0;
|
|
11
|
+
exports.scaffold = scaffold;
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
const renderer_js_1 = require("./renderer.js");
|
|
15
|
+
const files_js_1 = require("./templates/cli/files.js");
|
|
16
|
+
// ── Template registry ─────────────────────────────────────────────────────
|
|
17
|
+
exports.CANVAS_TEMPLATES = [
|
|
18
|
+
{
|
|
19
|
+
id: 'cli',
|
|
20
|
+
name: 'Node.js CLI',
|
|
21
|
+
description: 'A full CLI project — Commander.js + Chalk + Inquirer + TypeScript',
|
|
22
|
+
stack: 'Commander · Chalk · Inquirer · TypeScript',
|
|
23
|
+
icon: '◈',
|
|
24
|
+
files: files_js_1.CLI_TEMPLATE,
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: 'api',
|
|
28
|
+
name: 'REST API',
|
|
29
|
+
description: 'Fastify API with Zod validation — production-ready (coming soon)',
|
|
30
|
+
stack: 'Fastify · Zod · TypeScript',
|
|
31
|
+
icon: '◆',
|
|
32
|
+
files: [], // Phase 2
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
id: 'react-module',
|
|
36
|
+
name: 'React Module',
|
|
37
|
+
description: 'Mnemosyne-compliant React 18 module (coming soon)',
|
|
38
|
+
stack: 'React 18 · Tailwind · Framer Motion',
|
|
39
|
+
icon: '◇',
|
|
40
|
+
files: [], // Phase 2
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
id: 'agent-service',
|
|
44
|
+
name: 'Agent Service',
|
|
45
|
+
description: 'Background AI agent service (coming soon)',
|
|
46
|
+
stack: 'Node.js · TypeScript · Agent structure',
|
|
47
|
+
icon: '✦',
|
|
48
|
+
files: [], // Phase 2
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
// ── Write a single file ───────────────────────────────────────────────────
|
|
52
|
+
function writeFile(rootDir, file, vars, log) {
|
|
53
|
+
const dest = path_1.default.join(rootDir, file.path);
|
|
54
|
+
const dir = path_1.default.dirname(dest);
|
|
55
|
+
fs_1.default.mkdirSync(dir, { recursive: true });
|
|
56
|
+
const rendered = (0, renderer_js_1.render)(file.content, vars);
|
|
57
|
+
fs_1.default.writeFileSync(dest, rendered, 'utf8');
|
|
58
|
+
log(file.path);
|
|
59
|
+
}
|
|
60
|
+
// ── Main scaffold function ────────────────────────────────────────────────
|
|
61
|
+
function scaffold(opts, onFile) {
|
|
62
|
+
const template = exports.CANVAS_TEMPLATES.find(t => t.id === opts.template);
|
|
63
|
+
if (!template)
|
|
64
|
+
throw new Error(`Unknown template: ${opts.template}`);
|
|
65
|
+
if (template.files.length === 0)
|
|
66
|
+
throw new Error(`Template "${opts.template}" is not yet available.`);
|
|
67
|
+
const slug = (0, renderer_js_1.toSlug)(opts.projectName);
|
|
68
|
+
const rootDir = opts.targetDir ?? path_1.default.join(process.cwd(), slug);
|
|
69
|
+
const vars = (0, renderer_js_1.buildVars)(opts.projectName, opts.workspace, opts.author, opts.email);
|
|
70
|
+
const filesCreated = [];
|
|
71
|
+
const errors = [];
|
|
72
|
+
// Refuse to overwrite non-empty existing directory
|
|
73
|
+
if (fs_1.default.existsSync(rootDir)) {
|
|
74
|
+
const contents = fs_1.default.readdirSync(rootDir);
|
|
75
|
+
if (contents.length > 0) {
|
|
76
|
+
throw new Error(`Directory "${rootDir}" already exists and is not empty.`);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
fs_1.default.mkdirSync(rootDir, { recursive: true });
|
|
80
|
+
for (const file of template.files) {
|
|
81
|
+
try {
|
|
82
|
+
writeFile(rootDir, file, vars, (f) => {
|
|
83
|
+
filesCreated.push(f);
|
|
84
|
+
onFile?.(f);
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
errors.push(`${file.path}: ${err.message}`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return { rootDir, filesCreated, errors };
|
|
92
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// MnemoCanvas — Template Renderer
|
|
4
|
+
// Simple variable interpolation engine — zero dependencies
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.render = render;
|
|
8
|
+
exports.toSlug = toSlug;
|
|
9
|
+
exports.toPascal = toPascal;
|
|
10
|
+
exports.buildVars = buildVars;
|
|
11
|
+
// ── Renderer ──────────────────────────────────────────────────────────────
|
|
12
|
+
function render(template, vars) {
|
|
13
|
+
return Object.entries(vars).reduce((out, [key, val]) => {
|
|
14
|
+
return out.replaceAll(`{{${key}}}`, val);
|
|
15
|
+
}, template);
|
|
16
|
+
}
|
|
17
|
+
function toSlug(name) {
|
|
18
|
+
return name
|
|
19
|
+
.replace(/([A-Z])/g, (m, i) => (i > 0 ? '-' : '') + m)
|
|
20
|
+
.toLowerCase()
|
|
21
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
22
|
+
.replace(/-+/g, '-')
|
|
23
|
+
.replace(/^-|-$/g, '');
|
|
24
|
+
}
|
|
25
|
+
function toPascal(slug) {
|
|
26
|
+
return slug.split('-').map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join('');
|
|
27
|
+
}
|
|
28
|
+
function buildVars(projectName, workspace, author = 'XPACEGEMS', email = '') {
|
|
29
|
+
const slug = toSlug(projectName);
|
|
30
|
+
return {
|
|
31
|
+
PROJECT_NAME: projectName,
|
|
32
|
+
PROJECT_SLUG: slug,
|
|
33
|
+
PROJECT_PASCAL: toPascal(slug),
|
|
34
|
+
WORKSPACE: workspace,
|
|
35
|
+
DATE: new Date().toISOString().slice(0, 10),
|
|
36
|
+
AUTHOR: author,
|
|
37
|
+
AUTHOR_EMAIL: email,
|
|
38
|
+
MNEMOFORGE_VERSION: '1.2.4',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -0,0 +1,288 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// MnemoCanvas — CLI Template
|
|
4
|
+
// Generates a full Node.js CLI project wired to the Mnemosyne ecosystem
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.CLI_TEMPLATE = void 0;
|
|
8
|
+
exports.CLI_TEMPLATE = [
|
|
9
|
+
// ── package.json ─────────────────────────────────────────────────────────
|
|
10
|
+
{
|
|
11
|
+
path: 'package.json',
|
|
12
|
+
content: `{
|
|
13
|
+
"name": "{{PROJECT_SLUG}}",
|
|
14
|
+
"version": "0.1.0",
|
|
15
|
+
"description": "{{PROJECT_NAME}} — Built with MnemoForge · Mnemosyne Neural OS",
|
|
16
|
+
"type": "module",
|
|
17
|
+
"bin": {
|
|
18
|
+
"{{PROJECT_SLUG}}": "./dist/cli.js"
|
|
19
|
+
},
|
|
20
|
+
"main": "dist/cli.js",
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"dev": "tsc -w",
|
|
24
|
+
"start": "node dist/cli.js",
|
|
25
|
+
"prepublishOnly": "npm run build"
|
|
26
|
+
},
|
|
27
|
+
"keywords": ["cli", "mnemosyne", "{{PROJECT_SLUG}}"],
|
|
28
|
+
"author": "{{AUTHOR}} <{{AUTHOR_EMAIL}}>",
|
|
29
|
+
"license": "MIT",
|
|
30
|
+
"engines": { "node": ">=18.0.0" },
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"chalk": "^4.1.2",
|
|
33
|
+
"commander": "^11.1.0",
|
|
34
|
+
"inquirer": "^8.2.6"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/inquirer": "^8.2.10",
|
|
38
|
+
"@types/node": "^20.10.0",
|
|
39
|
+
"typescript": "^5.3.3"
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
`,
|
|
43
|
+
},
|
|
44
|
+
// ── tsconfig.json ─────────────────────────────────────────────────────────
|
|
45
|
+
{
|
|
46
|
+
path: 'tsconfig.json',
|
|
47
|
+
content: `{
|
|
48
|
+
"compilerOptions": {
|
|
49
|
+
"target": "ES2022",
|
|
50
|
+
"module": "Node16",
|
|
51
|
+
"moduleResolution": "Node16",
|
|
52
|
+
"outDir": "./dist",
|
|
53
|
+
"rootDir": "./src",
|
|
54
|
+
"strict": true,
|
|
55
|
+
"esModuleInterop": true,
|
|
56
|
+
"skipLibCheck": true,
|
|
57
|
+
"declaration": true,
|
|
58
|
+
"declarationMap": true,
|
|
59
|
+
"sourceMap": true
|
|
60
|
+
},
|
|
61
|
+
"include": ["src/**/*"],
|
|
62
|
+
"exclude": ["node_modules", "dist"]
|
|
63
|
+
}
|
|
64
|
+
`,
|
|
65
|
+
},
|
|
66
|
+
// ── .gitignore ────────────────────────────────────────────────────────────
|
|
67
|
+
{
|
|
68
|
+
path: '.gitignore',
|
|
69
|
+
content: `node_modules/
|
|
70
|
+
dist/
|
|
71
|
+
*.log
|
|
72
|
+
.DS_Store
|
|
73
|
+
Thumbs.db
|
|
74
|
+
`,
|
|
75
|
+
},
|
|
76
|
+
// ── .cursorrules ──────────────────────────────────────────────────────────
|
|
77
|
+
{
|
|
78
|
+
path: '.cursorrules',
|
|
79
|
+
content: `# {{PROJECT_NAME}} — AI Governance Rules
|
|
80
|
+
# Generated by MnemoForge v{{MNEMOFORGE_VERSION}} on {{DATE}}
|
|
81
|
+
# Workspace: {{WORKSPACE}}
|
|
82
|
+
|
|
83
|
+
## Identity
|
|
84
|
+
You are working on **{{PROJECT_NAME}}**, a CLI tool built within the Mnemosyne Neural OS ecosystem.
|
|
85
|
+
|
|
86
|
+
## Language & Stack
|
|
87
|
+
- TypeScript 5 (strict mode) — zero \`any\` tolerance
|
|
88
|
+
- Node.js 18+ (ESM modules)
|
|
89
|
+
- Commander.js for command structure
|
|
90
|
+
- Chalk for terminal colors
|
|
91
|
+
- Inquirer.js for interactive prompts
|
|
92
|
+
|
|
93
|
+
## Code Standards
|
|
94
|
+
- All functions must have explicit return types
|
|
95
|
+
- Use \`chalk.hex()\` for colors — never plain chalk colors
|
|
96
|
+
- Error handling: always use \`process.exit(1)\` on fatal errors
|
|
97
|
+
- Console output: always prefix with 2 spaces for alignment
|
|
98
|
+
|
|
99
|
+
## Chronicle & Memory
|
|
100
|
+
- Before starting a session, run: \`mnemoforge workspace show\`
|
|
101
|
+
- After key decisions, write a chronicle in \`handbook/chronicles/\`
|
|
102
|
+
- Archive chronicles with: \`mnemoforge chronicle archive --file <path>\`
|
|
103
|
+
|
|
104
|
+
## Mnemosyne Neural OS
|
|
105
|
+
This project is part of the Mnemosyne ecosystem.
|
|
106
|
+
Repository: https://github.com/yaka0007/Mnemosyne-Neural-OS
|
|
107
|
+
`,
|
|
108
|
+
},
|
|
109
|
+
// ── AGENT_INSTRUCTIONS.md ─────────────────────────────────────────────────
|
|
110
|
+
{
|
|
111
|
+
path: 'AGENT_INSTRUCTIONS.md',
|
|
112
|
+
content: `# {{PROJECT_NAME}} — Agent Mission Directive
|
|
113
|
+
*Generated by MnemoForge v{{MNEMOFORGE_VERSION}} · {{DATE}}*
|
|
114
|
+
|
|
115
|
+
## Context
|
|
116
|
+
You are an AI agent (Cursor, Claude, Copilot, or similar) working on **{{PROJECT_NAME}}**.
|
|
117
|
+
This is a CLI tool built within the **{{WORKSPACE}}** workspace of the Mnemosyne Neural OS ecosystem.
|
|
118
|
+
|
|
119
|
+
## Before You Start
|
|
120
|
+
1. Run \`mnemoforge workspace show\` to read the project safety rules
|
|
121
|
+
2. Read the latest chronicle: \`mnemoforge chronicle open\`
|
|
122
|
+
3. Check the vault: \`mnemoforge chronicle list\`
|
|
123
|
+
|
|
124
|
+
## Your Mission
|
|
125
|
+
Build and maintain {{PROJECT_NAME}} according to Mnemosyne standards:
|
|
126
|
+
- TypeScript strict, no \`any\`
|
|
127
|
+
- Clean terminal UX with chalk color palette
|
|
128
|
+
- Write a chronicle after each significant session
|
|
129
|
+
|
|
130
|
+
## After You Finish
|
|
131
|
+
Archive your session chronicle:
|
|
132
|
+
\`\`\`bash
|
|
133
|
+
mnemoforge chronicle archive --file handbook/chronicles/CHRONICLE-YYYY-MM-DD-session.md
|
|
134
|
+
\`\`\`
|
|
135
|
+
|
|
136
|
+
*"The model may not know who it is. The soul does."*
|
|
137
|
+
`,
|
|
138
|
+
},
|
|
139
|
+
// ── WORKSPACE.json ────────────────────────────────────────────────────────
|
|
140
|
+
{
|
|
141
|
+
path: 'WORKSPACE.json',
|
|
142
|
+
content: `{
|
|
143
|
+
"workspace": "{{WORKSPACE}}",
|
|
144
|
+
"project": "{{PROJECT_NAME}}",
|
|
145
|
+
"version": "0.1.0",
|
|
146
|
+
"created": "{{DATE}}",
|
|
147
|
+
"last_updated": "{{DATE}}",
|
|
148
|
+
"updated_by": "MnemoForge canvas",
|
|
149
|
+
"npm": {
|
|
150
|
+
"rules": [
|
|
151
|
+
"Always bump version before npm publish",
|
|
152
|
+
"Run pnpm run build before publish",
|
|
153
|
+
"Never publish with node_modules in package"
|
|
154
|
+
]
|
|
155
|
+
},
|
|
156
|
+
"architecture": {
|
|
157
|
+
"rules": [
|
|
158
|
+
"TypeScript strict — zero any",
|
|
159
|
+
"Commander.js for all command structure",
|
|
160
|
+
"Chalk hex colors only — no plain chalk colors",
|
|
161
|
+
"All errors use process.exit(1)"
|
|
162
|
+
]
|
|
163
|
+
},
|
|
164
|
+
"neural_coding": {
|
|
165
|
+
"principles": [
|
|
166
|
+
"Read workspace rules before starting any session",
|
|
167
|
+
"Write a chronicle after each significant decision",
|
|
168
|
+
"The agent understands context — no mechanical re-explanations"
|
|
169
|
+
]
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
`,
|
|
173
|
+
},
|
|
174
|
+
// ── src/cli.ts ────────────────────────────────────────────────────────────
|
|
175
|
+
{
|
|
176
|
+
path: 'src/cli.ts',
|
|
177
|
+
content: `#!/usr/bin/env node
|
|
178
|
+
// {{PROJECT_NAME}} CLI
|
|
179
|
+
// Generated by MnemoForge v{{MNEMOFORGE_VERSION}} · {{DATE}}
|
|
180
|
+
|
|
181
|
+
import { Command } from 'commander';
|
|
182
|
+
import chalk from 'chalk';
|
|
183
|
+
|
|
184
|
+
// ── Color palette ─────────────────────────────────────────────────────────
|
|
185
|
+
const V = chalk.hex('#8B5CF6');
|
|
186
|
+
const V2 = chalk.hex('#A78BFA');
|
|
187
|
+
const DIM = chalk.gray;
|
|
188
|
+
|
|
189
|
+
// ── Program ───────────────────────────────────────────────────────────────
|
|
190
|
+
const program = new Command()
|
|
191
|
+
.name('{{PROJECT_SLUG}}')
|
|
192
|
+
.description('{{PROJECT_NAME}} — Built with MnemoForge · Mnemosyne Neural OS')
|
|
193
|
+
.version('0.1.0', '-v, --version')
|
|
194
|
+
.action(() => {
|
|
195
|
+
console.log(V.bold('\\n ⬡ {{PROJECT_NAME}}\\n'));
|
|
196
|
+
console.log(DIM(' A Mnemosyne-grade CLI.'));
|
|
197
|
+
console.log(DIM(' Run ') + chalk.white('{{PROJECT_SLUG}} --help') + DIM(' to see commands.\\n'));
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
// ── Example command ───────────────────────────────────────────────────────
|
|
201
|
+
program
|
|
202
|
+
.command('hello')
|
|
203
|
+
.description('Say hello')
|
|
204
|
+
.action(() => {
|
|
205
|
+
console.log(V2.bold('\\n ⬡ {{PROJECT_NAME}}\\n'));
|
|
206
|
+
console.log(chalk.white(' Hello from {{PROJECT_NAME}}! 👋\\n'));
|
|
207
|
+
});
|
|
208
|
+
|
|
209
|
+
program.parse(process.argv);
|
|
210
|
+
`,
|
|
211
|
+
},
|
|
212
|
+
// ── handbook/chronicles/.gitkeep ─────────────────────────────────────────
|
|
213
|
+
{
|
|
214
|
+
path: 'handbook/chronicles/.gitkeep',
|
|
215
|
+
content: '',
|
|
216
|
+
},
|
|
217
|
+
// ── ROADMAP.md ────────────────────────────────────────────────────────────
|
|
218
|
+
{
|
|
219
|
+
path: 'ROADMAP.md',
|
|
220
|
+
content: `# {{PROJECT_NAME}} — Roadmap
|
|
221
|
+
*Generated by MnemoForge v{{MNEMOFORGE_VERSION}} · {{DATE}}*
|
|
222
|
+
*Workspace: {{WORKSPACE}}*
|
|
223
|
+
|
|
224
|
+
---
|
|
225
|
+
|
|
226
|
+
## Context
|
|
227
|
+
|
|
228
|
+
**{{PROJECT_NAME}}** is a CLI tool built within the {{WORKSPACE}} ecosystem.
|
|
229
|
+
This file is the **source of truth for any agent** working on this project.
|
|
230
|
+
Read it before starting any session.
|
|
231
|
+
|
|
232
|
+
## Current State
|
|
233
|
+
|
|
234
|
+
- Version: 0.1.0
|
|
235
|
+
- Stack: Node.js · TypeScript · Commander.js · Chalk · Inquirer
|
|
236
|
+
- Chronicles vault: \`handbook/chronicles/\`
|
|
237
|
+
|
|
238
|
+
## Before You Start (Agent Checklist)
|
|
239
|
+
|
|
240
|
+
1. Read this file
|
|
241
|
+
2. Run \`mnemoforge workspace show\` for safety rules
|
|
242
|
+
3. Run \`mnemoforge chronicle list\` to see recent decisions
|
|
243
|
+
|
|
244
|
+
---
|
|
245
|
+
|
|
246
|
+
## Phase 0 — Foundation *(current)*
|
|
247
|
+
|
|
248
|
+
- [x] Project scaffolded with MnemoForge canvas
|
|
249
|
+
- [ ] Core command structure in \`src/cli.ts\`
|
|
250
|
+
- [ ] First release published
|
|
251
|
+
|
|
252
|
+
## Phase 1 — Core Features
|
|
253
|
+
|
|
254
|
+
> Define your features here
|
|
255
|
+
|
|
256
|
+
- [ ] Feature A
|
|
257
|
+
- [ ] Feature B
|
|
258
|
+
|
|
259
|
+
## Phase 2 — Polish
|
|
260
|
+
|
|
261
|
+
> Testing, documentation, UX
|
|
262
|
+
|
|
263
|
+
- [ ] Unit tests
|
|
264
|
+
- [ ] README documentation
|
|
265
|
+
- [ ] First public release
|
|
266
|
+
|
|
267
|
+
---
|
|
268
|
+
|
|
269
|
+
## Key Decisions
|
|
270
|
+
|
|
271
|
+
> Log important architectural decisions here as you go.
|
|
272
|
+
> Example: "2026-04-05 — Chose Commander.js over yargs for simpler API"
|
|
273
|
+
|
|
274
|
+
| Date | Decision | Rationale |
|
|
275
|
+
|------|----------|-----------|
|
|
276
|
+
| {{DATE}} | Project created with MnemoForge canvas | Standard Mnemosyne CLI template |
|
|
277
|
+
|
|
278
|
+
---
|
|
279
|
+
|
|
280
|
+
## Agent Notes
|
|
281
|
+
|
|
282
|
+
*Add notes for your AI agent here — context, constraints, things to remember.*
|
|
283
|
+
|
|
284
|
+
- This project follows Mnemosyne Neural OS coding standards
|
|
285
|
+
- Write a chronicle after significant work sessions
|
|
286
|
+
`,
|
|
287
|
+
},
|
|
288
|
+
];
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.parseChronicle = parseChronicle;
|
|
7
|
+
exports.getChronicleType = getChronicleType;
|
|
8
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
9
|
+
// MnemoChronicle — Markdown Parser
|
|
10
|
+
// Extracts metadata (title, type, date, tags, excerpt) from chronicle files
|
|
11
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
12
|
+
const fs_1 = __importDefault(require("fs"));
|
|
13
|
+
const path_1 = __importDefault(require("path"));
|
|
14
|
+
function parseChronicle(filename, dir) {
|
|
15
|
+
const filePath = path_1.default.join(dir, filename);
|
|
16
|
+
const rawSlug = filename.replace(/^CHRONICLE-\d{4}-\d{2}-\d{2}-/, '').replace(/\.md$/, '').replace(/-/g, ' ');
|
|
17
|
+
let title = rawSlug.charAt(0).toUpperCase() + rawSlug.slice(1);
|
|
18
|
+
let type = 'session';
|
|
19
|
+
const tags = [];
|
|
20
|
+
let excerpt = '';
|
|
21
|
+
const dateMatch = filename.match(/CHRONICLE-(\d{4}-\d{2}-\d{2})/);
|
|
22
|
+
let date = dateMatch ? dateMatch[1] : '';
|
|
23
|
+
try {
|
|
24
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf8');
|
|
25
|
+
const resonanceIdx = raw.indexOf('<!--resonance');
|
|
26
|
+
const content = resonanceIdx !== -1 ? raw.slice(0, resonanceIdx) : raw;
|
|
27
|
+
const lines = content.split('\n');
|
|
28
|
+
let inFrontmatter = false, frontmatterDone = false, dividerCount = 0;
|
|
29
|
+
const bodyLines = [];
|
|
30
|
+
for (const line of lines.slice(0, 40)) {
|
|
31
|
+
const l = line.trim();
|
|
32
|
+
if (l === '---' && !frontmatterDone) {
|
|
33
|
+
dividerCount++;
|
|
34
|
+
if (dividerCount === 1) {
|
|
35
|
+
inFrontmatter = true;
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
if (dividerCount === 2) {
|
|
39
|
+
inFrontmatter = false;
|
|
40
|
+
frontmatterDone = true;
|
|
41
|
+
continue;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
if (inFrontmatter) {
|
|
45
|
+
if (l.startsWith('title:'))
|
|
46
|
+
title = l.replace('title:', '').trim().replace(/^['"]|['"]$/g, '');
|
|
47
|
+
if (l.startsWith('type:'))
|
|
48
|
+
type = l.replace('type:', '').trim();
|
|
49
|
+
if (l.startsWith('date:') && l.match(/\d{4}-\d{2}-\d{2}/))
|
|
50
|
+
date = l.match(/\d{4}-\d{2}-\d{2}/)[0];
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
if (l.startsWith('# ')) {
|
|
54
|
+
title = l.slice(2).trim();
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
if (l.startsWith('**Type**:')) {
|
|
58
|
+
type = l.replace('**Type**:', '').trim().toLowerCase();
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
61
|
+
if (l.startsWith('**Date**:')) {
|
|
62
|
+
const d = l.replace('**Date**:', '').trim();
|
|
63
|
+
if (d.match(/\d{4}-\d{2}-\d{2}/))
|
|
64
|
+
date = d.match(/\d{4}-\d{2}-\d{2}/)[0];
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (l.match(/^\*\*\w/))
|
|
68
|
+
continue;
|
|
69
|
+
if (l === '---')
|
|
70
|
+
continue;
|
|
71
|
+
if (l.length > 8 && frontmatterDone && !l.startsWith('#') && !l.match(/^[\w_]+:\s*/))
|
|
72
|
+
bodyLines.push(l);
|
|
73
|
+
}
|
|
74
|
+
const firstMeaningful = bodyLines.find(l => l.length > 10);
|
|
75
|
+
if (firstMeaningful)
|
|
76
|
+
excerpt = firstMeaningful.slice(0, 92) + (firstMeaningful.length > 92 ? '…' : '');
|
|
77
|
+
}
|
|
78
|
+
catch { /* use slug defaults */ }
|
|
79
|
+
return { title, type, tags, excerpt, date };
|
|
80
|
+
}
|
|
81
|
+
function getChronicleType(filename, dir) {
|
|
82
|
+
try {
|
|
83
|
+
const raw = fs_1.default.readFileSync(path_1.default.join(dir, filename), 'utf8').slice(0, 800);
|
|
84
|
+
const m = raw.match(/\*\*Type\*\*:\s*(\w+)/i) || raw.match(/^type:\s*(\w+)/im);
|
|
85
|
+
return m ? m[1].toLowerCase() : 'session';
|
|
86
|
+
}
|
|
87
|
+
catch {
|
|
88
|
+
return 'session';
|
|
89
|
+
}
|
|
90
|
+
}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.renderChronicle = renderChronicle;
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
// MnemoChronicle — Terminal Renderer
|
|
9
|
+
// Renders Markdown chronicle files as colored terminal output
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
const fs_1 = __importDefault(require("fs"));
|
|
12
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
13
|
+
function renderChronicle(filePath) {
|
|
14
|
+
const raw = fs_1.default.readFileSync(filePath, 'utf8');
|
|
15
|
+
const resonanceIdx = raw.indexOf('<!--resonance');
|
|
16
|
+
const content = resonanceIdx !== -1 ? raw.slice(0, resonanceIdx) : raw;
|
|
17
|
+
console.log('\n' + chalk_1.default.hex('#312E81')(' ' + '─'.repeat(72)));
|
|
18
|
+
console.log(chalk_1.default.gray(` ${filePath}`));
|
|
19
|
+
console.log(chalk_1.default.hex('#312E81')(' ' + '─'.repeat(72)) + '\n');
|
|
20
|
+
let dividerCount = 0;
|
|
21
|
+
for (const line of content.split('\n')) {
|
|
22
|
+
const l = line.trim();
|
|
23
|
+
if (l.startsWith('# ')) {
|
|
24
|
+
console.log('\n ' + chalk_1.default.hex('#8B5CF6').bold(l.slice(2)));
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (l.startsWith('## ')) {
|
|
28
|
+
console.log('\n ' + chalk_1.default.hex('#A78BFA').bold(' ' + l.slice(3)));
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
if (l.startsWith('### ')) {
|
|
32
|
+
console.log(' ' + chalk_1.default.hex('#C084FC')(' ' + l.slice(4)));
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
if (l === '---') {
|
|
36
|
+
dividerCount++;
|
|
37
|
+
if (dividerCount <= 2)
|
|
38
|
+
console.log(chalk_1.default.hex('#312E81')(' ' + '─'.repeat(60)));
|
|
39
|
+
continue;
|
|
40
|
+
}
|
|
41
|
+
if (l.match(/^\*\*[\w\s]+\*\*:/)) {
|
|
42
|
+
const p = l.match(/^\*\*([\w\s]+)\*\*:\s*(.*)/) ?? [];
|
|
43
|
+
if (p.length >= 3)
|
|
44
|
+
console.log(' ' + chalk_1.default.hex('#64748B')(` ${p[1].padEnd(14)} `) + chalk_1.default.hex('#94A3B8')(p[2]));
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
if (l.startsWith('> ')) {
|
|
48
|
+
console.log(' ' + chalk_1.default.hex('#7C3AED')(' │ ') + chalk_1.default.hex('#DDD6FE').italic(l.slice(2)));
|
|
49
|
+
continue;
|
|
50
|
+
}
|
|
51
|
+
if (l.startsWith('- ') || l.startsWith('* ')) {
|
|
52
|
+
console.log(' ' + chalk_1.default.hex('#6B7280')(' • ') + chalk_1.default.white(l.slice(2)));
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
if (l.match(/^\d+\. /)) {
|
|
56
|
+
console.log(' ' + chalk_1.default.hex('#6B7280')(' ') + chalk_1.default.white(l));
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (l.startsWith('```')) {
|
|
60
|
+
console.log(' ' + chalk_1.default.hex('#312E81')(' ' + '·'.repeat(50)));
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
if (l.match(/^#\w/) && !l.startsWith('# ')) {
|
|
64
|
+
console.log('\n ' + (l.match(/#\w+/g) ?? []).map((t) => chalk_1.default.hex('#7C3AED')(t)).join(' '));
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (l.length > 0) {
|
|
68
|
+
console.log(' ' + chalk_1.default.hex('#E2E8F0')(' ' + l));
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
console.log();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
console.log('\n' + chalk_1.default.hex('#312E81')(' ' + '─'.repeat(72)));
|
|
75
|
+
console.log(chalk_1.default.gray(`\n Open in editor → `) + chalk_1.default.white(`code "${filePath}"`) + '\n');
|
|
76
|
+
}
|
package/dist/lib/ui.js
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.ASCII = void 0;
|
|
7
|
+
exports.showWelcome = showWelcome;
|
|
8
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
9
|
+
// MnemoForge — Welcome Dashboard (shared UI)
|
|
10
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
11
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
12
|
+
const vault_js_1 = require("./vault.js");
|
|
13
|
+
const V = chalk_1.default.hex('#8B5CF6');
|
|
14
|
+
const V2 = chalk_1.default.hex('#A78BFA');
|
|
15
|
+
const V3 = chalk_1.default.hex('#C4B5FD');
|
|
16
|
+
const V4 = chalk_1.default.hex('#DDD6FE');
|
|
17
|
+
const DIM = chalk_1.default.gray;
|
|
18
|
+
exports.ASCII = [
|
|
19
|
+
V('███╗ ███╗███╗ ██╗███████╗███╗ ███╗ ██████╗ '),
|
|
20
|
+
V('████╗ ████║████╗ ██║██╔════╝████╗ ████║██╔═══██╗'),
|
|
21
|
+
V2('██╔████╔██║██╔██╗ ██║█████╗ ██╔████╔██║██║ ██║'),
|
|
22
|
+
V3('██║╚██╔╝██║██║╚██╗██║██╔══╝ ██║╚██╔╝██║██║ ██║'),
|
|
23
|
+
V4('██║ ╚═╝ ██║██║ ╚████║███████╗██║ ╚═╝ ██║╚██████╔╝'),
|
|
24
|
+
chalk_1.default.hex('#EDE9FE')('╚═╝ ╚═╝╚═╝ ╚═══╝╚══════╝╚═╝ ╚═╝ ╚═════╝ '),
|
|
25
|
+
].join('\n');
|
|
26
|
+
function showWelcome() {
|
|
27
|
+
const config = (0, vault_js_1.loadVaultConfig)();
|
|
28
|
+
const w = '═'.repeat(52);
|
|
29
|
+
const pad = (s, n) => s + ' '.repeat(Math.max(0, n - s.length));
|
|
30
|
+
console.log();
|
|
31
|
+
console.log(exports.ASCII);
|
|
32
|
+
console.log();
|
|
33
|
+
console.log(V(' ╔' + w + '╗'));
|
|
34
|
+
console.log(V(' ║') + chalk_1.default.hex('#F5F3FF').bold(' M N E M O S Y N E O S — N E U R A L O S ') + V(' ║'));
|
|
35
|
+
console.log(V(' ║') + DIM(' MnemoForge CLI v1.2.4 · XPACEGEMS LLC ') + V(' ║'));
|
|
36
|
+
console.log(V(' ╠' + w + '╣'));
|
|
37
|
+
if (config) {
|
|
38
|
+
const profiles = config.registeredModels ?? [];
|
|
39
|
+
const activeChron = (0, vault_js_1.listChronicles)(config).length;
|
|
40
|
+
const activeStyle = config.defaultChronicleStyle ?? 'session';
|
|
41
|
+
const activeName = config.ide + ' / ' + config.provider;
|
|
42
|
+
console.log(V(' ║') + DIM(' ⚡ RESONANCE PROFILES ') + V(' ║'));
|
|
43
|
+
console.log(V(' ║') + ' ' + chalk_1.default.green('★') + ' ' + chalk_1.default.white(pad(activeName, 32)) + DIM(pad(activeStyle, 12)) + DIM(activeChron + ' chron.') + ' ' + chalk_1.default.green('[✓]') + ' ' + V(' ║'));
|
|
44
|
+
if (profiles.length > 0) {
|
|
45
|
+
console.log(V(' ║') + ' ' + DIM('─'.repeat(48)) + V(' ║'));
|
|
46
|
+
profiles.forEach((p, i) => {
|
|
47
|
+
const pName = p.ide + ' / ' + p.provider;
|
|
48
|
+
const pStyle = p.defaultChronicleStyle ?? 'session';
|
|
49
|
+
console.log(V(' ║') + ' ' + DIM('○') + ' ' + DIM(pad(pName, 32)) + DIM(pad(pStyle, 12)) + DIM('[' + (i + 1) + '] switch') + ' ' + V(' ║'));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log(V(' ║') + chalk_1.default.yellow(' ⚠ No vault configured.') + ' Run: ' + chalk_1.default.white('mnemoforge chronicle init') + ' ' + V(' ║'));
|
|
55
|
+
}
|
|
56
|
+
console.log(V(' ╠' + w + '╣'));
|
|
57
|
+
console.log(V(' ║') + DIM(' COMMANDS ') + V(' ║'));
|
|
58
|
+
console.log(V(' ║') + ' ' + V2('chronicle init ') + DIM('─ add / reconfigure a profile ') + V(' ║'));
|
|
59
|
+
console.log(V(' ║') + ' ' + V2('chronicle switch ') + DIM('─ change active profile ') + V(' ║'));
|
|
60
|
+
console.log(V(' ║') + ' ' + V2('chronicle commit ') + DIM('─ write a new chronicle ') + V(' ║'));
|
|
61
|
+
console.log(V(' ║') + ' ' + V2('chronicle list ') + DIM('─ explore vault ') + V(' ║'));
|
|
62
|
+
console.log(V(' ║') + ' ' + V2('canvas ') + DIM('─ scaffold a new project ') + V(' ║'));
|
|
63
|
+
console.log(V(' ╠' + w + '╣'));
|
|
64
|
+
console.log(V(' ║') + DIM(' "Memory is the architecture of intelligence." ') + V(' ║'));
|
|
65
|
+
console.log(V(' ╚' + w + '╝'));
|
|
66
|
+
console.log();
|
|
67
|
+
}
|
package/package.json
CHANGED