memnant 0.1.0
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/LICENSE +21 -0
- package/README.md +101 -0
- package/dist/cli/ask.d.ts +9 -0
- package/dist/cli/ask.d.ts.map +1 -0
- package/dist/cli/ask.js +103 -0
- package/dist/cli/ask.js.map +1 -0
- package/dist/cli/check-copy.d.ts +8 -0
- package/dist/cli/check-copy.d.ts.map +1 -0
- package/dist/cli/check-copy.js +68 -0
- package/dist/cli/check-copy.js.map +1 -0
- package/dist/cli/check-design.d.ts +8 -0
- package/dist/cli/check-design.d.ts.map +1 -0
- package/dist/cli/check-design.js +100 -0
- package/dist/cli/check-design.js.map +1 -0
- package/dist/cli/default-action.d.ts +10 -0
- package/dist/cli/default-action.d.ts.map +1 -0
- package/dist/cli/default-action.js +94 -0
- package/dist/cli/default-action.js.map +1 -0
- package/dist/cli/export.d.ts +10 -0
- package/dist/cli/export.d.ts.map +1 -0
- package/dist/cli/export.js +109 -0
- package/dist/cli/export.js.map +1 -0
- package/dist/cli/index.d.ts +12 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +77 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +10 -0
- package/dist/cli/init.d.ts.map +1 -0
- package/dist/cli/init.js +157 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/instructions.d.ts +12 -0
- package/dist/cli/instructions.d.ts.map +1 -0
- package/dist/cli/instructions.js +117 -0
- package/dist/cli/instructions.js.map +1 -0
- package/dist/cli/lint.d.ts +9 -0
- package/dist/cli/lint.d.ts.map +1 -0
- package/dist/cli/lint.js +131 -0
- package/dist/cli/lint.js.map +1 -0
- package/dist/cli/log.d.ts +10 -0
- package/dist/cli/log.d.ts.map +1 -0
- package/dist/cli/log.js +83 -0
- package/dist/cli/log.js.map +1 -0
- package/dist/cli/promote.d.ts +9 -0
- package/dist/cli/promote.d.ts.map +1 -0
- package/dist/cli/promote.js +70 -0
- package/dist/cli/promote.js.map +1 -0
- package/dist/cli/recall.d.ts +10 -0
- package/dist/cli/recall.d.ts.map +1 -0
- package/dist/cli/recall.js +98 -0
- package/dist/cli/recall.js.map +1 -0
- package/dist/cli/serve.d.ts +10 -0
- package/dist/cli/serve.d.ts.map +1 -0
- package/dist/cli/serve.js +17 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/session.d.ts +10 -0
- package/dist/cli/session.d.ts.map +1 -0
- package/dist/cli/session.js +226 -0
- package/dist/cli/session.js.map +1 -0
- package/dist/cli/setup.d.ts +11 -0
- package/dist/cli/setup.d.ts.map +1 -0
- package/dist/cli/setup.js +103 -0
- package/dist/cli/setup.js.map +1 -0
- package/dist/cli/snapshot.d.ts +9 -0
- package/dist/cli/snapshot.d.ts.map +1 -0
- package/dist/cli/snapshot.js +126 -0
- package/dist/cli/snapshot.js.map +1 -0
- package/dist/cli/specs.d.ts +8 -0
- package/dist/cli/specs.d.ts.map +1 -0
- package/dist/cli/specs.js +96 -0
- package/dist/cli/specs.js.map +1 -0
- package/dist/cli/status.d.ts +8 -0
- package/dist/cli/status.d.ts.map +1 -0
- package/dist/cli/status.js +40 -0
- package/dist/cli/status.js.map +1 -0
- package/dist/cli/telegram.d.ts +8 -0
- package/dist/cli/telegram.d.ts.map +1 -0
- package/dist/cli/telegram.js +40 -0
- package/dist/cli/telegram.js.map +1 -0
- package/dist/cli/test-persona.d.ts +9 -0
- package/dist/cli/test-persona.d.ts.map +1 -0
- package/dist/cli/test-persona.js +176 -0
- package/dist/cli/test-persona.js.map +1 -0
- package/dist/config/defaults.d.ts +9 -0
- package/dist/config/defaults.d.ts.map +1 -0
- package/dist/config/defaults.js +56 -0
- package/dist/config/defaults.js.map +1 -0
- package/dist/context/compile.d.ts +29 -0
- package/dist/context/compile.d.ts.map +1 -0
- package/dist/context/compile.js +415 -0
- package/dist/context/compile.js.map +1 -0
- package/dist/governor/copy-check.d.ts +24 -0
- package/dist/governor/copy-check.d.ts.map +1 -0
- package/dist/governor/copy-check.js +75 -0
- package/dist/governor/copy-check.js.map +1 -0
- package/dist/governor/design-check.d.ts +20 -0
- package/dist/governor/design-check.d.ts.map +1 -0
- package/dist/governor/design-check.js +40 -0
- package/dist/governor/design-check.js.map +1 -0
- package/dist/governor/specs.d.ts +58 -0
- package/dist/governor/specs.d.ts.map +1 -0
- package/dist/governor/specs.js +183 -0
- package/dist/governor/specs.js.map +1 -0
- package/dist/ledger/database.d.ts +12 -0
- package/dist/ledger/database.d.ts.map +1 -0
- package/dist/ledger/database.js +56 -0
- package/dist/ledger/database.js.map +1 -0
- package/dist/ledger/records.d.ts +19 -0
- package/dist/ledger/records.d.ts.map +1 -0
- package/dist/ledger/records.js +40 -0
- package/dist/ledger/records.js.map +1 -0
- package/dist/ledger/sessions.d.ts +15 -0
- package/dist/ledger/sessions.d.ts.map +1 -0
- package/dist/ledger/sessions.js +54 -0
- package/dist/ledger/sessions.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +295 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/orchestrator/context.d.ts +22 -0
- package/dist/orchestrator/context.d.ts.map +1 -0
- package/dist/orchestrator/context.js +142 -0
- package/dist/orchestrator/context.js.map +1 -0
- package/dist/orchestrator/providers.d.ts +17 -0
- package/dist/orchestrator/providers.d.ts.map +1 -0
- package/dist/orchestrator/providers.js +57 -0
- package/dist/orchestrator/providers.js.map +1 -0
- package/dist/orchestrator/router.d.ts +30 -0
- package/dist/orchestrator/router.d.ts.map +1 -0
- package/dist/orchestrator/router.js +83 -0
- package/dist/orchestrator/router.js.map +1 -0
- package/dist/snapshot/scanner.d.ts +63 -0
- package/dist/snapshot/scanner.d.ts.map +1 -0
- package/dist/snapshot/scanner.js +293 -0
- package/dist/snapshot/scanner.js.map +1 -0
- package/dist/telegram/bot.d.ts +14 -0
- package/dist/telegram/bot.d.ts.map +1 -0
- package/dist/telegram/bot.js +139 -0
- package/dist/telegram/bot.js.map +1 -0
- package/dist/types.d.ts +99 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +16 -0
- package/dist/types.js.map +1 -0
- package/dist/vector/embeddings.d.ts +11 -0
- package/dist/vector/embeddings.d.ts.map +1 -0
- package/dist/vector/embeddings.js +30 -0
- package/dist/vector/embeddings.js.map +1 -0
- package/dist/vector/search.d.ts +26 -0
- package/dist/vector/search.d.ts.map +1 -0
- package/dist/vector/search.js +51 -0
- package/dist/vector/search.js.map +1 -0
- package/package.json +57 -0
package/dist/cli/lint.js
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant lint — CI integration for spec checks.
|
|
3
|
+
*
|
|
4
|
+
* Story 5.5: Runs all applicable spec checks (copy audit, design system
|
|
5
|
+
* validation) on source files. Designed for CI pipelines and pre-commit hooks.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync, readdirSync, statSync } from 'fs';
|
|
8
|
+
import { join, relative } from 'path';
|
|
9
|
+
import yaml from 'js-yaml';
|
|
10
|
+
import { checkCopy } from '../governor/copy-check.js';
|
|
11
|
+
import { checkDesign } from '../governor/design-check.js';
|
|
12
|
+
import { scanSpecs } from '../governor/specs.js';
|
|
13
|
+
const SOURCE_EXTENSIONS = new Set([
|
|
14
|
+
'.ts', '.tsx', '.js', '.jsx', '.vue', '.svelte',
|
|
15
|
+
'.html', '.css', '.scss',
|
|
16
|
+
]);
|
|
17
|
+
const TEXT_EXTENSIONS = new Set([
|
|
18
|
+
...SOURCE_EXTENSIONS,
|
|
19
|
+
'.md', '.mdx', '.txt', '.yaml', '.yml', '.json',
|
|
20
|
+
]);
|
|
21
|
+
export function registerLintCommand(program) {
|
|
22
|
+
program
|
|
23
|
+
.command('lint')
|
|
24
|
+
.description('Run all spec checks (copy audit, design system) for CI')
|
|
25
|
+
.argument('[path]', 'File or directory to lint (default: current directory)', '.')
|
|
26
|
+
.option('--strict', 'Treat discouraged violations as errors')
|
|
27
|
+
.action((targetPath, opts) => {
|
|
28
|
+
const cwd = process.cwd();
|
|
29
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
30
|
+
if (!existsSync(configPath)) {
|
|
31
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
35
|
+
const docsPath = join(cwd, config.governor.docs_path);
|
|
36
|
+
// Check if any spec documents exist
|
|
37
|
+
const specs = scanSpecs(docsPath);
|
|
38
|
+
if (specs.length === 0) {
|
|
39
|
+
console.log('No spec documents found. Nothing to lint.');
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
const hasCopySpec = specs.some((s) => s.frontmatter.type === 'copy_audit');
|
|
43
|
+
const hasDesignSpec = specs.some((s) => s.frontmatter.type === 'design_system');
|
|
44
|
+
if (!hasCopySpec && !hasDesignSpec) {
|
|
45
|
+
console.log('No spec documents found. Nothing to lint.');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
const absPath = join(cwd, targetPath);
|
|
49
|
+
if (!existsSync(absPath)) {
|
|
50
|
+
console.error(`Path not found: ${targetPath}`);
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
const files = collectFiles(absPath);
|
|
54
|
+
let bannedCount = 0;
|
|
55
|
+
let discouragedCount = 0;
|
|
56
|
+
let totalViolations = 0;
|
|
57
|
+
for (const file of files) {
|
|
58
|
+
const relPath = relative(cwd, file);
|
|
59
|
+
const ext = file.slice(file.lastIndexOf('.'));
|
|
60
|
+
const content = readFileSync(file, 'utf-8');
|
|
61
|
+
// Run copy audit on text files
|
|
62
|
+
if (hasCopySpec && TEXT_EXTENSIONS.has(ext)) {
|
|
63
|
+
const result = checkCopy(content, docsPath);
|
|
64
|
+
for (const v of result.violations) {
|
|
65
|
+
totalViolations++;
|
|
66
|
+
if (v.level === 'banned')
|
|
67
|
+
bannedCount++;
|
|
68
|
+
if (v.level === 'discouraged')
|
|
69
|
+
discouragedCount++;
|
|
70
|
+
const lineRef = v.line ? `:${v.line}` : '';
|
|
71
|
+
console.log(`${relPath}${lineRef} ${v.message}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Run design system check on source files
|
|
75
|
+
if (hasDesignSpec && SOURCE_EXTENSIONS.has(ext)) {
|
|
76
|
+
const result = checkDesign(content, relPath, docsPath);
|
|
77
|
+
for (const v of result.violations) {
|
|
78
|
+
totalViolations++;
|
|
79
|
+
bannedCount++;
|
|
80
|
+
console.log(`${v.file}:${v.line} ${v.message}`);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
if (totalViolations === 0) {
|
|
85
|
+
console.log('All checks passed.');
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.log('');
|
|
89
|
+
console.log(`${totalViolations} violation(s): ${bannedCount} banned, ${discouragedCount} discouraged`);
|
|
90
|
+
if (bannedCount > 0) {
|
|
91
|
+
process.exit(1);
|
|
92
|
+
}
|
|
93
|
+
if (opts.strict && discouragedCount > 0) {
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
const SKIP_DIRS = new Set(['node_modules', '.git', '.memnant', 'dist', '.next']);
|
|
99
|
+
function collectFiles(target) {
|
|
100
|
+
let stat;
|
|
101
|
+
try {
|
|
102
|
+
stat = statSync(target);
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
if (stat.isFile()) {
|
|
108
|
+
const ext = target.slice(target.lastIndexOf('.'));
|
|
109
|
+
if (TEXT_EXTENSIONS.has(ext))
|
|
110
|
+
return [target];
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
if (!stat.isDirectory())
|
|
114
|
+
return [];
|
|
115
|
+
const results = [];
|
|
116
|
+
let entries;
|
|
117
|
+
try {
|
|
118
|
+
entries = readdirSync(target);
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
121
|
+
return results;
|
|
122
|
+
}
|
|
123
|
+
for (const entry of entries) {
|
|
124
|
+
if (SKIP_DIRS.has(entry))
|
|
125
|
+
continue;
|
|
126
|
+
const absPath = join(target, entry);
|
|
127
|
+
results.push(...collectFiles(absPath));
|
|
128
|
+
}
|
|
129
|
+
return results;
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lint.js","sourceRoot":"","sources":["../../src/cli/lint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant log — Write records to the ledger.
|
|
3
|
+
*
|
|
4
|
+
* Story 1.2: Creates records with type, content, tags, and related records.
|
|
5
|
+
* Generates an embedding at write time using a local model.
|
|
6
|
+
* Content can come from --content flag or stdin pipe.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
export declare function registerLogCommand(program: Command): void;
|
|
10
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/cli/log.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmBpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2EzD"}
|
package/dist/cli/log.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant log — Write records to the ledger.
|
|
3
|
+
*
|
|
4
|
+
* Story 1.2: Creates records with type, content, tags, and related records.
|
|
5
|
+
* Generates an embedding at write time using a local model.
|
|
6
|
+
* Content can come from --content flag or stdin pipe.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import yaml from 'js-yaml';
|
|
11
|
+
import { openDatabase } from '../ledger/database.js';
|
|
12
|
+
import { insertRecord } from '../ledger/records.js';
|
|
13
|
+
import { generateEmbedding, serializeEmbedding } from '../vector/embeddings.js';
|
|
14
|
+
import { RECORD_TYPES } from '../types.js';
|
|
15
|
+
import { getActiveSession } from '../ledger/sessions.js';
|
|
16
|
+
function readStdin() {
|
|
17
|
+
try {
|
|
18
|
+
return readFileSync(0, 'utf-8');
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return '';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
export function registerLogCommand(program) {
|
|
25
|
+
program
|
|
26
|
+
.command('log')
|
|
27
|
+
.description('Write a record to the ledger')
|
|
28
|
+
.requiredOption('--type <type>', 'Record type')
|
|
29
|
+
.option('--content <content>', 'Record content (or pipe from stdin)')
|
|
30
|
+
.option('--tags <tags>', 'Comma-separated tags')
|
|
31
|
+
.option('--relates-to <ids>', 'Comma-separated related record IDs')
|
|
32
|
+
.action(async (opts) => {
|
|
33
|
+
// Validate record type
|
|
34
|
+
if (!RECORD_TYPES.includes(opts.type)) {
|
|
35
|
+
console.error(`Unknown record type '${opts.type}'. Valid types: ${RECORD_TYPES.join(', ')}`);
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
// Get content from --content flag or stdin
|
|
39
|
+
let content = opts.content;
|
|
40
|
+
if (!content && !process.stdin.isTTY) {
|
|
41
|
+
content = readStdin().trim();
|
|
42
|
+
}
|
|
43
|
+
if (!content) {
|
|
44
|
+
console.error('No content provided. Use --content or pipe from stdin.');
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
// Load project config
|
|
48
|
+
const cwd = process.cwd();
|
|
49
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
50
|
+
if (!existsSync(configPath)) {
|
|
51
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
55
|
+
const dbPath = join(cwd, config.memory.db_path);
|
|
56
|
+
if (!existsSync(dbPath)) {
|
|
57
|
+
console.error(`Ledger database not found at ${config.memory.db_path}. Run \`memnant init\` to recreate.`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
const db = openDatabase(dbPath);
|
|
61
|
+
// Parse tags and related records
|
|
62
|
+
const tags = opts.tags ? opts.tags.split(',').map((t) => t.trim()) : [];
|
|
63
|
+
const relatedRecords = opts.relatesTo ? opts.relatesTo.split(',').map((id) => id.trim()) : [];
|
|
64
|
+
// Generate embedding
|
|
65
|
+
const embedding = await generateEmbedding(content);
|
|
66
|
+
const embeddingBuffer = serializeEmbedding(embedding);
|
|
67
|
+
// Check for active session
|
|
68
|
+
const activeSession = getActiveSession(db, config.project.id);
|
|
69
|
+
// Insert record
|
|
70
|
+
const record = insertRecord(db, {
|
|
71
|
+
projectId: config.project.id,
|
|
72
|
+
type: opts.type,
|
|
73
|
+
contentText: content,
|
|
74
|
+
tags,
|
|
75
|
+
relatedRecords,
|
|
76
|
+
embedding: embeddingBuffer,
|
|
77
|
+
sourceSession: activeSession?.id ?? null,
|
|
78
|
+
});
|
|
79
|
+
db.close();
|
|
80
|
+
console.log(`Created ${record.type} record ${record.id}`);
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/cli/log.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,IAAI,MAAM,SAAS,CAAC;AAC3B,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAEzD,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,8BAA8B,CAAC;SAC3C,cAAc,CAAC,eAAe,EAAE,aAAa,CAAC;SAC9C,MAAM,CAAC,qBAAqB,EAAE,qCAAqC,CAAC;SACpE,MAAM,CAAC,eAAe,EAAE,sBAAsB,CAAC;SAC/C,MAAM,CAAC,oBAAoB,EAAE,oCAAoC,CAAC;SAClE,MAAM,CAAC,KAAK,EAAE,IAA2E,EAAE,EAAE;QAC5F,uBAAuB;QACvB,IAAI,CAAC,YAAY,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAqC,CAAC,EAAE,CAAC;YACvE,OAAO,CAAC,KAAK,CACX,wBAAwB,IAAI,CAAC,IAAI,mBAAmB,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAC9E,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,2CAA2C;QAC3C,IAAI,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QAC3B,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;YACrC,OAAO,GAAG,SAAS,EAAE,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;QAED,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wDAAwD,CAAC,CAAC;YACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,sBAAsB;QACtB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;QAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;QAE7C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,qDAAqD,CAAC,CAAC;YACrE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAkB,CAAC;QAC7E,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAEhD,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,KAAK,CACX,gCAAgC,MAAM,CAAC,MAAM,CAAC,OAAO,qCAAqC,CAC3F,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,EAAE,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;QAEhC,iCAAiC;QACjC,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAE9F,qBAAqB;QACrB,MAAM,SAAS,GAAG,MAAM,iBAAiB,CAAC,OAAO,CAAC,CAAC;QACnD,MAAM,eAAe,GAAG,kBAAkB,CAAC,SAAS,CAAC,CAAC;QAEtD,2BAA2B;QAC3B,MAAM,aAAa,GAAG,gBAAgB,CAAC,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE9D,gBAAgB;QAChB,MAAM,MAAM,GAAG,YAAY,CAAC,EAAE,EAAE;YAC9B,SAAS,EAAE,MAAM,CAAC,OAAO,CAAC,EAAE;YAC5B,IAAI,EAAE,IAAI,CAAC,IAAqC;YAChD,WAAW,EAAE,OAAO;YACpB,IAAI;YACJ,cAAc;YACd,SAAS,EAAE,eAAe;YAC1B,aAAa,EAAE,aAAa,EAAE,EAAE,IAAI,IAAI;SACzC,CAAC,CAAC;QAEH,EAAE,CAAC,KAAK,EAAE,CAAC;QAEX,OAAO,CAAC,GAAG,CAAC,WAAW,MAAM,CAAC,IAAI,WAAW,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;IAC5D,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant promote — Promote an orchestrator task to a different record type.
|
|
3
|
+
*
|
|
4
|
+
* Story 4.4: Copies content from an orchestrator_task into a new record
|
|
5
|
+
* (typically a decision) with a link back to the original.
|
|
6
|
+
*/
|
|
7
|
+
import { Command } from 'commander';
|
|
8
|
+
export declare function registerPromoteCommand(program: Command): void;
|
|
9
|
+
//# sourceMappingURL=promote.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote.d.ts","sourceRoot":"","sources":["../../src/cli/promote.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA2E7D"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant promote — Promote an orchestrator task to a different record type.
|
|
3
|
+
*
|
|
4
|
+
* Story 4.4: Copies content from an orchestrator_task into a new record
|
|
5
|
+
* (typically a decision) with a link back to the original.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, readFileSync } from 'fs';
|
|
8
|
+
import { join } from 'path';
|
|
9
|
+
import yaml from 'js-yaml';
|
|
10
|
+
import { openDatabase } from '../ledger/database.js';
|
|
11
|
+
import { insertRecord } from '../ledger/records.js';
|
|
12
|
+
import { generateEmbedding, serializeEmbedding } from '../vector/embeddings.js';
|
|
13
|
+
import { getActiveSession } from '../ledger/sessions.js';
|
|
14
|
+
import { RECORD_TYPES } from '../types.js';
|
|
15
|
+
export function registerPromoteCommand(program) {
|
|
16
|
+
program
|
|
17
|
+
.command('promote')
|
|
18
|
+
.description('Promote an orchestrator task to a decision or other record type')
|
|
19
|
+
.argument('<record-id>', 'Record ID (short or full) to promote')
|
|
20
|
+
.option('--type <type>', 'Target record type (default: decision)', 'decision')
|
|
21
|
+
.action(async (recordId, opts) => {
|
|
22
|
+
const cwd = process.cwd();
|
|
23
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
24
|
+
if (!existsSync(configPath)) {
|
|
25
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
29
|
+
const dbPath = join(cwd, config.memory.db_path);
|
|
30
|
+
if (!existsSync(dbPath)) {
|
|
31
|
+
console.error(`Ledger database not found at ${config.memory.db_path}. Run \`memnant init\` to recreate.`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
// Validate target type
|
|
35
|
+
if (!RECORD_TYPES.includes(opts.type)) {
|
|
36
|
+
console.error(`Unknown record type '${opts.type}'. Valid types: ${RECORD_TYPES.join(', ')}`);
|
|
37
|
+
process.exit(1);
|
|
38
|
+
}
|
|
39
|
+
const db = openDatabase(dbPath);
|
|
40
|
+
try {
|
|
41
|
+
// Find the source record (support short IDs)
|
|
42
|
+
const source = db.get('SELECT id, type, content_text FROM record WHERE id LIKE ?', [`${recordId}%`]);
|
|
43
|
+
if (!source) {
|
|
44
|
+
console.error(`Record '${recordId}' not found.`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
if (source.type !== 'orchestrator_task') {
|
|
48
|
+
console.error(`Record ${source.id.slice(0, 8)} is a ${source.type}, not an orchestrator_task. Only orchestrator tasks can be promoted.`);
|
|
49
|
+
process.exit(1);
|
|
50
|
+
}
|
|
51
|
+
// Create new record with link to original
|
|
52
|
+
const embedding = await generateEmbedding(source.content_text);
|
|
53
|
+
const embeddingBuffer = serializeEmbedding(embedding);
|
|
54
|
+
const activeSession = getActiveSession(db, config.project.id);
|
|
55
|
+
const newRecord = insertRecord(db, {
|
|
56
|
+
projectId: config.project.id,
|
|
57
|
+
type: opts.type,
|
|
58
|
+
contentText: source.content_text,
|
|
59
|
+
relatedRecords: [source.id],
|
|
60
|
+
embedding: embeddingBuffer,
|
|
61
|
+
sourceSession: activeSession?.id ?? null,
|
|
62
|
+
});
|
|
63
|
+
console.log(`Promoted ${source.id.slice(0, 8)} (orchestrator_task) → ${newRecord.id.slice(0, 8)} (${opts.type})`);
|
|
64
|
+
}
|
|
65
|
+
finally {
|
|
66
|
+
db.close();
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=promote.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promote.js","sourceRoot":"","sources":["../../src/cli/promote.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant recall — Semantic search over the ledger.
|
|
3
|
+
*
|
|
4
|
+
* Story 1.3: Finds relevant records using vector similarity against a
|
|
5
|
+
* natural language query. Supports type, date, and limit filters.
|
|
6
|
+
* Text output is one record per line; --json for structured output.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
export declare function registerRecallCommand(program: Command): void;
|
|
10
|
+
//# sourceMappingURL=recall.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall.d.ts","sourceRoot":"","sources":["../../src/cli/recall.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAWpC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0G5D"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant recall — Semantic search over the ledger.
|
|
3
|
+
*
|
|
4
|
+
* Story 1.3: Finds relevant records using vector similarity against a
|
|
5
|
+
* natural language query. Supports type, date, and limit filters.
|
|
6
|
+
* Text output is one record per line; --json for structured output.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync } from 'fs';
|
|
9
|
+
import { join } from 'path';
|
|
10
|
+
import yaml from 'js-yaml';
|
|
11
|
+
import { openDatabase } from '../ledger/database.js';
|
|
12
|
+
import { generateEmbedding } from '../vector/embeddings.js';
|
|
13
|
+
import { searchRecords } from '../vector/search.js';
|
|
14
|
+
import { RECORD_TYPES } from '../types.js';
|
|
15
|
+
import { computeStaleRecordIds } from '../context/compile.js';
|
|
16
|
+
export function registerRecallCommand(program) {
|
|
17
|
+
program
|
|
18
|
+
.command('recall')
|
|
19
|
+
.description('Search the ledger with a natural language query')
|
|
20
|
+
.argument('<query>', 'Natural language search query')
|
|
21
|
+
.option('--type <type>', 'Filter by record type')
|
|
22
|
+
.option('--since <date>', 'Filter to records after YYYY-MM-DD')
|
|
23
|
+
.option('--limit <n>', 'Maximum results (default 10)', '10')
|
|
24
|
+
.option('--full', 'Show complete content instead of truncated')
|
|
25
|
+
.option('--json', 'Output as JSON array')
|
|
26
|
+
.action(async (query, opts) => {
|
|
27
|
+
// Validate --type
|
|
28
|
+
if (opts.type && !RECORD_TYPES.includes(opts.type)) {
|
|
29
|
+
console.error(`Unknown record type '${opts.type}'. Valid types: ${RECORD_TYPES.join(', ')}`);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
// Validate --since
|
|
33
|
+
if (opts.since && !/^\d{4}-\d{2}-\d{2}$/.test(opts.since)) {
|
|
34
|
+
console.error(`Invalid date format '${opts.since}'. Expected YYYY-MM-DD (e.g. 2025-01-01).`);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
// Validate --limit
|
|
38
|
+
const limit = parseInt(opts.limit, 10);
|
|
39
|
+
if (isNaN(limit) || limit < 1) {
|
|
40
|
+
console.error(`Invalid limit '${opts.limit}'. Must be a positive integer.`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
// Load project config
|
|
44
|
+
const cwd = process.cwd();
|
|
45
|
+
const configPath = join(cwd, 'memnant.yaml');
|
|
46
|
+
if (!existsSync(configPath)) {
|
|
47
|
+
console.error('No memnant project found. Run `memnant init` first.');
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
const config = yaml.load(readFileSync(configPath, 'utf-8'));
|
|
51
|
+
const dbPath = join(cwd, config.memory.db_path);
|
|
52
|
+
if (!existsSync(dbPath)) {
|
|
53
|
+
console.error(`Ledger database not found at ${config.memory.db_path}. Run \`memnant init\` to recreate.`);
|
|
54
|
+
process.exit(1);
|
|
55
|
+
}
|
|
56
|
+
const db = openDatabase(dbPath);
|
|
57
|
+
// Generate query embedding and search
|
|
58
|
+
const queryEmbedding = await generateEmbedding(query);
|
|
59
|
+
const results = searchRecords(db, queryEmbedding, {
|
|
60
|
+
type: opts.type,
|
|
61
|
+
since: opts.since,
|
|
62
|
+
limit,
|
|
63
|
+
});
|
|
64
|
+
// Compute stale record IDs
|
|
65
|
+
const staleIds = computeStaleRecordIds(db, cwd);
|
|
66
|
+
db.close();
|
|
67
|
+
if (results.length === 0) {
|
|
68
|
+
console.log('No relevant records found.');
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
if (opts.json) {
|
|
72
|
+
const jsonOutput = results.map((r) => ({
|
|
73
|
+
id: r.id,
|
|
74
|
+
short_id: r.id.slice(0, 8),
|
|
75
|
+
type: r.type,
|
|
76
|
+
created_at: r.created_at,
|
|
77
|
+
content: r.content_text,
|
|
78
|
+
similarity: Math.round(r.similarity * 1000) / 1000,
|
|
79
|
+
tags: r.tags,
|
|
80
|
+
related_records: r.related_records,
|
|
81
|
+
stale: staleIds.has(r.id),
|
|
82
|
+
}));
|
|
83
|
+
console.log(JSON.stringify(jsonOutput, null, 2));
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
// Text output: one record per line
|
|
87
|
+
for (const r of results) {
|
|
88
|
+
const shortId = r.id.slice(0, 8);
|
|
89
|
+
const date = r.created_at.slice(0, 10);
|
|
90
|
+
const score = r.similarity.toFixed(3);
|
|
91
|
+
const staleMarker = staleIds.has(r.id) ? ' [stale]' : '';
|
|
92
|
+
const collapsed = r.content_text.replace(/\n/g, ' ');
|
|
93
|
+
const content = !opts.full && collapsed.length > 200 ? collapsed.slice(0, 200) + '...' : collapsed;
|
|
94
|
+
console.log(`${shortId} ${r.type} ${date} ${score}${staleMarker} ${content}`);
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
//# sourceMappingURL=recall.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recall.js","sourceRoot":"","sources":["../../src/cli/recall.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant serve — Start the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Story 1.4: Thin CLI wrapper that starts the MCP server on stdio transport.
|
|
5
|
+
* The server is used by agents (Claude Code, etc.) via MCP config:
|
|
6
|
+
* { "command": "memnant", "args": ["serve"] }
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
export declare function registerServeCommand(program: Command): void;
|
|
10
|
+
//# sourceMappingURL=serve.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAGpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAO3D"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant serve — Start the MCP server.
|
|
3
|
+
*
|
|
4
|
+
* Story 1.4: Thin CLI wrapper that starts the MCP server on stdio transport.
|
|
5
|
+
* The server is used by agents (Claude Code, etc.) via MCP config:
|
|
6
|
+
* { "command": "memnant", "args": ["serve"] }
|
|
7
|
+
*/
|
|
8
|
+
import { startServer } from '../mcp/server.js';
|
|
9
|
+
export function registerServeCommand(program) {
|
|
10
|
+
program
|
|
11
|
+
.command('serve')
|
|
12
|
+
.description('Start the MCP server (stdio transport)')
|
|
13
|
+
.action(async () => {
|
|
14
|
+
await startServer();
|
|
15
|
+
});
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=serve.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/cli/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO;SACJ,OAAO,CAAC,OAAO,CAAC;SAChB,WAAW,CAAC,wCAAwC,CAAC;SACrD,MAAM,CAAC,KAAK,IAAI,EAAE;QACjB,MAAM,WAAW,EAAE,CAAC;IACtB,CAAC,CAAC,CAAC;AACP,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memnant session — Session lifecycle commands.
|
|
3
|
+
*
|
|
4
|
+
* Story 2.1: session start with context compilation.
|
|
5
|
+
* Story 2.2: session close with log capture.
|
|
6
|
+
* Story 2.4: session status.
|
|
7
|
+
*/
|
|
8
|
+
import { Command } from 'commander';
|
|
9
|
+
export declare function registerSessionCommand(program: Command): void;
|
|
10
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/cli/session.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgEpC,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA4K7D"}
|