cmdr-agent 1.0.2 → 1.2.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/bin/cmdr.js +2 -1
- package/dist/bin/cmdr.js.map +1 -1
- package/dist/src/cli/args.js +1 -1
- package/dist/src/cli/commands.js +26 -0
- package/dist/src/cli/commands.js.map +1 -1
- package/dist/src/cli/ink/App.d.ts +40 -0
- package/dist/src/cli/ink/App.d.ts.map +1 -0
- package/dist/src/cli/ink/App.js +717 -0
- package/dist/src/cli/ink/App.js.map +1 -0
- package/dist/src/cli/repl.d.ts +4 -0
- package/dist/src/cli/repl.d.ts.map +1 -1
- package/dist/src/cli/repl.js +59 -532
- package/dist/src/cli/repl.js.map +1 -1
- package/dist/src/cli/theme.d.ts +1 -1
- package/dist/src/cli/theme.d.ts.map +1 -1
- package/dist/src/cli/theme.js +2 -2
- package/dist/src/cli/theme.js.map +1 -1
- package/dist/src/core/types.d.ts +6 -0
- package/dist/src/core/types.d.ts.map +1 -1
- package/dist/src/llm/model-registry.d.ts +5 -0
- package/dist/src/llm/model-registry.d.ts.map +1 -1
- package/dist/src/llm/model-registry.js +43 -0
- package/dist/src/llm/model-registry.js.map +1 -1
- package/dist/src/llm/ollama.d.ts.map +1 -1
- package/dist/src/llm/ollama.js +6 -0
- package/dist/src/llm/ollama.js.map +1 -1
- package/dist/src/session/prompt-builder.d.ts.map +1 -1
- package/dist/src/session/prompt-builder.js +9 -0
- package/dist/src/session/prompt-builder.js.map +1 -1
- package/dist/src/skills/injector.d.ts +19 -0
- package/dist/src/skills/injector.d.ts.map +1 -0
- package/dist/src/skills/injector.js +67 -0
- package/dist/src/skills/injector.js.map +1 -0
- package/dist/src/skills/loader.d.ts +31 -0
- package/dist/src/skills/loader.d.ts.map +1 -0
- package/dist/src/skills/loader.js +147 -0
- package/dist/src/skills/loader.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SkillsLoader — discovers and loads skills from bundled, user, and project directories.
|
|
3
|
+
*
|
|
4
|
+
* Skill priority: project > user > bundled (last write wins on name conflict).
|
|
5
|
+
*/
|
|
6
|
+
import { readFileSync, readdirSync, existsSync, statSync, cpSync, mkdirSync } from 'fs';
|
|
7
|
+
import { join, basename } from 'path';
|
|
8
|
+
import { homedir } from 'os';
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
// Paths
|
|
11
|
+
// ---------------------------------------------------------------------------
|
|
12
|
+
const BUNDLED_SKILLS_DIR = join(import.meta.dirname ?? '.', '..', '..', 'skills');
|
|
13
|
+
const USER_SKILLS_DIR = join(homedir(), '.cmdr', 'skills');
|
|
14
|
+
function projectSkillsDir(projectRoot) {
|
|
15
|
+
return join(projectRoot, '.cmdr', 'skills');
|
|
16
|
+
}
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// YAML frontmatter parser (minimal — avoids external dep)
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
function parseFrontmatter(content) {
|
|
21
|
+
const match = content.match(/^---\s*\n([\s\S]*?)\n---\s*\n([\s\S]*)$/);
|
|
22
|
+
if (!match)
|
|
23
|
+
return { meta: {}, body: content };
|
|
24
|
+
const meta = {};
|
|
25
|
+
for (const line of match[1].split('\n')) {
|
|
26
|
+
const colon = line.indexOf(':');
|
|
27
|
+
if (colon > 0) {
|
|
28
|
+
const key = line.slice(0, colon).trim();
|
|
29
|
+
const val = line.slice(colon + 1).trim().replace(/^["']|["']$/g, '');
|
|
30
|
+
meta[key] = val;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return { meta, body: match[2] };
|
|
34
|
+
}
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
// SkillsLoader
|
|
37
|
+
// ---------------------------------------------------------------------------
|
|
38
|
+
export class SkillsLoader {
|
|
39
|
+
skills = new Map();
|
|
40
|
+
/** Load skills from all three sources (project > user > bundled priority). */
|
|
41
|
+
loadAll(projectRoot) {
|
|
42
|
+
this.skills.clear();
|
|
43
|
+
// Load in order: bundled first, then user, then project (later overwrites earlier)
|
|
44
|
+
this.loadFrom(BUNDLED_SKILLS_DIR, 'bundled');
|
|
45
|
+
this.loadFrom(USER_SKILLS_DIR, 'user');
|
|
46
|
+
this.loadFrom(projectSkillsDir(projectRoot), 'project');
|
|
47
|
+
}
|
|
48
|
+
/** Get a specific skill by name. */
|
|
49
|
+
get(name) {
|
|
50
|
+
return this.skills.get(name.toLowerCase());
|
|
51
|
+
}
|
|
52
|
+
/** List all available skills. */
|
|
53
|
+
list() {
|
|
54
|
+
return Array.from(this.skills.values());
|
|
55
|
+
}
|
|
56
|
+
/** Find skills relevant to a query (search name + description). */
|
|
57
|
+
search(query) {
|
|
58
|
+
const lower = query.toLowerCase();
|
|
59
|
+
return this.list().filter(s => s.name.toLowerCase().includes(lower) || s.description.toLowerCase().includes(lower));
|
|
60
|
+
}
|
|
61
|
+
/** Install a skill from a local path into ~/.cmdr/skills/. */
|
|
62
|
+
install(sourcePath) {
|
|
63
|
+
if (!existsSync(sourcePath) || !statSync(sourcePath).isDirectory()) {
|
|
64
|
+
throw new Error(`Skill path not found or not a directory: ${sourcePath}`);
|
|
65
|
+
}
|
|
66
|
+
const skillName = basename(sourcePath);
|
|
67
|
+
const dest = join(USER_SKILLS_DIR, skillName);
|
|
68
|
+
mkdirSync(dest, { recursive: true });
|
|
69
|
+
cpSync(sourcePath, dest, { recursive: true });
|
|
70
|
+
return skillName;
|
|
71
|
+
}
|
|
72
|
+
/** Scaffold a new skill in .cmdr/skills/<name>. */
|
|
73
|
+
scaffold(projectRoot, name) {
|
|
74
|
+
const dir = join(projectSkillsDir(projectRoot), name);
|
|
75
|
+
if (existsSync(dir))
|
|
76
|
+
throw new Error(`Skill already exists: ${name}`);
|
|
77
|
+
mkdirSync(dir, { recursive: true });
|
|
78
|
+
mkdirSync(join(dir, 'scripts'), { recursive: true });
|
|
79
|
+
const template = `---
|
|
80
|
+
name: ${name}
|
|
81
|
+
description: "TODO: describe what this skill does"
|
|
82
|
+
---
|
|
83
|
+
|
|
84
|
+
# ${name}
|
|
85
|
+
|
|
86
|
+
## Instructions
|
|
87
|
+
|
|
88
|
+
TODO: Write instructions for the agent here.
|
|
89
|
+
`;
|
|
90
|
+
const { writeFileSync } = require('fs');
|
|
91
|
+
writeFileSync(join(dir, 'SKILL.md'), template);
|
|
92
|
+
return dir;
|
|
93
|
+
}
|
|
94
|
+
// -----------------------------------------------------------------------
|
|
95
|
+
// Private helpers
|
|
96
|
+
// -----------------------------------------------------------------------
|
|
97
|
+
loadFrom(dir, source) {
|
|
98
|
+
if (!existsSync(dir))
|
|
99
|
+
return;
|
|
100
|
+
let entries;
|
|
101
|
+
try {
|
|
102
|
+
entries = readdirSync(dir, { withFileTypes: true })
|
|
103
|
+
.filter(d => d.isDirectory())
|
|
104
|
+
.map(d => d.name);
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
for (const entry of entries) {
|
|
110
|
+
const skillDir = join(dir, entry);
|
|
111
|
+
const skillMdPath = join(skillDir, 'SKILL.md');
|
|
112
|
+
if (!existsSync(skillMdPath))
|
|
113
|
+
continue;
|
|
114
|
+
try {
|
|
115
|
+
const raw = readFileSync(skillMdPath, 'utf-8');
|
|
116
|
+
const { meta, body } = parseFrontmatter(raw);
|
|
117
|
+
const scripts = this.findFiles(skillDir, 'scripts');
|
|
118
|
+
const references = this.findFiles(skillDir, '').filter(f => f.endsWith('.md') && !f.endsWith('SKILL.md'));
|
|
119
|
+
this.skills.set(entry.toLowerCase(), {
|
|
120
|
+
name: meta.name || entry,
|
|
121
|
+
description: meta.description || '',
|
|
122
|
+
instructions: body.trim(),
|
|
123
|
+
scripts,
|
|
124
|
+
references,
|
|
125
|
+
source,
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Skip malformed skills
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
findFiles(base, subdir) {
|
|
134
|
+
const dir = subdir ? join(base, subdir) : base;
|
|
135
|
+
if (!existsSync(dir))
|
|
136
|
+
return [];
|
|
137
|
+
try {
|
|
138
|
+
return readdirSync(dir)
|
|
139
|
+
.filter(f => !statSync(join(dir, f)).isDirectory())
|
|
140
|
+
.map(f => join(dir, f));
|
|
141
|
+
}
|
|
142
|
+
catch {
|
|
143
|
+
return [];
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
//# sourceMappingURL=loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.js","sourceRoot":"","sources":["../../../src/skills/loader.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cmdr-agent",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "Open-source multi-agent coding tool for your terminal. Powered by Ollama.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"types": "dist/index.d.ts",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"build": "tsc",
|
|
13
|
+
"postbuild": "chmod +x dist/bin/cmdr.js",
|
|
13
14
|
"dev": "tsc --watch",
|
|
14
15
|
"test": "vitest run",
|
|
15
16
|
"test:watch": "vitest",
|
|
@@ -33,15 +34,18 @@
|
|
|
33
34
|
},
|
|
34
35
|
"dependencies": {
|
|
35
36
|
"chalk": "^5.3.0",
|
|
36
|
-
"
|
|
37
|
+
"ink": "^5.2.1",
|
|
38
|
+
"ink-text-input": "^6.0.0",
|
|
37
39
|
"marked": "^14.0.0",
|
|
38
40
|
"marked-terminal": "^7.2.0",
|
|
39
41
|
"ora": "^8.0.0",
|
|
42
|
+
"react": "^18.3.1",
|
|
40
43
|
"smol-toml": "^1.6.1",
|
|
41
44
|
"zod": "^3.23.0"
|
|
42
45
|
},
|
|
43
46
|
"devDependencies": {
|
|
44
47
|
"@types/node": "^22.0.0",
|
|
48
|
+
"@types/react": "^18.3.28",
|
|
45
49
|
"typescript": "^5.6.0",
|
|
46
50
|
"vitest": "^2.1.0"
|
|
47
51
|
},
|