@rotifer/playground 0.5.0-alpha.2 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +159 -15
- package/LICENSE +1 -1
- package/README.md +51 -23
- package/README.zh.md +54 -25
- package/dist/cloud/auth.d.ts +7 -1
- package/dist/cloud/auth.d.ts.map +1 -1
- package/dist/cloud/auth.js +65 -1
- package/dist/cloud/auth.js.map +1 -1
- package/dist/cloud/client.d.ts +4 -1
- package/dist/cloud/client.d.ts.map +1 -1
- package/dist/cloud/client.js +9 -2
- package/dist/cloud/client.js.map +1 -1
- package/dist/cloud/types.d.ts +3 -1
- package/dist/cloud/types.d.ts.map +1 -1
- package/dist/cloud/types.js.map +1 -1
- package/dist/commands/agent-create.d.ts.map +1 -1
- package/dist/commands/agent-create.js +66 -3
- package/dist/commands/agent-create.js.map +1 -1
- package/dist/commands/agent-run.d.ts.map +1 -1
- package/dist/commands/agent-run.js +296 -32
- package/dist/commands/agent-run.js.map +1 -1
- package/dist/commands/arena-submit.d.ts.map +1 -1
- package/dist/commands/arena-submit.js +45 -17
- package/dist/commands/arena-submit.js.map +1 -1
- package/dist/commands/compile.d.ts.map +1 -1
- package/dist/commands/compile.js +9 -3
- package/dist/commands/compile.js.map +1 -1
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +13 -3
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +23 -16
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/network.js +4 -4
- package/dist/commands/network.js.map +1 -1
- package/dist/commands/publish.d.ts.map +1 -1
- package/dist/commands/publish.js +162 -44
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/test.d.ts.map +1 -1
- package/dist/commands/test.js +209 -23
- package/dist/commands/test.js.map +1 -1
- package/dist/commands/wrap.d.ts.map +1 -1
- package/dist/commands/wrap.js +17 -1
- package/dist/commands/wrap.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/runtime/network-gateway.d.ts +53 -0
- package/dist/runtime/network-gateway.d.ts.map +1 -0
- package/dist/runtime/network-gateway.js +147 -0
- package/dist/runtime/network-gateway.js.map +1 -0
- package/dist/utils/binding.d.ts +25 -0
- package/dist/utils/binding.d.ts.map +1 -1
- package/dist/utils/binding.js.map +1 -1
- package/dist/utils/open-browser.d.ts +10 -0
- package/dist/utils/open-browser.d.ts.map +1 -0
- package/dist/utils/open-browser.js +23 -0
- package/dist/utils/open-browser.js.map +1 -0
- package/genes/academic-writer/.cloud-manifest.json +6 -0
- package/genes/academic-writer/.gene-manifest.json +8 -0
- package/genes/academic-writer/SKILL.md +274 -0
- package/genes/academic-writer/phenotype.json +28 -0
- package/genes/ai-components/.cloud-manifest.json +6 -0
- package/genes/ai-components/.gene-manifest.json +8 -0
- package/genes/ai-components/SKILL.md +381 -0
- package/genes/ai-components/phenotype.json +28 -0
- package/genes/algorithmic-art/.cloud-manifest.json +6 -0
- package/genes/algorithmic-art/.gene-manifest.json +8 -0
- package/genes/algorithmic-art/SKILL.md +405 -0
- package/genes/algorithmic-art/phenotype.json +28 -0
- package/genes/answer-synthesizer/.cloud-manifest.json +6 -0
- package/genes/answer-synthesizer/index.ts +194 -0
- package/genes/answer-synthesizer/phenotype.json +61 -0
- package/genes/api-designer/.cloud-manifest.json +6 -0
- package/genes/api-designer/.gene-manifest.json +8 -0
- package/genes/api-designer/SKILL.md +456 -0
- package/genes/api-designer/phenotype.json +28 -0
- package/genes/auto-coder/.cloud-manifest.json +6 -0
- package/genes/auto-coder/.gene-manifest.json +8 -0
- package/genes/auto-coder/SKILL.md +400 -0
- package/genes/auto-coder/phenotype.json +28 -0
- package/genes/auto-writer/.cloud-manifest.json +6 -0
- package/genes/auto-writer/.gene-manifest.json +8 -0
- package/genes/auto-writer/SKILL.md +361 -0
- package/genes/auto-writer/phenotype.json +28 -0
- package/genes/brand-personality/.cloud-manifest.json +6 -0
- package/genes/brand-personality/.gene-manifest.json +8 -0
- package/genes/brand-personality/SKILL.md +549 -0
- package/genes/brand-personality/phenotype.json +28 -0
- package/genes/business-writer/.cloud-manifest.json +6 -0
- package/genes/business-writer/.gene-manifest.json +8 -0
- package/genes/business-writer/SKILL.md +448 -0
- package/genes/business-writer/phenotype.json +28 -0
- package/genes/citation-manager/.cloud-manifest.json +6 -0
- package/genes/citation-manager/.gene-manifest.json +8 -0
- package/genes/citation-manager/SKILL.md +279 -0
- package/genes/citation-manager/index.ts +162 -0
- package/genes/citation-manager/package.json +1 -0
- package/genes/citation-manager/phenotype.json +50 -0
- package/genes/code-complexity/.cloud-manifest.json +6 -0
- package/genes/code-complexity/README.md +35 -0
- package/genes/code-complexity/index.ts +101 -0
- package/genes/code-complexity/phenotype.json +34 -0
- package/genes/copywriter/.cloud-manifest.json +6 -0
- package/genes/copywriter/.gene-manifest.json +8 -0
- package/genes/copywriter/SKILL.md +329 -0
- package/genes/copywriter/phenotype.json +28 -0
- package/genes/creative-writer/.cloud-manifest.json +6 -0
- package/genes/creative-writer/.gene-manifest.json +8 -0
- package/genes/creative-writer/SKILL.md +356 -0
- package/genes/creative-writer/phenotype.json +28 -0
- package/genes/data-modeler/.cloud-manifest.json +6 -0
- package/genes/data-modeler/.gene-manifest.json +8 -0
- package/genes/data-modeler/SKILL.md +486 -0
- package/genes/data-modeler/phenotype.json +28 -0
- package/genes/debugger/.cloud-manifest.json +6 -0
- package/genes/debugger/.gene-manifest.json +8 -0
- package/genes/debugger/SKILL.md +416 -0
- package/genes/debugger/phenotype.json +28 -0
- package/genes/design-tokens/.cloud-manifest.json +6 -0
- package/genes/design-tokens/.gene-manifest.json +8 -0
- package/genes/design-tokens/SKILL.md +222 -0
- package/genes/design-tokens/index.ts +128 -0
- package/genes/design-tokens/package.json +1 -0
- package/genes/design-tokens/phenotype.json +1 -0
- package/genes/devops-automator/.cloud-manifest.json +6 -0
- package/genes/devops-automator/.gene-manifest.json +8 -0
- package/genes/devops-automator/SKILL.md +490 -0
- package/genes/devops-automator/phenotype.json +28 -0
- package/genes/doc-coauthoring/.cloud-manifest.json +6 -0
- package/genes/doc-coauthoring/.gene-manifest.json +8 -0
- package/genes/doc-coauthoring/SKILL.md +375 -0
- package/genes/doc-coauthoring/phenotype.json +28 -0
- package/genes/doc-retrieval/.cloud-manifest.json +6 -0
- package/genes/doc-retrieval/index.ts +134 -0
- package/genes/doc-retrieval/phenotype.json +54 -0
- package/genes/docs-writer/.cloud-manifest.json +6 -0
- package/genes/docs-writer/.gene-manifest.json +8 -0
- package/genes/docs-writer/SKILL.md +492 -0
- package/genes/docs-writer/phenotype.json +28 -0
- package/genes/evolve-life/.cloud-manifest.json +6 -0
- package/genes/evolve-life/.compile-result.json +12 -0
- package/genes/evolve-life/README.md +52 -0
- package/genes/evolve-life/gene.ir.wasm +0 -0
- package/genes/evolve-life/gene.wasm +0 -0
- package/genes/evolve-life/index.ts +255 -0
- package/genes/evolve-life/phenotype.json +129 -0
- package/genes/evolve-life-bitwise/.cloud-manifest.json +6 -0
- package/genes/evolve-life-bitwise/.compile-result.json +12 -0
- package/genes/evolve-life-bitwise/gene.ir.wasm +0 -0
- package/genes/evolve-life-bitwise/gene.wasm +0 -0
- package/genes/evolve-life-bitwise/index.ts +273 -0
- package/genes/evolve-life-bitwise/phenotype.json +129 -0
- package/genes/evolve-life-sparse/.cloud-manifest.json +6 -0
- package/genes/evolve-life-sparse/.compile-result.json +12 -0
- package/genes/evolve-life-sparse/gene.ir.wasm +0 -0
- package/genes/evolve-life-sparse/gene.wasm +0 -0
- package/genes/evolve-life-sparse/index.ts +236 -0
- package/genes/evolve-life-sparse/phenotype.json +129 -0
- package/genes/fact-checker/.cloud-manifest.json +6 -0
- package/genes/fact-checker/.gene-manifest.json +8 -0
- package/genes/fact-checker/SKILL.md +373 -0
- package/genes/fact-checker/phenotype.json +28 -0
- package/genes/genesis-code-format/.cloud-manifest.json +6 -0
- package/genes/genesis-code-format/package.json +1 -0
- package/genes/genesis-code-format/phenotype.json +1 -0
- package/genes/genesis-file-read/.cloud-manifest.json +6 -0
- package/genes/genesis-file-read/index.ts +11 -1
- package/genes/genesis-file-read/package.json +1 -0
- package/genes/genesis-file-read/phenotype.json +1 -0
- package/genes/genesis-l0-constraint/.cloud-manifest.json +6 -0
- package/genes/genesis-l0-constraint/package.json +1 -0
- package/genes/genesis-l0-constraint/phenotype.json +1 -0
- package/genes/genesis-web-search/.cloud-manifest.json +2 -2
- package/genes/genesis-web-search/package.json +1 -0
- package/genes/genesis-web-search/phenotype.json +1 -0
- package/genes/genesis-web-search-lite/.cloud-manifest.json +6 -0
- package/genes/genesis-web-search-lite/package.json +1 -0
- package/genes/genesis-web-search-lite/phenotype.json +1 -0
- package/genes/git-workflow/.cloud-manifest.json +6 -0
- package/genes/git-workflow/.gene-manifest.json +8 -0
- package/genes/git-workflow/SKILL.md +407 -0
- package/genes/git-workflow/phenotype.json +28 -0
- package/genes/grammar-checker/.cloud-manifest.json +6 -0
- package/genes/grammar-checker/.gene-manifest.json +8 -0
- package/genes/grammar-checker/SKILL.md +194 -0
- package/genes/grammar-checker/index.ts +168 -0
- package/genes/grammar-checker/package.json +1 -0
- package/genes/grammar-checker/phenotype.json +52 -0
- package/genes/json-validator/.cloud-manifest.json +6 -0
- package/genes/json-validator/README.md +42 -0
- package/genes/json-validator/index.ts +112 -0
- package/genes/json-validator/phenotype.json +42 -0
- package/genes/license-advisor/.cloud-manifest.json +6 -0
- package/genes/license-advisor/.gene-manifest.json +8 -0
- package/genes/license-advisor/SKILL.md +117 -0
- package/genes/license-advisor/phenotype.json +28 -0
- package/genes/logic-architect/.cloud-manifest.json +6 -0
- package/genes/logic-architect/.gene-manifest.json +8 -0
- package/genes/logic-architect/SKILL.md +451 -0
- package/genes/logic-architect/phenotype.json +28 -0
- package/genes/markdown-formatter/.cloud-manifest.json +6 -0
- package/genes/markdown-formatter/README.md +34 -0
- package/genes/markdown-formatter/index.ts +86 -0
- package/genes/markdown-formatter/phenotype.json +32 -0
- package/genes/orch/.cloud-manifest.json +6 -0
- package/genes/orch/.gene-manifest.json +8 -0
- package/genes/orch/SKILL.md +504 -0
- package/genes/orch/phenotype.json +28 -0
- package/genes/particle-barneshut/.cloud-manifest.json +6 -0
- package/genes/particle-barneshut/.compile-result.json +12 -0
- package/genes/particle-barneshut/README.md +55 -0
- package/genes/particle-barneshut/gene.ir.wasm +0 -0
- package/genes/particle-barneshut/gene.wasm +0 -0
- package/genes/particle-barneshut/index.ts +486 -0
- package/genes/particle-barneshut/phenotype.json +137 -0
- package/genes/particle-brute/.cloud-manifest.json +6 -0
- package/genes/particle-brute/.compile-result.json +12 -0
- package/genes/particle-brute/README.md +55 -0
- package/genes/particle-brute/gene.ir.wasm +0 -0
- package/genes/particle-brute/gene.wasm +0 -0
- package/genes/particle-brute/index.ts +277 -0
- package/genes/particle-brute/phenotype.json +137 -0
- package/genes/particle-spatial/.cloud-manifest.json +6 -0
- package/genes/particle-spatial/.compile-result.json +12 -0
- package/genes/particle-spatial/README.md +53 -0
- package/genes/particle-spatial/gene.ir.wasm +0 -0
- package/genes/particle-spatial/gene.wasm +0 -0
- package/genes/particle-spatial/index.ts +352 -0
- package/genes/particle-spatial/phenotype.json +137 -0
- package/genes/performance-optimizer/.cloud-manifest.json +6 -0
- package/genes/performance-optimizer/.gene-manifest.json +8 -0
- package/genes/performance-optimizer/SKILL.md +480 -0
- package/genes/performance-optimizer/phenotype.json +28 -0
- package/genes/plagiarism-checker/.cloud-manifest.json +6 -0
- package/genes/plagiarism-checker/.gene-manifest.json +8 -0
- package/genes/plagiarism-checker/SKILL.md +342 -0
- package/genes/plagiarism-checker/phenotype.json +28 -0
- package/genes/product-manager/.cloud-manifest.json +6 -0
- package/genes/product-manager/.gene-manifest.json +8 -0
- package/genes/product-manager/SKILL.md +249 -0
- package/genes/product-manager/phenotype.json +28 -0
- package/genes/project-reviewer/.cloud-manifest.json +6 -0
- package/genes/project-reviewer/.gene-manifest.json +8 -0
- package/genes/project-reviewer/SKILL.md +312 -0
- package/genes/project-reviewer/phenotype.json +28 -0
- package/genes/prompt-engineer/.cloud-manifest.json +6 -0
- package/genes/prompt-engineer/.gene-manifest.json +8 -0
- package/genes/prompt-engineer/SKILL.md +411 -0
- package/genes/prompt-engineer/phenotype.json +28 -0
- package/genes/readability-analyzer/.cloud-manifest.json +6 -0
- package/genes/readability-analyzer/.gene-manifest.json +8 -0
- package/genes/readability-analyzer/SKILL.md +357 -0
- package/genes/readability-analyzer/index.ts +123 -0
- package/genes/readability-analyzer/package.json +1 -0
- package/genes/readability-analyzer/phenotype.json +35 -0
- package/genes/rotifer-protocol/SKILL.md +121 -0
- package/genes/security-auditor/.cloud-manifest.json +6 -0
- package/genes/security-auditor/.gene-manifest.json +8 -0
- package/genes/security-auditor/SKILL.md +494 -0
- package/genes/security-auditor/phenotype.json +28 -0
- package/genes/seo-optimizer/.cloud-manifest.json +6 -0
- package/genes/seo-optimizer/.gene-manifest.json +8 -0
- package/genes/seo-optimizer/SKILL.md +327 -0
- package/genes/seo-optimizer/index.ts +206 -0
- package/genes/seo-optimizer/package.json +1 -0
- package/genes/seo-optimizer/phenotype.json +1 -0
- package/genes/source-linker/.cloud-manifest.json +6 -0
- package/genes/source-linker/index.ts +88 -0
- package/genes/source-linker/phenotype.json +45 -0
- package/genes/style-optimizer/.cloud-manifest.json +6 -0
- package/genes/style-optimizer/.gene-manifest.json +8 -0
- package/genes/style-optimizer/SKILL.md +285 -0
- package/genes/style-optimizer/phenotype.json +28 -0
- package/genes/tech-lead/.cloud-manifest.json +6 -0
- package/genes/tech-lead/.gene-manifest.json +8 -0
- package/genes/tech-lead/SKILL.md +451 -0
- package/genes/tech-lead/phenotype.json +28 -0
- package/genes/test-wrap/.cloud-manifest.json +6 -0
- package/genes/test-wrap/.gene-manifest.json +8 -0
- package/genes/test-wrap/phenotype.json +28 -0
- package/genes/testing-strategist/.cloud-manifest.json +6 -0
- package/genes/testing-strategist/.gene-manifest.json +8 -0
- package/genes/testing-strategist/SKILL.md +500 -0
- package/genes/testing-strategist/phenotype.json +28 -0
- package/genes/text-summarizer/.cloud-manifest.json +6 -0
- package/genes/text-summarizer/README.md +34 -0
- package/genes/text-summarizer/index.ts +122 -0
- package/genes/text-summarizer/phenotype.json +32 -0
- package/genes/tone-analyzer/.cloud-manifest.json +6 -0
- package/genes/tone-analyzer/.gene-manifest.json +8 -0
- package/genes/tone-analyzer/SKILL.md +410 -0
- package/genes/tone-analyzer/phenotype.json +28 -0
- package/genes/translator/.cloud-manifest.json +6 -0
- package/genes/translator/.gene-manifest.json +8 -0
- package/genes/translator/SKILL.md +355 -0
- package/genes/translator/phenotype.json +28 -0
- package/genes/ui-components/.cloud-manifest.json +6 -0
- package/genes/ui-components/.gene-manifest.json +8 -0
- package/genes/ui-components/SKILL.md +467 -0
- package/genes/ui-components/phenotype.json +28 -0
- package/genes/uiux-designer/.cloud-manifest.json +6 -0
- package/genes/uiux-designer/.gene-manifest.json +8 -0
- package/genes/uiux-designer/SKILL.md +353 -0
- package/genes/uiux-designer/phenotype.json +28 -0
- package/genes/url-extractor/.cloud-manifest.json +6 -0
- package/genes/url-extractor/README.md +37 -0
- package/genes/url-extractor/index.ts +86 -0
- package/genes/url-extractor/phenotype.json +48 -0
- package/genes/ux-patterns/.cloud-manifest.json +6 -0
- package/genes/ux-patterns/.gene-manifest.json +8 -0
- package/genes/ux-patterns/SKILL.md +872 -0
- package/genes/ux-patterns/phenotype.json +28 -0
- package/genes/web3-components/.cloud-manifest.json +6 -0
- package/genes/web3-components/.gene-manifest.json +8 -0
- package/genes/web3-components/SKILL.md +390 -0
- package/genes/web3-components/phenotype.json +28 -0
- package/package.json +6 -5
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: logic-architect
|
|
3
|
+
description: Ensure code has sound business logic, data flow, and technical implementation for AI and Web3 projects. Focus on architecture, edge cases, state management, agent patterns, and wallet safety. Use when writing core logic, reviewing architecture, implementing APIs, or when the user mentions logic, architecture, data flow, or asks for code review ignoring UI.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# The Logic Architect (逻辑与架构专家)
|
|
7
|
+
|
|
8
|
+
**Goal**: 确保代码在商业逻辑、数据流转和技术实现上无懈可击。**忽略 UI 细节**。
|
|
9
|
+
|
|
10
|
+
**专注领域**: AI 应用架构 + Web3 安全逻辑
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Pre-Code Checklist
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
Logic Integrity Check:
|
|
18
|
+
- [ ] Edge cases: 0 items? 10000 items? Timeout?
|
|
19
|
+
- [ ] State flow: Start → Loading → Success/Error → Reset (闭环?)
|
|
20
|
+
- [ ] Data privacy: No secrets/keys sent to wrong endpoints?
|
|
21
|
+
- [ ] OPC efficiency: Is this the simplest maintainable solution?
|
|
22
|
+
- [ ] AI: Token limits? Streaming? Fallback model?
|
|
23
|
+
- [ ] Web3: Wallet states? Chain switching? Gas estimation?
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## 1. Strategic Filters (战略过滤器)
|
|
29
|
+
|
|
30
|
+
### OPC Efficiency (一人公司原则)
|
|
31
|
+
|
|
32
|
+
| Question | If No → Action |
|
|
33
|
+
|----------|----------------|
|
|
34
|
+
| 能自动化吗? | 寻找可自动化方案或接受手动成本 |
|
|
35
|
+
| 维护成本低吗? | 简化设计,减少移动部件 |
|
|
36
|
+
| 有现成方案吗? | 优先使用成熟库/服务 |
|
|
37
|
+
| 未来我能看懂吗? | 添加注释,简化逻辑 |
|
|
38
|
+
|
|
39
|
+
**拒绝清单**:
|
|
40
|
+
- 过度抽象(不需要时不要搞 Factory Pattern)
|
|
41
|
+
- 自建可外包的基础设施(Auth, Payment, Email)
|
|
42
|
+
- 需要 24/7 监控的复杂架构
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## 2. AI Architecture Patterns
|
|
47
|
+
|
|
48
|
+
### AI Response Type System
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
// 统一 AI 响应类型(兼容多 SDK)
|
|
52
|
+
type AIResponse<T> =
|
|
53
|
+
| { ok: true; data: T; usage?: TokenUsage }
|
|
54
|
+
| { ok: false; error: AIError }
|
|
55
|
+
|
|
56
|
+
type AIError =
|
|
57
|
+
| { code: 'RATE_LIMITED'; retryAfter: number }
|
|
58
|
+
| { code: 'TOKEN_LIMIT'; used: number; limit: number }
|
|
59
|
+
| { code: 'CONTEXT_LENGTH'; maxTokens: number }
|
|
60
|
+
| { code: 'INVALID_RESPONSE'; raw: unknown }
|
|
61
|
+
| { code: 'TIMEOUT' }
|
|
62
|
+
| { code: 'MODERATION_FLAGGED'; categories: string[] }
|
|
63
|
+
|
|
64
|
+
type TokenUsage = {
|
|
65
|
+
prompt: number
|
|
66
|
+
completion: number
|
|
67
|
+
total: number
|
|
68
|
+
cost?: number // USD
|
|
69
|
+
}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Streaming Pattern
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
// 流式响应处理(Vercel AI SDK 风格)
|
|
76
|
+
async function* streamChat(messages: Message[]): AsyncGenerator<string> {
|
|
77
|
+
const response = await openai.chat.completions.create({
|
|
78
|
+
model: 'gpt-4',
|
|
79
|
+
messages,
|
|
80
|
+
stream: true,
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
for await (const chunk of response) {
|
|
84
|
+
const content = chunk.choices[0]?.delta?.content
|
|
85
|
+
if (content) yield content
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// 使用 Vercel AI SDK 时
|
|
90
|
+
import { streamText } from 'ai'
|
|
91
|
+
const { textStream } = await streamText({
|
|
92
|
+
model: openai('gpt-4'),
|
|
93
|
+
messages,
|
|
94
|
+
})
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Multi-Model Fallback
|
|
98
|
+
|
|
99
|
+
```typescript
|
|
100
|
+
// 模型降级策略
|
|
101
|
+
const MODEL_CHAIN = [
|
|
102
|
+
{ model: 'gpt-4o', maxTokens: 128000 },
|
|
103
|
+
{ model: 'gpt-4o-mini', maxTokens: 128000 },
|
|
104
|
+
{ model: 'claude-3-5-sonnet', maxTokens: 200000 },
|
|
105
|
+
] as const
|
|
106
|
+
|
|
107
|
+
async function callWithFallback<T>(
|
|
108
|
+
prompt: string,
|
|
109
|
+
schema: ZodSchema<T>
|
|
110
|
+
): Promise<T> {
|
|
111
|
+
for (const { model } of MODEL_CHAIN) {
|
|
112
|
+
try {
|
|
113
|
+
return await generateObject({ model, prompt, schema })
|
|
114
|
+
} catch (e) {
|
|
115
|
+
if (isLastModel(model)) throw e
|
|
116
|
+
console.warn(`${model} failed, falling back...`)
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
throw new Error('All models failed')
|
|
120
|
+
}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### Context Management
|
|
124
|
+
|
|
125
|
+
```typescript
|
|
126
|
+
// 长对话上下文管理
|
|
127
|
+
function truncateContext(
|
|
128
|
+
messages: Message[],
|
|
129
|
+
maxTokens: number
|
|
130
|
+
): Message[] {
|
|
131
|
+
// 保留: system prompt + 最近 N 条
|
|
132
|
+
const system = messages.filter(m => m.role === 'system')
|
|
133
|
+
const others = messages.filter(m => m.role !== 'system')
|
|
134
|
+
|
|
135
|
+
let tokenCount = countTokens(system)
|
|
136
|
+
const kept: Message[] = []
|
|
137
|
+
|
|
138
|
+
// 从最新往前保留
|
|
139
|
+
for (let i = others.length - 1; i >= 0; i--) {
|
|
140
|
+
const msgTokens = countTokens([others[i]])
|
|
141
|
+
if (tokenCount + msgTokens > maxTokens) break
|
|
142
|
+
kept.unshift(others[i])
|
|
143
|
+
tokenCount += msgTokens
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return [...system, ...kept]
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### Agent / Tool Pattern
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
// Agent 工具调用模式
|
|
154
|
+
interface Tool<TInput, TOutput> {
|
|
155
|
+
name: string
|
|
156
|
+
description: string
|
|
157
|
+
schema: ZodSchema<TInput>
|
|
158
|
+
execute: (input: TInput) => Promise<TOutput>
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// 工具执行循环
|
|
162
|
+
async function agentLoop(
|
|
163
|
+
initialPrompt: string,
|
|
164
|
+
tools: Tool[],
|
|
165
|
+
maxIterations = 10
|
|
166
|
+
): Promise<string> {
|
|
167
|
+
let messages = [{ role: 'user', content: initialPrompt }]
|
|
168
|
+
|
|
169
|
+
for (let i = 0; i < maxIterations; i++) {
|
|
170
|
+
const response = await llm.chat({ messages, tools })
|
|
171
|
+
|
|
172
|
+
if (response.finishReason === 'stop') {
|
|
173
|
+
return response.content
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
if (response.finishReason === 'tool_calls') {
|
|
177
|
+
for (const call of response.toolCalls) {
|
|
178
|
+
const tool = tools.find(t => t.name === call.name)
|
|
179
|
+
const result = await tool.execute(call.args)
|
|
180
|
+
messages.push({ role: 'tool', content: result, toolCallId: call.id })
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
throw new Error('Max iterations reached')
|
|
185
|
+
}
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
### Cost Control
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// 成本追踪
|
|
192
|
+
const PRICING = {
|
|
193
|
+
'gpt-4o': { input: 2.5, output: 10 }, // per 1M tokens
|
|
194
|
+
'gpt-4o-mini': { input: 0.15, output: 0.6 },
|
|
195
|
+
'claude-3-5-sonnet': { input: 3, output: 15 },
|
|
196
|
+
} as const
|
|
197
|
+
|
|
198
|
+
function calculateCost(model: string, usage: TokenUsage): number {
|
|
199
|
+
const price = PRICING[model]
|
|
200
|
+
return (usage.prompt * price.input + usage.completion * price.output) / 1_000_000
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
// 预算控制
|
|
204
|
+
async function withBudget<T>(
|
|
205
|
+
fn: () => Promise<{ result: T; usage: TokenUsage }>,
|
|
206
|
+
maxCostUSD: number
|
|
207
|
+
): Promise<T> {
|
|
208
|
+
const { result, usage } = await fn()
|
|
209
|
+
const cost = calculateCost(currentModel, usage)
|
|
210
|
+
if (cost > maxCostUSD) {
|
|
211
|
+
throw new Error(`Cost ${cost} exceeds budget ${maxCostUSD}`)
|
|
212
|
+
}
|
|
213
|
+
return result
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
---
|
|
218
|
+
|
|
219
|
+
## 3. Web3 Architecture Patterns
|
|
220
|
+
|
|
221
|
+
### Wallet State Machine
|
|
222
|
+
|
|
223
|
+
```typescript
|
|
224
|
+
// 完整钱包状态(wagmi + viem / ethers 通用)
|
|
225
|
+
type WalletState =
|
|
226
|
+
| { status: 'disconnected' }
|
|
227
|
+
| { status: 'connecting' }
|
|
228
|
+
| { status: 'connected'; address: Address; chainId: number }
|
|
229
|
+
| { status: 'wrong_network'; expected: number; actual: number }
|
|
230
|
+
| { status: 'signing'; message: string }
|
|
231
|
+
| { status: 'tx_pending'; hash: Hash }
|
|
232
|
+
| { status: 'tx_confirmed'; hash: Hash; receipt: TransactionReceipt }
|
|
233
|
+
| { status: 'tx_failed'; hash?: Hash; error: Error }
|
|
234
|
+
|
|
235
|
+
// 状态转换
|
|
236
|
+
// disconnected → connecting → connected
|
|
237
|
+
// → wrong_network → (switch) → connected
|
|
238
|
+
// connected → signing → connected
|
|
239
|
+
// connected → tx_pending → tx_confirmed
|
|
240
|
+
// → tx_failed
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
### Transaction Pattern (wagmi + viem)
|
|
244
|
+
|
|
245
|
+
```typescript
|
|
246
|
+
import { useWriteContract, useWaitForTransactionReceipt } from 'wagmi'
|
|
247
|
+
|
|
248
|
+
function useContractWrite() {
|
|
249
|
+
const { writeContract, data: hash, isPending, error } = useWriteContract()
|
|
250
|
+
const { isLoading: isConfirming, isSuccess } = useWaitForTransactionReceipt({ hash })
|
|
251
|
+
|
|
252
|
+
async function execute(args: ContractArgs) {
|
|
253
|
+
// Pre-flight checks
|
|
254
|
+
if (!address) throw new Error('Wallet not connected')
|
|
255
|
+
if (chainId !== expectedChainId) throw new Error('Wrong network')
|
|
256
|
+
|
|
257
|
+
// Gas estimation with buffer
|
|
258
|
+
const gasEstimate = await publicClient.estimateContractGas(args)
|
|
259
|
+
const gasLimit = gasEstimate * 120n / 100n // 20% buffer
|
|
260
|
+
|
|
261
|
+
writeContract({ ...args, gas: gasLimit })
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
return { execute, hash, isPending, isConfirming, isSuccess, error }
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
### Transaction Pattern (ethers.js)
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
import { ethers } from 'ethers'
|
|
272
|
+
|
|
273
|
+
async function executeTransaction(
|
|
274
|
+
contract: ethers.Contract,
|
|
275
|
+
method: string,
|
|
276
|
+
args: unknown[]
|
|
277
|
+
): Promise<TransactionReceipt> {
|
|
278
|
+
// Gas estimation
|
|
279
|
+
const gasEstimate = await contract[method].estimateGas(...args)
|
|
280
|
+
const gasLimit = gasEstimate * 120n / 100n
|
|
281
|
+
|
|
282
|
+
// Execute
|
|
283
|
+
const tx = await contract[method](...args, { gasLimit })
|
|
284
|
+
|
|
285
|
+
// Wait for confirmation
|
|
286
|
+
const receipt = await tx.wait(1) // 1 confirmation
|
|
287
|
+
|
|
288
|
+
if (receipt.status === 0) {
|
|
289
|
+
throw new Error('Transaction reverted')
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
return receipt
|
|
293
|
+
}
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### BigInt Handling
|
|
297
|
+
|
|
298
|
+
```typescript
|
|
299
|
+
// BigInt 格式化(禁止精度丢失)
|
|
300
|
+
import { formatUnits, parseUnits } from 'viem'
|
|
301
|
+
|
|
302
|
+
// ✅ 正确
|
|
303
|
+
const amount = parseUnits('1.5', 18) // 1.5 ETH → bigint
|
|
304
|
+
const display = formatUnits(balance, 18) // bigint → string
|
|
305
|
+
|
|
306
|
+
// ❌ 禁止(精度丢失)
|
|
307
|
+
const bad = Number(balance) // 大数会丢失精度
|
|
308
|
+
const worse = balance / 10n ** 18n // 整除丢失小数
|
|
309
|
+
```
|
|
310
|
+
|
|
311
|
+
### Chain Configuration
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
// 多链配置
|
|
315
|
+
const SUPPORTED_CHAINS = {
|
|
316
|
+
1: { name: 'Ethereum', rpc: process.env.ETH_RPC_URL },
|
|
317
|
+
137: { name: 'Polygon', rpc: process.env.POLYGON_RPC_URL },
|
|
318
|
+
42161: { name: 'Arbitrum', rpc: process.env.ARB_RPC_URL },
|
|
319
|
+
} as const
|
|
320
|
+
|
|
321
|
+
type SupportedChainId = keyof typeof SUPPORTED_CHAINS
|
|
322
|
+
|
|
323
|
+
function getChainConfig(chainId: number): ChainConfig {
|
|
324
|
+
const config = SUPPORTED_CHAINS[chainId as SupportedChainId]
|
|
325
|
+
if (!config) throw new Error(`Unsupported chain: ${chainId}`)
|
|
326
|
+
return config
|
|
327
|
+
}
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
---
|
|
331
|
+
|
|
332
|
+
## 4. Logic Integrity Protocol
|
|
333
|
+
|
|
334
|
+
### Edge Cases Matrix
|
|
335
|
+
|
|
336
|
+
| Scenario | Expected Behavior |
|
|
337
|
+
|----------|------------------|
|
|
338
|
+
| `items.length === 0` | ? |
|
|
339
|
+
| `items.length === 1` | ? |
|
|
340
|
+
| `items.length > 1000` | ? (分页/虚拟化?) |
|
|
341
|
+
| `network timeout` | ? |
|
|
342
|
+
| `AI token limit hit` | ? (truncate/split?) |
|
|
343
|
+
| `wallet disconnected mid-tx` | ? |
|
|
344
|
+
| `gas price spike` | ? |
|
|
345
|
+
|
|
346
|
+
### State Management Pattern
|
|
347
|
+
|
|
348
|
+
```typescript
|
|
349
|
+
type AsyncState<T, E = Error> =
|
|
350
|
+
| { status: 'idle' }
|
|
351
|
+
| { status: 'loading' }
|
|
352
|
+
| { status: 'success'; data: T }
|
|
353
|
+
| { status: 'error'; error: E }
|
|
354
|
+
|
|
355
|
+
// AI 特化版
|
|
356
|
+
type AIStreamState<T> =
|
|
357
|
+
| { status: 'idle' }
|
|
358
|
+
| { status: 'streaming'; partial: string }
|
|
359
|
+
| { status: 'success'; data: T; usage: TokenUsage }
|
|
360
|
+
| { status: 'error'; error: AIError }
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### Data Privacy Rules
|
|
364
|
+
|
|
365
|
+
```
|
|
366
|
+
NEVER send to external endpoints:
|
|
367
|
+
- Private keys / seed phrases / mnemonics
|
|
368
|
+
- Wallet signatures without user consent
|
|
369
|
+
- AI prompts containing user PII
|
|
370
|
+
- API keys in client-side code
|
|
371
|
+
|
|
372
|
+
ALWAYS:
|
|
373
|
+
- Mask addresses in logs (0x1234...5678)
|
|
374
|
+
- Use server-side for AI API calls
|
|
375
|
+
- Validate transaction parameters before signing
|
|
376
|
+
- Rate limit AI endpoints
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
---
|
|
380
|
+
|
|
381
|
+
## 5. Review Checklist
|
|
382
|
+
|
|
383
|
+
```markdown
|
|
384
|
+
## Logic Review
|
|
385
|
+
|
|
386
|
+
### Correctness
|
|
387
|
+
- [ ] 所有边界条件都有处理
|
|
388
|
+
- [ ] 状态流转形成闭环
|
|
389
|
+
- [ ] 错误信息对调试有帮助
|
|
390
|
+
|
|
391
|
+
### AI Specific
|
|
392
|
+
- [ ] Token 超限有降级策略
|
|
393
|
+
- [ ] 流式响应正确处理
|
|
394
|
+
- [ ] 幻觉有验证机制
|
|
395
|
+
- [ ] 成本可追踪
|
|
396
|
+
|
|
397
|
+
### Web3 Specific
|
|
398
|
+
- [ ] 钱包状态全覆盖
|
|
399
|
+
- [ ] BigInt 正确处理
|
|
400
|
+
- [ ] Gas 估算有 buffer
|
|
401
|
+
- [ ] 链切换有处理
|
|
402
|
+
|
|
403
|
+
### Security
|
|
404
|
+
- [ ] 无敏感数据泄露
|
|
405
|
+
- [ ] 输入已验证/清洗
|
|
406
|
+
- [ ] 权限检查到位
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## Quick Reference
|
|
412
|
+
|
|
413
|
+
### Common Patterns
|
|
414
|
+
|
|
415
|
+
```typescript
|
|
416
|
+
// Retry with backoff
|
|
417
|
+
async function withRetry<T>(fn: () => Promise<T>, maxRetries = 3): Promise<T>
|
|
418
|
+
|
|
419
|
+
// Timeout wrapper
|
|
420
|
+
function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>
|
|
421
|
+
|
|
422
|
+
// Debounce for inputs
|
|
423
|
+
function debounce<T extends (...args: any[]) => any>(fn: T, ms: number)
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### AI SDK Quick Reference
|
|
427
|
+
|
|
428
|
+
```typescript
|
|
429
|
+
// Vercel AI SDK
|
|
430
|
+
import { generateText, streamText, generateObject } from 'ai'
|
|
431
|
+
import { openai } from '@ai-sdk/openai'
|
|
432
|
+
import { anthropic } from '@ai-sdk/anthropic'
|
|
433
|
+
|
|
434
|
+
// OpenAI SDK
|
|
435
|
+
import OpenAI from 'openai'
|
|
436
|
+
const client = new OpenAI()
|
|
437
|
+
|
|
438
|
+
// LangChain
|
|
439
|
+
import { ChatOpenAI } from '@langchain/openai'
|
|
440
|
+
```
|
|
441
|
+
|
|
442
|
+
### Web3 SDK Quick Reference
|
|
443
|
+
|
|
444
|
+
```typescript
|
|
445
|
+
// wagmi + viem
|
|
446
|
+
import { useAccount, useConnect, useWriteContract } from 'wagmi'
|
|
447
|
+
import { parseUnits, formatUnits, Address } from 'viem'
|
|
448
|
+
|
|
449
|
+
// ethers.js
|
|
450
|
+
import { ethers, parseEther, formatEther } from 'ethers'
|
|
451
|
+
```
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "code.architecture",
|
|
3
|
+
"description": "Ensure code has sound business logic, data flow, and technical implementation for AI and Web3 projects. Focus on architecture, edge cases, state management, agent patterns, and wallet safety. Use when writing core logic, reviewing architecture, implementing APIs, or when the user mentions logic, architecture, data flow, or asks for code review ignoring UI.",
|
|
4
|
+
"inputSchema": {
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"prompt": {
|
|
8
|
+
"type": "string"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"required": []
|
|
12
|
+
},
|
|
13
|
+
"outputSchema": {
|
|
14
|
+
"type": "object",
|
|
15
|
+
"properties": {
|
|
16
|
+
"result": {
|
|
17
|
+
"type": "string"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"dependencies": [],
|
|
22
|
+
"version": "0.1.0",
|
|
23
|
+
"author": "rotifer-team",
|
|
24
|
+
"createdAt": 1771939407333,
|
|
25
|
+
"fidelity": "Wrapped",
|
|
26
|
+
"transparency": "Open",
|
|
27
|
+
"source": "skill"
|
|
28
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# markdown-formatter
|
|
2
|
+
|
|
3
|
+
A Native Gene that normalizes Markdown formatting for consistency.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
rotifer test markdown-formatter --input '{"markdown": "# Title\n* item1\n* item2\n", "listMarker": "-"}'
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Features
|
|
12
|
+
|
|
13
|
+
- Standardize list bullet markers (`-`, `*`, `+`)
|
|
14
|
+
- Normalize heading styles (ATX `#` or Setext underline)
|
|
15
|
+
- Enforce consistent blank line spacing
|
|
16
|
+
- Wrap long lines at configurable width
|
|
17
|
+
- Report number of changes applied
|
|
18
|
+
|
|
19
|
+
## Input
|
|
20
|
+
|
|
21
|
+
| Field | Type | Required | Description |
|
|
22
|
+
|-------|------|----------|-------------|
|
|
23
|
+
| `markdown` | string | Yes | Raw Markdown text |
|
|
24
|
+
| `lineWidth` | number | No | Max line width (default: 80) |
|
|
25
|
+
| `listMarker` | string | No | Bullet char: `-`, `*`, or `+` |
|
|
26
|
+
| `headingStyle` | string | No | `"atx"` or `"setext"` |
|
|
27
|
+
|
|
28
|
+
## Output
|
|
29
|
+
|
|
30
|
+
| Field | Type | Description |
|
|
31
|
+
|-------|------|-------------|
|
|
32
|
+
| `formatted` | string | Formatted Markdown |
|
|
33
|
+
| `changed` | boolean | Whether changes were made |
|
|
34
|
+
| `changeCount` | number | Number of changes applied |
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
interface FormatterInput {
|
|
2
|
+
markdown: string;
|
|
3
|
+
lineWidth?: number;
|
|
4
|
+
listMarker?: "-" | "*" | "+";
|
|
5
|
+
headingStyle?: "atx" | "setext";
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface FormatterOutput {
|
|
9
|
+
formatted: string;
|
|
10
|
+
changed: boolean;
|
|
11
|
+
changeCount: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function express(input: FormatterInput): Promise<FormatterOutput> {
|
|
15
|
+
const src = input.markdown || "";
|
|
16
|
+
const marker = input.listMarker ?? "-";
|
|
17
|
+
let changes = 0;
|
|
18
|
+
const lines = src.split("\n");
|
|
19
|
+
const out: string[] = [];
|
|
20
|
+
let prevBlank = false;
|
|
21
|
+
let prevHeading = false;
|
|
22
|
+
|
|
23
|
+
for (let i = 0; i < lines.length; i++) {
|
|
24
|
+
let line = lines[i];
|
|
25
|
+
|
|
26
|
+
line = line.replace(/[ \t]+$/, (m) => { if (m) changes++; return ""; });
|
|
27
|
+
|
|
28
|
+
const headingMatch = line.match(/^(#{1,6})\s*(.*)/);
|
|
29
|
+
if (headingMatch) {
|
|
30
|
+
const level = headingMatch[1];
|
|
31
|
+
const text = headingMatch[2].replace(/\s+#+\s*$/, "").trim();
|
|
32
|
+
const newLine = `${level} ${text}`;
|
|
33
|
+
if (newLine !== line) changes++;
|
|
34
|
+
if (out.length > 0 && !prevBlank) { out.push(""); changes++; }
|
|
35
|
+
out.push(newLine);
|
|
36
|
+
prevHeading = true;
|
|
37
|
+
prevBlank = false;
|
|
38
|
+
continue;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
if (prevHeading && line.trim() !== "") {
|
|
42
|
+
if (!prevBlank) { out.push(""); changes++; }
|
|
43
|
+
prevHeading = false;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const listMatch = line.match(/^(\s*)[*+\-]\s+(.*)/);
|
|
47
|
+
if (listMatch) {
|
|
48
|
+
const indent = listMatch[1];
|
|
49
|
+
const content = listMatch[2];
|
|
50
|
+
const newLine = `${indent}${marker} ${content}`;
|
|
51
|
+
if (newLine !== line) changes++;
|
|
52
|
+
out.push(newLine);
|
|
53
|
+
prevBlank = false;
|
|
54
|
+
prevHeading = false;
|
|
55
|
+
continue;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if (line.trim() === "") {
|
|
59
|
+
if (!prevBlank) {
|
|
60
|
+
out.push("");
|
|
61
|
+
prevBlank = true;
|
|
62
|
+
} else {
|
|
63
|
+
changes++;
|
|
64
|
+
}
|
|
65
|
+
prevHeading = false;
|
|
66
|
+
continue;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
out.push(line);
|
|
70
|
+
prevBlank = false;
|
|
71
|
+
prevHeading = false;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let formatted = out.join("\n");
|
|
75
|
+
if (formatted.length > 0 && !formatted.endsWith("\n")) {
|
|
76
|
+
formatted += "\n";
|
|
77
|
+
if (!src.endsWith("\n")) changes++;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
while (formatted.endsWith("\n\n")) {
|
|
81
|
+
formatted = formatted.slice(0, -1);
|
|
82
|
+
changes++;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
return { formatted, changed: changes > 0, changeCount: changes };
|
|
86
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"domain": "text.format",
|
|
3
|
+
"description": "Normalizes Markdown formatting: fixes heading levels, standardizes list markers, wraps long lines, and enforces consistent spacing.",
|
|
4
|
+
"inputSchema": {
|
|
5
|
+
"type": "object",
|
|
6
|
+
"properties": {
|
|
7
|
+
"markdown": { "type": "string", "description": "Raw Markdown text to format" },
|
|
8
|
+
"lineWidth": { "type": "number", "description": "Maximum line width for wrapping", "default": 80 },
|
|
9
|
+
"listMarker": { "type": "string", "description": "List bullet character", "enum": ["-", "*", "+"], "default": "-" },
|
|
10
|
+
"headingStyle": { "type": "string", "description": "Heading style", "enum": ["atx", "setext"], "default": "atx" }
|
|
11
|
+
},
|
|
12
|
+
"required": ["markdown"]
|
|
13
|
+
},
|
|
14
|
+
"outputSchema": {
|
|
15
|
+
"type": "object",
|
|
16
|
+
"properties": {
|
|
17
|
+
"formatted": { "type": "string", "description": "Formatted Markdown text" },
|
|
18
|
+
"changed": { "type": "boolean", "description": "Whether any formatting changes were made" },
|
|
19
|
+
"changeCount": { "type": "number", "description": "Number of formatting changes applied" }
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"dependencies": [],
|
|
23
|
+
"version": "0.1.0",
|
|
24
|
+
"author": "rotifer-genesis",
|
|
25
|
+
"fidelity": "Native",
|
|
26
|
+
"transparency": "Open",
|
|
27
|
+
"semantic_requirements": {
|
|
28
|
+
"timeModel": "Sync",
|
|
29
|
+
"concurrencyModel": "Stateless",
|
|
30
|
+
"failureSemantics": "Fail"
|
|
31
|
+
}
|
|
32
|
+
}
|