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.
Files changed (38) hide show
  1. package/dist/bin/cmdr.js +2 -1
  2. package/dist/bin/cmdr.js.map +1 -1
  3. package/dist/src/cli/args.js +1 -1
  4. package/dist/src/cli/commands.js +26 -0
  5. package/dist/src/cli/commands.js.map +1 -1
  6. package/dist/src/cli/ink/App.d.ts +40 -0
  7. package/dist/src/cli/ink/App.d.ts.map +1 -0
  8. package/dist/src/cli/ink/App.js +717 -0
  9. package/dist/src/cli/ink/App.js.map +1 -0
  10. package/dist/src/cli/repl.d.ts +4 -0
  11. package/dist/src/cli/repl.d.ts.map +1 -1
  12. package/dist/src/cli/repl.js +59 -532
  13. package/dist/src/cli/repl.js.map +1 -1
  14. package/dist/src/cli/theme.d.ts +1 -1
  15. package/dist/src/cli/theme.d.ts.map +1 -1
  16. package/dist/src/cli/theme.js +2 -2
  17. package/dist/src/cli/theme.js.map +1 -1
  18. package/dist/src/core/types.d.ts +6 -0
  19. package/dist/src/core/types.d.ts.map +1 -1
  20. package/dist/src/llm/model-registry.d.ts +5 -0
  21. package/dist/src/llm/model-registry.d.ts.map +1 -1
  22. package/dist/src/llm/model-registry.js +43 -0
  23. package/dist/src/llm/model-registry.js.map +1 -1
  24. package/dist/src/llm/ollama.d.ts.map +1 -1
  25. package/dist/src/llm/ollama.js +6 -0
  26. package/dist/src/llm/ollama.js.map +1 -1
  27. package/dist/src/session/prompt-builder.d.ts.map +1 -1
  28. package/dist/src/session/prompt-builder.js +9 -0
  29. package/dist/src/session/prompt-builder.js.map +1 -1
  30. package/dist/src/skills/injector.d.ts +19 -0
  31. package/dist/src/skills/injector.d.ts.map +1 -0
  32. package/dist/src/skills/injector.js +67 -0
  33. package/dist/src/skills/injector.js.map +1 -0
  34. package/dist/src/skills/loader.d.ts +31 -0
  35. package/dist/src/skills/loader.d.ts.map +1 -0
  36. package/dist/src/skills/loader.js +147 -0
  37. package/dist/src/skills/loader.js.map +1 -0
  38. 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.2",
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
- "cmdr-agent": "^1.0.1",
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
  },