@slorenzot/memento-cli 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/dist/CLI.d.ts +11 -0
- package/dist/CLI.d.ts.map +1 -0
- package/dist/CLI.js +173 -0
- package/dist/CLI.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/package.json +29 -0
- package/src/CLI.test.ts +60 -0
- package/src/CLI.ts +187 -0
- package/src/index.ts +1 -0
- package/tsconfig.json +14 -0
package/dist/CLI.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare class CLI {
|
|
2
|
+
private program;
|
|
3
|
+
private memory;
|
|
4
|
+
private activeSessionId;
|
|
5
|
+
constructor(dbPath?: string);
|
|
6
|
+
private setupCommands;
|
|
7
|
+
private getOrCreateSessionId;
|
|
8
|
+
run(argv?: string[]): Promise<void>;
|
|
9
|
+
close(): void;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=CLI.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CLI.d.ts","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"AAKA,qBAAa,GAAG;IACd,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAAe;IAC7B,OAAO,CAAC,eAAe,CAAuB;gBAElC,MAAM,GAAE,MAA4B;IAMhD,OAAO,CAAC,aAAa;YAsJP,oBAAoB;IAa5B,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB;IAIvC,KAAK;CAGN"}
|
package/dist/CLI.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CLI = void 0;
|
|
4
|
+
const commander_1 = require("commander");
|
|
5
|
+
const core_1 = require("@memento/core");
|
|
6
|
+
class CLI {
|
|
7
|
+
program;
|
|
8
|
+
memory;
|
|
9
|
+
activeSessionId = null;
|
|
10
|
+
constructor(dbPath = './data/memento.db') {
|
|
11
|
+
this.program = new commander_1.Command();
|
|
12
|
+
this.memory = new core_1.MemoryEngine(dbPath);
|
|
13
|
+
this.setupCommands();
|
|
14
|
+
}
|
|
15
|
+
setupCommands() {
|
|
16
|
+
this.program
|
|
17
|
+
.name('memento')
|
|
18
|
+
.description('Persistent memory system for AI coding agents')
|
|
19
|
+
.version('0.1.0');
|
|
20
|
+
this.program
|
|
21
|
+
.command('setup [agent]')
|
|
22
|
+
.description('Setup configuration for an AI agent')
|
|
23
|
+
.action((agent) => {
|
|
24
|
+
console.log(`Setup for agent: ${agent || 'default'}`);
|
|
25
|
+
console.log('Configuration saved to ~/.memento/config.json');
|
|
26
|
+
});
|
|
27
|
+
this.program
|
|
28
|
+
.command('serve [port]')
|
|
29
|
+
.description('Start API server')
|
|
30
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
31
|
+
.action((port, options) => {
|
|
32
|
+
console.log(`Starting API server on port ${port || 3000}`);
|
|
33
|
+
console.log(`Database: ${options.db}`);
|
|
34
|
+
console.log('Note: API server not implemented in CLI mode');
|
|
35
|
+
});
|
|
36
|
+
this.program
|
|
37
|
+
.command('mcp')
|
|
38
|
+
.description('Start MCP server')
|
|
39
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
40
|
+
.action((options) => {
|
|
41
|
+
console.log(`Starting MCP server`);
|
|
42
|
+
console.log(`Database: ${options.db}`);
|
|
43
|
+
console.log('Note: MCP server not implemented in CLI mode');
|
|
44
|
+
});
|
|
45
|
+
this.program
|
|
46
|
+
.command('search <query>')
|
|
47
|
+
.description('Search observations')
|
|
48
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
49
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
50
|
+
.option('--limit <number>', 'Limit results')
|
|
51
|
+
.action(async (query, options) => {
|
|
52
|
+
const result = await this.memory.search({
|
|
53
|
+
query,
|
|
54
|
+
type: options.type,
|
|
55
|
+
projectId: options.project,
|
|
56
|
+
limit: options.limit ? parseInt(options.limit) : undefined,
|
|
57
|
+
});
|
|
58
|
+
console.log(`Found ${result.total} observations:`);
|
|
59
|
+
result.observations.forEach((obs) => {
|
|
60
|
+
console.log(` [${obs.type}] ${obs.title}`);
|
|
61
|
+
console.log(` ${obs.content.substring(0, 100)}...`);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
this.program
|
|
65
|
+
.command('save <title> <content>')
|
|
66
|
+
.description('Save an observation')
|
|
67
|
+
.option('-t, --type <type>', 'Observation type', 'note')
|
|
68
|
+
.option('-k, --topic <topic>', 'Topic key')
|
|
69
|
+
.option('-p, --project <project>', 'Project ID', 'default')
|
|
70
|
+
.action(async (title, content, options) => {
|
|
71
|
+
const sessionId = await this.getOrCreateSessionId(options.project);
|
|
72
|
+
const observation = await this.memory.createObservation({
|
|
73
|
+
sessionId,
|
|
74
|
+
title,
|
|
75
|
+
content,
|
|
76
|
+
type: options.type,
|
|
77
|
+
topicKey: options.topic || null,
|
|
78
|
+
projectId: options.project,
|
|
79
|
+
metadata: {},
|
|
80
|
+
});
|
|
81
|
+
console.log(`Saved observation: ${observation.uuid}`);
|
|
82
|
+
});
|
|
83
|
+
this.program
|
|
84
|
+
.command('get <id>')
|
|
85
|
+
.description('Get observation by ID')
|
|
86
|
+
.action(async (id) => {
|
|
87
|
+
const observation = await this.memory.getObservation(parseInt(id));
|
|
88
|
+
if (!observation) {
|
|
89
|
+
console.error('Observation not found');
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
console.log(`[${observation.type}] ${observation.title}`);
|
|
93
|
+
console.log(observation.content);
|
|
94
|
+
console.log(`Topic: ${observation.topicKey || 'none'}`);
|
|
95
|
+
console.log(`Created: ${observation.createdAt.toISOString()}`);
|
|
96
|
+
});
|
|
97
|
+
this.program
|
|
98
|
+
.command('update <id>')
|
|
99
|
+
.description('Update observation')
|
|
100
|
+
.option('-t, --title <title>', 'New title')
|
|
101
|
+
.option('-c, --content <content>', 'New content')
|
|
102
|
+
.option('-k, --topic <topic>', 'New topic key')
|
|
103
|
+
.action(async (id, options) => {
|
|
104
|
+
const updates = {};
|
|
105
|
+
if (options.title)
|
|
106
|
+
updates.title = options.title;
|
|
107
|
+
if (options.content)
|
|
108
|
+
updates.content = options.content;
|
|
109
|
+
if (options.topic)
|
|
110
|
+
updates.topicKey = options.topic;
|
|
111
|
+
const observation = await this.memory.updateObservation(parseInt(id), updates);
|
|
112
|
+
console.log(`Updated observation: ${observation.uuid}`);
|
|
113
|
+
});
|
|
114
|
+
this.program
|
|
115
|
+
.command('delete <id>')
|
|
116
|
+
.description('Delete observation')
|
|
117
|
+
.action(async (id) => {
|
|
118
|
+
await this.memory.deleteObservation(parseInt(id));
|
|
119
|
+
console.log(`Deleted observation ${id}`);
|
|
120
|
+
});
|
|
121
|
+
this.program
|
|
122
|
+
.command('timeline [project]')
|
|
123
|
+
.description('Show timeline of observations')
|
|
124
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
125
|
+
.action(async (project, options) => {
|
|
126
|
+
const result = await this.memory.search({
|
|
127
|
+
projectId: project,
|
|
128
|
+
limit: parseInt(options.limit),
|
|
129
|
+
});
|
|
130
|
+
console.log(`Timeline (${result.total} observations):`);
|
|
131
|
+
result.observations.forEach((obs) => {
|
|
132
|
+
const date = obs.createdAt.toLocaleDateString();
|
|
133
|
+
console.log(` ${date} [${obs.type}] ${obs.title}`);
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
this.program
|
|
137
|
+
.command('stats')
|
|
138
|
+
.description('Show statistics')
|
|
139
|
+
.action(async () => {
|
|
140
|
+
const result = await this.memory.search({});
|
|
141
|
+
const byType = result.observations.reduce((acc, obs) => {
|
|
142
|
+
acc[obs.type] = (acc[obs.type] || 0) + 1;
|
|
143
|
+
return acc;
|
|
144
|
+
}, {});
|
|
145
|
+
console.log('Statistics:');
|
|
146
|
+
console.log(` Total observations: ${result.total}`);
|
|
147
|
+
console.log(' By type:');
|
|
148
|
+
Object.entries(byType).forEach(([type, count]) => {
|
|
149
|
+
console.log(` ${type}: ${count}`);
|
|
150
|
+
});
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
async getOrCreateSessionId(projectId) {
|
|
154
|
+
if (this.activeSessionId) {
|
|
155
|
+
return this.activeSessionId;
|
|
156
|
+
}
|
|
157
|
+
const session = await this.memory.createSession({
|
|
158
|
+
projectId,
|
|
159
|
+
endedAt: null,
|
|
160
|
+
metadata: {},
|
|
161
|
+
});
|
|
162
|
+
this.activeSessionId = session.id;
|
|
163
|
+
return session.id;
|
|
164
|
+
}
|
|
165
|
+
async run(argv = process.argv) {
|
|
166
|
+
await this.program.parseAsync(argv);
|
|
167
|
+
}
|
|
168
|
+
close() {
|
|
169
|
+
this.memory.close();
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
exports.CLI = CLI;
|
|
173
|
+
//# sourceMappingURL=CLI.js.map
|
package/dist/CLI.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CLI.js","sourceRoot":"","sources":["../src/CLI.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,OAAO,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@slorenzot/memento-cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "CLI interface for Memento",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"memento": "./dist/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"scripts": {
|
|
11
|
+
"dev": "bun run src/cli.ts",
|
|
12
|
+
"build": "bun tsc --declaration --declarationMap --emitDeclarationOnly --outDir ./dist",
|
|
13
|
+
"test": "bun test",
|
|
14
|
+
"typecheck": "bun tsc --noEmit"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@slorenzot/memento-core": "workspace:*",
|
|
18
|
+
"commander": "^12.0.0",
|
|
19
|
+
"ink": "^4.4.1",
|
|
20
|
+
"chalk": "^5.3.0",
|
|
21
|
+
"ora": "^8.0.1",
|
|
22
|
+
"zod": "^3.22.4",
|
|
23
|
+
"dotenv": "^16.4.1"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@types/node": "^20.11.0",
|
|
27
|
+
"bun-types": "^1.3.11"
|
|
28
|
+
}
|
|
29
|
+
}
|
package/src/CLI.test.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from 'bun:test';
|
|
2
|
+
import { CLI } from './CLI';
|
|
3
|
+
|
|
4
|
+
describe('CLI', () => {
|
|
5
|
+
let cli: CLI;
|
|
6
|
+
let testDbPath: string;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
testDbPath = `/tmp/test-cli-${Date.now()}.db`;
|
|
10
|
+
cli = new CLI(testDbPath);
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
afterEach(() => {
|
|
14
|
+
cli.close();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('should initialize without errors', () => {
|
|
18
|
+
expect(cli).toBeDefined();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('Commands', () => {
|
|
22
|
+
it('should have all required commands', () => {
|
|
23
|
+
const commands = cli['program'].commands;
|
|
24
|
+
|
|
25
|
+
const commandNames = commands.map((c) => c.name());
|
|
26
|
+
expect(commandNames).toContain('setup');
|
|
27
|
+
expect(commandNames).toContain('serve');
|
|
28
|
+
expect(commandNames).toContain('mcp');
|
|
29
|
+
expect(commandNames).toContain('search');
|
|
30
|
+
expect(commandNames).toContain('save');
|
|
31
|
+
expect(commandNames).toContain('get');
|
|
32
|
+
expect(commandNames).toContain('update');
|
|
33
|
+
expect(commandNames).toContain('delete');
|
|
34
|
+
expect(commandNames).toContain('timeline');
|
|
35
|
+
expect(commandNames).toContain('stats');
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('should have proper descriptions', () => {
|
|
39
|
+
const commands = cli['program'].commands;
|
|
40
|
+
|
|
41
|
+
const setupCommand = commands.find((c) => c.name() === 'setup');
|
|
42
|
+
expect(setupCommand).toBeDefined();
|
|
43
|
+
expect(setupCommand?.description()).toContain('Setup');
|
|
44
|
+
|
|
45
|
+
const searchCommand = commands.find((c) => c.name() === 'search');
|
|
46
|
+
expect(searchCommand).toBeDefined();
|
|
47
|
+
expect(searchCommand?.description()).toContain('Search');
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
describe('Session Management', () => {
|
|
52
|
+
it('should create and track active session', async () => {
|
|
53
|
+
const sessionId = await cli['getOrCreateSessionId']('test-project');
|
|
54
|
+
expect(sessionId).toBeDefined();
|
|
55
|
+
|
|
56
|
+
const sameSessionId = await cli['getOrCreateSessionId']('test-project');
|
|
57
|
+
expect(sameSessionId).toBe(sessionId);
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
});
|
package/src/CLI.ts
ADDED
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
import { MemoryEngine } from '@slorenzot/memento-core';
|
|
3
|
+
import type { Observation } from '@slorenzot/memento-core';
|
|
4
|
+
|
|
5
|
+
// @ts-ignore
|
|
6
|
+
export class CLI {
|
|
7
|
+
private program: Command;
|
|
8
|
+
private memory: MemoryEngine;
|
|
9
|
+
private activeSessionId: number | null = null;
|
|
10
|
+
|
|
11
|
+
constructor(dbPath: string = './data/memento.db') {
|
|
12
|
+
this.program = new Command();
|
|
13
|
+
this.memory = new MemoryEngine(dbPath);
|
|
14
|
+
this.setupCommands();
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
private setupCommands() {
|
|
18
|
+
this.program
|
|
19
|
+
.name('memento')
|
|
20
|
+
.description('Persistent memory system for AI coding agents')
|
|
21
|
+
.version('0.1.0');
|
|
22
|
+
|
|
23
|
+
this.program
|
|
24
|
+
.command('setup [agent]')
|
|
25
|
+
.description('Setup configuration for an AI agent')
|
|
26
|
+
.action((agent) => {
|
|
27
|
+
console.log(`Setup for agent: ${agent || 'default'}`);
|
|
28
|
+
console.log('Configuration saved to ~/.memento/config.json');
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
this.program
|
|
32
|
+
.command('serve [port]')
|
|
33
|
+
.description('Start API server')
|
|
34
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
35
|
+
.action((port, options) => {
|
|
36
|
+
console.log(`Starting API server on port ${port || 3000}`);
|
|
37
|
+
console.log(`Database: ${options.db}`);
|
|
38
|
+
console.log('Note: API server not implemented in CLI mode');
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
this.program
|
|
42
|
+
.command('mcp')
|
|
43
|
+
.description('Start MCP server')
|
|
44
|
+
.option('-d, --db <path>', 'Database path', './data/memento.db')
|
|
45
|
+
.action((options) => {
|
|
46
|
+
console.log(`Starting MCP server`);
|
|
47
|
+
console.log(`Database: ${options.db}`);
|
|
48
|
+
console.log('Note: MCP server not implemented in CLI mode');
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
this.program
|
|
52
|
+
.command('search <query>')
|
|
53
|
+
.description('Search observations')
|
|
54
|
+
.option('-t, --type <type>', 'Filter by type')
|
|
55
|
+
.option('-p, --project <project>', 'Filter by project')
|
|
56
|
+
.option('--limit <number>', 'Limit results')
|
|
57
|
+
.action(async (query, options) => {
|
|
58
|
+
const result = await this.memory.search({
|
|
59
|
+
query,
|
|
60
|
+
type: options.type as Observation['type'] | undefined,
|
|
61
|
+
projectId: options.project as string | undefined,
|
|
62
|
+
limit: options.limit ? parseInt(options.limit as string) : undefined,
|
|
63
|
+
});
|
|
64
|
+
console.log(`Found ${result.total} observations:`);
|
|
65
|
+
result.observations.forEach((obs) => {
|
|
66
|
+
console.log(` [${obs.type}] ${obs.title}`);
|
|
67
|
+
console.log(` ${obs.content.substring(0, 100)}...`);
|
|
68
|
+
});
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
this.program
|
|
72
|
+
.command('save <title> <content>')
|
|
73
|
+
.description('Save an observation')
|
|
74
|
+
.option('-t, --type <type>', 'Observation type', 'note')
|
|
75
|
+
.option('-k, --topic <topic>', 'Topic key')
|
|
76
|
+
.option('-p, --project <project>', 'Project ID', 'default')
|
|
77
|
+
.action(async (title, content, options) => {
|
|
78
|
+
const sessionId = await this.getOrCreateSessionId(options.project as string);
|
|
79
|
+
const observation = await this.memory.createObservation({
|
|
80
|
+
sessionId,
|
|
81
|
+
title,
|
|
82
|
+
content,
|
|
83
|
+
type: options.type as Observation['type'],
|
|
84
|
+
topicKey: options.topic || null,
|
|
85
|
+
projectId: options.project as string,
|
|
86
|
+
metadata: {},
|
|
87
|
+
});
|
|
88
|
+
console.log(`Saved observation: ${observation.uuid}`);
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
this.program
|
|
92
|
+
.command('get <id>')
|
|
93
|
+
.description('Get observation by ID')
|
|
94
|
+
.action(async (id) => {
|
|
95
|
+
const observation = await this.memory.getObservation(parseInt(id));
|
|
96
|
+
if (!observation) {
|
|
97
|
+
console.error('Observation not found');
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
console.log(`[${observation.type}] ${observation.title}`);
|
|
101
|
+
console.log(observation.content);
|
|
102
|
+
console.log(`Topic: ${observation.topicKey || 'none'}`);
|
|
103
|
+
console.log(`Created: ${observation.createdAt.toISOString()}`);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
this.program
|
|
107
|
+
.command('update <id>')
|
|
108
|
+
.description('Update observation')
|
|
109
|
+
.option('-t, --title <title>', 'New title')
|
|
110
|
+
.option('-c, --content <content>', 'New content')
|
|
111
|
+
.option('-k, --topic <topic>', 'New topic key')
|
|
112
|
+
.action(async (id, options) => {
|
|
113
|
+
const updates: Partial<Observation> = {};
|
|
114
|
+
if (options.title) updates.title = options.title;
|
|
115
|
+
if (options.content) updates.content = options.content;
|
|
116
|
+
if (options.topic) updates.topicKey = options.topic;
|
|
117
|
+
|
|
118
|
+
const observation = await this.memory.updateObservation(parseInt(id), updates);
|
|
119
|
+
console.log(`Updated observation: ${observation.uuid}`);
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
this.program
|
|
123
|
+
.command('delete <id>')
|
|
124
|
+
.description('Delete observation')
|
|
125
|
+
.action(async (id) => {
|
|
126
|
+
await this.memory.deleteObservation(parseInt(id));
|
|
127
|
+
console.log(`Deleted observation ${id}`);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
this.program
|
|
131
|
+
.command('timeline [project]')
|
|
132
|
+
.description('Show timeline of observations')
|
|
133
|
+
.option('-l, --limit <number>', 'Limit results', '20')
|
|
134
|
+
.action(async (project, options) => {
|
|
135
|
+
const result = await this.memory.search({
|
|
136
|
+
projectId: project,
|
|
137
|
+
limit: parseInt(options.limit as string),
|
|
138
|
+
});
|
|
139
|
+
console.log(`Timeline (${result.total} observations):`);
|
|
140
|
+
result.observations.forEach((obs) => {
|
|
141
|
+
const date = obs.createdAt.toLocaleDateString();
|
|
142
|
+
console.log(` ${date} [${obs.type}] ${obs.title}`);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
|
|
146
|
+
this.program
|
|
147
|
+
.command('stats')
|
|
148
|
+
.description('Show statistics')
|
|
149
|
+
.action(async () => {
|
|
150
|
+
const result = await this.memory.search({});
|
|
151
|
+
const byType = result.observations.reduce(
|
|
152
|
+
(acc, obs) => {
|
|
153
|
+
acc[obs.type] = (acc[obs.type] || 0) + 1;
|
|
154
|
+
return acc;
|
|
155
|
+
},
|
|
156
|
+
{} as Record<string, number>
|
|
157
|
+
);
|
|
158
|
+
console.log('Statistics:');
|
|
159
|
+
console.log(` Total observations: ${result.total}`);
|
|
160
|
+
console.log(' By type:');
|
|
161
|
+
Object.entries(byType).forEach(([type, count]) => {
|
|
162
|
+
console.log(` ${type}: ${count}`);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
private async getOrCreateSessionId(projectId: string): Promise<number> {
|
|
168
|
+
if (this.activeSessionId) {
|
|
169
|
+
return this.activeSessionId;
|
|
170
|
+
}
|
|
171
|
+
const session = await this.memory.createSession({
|
|
172
|
+
projectId,
|
|
173
|
+
endedAt: null,
|
|
174
|
+
metadata: {},
|
|
175
|
+
});
|
|
176
|
+
this.activeSessionId = session.id;
|
|
177
|
+
return session.id;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
async run(argv: string[] = process.argv) {
|
|
181
|
+
await this.program.parseAsync(argv);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
close() {
|
|
185
|
+
this.memory.close();
|
|
186
|
+
}
|
|
187
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { CLI } from './CLI';
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"extends": "../../tsconfig.json",
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
"outDir": "./dist",
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"removeComments": true,
|
|
10
|
+
"types": ["bun-types"]
|
|
11
|
+
},
|
|
12
|
+
"include": ["src/**/*"],
|
|
13
|
+
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.test.tsx"]
|
|
14
|
+
}
|