natureco-cli 1.0.1 → 1.0.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/bin/natureco.js +52 -1
- package/package.json +5 -5
- package/src/commands/chat.js +211 -9
- package/src/commands/commands.js +74 -0
- package/src/commands/cron.js +383 -0
- package/src/commands/git.js +229 -0
- package/src/commands/help.js +28 -4
- package/src/commands/hooks.js +87 -0
- package/src/commands/sessions.js +119 -0
- package/src/commands/setup.js +150 -134
- package/src/commands/skills.js +85 -1
- package/src/commands/tasks.js +79 -0
- package/src/utils/api.js +9 -0
- package/src/utils/background.js +66 -0
- package/src/utils/commands.js +77 -0
- package/src/utils/cron.js +126 -0
- package/src/utils/hooks.js +154 -0
- package/src/utils/memory.js +160 -0
- package/src/utils/sessions.js +109 -0
- package/src/utils/skills.js +41 -5
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
const os = require('os');
|
|
4
|
+
|
|
5
|
+
function getSessionsDir(botId) {
|
|
6
|
+
return path.join(os.homedir(), '.natureco', 'history', botId, 'sessions');
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function ensureSessionsDir(botId) {
|
|
10
|
+
const dir = getSessionsDir(botId);
|
|
11
|
+
if (!fs.existsSync(dir)) {
|
|
12
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function createSession(botId, botName) {
|
|
17
|
+
ensureSessionsDir(botId);
|
|
18
|
+
|
|
19
|
+
const sessionId = Date.now().toString(36) + Math.random().toString(36).slice(2, 7);
|
|
20
|
+
const session = {
|
|
21
|
+
id: sessionId,
|
|
22
|
+
botId,
|
|
23
|
+
botName,
|
|
24
|
+
createdAt: new Date().toISOString(),
|
|
25
|
+
messages: [],
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
saveSession(botId, session);
|
|
29
|
+
return session;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function saveSession(botId, session) {
|
|
33
|
+
ensureSessionsDir(botId);
|
|
34
|
+
const sessionFile = path.join(getSessionsDir(botId), `${session.id}.json`);
|
|
35
|
+
fs.writeFileSync(sessionFile, JSON.stringify(session, null, 2), 'utf-8');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function loadSession(botId, sessionId) {
|
|
39
|
+
const sessionFile = path.join(getSessionsDir(botId), `${sessionId}.json`);
|
|
40
|
+
if (!fs.existsSync(sessionFile)) {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
try {
|
|
44
|
+
const data = fs.readFileSync(sessionFile, 'utf-8');
|
|
45
|
+
return JSON.parse(data);
|
|
46
|
+
} catch {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
function getLatestSession(botId) {
|
|
52
|
+
ensureSessionsDir(botId);
|
|
53
|
+
const sessionsDir = getSessionsDir(botId);
|
|
54
|
+
const files = fs.readdirSync(sessionsDir).filter(f => f.endsWith('.json'));
|
|
55
|
+
|
|
56
|
+
if (files.length === 0) return null;
|
|
57
|
+
|
|
58
|
+
// Sort by modification time
|
|
59
|
+
const sorted = files
|
|
60
|
+
.map(f => ({
|
|
61
|
+
file: f,
|
|
62
|
+
mtime: fs.statSync(path.join(sessionsDir, f)).mtime.getTime(),
|
|
63
|
+
}))
|
|
64
|
+
.sort((a, b) => b.mtime - a.mtime);
|
|
65
|
+
|
|
66
|
+
const latestFile = sorted[0].file;
|
|
67
|
+
const sessionId = path.basename(latestFile, '.json');
|
|
68
|
+
return loadSession(botId, sessionId);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function listSessions(botId) {
|
|
72
|
+
ensureSessionsDir(botId);
|
|
73
|
+
const sessionsDir = getSessionsDir(botId);
|
|
74
|
+
const files = fs.readdirSync(sessionsDir).filter(f => f.endsWith('.json'));
|
|
75
|
+
|
|
76
|
+
const sessions = files.map(f => {
|
|
77
|
+
const sessionId = path.basename(f, '.json');
|
|
78
|
+
const session = loadSession(botId, sessionId);
|
|
79
|
+
return session;
|
|
80
|
+
}).filter(Boolean);
|
|
81
|
+
|
|
82
|
+
// Sort by creation time
|
|
83
|
+
sessions.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
|
|
84
|
+
|
|
85
|
+
return sessions;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
function addMessageToSession(botId, sessionId, userMessage, botReply) {
|
|
89
|
+
const session = loadSession(botId, sessionId);
|
|
90
|
+
if (!session) return false;
|
|
91
|
+
|
|
92
|
+
session.messages.push({
|
|
93
|
+
user: userMessage,
|
|
94
|
+
bot: botReply,
|
|
95
|
+
timestamp: new Date().toISOString(),
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
saveSession(botId, session);
|
|
99
|
+
return true;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
module.exports = {
|
|
103
|
+
createSession,
|
|
104
|
+
saveSession,
|
|
105
|
+
loadSession,
|
|
106
|
+
getLatestSession,
|
|
107
|
+
listSessions,
|
|
108
|
+
addMessageToSession,
|
|
109
|
+
};
|
package/src/utils/skills.js
CHANGED
|
@@ -10,7 +10,7 @@ const PROJECT_SKILLS_DIR = path.join(process.cwd(), '.natureco', 'skills');
|
|
|
10
10
|
|
|
11
11
|
// Skill metadata parser
|
|
12
12
|
function parseSkillMetadata(content) {
|
|
13
|
-
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
13
|
+
const frontmatterMatch = content.match(/^---\r?\n([\s\S]*?)\r?\n---/);
|
|
14
14
|
if (!frontmatterMatch) return null;
|
|
15
15
|
|
|
16
16
|
const frontmatter = frontmatterMatch[1];
|
|
@@ -144,14 +144,32 @@ function getSkills() {
|
|
|
144
144
|
return skills;
|
|
145
145
|
}
|
|
146
146
|
|
|
147
|
-
// Install skill from NatureHub
|
|
147
|
+
// Install skill from NatureHub or ClawHub
|
|
148
148
|
async function installSkill(slug) {
|
|
149
|
-
|
|
149
|
+
let url;
|
|
150
|
+
let actualSlug = slug;
|
|
151
|
+
|
|
152
|
+
// ClawHub format: clawhub:github
|
|
153
|
+
if (slug.startsWith('clawhub:')) {
|
|
154
|
+
actualSlug = slug.replace('clawhub:', '');
|
|
155
|
+
url = `https://clawhub.ai/skills/${actualSlug}/SKILL.md`;
|
|
156
|
+
}
|
|
157
|
+
// Direct URL
|
|
158
|
+
else if (slug.startsWith('http://') || slug.startsWith('https://')) {
|
|
159
|
+
url = slug;
|
|
160
|
+
// Extract slug from URL
|
|
161
|
+
const urlParts = slug.split('/');
|
|
162
|
+
actualSlug = urlParts[urlParts.length - 2] || 'custom-skill';
|
|
163
|
+
}
|
|
164
|
+
// NatureHub (default)
|
|
165
|
+
else {
|
|
166
|
+
url = `https://natureco.me/hub/skills/${slug}/SKILL.md`;
|
|
167
|
+
}
|
|
150
168
|
|
|
151
169
|
try {
|
|
152
170
|
const response = await fetch(url);
|
|
153
171
|
if (!response.ok) {
|
|
154
|
-
throw new Error(`Skill bulunamadı: ${
|
|
172
|
+
throw new Error(`Skill bulunamadı: ${actualSlug}`);
|
|
155
173
|
}
|
|
156
174
|
|
|
157
175
|
const content = await response.text();
|
|
@@ -172,7 +190,7 @@ async function installSkill(slug) {
|
|
|
172
190
|
fs.mkdirSync(USER_SKILLS_DIR, { recursive: true });
|
|
173
191
|
}
|
|
174
192
|
|
|
175
|
-
const skillDir = path.join(USER_SKILLS_DIR,
|
|
193
|
+
const skillDir = path.join(USER_SKILLS_DIR, actualSlug);
|
|
176
194
|
if (!fs.existsSync(skillDir)) {
|
|
177
195
|
fs.mkdirSync(skillDir, { recursive: true });
|
|
178
196
|
}
|
|
@@ -256,6 +274,23 @@ Bu skill ${name} işlemlerini yapar.
|
|
|
256
274
|
return path.join(skillDir, 'SKILL.md');
|
|
257
275
|
}
|
|
258
276
|
|
|
277
|
+
// Popular skills list
|
|
278
|
+
const POPULAR_SKILLS = [
|
|
279
|
+
{ slug: 'github', name: 'GitHub', description: 'GitHub repo işlemleri' },
|
|
280
|
+
{ slug: 'filesystem', name: 'Filesystem', description: 'Dosya sistemi işlemleri' },
|
|
281
|
+
{ slug: 'web-search', name: 'Web Search', description: 'Web arama' },
|
|
282
|
+
{ slug: 'summarize', name: 'Summarize', description: 'Metin özetleme' },
|
|
283
|
+
{ slug: 'code-review', name: 'Code Review', description: 'Kod inceleme' },
|
|
284
|
+
{ slug: 'translate', name: 'Translate', description: 'Çeviri' },
|
|
285
|
+
{ slug: 'weather', name: 'Weather', description: 'Hava durumu' },
|
|
286
|
+
{ slug: 'calendar', name: 'Calendar', description: 'Takvim yönetimi' },
|
|
287
|
+
];
|
|
288
|
+
|
|
289
|
+
// Get popular skills
|
|
290
|
+
function getPopularSkills() {
|
|
291
|
+
return POPULAR_SKILLS;
|
|
292
|
+
}
|
|
293
|
+
|
|
259
294
|
// Get skill prompt injection content
|
|
260
295
|
function getSkillPrompts() {
|
|
261
296
|
const skills = getSkills();
|
|
@@ -282,4 +317,5 @@ module.exports = {
|
|
|
282
317
|
createSkillTemplate,
|
|
283
318
|
getSkillPrompts,
|
|
284
319
|
checkSkillRequirements,
|
|
320
|
+
getPopularSkills,
|
|
285
321
|
};
|