claude-flow-novice 1.5.20 → 1.5.22
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/.claude/agents/CLAUDE.md +186 -2386
- package/.claude/agents/agent-principles/agent-type-guidelines.md +328 -0
- package/.claude/agents/agent-principles/format-selection.md +204 -0
- package/.claude/agents/agent-principles/prompt-engineering.md +371 -0
- package/.claude/agents/agent-principles/quality-metrics.md +294 -0
- package/.claude/agents/frontend/README.md +640 -0
- package/.claude/agents/frontend/interaction-tester.md +879 -0
- package/.claude/agents/frontend/react-frontend-engineer.md +130 -0
- package/.claude/agents/frontend/state-architect.md +250 -0
- package/.claude/agents/frontend/ui-designer.md +325 -0
- package/.claude/agents/researcher.md +1 -1
- package/.claude/agents/swarm/test-coordinator.md +383 -0
- package/.claude/agents/task-coordinator.md +126 -0
- package/.claude/settings.json +7 -7
- package/.claude-flow-novice/dist/src/hooks/enhanced-hooks-cli.js +168 -167
- package/.claude-flow-novice/dist/src/providers/tiered-router.js +118 -0
- package/.claude-flow-novice/dist/src/providers/tiered-router.js.map +1 -0
- package/.claude-flow-novice/dist/src/providers/types.js.map +1 -1
- package/.claude-flow-novice/dist/src/providers/zai-provider.js +268 -0
- package/.claude-flow-novice/dist/src/providers/zai-provider.js.map +1 -0
- package/package.json +1 -1
- package/src/cli/simple-commands/init/templates/CLAUDE.md +25 -0
- package/src/hooks/enhanced-hooks-cli.js +23 -3
- package/src/hooks/enhanced-post-edit-pipeline.js +154 -75
- /package/.claude/agents/{CLAUDE_AGENT_DESIGN_PRINCIPLES.md → agent-principles/CLAUDE_AGENT_DESIGN_PRINCIPLES.md} +0 -0
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Z.ai Provider Implementation (Tier 3)
|
|
3
|
+
* Minimal implementation for testing Z.ai API integration
|
|
4
|
+
*/ import { BaseProvider } from './base-provider.js';
|
|
5
|
+
import { LLMProviderError } from './types.js';
|
|
6
|
+
export class ZaiProvider extends BaseProvider {
|
|
7
|
+
name = 'zai';
|
|
8
|
+
capabilities = {
|
|
9
|
+
supportedModels: [
|
|
10
|
+
'claude-3-5-sonnet-20241022'
|
|
11
|
+
],
|
|
12
|
+
maxContextLength: {
|
|
13
|
+
'claude-3-5-sonnet-20241022': 200000
|
|
14
|
+
},
|
|
15
|
+
maxOutputTokens: {
|
|
16
|
+
'claude-3-5-sonnet-20241022': 8192
|
|
17
|
+
},
|
|
18
|
+
supportsStreaming: true,
|
|
19
|
+
supportsFunctionCalling: false,
|
|
20
|
+
supportsSystemMessages: true,
|
|
21
|
+
supportsVision: true,
|
|
22
|
+
supportsAudio: false,
|
|
23
|
+
supportsTools: false,
|
|
24
|
+
supportsFineTuning: false,
|
|
25
|
+
supportsEmbeddings: false,
|
|
26
|
+
supportsLogprobs: false,
|
|
27
|
+
supportsBatching: false,
|
|
28
|
+
pricing: {
|
|
29
|
+
'claude-3-5-sonnet-20241022': {
|
|
30
|
+
promptCostPer1k: 0.003,
|
|
31
|
+
completionCostPer1k: 0.015,
|
|
32
|
+
currency: 'USD'
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
};
|
|
36
|
+
apiKey;
|
|
37
|
+
baseURL = 'https://api.z.ai/v1';
|
|
38
|
+
async doInitialize() {
|
|
39
|
+
// Validate API key
|
|
40
|
+
if (!this.config.apiKey) {
|
|
41
|
+
throw new Error('Z.ai API key is required. Set Z_AI_API_KEY in .env');
|
|
42
|
+
}
|
|
43
|
+
this.apiKey = this.config.apiKey;
|
|
44
|
+
this.logger.info('Z.ai provider initialized', {
|
|
45
|
+
model: this.config.model,
|
|
46
|
+
baseURL: this.baseURL
|
|
47
|
+
});
|
|
48
|
+
}
|
|
49
|
+
async doComplete(request) {
|
|
50
|
+
const model = request.model || this.config.model;
|
|
51
|
+
// Build request payload
|
|
52
|
+
const payload = {
|
|
53
|
+
model,
|
|
54
|
+
messages: request.messages.filter((msg)=>msg.role !== 'function').map((msg)=>({
|
|
55
|
+
role: msg.role,
|
|
56
|
+
content: msg.content
|
|
57
|
+
})),
|
|
58
|
+
temperature: request.temperature ?? this.config.temperature,
|
|
59
|
+
max_tokens: request.maxTokens ?? this.config.maxTokens,
|
|
60
|
+
stream: false
|
|
61
|
+
};
|
|
62
|
+
// Call Z.ai API
|
|
63
|
+
const response = await this.callZaiAPI('/chat/completions', payload);
|
|
64
|
+
// Calculate cost
|
|
65
|
+
const pricing = this.capabilities.pricing[model];
|
|
66
|
+
const promptCost = response.usage.prompt_tokens / 1000 * pricing.promptCostPer1k;
|
|
67
|
+
const completionCost = response.usage.completion_tokens / 1000 * pricing.completionCostPer1k;
|
|
68
|
+
// Convert to unified response format
|
|
69
|
+
return {
|
|
70
|
+
id: response.id,
|
|
71
|
+
model,
|
|
72
|
+
provider: 'zai',
|
|
73
|
+
content: response.choices[0].message.content,
|
|
74
|
+
usage: {
|
|
75
|
+
promptTokens: response.usage.prompt_tokens,
|
|
76
|
+
completionTokens: response.usage.completion_tokens,
|
|
77
|
+
totalTokens: response.usage.total_tokens
|
|
78
|
+
},
|
|
79
|
+
cost: {
|
|
80
|
+
promptCost,
|
|
81
|
+
completionCost,
|
|
82
|
+
totalCost: promptCost + completionCost,
|
|
83
|
+
currency: 'USD'
|
|
84
|
+
},
|
|
85
|
+
finishReason: response.choices[0].finish_reason === 'stop' ? 'stop' : 'length'
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
async *doStreamComplete(request) {
|
|
89
|
+
const model = request.model || this.config.model;
|
|
90
|
+
// Build request payload
|
|
91
|
+
const payload = {
|
|
92
|
+
model,
|
|
93
|
+
messages: request.messages.filter((msg)=>msg.role !== 'function').map((msg)=>({
|
|
94
|
+
role: msg.role,
|
|
95
|
+
content: msg.content
|
|
96
|
+
})),
|
|
97
|
+
temperature: request.temperature ?? this.config.temperature,
|
|
98
|
+
max_tokens: request.maxTokens ?? this.config.maxTokens,
|
|
99
|
+
stream: true
|
|
100
|
+
};
|
|
101
|
+
// Call Z.ai streaming API
|
|
102
|
+
const response = await fetch(`${this.baseURL}/chat/completions`, {
|
|
103
|
+
method: 'POST',
|
|
104
|
+
headers: {
|
|
105
|
+
'Content-Type': 'application/json',
|
|
106
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
107
|
+
},
|
|
108
|
+
body: JSON.stringify(payload)
|
|
109
|
+
});
|
|
110
|
+
if (!response.ok) {
|
|
111
|
+
throw new LLMProviderError(`Z.ai API error: ${response.status} ${response.statusText}`, 'API_ERROR', 'zai', undefined, response.status >= 500);
|
|
112
|
+
}
|
|
113
|
+
if (!response.body) {
|
|
114
|
+
throw new LLMProviderError('No response body from Z.ai API', 'NO_RESPONSE_BODY', 'zai');
|
|
115
|
+
}
|
|
116
|
+
// Process SSE stream
|
|
117
|
+
const reader = response.body.getReader();
|
|
118
|
+
const decoder = new TextDecoder();
|
|
119
|
+
let buffer = '';
|
|
120
|
+
let totalTokens = 0;
|
|
121
|
+
try {
|
|
122
|
+
while(true){
|
|
123
|
+
const { done, value } = await reader.read();
|
|
124
|
+
if (done) break;
|
|
125
|
+
buffer += decoder.decode(value, {
|
|
126
|
+
stream: true
|
|
127
|
+
});
|
|
128
|
+
const lines = buffer.split('\n');
|
|
129
|
+
buffer = lines.pop() || '';
|
|
130
|
+
for (const line of lines){
|
|
131
|
+
if (!line.trim() || line.startsWith(':')) continue;
|
|
132
|
+
if (line.startsWith('data: ')) {
|
|
133
|
+
const data = line.slice(6);
|
|
134
|
+
if (data === '[DONE]') continue;
|
|
135
|
+
try {
|
|
136
|
+
const event = JSON.parse(data);
|
|
137
|
+
if (event.choices?.[0]?.delta?.content) {
|
|
138
|
+
yield {
|
|
139
|
+
type: 'content',
|
|
140
|
+
delta: {
|
|
141
|
+
content: event.choices[0].delta.content
|
|
142
|
+
}
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (event.usage) {
|
|
146
|
+
totalTokens = event.usage.total_tokens;
|
|
147
|
+
}
|
|
148
|
+
} catch (parseError) {
|
|
149
|
+
this.logger.warn('Failed to parse SSE event', {
|
|
150
|
+
line,
|
|
151
|
+
error: parseError
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
// Emit final usage statistics
|
|
158
|
+
const pricing = this.capabilities.pricing[model];
|
|
159
|
+
const promptTokens = this.estimateTokens(JSON.stringify(request.messages));
|
|
160
|
+
const completionTokens = totalTokens - promptTokens;
|
|
161
|
+
const promptCost = promptTokens / 1000 * pricing.promptCostPer1k;
|
|
162
|
+
const completionCost = completionTokens / 1000 * pricing.completionCostPer1k;
|
|
163
|
+
yield {
|
|
164
|
+
type: 'done',
|
|
165
|
+
usage: {
|
|
166
|
+
promptTokens,
|
|
167
|
+
completionTokens,
|
|
168
|
+
totalTokens
|
|
169
|
+
},
|
|
170
|
+
cost: {
|
|
171
|
+
promptCost,
|
|
172
|
+
completionCost,
|
|
173
|
+
totalCost: promptCost + completionCost,
|
|
174
|
+
currency: 'USD'
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
} finally{
|
|
178
|
+
reader.releaseLock();
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
async listModels() {
|
|
182
|
+
return this.capabilities.supportedModels;
|
|
183
|
+
}
|
|
184
|
+
async getModelInfo(model) {
|
|
185
|
+
return {
|
|
186
|
+
model,
|
|
187
|
+
name: 'Claude 3.5 Sonnet',
|
|
188
|
+
description: 'Claude 3.5 Sonnet via Z.ai',
|
|
189
|
+
contextLength: this.capabilities.maxContextLength[model] || 200000,
|
|
190
|
+
maxOutputTokens: this.capabilities.maxOutputTokens[model] || 8192,
|
|
191
|
+
supportedFeatures: [
|
|
192
|
+
'chat',
|
|
193
|
+
'completion',
|
|
194
|
+
'vision',
|
|
195
|
+
'streaming'
|
|
196
|
+
],
|
|
197
|
+
pricing: this.capabilities.pricing[model]
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
async doHealthCheck() {
|
|
201
|
+
try {
|
|
202
|
+
// Minimal health check request
|
|
203
|
+
const response = await this.callZaiAPI('/chat/completions', {
|
|
204
|
+
model: this.config.model,
|
|
205
|
+
messages: [
|
|
206
|
+
{
|
|
207
|
+
role: 'user',
|
|
208
|
+
content: 'Hi'
|
|
209
|
+
}
|
|
210
|
+
],
|
|
211
|
+
max_tokens: 1,
|
|
212
|
+
stream: false
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
healthy: true,
|
|
216
|
+
timestamp: new Date(),
|
|
217
|
+
details: {
|
|
218
|
+
model: response.model,
|
|
219
|
+
status: 'operational'
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
} catch (error) {
|
|
223
|
+
return {
|
|
224
|
+
healthy: false,
|
|
225
|
+
error: error instanceof Error ? error.message : 'Unknown error',
|
|
226
|
+
timestamp: new Date()
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Call Z.ai API with error handling
|
|
232
|
+
*/ async callZaiAPI(endpoint, payload) {
|
|
233
|
+
const url = `${this.baseURL}${endpoint}`;
|
|
234
|
+
try {
|
|
235
|
+
const response = await fetch(url, {
|
|
236
|
+
method: 'POST',
|
|
237
|
+
headers: {
|
|
238
|
+
'Content-Type': 'application/json',
|
|
239
|
+
Authorization: `Bearer ${this.apiKey}`
|
|
240
|
+
},
|
|
241
|
+
body: JSON.stringify(payload)
|
|
242
|
+
});
|
|
243
|
+
if (!response.ok) {
|
|
244
|
+
const errorBody = await response.text();
|
|
245
|
+
let errorMessage = `Z.ai API error: ${response.status} ${response.statusText}`;
|
|
246
|
+
try {
|
|
247
|
+
const errorJson = JSON.parse(errorBody);
|
|
248
|
+
errorMessage = errorJson.error?.message || errorMessage;
|
|
249
|
+
} catch {
|
|
250
|
+
// Use default error message if body is not JSON
|
|
251
|
+
}
|
|
252
|
+
throw new LLMProviderError(errorMessage, response.status === 429 ? 'RATE_LIMIT' : 'API_ERROR', 'zai', undefined, response.status >= 500);
|
|
253
|
+
}
|
|
254
|
+
return await response.json();
|
|
255
|
+
} catch (error) {
|
|
256
|
+
if (error instanceof LLMProviderError) {
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
throw new LLMProviderError(error instanceof Error ? error.message : String(error), 'NETWORK_ERROR', 'zai', undefined, true);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
destroy() {
|
|
263
|
+
super.destroy();
|
|
264
|
+
this.logger.info('Z.ai provider destroyed');
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
//# sourceMappingURL=zai-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../src/providers/zai-provider.ts"],"names":["BaseProvider","LLMProviderError","ZaiProvider","name","capabilities","supportedModels","maxContextLength","maxOutputTokens","supportsStreaming","supportsFunctionCalling","supportsSystemMessages","supportsVision","supportsAudio","supportsTools","supportsFineTuning","supportsEmbeddings","supportsLogprobs","supportsBatching","pricing","promptCostPer1k","completionCostPer1k","currency","apiKey","baseURL","doInitialize","config","Error","logger","info","model","doComplete","request","payload","messages","filter","msg","role","map","content","temperature","max_tokens","maxTokens","stream","response","callZaiAPI","promptCost","usage","prompt_tokens","completionCost","completion_tokens","id","provider","choices","message","promptTokens","completionTokens","totalTokens","total_tokens","cost","totalCost","finishReason","finish_reason","doStreamComplete","fetch","method","headers","Authorization","body","JSON","stringify","ok","status","statusText","undefined","reader","getReader","decoder","TextDecoder","buffer","done","value","read","decode","lines","split","pop","line","trim","startsWith","data","slice","event","parse","delta","type","parseError","warn","error","estimateTokens","releaseLock","listModels","getModelInfo","description","contextLength","supportedFeatures","doHealthCheck","healthy","timestamp","Date","details","endpoint","url","errorBody","text","errorMessage","errorJson","json","String","destroy"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow-novice",
|
|
3
|
-
"version": "1.5.
|
|
3
|
+
"version": "1.5.22",
|
|
4
4
|
"description": "Standalone Claude Flow for beginners - AI agent orchestration made easy with enhanced TDD testing pipeline. Enhanced init command creates complete agent system, MCP configuration with 30 essential tools, and automated hooks with single-file testing, real-time coverage analysis, and advanced validation. Fully standalone with zero external dependencies, complete project setup in one command.",
|
|
5
5
|
"mcpName": "io.github.ruvnet/claude-flow",
|
|
6
6
|
"main": ".claude-flow-novice/dist/index.js",
|
|
@@ -32,6 +32,31 @@
|
|
|
32
32
|
- Refactoring or optimization work
|
|
33
33
|
- ANY feature development (even "simple" ones)
|
|
34
34
|
|
|
35
|
+
## 🚨 CRITICAL: Safe Test Execution
|
|
36
|
+
|
|
37
|
+
**NEVER run tests inside agents** - causes memory leaks from orphaned processes.
|
|
38
|
+
|
|
39
|
+
### Correct Pattern:
|
|
40
|
+
```bash
|
|
41
|
+
# 1. Run tests ONCE, save results
|
|
42
|
+
npm test -- --run --reporter=json > test-results.json 2>&1
|
|
43
|
+
|
|
44
|
+
# 2. Agents READ results file (no execution)
|
|
45
|
+
cat test-results.json
|
|
46
|
+
|
|
47
|
+
# 3. Kill orphaned processes after swarm
|
|
48
|
+
pkill -f vitest; pkill -f "npm test"
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Forbidden:
|
|
52
|
+
- ❌ `Task("agent", "run npm test", "type")` - spawns orphaned process
|
|
53
|
+
- ❌ Multiple agents running tests concurrently - 3x memory usage
|
|
54
|
+
- ❌ Long-running test commands without timeout cleanup
|
|
55
|
+
|
|
56
|
+
### Memory Impact:
|
|
57
|
+
- Each test run: 65MB+ heap
|
|
58
|
+
- Concurrent runs: 65MB × agent_count
|
|
59
|
+
- Orphaned processes persist after swarm completion
|
|
35
60
|
### Agent Requirements by Task Complexity
|
|
36
61
|
|
|
37
62
|
| Task Size | Steps | Agent Count | Example Team Composition |
|
|
@@ -61,8 +61,9 @@ Enhanced Features:
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
// Build unified pipeline command with TDD mode enabled by default
|
|
64
|
-
// Use
|
|
65
|
-
|
|
64
|
+
// Use __dirname to find config/hooks in the installed package location
|
|
65
|
+
// Path: .claude-flow-novice/dist/src/hooks -> ../../../../config/hooks
|
|
66
|
+
const pipelinePath = join(__dirname, '../../../../config/hooks/post-edit-pipeline.js');
|
|
66
67
|
const pipelineArgs = [file, '--tdd-mode'];
|
|
67
68
|
|
|
68
69
|
// Pass through all relevant flags
|
|
@@ -81,18 +82,28 @@ Enhanced Features:
|
|
|
81
82
|
// Structured output is default in unified pipeline
|
|
82
83
|
}
|
|
83
84
|
|
|
84
|
-
// Execute unified pipeline
|
|
85
|
+
// Execute unified pipeline with timeout protection
|
|
85
86
|
const proc = spawn('node', [pipelinePath, ...pipelineArgs], {
|
|
86
87
|
stdio: 'inherit',
|
|
87
88
|
cwd: process.cwd()
|
|
88
89
|
});
|
|
89
90
|
|
|
91
|
+
// Set timeout to kill hanging processes (5 minutes max)
|
|
92
|
+
const timeout = setTimeout(() => {
|
|
93
|
+
console.error('❌ Pipeline timeout - killing process');
|
|
94
|
+
proc.kill('SIGKILL');
|
|
95
|
+
process.exit(1);
|
|
96
|
+
}, 300000); // 5 minutes
|
|
97
|
+
|
|
90
98
|
proc.on('close', (code) => {
|
|
99
|
+
clearTimeout(timeout);
|
|
91
100
|
process.exit(code || 0);
|
|
92
101
|
});
|
|
93
102
|
|
|
94
103
|
proc.on('error', (error) => {
|
|
104
|
+
clearTimeout(timeout);
|
|
95
105
|
console.error(`❌ Failed to execute unified pipeline: ${error.message}`);
|
|
106
|
+
proc.kill('SIGKILL');
|
|
96
107
|
process.exit(1);
|
|
97
108
|
});
|
|
98
109
|
|
|
@@ -121,10 +132,17 @@ export async function enhancedPostEdit(file, memoryKey = null, options = {}) {
|
|
|
121
132
|
let stdout = '';
|
|
122
133
|
let stderr = '';
|
|
123
134
|
|
|
135
|
+
// Set timeout to kill hanging processes (5 minutes max)
|
|
136
|
+
const timeout = setTimeout(() => {
|
|
137
|
+
proc.kill('SIGKILL');
|
|
138
|
+
reject(new Error('Pipeline execution timeout after 5 minutes'));
|
|
139
|
+
}, 300000); // 5 minutes
|
|
140
|
+
|
|
124
141
|
proc.stdout.on('data', (data) => stdout += data.toString());
|
|
125
142
|
proc.stderr.on('data', (data) => stderr += data.toString());
|
|
126
143
|
|
|
127
144
|
proc.on('close', (code) => {
|
|
145
|
+
clearTimeout(timeout);
|
|
128
146
|
resolve({
|
|
129
147
|
success: code === 0,
|
|
130
148
|
file,
|
|
@@ -137,6 +155,8 @@ export async function enhancedPostEdit(file, memoryKey = null, options = {}) {
|
|
|
137
155
|
});
|
|
138
156
|
|
|
139
157
|
proc.on('error', (error) => {
|
|
158
|
+
clearTimeout(timeout);
|
|
159
|
+
proc.kill('SIGKILL');
|
|
140
160
|
reject(error);
|
|
141
161
|
});
|
|
142
162
|
});
|