@stan-chen/simple-cli 0.2.3 → 0.2.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/README.md +62 -63
- package/dist/anyllm.py +62 -0
- package/dist/builtins.d.ts +726 -0
- package/dist/builtins.js +481 -0
- package/dist/cli.d.ts +0 -4
- package/dist/cli.js +34 -493
- package/dist/engine.d.ts +33 -0
- package/dist/engine.js +138 -0
- package/dist/learnings.d.ts +15 -0
- package/dist/learnings.js +54 -0
- package/dist/llm.d.ts +18 -0
- package/dist/llm.js +73 -0
- package/dist/mcp.d.ts +132 -0
- package/dist/mcp.js +43 -0
- package/dist/skills.d.ts +5 -16
- package/dist/skills.js +91 -253
- package/dist/tui.d.ts +1 -0
- package/dist/tui.js +15 -0
- package/package.json +10 -6
- package/dist/claw/jit.d.ts +0 -5
- package/dist/claw/jit.js +0 -138
- package/dist/claw/management.d.ts +0 -3
- package/dist/claw/management.js +0 -107
- package/dist/commands/add.d.ts +0 -9
- package/dist/commands/add.js +0 -50
- package/dist/commands/git/commit.d.ts +0 -12
- package/dist/commands/git/commit.js +0 -98
- package/dist/commands/git/status.d.ts +0 -6
- package/dist/commands/git/status.js +0 -42
- package/dist/commands/index.d.ts +0 -16
- package/dist/commands/index.js +0 -377
- package/dist/commands/mcp/status.d.ts +0 -6
- package/dist/commands/mcp/status.js +0 -31
- package/dist/commands/swarm.d.ts +0 -36
- package/dist/commands/swarm.js +0 -236
- package/dist/commands.d.ts +0 -32
- package/dist/commands.js +0 -427
- package/dist/context.d.ts +0 -116
- package/dist/context.js +0 -337
- package/dist/index.d.ts +0 -6
- package/dist/index.js +0 -109
- package/dist/lib/agent.d.ts +0 -99
- package/dist/lib/agent.js +0 -313
- package/dist/lib/editor.d.ts +0 -74
- package/dist/lib/editor.js +0 -441
- package/dist/lib/git.d.ts +0 -164
- package/dist/lib/git.js +0 -356
- package/dist/lib/shim.d.ts +0 -4
- package/dist/lib/shim.js +0 -30
- package/dist/lib/ui.d.ts +0 -159
- package/dist/lib/ui.js +0 -277
- package/dist/mcp/client.d.ts +0 -22
- package/dist/mcp/client.js +0 -81
- package/dist/mcp/manager.d.ts +0 -186
- package/dist/mcp/manager.js +0 -446
- package/dist/prompts/provider.d.ts +0 -22
- package/dist/prompts/provider.js +0 -79
- package/dist/providers/index.d.ts +0 -31
- package/dist/providers/index.js +0 -93
- package/dist/providers/multi.d.ts +0 -12
- package/dist/providers/multi.js +0 -28
- package/dist/registry.d.ts +0 -29
- package/dist/registry.js +0 -443
- package/dist/repoMap.d.ts +0 -5
- package/dist/repoMap.js +0 -79
- package/dist/router.d.ts +0 -41
- package/dist/router.js +0 -118
- package/dist/swarm/coordinator.d.ts +0 -86
- package/dist/swarm/coordinator.js +0 -257
- package/dist/swarm/index.d.ts +0 -28
- package/dist/swarm/index.js +0 -29
- package/dist/swarm/task.d.ts +0 -104
- package/dist/swarm/task.js +0 -221
- package/dist/swarm/types.d.ts +0 -132
- package/dist/swarm/types.js +0 -37
- package/dist/swarm/worker.d.ts +0 -109
- package/dist/swarm/worker.js +0 -369
- package/dist/tools/analyzeFile.d.ts +0 -16
- package/dist/tools/analyzeFile.js +0 -43
- package/dist/tools/analyze_file.d.ts +0 -16
- package/dist/tools/analyze_file.js +0 -43
- package/dist/tools/clawBrain.d.ts +0 -23
- package/dist/tools/clawBrain.js +0 -136
- package/dist/tools/claw_brain.d.ts +0 -23
- package/dist/tools/claw_brain.js +0 -139
- package/dist/tools/deleteFile.d.ts +0 -19
- package/dist/tools/deleteFile.js +0 -36
- package/dist/tools/delete_file.d.ts +0 -19
- package/dist/tools/delete_file.js +0 -36
- package/dist/tools/fileOps.d.ts +0 -22
- package/dist/tools/fileOps.js +0 -43
- package/dist/tools/file_ops.d.ts +0 -22
- package/dist/tools/file_ops.js +0 -43
- package/dist/tools/git.d.ts +0 -40
- package/dist/tools/git.js +0 -236
- package/dist/tools/glob.d.ts +0 -34
- package/dist/tools/glob.js +0 -165
- package/dist/tools/grep.d.ts +0 -53
- package/dist/tools/grep.js +0 -296
- package/dist/tools/linter.d.ts +0 -35
- package/dist/tools/linter.js +0 -407
- package/dist/tools/listDir.d.ts +0 -29
- package/dist/tools/listDir.js +0 -50
- package/dist/tools/list_dir.d.ts +0 -29
- package/dist/tools/list_dir.js +0 -50
- package/dist/tools/memory.d.ts +0 -34
- package/dist/tools/memory.js +0 -215
- package/dist/tools/organizer.d.ts +0 -1
- package/dist/tools/organizer.js +0 -65
- package/dist/tools/readFiles.d.ts +0 -25
- package/dist/tools/readFiles.js +0 -31
- package/dist/tools/read_files.d.ts +0 -25
- package/dist/tools/read_files.js +0 -31
- package/dist/tools/reloadTools.d.ts +0 -11
- package/dist/tools/reloadTools.js +0 -22
- package/dist/tools/reload_tools.d.ts +0 -11
- package/dist/tools/reload_tools.js +0 -22
- package/dist/tools/runCommand.d.ts +0 -32
- package/dist/tools/runCommand.js +0 -79
- package/dist/tools/run_command.d.ts +0 -32
- package/dist/tools/run_command.js +0 -103
- package/dist/tools/scheduler.d.ts +0 -25
- package/dist/tools/scheduler.js +0 -65
- package/dist/tools/scraper.d.ts +0 -31
- package/dist/tools/scraper.js +0 -211
- package/dist/tools/writeFiles.d.ts +0 -63
- package/dist/tools/writeFiles.js +0 -87
- package/dist/tools/write_files.d.ts +0 -84
- package/dist/tools/write_files.js +0 -91
- package/dist/tools/write_to_file.d.ts +0 -15
- package/dist/tools/write_to_file.js +0 -21
- package/dist/ui/server.d.ts +0 -5
- package/dist/ui/server.js +0 -74
- package/dist/watcher.d.ts +0 -35
- package/dist/watcher.js +0 -164
- /package/{docs/assets → assets}/logo.jpeg +0 -0
package/dist/skills.js
CHANGED
|
@@ -1,229 +1,87 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
* Based on OpenHands skills and Aider prompts
|
|
4
|
-
* Provides specialized behavior presets for different tasks
|
|
5
|
-
*/
|
|
6
|
-
import { readFile, writeFile, readdir } from 'fs/promises';
|
|
1
|
+
import { readFile, readdir, writeFile } from 'fs/promises';
|
|
2
|
+
import { join, basename, extname } from 'path';
|
|
7
3
|
import { existsSync } from 'fs';
|
|
8
|
-
import { join } from 'path';
|
|
9
|
-
// Built-in skills
|
|
10
4
|
export const builtinSkills = {
|
|
11
|
-
// Code editing skill (default)
|
|
12
5
|
code: {
|
|
13
6
|
name: 'code',
|
|
14
|
-
description: '
|
|
15
|
-
systemPrompt: `You are a coding assistant.
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
## Command
|
|
36
|
-
python scripts/tool.py
|
|
37
|
-
\`\`\`
|
|
38
|
-
Inputs are passed via **stdin** (JSON) and the \`TOOL_INPUT\` env var.
|
|
39
|
-
After creating/modifying, call \`reloadTools\`.
|
|
40
|
-
|
|
41
|
-
4. **Self-Orchestration**: If a project lacks clear success criteria (missing \`.agent/\` or \`.simple/\` directories), you should take the initiative to create them. Use these folders to store implementation plans, SPEC/PRDs, and validation tests.
|
|
42
|
-
|
|
43
|
-
When making changes to files:
|
|
44
|
-
1. Read the file first to understand the context
|
|
45
|
-
2. Make precise, targeted changes using search/replace
|
|
46
|
-
3. Verify changes don't break existing functionality
|
|
47
|
-
4. Follow the existing code style`,
|
|
48
|
-
tools: ['read_files', 'write_files', 'run_command', 'glob', 'grep', 'lint', 'reload_tools', 'scheduler'],
|
|
49
|
-
},
|
|
50
|
-
// Architect skill for planning
|
|
51
|
-
architect: {
|
|
52
|
-
name: 'architect',
|
|
53
|
-
description: 'Design and planning mode - focuses on architecture decisions',
|
|
54
|
-
systemPrompt: `You are a software architect assistant. Your role is to:
|
|
55
|
-
|
|
56
|
-
1. Help design system architecture
|
|
57
|
-
2. Make technology decisions
|
|
58
|
-
3. Plan implementation strategies
|
|
59
|
-
4. Review and improve existing designs
|
|
60
|
-
|
|
61
|
-
When working on architecture:
|
|
62
|
-
- Ask clarifying questions about requirements
|
|
63
|
-
- Consider scalability, maintainability, and security
|
|
64
|
-
- Provide multiple options when appropriate
|
|
65
|
-
- Document decisions and trade-offs
|
|
66
|
-
|
|
67
|
-
Focus on high-level design rather than implementation details.
|
|
68
|
-
Generate diagrams and documentation when helpful.`,
|
|
69
|
-
tools: ['read_files', 'glob', 'grep', 'memory'],
|
|
70
|
-
modelPreference: 'orchestrator',
|
|
71
|
-
},
|
|
72
|
-
// Ask skill for questions only
|
|
73
|
-
ask: {
|
|
74
|
-
name: 'ask',
|
|
75
|
-
description: 'Question-answering mode - no file modifications',
|
|
76
|
-
systemPrompt: `You are a helpful coding assistant in read-only mode.
|
|
77
|
-
|
|
78
|
-
You can:
|
|
79
|
-
- Answer questions about the codebase
|
|
80
|
-
- Explain how code works
|
|
81
|
-
- Suggest improvements
|
|
82
|
-
- Help with debugging
|
|
83
|
-
|
|
84
|
-
You should NOT:
|
|
85
|
-
- Modify any files
|
|
86
|
-
- Run commands that change state
|
|
87
|
-
- Create new files
|
|
88
|
-
|
|
89
|
-
Always read files before answering questions about them.`,
|
|
90
|
-
tools: ['read_files', 'glob', 'grep'],
|
|
91
|
-
},
|
|
92
|
-
// Help/docs skill
|
|
93
|
-
help: {
|
|
94
|
-
name: 'help',
|
|
95
|
-
description: 'Help and documentation assistant',
|
|
96
|
-
systemPrompt: `You are a documentation assistant. Help users understand:
|
|
97
|
-
|
|
98
|
-
- How to use this CLI tool
|
|
99
|
-
- Programming concepts and patterns
|
|
100
|
-
- Best practices and conventions
|
|
101
|
-
- Error messages and debugging
|
|
102
|
-
|
|
103
|
-
Be concise and provide examples when helpful.
|
|
104
|
-
Reference official documentation when available.`,
|
|
105
|
-
tools: ['read_files', 'scrape_url'],
|
|
106
|
-
},
|
|
107
|
-
// Test skill
|
|
108
|
-
test: {
|
|
109
|
-
name: 'test',
|
|
110
|
-
description: 'Test writing and debugging assistant',
|
|
111
|
-
systemPrompt: `You are a test engineering assistant. Your focus is:
|
|
112
|
-
|
|
113
|
-
1. Writing comprehensive tests
|
|
114
|
-
2. Debugging failing tests
|
|
115
|
-
3. Improving test coverage
|
|
116
|
-
4. Setting up test infrastructure
|
|
117
|
-
|
|
118
|
-
Test guidelines:
|
|
119
|
-
- Follow the project's existing test patterns
|
|
120
|
-
- Cover edge cases and error conditions
|
|
121
|
-
- Write clear test descriptions
|
|
122
|
-
- Use appropriate mocking when needed
|
|
123
|
-
|
|
124
|
-
After writing tests, run them to verify they pass.`,
|
|
125
|
-
tools: ['read_files', 'write_files', 'run_command', 'glob', 'grep', 'lint', 'scheduler'],
|
|
126
|
-
},
|
|
127
|
-
// Debug skill
|
|
128
|
-
debug: {
|
|
129
|
-
name: 'debug',
|
|
130
|
-
description: 'Debugging assistant for troubleshooting issues',
|
|
131
|
-
systemPrompt: `You are a debugging assistant. Your process:
|
|
132
|
-
|
|
133
|
-
1. Understand the error or unexpected behavior
|
|
134
|
-
2. Reproduce the issue if possible
|
|
135
|
-
3. Analyze logs, stack traces, and code
|
|
136
|
-
4. Form hypotheses about the cause
|
|
137
|
-
5. Test fixes incrementally
|
|
138
|
-
|
|
139
|
-
Debugging tips:
|
|
140
|
-
- Add logging to understand program flow
|
|
141
|
-
- Check recent changes that might have caused the issue
|
|
142
|
-
- Look for common patterns (null checks, async issues, etc.)
|
|
143
|
-
- Use the linter to catch syntax errors`,
|
|
144
|
-
tools: ['read_files', 'write_files', 'run_command', 'grep', 'lint', 'git', 'scheduler'],
|
|
145
|
-
},
|
|
146
|
-
// Refactor skill
|
|
147
|
-
refactor: {
|
|
148
|
-
name: 'refactor',
|
|
149
|
-
description: 'Code refactoring with safety focus',
|
|
150
|
-
systemPrompt: `You are a refactoring assistant. Your approach:
|
|
151
|
-
|
|
152
|
-
1. Understand the current implementation
|
|
153
|
-
2. Identify areas for improvement
|
|
154
|
-
3. Make incremental, safe changes
|
|
155
|
-
4. Verify behavior is preserved
|
|
156
|
-
|
|
157
|
-
Refactoring principles:
|
|
158
|
-
- Small, focused changes
|
|
159
|
-
- Maintain existing tests
|
|
160
|
-
- Improve readability and maintainability
|
|
161
|
-
- Reduce duplication
|
|
162
|
-
- Follow SOLID principles
|
|
163
|
-
|
|
164
|
-
Always run tests after refactoring to ensure nothing broke.`,
|
|
165
|
-
tools: ['read_files', 'write_files', 'run_command', 'glob', 'grep', 'lint', 'git', 'scheduler'],
|
|
166
|
-
},
|
|
167
|
-
// Review skill
|
|
168
|
-
review: {
|
|
169
|
-
name: 'review',
|
|
170
|
-
description: 'Code review assistant',
|
|
171
|
-
systemPrompt: `You are a code reviewer. Review code for:
|
|
172
|
-
|
|
173
|
-
1. Correctness - Does it work as intended?
|
|
174
|
-
2. Security - Are there vulnerabilities?
|
|
175
|
-
3. Performance - Are there inefficiencies?
|
|
176
|
-
4. Style - Does it follow conventions?
|
|
177
|
-
5. Maintainability - Is it easy to understand?
|
|
178
|
-
|
|
179
|
-
Provide constructive feedback with specific suggestions.
|
|
180
|
-
Prioritize critical issues over minor style concerns.`,
|
|
181
|
-
tools: ['read_files', 'glob', 'grep', 'git', 'lint'],
|
|
182
|
-
},
|
|
183
|
-
// Shell skill
|
|
184
|
-
shell: {
|
|
185
|
-
name: 'shell',
|
|
186
|
-
description: 'Shell/command-line assistant',
|
|
187
|
-
systemPrompt: `You are a shell/command-line assistant. Help with:
|
|
188
|
-
|
|
189
|
-
- Writing shell scripts
|
|
190
|
-
- Running and debugging commands
|
|
191
|
-
- System administration tasks
|
|
192
|
-
- Build and deployment scripts
|
|
193
|
-
|
|
194
|
-
Safety guidelines:
|
|
195
|
-
- Explain what commands do before running
|
|
196
|
-
- Use safe defaults (no force flags unless needed)
|
|
197
|
-
- Be careful with destructive operations
|
|
198
|
-
- Test commands before applying to production`,
|
|
199
|
-
tools: ['run_command', 'read_files', 'write_files', 'glob'],
|
|
200
|
-
},
|
|
201
|
-
// Git skill
|
|
202
|
-
git: {
|
|
203
|
-
name: 'git',
|
|
204
|
-
description: 'Git version control assistant',
|
|
205
|
-
systemPrompt: `You are a Git assistant. Help with:
|
|
206
|
-
|
|
207
|
-
- Understanding git history and changes
|
|
208
|
-
- Creating meaningful commits
|
|
209
|
-
- Managing branches
|
|
210
|
-
- Resolving merge conflicts
|
|
211
|
-
- Best practices for version control
|
|
212
|
-
|
|
213
|
-
Git guidelines:
|
|
214
|
-
- Write clear, descriptive commit messages
|
|
215
|
-
- Make small, focused commits
|
|
216
|
-
- Keep branches up to date
|
|
217
|
-
- Review changes before committing`,
|
|
218
|
-
tools: ['git', 'read_files', 'glob', 'grep'],
|
|
219
|
-
},
|
|
7
|
+
description: 'A helpful coding assistant.',
|
|
8
|
+
systemPrompt: `You are a helpful coding assistant. Use tools to solve tasks.
|
|
9
|
+
You must output your response in JSON format.
|
|
10
|
+
The JSON should have the following structure:
|
|
11
|
+
{
|
|
12
|
+
"thought": "Your reasoning here",
|
|
13
|
+
"tool": "tool_name",
|
|
14
|
+
"args": { "arg_name": "value" }
|
|
15
|
+
}
|
|
16
|
+
If you don't need to use a tool, use "tool": "none" and provide a "message".
|
|
17
|
+
{
|
|
18
|
+
"thought": "Reasoning",
|
|
19
|
+
"tool": "none",
|
|
20
|
+
"message": "Response to user"
|
|
21
|
+
}
|
|
22
|
+
Important:
|
|
23
|
+
- If a task requires multiple steps, perform them one by one.
|
|
24
|
+
- Do not ask for confirmation if you have enough information to proceed.
|
|
25
|
+
- When writing to files that might exist (like logs), read them first and append to them if necessary, unless instructed to overwrite.
|
|
26
|
+
`
|
|
27
|
+
}
|
|
220
28
|
};
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
29
|
+
export async function loadSkillFromFile(path) {
|
|
30
|
+
if (!existsSync(path))
|
|
31
|
+
return null;
|
|
32
|
+
try {
|
|
33
|
+
const content = await readFile(path, 'utf-8');
|
|
34
|
+
const ext = extname(path).toLowerCase();
|
|
35
|
+
if (ext === '.json') {
|
|
36
|
+
const skill = JSON.parse(content);
|
|
37
|
+
if (!skill.name || !skill.systemPrompt)
|
|
38
|
+
return null;
|
|
39
|
+
return skill;
|
|
40
|
+
}
|
|
41
|
+
else if (ext === '.md') {
|
|
42
|
+
// Parse markdown:
|
|
43
|
+
// Title (# Title) -> Name
|
|
44
|
+
// Content -> System Prompt
|
|
45
|
+
let name = basename(path, '.md');
|
|
46
|
+
const titleMatch = content.match(/^#\s+(.+)$/m);
|
|
47
|
+
if (titleMatch) {
|
|
48
|
+
name = titleMatch[1].trim();
|
|
49
|
+
}
|
|
50
|
+
return {
|
|
51
|
+
name,
|
|
52
|
+
description: `Loaded from ${basename(path)}`,
|
|
53
|
+
systemPrompt: content
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
catch (e) {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
export async function getActiveSkill(cwd = process.cwd()) {
|
|
63
|
+
// 1. Env var
|
|
64
|
+
if (process.env.SIMPLE_CLI_SKILL) {
|
|
65
|
+
if (builtinSkills[process.env.SIMPLE_CLI_SKILL]) {
|
|
66
|
+
return builtinSkills[process.env.SIMPLE_CLI_SKILL];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
// 2. Project config (.agent/AGENT.md or .agent/SOUL.md)
|
|
70
|
+
const agentMd = join(cwd, '.agent', 'AGENT.md');
|
|
71
|
+
if (existsSync(agentMd)) {
|
|
72
|
+
const skill = await loadSkillFromFile(agentMd);
|
|
73
|
+
if (skill)
|
|
74
|
+
return skill;
|
|
75
|
+
}
|
|
76
|
+
const soulMd = join(cwd, '.agent', 'SOUL.md');
|
|
77
|
+
if (existsSync(soulMd)) {
|
|
78
|
+
const skill = await loadSkillFromFile(soulMd);
|
|
79
|
+
if (skill)
|
|
80
|
+
return skill;
|
|
81
|
+
}
|
|
82
|
+
// 3. Default
|
|
83
|
+
return builtinSkills.code;
|
|
225
84
|
}
|
|
226
|
-
// Set active skill
|
|
227
85
|
export function setActiveSkill(name) {
|
|
228
86
|
if (builtinSkills[name]) {
|
|
229
87
|
process.env.SIMPLE_CLI_SKILL = name;
|
|
@@ -231,58 +89,38 @@ export function setActiveSkill(name) {
|
|
|
231
89
|
}
|
|
232
90
|
return undefined;
|
|
233
91
|
}
|
|
234
|
-
// List available skills
|
|
235
92
|
export function listSkills() {
|
|
236
93
|
return Object.values(builtinSkills);
|
|
237
94
|
}
|
|
238
|
-
// Load custom skill from file
|
|
239
|
-
export async function loadSkillFromFile(path) {
|
|
240
|
-
try {
|
|
241
|
-
const content = await readFile(path, 'utf-8');
|
|
242
|
-
const skill = JSON.parse(content);
|
|
243
|
-
if (!skill.name || !skill.systemPrompt) {
|
|
244
|
-
return null;
|
|
245
|
-
}
|
|
246
|
-
return skill;
|
|
247
|
-
}
|
|
248
|
-
catch {
|
|
249
|
-
return null;
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
// Save custom skill to file
|
|
253
|
-
export async function saveSkillToFile(skill, path) {
|
|
254
|
-
await writeFile(path, JSON.stringify(skill, null, 2));
|
|
255
|
-
}
|
|
256
|
-
// Load all custom skills from a directory
|
|
257
95
|
export async function loadCustomSkills(dir) {
|
|
258
96
|
const skills = {};
|
|
259
|
-
if (!existsSync(dir))
|
|
97
|
+
if (!existsSync(dir))
|
|
260
98
|
return skills;
|
|
261
|
-
}
|
|
262
99
|
try {
|
|
263
|
-
const
|
|
264
|
-
for (const
|
|
265
|
-
if (
|
|
266
|
-
const
|
|
100
|
+
const entries = await readdir(dir, { withFileTypes: true });
|
|
101
|
+
for (const entry of entries) {
|
|
102
|
+
if (entry.isFile()) {
|
|
103
|
+
const path = join(dir, entry.name);
|
|
104
|
+
const skill = await loadSkillFromFile(path);
|
|
267
105
|
if (skill) {
|
|
268
106
|
skills[skill.name] = skill;
|
|
269
107
|
}
|
|
270
108
|
}
|
|
271
109
|
}
|
|
272
110
|
}
|
|
273
|
-
catch {
|
|
274
|
-
// Ignore errors
|
|
275
|
-
}
|
|
111
|
+
catch { }
|
|
276
112
|
return skills;
|
|
277
113
|
}
|
|
278
|
-
// Get skill system prompt with context
|
|
279
114
|
export function buildSkillPrompt(skill, context) {
|
|
280
115
|
let prompt = skill.systemPrompt;
|
|
281
|
-
if (context?.files?.length) {
|
|
282
|
-
prompt += `\n\n## Active Files\nYou are working with these files:\n${context.files.join('\n')}`;
|
|
283
|
-
}
|
|
284
116
|
if (context?.repoMap) {
|
|
285
117
|
prompt += `\n\n## Repository Structure\n${context.repoMap}`;
|
|
286
118
|
}
|
|
119
|
+
if (context?.files && context.files.length > 0) {
|
|
120
|
+
prompt += `\n\n## Active Files\n${context.files.join('\n')}`;
|
|
121
|
+
}
|
|
287
122
|
return prompt;
|
|
288
123
|
}
|
|
124
|
+
export async function saveSkillToFile(skill, path) {
|
|
125
|
+
await writeFile(path, JSON.stringify(skill, null, 2));
|
|
126
|
+
}
|
package/dist/tui.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function showBanner(): void;
|
package/dist/tui.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import pc from 'picocolors';
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import { join, dirname } from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
const pkg = JSON.parse(fs.readFileSync(join(__dirname, '../package.json'), 'utf8'));
|
|
7
|
+
export function showBanner() {
|
|
8
|
+
const cat = `
|
|
9
|
+
/\\_/\\
|
|
10
|
+
( o.o )
|
|
11
|
+
> ^ <
|
|
12
|
+
`;
|
|
13
|
+
console.log(pc.magenta(cat));
|
|
14
|
+
console.log(` ${pc.bgMagenta(pc.black(' SIMPLE-CLI '))} ${pc.dim(`v${pkg.version}`)}\n`);
|
|
15
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stan-chen/simple-cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.5",
|
|
4
4
|
"description": "A lean, lightweight coding agent. Packs a punch with token efficiency.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/cli.js",
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
},
|
|
10
10
|
"scripts": {
|
|
11
11
|
"start": "node --loader ts-node/esm src/cli.ts",
|
|
12
|
-
"dev": "node --loader ts-node/esm --watch src/
|
|
13
|
-
"build": "tsc",
|
|
12
|
+
"dev": "node --loader ts-node/esm --watch src/cli.ts",
|
|
13
|
+
"build": "tsc && node -e \"require('fs').copyFileSync('src/anyllm.py', 'dist/anyllm.py')\"",
|
|
14
14
|
"typecheck": "tsc --noEmit",
|
|
15
15
|
"test": "vitest run",
|
|
16
16
|
"test:watch": "vitest",
|
|
@@ -42,13 +42,17 @@
|
|
|
42
42
|
"@clack/prompts": "^0.7.0",
|
|
43
43
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
44
44
|
"@oclif/core": "^4.0.0",
|
|
45
|
-
"@
|
|
45
|
+
"@types/cors": "^2.8.19",
|
|
46
|
+
"@types/express": "^5.0.6",
|
|
46
47
|
"@types/node-fetch": "^2.6.13",
|
|
47
48
|
"ai": "^6.0.67",
|
|
49
|
+
"body-parser": "^1.20.4",
|
|
48
50
|
"chalk": "^5.3.0",
|
|
49
51
|
"chokidar": "^5.0.0",
|
|
52
|
+
"cors": "^2.8.6",
|
|
50
53
|
"diff": "^5.2.0",
|
|
51
54
|
"dotenv": "^16.4.7",
|
|
55
|
+
"express": "^4.22.1",
|
|
52
56
|
"fast-glob": "^3.3.2",
|
|
53
57
|
"fast-levenshtein": "^3.0.0",
|
|
54
58
|
"glob": "^13.0.0",
|
|
@@ -79,6 +83,6 @@
|
|
|
79
83
|
"files": [
|
|
80
84
|
"dist",
|
|
81
85
|
"README.md",
|
|
82
|
-
"
|
|
86
|
+
"assets/logo.jpeg"
|
|
83
87
|
]
|
|
84
|
-
}
|
|
88
|
+
}
|
package/dist/claw/jit.d.ts
DELETED
package/dist/claw/jit.js
DELETED
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
|
-
import pc from 'picocolors';
|
|
4
|
-
import { createProvider } from '../providers/index.js';
|
|
5
|
-
import { runDeterministicOrganizer } from '../tools/organizer.js';
|
|
6
|
-
/**
|
|
7
|
-
* JIT Agent Generation: Task-specific personas
|
|
8
|
-
* Reuse the central provider system - don't reinvent the wheel!
|
|
9
|
-
*/
|
|
10
|
-
export async function generateJitAgent(intent, targetDir) {
|
|
11
|
-
const memoryDir = path.join(targetDir, '.simple', 'workdir', 'memory');
|
|
12
|
-
const agentFile = path.join(targetDir, '.simple', 'workdir', 'AGENT.md');
|
|
13
|
-
// Ensure state directories exist
|
|
14
|
-
if (!fs.existsSync(memoryDir)) {
|
|
15
|
-
fs.mkdirSync(path.join(memoryDir, 'notes'), { recursive: true });
|
|
16
|
-
fs.mkdirSync(path.join(memoryDir, 'logs'), { recursive: true });
|
|
17
|
-
fs.mkdirSync(path.join(memoryDir, 'reflections'), { recursive: true });
|
|
18
|
-
fs.mkdirSync(path.join(memoryDir, 'graph'), { recursive: true });
|
|
19
|
-
}
|
|
20
|
-
// Load recent memory context if available
|
|
21
|
-
const reflectionsDir = path.join(memoryDir, 'reflections');
|
|
22
|
-
let memoryContext = '';
|
|
23
|
-
try {
|
|
24
|
-
if (fs.existsSync(reflectionsDir)) {
|
|
25
|
-
const files = fs.readdirSync(reflectionsDir)
|
|
26
|
-
.filter(f => f.endsWith('.md'))
|
|
27
|
-
.sort()
|
|
28
|
-
.reverse()
|
|
29
|
-
.slice(0, 3);
|
|
30
|
-
for (const f of files) {
|
|
31
|
-
const content = fs.readFileSync(path.join(reflectionsDir, f), 'utf-8');
|
|
32
|
-
memoryContext += `\n--- Previous Reflection (${f}) ---\n${content}\n`;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
catch (e) { /* ignore */ }
|
|
37
|
-
try {
|
|
38
|
-
const provider = createProvider();
|
|
39
|
-
const prompt = `You are the architect of a high-performance agent swarm.
|
|
40
|
-
Your task: Create a MISSION_DIRECTIVE (AGENT.md) for a specialized autonomous sub-agent.
|
|
41
|
-
|
|
42
|
-
WORKSPACE_PATH: "${targetDir}"
|
|
43
|
-
INTENT: "${intent}"
|
|
44
|
-
|
|
45
|
-
${memoryContext ? `## HISTORICAL MISSION LOGS:\n${memoryContext}\nCRITICAL: If the intent denotes a recurring or state-dependent task, ignore past completion tokens. Re-verify the current filesystem state immediately.` : ''}
|
|
46
|
-
|
|
47
|
-
## DIRECTIVE PREREQUISITES:
|
|
48
|
-
1. THE AGENT IS THE TOOL. You are not writing a guide for a human. You are writing the internal operating logic for an AI.
|
|
49
|
-
2. CURRENT DIRECTORY FOCUS. The sub-agent is ALREADY in the WORKSPACE_PATH. It MUST ALWAYS use relative paths starting with '.' or filenames.
|
|
50
|
-
3. NO OUTSIDE PATHS. Explicitly FORBID searching or moving files outside WORKSPACE_PATH. Do not look for "C:\Users\..." or "/Users/...".
|
|
51
|
-
4. IMMEDIATE ACTION IS MANDATORY. The first thing the agent does upon activation is use list_dir(".") to see what is actually in the current folder.
|
|
52
|
-
5. NO CONVERSATIONAL FILLER. The sub-agent must communicate ONLY via JSON tool calls and internal thoughts.
|
|
53
|
-
6. CONDITIONAL LOGIC MASTERY. If the intent has "If" or "When" clauses (e.g., logging receipts before moving), the agent MUST prioritize the multi-step sequence (Read -> Process -> Move).
|
|
54
|
-
7. MISSION OBJECTIVE: Fulfill the intent in as few steps as possible.
|
|
55
|
-
|
|
56
|
-
## OUTPUT FORMAT (AGENT.md):
|
|
57
|
-
- # [Agent Persona Name]
|
|
58
|
-
- ## 🎯 Objective: Concise mission statement.
|
|
59
|
-
- ## 🛠️ Execution Strategy: Step-by-step plan using list_dir, move_file, write_to_file, scheduler, etc. ALWAYS start with list_dir("."). Address multi-step sequences explicitly.
|
|
60
|
-
- ## ⚠️ Constraints: Critical failure conditions (e.g., "Do not delete .env files"). FORBID absolute paths.
|
|
61
|
-
|
|
62
|
-
IMPORTANT: DO NOT include code blocks, pseudo-code, or markdown examples in the AGENT.md. The agent already knows the tool syntax. Only describe the logic.`;
|
|
63
|
-
console.log(pc.dim(' Refining agent directive via LLM...'));
|
|
64
|
-
const timeoutPromise = new Promise((_, reject) => setTimeout(() => reject(new Error('LLM Directive Timeout')), 25000));
|
|
65
|
-
const responsePromise = provider.generateResponse('You are a technical system logic designer. You respond ONLY with structured directive text.', [
|
|
66
|
-
{ role: 'user', content: prompt }
|
|
67
|
-
]);
|
|
68
|
-
const response = await Promise.race([responsePromise, timeoutPromise]);
|
|
69
|
-
const res = response;
|
|
70
|
-
console.log(pc.dim(' Directive received. Applying stressors filtration.'));
|
|
71
|
-
let content;
|
|
72
|
-
if (!res || (res.message?.includes('Error') && !res.thought)) {
|
|
73
|
-
console.warn(pc.yellow('⚠️ LLM directive failed. Seeding mission with hardened fallback template.'));
|
|
74
|
-
content = fallbackTemplate(intent);
|
|
75
|
-
}
|
|
76
|
-
else {
|
|
77
|
-
// Robust content extraction
|
|
78
|
-
let raw = res.message || res.thought || res.raw || '';
|
|
79
|
-
// 1. Strip all conversational prefix/suffix
|
|
80
|
-
const lines = raw.split('\n');
|
|
81
|
-
const startIndex = lines.findIndex((l) => l.startsWith('#'));
|
|
82
|
-
if (startIndex !== -1) {
|
|
83
|
-
raw = lines.slice(startIndex).join('\n');
|
|
84
|
-
}
|
|
85
|
-
// 2. Filtration: Remove all code blocks (stressor: model tries to show examples)
|
|
86
|
-
raw = raw.replace(/```[\s\S]*?```/g, '');
|
|
87
|
-
// 3. Logical Termination: Model often adds "Next steps" or "Hope this helps"
|
|
88
|
-
const segments = raw.split(/## (IMMEDIATE ACTION|NEXT STEPS|CONCLUSION|SUMMARY|APPENDIX|EXAMPLES)/i);
|
|
89
|
-
const processed = segments[0].trim();
|
|
90
|
-
content = processed || fallbackTemplate(intent);
|
|
91
|
-
}
|
|
92
|
-
const workdir = path.dirname(agentFile);
|
|
93
|
-
if (!fs.existsSync(workdir))
|
|
94
|
-
fs.mkdirSync(workdir, { recursive: true });
|
|
95
|
-
fs.writeFileSync(agentFile, content);
|
|
96
|
-
console.log(pc.green(`✅ Autonomous Directive Active: ${path.relative(targetDir, agentFile)}`));
|
|
97
|
-
// Registry & Memory Logging
|
|
98
|
-
const logId = Date.now();
|
|
99
|
-
const logFile = path.join(memoryDir, 'logs', `jit-${logId}.log`);
|
|
100
|
-
fs.writeFileSync(logFile, `[DIRECTIVE_GENERATED] Intent: ${intent}\nTimestamp: ${new Date().toISOString()}\nActionable: Detecting...\n`);
|
|
101
|
-
// Heuristic Actionability Check
|
|
102
|
-
const actionablePatterns = [/list_dir/i, /move_file/i, /scheduler/i, /write_to_file/i, /analyze_file/i, /"tool"/i];
|
|
103
|
-
const isActionable = actionablePatterns.some(p => p.test(content) || p.test(res?.raw || ''));
|
|
104
|
-
fs.appendFileSync(logFile, `Result: ${isActionable ? 'ACTIONABLE' : 'TEXT_ONLY'}\n`);
|
|
105
|
-
const inStrictEnv = process.env.VITEST === 'true' || process.env.CI === 'true' || targetDir.includes('demo');
|
|
106
|
-
if (!isActionable && inStrictEnv) {
|
|
107
|
-
console.log(pc.yellow('⚠️ Directive lacks actionable markers. Injecting deterministic mission override.'));
|
|
108
|
-
runDeterministicOrganizer(targetDir);
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
catch (error) {
|
|
112
|
-
console.error(pc.red('Hardened JIT Generator caught critical exception:'), error);
|
|
113
|
-
fs.writeFileSync(agentFile, fallbackTemplate(intent));
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
function fallbackTemplate(intent) {
|
|
117
|
-
return [
|
|
118
|
-
'# 🤖 HARIDIAN-X AUTONOMOUS AGENT',
|
|
119
|
-
'',
|
|
120
|
-
'## 🎯 Objective',
|
|
121
|
-
`Execute the following mission with zero human oversight: "${intent}"`,
|
|
122
|
-
'',
|
|
123
|
-
'## 🛠️ Execution Strategy',
|
|
124
|
-
'1. **RECONNAISSANCE**: Call list_dir(".") immediately to explore the folder contents. NEVER use absolute paths.',
|
|
125
|
-
'2. **ANALYSIS**: For every file found in the CURRENT folder, call analyze_file to understand structure and content.',
|
|
126
|
-
'3. **OPERATION**: Execute the intent using move_file, write_to_file, or run_command. Use RELATIVE paths.',
|
|
127
|
-
'4. **PERSISTENCE**: If the intent describes a recurring need, call scheduler immediately.',
|
|
128
|
-
'5. **VALIDATION**: Re-verify the filesystem state after every destructive action.',
|
|
129
|
-
'',
|
|
130
|
-
'## ⚠️ Constraints',
|
|
131
|
-
'- DO NOT search for files outside the current directory.',
|
|
132
|
-
'- DO NOT use absolute paths starting with C:\\ or /.',
|
|
133
|
-
'- DO NOT reply with conversational text or advice.',
|
|
134
|
-
'- DO NOT create tutorial files or examples.',
|
|
135
|
-
'- ALL output must be exactly one JSON object containing "thought", "tool", and "args".',
|
|
136
|
-
''
|
|
137
|
-
].join('\n');
|
|
138
|
-
}
|