@howlil/ez-agents 3.1.0 → 3.4.2

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 (110) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +288 -718
  3. package/bin/install.js +438 -71
  4. package/commands/ez/auth.md +87 -0
  5. package/commands/ez/join-discord.md +18 -18
  6. package/ez-agents/bin/ez-tools.cjs +120 -2
  7. package/ez-agents/bin/lib/assistant-adapter.cjs +264 -205
  8. package/ez-agents/bin/lib/audit-exec.cjs +26 -9
  9. package/ez-agents/bin/lib/auth.cjs +2 -1
  10. package/ez-agents/bin/lib/circuit-breaker.cjs +118 -118
  11. package/ez-agents/bin/lib/commands.cjs +42 -23
  12. package/ez-agents/bin/lib/config.cjs +190 -183
  13. package/ez-agents/bin/lib/core.cjs +42 -25
  14. package/ez-agents/bin/lib/file-lock.cjs +236 -236
  15. package/ez-agents/bin/lib/frontmatter.cjs +299 -299
  16. package/ez-agents/bin/lib/fs-utils.cjs +153 -153
  17. package/ez-agents/bin/lib/git-utils.cjs +203 -203
  18. package/ez-agents/bin/lib/health-check.cjs +2 -3
  19. package/ez-agents/bin/lib/index.cjs +113 -113
  20. package/ez-agents/bin/lib/init.cjs +757 -710
  21. package/ez-agents/bin/lib/logger.cjs +52 -15
  22. package/ez-agents/bin/lib/milestone.cjs +241 -241
  23. package/ez-agents/bin/lib/model-provider.cjs +241 -146
  24. package/ez-agents/bin/lib/phase.cjs +925 -908
  25. package/ez-agents/bin/lib/planning-write.cjs +107 -0
  26. package/ez-agents/bin/lib/retry.cjs +119 -119
  27. package/ez-agents/bin/lib/roadmap.cjs +306 -305
  28. package/ez-agents/bin/lib/safe-exec.cjs +91 -5
  29. package/ez-agents/bin/lib/safe-path.cjs +130 -130
  30. package/ez-agents/bin/lib/state.cjs +736 -721
  31. package/ez-agents/bin/lib/temp-file.cjs +239 -239
  32. package/ez-agents/bin/lib/template.cjs +223 -222
  33. package/ez-agents/bin/lib/test-file-lock.cjs +112 -112
  34. package/ez-agents/bin/lib/test-graceful.cjs +93 -93
  35. package/ez-agents/bin/lib/test-logger.cjs +60 -60
  36. package/ez-agents/bin/lib/test-safe-exec.cjs +38 -38
  37. package/ez-agents/bin/lib/test-safe-path.cjs +33 -33
  38. package/ez-agents/bin/lib/test-temp-file.cjs +125 -125
  39. package/ez-agents/bin/lib/timeout-exec.cjs +63 -62
  40. package/ez-agents/bin/lib/verify.cjs +69 -26
  41. package/ez-agents/references/checkpoints.md +776 -776
  42. package/ez-agents/references/continuation-format.md +249 -249
  43. package/ez-agents/references/questioning.md +162 -162
  44. package/ez-agents/references/tdd.md +263 -263
  45. package/ez-agents/templates/codebase/concerns.md +310 -310
  46. package/ez-agents/templates/codebase/conventions.md +307 -307
  47. package/ez-agents/templates/codebase/integrations.md +280 -280
  48. package/ez-agents/templates/codebase/stack.md +186 -186
  49. package/ez-agents/templates/codebase/testing.md +480 -480
  50. package/ez-agents/templates/config.json +37 -37
  51. package/ez-agents/templates/continue-here.md +78 -78
  52. package/ez-agents/templates/milestone-archive.md +123 -123
  53. package/ez-agents/templates/milestone.md +115 -115
  54. package/ez-agents/templates/requirements.md +231 -231
  55. package/ez-agents/templates/research-project/ARCHITECTURE.md +204 -204
  56. package/ez-agents/templates/research-project/FEATURES.md +147 -147
  57. package/ez-agents/templates/research-project/PITFALLS.md +200 -200
  58. package/ez-agents/templates/research-project/STACK.md +120 -120
  59. package/ez-agents/templates/research-project/SUMMARY.md +170 -170
  60. package/ez-agents/templates/retrospective.md +54 -54
  61. package/ez-agents/templates/roadmap.md +202 -202
  62. package/ez-agents/templates/summary-minimal.md +41 -41
  63. package/ez-agents/templates/summary-standard.md +48 -48
  64. package/ez-agents/templates/summary.md +248 -248
  65. package/ez-agents/templates/user-setup.md +311 -311
  66. package/ez-agents/templates/verification-report.md +322 -322
  67. package/ez-agents/workflows/add-phase.md +112 -112
  68. package/ez-agents/workflows/add-tests.md +351 -351
  69. package/ez-agents/workflows/add-todo.md +158 -158
  70. package/ez-agents/workflows/audit-milestone.md +332 -332
  71. package/ez-agents/workflows/autonomous.md +743 -743
  72. package/ez-agents/workflows/check-todos.md +177 -177
  73. package/ez-agents/workflows/cleanup.md +152 -152
  74. package/ez-agents/workflows/complete-milestone.md +766 -766
  75. package/ez-agents/workflows/diagnose-issues.md +219 -219
  76. package/ez-agents/workflows/discovery-phase.md +289 -289
  77. package/ez-agents/workflows/discuss-phase.md +762 -762
  78. package/ez-agents/workflows/execute-phase.md +468 -468
  79. package/ez-agents/workflows/execute-plan.md +483 -483
  80. package/ez-agents/workflows/health.md +159 -159
  81. package/ez-agents/workflows/help.md +492 -492
  82. package/ez-agents/workflows/insert-phase.md +130 -130
  83. package/ez-agents/workflows/list-phase-assumptions.md +178 -178
  84. package/ez-agents/workflows/map-codebase.md +316 -316
  85. package/ez-agents/workflows/new-milestone.md +384 -384
  86. package/ez-agents/workflows/new-project.md +1113 -1111
  87. package/ez-agents/workflows/node-repair.md +92 -92
  88. package/ez-agents/workflows/pause-work.md +122 -122
  89. package/ez-agents/workflows/plan-milestone-gaps.md +274 -274
  90. package/ez-agents/workflows/plan-phase.md +651 -651
  91. package/ez-agents/workflows/progress.md +382 -382
  92. package/ez-agents/workflows/quick.md +610 -610
  93. package/ez-agents/workflows/remove-phase.md +155 -155
  94. package/ez-agents/workflows/research-phase.md +74 -74
  95. package/ez-agents/workflows/resume-project.md +307 -307
  96. package/ez-agents/workflows/set-profile.md +81 -81
  97. package/ez-agents/workflows/settings.md +242 -242
  98. package/ez-agents/workflows/stats.md +57 -57
  99. package/ez-agents/workflows/transition.md +544 -544
  100. package/ez-agents/workflows/ui-phase.md +290 -290
  101. package/ez-agents/workflows/ui-review.md +157 -157
  102. package/ez-agents/workflows/update.md +320 -320
  103. package/ez-agents/workflows/validate-phase.md +167 -167
  104. package/ez-agents/workflows/verify-phase.md +243 -243
  105. package/ez-agents/workflows/verify-work.md +584 -584
  106. package/package.json +2 -3
  107. package/scripts/build-hooks.js +43 -43
  108. package/scripts/fix-qwen-installation.js +144 -0
  109. package/scripts/run-tests.cjs +29 -29
  110. package/README.zh-CN.md +0 -702
