foliko 1.1.0 → 1.1.1
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/.agent/.shared/ui-ux-pro-max/data/charts.csv +26 -0
- package/.agent/.shared/ui-ux-pro-max/data/colors.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/icons.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/landing.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/data/products.csv +97 -0
- package/.agent/.shared/ui-ux-pro-max/data/prompts.csv +24 -0
- package/.agent/.shared/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/.agent/.shared/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/.agent/.shared/ui-ux-pro-max/data/styles.csv +59 -0
- package/.agent/.shared/ui-ux-pro-max/data/typography.csv +58 -0
- package/.agent/.shared/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/.agent/.shared/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/.agent/.shared/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/core.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/__pycache__/design_system.cpython-313.pyc +0 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/core.py +258 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/.agent/.shared/ui-ux-pro-max/scripts/search.py +106 -0
- package/.agent/ARCHITECTURE.md +288 -0
- package/.agent/agents/ambient-agent.md +57 -0
- package/.agent/agents/debugger.md +55 -0
- package/.agent/agents/email-assistant.md +49 -0
- package/.agent/agents/file-manager.md +42 -0
- package/.agent/agents/python-developer.md +60 -0
- package/.agent/agents/scheduler.md +59 -0
- package/.agent/agents/web-developer.md +45 -0
- package/.agent/data/default.json +412 -3
- package/.agent/data/plugins-state.json +173 -174
- package/.agent/data/puppeteer-sessions/undefined.json +6 -0
- package/.agent/mcp_config_updated.json +12 -0
- package/.agent/plugins/poster-plugin/fonts/NotoColorEmoji-Regular.ttf +0 -0
- package/.agent/plugins/poster-plugin/src/elements/polygon.js +37 -6
- package/.agent/plugins/poster-plugin/src/elements/text.js +71 -2
- package/.agent/plugins/poster-plugin/src/fonts.js +123 -8
- package/.agent/plugins/poster-plugin/src/index.js +15 -16
- package/.agent/plugins/puppeteer-plugin/README.md +147 -0
- package/.agent/plugins/puppeteer-plugin/index.js +1418 -0
- package/.agent/plugins/puppeteer-plugin/package.json +9 -0
- package/.agent/plugins.json +5 -11
- package/.agent/rules/GEMINI.md +273 -0
- package/.agent/rules/allow-rule.md +77 -0
- package/.agent/rules/log-rule.md +83 -0
- package/.agent/rules/security-rule.md +93 -0
- package/.agent/scripts/auto_preview.py +148 -0
- package/.agent/scripts/checklist.py +217 -0
- package/.agent/scripts/session_manager.py +120 -0
- package/.agent/scripts/verify_all.py +327 -0
- package/.agent/sessions/cli_default.json +135 -23981
- package/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json +2195 -0
- package/.agent/skills/api-patterns/SKILL.md +81 -0
- package/.agent/skills/api-patterns/api-style.md +42 -0
- package/.agent/skills/api-patterns/auth.md +24 -0
- package/.agent/skills/api-patterns/documentation.md +26 -0
- package/.agent/skills/api-patterns/graphql.md +41 -0
- package/.agent/skills/api-patterns/rate-limiting.md +31 -0
- package/.agent/skills/api-patterns/response.md +37 -0
- package/.agent/skills/api-patterns/rest.md +40 -0
- package/.agent/skills/api-patterns/scripts/api_validator.py +211 -0
- package/.agent/skills/api-patterns/security-testing.md +122 -0
- package/.agent/skills/api-patterns/trpc.md +41 -0
- package/.agent/skills/api-patterns/versioning.md +22 -0
- package/.agent/skills/app-builder/SKILL.md +75 -0
- package/.agent/skills/app-builder/agent-coordination.md +71 -0
- package/.agent/skills/app-builder/feature-building.md +53 -0
- package/.agent/skills/app-builder/project-detection.md +34 -0
- package/.agent/skills/app-builder/scaffolding.md +118 -0
- package/.agent/skills/app-builder/tech-stack.md +40 -0
- package/.agent/skills/app-builder/templates/SKILL.md +39 -0
- package/.agent/skills/app-builder/templates/astro-static/TEMPLATE.md +76 -0
- package/.agent/skills/app-builder/templates/chrome-extension/TEMPLATE.md +92 -0
- package/.agent/skills/app-builder/templates/cli-tool/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/electron-desktop/TEMPLATE.md +88 -0
- package/.agent/skills/app-builder/templates/express-api/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/flutter-app/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/monorepo-turborepo/TEMPLATE.md +90 -0
- package/.agent/skills/app-builder/templates/nextjs-fullstack/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-saas/TEMPLATE.md +122 -0
- package/.agent/skills/app-builder/templates/nextjs-static/TEMPLATE.md +169 -0
- package/.agent/skills/app-builder/templates/nuxt-app/TEMPLATE.md +134 -0
- package/.agent/skills/app-builder/templates/python-fastapi/TEMPLATE.md +83 -0
- package/.agent/skills/app-builder/templates/react-native-app/TEMPLATE.md +119 -0
- package/.agent/skills/architecture/SKILL.md +55 -0
- package/.agent/skills/architecture/context-discovery.md +43 -0
- package/.agent/skills/architecture/examples.md +94 -0
- package/.agent/skills/architecture/pattern-selection.md +68 -0
- package/.agent/skills/architecture/patterns-reference.md +50 -0
- package/.agent/skills/architecture/trade-off-analysis.md +77 -0
- package/.agent/skills/clean-code/SKILL.md +201 -0
- package/.agent/skills/doc.md +177 -0
- package/.agent/skills/frontend-design/SKILL.md +418 -0
- package/.agent/skills/frontend-design/animation-guide.md +331 -0
- package/.agent/skills/frontend-design/color-system.md +311 -0
- package/.agent/skills/frontend-design/decision-trees.md +418 -0
- package/.agent/skills/frontend-design/motion-graphics.md +306 -0
- package/.agent/skills/frontend-design/scripts/accessibility_checker.py +183 -0
- package/.agent/skills/frontend-design/scripts/ux_audit.py +722 -0
- package/.agent/skills/frontend-design/typography-system.md +345 -0
- package/.agent/skills/frontend-design/ux-psychology.md +1116 -0
- package/.agent/skills/frontend-design/visual-effects.md +383 -0
- package/.agent/skills/i18n-localization/SKILL.md +154 -0
- package/.agent/skills/i18n-localization/scripts/i18n_checker.py +241 -0
- package/.agent/skills/mcp-builder/SKILL.md +176 -0
- package/.agent/skills/web-design-guidelines/SKILL.md +57 -0
- package/.agent/workflows/brainstorm.md +113 -0
- package/.agent/workflows/create.md +59 -0
- package/.agent/workflows/debug.md +103 -0
- package/.agent/workflows/deploy.md +176 -0
- package/.agent/workflows/enhance.md +63 -0
- package/.agent/workflows/orchestrate.md +237 -0
- package/.agent/workflows/plan.md +89 -0
- package/.agent/workflows/preview.md +81 -0
- package/.agent/workflows/simple-test.md +42 -0
- package/.agent/workflows/status.md +86 -0
- package/.agent/workflows/structured-orchestrate.md +180 -0
- package/.agent/workflows/test.md +144 -0
- package/.agent/workflows/ui-ux-pro-max.md +296 -0
- package/.claude/settings.local.json +16 -1
- package/.env.example +56 -56
- package/README.md +441 -441
- package/calc_tokens_weixin.js +81 -0
- package/cli/src/commands/chat.js +2 -1
- package/foliko-creative-3.png +0 -0
- package/foliko-creative-4.png +0 -0
- package/foliko-creative-5.png +0 -0
- package/package.json +1 -1
- package/plugins/extension-executor-plugin.js +80 -2
- package/plugins/file-system-plugin.js +2 -2
- package/plugins/weixin-plugin.js +10 -2
- package/skills/find-skills/AGENTS.md +162 -162
- package/skills/find-skills/SKILL.md +133 -133
- package/skills/poster-guide/SKILL.md +948 -632
- package/src/core/agent-chat.js +82 -3
- package/story-cover-book-v2.png +0 -0
- package/story-cover-japanese-1.png +0 -0
- package/story-cover-japanese-2.png +0 -0
- package/story-cover-japanese-3.png +0 -0
- package/story-cover-moran.png +0 -0
- package/undefined.png +0 -0
- package/.agent/agents/code-assistant.json +0 -14
- package/.agent/agents/email-assistant.json +0 -14
- package/.agent/agents/file-assistant.json +0 -15
- package/.agent/agents/system-assistant.json +0 -15
- package/.agent/agents/web-assistant.json +0 -12
- package/.agent/data/ambient/goals.json +0 -50
- package/.agent/data/ambient/memories.json +0 -7
- package/.agent/data/scheduler/tasks.json +0 -1
- package/.agent/memory/core.md +0 -1
- package/.agent/memory/project/mnn93ogy-ypjn27.md +0 -9
- package/.agent/memory/project/mnn98fqy-5nhc1u.md +0 -25
- package/.agent/memory/user/mnm67t9m-x8rekk.md +0 -9
- package/.agent/memory/user/mnn5mmqh-w6aktx.md +0 -11
- package/.agent/memory/user/mnnbfhhn-dk1bd1.md +0 -22
- package/.agent/package.json +0 -8
- package/.agent/plugins/__pycache__/file_writer.cpython-312.pyc +0 -0
- package/.agent/plugins/daytona/README.md +0 -89
- package/.agent/plugins/daytona/index.js +0 -377
- package/.agent/plugins/daytona/package.json +0 -12
- package/.agent/plugins/marknative/README.md +0 -134
- package/.agent/plugins/marknative/index.js +0 -228
- package/.agent/plugins/marknative/package.json +0 -12
- package/.agent/plugins/marknative/update-readme.js +0 -134
- package/.agent/plugins/system-info/index.js +0 -387
- package/.agent/plugins/system-info/package.json +0 -4
- package/.agent/plugins/system-info/test.js +0 -40
- package/.agent/python-scripts/test_sample.py +0 -24
- package/.agent/skills/agent-browser/SKILL.md +0 -311
- package/.agent/skills/agent-browser/TEST_PLAN.md +0 -200
- package/.agent/skills/sysinfo/SKILL.md +0 -38
- package/.agent/skills/sysinfo/system-info.sh +0 -130
- package/.agent/skills/workflow/SKILL.md +0 -324
- package/.agent/weixin.json +0 -6
- package/.agent/workflows/email-digest.json +0 -50
- package/.agent/workflows/file-backup.json +0 -21
- package/.agent/workflows/get-ip-notify.json +0 -32
- package/.agent/workflows/news-aggregator.json +0 -93
- package/.agent/workflows/news-dashboard-v2.json +0 -94
- package/.agent/workflows/notification-batch.json +0 -32
- package/output/beef-love-poster.png +0 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
const fs = require('fs');
|
|
2
|
+
|
|
3
|
+
function encode(text) {
|
|
4
|
+
if (!text || typeof text !== 'string') return 0;
|
|
5
|
+
const cleanText = text.replace(/\0+/g, '').replace(/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/g, '').slice(0, 100000);
|
|
6
|
+
if (!cleanText) return 0;
|
|
7
|
+
const chineseChars = (cleanText.match(/[\u4e00-\u9fff\u3400-\u4dbf]/g) || []).length;
|
|
8
|
+
const englishChars = cleanText.length - chineseChars;
|
|
9
|
+
const chineseTokens = chineseChars / 2;
|
|
10
|
+
const englishTokens = englishChars / 4;
|
|
11
|
+
return Math.ceil(chineseTokens + englishTokens);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const filePath = 'D:/code/vb-agent/.agent/sessions/weixin_o9cq80zgZqKPA2-s59PN43GdDy1w@im.wechat.json';
|
|
15
|
+
const data = JSON.parse(fs.readFileSync(filePath, 'utf8'));
|
|
16
|
+
|
|
17
|
+
let totalTokens = 0;
|
|
18
|
+
let totalChars = 0;
|
|
19
|
+
let largeMessages = [];
|
|
20
|
+
const messages = data.messages || [];
|
|
21
|
+
|
|
22
|
+
for (let i = 0; i < messages.length; i++) {
|
|
23
|
+
const msg = messages[i];
|
|
24
|
+
let msgTokens = 4;
|
|
25
|
+
let msgChars = 0;
|
|
26
|
+
|
|
27
|
+
if (typeof msg.content === 'string') {
|
|
28
|
+
msgTokens += encode(msg.content);
|
|
29
|
+
msgChars += msg.content.length;
|
|
30
|
+
} else if (Array.isArray(msg.content)) {
|
|
31
|
+
for (const part of msg.content) {
|
|
32
|
+
if (!part || typeof part !== 'object') continue;
|
|
33
|
+
if (part.text) {
|
|
34
|
+
const text = String(part.text);
|
|
35
|
+
msgTokens += encode(text);
|
|
36
|
+
msgChars += text.length;
|
|
37
|
+
}
|
|
38
|
+
if (part.type === 'tool-result' && part.output) {
|
|
39
|
+
let outputText = '';
|
|
40
|
+
if (typeof part.output === 'string') {
|
|
41
|
+
outputText = part.output;
|
|
42
|
+
} else if (part.output && part.output.value) {
|
|
43
|
+
outputText = String(part.output.value);
|
|
44
|
+
} else if (part.output && part.output.html) {
|
|
45
|
+
outputText = part.output.html;
|
|
46
|
+
} else if (part.output) {
|
|
47
|
+
outputText = JSON.stringify(part.output);
|
|
48
|
+
}
|
|
49
|
+
msgTokens += encode(outputText);
|
|
50
|
+
msgChars += outputText.length;
|
|
51
|
+
}
|
|
52
|
+
if (part.type === 'tool_use' && part.input) {
|
|
53
|
+
const inputStr = JSON.stringify(part.input);
|
|
54
|
+
msgTokens += encode(inputStr);
|
|
55
|
+
msgChars += inputStr.length;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
} else if (msg.content && typeof msg.content === 'object') {
|
|
59
|
+
try {
|
|
60
|
+
const str = JSON.stringify(msg.content);
|
|
61
|
+
msgTokens += encode(str);
|
|
62
|
+
msgChars += str.length;
|
|
63
|
+
} catch (e) {}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
totalTokens += msgTokens;
|
|
67
|
+
totalChars += msgChars;
|
|
68
|
+
|
|
69
|
+
if (msgTokens > 3000) {
|
|
70
|
+
largeMessages.push({ index: i, role: msg.role, tokens: msgTokens, chars: msgChars });
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
console.log('Messages:', messages.length);
|
|
75
|
+
console.log('Total chars:', totalChars);
|
|
76
|
+
console.log('Total tokens (approx):', totalTokens);
|
|
77
|
+
console.log('File size:', fs.statSync(filePath).size, 'bytes');
|
|
78
|
+
console.log('\nLarge messages (>3000 tokens):');
|
|
79
|
+
largeMessages.forEach(m => {
|
|
80
|
+
console.log(` [${m.index}] ${m.role}: ${m.tokens} tokens, ${m.chars} chars`);
|
|
81
|
+
});
|
package/cli/src/commands/chat.js
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -23,6 +23,52 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
23
23
|
this._extensions = new Map();
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* 从 JSON Schema 构建 Zod Schema
|
|
28
|
+
* @param {Object} jsonSchema - JSON Schema 对象
|
|
29
|
+
* @returns {z.ZodObject}
|
|
30
|
+
*/
|
|
31
|
+
_buildZodSchema(jsonSchema) {
|
|
32
|
+
const properties = jsonSchema.properties || {};
|
|
33
|
+
const required = jsonSchema.required || [];
|
|
34
|
+
const shape = {};
|
|
35
|
+
|
|
36
|
+
for (const [name, prop] of Object.entries(properties)) {
|
|
37
|
+
let field;
|
|
38
|
+
const isRequired = required.includes(name);
|
|
39
|
+
|
|
40
|
+
switch (prop.type) {
|
|
41
|
+
case 'string':
|
|
42
|
+
field = z.string();
|
|
43
|
+
break;
|
|
44
|
+
case 'number':
|
|
45
|
+
field = z.number();
|
|
46
|
+
break;
|
|
47
|
+
case 'boolean':
|
|
48
|
+
field = z.boolean();
|
|
49
|
+
break;
|
|
50
|
+
case 'array':
|
|
51
|
+
field = z.array(z.any());
|
|
52
|
+
break;
|
|
53
|
+
case 'object':
|
|
54
|
+
field = z.object({});
|
|
55
|
+
break;
|
|
56
|
+
default:
|
|
57
|
+
field = z.any();
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (prop.description) {
|
|
61
|
+
field = field.describe(prop.description);
|
|
62
|
+
}
|
|
63
|
+
if (!isRequired) {
|
|
64
|
+
field = field.optional();
|
|
65
|
+
}
|
|
66
|
+
shape[name] = field;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
return z.object(shape);
|
|
70
|
+
}
|
|
71
|
+
|
|
26
72
|
install(framework) {
|
|
27
73
|
this._framework = framework;
|
|
28
74
|
|
|
@@ -142,7 +188,35 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
142
188
|
|
|
143
189
|
const toolDef = ext.tools.find((t) => t.name === tool);
|
|
144
190
|
if (!toolDef) {
|
|
145
|
-
|
|
191
|
+
const availableTools = ext.tools.map((t) => t.name).join(', ');
|
|
192
|
+
return {
|
|
193
|
+
success: false,
|
|
194
|
+
error: `扩展工具 '${tool}' 不存在。可用工具: ${availableTools || '无'}`
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// 验证参数
|
|
199
|
+
if (toolDef.inputSchema) {
|
|
200
|
+
try {
|
|
201
|
+
const schema = toolDef.inputSchema instanceof z.ZodType
|
|
202
|
+
? toolDef.inputSchema
|
|
203
|
+
: this._buildZodSchema(toolDef.inputSchema);
|
|
204
|
+
schema.parse(toolArgs);
|
|
205
|
+
} catch (err) {
|
|
206
|
+
if (err instanceof z.ZodError) {
|
|
207
|
+
const fieldErrors = err.errors.map((e) => `${e.path.join('.')}: ${e.message}`).join('; ');
|
|
208
|
+
return {
|
|
209
|
+
success: false,
|
|
210
|
+
error: `参数错误: ${fieldErrors}`,
|
|
211
|
+
inputSchema: toolDef.inputSchema,
|
|
212
|
+
};
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
success: false,
|
|
216
|
+
error: `参数验证失败: ${err.message}`,
|
|
217
|
+
inputSchema: toolDef.inputSchema,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
146
220
|
}
|
|
147
221
|
|
|
148
222
|
try {
|
|
@@ -220,7 +294,11 @@ class ExtensionExecutorPlugin extends Plugin {
|
|
|
220
294
|
|
|
221
295
|
const toolDef = ext.tools.find((t) => t.name === tool);
|
|
222
296
|
if (!toolDef) {
|
|
223
|
-
|
|
297
|
+
const availableTools = ext.tools.map((t) => t.name).join(', ');
|
|
298
|
+
return {
|
|
299
|
+
success: false,
|
|
300
|
+
error: `扩展工具 '${tool}' 不存在。可用工具: ${availableTools || '无'}`
|
|
301
|
+
};
|
|
224
302
|
}
|
|
225
303
|
|
|
226
304
|
return {
|
|
@@ -827,10 +827,10 @@ class FileSystemPlugin extends Plugin {
|
|
|
827
827
|
timeout: z.number().optional().describe('超时时间(ms),默认 30000'),
|
|
828
828
|
proxy: z.boolean().optional().describe('是否使用代理,默认 false。访问失败时可自动设为 true 重试'),
|
|
829
829
|
toMarkdown: z.boolean().default(true).describe('是否将 HTML 响应转换为 Markdown 格式,默认 true'),
|
|
830
|
-
maxLength: z.number().
|
|
830
|
+
maxLength: z.number().default(50000).describe('最大返回长度(字符数),超过则截断,默认 50000')
|
|
831
831
|
}),
|
|
832
832
|
execute: async (args, framework) => {
|
|
833
|
-
const { url, method = 'GET', headers = {}, body, timeout = 30000, proxy = false, toMarkdown = true, maxLength } = args
|
|
833
|
+
const { url, method = 'GET', headers = {}, body, timeout = 30000, proxy = false, toMarkdown = true, maxLength = 50000 } = args
|
|
834
834
|
try {
|
|
835
835
|
const controller = new AbortController()
|
|
836
836
|
const timeoutId = setTimeout(() => controller.abort(), timeout)
|
package/plugins/weixin-plugin.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* - forceLogin: 是否强制重新扫码登录
|
|
7
7
|
* - qrcodeTerminal: 是否在终端渲染二维码 (默认 true)
|
|
8
8
|
*/
|
|
9
|
-
|
|
9
|
+
const { CLEAR_LINE, CYAN, DIM, GREEN, RED, YELLOW, colored } = require('../cli/src/utils/ansi');
|
|
10
10
|
const { Plugin } = require('../src/core/plugin-base')
|
|
11
11
|
const { logger } = require('../src/utils/logger')
|
|
12
12
|
const log = logger.child('WeChat')
|
|
@@ -468,11 +468,14 @@ class WeixinPlugin extends Plugin {
|
|
|
468
468
|
|
|
469
469
|
try {
|
|
470
470
|
// 使用 chatStream 保持和 CLI 一致的行为
|
|
471
|
-
|
|
472
471
|
let fullResponse = '';
|
|
473
472
|
for await (const chunk of agent.chatStream(text, { sessionId })) {
|
|
474
473
|
if (chunk.type === 'text') {
|
|
475
474
|
fullResponse += chunk.text;
|
|
475
|
+
} else if (chunk.type === 'tool-call') {
|
|
476
|
+
log.info(`[工具调用] ${chunk.toolName}`);
|
|
477
|
+
} else if (chunk.type === 'error') {
|
|
478
|
+
log.warn(' Chat stream error:', chunk.error);
|
|
476
479
|
}
|
|
477
480
|
}
|
|
478
481
|
const response = cleanResponse(fullResponse);
|
|
@@ -516,6 +519,11 @@ class WeixinPlugin extends Plugin {
|
|
|
516
519
|
for await (const chunk of agent.chatStream(text, { sessionId })) {
|
|
517
520
|
if (chunk.type === 'text') {
|
|
518
521
|
fullResponse += chunk.text;
|
|
522
|
+
} else if (chunk.type === 'tool-call') {
|
|
523
|
+
// 发送工具调用提示
|
|
524
|
+
log.info(`[工具调用] ${chunk.toolName}`);
|
|
525
|
+
} else if (chunk.type === 'error') {
|
|
526
|
+
log.warn(' Chat stream error:', chunk.error);
|
|
519
527
|
}
|
|
520
528
|
}
|
|
521
529
|
const response = cleanResponse(fullResponse);
|
|
@@ -1,162 +1,162 @@
|
|
|
1
|
-
# AGENTS.md
|
|
2
|
-
|
|
3
|
-
This file provides guidance to AI coding agents working on the `skills` CLI codebase.
|
|
4
|
-
|
|
5
|
-
## Project Overview
|
|
6
|
-
|
|
7
|
-
`skills` is the CLI for the open agent skills ecosystem.
|
|
8
|
-
|
|
9
|
-
## Commands
|
|
10
|
-
|
|
11
|
-
| Command | Description |
|
|
12
|
-
| ----------------------------- | --------------------------------------------------- |
|
|
13
|
-
| `skills` | Show banner with available commands |
|
|
14
|
-
| `skills add <pkg>` | Install skills from git repos, URLs, or local paths |
|
|
15
|
-
| `skills experimental_install` | Restore skills from skills-lock.json |
|
|
16
|
-
| `skills experimental_sync` | Sync skills from node_modules into agent dirs |
|
|
17
|
-
| `skills list` | List installed skills (alias: `ls`) |
|
|
18
|
-
| `skills check` | Check for available skill updates |
|
|
19
|
-
| `skills update` | Update all skills to latest versions |
|
|
20
|
-
| `skills init [name]` | Create a new SKILL.md template |
|
|
21
|
-
|
|
22
|
-
Aliases: `skills a` works for `add`. `skills i`, `skills install` (no args) restore from `skills-lock.json`. `skills ls` works for `list`. `skills experimental_install` restores from `skills-lock.json`. `skills experimental_sync` crawls `node_modules` for skills.
|
|
23
|
-
|
|
24
|
-
## Architecture
|
|
25
|
-
|
|
26
|
-
```
|
|
27
|
-
src/
|
|
28
|
-
├── cli.ts # Main entry point, command routing, init/check/update
|
|
29
|
-
├── cli.test.ts # CLI tests
|
|
30
|
-
├── add.ts # Core add command logic
|
|
31
|
-
├── add.test.ts # Add command tests
|
|
32
|
-
├── list.ts # List installed skills command
|
|
33
|
-
├── list.test.ts # List command tests
|
|
34
|
-
├── agents.ts # Agent definitions and detection
|
|
35
|
-
├── installer.ts # Skill installation logic (symlink/copy) + listInstalledSkills
|
|
36
|
-
├── skills.ts # Skill discovery and parsing
|
|
37
|
-
├── skill-lock.ts # Global lock file management (~/.agents/.skill-lock.json)
|
|
38
|
-
├── local-lock.ts # Local lock file management (skills-lock.json, checked in)
|
|
39
|
-
├── sync.ts # Sync command - crawl node_modules for skills
|
|
40
|
-
├── source-parser.ts # Parse git URLs, GitHub shorthand, local paths
|
|
41
|
-
├── git.ts # Git clone operations
|
|
42
|
-
├── telemetry.ts # Anonymous usage tracking
|
|
43
|
-
├── types.ts # TypeScript types
|
|
44
|
-
├── mintlify.ts # Mintlify skill fetching (legacy)
|
|
45
|
-
├── providers/ # Remote skill providers (GitHub, HuggingFace, Mintlify)
|
|
46
|
-
│ ├── index.ts
|
|
47
|
-
│ ├── registry.ts
|
|
48
|
-
│ ├── types.ts
|
|
49
|
-
│ ├── huggingface.ts
|
|
50
|
-
│ └── mintlify.ts
|
|
51
|
-
├── init.test.ts # Init command tests
|
|
52
|
-
└── test-utils.ts # Test utilities
|
|
53
|
-
|
|
54
|
-
tests/
|
|
55
|
-
├── sanitize-name.test.ts # Tests for sanitizeName (path traversal prevention)
|
|
56
|
-
├── skill-matching.test.ts # Tests for filterSkills (multi-word skill name matching)
|
|
57
|
-
├── source-parser.test.ts # Tests for URL/path parsing
|
|
58
|
-
├── installer-symlink.test.ts # Tests for symlink installation
|
|
59
|
-
├── list-installed.test.ts # Tests for listing installed skills
|
|
60
|
-
├── skill-path.test.ts # Tests for skill path handling
|
|
61
|
-
├── wellknown-provider.test.ts # Tests for well-known provider
|
|
62
|
-
└── dist.test.ts # Tests for built distribution
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
## Update Checking System
|
|
66
|
-
|
|
67
|
-
### How `skills check` and `skills update` Work
|
|
68
|
-
|
|
69
|
-
1. Read `~/.agents/.skill-lock.json` for installed skills
|
|
70
|
-
2. For each skill, get `skillFolderHash` from lock file
|
|
71
|
-
3. POST to `https://add-skill.vercel.sh/check-updates` with:
|
|
72
|
-
```json
|
|
73
|
-
{
|
|
74
|
-
"skills": [{ "name": "...", "source": "...", "skillFolderHash": "..." }],
|
|
75
|
-
"forceRefresh": true
|
|
76
|
-
}
|
|
77
|
-
```
|
|
78
|
-
4. API fetches fresh content from GitHub, computes hash, compares
|
|
79
|
-
5. Returns list of skills with different hashes (updates available)
|
|
80
|
-
|
|
81
|
-
### Why `forceRefresh: true`?
|
|
82
|
-
|
|
83
|
-
Both `check` and `update` always send `forceRefresh: true`. This ensures the API fetches fresh content from GitHub rather than using its Redis cache.
|
|
84
|
-
|
|
85
|
-
**Without forceRefresh:** Users saw phantom "updates available" due to stale cached hashes. The fix was to always fetch fresh.
|
|
86
|
-
|
|
87
|
-
**Tradeoff:** Slightly slower (GitHub API call per skill), but always accurate.
|
|
88
|
-
|
|
89
|
-
### Lock File Compatibility
|
|
90
|
-
|
|
91
|
-
The lock file format is v3. Key field: `skillFolderHash` (GitHub tree SHA for the skill folder).
|
|
92
|
-
|
|
93
|
-
If reading an older lock file version, it's wiped. Users must reinstall skills to populate the new format.
|
|
94
|
-
|
|
95
|
-
## Key Integration Points
|
|
96
|
-
|
|
97
|
-
| Feature | Implementation |
|
|
98
|
-
| -------------------------- | ------------------------------------------- |
|
|
99
|
-
| `skills add` | `src/add.ts` - full implementation |
|
|
100
|
-
| `skills experimental_sync` | `src/sync.ts` - crawl node_modules |
|
|
101
|
-
| `skills check` | `POST /check-updates` API |
|
|
102
|
-
| `skills update` | `POST /check-updates` + reinstall per skill |
|
|
103
|
-
|
|
104
|
-
## Development
|
|
105
|
-
|
|
106
|
-
```bash
|
|
107
|
-
# Install dependencies
|
|
108
|
-
pnpm install
|
|
109
|
-
|
|
110
|
-
# Build
|
|
111
|
-
pnpm build
|
|
112
|
-
|
|
113
|
-
# Test locally
|
|
114
|
-
pnpm dev add vercel-labs/agent-skills --list
|
|
115
|
-
pnpm dev experimental_sync
|
|
116
|
-
pnpm dev check
|
|
117
|
-
pnpm dev update
|
|
118
|
-
pnpm dev init my-skill
|
|
119
|
-
|
|
120
|
-
# Run all tests
|
|
121
|
-
pnpm test
|
|
122
|
-
|
|
123
|
-
# Run specific test file(s)
|
|
124
|
-
pnpm test tests/sanitize-name.test.ts
|
|
125
|
-
pnpm test tests/skill-matching.test.ts tests/source-parser.test.ts
|
|
126
|
-
|
|
127
|
-
# Type check
|
|
128
|
-
pnpm type-check
|
|
129
|
-
|
|
130
|
-
# Format code
|
|
131
|
-
pnpm format
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## Code Style
|
|
135
|
-
|
|
136
|
-
This project uses Prettier for code formatting. **Always run `pnpm format` before committing changes** to ensure consistent formatting.
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
# Format all files
|
|
140
|
-
pnpm format
|
|
141
|
-
|
|
142
|
-
# Check formatting without fixing
|
|
143
|
-
pnpm prettier --check .
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
CI will fail if code is not properly formatted.
|
|
147
|
-
|
|
148
|
-
## Publishing
|
|
149
|
-
|
|
150
|
-
```bash
|
|
151
|
-
# 1. Bump version in package.json
|
|
152
|
-
# 2. Build
|
|
153
|
-
pnpm build
|
|
154
|
-
# 3. Publish
|
|
155
|
-
npm publish
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Adding a New Agent
|
|
159
|
-
|
|
160
|
-
1. Add the agent definition to `src/agents.ts`
|
|
161
|
-
2. Run `pnpm run -C scripts validate-agents.ts` to validate
|
|
162
|
-
3. Run `pnpm run -C scripts sync-agents.ts` to update README.md
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to AI coding agents working on the `skills` CLI codebase.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
`skills` is the CLI for the open agent skills ecosystem.
|
|
8
|
+
|
|
9
|
+
## Commands
|
|
10
|
+
|
|
11
|
+
| Command | Description |
|
|
12
|
+
| ----------------------------- | --------------------------------------------------- |
|
|
13
|
+
| `skills` | Show banner with available commands |
|
|
14
|
+
| `skills add <pkg>` | Install skills from git repos, URLs, or local paths |
|
|
15
|
+
| `skills experimental_install` | Restore skills from skills-lock.json |
|
|
16
|
+
| `skills experimental_sync` | Sync skills from node_modules into agent dirs |
|
|
17
|
+
| `skills list` | List installed skills (alias: `ls`) |
|
|
18
|
+
| `skills check` | Check for available skill updates |
|
|
19
|
+
| `skills update` | Update all skills to latest versions |
|
|
20
|
+
| `skills init [name]` | Create a new SKILL.md template |
|
|
21
|
+
|
|
22
|
+
Aliases: `skills a` works for `add`. `skills i`, `skills install` (no args) restore from `skills-lock.json`. `skills ls` works for `list`. `skills experimental_install` restores from `skills-lock.json`. `skills experimental_sync` crawls `node_modules` for skills.
|
|
23
|
+
|
|
24
|
+
## Architecture
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
src/
|
|
28
|
+
├── cli.ts # Main entry point, command routing, init/check/update
|
|
29
|
+
├── cli.test.ts # CLI tests
|
|
30
|
+
├── add.ts # Core add command logic
|
|
31
|
+
├── add.test.ts # Add command tests
|
|
32
|
+
├── list.ts # List installed skills command
|
|
33
|
+
├── list.test.ts # List command tests
|
|
34
|
+
├── agents.ts # Agent definitions and detection
|
|
35
|
+
├── installer.ts # Skill installation logic (symlink/copy) + listInstalledSkills
|
|
36
|
+
├── skills.ts # Skill discovery and parsing
|
|
37
|
+
├── skill-lock.ts # Global lock file management (~/.agents/.skill-lock.json)
|
|
38
|
+
├── local-lock.ts # Local lock file management (skills-lock.json, checked in)
|
|
39
|
+
├── sync.ts # Sync command - crawl node_modules for skills
|
|
40
|
+
├── source-parser.ts # Parse git URLs, GitHub shorthand, local paths
|
|
41
|
+
├── git.ts # Git clone operations
|
|
42
|
+
├── telemetry.ts # Anonymous usage tracking
|
|
43
|
+
├── types.ts # TypeScript types
|
|
44
|
+
├── mintlify.ts # Mintlify skill fetching (legacy)
|
|
45
|
+
├── providers/ # Remote skill providers (GitHub, HuggingFace, Mintlify)
|
|
46
|
+
│ ├── index.ts
|
|
47
|
+
│ ├── registry.ts
|
|
48
|
+
│ ├── types.ts
|
|
49
|
+
│ ├── huggingface.ts
|
|
50
|
+
│ └── mintlify.ts
|
|
51
|
+
├── init.test.ts # Init command tests
|
|
52
|
+
└── test-utils.ts # Test utilities
|
|
53
|
+
|
|
54
|
+
tests/
|
|
55
|
+
├── sanitize-name.test.ts # Tests for sanitizeName (path traversal prevention)
|
|
56
|
+
├── skill-matching.test.ts # Tests for filterSkills (multi-word skill name matching)
|
|
57
|
+
├── source-parser.test.ts # Tests for URL/path parsing
|
|
58
|
+
├── installer-symlink.test.ts # Tests for symlink installation
|
|
59
|
+
├── list-installed.test.ts # Tests for listing installed skills
|
|
60
|
+
├── skill-path.test.ts # Tests for skill path handling
|
|
61
|
+
├── wellknown-provider.test.ts # Tests for well-known provider
|
|
62
|
+
└── dist.test.ts # Tests for built distribution
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Update Checking System
|
|
66
|
+
|
|
67
|
+
### How `skills check` and `skills update` Work
|
|
68
|
+
|
|
69
|
+
1. Read `~/.agents/.skill-lock.json` for installed skills
|
|
70
|
+
2. For each skill, get `skillFolderHash` from lock file
|
|
71
|
+
3. POST to `https://add-skill.vercel.sh/check-updates` with:
|
|
72
|
+
```json
|
|
73
|
+
{
|
|
74
|
+
"skills": [{ "name": "...", "source": "...", "skillFolderHash": "..." }],
|
|
75
|
+
"forceRefresh": true
|
|
76
|
+
}
|
|
77
|
+
```
|
|
78
|
+
4. API fetches fresh content from GitHub, computes hash, compares
|
|
79
|
+
5. Returns list of skills with different hashes (updates available)
|
|
80
|
+
|
|
81
|
+
### Why `forceRefresh: true`?
|
|
82
|
+
|
|
83
|
+
Both `check` and `update` always send `forceRefresh: true`. This ensures the API fetches fresh content from GitHub rather than using its Redis cache.
|
|
84
|
+
|
|
85
|
+
**Without forceRefresh:** Users saw phantom "updates available" due to stale cached hashes. The fix was to always fetch fresh.
|
|
86
|
+
|
|
87
|
+
**Tradeoff:** Slightly slower (GitHub API call per skill), but always accurate.
|
|
88
|
+
|
|
89
|
+
### Lock File Compatibility
|
|
90
|
+
|
|
91
|
+
The lock file format is v3. Key field: `skillFolderHash` (GitHub tree SHA for the skill folder).
|
|
92
|
+
|
|
93
|
+
If reading an older lock file version, it's wiped. Users must reinstall skills to populate the new format.
|
|
94
|
+
|
|
95
|
+
## Key Integration Points
|
|
96
|
+
|
|
97
|
+
| Feature | Implementation |
|
|
98
|
+
| -------------------------- | ------------------------------------------- |
|
|
99
|
+
| `skills add` | `src/add.ts` - full implementation |
|
|
100
|
+
| `skills experimental_sync` | `src/sync.ts` - crawl node_modules |
|
|
101
|
+
| `skills check` | `POST /check-updates` API |
|
|
102
|
+
| `skills update` | `POST /check-updates` + reinstall per skill |
|
|
103
|
+
|
|
104
|
+
## Development
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Install dependencies
|
|
108
|
+
pnpm install
|
|
109
|
+
|
|
110
|
+
# Build
|
|
111
|
+
pnpm build
|
|
112
|
+
|
|
113
|
+
# Test locally
|
|
114
|
+
pnpm dev add vercel-labs/agent-skills --list
|
|
115
|
+
pnpm dev experimental_sync
|
|
116
|
+
pnpm dev check
|
|
117
|
+
pnpm dev update
|
|
118
|
+
pnpm dev init my-skill
|
|
119
|
+
|
|
120
|
+
# Run all tests
|
|
121
|
+
pnpm test
|
|
122
|
+
|
|
123
|
+
# Run specific test file(s)
|
|
124
|
+
pnpm test tests/sanitize-name.test.ts
|
|
125
|
+
pnpm test tests/skill-matching.test.ts tests/source-parser.test.ts
|
|
126
|
+
|
|
127
|
+
# Type check
|
|
128
|
+
pnpm type-check
|
|
129
|
+
|
|
130
|
+
# Format code
|
|
131
|
+
pnpm format
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
## Code Style
|
|
135
|
+
|
|
136
|
+
This project uses Prettier for code formatting. **Always run `pnpm format` before committing changes** to ensure consistent formatting.
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
# Format all files
|
|
140
|
+
pnpm format
|
|
141
|
+
|
|
142
|
+
# Check formatting without fixing
|
|
143
|
+
pnpm prettier --check .
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
CI will fail if code is not properly formatted.
|
|
147
|
+
|
|
148
|
+
## Publishing
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
# 1. Bump version in package.json
|
|
152
|
+
# 2. Build
|
|
153
|
+
pnpm build
|
|
154
|
+
# 3. Publish
|
|
155
|
+
npm publish
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
## Adding a New Agent
|
|
159
|
+
|
|
160
|
+
1. Add the agent definition to `src/agents.ts`
|
|
161
|
+
2. Run `pnpm run -C scripts validate-agents.ts` to validate
|
|
162
|
+
3. Run `pnpm run -C scripts sync-agents.ts` to update README.md
|