@llmtune/cli 0.1.0 → 0.1.1
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/README.md +1 -1
- package/dist/agent/conversation.d.ts +42 -0
- package/dist/agent/conversation.js +105 -0
- package/dist/agent/loop.d.ts +19 -0
- package/dist/agent/loop.js +185 -0
- package/dist/agent/planner.d.ts +8 -0
- package/dist/agent/planner.js +43 -0
- package/dist/auth/client.d.ts +4 -0
- package/dist/auth/client.js +24 -0
- package/dist/auth/config.d.ts +21 -0
- package/dist/auth/config.js +83 -0
- package/dist/commands/chat.d.ts +5 -0
- package/dist/commands/chat.js +27 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +37 -0
- package/dist/commands/login.d.ts +2 -0
- package/dist/commands/login.js +93 -0
- package/dist/commands/marketplace.d.ts +6 -0
- package/dist/commands/marketplace.js +213 -0
- package/dist/commands/models.d.ts +2 -0
- package/dist/commands/models.js +53 -0
- package/dist/compact/history-store.d.ts +29 -0
- package/dist/compact/history-store.js +110 -0
- package/dist/compact/microcompact.d.ts +10 -0
- package/dist/compact/microcompact.js +43 -0
- package/dist/compact/service.d.ts +13 -0
- package/dist/compact/service.js +156 -0
- package/dist/context/analyzer.d.ts +26 -0
- package/dist/context/analyzer.js +99 -0
- package/dist/context/builder.d.ts +13 -0
- package/dist/context/builder.js +144 -0
- package/dist/context/cache.d.ts +6 -0
- package/dist/context/cache.js +8 -0
- package/dist/context/git-context.d.ts +9 -0
- package/dist/context/git-context.js +49 -0
- package/dist/context/llmtune-md.d.ts +6 -0
- package/dist/context/llmtune-md.js +73 -0
- package/dist/context/workspace.d.ts +11 -0
- package/dist/context/workspace.js +115 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +1 -1
- package/dist/marketplace/client.d.ts +52 -0
- package/dist/marketplace/client.js +86 -0
- package/dist/memory/files.d.ts +14 -0
- package/dist/memory/files.js +116 -0
- package/dist/memory/service.d.ts +22 -0
- package/dist/memory/service.js +146 -0
- package/dist/repl/repl.d.ts +8 -0
- package/dist/repl/repl.js +374 -0
- package/dist/skills/args.d.ts +10 -0
- package/dist/skills/args.js +37 -0
- package/dist/skills/frontmatter.d.ts +6 -0
- package/dist/skills/frontmatter.js +44 -0
- package/dist/skills/loader.d.ts +5 -0
- package/dist/skills/loader.js +59 -0
- package/dist/skills/registry.d.ts +27 -0
- package/dist/skills/registry.js +162 -0
- package/dist/skills/signing/signer.d.ts +19 -0
- package/dist/skills/signing/signer.js +110 -0
- package/dist/skills/trust.d.ts +11 -0
- package/dist/skills/trust.js +42 -0
- package/dist/telemetry/logger.d.ts +51 -0
- package/dist/telemetry/logger.js +135 -0
- package/dist/tools/permissions.d.ts +20 -0
- package/dist/tools/permissions.js +58 -0
- package/dist/tools/protocol.d.ts +22 -0
- package/dist/tools/protocol.js +3 -0
- package/dist/tools/registry.d.ts +20 -0
- package/dist/tools/registry.js +77 -0
- package/dist/tools/sandbox/docker.d.ts +16 -0
- package/dist/tools/sandbox/docker.js +240 -0
- package/dist/tools/sandbox/index.d.ts +18 -0
- package/dist/tools/sandbox/index.js +80 -0
- package/dist/tools/tools/ask-user.d.ts +3 -0
- package/dist/tools/tools/ask-user.js +56 -0
- package/dist/tools/tools/bash.d.ts +3 -0
- package/dist/tools/tools/bash.js +85 -0
- package/dist/tools/tools/edit.d.ts +3 -0
- package/dist/tools/tools/edit.js +138 -0
- package/dist/tools/tools/glob.d.ts +3 -0
- package/dist/tools/tools/glob.js +63 -0
- package/dist/tools/tools/grep.d.ts +3 -0
- package/dist/tools/tools/grep.js +148 -0
- package/dist/tools/tools/read.d.ts +3 -0
- package/dist/tools/tools/read.js +85 -0
- package/dist/tools/tools/web-fetch.d.ts +3 -0
- package/dist/tools/tools/web-fetch.js +142 -0
- package/dist/tools/tools/write.d.ts +3 -0
- package/dist/tools/tools/write.js +84 -0
- package/dist/tools/validation.d.ts +13 -0
- package/dist/tools/validation.js +142 -0
- package/dist/utils/markdown.d.ts +9 -0
- package/dist/utils/markdown.js +89 -0
- package/dist/utils/streaming.d.ts +10 -0
- package/dist/utils/streaming.js +63 -0
- package/dist/utils/tokens.d.ts +12 -0
- package/dist/utils/tokens.js +44 -0
- package/package.json +2 -2
- package/dist/agent/conversation.d.ts.map +0 -1
- package/dist/agent/loop.d.ts.map +0 -1
- package/dist/agent/planner.d.ts.map +0 -1
- package/dist/auth/client.d.ts.map +0 -1
- package/dist/auth/config.d.ts.map +0 -1
- package/dist/commands/chat.d.ts.map +0 -1
- package/dist/commands/config.d.ts.map +0 -1
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/marketplace.d.ts.map +0 -1
- package/dist/commands/models.d.ts.map +0 -1
- package/dist/compact/history-store.d.ts.map +0 -1
- package/dist/compact/microcompact.d.ts.map +0 -1
- package/dist/compact/service.d.ts.map +0 -1
- package/dist/context/analyzer.d.ts.map +0 -1
- package/dist/context/builder.d.ts.map +0 -1
- package/dist/context/cache.d.ts.map +0 -1
- package/dist/context/git-context.d.ts.map +0 -1
- package/dist/context/llmtune-md.d.ts.map +0 -1
- package/dist/context/workspace.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/marketplace/client.d.ts.map +0 -1
- package/dist/memory/files.d.ts.map +0 -1
- package/dist/memory/service.d.ts.map +0 -1
- package/dist/repl/repl.d.ts.map +0 -1
- package/dist/skills/args.d.ts.map +0 -1
- package/dist/skills/frontmatter.d.ts.map +0 -1
- package/dist/skills/loader.d.ts.map +0 -1
- package/dist/skills/registry.d.ts.map +0 -1
- package/dist/skills/signing/signer.d.ts.map +0 -1
- package/dist/skills/trust.d.ts.map +0 -1
- package/dist/telemetry/logger.d.ts.map +0 -1
- package/dist/tools/permissions.d.ts.map +0 -1
- package/dist/tools/protocol.d.ts.map +0 -1
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/sandbox/docker.d.ts.map +0 -1
- package/dist/tools/sandbox/index.d.ts.map +0 -1
- package/dist/tools/tools/ask-user.d.ts.map +0 -1
- package/dist/tools/tools/bash.d.ts.map +0 -1
- package/dist/tools/tools/edit.d.ts.map +0 -1
- package/dist/tools/tools/glob.d.ts.map +0 -1
- package/dist/tools/tools/grep.d.ts.map +0 -1
- package/dist/tools/tools/read.d.ts.map +0 -1
- package/dist/tools/tools/web-fetch.d.ts.map +0 -1
- package/dist/tools/tools/write.d.ts.map +0 -1
- package/dist/tools/validation.d.ts.map +0 -1
- package/dist/utils/markdown.d.ts.map +0 -1
- package/dist/utils/streaming.d.ts.map +0 -1
- package/dist/utils/tokens.d.ts.map +0 -1
- package/src/agent/conversation.ts +0 -140
- package/src/agent/loop.ts +0 -215
- package/src/agent/planner.ts +0 -55
- package/src/auth/client.ts +0 -19
- package/src/auth/config.ts +0 -89
- package/src/commands/chat.ts +0 -28
- package/src/commands/config.ts +0 -36
- package/src/commands/login.ts +0 -63
- package/src/commands/marketplace.ts +0 -190
- package/src/commands/models.ts +0 -74
- package/src/compact/history-store.ts +0 -101
- package/src/compact/microcompact.ts +0 -49
- package/src/compact/service.ts +0 -154
- package/src/context/analyzer.ts +0 -127
- package/src/context/builder.ts +0 -123
- package/src/context/cache.ts +0 -11
- package/src/context/git-context.ts +0 -58
- package/src/context/llmtune-md.ts +0 -48
- package/src/context/workspace.ts +0 -139
- package/src/index.ts +0 -100
- package/src/marketplace/client.ts +0 -118
- package/src/memory/files.ts +0 -81
- package/src/memory/service.ts +0 -124
- package/src/repl/repl.ts +0 -400
- package/src/skills/args.ts +0 -35
- package/src/skills/builtin/explain-code/SKILL.md +0 -30
- package/src/skills/frontmatter.ts +0 -47
- package/src/skills/loader.ts +0 -25
- package/src/skills/registry.ts +0 -155
- package/src/skills/signing/signer.ts +0 -101
- package/src/skills/trust.ts +0 -50
- package/src/telemetry/logger.ts +0 -108
- package/src/tools/permissions.ts +0 -83
- package/src/tools/protocol.ts +0 -24
- package/src/tools/registry.ts +0 -93
- package/src/tools/sandbox/docker.ts +0 -225
- package/src/tools/sandbox/index.ts +0 -91
- package/src/tools/tools/ask-user.ts +0 -60
- package/src/tools/tools/bash.ts +0 -97
- package/src/tools/tools/edit.ts +0 -111
- package/src/tools/tools/glob.ts +0 -68
- package/src/tools/tools/grep.ts +0 -121
- package/src/tools/tools/read.ts +0 -57
- package/src/tools/tools/web-fetch.ts +0 -158
- package/src/tools/tools/write.ts +0 -52
- package/src/tools/validation.ts +0 -164
- package/src/utils/markdown.ts +0 -96
- package/src/utils/streaming.ts +0 -63
- package/src/utils/tokens.ts +0 -41
- package/tsconfig.json +0 -20
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildWorkspaceSnapshot = buildWorkspaceSnapshot;
|
|
4
|
+
exports.renderWorkspaceSection = renderWorkspaceSection;
|
|
5
|
+
const promises_1 = require("fs/promises");
|
|
6
|
+
const path_1 = require("path");
|
|
7
|
+
const KEY_FILE_NAMES = new Set([
|
|
8
|
+
"package.json",
|
|
9
|
+
"tsconfig.json",
|
|
10
|
+
"Cargo.toml",
|
|
11
|
+
"go.mod",
|
|
12
|
+
"pyproject.toml",
|
|
13
|
+
"requirements.txt",
|
|
14
|
+
"Makefile",
|
|
15
|
+
"Dockerfile",
|
|
16
|
+
"docker-compose.yml",
|
|
17
|
+
"README.md",
|
|
18
|
+
"CLAUDE.md",
|
|
19
|
+
"LLMTUNE.md",
|
|
20
|
+
".env.example",
|
|
21
|
+
".gitignore",
|
|
22
|
+
"prisma",
|
|
23
|
+
"schema.prisma",
|
|
24
|
+
]);
|
|
25
|
+
const IGNORED_DIRS = new Set([
|
|
26
|
+
"node_modules",
|
|
27
|
+
".git",
|
|
28
|
+
"__pycache__",
|
|
29
|
+
".next",
|
|
30
|
+
"dist",
|
|
31
|
+
"build",
|
|
32
|
+
".venv",
|
|
33
|
+
"venv",
|
|
34
|
+
".tox",
|
|
35
|
+
"target",
|
|
36
|
+
".cache",
|
|
37
|
+
".turbo",
|
|
38
|
+
"coverage",
|
|
39
|
+
]);
|
|
40
|
+
async function buildWorkspaceSnapshot(workspaceRoot, cwd) {
|
|
41
|
+
const root = workspaceRoot;
|
|
42
|
+
const current = cwd ?? workspaceRoot;
|
|
43
|
+
const topEntries = await safeReaddir(root);
|
|
44
|
+
const topLevelEntries = topEntries.map((e) => e.name);
|
|
45
|
+
const keyFiles = [];
|
|
46
|
+
const fileTypeCounts = {};
|
|
47
|
+
let totalFiles = 0;
|
|
48
|
+
await walkDir(root, "", async (name, relPath, isDir) => {
|
|
49
|
+
if (isDir)
|
|
50
|
+
return;
|
|
51
|
+
totalFiles++;
|
|
52
|
+
const ext = (0, path_1.extname)(name).toLowerCase();
|
|
53
|
+
fileTypeCounts[ext] = (fileTypeCounts[ext] ?? 0) + 1;
|
|
54
|
+
if (KEY_FILE_NAMES.has(name)) {
|
|
55
|
+
keyFiles.push((0, path_1.relative)(root, (0, path_1.join)(root, relPath, name)));
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
return {
|
|
59
|
+
workspace_root: root,
|
|
60
|
+
current_directory: current,
|
|
61
|
+
top_level_entries: topLevelEntries.slice(0, 30),
|
|
62
|
+
key_files: keyFiles.slice(0, 20),
|
|
63
|
+
total_files: totalFiles,
|
|
64
|
+
file_type_counts: fileTypeCounts,
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function renderWorkspaceSection(snapshot) {
|
|
68
|
+
const today = new Date().toISOString().split("T")[0];
|
|
69
|
+
const lines = [
|
|
70
|
+
"## Runtime Context",
|
|
71
|
+
`- Today's date: ${today}`,
|
|
72
|
+
`- Workspace root: ${snapshot.workspace_root}`,
|
|
73
|
+
`- Current directory: ${snapshot.current_directory}`,
|
|
74
|
+
`- Total files: ${snapshot.total_files}`,
|
|
75
|
+
];
|
|
76
|
+
const topExts = Object.entries(snapshot.file_type_counts)
|
|
77
|
+
.sort((a, b) => b[1] - a[1])
|
|
78
|
+
.slice(0, 5)
|
|
79
|
+
.map(([ext, count]) => `${ext || "none"}: ${count}`);
|
|
80
|
+
if (topExts.length > 0) {
|
|
81
|
+
lines.push(`- Top file types: ${topExts.join(", ")}`);
|
|
82
|
+
}
|
|
83
|
+
if (snapshot.key_files.length > 0) {
|
|
84
|
+
lines.push(`- Key files: ${snapshot.key_files.join(", ")}`);
|
|
85
|
+
}
|
|
86
|
+
if (snapshot.top_level_entries.length > 0) {
|
|
87
|
+
lines.push(`- Top-level entries: ${snapshot.top_level_entries.slice(0, 15).join(", ")}`);
|
|
88
|
+
}
|
|
89
|
+
return lines.join("\n");
|
|
90
|
+
}
|
|
91
|
+
async function walkDir(root, relDir, visitor, depth = 0) {
|
|
92
|
+
if (depth > 3)
|
|
93
|
+
return;
|
|
94
|
+
const entries = await safeReaddir((0, path_1.join)(root, relDir));
|
|
95
|
+
for (const entry of entries) {
|
|
96
|
+
if (IGNORED_DIRS.has(entry.name))
|
|
97
|
+
continue;
|
|
98
|
+
const relPath = relDir ? `${relDir}/${entry.name}` : entry.name;
|
|
99
|
+
const isDir = entry.isDirectory();
|
|
100
|
+
await visitor(entry.name, relDir, isDir);
|
|
101
|
+
if (isDir && depth < 3) {
|
|
102
|
+
await walkDir(root, relPath, visitor, depth + 1);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
async function safeReaddir(dirPath) {
|
|
107
|
+
try {
|
|
108
|
+
const entries = await (0, promises_1.readdir)(dirPath, { withFileTypes: true });
|
|
109
|
+
return entries;
|
|
110
|
+
}
|
|
111
|
+
catch {
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
//# sourceMappingURL=workspace.js.map
|
package/dist/index.d.ts
ADDED
package/dist/index.js
CHANGED
|
@@ -45,7 +45,7 @@ const repl_1 = require("./repl/repl");
|
|
|
45
45
|
const program = new commander_1.Command();
|
|
46
46
|
program
|
|
47
47
|
.name("llmtune")
|
|
48
|
-
.description("
|
|
48
|
+
.description("AI CLI Agent powered by llmtune.io")
|
|
49
49
|
.version("0.1.0");
|
|
50
50
|
program
|
|
51
51
|
.command("login")
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Skill marketplace client.
|
|
3
|
+
* Interacts with the infra's skill registry API to list, search, install, and publish skills.
|
|
4
|
+
*/
|
|
5
|
+
import type { AppConfig } from "../auth/config";
|
|
6
|
+
export interface MarketplaceSkill {
|
|
7
|
+
name: string;
|
|
8
|
+
description: string;
|
|
9
|
+
trustLevel: "local" | "community" | "verified" | "signed";
|
|
10
|
+
allowedTools: string[];
|
|
11
|
+
author?: string;
|
|
12
|
+
version?: string;
|
|
13
|
+
installs?: number;
|
|
14
|
+
rating?: number;
|
|
15
|
+
tags?: string[];
|
|
16
|
+
}
|
|
17
|
+
export interface SearchResult {
|
|
18
|
+
skills: MarketplaceSkill[];
|
|
19
|
+
total: number;
|
|
20
|
+
page: number;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* List all skills in the marketplace.
|
|
24
|
+
*/
|
|
25
|
+
export declare function listSkills(config: AppConfig, options?: {
|
|
26
|
+
search?: string;
|
|
27
|
+
tag?: string;
|
|
28
|
+
page?: number;
|
|
29
|
+
limit?: number;
|
|
30
|
+
}): Promise<SearchResult>;
|
|
31
|
+
/**
|
|
32
|
+
* Get details for a specific skill.
|
|
33
|
+
*/
|
|
34
|
+
export declare function getSkillDetails(config: AppConfig, name: string): Promise<MarketplaceSkill>;
|
|
35
|
+
/**
|
|
36
|
+
* Install a skill from the marketplace to the local skills directory.
|
|
37
|
+
*/
|
|
38
|
+
export declare function installSkill(config: AppConfig, name: string): Promise<string>;
|
|
39
|
+
/**
|
|
40
|
+
* Publish a local skill to the marketplace.
|
|
41
|
+
*/
|
|
42
|
+
export declare function publishSkill(config: AppConfig, skill: {
|
|
43
|
+
name: string;
|
|
44
|
+
description: string;
|
|
45
|
+
content: string;
|
|
46
|
+
trustLevel: string;
|
|
47
|
+
allowedTools: string[];
|
|
48
|
+
}): Promise<{
|
|
49
|
+
published: boolean;
|
|
50
|
+
skillName: string;
|
|
51
|
+
}>;
|
|
52
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.listSkills = listSkills;
|
|
4
|
+
exports.getSkillDetails = getSkillDetails;
|
|
5
|
+
exports.installSkill = installSkill;
|
|
6
|
+
exports.publishSkill = publishSkill;
|
|
7
|
+
function getApiBase(config) {
|
|
8
|
+
return String(config.apiBase ?? "https://api.llmtune.io/api/agent/v1").replace(/\/$/, "");
|
|
9
|
+
}
|
|
10
|
+
function getHeaders(config) {
|
|
11
|
+
return {
|
|
12
|
+
"Content-Type": "application/json",
|
|
13
|
+
Authorization: `Bearer ${config.apiKey}`,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* List all skills in the marketplace.
|
|
18
|
+
*/
|
|
19
|
+
async function listSkills(config, options) {
|
|
20
|
+
const base = getApiBase(config);
|
|
21
|
+
const params = new URLSearchParams();
|
|
22
|
+
if (options?.search)
|
|
23
|
+
params.set("search", options.search);
|
|
24
|
+
if (options?.tag)
|
|
25
|
+
params.set("tag", options.tag);
|
|
26
|
+
if (options?.page)
|
|
27
|
+
params.set("page", String(options.page));
|
|
28
|
+
if (options?.limit)
|
|
29
|
+
params.set("limit", String(options.limit));
|
|
30
|
+
const url = `${base}/skills?${params.toString()}`;
|
|
31
|
+
const response = await fetch(url, { headers: getHeaders(config) });
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
throw new Error(`Failed to list skills: HTTP ${response.status}`);
|
|
34
|
+
}
|
|
35
|
+
return (await response.json());
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Get details for a specific skill.
|
|
39
|
+
*/
|
|
40
|
+
async function getSkillDetails(config, name) {
|
|
41
|
+
const base = getApiBase(config);
|
|
42
|
+
const url = `${base}/skills/${encodeURIComponent(name)}`;
|
|
43
|
+
const response = await fetch(url, { headers: getHeaders(config) });
|
|
44
|
+
if (!response.ok) {
|
|
45
|
+
if (response.status === 404)
|
|
46
|
+
throw new Error(`Skill not found: ${name}`);
|
|
47
|
+
throw new Error(`Failed to get skill: HTTP ${response.status}`);
|
|
48
|
+
}
|
|
49
|
+
return (await response.json());
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Install a skill from the marketplace to the local skills directory.
|
|
53
|
+
*/
|
|
54
|
+
async function installSkill(config, name) {
|
|
55
|
+
const base = getApiBase(config);
|
|
56
|
+
const url = `${base}/skills/install`;
|
|
57
|
+
const response = await fetch(url, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: getHeaders(config),
|
|
60
|
+
body: JSON.stringify({ skillName: name }),
|
|
61
|
+
});
|
|
62
|
+
if (!response.ok) {
|
|
63
|
+
const body = await response.text();
|
|
64
|
+
throw new Error(`Failed to install skill: ${body}`);
|
|
65
|
+
}
|
|
66
|
+
const data = (await response.json());
|
|
67
|
+
return data.installPath;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Publish a local skill to the marketplace.
|
|
71
|
+
*/
|
|
72
|
+
async function publishSkill(config, skill) {
|
|
73
|
+
const base = getApiBase(config);
|
|
74
|
+
const url = `${base}/skills`;
|
|
75
|
+
const response = await fetch(url, {
|
|
76
|
+
method: "POST",
|
|
77
|
+
headers: getHeaders(config),
|
|
78
|
+
body: JSON.stringify(skill),
|
|
79
|
+
});
|
|
80
|
+
if (!response.ok) {
|
|
81
|
+
const body = await response.text();
|
|
82
|
+
throw new Error(`Failed to publish skill: ${body}`);
|
|
83
|
+
}
|
|
84
|
+
return (await response.json());
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface MemoryCategory {
|
|
2
|
+
key: string;
|
|
3
|
+
filename: string;
|
|
4
|
+
description: string;
|
|
5
|
+
}
|
|
6
|
+
export declare const MEMORY_CATEGORIES: MemoryCategory[];
|
|
7
|
+
export declare function getMemoryDir(): string;
|
|
8
|
+
export declare function ensureMemoryDir(): void;
|
|
9
|
+
export declare function readMemory(key: string): string;
|
|
10
|
+
export declare function writeMemory(key: string, content: string): void;
|
|
11
|
+
export declare function appendMemory(key: string, line: string): void;
|
|
12
|
+
export declare function readAllMemory(): Record<string, string>;
|
|
13
|
+
export declare function buildMemoryPrompt(): string;
|
|
14
|
+
//# sourceMappingURL=files.d.ts.map
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.MEMORY_CATEGORIES = void 0;
|
|
37
|
+
exports.getMemoryDir = getMemoryDir;
|
|
38
|
+
exports.ensureMemoryDir = ensureMemoryDir;
|
|
39
|
+
exports.readMemory = readMemory;
|
|
40
|
+
exports.writeMemory = writeMemory;
|
|
41
|
+
exports.appendMemory = appendMemory;
|
|
42
|
+
exports.readAllMemory = readAllMemory;
|
|
43
|
+
exports.buildMemoryPrompt = buildMemoryPrompt;
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const config_1 = require("../auth/config");
|
|
47
|
+
exports.MEMORY_CATEGORIES = [
|
|
48
|
+
{ key: "preferences", filename: "preferences.md", description: "User preferences (language, style, conventions)" },
|
|
49
|
+
{ key: "project", filename: "project-notes.md", description: "Project knowledge (architecture, patterns, key decisions)" },
|
|
50
|
+
{ key: "decisions", filename: "decisions.md", description: "Past decisions and rationale" },
|
|
51
|
+
{ key: "architecture", filename: "architecture.md", description: "System architecture notes" },
|
|
52
|
+
];
|
|
53
|
+
function getMemoryDir() {
|
|
54
|
+
return path.join((0, config_1.getConfigDir)(), "memory");
|
|
55
|
+
}
|
|
56
|
+
function ensureMemoryDir() {
|
|
57
|
+
const dir = getMemoryDir();
|
|
58
|
+
if (!fs.existsSync(dir)) {
|
|
59
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
60
|
+
}
|
|
61
|
+
for (const cat of exports.MEMORY_CATEGORIES) {
|
|
62
|
+
const filePath = path.join(dir, cat.filename);
|
|
63
|
+
if (!fs.existsSync(filePath)) {
|
|
64
|
+
fs.writeFileSync(filePath, `# ${cat.description}\n\n`, "utf-8");
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function readMemory(key) {
|
|
69
|
+
const cat = exports.MEMORY_CATEGORIES.find((c) => c.key === key);
|
|
70
|
+
if (!cat)
|
|
71
|
+
return "";
|
|
72
|
+
const filePath = path.join(getMemoryDir(), cat.filename);
|
|
73
|
+
try {
|
|
74
|
+
return fs.readFileSync(filePath, "utf-8").trim();
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
return "";
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
function writeMemory(key, content) {
|
|
81
|
+
const cat = exports.MEMORY_CATEGORIES.find((c) => c.key === key);
|
|
82
|
+
if (!cat)
|
|
83
|
+
return;
|
|
84
|
+
ensureMemoryDir();
|
|
85
|
+
const filePath = path.join(getMemoryDir(), cat.filename);
|
|
86
|
+
fs.writeFileSync(filePath, content, "utf-8");
|
|
87
|
+
}
|
|
88
|
+
function appendMemory(key, line) {
|
|
89
|
+
const current = readMemory(key);
|
|
90
|
+
writeMemory(key, current + "\n" + line);
|
|
91
|
+
}
|
|
92
|
+
function readAllMemory() {
|
|
93
|
+
const result = {};
|
|
94
|
+
for (const cat of exports.MEMORY_CATEGORIES) {
|
|
95
|
+
const content = readMemory(cat.key);
|
|
96
|
+
if (content)
|
|
97
|
+
result[cat.key] = content;
|
|
98
|
+
}
|
|
99
|
+
return result;
|
|
100
|
+
}
|
|
101
|
+
function buildMemoryPrompt() {
|
|
102
|
+
const memories = readAllMemory();
|
|
103
|
+
const entries = Object.entries(memories);
|
|
104
|
+
if (entries.length === 0)
|
|
105
|
+
return "";
|
|
106
|
+
const lines = ["## User Memory"];
|
|
107
|
+
for (const [key, content] of entries) {
|
|
108
|
+
const cat = exports.MEMORY_CATEGORIES.find((c) => c.key === key);
|
|
109
|
+
if (cat && content.trim()) {
|
|
110
|
+
lines.push(`### ${cat.description}`);
|
|
111
|
+
lines.push(content);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
return lines.join("\n");
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=files.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
declare const MEMORY_FILES: {
|
|
2
|
+
readonly preferences: "preferences.md";
|
|
3
|
+
readonly "project-notes": "project-notes.md";
|
|
4
|
+
readonly decisions: "decisions.md";
|
|
5
|
+
readonly architecture: "architecture.md";
|
|
6
|
+
};
|
|
7
|
+
type MemoryCategory = keyof typeof MEMORY_FILES;
|
|
8
|
+
export interface MemoryEntry {
|
|
9
|
+
category: MemoryCategory;
|
|
10
|
+
content: string;
|
|
11
|
+
path: string;
|
|
12
|
+
}
|
|
13
|
+
export declare function readMemory(category: MemoryCategory): string;
|
|
14
|
+
export declare function writeMemory(category: MemoryCategory, content: string): void;
|
|
15
|
+
export declare function appendMemory(category: MemoryCategory, line: string): void;
|
|
16
|
+
export declare function readAllMemory(): MemoryEntry[];
|
|
17
|
+
export declare function buildMemoryPrompt(): string;
|
|
18
|
+
export declare function clearMemory(category?: MemoryCategory): void;
|
|
19
|
+
export declare function getMemoryDir(): string;
|
|
20
|
+
export declare function initMemoryFiles(): void;
|
|
21
|
+
export {};
|
|
22
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.readMemory = readMemory;
|
|
37
|
+
exports.writeMemory = writeMemory;
|
|
38
|
+
exports.appendMemory = appendMemory;
|
|
39
|
+
exports.readAllMemory = readAllMemory;
|
|
40
|
+
exports.buildMemoryPrompt = buildMemoryPrompt;
|
|
41
|
+
exports.clearMemory = clearMemory;
|
|
42
|
+
exports.getMemoryDir = getMemoryDir;
|
|
43
|
+
exports.initMemoryFiles = initMemoryFiles;
|
|
44
|
+
const fs = __importStar(require("fs"));
|
|
45
|
+
const path = __importStar(require("path"));
|
|
46
|
+
const os = __importStar(require("os"));
|
|
47
|
+
const MEMORY_DIR = path.join(os.homedir(), ".llmtune", "memory");
|
|
48
|
+
const MEMORY_FILES = {
|
|
49
|
+
preferences: "preferences.md",
|
|
50
|
+
"project-notes": "project-notes.md",
|
|
51
|
+
decisions: "decisions.md",
|
|
52
|
+
architecture: "architecture.md",
|
|
53
|
+
};
|
|
54
|
+
function ensureMemoryDir() {
|
|
55
|
+
if (!fs.existsSync(MEMORY_DIR)) {
|
|
56
|
+
fs.mkdirSync(MEMORY_DIR, { recursive: true });
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function getMemoryPath(category) {
|
|
60
|
+
return path.join(MEMORY_DIR, MEMORY_FILES[category]);
|
|
61
|
+
}
|
|
62
|
+
function readMemory(category) {
|
|
63
|
+
const filePath = getMemoryPath(category);
|
|
64
|
+
try {
|
|
65
|
+
return fs.readFileSync(filePath, "utf-8").trim();
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return "";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function writeMemory(category, content) {
|
|
72
|
+
ensureMemoryDir();
|
|
73
|
+
const filePath = getMemoryPath(category);
|
|
74
|
+
fs.writeFileSync(filePath, content.trim() + "\n", "utf-8");
|
|
75
|
+
}
|
|
76
|
+
function appendMemory(category, line) {
|
|
77
|
+
ensureMemoryDir();
|
|
78
|
+
const existing = readMemory(category);
|
|
79
|
+
const updated = existing ? `${existing}\n${line}` : line;
|
|
80
|
+
writeMemory(category, updated);
|
|
81
|
+
}
|
|
82
|
+
function readAllMemory() {
|
|
83
|
+
ensureMemoryDir();
|
|
84
|
+
const entries = [];
|
|
85
|
+
for (const [category, filename] of Object.entries(MEMORY_FILES)) {
|
|
86
|
+
const content = readMemory(category);
|
|
87
|
+
if (content) {
|
|
88
|
+
entries.push({
|
|
89
|
+
category: category,
|
|
90
|
+
content,
|
|
91
|
+
path: path.join(MEMORY_DIR, filename),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return entries;
|
|
96
|
+
}
|
|
97
|
+
function buildMemoryPrompt() {
|
|
98
|
+
const entries = readAllMemory();
|
|
99
|
+
if (entries.length === 0)
|
|
100
|
+
return "";
|
|
101
|
+
const sections = entries.map((entry) => {
|
|
102
|
+
const label = entry.category.replace(/-/g, " ").replace(/\b\w/g, (c) => c.toUpperCase());
|
|
103
|
+
return `### ${label}\n${entry.content}`;
|
|
104
|
+
});
|
|
105
|
+
return "## User Memory\n\n" + sections.join("\n\n");
|
|
106
|
+
}
|
|
107
|
+
function clearMemory(category) {
|
|
108
|
+
if (category) {
|
|
109
|
+
const filePath = getMemoryPath(category);
|
|
110
|
+
try {
|
|
111
|
+
fs.unlinkSync(filePath);
|
|
112
|
+
}
|
|
113
|
+
catch {
|
|
114
|
+
// file doesn't exist
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
for (const filename of Object.values(MEMORY_FILES)) {
|
|
119
|
+
try {
|
|
120
|
+
fs.unlinkSync(path.join(MEMORY_DIR, filename));
|
|
121
|
+
}
|
|
122
|
+
catch {
|
|
123
|
+
// skip
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
function getMemoryDir() {
|
|
129
|
+
return MEMORY_DIR;
|
|
130
|
+
}
|
|
131
|
+
function initMemoryFiles() {
|
|
132
|
+
ensureMemoryDir();
|
|
133
|
+
const defaults = {
|
|
134
|
+
preferences: "# User Preferences\n# Add your coding preferences here (one per line)\n# Example: I prefer TypeScript over JavaScript\n# Example: I use 2-space indentation\n",
|
|
135
|
+
"project-notes": "# Project Notes\n# Key facts about the current project\n# Example: Auth uses JWT + bcrypt\n# Example: Database is Neon PostgreSQL via Prisma\n",
|
|
136
|
+
decisions: "# Architecture Decisions\n# Record important technical decisions\n# Example: Decided to use Prisma instead of Drizzle for ORM\n",
|
|
137
|
+
architecture: "# Architecture Overview\n# Describe the project structure\n# Example: Frontend: Next.js 16, Backend: Express 5, DB: Neon\n",
|
|
138
|
+
};
|
|
139
|
+
for (const [category, defaultContent] of Object.entries(defaults)) {
|
|
140
|
+
const filePath = getMemoryPath(category);
|
|
141
|
+
if (!fs.existsSync(filePath)) {
|
|
142
|
+
fs.writeFileSync(filePath, defaultContent, "utf-8");
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
//# sourceMappingURL=service.js.map
|