@@ -1,146 +1,241 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * GSD Model Provider — Unified API for multiple AI providers
5
- *
6
- * Supports: Anthropic, Moonshot (Kimi), Alibaba (Qwen), OpenAI
7
- *
8
- * Usage:
9
- * const ModelProvider = require('./model-provider.cjs');
10
- * const model = new ModelProvider({ provider: 'anthropic', model: 'sonnet' });
11
- * const response = await model.chat([{ role: 'user', content: 'Hello' }]);
12
- */
13
-
14
- const Logger = require('./logger.cjs');
15
- const logger = new Logger();
16
-
17
- class ModelProvider {
18
- /**
19
- * Create model provider
20
- * @param {Object} config - Configuration
21
- */
22
- constructor(config) {
23
- this.provider = config.provider || 'anthropic';
24
- this.model = config.model || 'sonnet';
25
- this.apiKey = config.apiKey || process.env[`${this.provider.toUpperCase()}_API_KEY`];
26
-
27
- if (!this.apiKey) {
28
- logger.warn('API key not configured', { provider: this.provider });
29
- }
30
- }
31
-
32
- /**
33
- * Send chat message
34
- * @param {Object[]} messages - Chat messages
35
- * @param {Object} options - Chat options
36
- * @returns {Promise<Object>} - Response
37
- */
38
- async chat(messages, options = {}) {
39
- logger.info('Chat request', {
40
- provider: this.provider,
41
- model: this.model,
42
- messageCount: messages.length
43
- });
44
-
45
- switch (this.provider) {
46
- case 'anthropic':
47
- return this._chatAnthropic(messages, options);
48
- case 'moonshot':
49
- return this._chatMoonshot(messages, options);
50
- case 'alibaba':
51
- return this._chatQwen(messages, options);
52
- case 'openai':
53
- return this._chatOpenAI(messages, options);
54
- default:
55
- throw new Error(`Unsupported provider: ${this.provider}`);
56
- }
57
- }
58
-
59
- /**
60
- * Anthropic Claude API
61
- */
62
- async _chatAnthropic(messages, options) {
63
- // Placeholder - would use @anthropic-ai/sdk in production
64
- logger.debug('Anthropic chat', { model: this.model });
65
- return {
66
- content: '[Anthropic response placeholder]',
67
- provider: 'anthropic',
68
- model: this.model
69
- };
70
- }
71
-
72
- /**
73
- * Moonshot (Kimi) API
74
- */
75
- async _chatMoonshot(messages, options) {
76
- // Placeholder - would use moonshot SDK in production
77
- logger.debug('Moonshot chat', { model: this.model });
78
- return {
79
- content: '[Moonshot response placeholder]',
80
- provider: 'moonshot',
81
- model: this.model
82
- };
83
- }
84
-
85
- /**
86
- * Alibaba Qwen API
87
- */
88
- async _chatQwen(messages, options) {
89
- // Placeholder - would use DashScope SDK in production
90
- logger.debug('Qwen chat', { model: this.model });
91
- return {
92
- content: '[Qwen response placeholder]',
93
- provider: 'alibaba',
94
- model: this.model
95
- };
96
- }
97
-
98
- /**
99
- * OpenAI API
100
- */
101
- async _chatOpenAI(messages, options) {
102
- // Placeholder - would use openai SDK in production
103
- logger.debug('OpenAI chat', { model: this.model });
104
- return {
105
- content: '[OpenAI response placeholder]',
106
- provider: 'openai',
107
- model: this.model
108
- };
109
- }
110
-
111
- /**
112
- * Count tokens (approximate)
113
- * @param {string} text - Text to count
114
- * @returns {number} - Approximate token count
115
- */
116
- countTokens(text) {
117
- // Rough estimate: 1 token ≈ 4 characters
118
- return Math.ceil(text.length / 4);
119
- }
120
-
121
- /**
122
- * Get provider info
123
- * @returns {Object} - Provider information
124
- */
125
- getInfo() {
126
- return {
127
- provider: this.provider,
128
- model: this.model,
129
- hasApiKey: !!this.apiKey
130
- };
131
- }
132
- }
133
-
134
- /**
135
- * Create provider from config
136
- * @param {Object} config - Provider config
137
- * @returns {ModelProvider} - Model provider instance
138
- */
139
- function createProvider(config) {
140
- return new ModelProvider(config);
141
- }
142
-
143
- module.exports = {
144
- ModelProvider,
145
- createProvider
146
- };
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * EZ Model Provider — Unified API for multiple AI providers
5
+ *
6
+ * Supports: Anthropic, Moonshot (Kimi), Alibaba (Qwen), OpenAI
7
+ */
8
+
9
+ const https = require('https');
10
+ const { URL } = require('url');
11
+ const Logger = require('./logger.cjs');
12
+ const logger = new Logger();
13
+
14
+ class ModelProvider {
15
+ /**
16
+ * Create model provider
17
+ * @param {Object} config - Configuration
18
+ */
19
+ constructor(config) {
20
+ this.provider = config.provider || 'anthropic';
21
+ this.model = config.model || 'sonnet';
22
+ this.apiKey = config.apiKey || process.env[`${this.provider.toUpperCase()}_API_KEY`];
23
+
24
+ if (!this.apiKey && this.provider !== 'anthropic') {
25
+ logger.warn('API key not configured', { provider: this.provider });
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Helper for HTTP requests
31
+ */
32
+ _httpRequest(options, data) {
33
+ return new Promise((resolve, reject) => {
34
+ const req = https.request(options, (res) => {
35
+ let body = '';
36
+ res.on('data', (chunk) => body += chunk);
37
+ res.on('end', () => {
38
+ if (res.statusCode >= 200 && res.statusCode < 300) {
39
+ try {
40
+ resolve(JSON.parse(body));
41
+ } catch (e) {
42
+ resolve(body);
43
+ }
44
+ } else {
45
+ reject(new Error(`HTTP ${res.statusCode}: ${body}`));
46
+ }
47
+ });
48
+ });
49
+ req.on('error', reject);
50
+ if (data) req.write(JSON.stringify(data));
51
+ req.end();
52
+ });
53
+ }
54
+
55
+ /**
56
+ * Send chat message
57
+ * @param {Object[]} messages - Chat messages
58
+ * @param {Object} options - Chat options
59
+ * @returns {Promise<Object>} - Response
60
+ */
61
+ async chat(messages, options = {}) {
62
+ logger.info('Chat request', {
63
+ provider: this.provider,
64
+ model: this.model,
65
+ messageCount: messages.length
66
+ });
67
+
68
+ switch (this.provider) {
69
+ case 'anthropic':
70
+ return this._chatAnthropic(messages, options);
71
+ case 'moonshot':
72
+ return this._chatMoonshot(messages, options);
73
+ case 'alibaba':
74
+ case 'qwen':
75
+ return this._chatQwen(messages, options);
76
+ case 'openai':
77
+ return this._chatOpenAI(messages, options);
78
+ default:
79
+ throw new Error(`Unsupported provider: ${this.provider}`);
80
+ }
81
+ }
82
+
83
+ /**
84
+ * Anthropic Claude API
85
+ */
86
+ async _chatAnthropic(messages, options) {
87
+ // Anthropic usually requires their SDK or complex headers
88
+ logger.debug('Anthropic chat', { model: this.model });
89
+ return {
90
+ content: '[Anthropic response placeholder - requires SDK]',
91
+ provider: 'anthropic',
92
+ model: this.model
93
+ };
94
+ }
95
+
96
+ /**
97
+ * Moonshot (Kimi) API
98
+ */
99
+ async _chatMoonshot(messages, options) {
100
+ const modelName = this.model === 'sonnet' ? 'moonshot-v1-8k' : this.model;
101
+ const data = {
102
+ model: modelName,
103
+ messages: messages,
104
+ temperature: options.temperature || 0.3
105
+ };
106
+
107
+ const reqOptions = {
108
+ hostname: 'api.moonshot.cn',
109
+ path: '/v1/chat/completions',
110
+ method: 'POST',
111
+ headers: {
112
+ 'Content-Type': 'application/json',
113
+ 'Authorization': `Bearer ${this.apiKey}`
114
+ }
115
+ };
116
+
117
+ try {
118
+ const response = await this._httpRequest(reqOptions, data);
119
+ return {
120
+ content: response.choices[0].message.content,
121
+ provider: 'moonshot',
122
+ model: modelName
123
+ };
124
+ } catch (error) {
125
+ logger.error('Moonshot API error', { error: error.message });
126
+ throw error;
127
+ }
128
+ }
129
+
130
+ /**
131
+ * Alibaba Qwen API (DashScope)
132
+ */
133
+ async _chatQwen(messages, options) {
134
+ // Map generic model names to Qwen specific ones
135
+ let modelName = this.model;
136
+ if (modelName === 'sonnet' || modelName === 'gpt-4') modelName = 'qwen-max';
137
+ if (modelName === 'haiku' || modelName === 'gpt-3.5-turbo') modelName = 'qwen-plus';
138
+
139
+ const data = {
140
+ model: modelName,
141
+ input: {
142
+ messages: messages
143
+ },
144
+ parameters: {
145
+ result_format: 'message',
146
+ temperature: options.temperature || 0.3
147
+ }
148
+ };
149
+
150
+ const reqOptions = {
151
+ hostname: 'dashscope.aliyuncs.com',
152
+ path: '/api/v1/services/aigc/text-generation/generation',
153
+ method: 'POST',
154
+ headers: {
155
+ 'Content-Type': 'application/json',
156
+ 'Authorization': `Bearer ${this.apiKey}`
157
+ }
158
+ };
159
+
160
+ try {
161
+ const response = await this._httpRequest(reqOptions, data);
162
+ return {
163
+ content: response.output.choices[0].message.content,
164
+ provider: 'alibaba',
165
+ model: modelName
166
+ };
167
+ } catch (error) {
168
+ logger.error('Qwen API error', { error: error.message });
169
+ throw error;
170
+ }
171
+ }
172
+
173
+ /**
174
+ * OpenAI API
175
+ */
176
+ async _chatOpenAI(messages, options) {
177
+ const modelName = this.model === 'sonnet' ? 'gpt-4-turbo' : this.model;
178
+ const data = {
179
+ model: modelName,
180
+ messages: messages,
181
+ temperature: options.temperature || 0.3
182
+ };
183
+
184
+ const reqOptions = {
185
+ hostname: 'api.openai.com',
186
+ path: '/v1/chat/completions',
187
+ method: 'POST',
188
+ headers: {
189
+ 'Content-Type': 'application/json',
190
+ 'Authorization': `Bearer ${this.apiKey}`
191
+ }
192
+ };
193
+
194
+ try {
195
+ const response = await this._httpRequest(reqOptions, data);
196
+ return {
197
+ content: response.choices[0].message.content,
198
+ provider: 'openai',
199
+ model: modelName
200
+ };
201
+ } catch (error) {
202
+ logger.error('OpenAI API error', { error: error.message });
203
+ throw error;
204
+ }
205
+ }
206
+
207
+ /**
208
+ * Count tokens (approximate)
209
+ * @param {string} text - Text to count
210
+ * @returns {number} - Approximate token count
211
+ */
212
+ countTokens(text) {
213
+ return Math.ceil(text.length / 4);
214
+ }
215
+
216
+ /**
217
+ * Get provider info
218
+ * @returns {Object} - Provider information
219
+ */
220
+ getInfo() {
221
+ return {
222
+ provider: this.provider,
223
+ model: this.model,
224
+ hasApiKey: !!this.apiKey
225
+ };
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Create provider from config
231
+ * @param {Object} config - Provider config
232
+ * @returns {ModelProvider} - Model provider instance
233
+ */
234
+ function createProvider(config) {
235
+ return new ModelProvider(config);
236
+ }
237
+
238
+ module.exports = {
239
+ ModelProvider,
240
+ createProvider
241
+ };