autosnippet 3.0.0 → 3.0.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.
- package/README.md +230 -324
- package/bin/api-server.js +1 -1
- package/bin/cli.js +204 -244
- package/bin/mcp-server.js +5 -3
- package/config/knowledge-base.config.js +132 -132
- package/dashboard/dist/assets/{icons-CEfgGaZi.js → icons-Cdq22n2i.js} +95 -100
- package/dashboard/dist/assets/index-ClkyPkDX.js +133 -0
- package/dashboard/dist/assets/index-t4QrJwv1.css +1 -0
- package/dashboard/dist/index.html +3 -3
- package/lib/bootstrap.js +8 -8
- package/lib/cli/AiScanService.js +86 -40
- package/lib/cli/KnowledgeSyncService.js +113 -74
- package/lib/cli/SetupService.js +439 -277
- package/lib/cli/UpgradeService.js +63 -100
- package/lib/core/AstAnalyzer.js +276 -597
- package/lib/core/ast/ProjectGraph.js +101 -40
- package/lib/core/ast/ensure-grammars.js +232 -0
- package/lib/core/ast/index.js +115 -0
- package/lib/core/ast/lang-dart.js +661 -0
- package/lib/core/ast/lang-go.js +530 -0
- package/lib/core/ast/lang-java.js +435 -0
- package/lib/core/ast/lang-javascript.js +272 -0
- package/lib/core/ast/lang-kotlin.js +423 -0
- package/lib/core/ast/lang-objc.js +388 -0
- package/lib/core/ast/lang-python.js +371 -0
- package/lib/core/ast/lang-swift.js +337 -0
- package/lib/core/ast/lang-typescript.js +503 -0
- package/lib/core/capability/CapabilityProbe.js +18 -9
- package/lib/core/constitution/Constitution.js +2 -3
- package/lib/core/constitution/ConstitutionValidator.js +65 -24
- package/lib/core/discovery/DartDiscoverer.js +534 -0
- package/lib/core/discovery/DiscovererRegistry.js +83 -0
- package/lib/core/discovery/GenericDiscoverer.js +225 -0
- package/lib/core/discovery/GoDiscoverer.js +541 -0
- package/lib/core/discovery/JvmDiscoverer.js +506 -0
- package/lib/core/discovery/NodeDiscoverer.js +466 -0
- package/lib/core/discovery/ProjectDiscoverer.js +93 -0
- package/lib/core/discovery/PythonDiscoverer.js +338 -0
- package/lib/core/discovery/SpmDiscoverer.js +5 -0
- package/lib/core/discovery/index.js +53 -0
- package/lib/core/enhancement/EnhancementPack.js +71 -0
- package/lib/core/enhancement/EnhancementRegistry.js +47 -0
- package/lib/core/enhancement/android-enhancement.js +102 -0
- package/lib/core/enhancement/django-enhancement.js +70 -0
- package/lib/core/enhancement/fastapi-enhancement.js +63 -0
- package/lib/core/enhancement/go-grpc-enhancement.js +152 -0
- package/lib/core/enhancement/go-web-enhancement.js +201 -0
- package/lib/core/enhancement/index.js +65 -0
- package/lib/core/enhancement/node-server-enhancement.js +88 -0
- package/lib/core/enhancement/react-enhancement.js +86 -0
- package/lib/core/enhancement/spring-enhancement.js +112 -0
- package/lib/core/enhancement/vue-enhancement.js +96 -0
- package/lib/core/gateway/Gateway.js +8 -9
- package/lib/core/gateway/GatewayActionRegistry.js +1 -1
- package/lib/core/permission/PermissionManager.js +12 -8
- package/lib/domain/index.js +13 -9
- package/lib/domain/knowledge/KnowledgeEntry.js +111 -101
- package/lib/domain/knowledge/KnowledgeRepository.js +0 -1
- package/lib/domain/knowledge/Lifecycle.js +22 -22
- package/lib/domain/knowledge/index.js +9 -12
- package/lib/domain/knowledge/values/Constraints.js +31 -21
- package/lib/domain/knowledge/values/Content.js +21 -13
- package/lib/domain/knowledge/values/Quality.js +31 -18
- package/lib/domain/knowledge/values/Reasoning.js +20 -12
- package/lib/domain/knowledge/values/Relations.js +37 -25
- package/lib/domain/knowledge/values/Stats.js +18 -12
- package/lib/domain/knowledge/values/index.js +4 -3
- package/lib/domain/snippet/Snippet.js +35 -10
- package/lib/external/ai/AiFactory.js +48 -16
- package/lib/external/ai/AiProvider.js +184 -90
- package/lib/external/ai/providers/ClaudeProvider.js +25 -12
- package/lib/external/ai/providers/GoogleGeminiProvider.js +59 -30
- package/lib/external/ai/providers/MockProvider.js +9 -3
- package/lib/external/ai/providers/OpenAiProvider.js +51 -29
- package/lib/external/mcp/McpServer.js +66 -36
- package/lib/external/mcp/errorHandler.js +23 -11
- package/lib/external/mcp/handlers/LanguageExtensions.js +138 -53
- package/lib/external/mcp/handlers/TargetClassifier.js +52 -16
- package/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +81 -20
- package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +71 -42
- package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +9 -17
- package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +14 -9
- package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +15 -7
- package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +352 -153
- package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +52 -12
- package/lib/external/mcp/handlers/bootstrap/skills.js +143 -39
- package/lib/external/mcp/handlers/bootstrap.js +691 -168
- package/lib/external/mcp/handlers/browse.js +66 -22
- package/lib/external/mcp/handlers/candidate.js +118 -35
- package/lib/external/mcp/handlers/consolidated.js +49 -17
- package/lib/external/mcp/handlers/guard.js +104 -39
- package/lib/external/mcp/handlers/knowledge.js +60 -36
- package/lib/external/mcp/handlers/search.js +43 -14
- package/lib/external/mcp/handlers/skill.js +120 -45
- package/lib/external/mcp/handlers/structure.js +240 -86
- package/lib/external/mcp/handlers/system.js +42 -12
- package/lib/external/mcp/handlers/wiki.js +58 -33
- package/lib/external/mcp/tools.js +306 -123
- package/lib/http/HttpServer.js +72 -47
- package/lib/http/middleware/RateLimiter.js +5 -3
- package/lib/http/middleware/errorHandler.js +6 -1
- package/lib/http/middleware/requestLogger.js +14 -3
- package/lib/http/middleware/roleResolver.js +30 -23
- package/lib/http/routes/ai.js +387 -265
- package/lib/http/routes/auth.js +81 -61
- package/lib/http/routes/candidates.js +430 -320
- package/lib/http/routes/commands.js +289 -189
- package/lib/http/routes/extract.js +158 -125
- package/lib/http/routes/guardRules.js +309 -217
- package/lib/http/routes/knowledge.js +213 -154
- package/lib/http/routes/modules.js +578 -0
- package/lib/http/routes/monitoring.js +6 -6
- package/lib/http/routes/recipes.js +104 -93
- package/lib/http/routes/search.js +361 -305
- package/lib/http/routes/skills.js +145 -98
- package/lib/http/routes/snippets.js +42 -30
- package/lib/http/routes/spm.js +3 -405
- package/lib/http/routes/violations.js +113 -93
- package/lib/http/routes/wiki.js +211 -170
- package/lib/http/utils/routeHelpers.js +3 -1
- package/lib/http/utils/sse-sessions.js +16 -6
- package/lib/http/utils/sse.js +15 -5
- package/lib/infrastructure/audit/AuditLogger.js +5 -2
- package/lib/infrastructure/audit/AuditStore.js +10 -7
- package/lib/infrastructure/cache/CacheService.js +3 -1
- package/lib/infrastructure/cache/GraphCache.js +8 -4
- package/lib/infrastructure/cache/UnifiedCacheAdapter.js +1 -1
- package/lib/infrastructure/config/ConfigLoader.js +9 -5
- package/lib/infrastructure/config/Defaults.js +30 -10
- package/lib/infrastructure/config/Paths.js +28 -8
- package/lib/infrastructure/config/TriggerSymbol.js +22 -10
- package/lib/infrastructure/database/DatabaseConnection.js +15 -10
- package/lib/infrastructure/database/migrations/001_initial_schema.js +0 -1
- package/lib/infrastructure/external/ClipboardManager.js +6 -2
- package/lib/infrastructure/external/NativeUi.js +50 -43
- package/lib/infrastructure/external/OpenBrowser.js +14 -17
- package/lib/infrastructure/external/XcodeAutomation.js +14 -258
- package/lib/infrastructure/logging/Logger.js +46 -30
- package/lib/infrastructure/monitoring/ErrorTracker.js +7 -5
- package/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -4
- package/lib/infrastructure/paths/HeaderResolver.js +25 -9
- package/lib/infrastructure/paths/PathFinder.js +34 -12
- package/lib/infrastructure/plugin/PluginManager.js +26 -8
- package/lib/infrastructure/realtime/RealtimeService.js +2 -2
- package/lib/infrastructure/vector/Chunker.js +22 -7
- package/lib/infrastructure/vector/IndexingPipeline.js +46 -22
- package/lib/infrastructure/vector/JsonVectorAdapter.js +90 -53
- package/lib/infrastructure/vector/VectorStore.js +28 -10
- package/lib/injection/ServiceContainer.js +247 -93
- package/lib/platform/ios/index.js +63 -0
- package/lib/platform/ios/routes/spm.js +437 -0
- package/lib/platform/ios/snippet/PlaceholderConverter.js +55 -0
- package/lib/platform/ios/snippet/XcodeCodec.js +112 -0
- package/lib/{service → platform/ios}/spm/DependencyGraph.js +41 -17
- package/lib/{service → platform/ios}/spm/PackageSwiftParser.js +41 -14
- package/lib/{service → platform/ios}/spm/PolicyEngine.js +9 -4
- package/lib/platform/ios/spm/SpmDiscoverer.js +122 -0
- package/lib/{service → platform/ios}/spm/SpmService.js +385 -127
- package/lib/{service/automation → platform/ios/xcode}/SaveEventFilter.js +8 -7
- package/lib/platform/ios/xcode/XcodeAutomation.js +350 -0
- package/lib/{service/automation → platform/ios/xcode}/XcodeIntegration.js +325 -145
- package/lib/repository/base/BaseRepository.js +7 -9
- package/lib/repository/knowledge/KnowledgeRepository.impl.js +98 -75
- package/lib/repository/token/TokenUsageStore.js +4 -2
- package/lib/service/automation/ActionPipeline.js +1 -1
- package/lib/service/automation/AutomationOrchestrator.js +8 -4
- package/lib/service/automation/ContextCollector.js +7 -5
- package/lib/service/automation/DirectiveDetector.js +23 -16
- package/lib/service/automation/FileWatcher.js +112 -56
- package/lib/service/automation/TriggerResolver.js +6 -4
- package/lib/service/automation/handlers/AlinkHandler.js +24 -12
- package/lib/service/automation/handlers/CreateHandler.js +19 -20
- package/lib/service/automation/handlers/DraftHandler.js +14 -8
- package/lib/service/automation/handlers/GuardHandler.js +93 -63
- package/lib/service/automation/handlers/HeaderHandler.js +1 -6
- package/lib/service/automation/handlers/SearchHandler.js +155 -88
- package/lib/service/bootstrap/BootstrapTaskManager.js +77 -35
- package/lib/service/candidate/SimilarityService.js +25 -9
- package/lib/service/chat/AnalystAgent.js +50 -24
- package/lib/service/chat/CandidateGuardrail.js +143 -17
- package/lib/service/chat/ChatAgent.js +759 -243
- package/lib/service/chat/ContextWindow.js +116 -71
- package/lib/service/chat/ConversationStore.js +77 -36
- package/lib/service/chat/EpisodicConsolidator.js +47 -23
- package/lib/service/chat/HandoffProtocol.js +98 -22
- package/lib/service/chat/Memory.js +34 -14
- package/lib/service/chat/ProducerAgent.js +40 -20
- package/lib/service/chat/ProjectSemanticMemory.js +109 -78
- package/lib/service/chat/ReasoningLayer.js +148 -70
- package/lib/service/chat/ReasoningTrace.js +44 -32
- package/lib/service/chat/TaskPipeline.js +39 -19
- package/lib/service/chat/ToolRegistry.js +48 -29
- package/lib/service/chat/WorkingMemory.js +44 -18
- package/lib/service/chat/tools.js +1096 -494
- package/lib/service/context/RecipeExtractor.js +132 -51
- package/lib/service/cursor/CursorDeliveryPipeline.js +82 -37
- package/lib/service/cursor/KnowledgeCompressor.js +25 -22
- package/lib/service/cursor/RulesGenerator.js +13 -7
- package/lib/service/cursor/SkillsSyncer.js +77 -27
- package/lib/service/cursor/TokenBudget.js +2 -2
- package/lib/service/cursor/TopicClassifier.js +54 -20
- package/lib/service/guard/ComplianceReporter.js +55 -43
- package/lib/service/guard/ExclusionManager.js +67 -29
- package/lib/service/guard/GuardCheckEngine.js +381 -86
- package/lib/service/guard/GuardFeedbackLoop.js +22 -10
- package/lib/service/guard/GuardService.js +29 -19
- package/lib/service/guard/RuleLearner.js +55 -23
- package/lib/service/guard/SourceFileCollector.js +27 -20
- package/lib/service/guard/ViolationsStore.js +43 -38
- package/lib/service/knowledge/CodeEntityGraph.js +147 -82
- package/lib/service/knowledge/ConfidenceRouter.js +12 -10
- package/lib/service/knowledge/KnowledgeFileWriter.js +147 -56
- package/lib/service/knowledge/KnowledgeGraphService.js +81 -34
- package/lib/service/knowledge/KnowledgeService.js +222 -112
- package/lib/service/module/ModuleService.js +969 -0
- package/lib/service/quality/FeedbackCollector.js +27 -15
- package/lib/service/quality/QualityScorer.js +78 -24
- package/lib/service/recipe/RecipeCandidateValidator.js +110 -44
- package/lib/service/recipe/RecipeParser.js +78 -45
- package/lib/service/search/CoarseRanker.js +43 -28
- package/lib/service/search/CrossEncoderReranker.js +32 -21
- package/lib/service/search/InvertedIndex.js +21 -7
- package/lib/service/search/MultiSignalRanker.js +90 -28
- package/lib/service/search/RetrievalFunnel.js +45 -24
- package/lib/service/search/SearchEngine.js +255 -103
- package/lib/service/skills/EventAggregator.js +32 -15
- package/lib/service/skills/SignalCollector.js +140 -64
- package/lib/service/skills/SkillAdvisor.js +79 -42
- package/lib/service/skills/SkillHooks.js +16 -14
- package/lib/service/snippet/PlaceholderConverter.js +5 -0
- package/lib/service/snippet/SnippetFactory.js +116 -99
- package/lib/service/snippet/SnippetInstaller.js +234 -62
- package/lib/service/snippet/codecs/SnippetCodec.js +67 -0
- package/lib/service/snippet/codecs/VSCodeCodec.js +102 -0
- package/lib/service/snippet/codecs/XcodeCodec.js +5 -0
- package/lib/service/wiki/WikiGenerator.js +637 -263
- package/lib/shared/DimensionCopyRegistry.js +472 -0
- package/lib/shared/LanguageService.js +399 -0
- package/lib/shared/PathGuard.js +45 -28
- package/lib/shared/RecipeReadinessChecker.js +72 -12
- package/lib/shared/constants.js +41 -41
- package/lib/shared/errors/BaseError.js +2 -2
- package/lib/shared/errors/index.js +4 -4
- package/lib/shared/similarity.js +25 -8
- package/lib/shared/token-utils.js +6 -2
- package/lib/shared/utils/common.js +12 -4
- package/package.json +49 -13
- package/scripts/bench-real-projects.mjs +256 -0
- package/scripts/build-native-ui.js +30 -30
- package/scripts/clear-old-vector-index.js +5 -35
- package/scripts/clear-vector-cache.js +7 -37
- package/scripts/collect-test-project-stats.mjs +160 -0
- package/scripts/diagnose-mcp.js +41 -32
- package/scripts/ensure-parse-package.js +6 -9
- package/scripts/generate-recipe-drafts.js +116 -77
- package/scripts/init-db.js +3 -20
- package/scripts/init-snippets.js +305 -0
- package/scripts/init-vector-db.js +173 -170
- package/scripts/install-cursor-skill.js +148 -104
- package/scripts/install-full.js +8 -21
- package/scripts/install-vscode-copilot.js +146 -145
- package/scripts/migrate-md-to-knowledge.mjs +139 -151
- package/scripts/postinstall-safe.js +5 -17
- package/scripts/recipe-audit.js +106 -82
- package/scripts/release.js +283 -323
- package/scripts/setup-mcp-config.js +60 -52
- package/scripts/verify-context-api.js +20 -20
- package/skills/autosnippet-analysis/SKILL.md +10 -6
- package/skills/autosnippet-candidates/SKILL.md +27 -26
- package/skills/autosnippet-coldstart/SKILL.md +555 -38
- package/skills/autosnippet-concepts/SKILL.md +349 -337
- package/skills/autosnippet-create/SKILL.md +5 -5
- package/skills/autosnippet-reference-dart/SKILL.md +543 -0
- package/skills/autosnippet-reference-go/SKILL.md +539 -0
- package/skills/autosnippet-reference-java/SKILL.md +534 -0
- package/skills/autosnippet-reference-jsts/SKILL.md +41 -9
- package/skills/autosnippet-reference-kotlin/SKILL.md +526 -0
- package/skills/autosnippet-reference-objc/SKILL.md +29 -6
- package/skills/autosnippet-reference-python/SKILL.md +800 -0
- package/skills/autosnippet-reference-swift/SKILL.md +70 -14
- package/skills/autosnippet-structure/SKILL.md +4 -4
- package/templates/cursor-rules/autosnippet-conventions.mdc +2 -2
- package/templates/recipes-setup/README.md +2 -2
- package/templates/recipes-setup/_template.md +1 -1
- package/dashboard/dist/assets/index-Bun3ld_J.css +0 -1
- package/dashboard/dist/assets/index-_Sk_Dmg3.js +0 -143
- package/resources/asd-entry/main.swift +0 -159
- package/scripts/build-asd-entry.js +0 -51
- package/scripts/init-xcode-snippets.js +0 -311
- package/template.json +0 -39
|
@@ -27,7 +27,7 @@ In AutoSnippet, the **知识库** is the set of project-owned artifacts under **
|
|
|
27
27
|
|
|
28
28
|
| Part | Location | Meaning |
|
|
29
29
|
|------|----------|---------|
|
|
30
|
-
| **Snippets** | AutoSnippet 根 spec `list` 或 `AutoSnippet/snippets/*.json` | Code snippets synced to Xcode CodeSnippets; developers use them by trigger (completion). |
|
|
30
|
+
| **Snippets** | AutoSnippet 根 spec `list` 或 `AutoSnippet/snippets/*.json` | Code snippets synced to IDE (Xcode CodeSnippets / VSCode .code-snippets); developers use them by trigger (completion). |
|
|
31
31
|
| **Recipes** | `AutoSnippet/recipes/*.md` (or `recipes.dir` in root spec) | Markdown docs: standard code + usage guide; used for AI context, Guard, and search. |
|
|
32
32
|
| **Candidates** | `AutoSnippet/.autosnippet/candidates.json` | AI-scanned candidates; review in Dashboard **Candidates** then approve or delete. |
|
|
33
33
|
| **Context index** | `AutoSnippet/.autosnippet/context/` | Vector index built by `asd embed`; used for on-demand semantic search and Guard. |
|
|
@@ -47,7 +47,7 @@ The knowledge base has **context storage** capability: Recipes, docs, etc. are e
|
|
|
47
47
|
|------|-------------|
|
|
48
48
|
| **Storage path** | `AutoSnippet/.autosnippet/context/` |
|
|
49
49
|
| **Build command** | Run `asd embed` from project root |
|
|
50
|
-
| **Index sources** | `recipe` (AutoSnippet/recipes/*.md), `doc` (docs dir), `target-readme` (
|
|
50
|
+
| **Index sources** | `recipe` (AutoSnippet/recipes/*.md), `doc` (docs dir), `target-readme` (module target READMEs) |
|
|
51
51
|
| **Storage adapter** | Default `json` |
|
|
52
52
|
| **Usage** | With `asd ui` running, MCP tool `autosnippet_search(mode=context)` takes `query`, `limit?` for semantic search |
|
|
53
53
|
| **Use cases** | On-demand lookup of relevant Recipe/docs; Guard review against knowledge base; Dashboard semantic search |
|
|
@@ -121,21 +121,34 @@ This is a conceptual map. Skills stay semantic; MCP provides capability.
|
|
|
121
121
|
|
|
122
122
|
**CRITICAL RULES for Frontmatter fields:**
|
|
123
123
|
- **`category`**: MUST be ONE of these 8 values: `View`, `Service`, `Tool`, `Model`, `Network`, `Storage`, `UI`, `Utility`. NEVER use module names (e.g. "BDNetworkControl") or custom categories.
|
|
124
|
-
- **`headers`**: MUST be complete import/include statements from the code.
|
|
125
|
-
-
|
|
126
|
-
-
|
|
127
|
-
-
|
|
124
|
+
- **`headers`**: MUST be complete import/include statements from the code. Examples by language:
|
|
125
|
+
- Swift: `["import Foundation"]`
|
|
126
|
+
- ObjC: `["#import <Module/Header.h>"]`
|
|
127
|
+
- Go: `["import \"fmt\""]`
|
|
128
|
+
- Python: `["import os"]` / `["from pathlib import Path"]`
|
|
129
|
+
- Java: `["import java.util.List;"]`
|
|
130
|
+
- Kotlin: `["import kotlinx.coroutines.*"]`
|
|
131
|
+
- JS/TS: `["import fs from 'node:fs'"]`
|
|
132
|
+
- **`trigger`**: MUST start with `@` (e.g. `@request-manager`). kebab-case, no spaces.
|
|
133
|
+
- **`language`**: MUST be one of the supported languages (lowercase): `swift`, `objectivec`, `go`, `python`, `java`, `kotlin`, `javascript`, `typescript`.
|
|
134
|
+
- **`kind`**: MUST be one of: `rule`, `pattern`, `fact`.
|
|
135
|
+
- **`doClause`**: English imperative sentence, ≤60 tokens.
|
|
136
|
+
- **`description`**: 中文摘要 ≤80字。
|
|
137
|
+
- **`content`**: 对象 `{ markdown (≥200字), pattern (核心代码), rationale (设计原理) }`。
|
|
138
|
+
- **`usageGuide`**: Markdown `###` 章节格式的使用指南。
|
|
139
|
+
- **`knowledgeType`**: 如 `code-pattern` / `architecture` / `best-practice` / `code-standard` 等。
|
|
140
|
+
- **`reasoning`**: `{ whyStandard, sources[], confidence }`。
|
|
128
141
|
|
|
129
142
|
**Standard Category Definitions (8 categories - MUST use exactly these):**
|
|
130
143
|
|
|
131
144
|
| Category | When to Use | Examples |
|
|
132
145
|
|----------|-------------|----------|
|
|
133
|
-
| `View` | UI components, view controllers, custom views |
|
|
146
|
+
| `View` | UI components, view controllers, custom views | React Component, SwiftUI View, UIViewController, Android Activity |
|
|
134
147
|
| `Service` | Business logic services, managers, coordinators | UserService, LocationManager, PaymentCoordinator |
|
|
135
|
-
| `Tool` | Utility classes, helpers, extensions | StringHelper, DateFormatter
|
|
148
|
+
| `Tool` | Utility classes, helpers, extensions | StringHelper, DateFormatter, validation utils |
|
|
136
149
|
| `Model` | Data models, entities, value objects | User model, APIResponse, configuration objects |
|
|
137
|
-
| `Network` | Network requests, API clients, HTTP/WebSocket |
|
|
138
|
-
| `Storage` | Persistence, caching, database operations |
|
|
150
|
+
| `Network` | Network requests, API clients, HTTP/WebSocket | fetch/axios wrapper, URLSession, OkHttp, net/http |
|
|
151
|
+
| `Storage` | Persistence, caching, database operations | SQLite, Redis, UserDefaults, file I/O, cache manager |
|
|
139
152
|
| `UI` | UI-related utilities not specific to one view | Theme manager, color palette, UI constants |
|
|
140
153
|
| `Utility` | General utilities that don't fit other categories | Logger, error handler, general helpers |
|
|
141
154
|
|
|
@@ -154,22 +167,21 @@ This is a conceptual map. Skills stay semantic; MCP provides capability.
|
|
|
154
167
|
| 字段 | 含义 | 来源 | 规则 |
|
|
155
168
|
| :--- | :--- | :--- | :--- |
|
|
156
169
|
| `title` | 标准用法的名称 | 人工命名 | **必填**;**中文**;简短精准(✅ "颜色工具方法"、"异步请求处理";❌ 避免 "Use xxx");≤20 字 |
|
|
157
|
-
| `trigger` | 触发词(Snippet/检索) | 人工命名 | **必填**;`@`
|
|
170
|
+
| `trigger` | 触发词(Snippet/检索) | 人工命名 | **必填**;`@` 开头,kebab-case、无空格;唯一 |
|
|
158
171
|
| `category` | 8 类标准分类 | 人工判断 | **必填**;必须为 8 类之一 |
|
|
159
|
-
| `language` | 代码语言 | 从代码确定 |
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
172
|
+
| `language` | 代码语言 | 从代码确定 | **必填**;支持 `swift` / `objectivec` / `go` / `python` / `java` / `kotlin` / `javascript` / `typescript` |
|
|
173
|
+
| `kind` | 知识类型 | 人工/AI | **必填**;`rule` / `pattern` / `fact` |
|
|
174
|
+
| `doClause` | 英文祈使句指令 | AI/人工 | **必填**;≤60 tokens |
|
|
175
|
+
| `description` | 中文功能摘要 | 人工/AI | **必填**;≤80字 |
|
|
176
|
+
| `content` | 内容对象 | 从代码/AI | **必填**;`{ markdown (≥200字), pattern (核心代码), rationale (设计原理) }` |
|
|
177
|
+
| `headers` | 完整 import/include 语句 | 从代码提取 | **必填**;数组;无 import 传 `[]` |
|
|
178
|
+
| `usageGuide` | 使用指南 | AI/人工 | **必填**;Markdown `###` 章节格式 |
|
|
179
|
+
| `knowledgeType` | 知识维度 | AI/人工 | **必填**;如 `code-pattern` / `architecture` / `best-practice` / `code-standard` 等 |
|
|
180
|
+
| `reasoning` | 推理依据 | Agent 必填 | **必填**;`{ whyStandard, sources[], confidence }` |
|
|
163
181
|
| `keywords` | 语义标签 | AI/人工 | 可选;数组;用于检索 |
|
|
164
|
-
| `tags` | 额外标签 | 人工 |
|
|
165
|
-
| `version` | 版本号 | 系统/人工 | 可选;语义化版本(如 `1.0.0`) |
|
|
166
|
-
| `author` | 作者/团队 | 人工 | 可选;字符串 |
|
|
167
|
-
| `deprecated` | 是否弃用 | 人工 | 可选;布尔值 |
|
|
168
|
-
| `id` | 唯一标识 | 系统生成 | 可选;若提供需唯一 |
|
|
169
|
-
| `moduleName` | 模块名 | 从 headers 解析 | 自动;不手填 |
|
|
170
|
-
| `deps` | 依赖关系 | 系统解析 | 可选;对象 `{ targets, imports }` |
|
|
182
|
+
| `tags` | 额外标签 | 人工 | 可选;数组 |
|
|
171
183
|
| `difficulty` | 难度等级 | 系统评估 | 可选;`beginner/intermediate/advanced` |
|
|
172
|
-
| `
|
|
184
|
+
| `scope` | 适用范围 | AI/人工 | 可选;`universal/project-specific/target-specific` |
|
|
173
185
|
|
|
174
186
|
**系统字段(自动生成,无需手填)**:`created`、`lastModified`、`contentHash`。
|
|
175
187
|
|
|
@@ -177,108 +189,58 @@ This is a conceptual map. Skills stay semantic; MCP provides capability.
|
|
|
177
189
|
- 多段 Recipe 可在同一文本中,使用「空行 + `---` + 下一段 Frontmatter」分隔。
|
|
178
190
|
- 当内容已是完整 Recipe MD(含 Frontmatter + Snippet + Usage Guide)时,系统直接解析入库,无需 AI 重写。
|
|
179
191
|
|
|
180
|
-
**Complete Recipe Template (ALWAYS use this structure):**
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
headers:
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
## Snippet / Code Reference
|
|
208
|
-
|
|
209
|
-
```objectivec
|
|
210
|
-
#import <BDNetworkControl/BDBaseRequest.h>
|
|
211
|
-
|
|
212
|
-
// Usage example - make it runnable and focused
|
|
213
|
-
BDBaseRequest *request = [[BDBaseRequest alloc] init];
|
|
214
|
-
request.url = @"https://api.example.com/endpoint";
|
|
215
|
-
request.method = BDRequestMethodGET;
|
|
216
|
-
|
|
217
|
-
[request startWithCompletionBlock:^(BDBaseRequest *req) {
|
|
218
|
-
// Handle success
|
|
219
|
-
id responseData = req.responseJson;
|
|
220
|
-
NSLog(@"Success: %@", responseData);
|
|
221
|
-
} failure:^(BDBaseRequest *req, NSError *error) {
|
|
222
|
-
// Handle error
|
|
223
|
-
NSLog(@"Error: %@", error.localizedDescription);
|
|
224
|
-
}];
|
|
192
|
+
**Complete Recipe Template (V3 — ALWAYS use this structure):**
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
{
|
|
196
|
+
"title": "带重试的 HTTP GET 请求",
|
|
197
|
+
"trigger": "@request-retry",
|
|
198
|
+
"category": "Network",
|
|
199
|
+
"language": "javascript",
|
|
200
|
+
"kind": "pattern",
|
|
201
|
+
"doClause": "Use fetchWithRetry for HTTP GET requests with automatic retry and exponential backoff",
|
|
202
|
+
"description": "封装带自动重试和指数退避的 HTTP GET 请求,适用于不稳定网络环境下的数据获取场景",
|
|
203
|
+
"headers": ["import fetch from 'node-fetch'"],
|
|
204
|
+
"content": {
|
|
205
|
+
"markdown": "## 带重试的 HTTP GET 请求\n\n在网络不稳定的场景中,单次 HTTP 请求可能因超时或服务端故障而失败。本模式封装了自动重试逻辑与指数退避策略,确保请求在合理次数内成功返回。\n\n### 核心实现\n\n```javascript\nimport fetch from 'node-fetch';\n\nasync function fetchWithRetry(url, options = {}, maxRetries = 3) {\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return await response.json();\n } catch (error) {\n if (attempt === maxRetries) throw error;\n await new Promise(r => setTimeout(r, 1000 * attempt));\n }\n }\n}\n\n// Usage\nconst data = await fetchWithRetry('https://api.example.com/endpoint');\nconsole.log('Success:', data);\n```\n\n### 设计要点\n- 指数退避:每次重试等待时间递增(1s, 2s, 3s),避免服务端过载\n- 最大重试次数可配置,默认 3 次\n- 非 2xx 状态码也视为失败并触发重试",
|
|
206
|
+
"pattern": "async function fetchWithRetry(url, options = {}, maxRetries = 3) {\n for (let attempt = 1; attempt <= maxRetries; attempt++) {\n try {\n const response = await fetch(url, options);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return await response.json();\n } catch (error) {\n if (attempt === maxRetries) throw error;\n await new Promise(r => setTimeout(r, 1000 * attempt));\n }\n }\n}",
|
|
207
|
+
"rationale": "指数退避策略是处理网络不稳定的行业标准做法,既保证了请求的可靠性,又通过递增等待避免了对服务端的冲击。封装为独立函数便于全项目统一使用。"
|
|
208
|
+
},
|
|
209
|
+
"usageGuide": "### When to Use\n- 需要对不稳定 API 进行可靠调用时\n- 网络环境可能出现间歇性故障的场景\n\n### Key Points\n- maxRetries 默认 3,可根据场景调整\n- 退避时间为线性递增(1s × attempt),可改为指数递增\n- 非 2xx 响应也会触发重试\n\n### Parameters & Customization\n- `url`: 请求地址\n- `options`: fetch 选项(method, headers, body 等)\n- `maxRetries`: 最大重试次数\n\n### Error Handling\n- 超过最大重试次数后抛出最后一次错误\n- 建议在调用处用 try/catch 捕获\n\n### Related Patterns\n- @http-client-base 基础 HTTP 客户端\n- @circuit-breaker 熔断器模式",
|
|
210
|
+
"knowledgeType": "code-pattern",
|
|
211
|
+
"reasoning": {
|
|
212
|
+
"whyStandard": "指数退避 + 自动重试是 HTTP 客户端的行业最佳实践,被 AWS SDK、Google Cloud 等广泛采用",
|
|
213
|
+
"sources": ["node-fetch documentation", "MDN Fetch API", "AWS SDK retry strategy"],
|
|
214
|
+
"confidence": 0.9
|
|
215
|
+
},
|
|
216
|
+
"keywords": ["network", "retry", "http", "fetch", "exponential-backoff"],
|
|
217
|
+
"tags": ["network", "resilience"]
|
|
218
|
+
}
|
|
225
219
|
```
|
|
226
220
|
|
|
227
|
-
## AI Context / Usage Guide
|
|
228
|
-
|
|
229
|
-
### When to Use
|
|
230
|
-
- Describe the specific scenario where this Recipe applies
|
|
231
|
-
- List conditions or contexts that make this Recipe relevant
|
|
232
|
-
|
|
233
|
-
### Key Points
|
|
234
|
-
- Important considerations when using this code
|
|
235
|
-
- Common pitfalls to avoid
|
|
236
|
-
- Best practices specific to this usage
|
|
237
|
-
|
|
238
|
-
### Parameters & Customization
|
|
239
|
-
- Explain what developers need to customize
|
|
240
|
-
- Document placeholder values and their meanings
|
|
241
|
-
|
|
242
|
-
### Dependencies & Preconditions
|
|
243
|
-
- Required modules, permissions, and minimum OS version
|
|
244
|
-
|
|
245
|
-
### Error Handling & Edge Cases
|
|
246
|
-
- Common failure modes, retry/timeout, and fallback behavior
|
|
247
|
-
|
|
248
|
-
### Performance & Resources
|
|
249
|
-
- Cache, threading, and memory considerations
|
|
250
|
-
|
|
251
|
-
### Security & Compliance
|
|
252
|
-
- Sensitive data handling, auth, and logging guidance
|
|
253
|
-
|
|
254
|
-
### Common Pitfalls
|
|
255
|
-
- Typical misuse and how to avoid it
|
|
256
|
-
|
|
257
|
-
### Related Patterns
|
|
258
|
-
- Link to related Recipes (use @trigger format)
|
|
259
|
-
- Note alternative approaches if applicable
|
|
260
|
-
````
|
|
261
|
-
|
|
262
221
|
**Template Usage Rules:**
|
|
263
|
-
1. **NEVER skip
|
|
264
|
-
2. **
|
|
265
|
-
-
|
|
266
|
-
-
|
|
267
|
-
-
|
|
268
|
-
-
|
|
269
|
-
-
|
|
270
|
-
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
222
|
+
1. **NEVER skip required fields** — 所有 V3 必填字段必须齐全
|
|
223
|
+
2. **V3 必填字段清单(缺一不可)**:
|
|
224
|
+
- `title` — 中文 ≤20字
|
|
225
|
+
- `trigger` — `@` 开头 kebab-case
|
|
226
|
+
- `category` — 8 类之一: View/Service/Tool/Model/Network/Storage/UI/Utility
|
|
227
|
+
- `language` — 编程语言标识
|
|
228
|
+
- `kind` — rule / pattern / fact
|
|
229
|
+
- `doClause` — 英文祈使句 ≤60 tokens
|
|
230
|
+
- `description` — 中文摘要 ≤80字
|
|
231
|
+
- `content` — `{ markdown (≥200字), pattern (核心代码), rationale (设计原理) }`
|
|
232
|
+
- `headers` — import 语句数组(无 import 传 `[]`)
|
|
233
|
+
- `usageGuide` — Markdown `###` 章节格式
|
|
234
|
+
- `knowledgeType` — 如 `code-pattern` / `architecture` / `best-practice` 等
|
|
235
|
+
- `reasoning` — `{ whyStandard, sources[], confidence }`
|
|
236
|
+
3. **DO NOT include `type: full`** — this field is deprecated and should be removed
|
|
237
|
+
4. **Headers MUST be complete import statements** — e.g. `import X`, `#import <X>`, `from X import Y`, `import "fmt"` — not just filenames
|
|
238
|
+
5. **content.markdown** — 需包含完整代码示例 + 说明文字,≥200 字
|
|
239
|
+
6. **content.pattern** — 核心骨架代码,不含注释和使用示例
|
|
240
|
+
7. **content.rationale** — 为什么这样写的设计原理
|
|
241
|
+
8. **usageGuide** — 解释 When/How/Why、依赖、错误处理、性能、安全、陷阱和相关模式
|
|
242
|
+
9. **Use placeholders** — use IDE-appropriate placeholders: Xcode uses `<#placeholder#>`, VSCode uses `${1:placeholder}`. In Recipe source, prefer Xcode format (auto-converted on install). Explain placeholders in Usage Guide.
|
|
243
|
+
10. **Make trigger unique**: Format `@feature-name`, kebab-case, no spaces
|
|
282
244
|
|
|
283
245
|
---
|
|
284
246
|
|
|
@@ -286,29 +248,34 @@ request.method = BDRequestMethodGET;
|
|
|
286
248
|
|
|
287
249
|
- **类别误用**:category 只能是 8 类之一,不能写模块名
|
|
288
250
|
- **headers 不完整**:必须是完整 import/#import 语句数组,不能是文件名
|
|
289
|
-
- **缺失必填**:`title`/`trigger`/`category`/`language`/`
|
|
251
|
+
- **缺失必填**:`title`/`trigger`/`category`/`language`/`kind`/`doClause`/`description`/`headers`/`content`(markdown+rationale)/`usageGuide`/`knowledgeType`/`reasoning` 必须齐全
|
|
290
252
|
- **trigger 格式错误**:必须 `@` 开头,小写、无空格
|
|
291
253
|
- **字段滥用**:不要使用已弃用的 `type` 字段
|
|
292
254
|
- **合并多模式**:一个 Recipe 只描述一个具体场景
|
|
293
255
|
|
|
294
256
|
### ✅ Quick Checklist Before Submitting
|
|
295
257
|
|
|
296
|
-
- [ ] Has all
|
|
297
|
-
- [ ] **
|
|
298
|
-
- [ ]
|
|
299
|
-
- [ ]
|
|
300
|
-
- [ ] `
|
|
301
|
-
- [ ]
|
|
302
|
-
- [ ]
|
|
258
|
+
- [ ] Has all required V3 fields filled
|
|
259
|
+
- [ ] **title**: 中文简短标题(≤20字)
|
|
260
|
+
- [ ] **content**: `{ markdown (≥200字), pattern (核心代码), rationale (设计原理) }`
|
|
261
|
+
- [ ] **trigger**: `@` 开头 kebab-case
|
|
262
|
+
- [ ] **kind**: `rule` / `pattern` / `fact`
|
|
263
|
+
- [ ] **doClause**: 英文祈使句(≠60 tokens)
|
|
264
|
+
- [ ] **description**: 中文摘要 ≤80字
|
|
265
|
+
- [ ] **category**: ONE of View/Service/Tool/Model/Network/Storage/UI/Utility
|
|
266
|
+
- [ ] **language**: `swift`/`objectivec`/`go`/`python`/`java`/`kotlin`/`javascript`/`typescript`
|
|
267
|
+
- [ ] **headers**: 完整 import 语句数组(无 import 传 `[]`)
|
|
268
|
+
- [ ] **usageGuide**: Markdown `###` 章节格式
|
|
269
|
+
- [ ] **knowledgeType**: `code-pattern` / `architecture` / `best-practice` 等
|
|
270
|
+
- [ ] **reasoning**: `{ whyStandard, sources[], confidence }`
|
|
303
271
|
- [ ] Code snippet is runnable with minimal edits
|
|
304
|
-
- [ ] Summary describes the specific use case (not generic)
|
|
305
272
|
- [ ] No `type:` field (this is deprecated)
|
|
306
|
-
- [ ]
|
|
273
|
+
- [ ] No `code` / `summary_cn` / `summary_en` (use V3 `content` + `description` instead)
|
|
307
274
|
|
|
308
275
|
### Recipe Creation Principles
|
|
309
276
|
|
|
310
277
|
When creating or extracting Recipes:
|
|
311
|
-
1.
|
|
278
|
+
1. **V3 必填字段一次性填写**:title, content(markdown+pattern+rationale), trigger, kind, doClause, description, category, language, headers, usageGuide, knowledgeType, reasoning
|
|
312
279
|
2. **保持单场景**:一个 Recipe 只讲一个具体用法
|
|
313
280
|
3. **字段严格**:必填字段必须齐全、格式正确
|
|
314
281
|
- Tools like Dashboard `/api/v1/ai/translate` can help auto-generate missing language, but it's better to provide both
|
|
@@ -317,8 +284,22 @@ When creating or extracting Recipes:
|
|
|
317
284
|
4. **Reusable and focused**: Developer should be able to copy-paste the Recipe's code snippet and use it directly for that ONE scenario.
|
|
318
285
|
5. **Summary should be specific**: "Use async/await for sequential API calls" NOT "Async programming guide".
|
|
319
286
|
6. **Category MUST use standard values**: ONLY use one of these 8 categories: `View`, `Service`, `Tool`, `Model`, `Network`, `Storage`, `UI`, `Utility`. Never use module names (e.g. "BDNetworkControl") or other custom values as category.
|
|
320
|
-
7. **Headers must be complete import statements**: Extract all import/include statements from code. Format
|
|
321
|
-
|
|
287
|
+
7. **Headers must be complete import statements**: Extract all import/include statements from code. Format by language:
|
|
288
|
+
- Swift: `["import ModuleName"]`
|
|
289
|
+
- ObjC: `["#import <Module/Header.h>"]`
|
|
290
|
+
- Go: `["import \"fmt\""]`
|
|
291
|
+
- Python: `["import os"]` / `["from pathlib import Path"]`
|
|
292
|
+
- Java/Kotlin: `["import java.util.List;"]`
|
|
293
|
+
- JS/TS: `["import fs from 'node:fs'"]`
|
|
294
|
+
Include the full statement, not just module names.
|
|
295
|
+
8. **Auto-extract moduleName**: Parse from headers. Examples:
|
|
296
|
+
- ObjC: `["#import <BDNetworkControl/BDBaseRequest.h>"]` → `moduleName: BDNetworkControl`
|
|
297
|
+
- Swift: `["import Foundation"]` → `moduleName: Foundation`
|
|
298
|
+
- Go: `["import \"net/http\""]` → `moduleName: net/http`
|
|
299
|
+
- Python: `["from flask import Flask"]` → `moduleName: flask`
|
|
300
|
+
- Java: `["import com.google.gson.Gson;"]` → `moduleName: com.google.gson`
|
|
301
|
+
- JS/TS: `["import express from 'express'"]` → `moduleName: express`
|
|
302
|
+
If multiple modules exist, use the primary/main one.
|
|
322
303
|
9. **Auto-generate tags**: Analyze code to extract 2-4 keyword tags:
|
|
323
304
|
- **Functionality**: network, storage, ui, animation, async, cache, threading
|
|
324
305
|
- **Patterns**: template, singleton, factory, observer, delegate
|
|
@@ -351,10 +332,241 @@ When both Recipe and project source code have relevant implementations, **prefer
|
|
|
351
332
|
|
|
352
333
|
---
|
|
353
334
|
|
|
335
|
+
## Multi-Language Recipe Examples (V3)
|
|
336
|
+
|
|
337
|
+
> 以下展示不同语言的标准 V3 Recipe 示例,展示所有必填字段在各语言下的写法。
|
|
338
|
+
|
|
339
|
+
### Example 1: Swift — 网络请求(iOS/macOS)
|
|
340
|
+
|
|
341
|
+
```json
|
|
342
|
+
{
|
|
343
|
+
"title": "URLSession 异步 GET 请求",
|
|
344
|
+
"trigger": "@url-session-get",
|
|
345
|
+
"category": "Network",
|
|
346
|
+
"language": "swift",
|
|
347
|
+
"kind": "pattern",
|
|
348
|
+
"doClause": "Use async/await URLSession for GET requests with error handling and JSON decoding",
|
|
349
|
+
"description": "使用 async/await 的 URLSession GET 请求,包含错误处理与 JSON 解码,适用于 iOS/macOS 网络层",
|
|
350
|
+
"headers": ["import Foundation"],
|
|
351
|
+
"content": {
|
|
352
|
+
"markdown": "## URLSession 异步 GET 请求\n\n使用 Swift concurrency 的 async/await 语法封装 URLSession GET 请求,自动校验 HTTP 状态码并解码 JSON。\n\n```swift\nfunc fetchData<T: Decodable>(from url: URL) async throws -> T {\n let (data, response) = try await URLSession.shared.data(from: url)\n guard let http = response as? HTTPURLResponse,\n (200..<300).contains(http.statusCode) else {\n throw URLError(.badServerResponse)\n }\n return try JSONDecoder().decode(T.self, from: data)\n}\n\n// Usage\nlet users: [User] = try await fetchData(from: URL(string: \"https://api.example.com/users\")!)\n```\n\n### 设计要点\n- 泛型 Decodable 约束,支持任意 JSON 模型\n- 校验 HTTP 2xx 范围状态码\n- 利用 Swift Concurrency 自动管理线程",
|
|
353
|
+
"pattern": "func fetchData<T: Decodable>(from url: URL) async throws -> T {\n let (data, response) = try await URLSession.shared.data(from: url)\n guard let http = response as? HTTPURLResponse,\n (200..<300).contains(http.statusCode) else {\n throw URLError(.badServerResponse)\n }\n return try JSONDecoder().decode(T.self, from: data)\n}",
|
|
354
|
+
"rationale": "async/await 是 Swift 5.5+ 推荐的异步模式,相比 completion handler 更清晰且不易出错,泛型解码减少重复代码。"
|
|
355
|
+
},
|
|
356
|
+
"usageGuide": "### When to Use\n- iOS/macOS 项目中需要从 REST API 获取 JSON 数据\n- 使用 Swift 5.5+ 的项目\n\n### Key Points\n- 必须在 async 上下文中调用\n- 返回类型需遵循 Decodable 协议\n\n### Error Handling\n- 非 2xx 抛出 URLError(.badServerResponse)\n- JSON 解码失败抛出 DecodingError",
|
|
357
|
+
"knowledgeType": "code-pattern",
|
|
358
|
+
"reasoning": {
|
|
359
|
+
"whyStandard": "Apple 官方推荐 async/await URLSession API,是 Swift Concurrency 标准做法",
|
|
360
|
+
"sources": ["Apple URLSession documentation", "Swift Concurrency WWDC21"],
|
|
361
|
+
"confidence": 0.95
|
|
362
|
+
},
|
|
363
|
+
"keywords": ["network", "async", "urlsession", "json"],
|
|
364
|
+
"tags": ["network", "template"]
|
|
365
|
+
}
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
### Example 2: Objective-C — KVO 安全模式
|
|
369
|
+
|
|
370
|
+
```json
|
|
371
|
+
{
|
|
372
|
+
"title": "NSObject KVO 安全订阅",
|
|
373
|
+
"trigger": "@kvo-safe",
|
|
374
|
+
"category": "Utility",
|
|
375
|
+
"language": "objectivec",
|
|
376
|
+
"kind": "rule",
|
|
377
|
+
"doClause": "Pair addObserver and removeObserver to prevent KVO leaks and crashes",
|
|
378
|
+
"description": "配对 addObserver/removeObserver,避免 KVO 泄漏与崩溃,确保生命周期安全",
|
|
379
|
+
"headers": ["#import <Foundation/Foundation.h>"],
|
|
380
|
+
"content": {
|
|
381
|
+
"markdown": "## NSObject KVO 安全订阅\n\nKVO 是 Cocoa 的核心机制,但未正确移除观察者会导致崩溃。本规则要求 addObserver 与 removeObserver 必须配对。\n\n```objectivec\n// Add observer\n[self.target addObserver:self\n forKeyPath:@\"<#property#>\"\n options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld\n context:NULL];\n\n// Handle changes\n- (void)observeValueForKeyPath:(NSString *)keyPath\n ofObject:(id)object\n change:(NSDictionary *)change\n context:(void *)context {\n if ([keyPath isEqualToString:@\"<#property#>\"]) {\n id newValue = change[NSKeyValueChangeNewKey];\n // Handle change\n }\n}\n\n// MUST remove in dealloc\n- (void)dealloc {\n [self.target removeObserver:self forKeyPath:@\"<#property#>\"];\n}\n```\n\n### 设计要点\n- addObserver 与 removeObserver 必须一一配对\n- dealloc 中移除是最后的安全网\n- 使用 context 区分不同观察",
|
|
382
|
+
"pattern": "[self.target addObserver:self forKeyPath:@\"<#property#>\" options:NSKeyValueObservingOptionNew context:NULL];\n- (void)dealloc { [self.target removeObserver:self forKeyPath:@\"<#property#>\"]; }",
|
|
383
|
+
"rationale": "KVO 观察者未移除会在对象释放后导致野指针崩溃,配对管理是 Cocoa 开发的基本安全规则。"
|
|
384
|
+
},
|
|
385
|
+
"usageGuide": "### When to Use\n- 使用 KVO 监听属性变化时\n- 任何 addObserver 调用都必须有对应的 removeObserver\n\n### Common Pitfalls\n- 忘记在 dealloc 中移除观察者\n- 重复添加同一 keyPath 的观察者\n- 多线程环境下的竞态条件",
|
|
386
|
+
"knowledgeType": "code-standard",
|
|
387
|
+
"reasoning": {
|
|
388
|
+
"whyStandard": "Apple 官方文档明确要求 KVO 观察者必须在释放前移除,否则会触发异常",
|
|
389
|
+
"sources": ["Apple KVO Programming Guide", "NSObject Protocol Reference"],
|
|
390
|
+
"confidence": 0.95
|
|
391
|
+
},
|
|
392
|
+
"keywords": ["kvo", "safety", "lifecycle"],
|
|
393
|
+
"tags": ["safety"]
|
|
394
|
+
}
|
|
395
|
+
```
|
|
396
|
+
|
|
397
|
+
### Example 3: Go — HTTP Handler with Middleware
|
|
398
|
+
|
|
399
|
+
```json
|
|
400
|
+
{
|
|
401
|
+
"title": "Go HTTP Handler 中间件链",
|
|
402
|
+
"trigger": "@go-handler",
|
|
403
|
+
"category": "Network",
|
|
404
|
+
"language": "go",
|
|
405
|
+
"kind": "pattern",
|
|
406
|
+
"doClause": "Use middleware chain pattern for net/http handlers with logging and recovery",
|
|
407
|
+
"description": "标准 net/http Handler + 中间件链模式,含日志和 panic 恢复中间件",
|
|
408
|
+
"headers": ["import \"net/http\"", "import \"log\""],
|
|
409
|
+
"content": {
|
|
410
|
+
"markdown": "## Go HTTP Handler 中间件链\n\n使用函数式中间件链组合 HTTP 处理器,每个中间件负责单一职责(日志、恢复等),通过 Chain 函数串联。\n\n```go\ntype Middleware func(http.Handler) http.Handler\n\nfunc LoggingMiddleware(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tlog.Printf(\"%s %s\", r.Method, r.URL.Path)\n\t\tnext.ServeHTTP(w, r)\n\t})\n}\n\nfunc RecoveryMiddleware(next http.Handler) http.Handler {\n\treturn http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {\n\t\tdefer func() {\n\t\t\tif err := recover(); err != nil {\n\t\t\t\thttp.Error(w, \"Internal Server Error\", 500)\n\t\t\t\tlog.Printf(\"panic recovered: %v\", err)\n\t\t\t}\n\t\t}()\n\t\tnext.ServeHTTP(w, r)\n\t})\n}\n\nfunc Chain(h http.Handler, mws ...Middleware) http.Handler {\n\tfor i := len(mws) - 1; i >= 0; i-- {\n\t\tmw := mws[i]\n\t\th = mw(h)\n\t}\n\treturn h\n}\n```\n\n### 设计要点\n- Middleware 类型签名统一:`func(http.Handler) http.Handler`\n- Chain 从右向左包装,保证执行顺序与传入顺序一致\n- RecoveryMiddleware 防止 panic 导致进程崩溃",
|
|
411
|
+
"pattern": "type Middleware func(http.Handler) http.Handler\n\nfunc Chain(h http.Handler, mws ...Middleware) http.Handler {\n\tfor i := len(mws) - 1; i >= 0; i-- {\n\t\tmw := mws[i]\n\t\th = mw(h)\n\t}\n\treturn h\n}",
|
|
412
|
+
"rationale": "中间件链是 Go HTTP 服务的标准架构模式,被 chi、gorilla/mux 等主流框架广泛采用,通过函数组合实现关注点分离。"
|
|
413
|
+
},
|
|
414
|
+
"usageGuide": "### When to Use\n- 构建 Go HTTP 服务时需要统一的请求处理流水线\n- 需要日志、认证、恢复等通用功能\n\n### Key Points\n- 中间件顺序很重要:Recovery 应在最外层\n- 可自由扩展: Auth、CORS、RateLimit 等\n\n### Related Patterns\n- @go-graceful-shutdown 优雅关闭\n- @go-context-propagation 上下文传递",
|
|
415
|
+
"knowledgeType": "code-pattern",
|
|
416
|
+
"reasoning": {
|
|
417
|
+
"whyStandard": "函数式中间件链是 Go 社区的标准 HTTP 服务架构,与 net/http 原生接口完全兼容",
|
|
418
|
+
"sources": ["Go net/http documentation", "chi router middleware pattern"],
|
|
419
|
+
"confidence": 0.9
|
|
420
|
+
},
|
|
421
|
+
"keywords": ["http", "handler", "middleware", "server"],
|
|
422
|
+
"tags": ["network", "pattern"]
|
|
423
|
+
}
|
|
424
|
+
```
|
|
425
|
+
|
|
426
|
+
### Example 4: Python — 异步数据库查询
|
|
427
|
+
|
|
428
|
+
```json
|
|
429
|
+
{
|
|
430
|
+
"title": "异步 PostgreSQL 连接池查询",
|
|
431
|
+
"trigger": "@async-db",
|
|
432
|
+
"category": "Storage",
|
|
433
|
+
"language": "python",
|
|
434
|
+
"kind": "pattern",
|
|
435
|
+
"doClause": "Use asyncpg connection pool for async PostgreSQL queries with proper error handling",
|
|
436
|
+
"description": "使用 asyncpg 连接池执行异步 PostgreSQL 查询,含连接管理与错误处理",
|
|
437
|
+
"headers": ["import asyncpg", "import asyncio"],
|
|
438
|
+
"content": {
|
|
439
|
+
"markdown": "## 异步 PostgreSQL 连接池查询\n\nasyncpg 连接池管理数据库连接的生命周期,避免频繁创建/销毁连接的开销。\n\n```python\nimport asyncpg\nimport asyncio\n\nasync def create_pool(dsn: str) -> asyncpg.Pool:\n return await asyncpg.create_pool(dsn, min_size=5, max_size=20)\n\nasync def fetch_users(pool: asyncpg.Pool, limit: int = 100) -> list[dict]:\n async with pool.acquire() as conn:\n rows = await conn.fetch(\n \"SELECT id, name, email FROM users WHERE active = $1 LIMIT $2\",\n True, limit\n )\n return [dict(row) for row in rows]\n\n# Usage\npool = await create_pool(\"postgresql://user:pass@localhost/mydb\")\ntry:\n users = await fetch_users(pool)\nfinally:\n await pool.close()\n```\n\n### 设计要点\n- 连接池 min_size/max_size 控制资源消耗\n- async with pool.acquire() 自动归还连接\n- 参数化查询防止 SQL 注入",
|
|
440
|
+
"pattern": "async def create_pool(dsn: str) -> asyncpg.Pool:\n return await asyncpg.create_pool(dsn, min_size=5, max_size=20)\n\nasync def fetch_users(pool: asyncpg.Pool, limit: int = 100) -> list[dict]:\n async with pool.acquire() as conn:\n rows = await conn.fetch(query, *params)\n return [dict(row) for row in rows]",
|
|
441
|
+
"rationale": "连接池是数据库访问的标准做法,asyncpg 是 Python 社区性能最优的 PostgreSQL 异步驱动,参数化查询确保安全。"
|
|
442
|
+
},
|
|
443
|
+
"usageGuide": "### When to Use\n- Python 异步应用中访问 PostgreSQL\n- 需要高并发数据库访问的场景\n\n### Key Points\n- 必须在 asyncio 事件循环中使用\n- 应用退出前调用 pool.close()\n- 使用参数化查询($1, $2)而非字符串拼接\n\n### Dependencies\n- asyncpg >= 0.27.0\n- PostgreSQL 9.5+",
|
|
444
|
+
"knowledgeType": "code-pattern",
|
|
445
|
+
"reasoning": {
|
|
446
|
+
"whyStandard": "asyncpg 连接池是 Python 异步 PostgreSQL 访问的行业标准,被 FastAPI、Starlette 等框架推荐",
|
|
447
|
+
"sources": ["asyncpg documentation", "PostgreSQL connection pooling best practices"],
|
|
448
|
+
"confidence": 0.9
|
|
449
|
+
},
|
|
450
|
+
"keywords": ["database", "async", "postgresql", "pool"],
|
|
451
|
+
"tags": ["storage", "async"]
|
|
452
|
+
}
|
|
453
|
+
```
|
|
454
|
+
|
|
455
|
+
### Example 5: TypeScript — React 自定义 Hook
|
|
456
|
+
|
|
457
|
+
```json
|
|
458
|
+
{
|
|
459
|
+
"title": "React 通用 useFetch Hook",
|
|
460
|
+
"trigger": "@use-fetch",
|
|
461
|
+
"category": "Tool",
|
|
462
|
+
"language": "typescript",
|
|
463
|
+
"kind": "pattern",
|
|
464
|
+
"doClause": "Use generic useFetch hook with loading state, error handling, and auto-cancellation",
|
|
465
|
+
"description": "通用 useFetch Hook,支持泛型、loading 状态、错误处理与请求自动取消",
|
|
466
|
+
"headers": ["import { useState, useEffect } from 'react'"],
|
|
467
|
+
"content": {
|
|
468
|
+
"markdown": "## React 通用 useFetch Hook\n\n封装 fetch 请求为自定义 Hook,统一管理 loading/data/error 三态,URL 变化时自动取消上一次请求。\n\n```typescript\nimport { useState, useEffect } from 'react';\n\ninterface FetchState<T> {\n data: T | null;\n loading: boolean;\n error: Error | null;\n}\n\nfunction useFetch<T>(url: string): FetchState<T> {\n const [state, setState] = useState<FetchState<T>>({\n data: null, loading: true, error: null,\n });\n\n useEffect(() => {\n const controller = new AbortController();\n setState(prev => ({ ...prev, loading: true, error: null }));\n\n fetch(url, { signal: controller.signal })\n .then(res => {\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n return res.json();\n })\n .then(data => setState({ data, loading: false, error: null }))\n .catch(err => {\n if (err.name !== 'AbortError') {\n setState({ data: null, loading: false, error: err });\n }\n });\n\n return () => controller.abort();\n }, [url]);\n\n return state;\n}\n```\n\n### 设计要点\n- AbortController 在组件卸载或 URL 变化时取消请求\n- 泛型 T 支持任意返回类型\n- 三态(loading/data/error)覆盖所有 UI 场景",
|
|
469
|
+
"pattern": "function useFetch<T>(url: string): FetchState<T> {\n const [state, setState] = useState<FetchState<T>>({ data: null, loading: true, error: null });\n useEffect(() => {\n const controller = new AbortController();\n fetch(url, { signal: controller.signal }).then(res => res.json()).then(data => setState({ data, loading: false, error: null }));\n return () => controller.abort();\n }, [url]);\n return state;\n}",
|
|
470
|
+
"rationale": "自定义 Hook 是 React 的标准复用模式,AbortController 防止内存泄漏,泛型确保类型安全。"
|
|
471
|
+
},
|
|
472
|
+
"usageGuide": "### When to Use\n- React 函数组件中需要 fetch 远程数据\n- 需要统一的 loading/error 状态管理\n\n### Key Points\n- URL 变化会自动重新请求\n- 组件卸载时自动取消进行中的请求\n- 返回 { data, loading, error } 三态\n\n### Common Pitfalls\n- 不要在 Hook 外部修改返回的 state\n- 复杂场景考虑使用 React Query / SWR",
|
|
473
|
+
"knowledgeType": "code-pattern",
|
|
474
|
+
"reasoning": {
|
|
475
|
+
"whyStandard": "自定义 Hook + AbortController 是 React 官方推荐的数据获取模式",
|
|
476
|
+
"sources": ["React documentation - Custom Hooks", "MDN AbortController"],
|
|
477
|
+
"confidence": 0.9
|
|
478
|
+
},
|
|
479
|
+
"keywords": ["react", "hook", "fetch", "typescript"],
|
|
480
|
+
"tags": ["ui", "pattern"]
|
|
481
|
+
}
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
### Example 6: Java — 泛型 Repository 模式
|
|
485
|
+
|
|
486
|
+
```json
|
|
487
|
+
{
|
|
488
|
+
"title": "泛型 Repository 接口",
|
|
489
|
+
"trigger": "@java-repo",
|
|
490
|
+
"category": "Service",
|
|
491
|
+
"language": "java",
|
|
492
|
+
"kind": "pattern",
|
|
493
|
+
"doClause": "Use generic Repository interface with Optional returns for type-safe data access",
|
|
494
|
+
"description": "Spring Data 风格泛型 Repository 接口,使用 Optional 避免空指针,统一数据访问层",
|
|
495
|
+
"headers": ["import java.util.Optional;", "import java.util.List;"],
|
|
496
|
+
"content": {
|
|
497
|
+
"markdown": "## 泛型 Repository 接口\n\n定义统一的泛型数据访问层接口,使用 Optional 返回值避免 NullPointerException,所有实体 Repository 统一实现此接口。\n\n```java\npublic interface Repository<T, ID> {\n Optional<T> findById(ID id);\n List<T> findAll();\n T save(T entity);\n void deleteById(ID id);\n boolean existsById(ID id);\n}\n\n// Implementation\npublic class UserRepository implements Repository<User, Long> {\n @Override\n public Optional<User> findById(Long id) {\n return Optional.ofNullable(queryResult);\n }\n\n @Override\n public User save(User entity) {\n // persist entity\n return entity;\n }\n // ... other methods\n}\n```\n\n### 设计要点\n- 泛型 <T, ID> 支持任意实体类型\n- Optional 返回避免 null 判断\n- 接口统一,实现可替换(内存/数据库/远程)",
|
|
498
|
+
"pattern": "public interface Repository<T, ID> {\n Optional<T> findById(ID id);\n List<T> findAll();\n T save(T entity);\n void deleteById(ID id);\n boolean existsById(ID id);\n}",
|
|
499
|
+
"rationale": "Repository 模式是 DDD 的核心模式,Spring Data 将其标准化。泛型接口减少重复代码,Optional 是 Java 8+ 避免 NPE 的标准做法。"
|
|
500
|
+
},
|
|
501
|
+
"usageGuide": "### When to Use\n- Java 项目需要统一的数据访问层\n- 使用 Spring Data 或自定义 ORM 时\n\n### Key Points\n- 每个实体创建对应的 Repository 实现\n- findById 返回 Optional,调用方用 orElse/orElseThrow 处理\n- save 方法同时处理新增和更新\n\n### Related Patterns\n- @java-service-layer 服务层模式\n- @java-entity-base 基础实体类",
|
|
502
|
+
"knowledgeType": "architecture",
|
|
503
|
+
"reasoning": {
|
|
504
|
+
"whyStandard": "Repository 模式是 Spring Data 的核心抽象,是 Java 企业级开发的行业标准",
|
|
505
|
+
"sources": ["Spring Data documentation", "Domain-Driven Design by Eric Evans"],
|
|
506
|
+
"confidence": 0.95
|
|
507
|
+
},
|
|
508
|
+
"keywords": ["repository", "generics", "optional", "pattern"],
|
|
509
|
+
"tags": ["architecture", "pattern"]
|
|
510
|
+
}
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### Example 7: Kotlin — 协程 Flow 数据流
|
|
514
|
+
|
|
515
|
+
```json
|
|
516
|
+
{
|
|
517
|
+
"title": "Kotlin Flow 异步数据流",
|
|
518
|
+
"trigger": "@kotlin-flow",
|
|
519
|
+
"category": "Service",
|
|
520
|
+
"language": "kotlin",
|
|
521
|
+
"kind": "pattern",
|
|
522
|
+
"doClause": "Use Kotlin Flow with retry and error handling for async data streams",
|
|
523
|
+
"description": "使用 Kotlin Flow 处理异步数据流,含 retry 重试和错误恢复机制",
|
|
524
|
+
"headers": ["import kotlinx.coroutines.flow.*", "import kotlinx.coroutines.delay"],
|
|
525
|
+
"content": {
|
|
526
|
+
"markdown": "## Kotlin Flow 异步数据流\n\n使用 Flow 构建响应式数据流,结合 retry 和 catch 操作符实现自动重试与错误恢复。\n\n```kotlin\nfun fetchUsersFlow(): Flow<List<User>> = flow {\n val users = apiClient.getUsers()\n emit(users)\n}.retry(retries = 3) { cause ->\n cause is IOException && run { delay(1000); true }\n}.catch { e ->\n emit(emptyList())\n logger.error(\"Failed to fetch users\", e)\n}.flowOn(Dispatchers.IO)\n\n// Collect in ViewModel\nviewModelScope.launch {\n fetchUsersFlow()\n .collect { users ->\n _uiState.value = UiState.Success(users)\n }\n}\n```\n\n### 设计要点\n- flow builder 在协程中发射数据\n- retry 操作符对 IOException 自动重试 3 次\n- catch 操作符兜底:发射空列表并记录日志\n- flowOn(Dispatchers.IO) 确保网络请求在 IO 线程",
|
|
527
|
+
"pattern": "fun fetchUsersFlow(): Flow<List<User>> = flow {\n val data = apiClient.getData()\n emit(data)\n}.retry(retries = 3) { cause ->\n cause is IOException && run { delay(1000); true }\n}.catch { e ->\n emit(emptyList())\n}.flowOn(Dispatchers.IO)",
|
|
528
|
+
"rationale": "Kotlin Flow 是 Kotlin 协程的标准响应式流 API,retry + catch 组合是处理不稳定数据源的最佳实践,flowOn 确保线程安全。"
|
|
529
|
+
},
|
|
530
|
+
"usageGuide": "### When to Use\n- Android/Kotlin 项目中需要响应式数据流\n- ViewModel 向 UI 层提供可观察数据\n\n### Key Points\n- collect 是终端操作符,必须在协程中调用\n- flowOn 只影响上游操作符\n- retry 中的 delay 实现退避策略\n\n### Common Pitfalls\n- 不要在 catch 之后再使用 retry\n- collect 在主线程调用时确保 flowOn 指定了合适的调度器\n\n### Related Patterns\n- @kotlin-stateflow StateFlow 状态管理\n- @kotlin-coroutine-scope 协程作用域",
|
|
531
|
+
"knowledgeType": "code-pattern",
|
|
532
|
+
"reasoning": {
|
|
533
|
+
"whyStandard": "Kotlin Flow 是 JetBrains 官方推荐的异步流 API,Google Android 团队推荐替代 RxJava",
|
|
534
|
+
"sources": ["Kotlin Flow documentation", "Android Developer Guide - Kotlin Flow"],
|
|
535
|
+
"confidence": 0.9
|
|
536
|
+
},
|
|
537
|
+
"keywords": ["flow", "coroutine", "async", "stream"],
|
|
538
|
+
"tags": ["async", "pattern"]
|
|
539
|
+
}
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Headers 格式速查表
|
|
543
|
+
|
|
544
|
+
| Language | headers 格式示例 |
|
|
545
|
+
|----------|-----------------|
|
|
546
|
+
| Swift | `["import Foundation"]`, `["import UIKit"]` |
|
|
547
|
+
| ObjC | `["#import <Foundation/Foundation.h>"]`, `["#import <UIKit/UIKit.h>"]` |
|
|
548
|
+
| Go | `["import \"net/http\""]`, `["import \"fmt\""]` |
|
|
549
|
+
| Python | `["import asyncio"]`, `["from pathlib import Path"]` |
|
|
550
|
+
| Java | `["import java.util.List;"]`, `["import java.util.Optional;"]` |
|
|
551
|
+
| Kotlin | `["import kotlinx.coroutines.flow.*"]` |
|
|
552
|
+
| JavaScript | `["import express from 'express'"]`, `["const fs = require('fs')"]` |
|
|
553
|
+
| TypeScript | `["import { useState } from 'react'"]`, `["import type { Config } from './types'"]` |
|
|
554
|
+
|
|
555
|
+
### Placeholder 格式速查表
|
|
556
|
+
|
|
557
|
+
| 目标 IDE | 格式 | 示例 |
|
|
558
|
+
|----------|------|------|
|
|
559
|
+
| Xcode | `<#name#>` | `<#URL#>`, `<#Token#>`, `<#completion#>` |
|
|
560
|
+
| VSCode | `${N:name}` | `${1:url}`, `${2:token}`, `${3:callback}` |
|
|
561
|
+
|
|
562
|
+
> **写法建议**: Recipe 源文件中统一使用 Xcode 格式 `<#...#>`,`asd install` 会自动按目标 IDE 转换。
|
|
563
|
+
|
|
564
|
+
---
|
|
565
|
+
|
|
354
566
|
## Snippet
|
|
355
567
|
|
|
356
568
|
- **Definition**: A single code snippet entry (title, trigger, body, headers, etc.) listed in the root spec or under `AutoSnippet/snippets/`.
|
|
357
|
-
- **Role**: Synced to Xcode CodeSnippets via **`asd install`**; developers insert by trigger or from the snippet library.
|
|
569
|
+
- **Role**: Synced to IDE (Xcode CodeSnippets / VSCode .code-snippets) via **`asd install`**; developers insert by trigger or from the snippet library.
|
|
358
570
|
- **Relation**: A Recipe can describe the same pattern as a Snippet; creating from Dashboard can produce both.
|
|
359
571
|
|
|
360
572
|
---
|
|
@@ -375,7 +587,7 @@ When `asd ui` is running in the project root, use the HTTP API for on-demand sem
|
|
|
375
587
|
| **Create Recipe** | Dashboard New Recipe; or write to `_draft_recipe.md` and watch auto-adds; or MCP `autosnippet_submit_knowledge_batch` | autosnippet-create |
|
|
376
588
|
| **Search & insert** | `ass` shortcut or `// as:search`, `asd search`, Dashboard search | autosnippet-search |
|
|
377
589
|
| **Audit review** | `// as:audit`; watch runs AI review against knowledge base | autosnippet-guard |
|
|
378
|
-
| **Dependency graph** | `AutoSnippet/AutoSnippet.spmmap.json`; `asd spm-map` to update; MCP graph tools for querying | autosnippet-structure |
|
|
590
|
+
| **Dependency graph** | `AutoSnippet/AutoSnippet.spmmap.json`; `asd spm-map` to update; MCP graph tools for querying (supports SPM/Node/Go/JVM/Python) | autosnippet-structure |
|
|
379
591
|
| **Vector store** | Built by `asd embed`; `autosnippet_search(mode=context)` for on-demand lookup. Use as context storage to save space | autosnippet-concepts / autosnippet-recipes |
|
|
380
592
|
| **MCP tools** | `autosnippet_search` (统合搜索), `autosnippet_guard` (Guard 检查) | — |
|
|
381
593
|
|
|
@@ -383,206 +595,6 @@ When `asd ui` is running in the project root, use the HTTP API for on-demand sem
|
|
|
383
595
|
|
|
384
596
|
---
|
|
385
597
|
|
|
386
|
-
## Project-Specific Context (BiliDemo Objective-C)
|
|
387
|
-
|
|
388
|
-
This project uses **Objective-C** and is organized around several key modules and patterns:
|
|
389
|
-
|
|
390
|
-
### Module Organization
|
|
391
|
-
|
|
392
|
-
| Module | Category | Primary Use Cases |
|
|
393
|
-
|--------|----------|-------------------|
|
|
394
|
-
| **BDNetworkControl** | Network | HTTP requests, response handling, retries, timeouts, status codes |
|
|
395
|
-
| **BDPyramid** | Service | Module system, lifecycle hooks, context management, startup monitoring |
|
|
396
|
-
| **BDUIKit** | UI | Custom UI components, alerts, views, collections, animations |
|
|
397
|
-
| **BDFoundation** | Utility | KVO patterns, NSArray/NSDictionary helpers, type safety |
|
|
398
|
-
| **BDAuthor** | View | Author profile pages, custom transitions, animations |
|
|
399
|
-
| **BDWBISigner** | Tool | URL parameter handling, WBI signature generation |
|
|
400
|
-
|
|
401
|
-
### Objective-C Recipe Best Practices
|
|
402
|
-
|
|
403
|
-
**Headers format** (complete imports, not just module names):
|
|
404
|
-
```yaml
|
|
405
|
-
headers:
|
|
406
|
-
- "#import <BDNetworkControl/BDBaseRequest.h>"
|
|
407
|
-
- "#import <BDNetworkControl/BDRequestDefine.h>"
|
|
408
|
-
```
|
|
409
|
-
|
|
410
|
-
**Trigger naming** (use class or pattern name):
|
|
411
|
-
- `@BDBaseRequest` - core class patterns
|
|
412
|
-
- `@BDBaseRequestRetry` - specific feature patterns
|
|
413
|
-
- `@BDPModule` - framework/architecture patterns
|
|
414
|
-
- `@KVOSafe` - safety/best practice patterns
|
|
415
|
-
- `@URLParameterConversion` - utility/helper patterns
|
|
416
|
-
|
|
417
|
-
**Category selection** (use 8 standard categories, not module names):
|
|
418
|
-
- `Network` - BDNetworkControl usage, API calls, response handling
|
|
419
|
-
- `Service` - BDPyramid modules, architecture, lifecycle
|
|
420
|
-
- `UI` - BDUIKit custom components, layouts
|
|
421
|
-
- `Utility` - helpers, converters, safe wrappers
|
|
422
|
-
- `Tool` - WBISigner, signature generation, specialized tools
|
|
423
|
-
- `View` - custom views, author pages, animations
|
|
424
|
-
- `Storage` - persistence, caching (if applicable)
|
|
425
|
-
- `Model` - data structures, model patterns (if applicable)
|
|
426
|
-
|
|
427
|
-
### Real-World Recipe Examples (BiliDemo)
|
|
428
|
-
|
|
429
|
-
**Example 1: Network Request Response Handling**
|
|
430
|
-
```yaml
|
|
431
|
-
id: BDBaseRequest.ResponseHandling
|
|
432
|
-
title: BDBaseRequest 响应与错误处理
|
|
433
|
-
trigger: @BDBaseRequestResponse
|
|
434
|
-
category: Network
|
|
435
|
-
language: objectivec
|
|
436
|
-
summary_cn: 使用 responseJson/responseString 获取成功响应,failure block 中使用 NSError。
|
|
437
|
-
summary_en: Use responseJson/responseString for success and NSError in failure block.
|
|
438
|
-
headers:
|
|
439
|
-
- "#import <BDNetworkControl/BDBaseRequest.h>"
|
|
440
|
-
keywords: [network, response, error-handling]
|
|
441
|
-
tags: [network]
|
|
442
|
-
version: "1.0.0"
|
|
443
|
-
author: team_name
|
|
444
|
-
deprecated: false
|
|
445
|
-
moduleName: BDNetworkControl
|
|
446
|
-
deps:
|
|
447
|
-
targets: ["BDNetworkControl"]
|
|
448
|
-
imports: ["BDNetworkControl"]
|
|
449
|
-
difficulty: beginner
|
|
450
|
-
authority: 3
|
|
451
|
-
---
|
|
452
|
-
|
|
453
|
-
## Snippet / Code Reference
|
|
454
|
-
|
|
455
|
-
```objc
|
|
456
|
-
[req startWithCompletionBlock:^(BDBaseRequest *r) {
|
|
457
|
-
id json = r.responseJson;
|
|
458
|
-
NSString *raw = r.responseString;
|
|
459
|
-
NSData *data = r.responseData;
|
|
460
|
-
NSInteger code = r.responseStatusCode;
|
|
461
|
-
NSDictionary *headers = r.responseHeaders;
|
|
462
|
-
} failure:^(BDBaseRequest *r, NSError *error) {
|
|
463
|
-
NSLog(@"Error domain: %@, code: %ld", error.domain, (long)error.code);
|
|
464
|
-
}];
|
|
465
|
-
```
|
|
466
|
-
|
|
467
|
-
## AI Context / Usage Guide
|
|
468
|
-
|
|
469
|
-
成功响应用 responseJson(自动 JSON 解析)、responseString(raw 文本)或 responseData(二进制);失败用 NSError 的 domain 和 code;可读 HTTP 状态码和响应头。
|
|
470
|
-
```
|
|
471
|
-
|
|
472
|
-
**Example 2: Module Lifecycle Pattern**
|
|
473
|
-
```yaml
|
|
474
|
-
id: BDPyramid.ModuleLifecycle
|
|
475
|
-
title: BDPyramid Module 定义与生命周期
|
|
476
|
-
trigger: @BDPyramidModule
|
|
477
|
-
category: Service
|
|
478
|
-
language: objectivec
|
|
479
|
-
summary_cn: 使用 ModuleDefine 声明组件,实现 BDPModuleProtocol 的注册和初始化方法。
|
|
480
|
-
summary_en: Define module with ModuleDefine and implement BDPModuleProtocol lifecycle.
|
|
481
|
-
headers:
|
|
482
|
-
- "#import <BDPyramid/BDPyramid.h>"
|
|
483
|
-
- "#import <BDPyramid/BDPModuleProtocol.h>"
|
|
484
|
-
keywords: [module, lifecycle, registration]
|
|
485
|
-
tags: [architecture]
|
|
486
|
-
version: "1.0.0"
|
|
487
|
-
author: team_name
|
|
488
|
-
deprecated: false
|
|
489
|
-
moduleName: BDPyramid
|
|
490
|
-
deps:
|
|
491
|
-
targets: ["BDPyramid"]
|
|
492
|
-
imports: ["BDPyramid"]
|
|
493
|
-
difficulty: intermediate
|
|
494
|
-
authority: 3
|
|
495
|
-
---
|
|
496
|
-
|
|
497
|
-
## Snippet / Code Reference
|
|
498
|
-
|
|
499
|
-
```objc
|
|
500
|
-
ModuleDefine(MyCustomModule);
|
|
501
|
-
|
|
502
|
-
@interface MyCustomModule : NSObject <BDPModuleProtocol>
|
|
503
|
-
@end
|
|
504
|
-
|
|
505
|
-
@implementation MyCustomModule
|
|
506
|
-
+ (NSInteger)modulePriority {
|
|
507
|
-
return BDPModulePriorityHigh; // Priority: higher = earlier execution
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
- (void)moduleRegister:(BDPContext *)context {
|
|
511
|
-
// Register module with framework, setup initial state
|
|
512
|
-
}
|
|
513
|
-
|
|
514
|
-
- (void)moduleInit:(BDPContext *)context {
|
|
515
|
-
// Initialize module after all modules registered
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
- (void)applicationEnvironmentDidSetup:(BDPContext *)context {
|
|
519
|
-
// Called when app environment ready (window visible, etc.)
|
|
520
|
-
}
|
|
521
|
-
@end
|
|
522
|
-
```
|
|
523
|
-
|
|
524
|
-
## AI Context / Usage Guide
|
|
525
|
-
|
|
526
|
-
Priority 值越大越先执行;moduleRegister 用于框架内注册,moduleInit 用于初始化逻辑;可以按需实现其他生命周期方法。
|
|
527
|
-
```
|
|
528
|
-
|
|
529
|
-
**Example 3: Safe KVO Pattern**
|
|
530
|
-
```yaml
|
|
531
|
-
id: NSObject.KVOSafe
|
|
532
|
-
title: NSObject KVO 安全添加与移除
|
|
533
|
-
trigger: @KVOSafe
|
|
534
|
-
category: Utility
|
|
535
|
-
language: objectivec
|
|
536
|
-
summary_cn: 避免 KVO 重复注册或泄漏,需配对 addObserver 和 removeObserver,避免循环引用。
|
|
537
|
-
summary_en: Pair addObserver/removeObserver to avoid leaks and crashes.
|
|
538
|
-
headers:
|
|
539
|
-
- "#import <Foundation/Foundation.h>"
|
|
540
|
-
keywords: [kvo, safety, lifecycle]
|
|
541
|
-
tags: [safety]
|
|
542
|
-
version: "1.0.0"
|
|
543
|
-
author: team_name
|
|
544
|
-
deprecated: false
|
|
545
|
-
moduleName: Foundation
|
|
546
|
-
deps:
|
|
547
|
-
targets: ["Foundation"]
|
|
548
|
-
imports: ["Foundation"]
|
|
549
|
-
difficulty: beginner
|
|
550
|
-
authority: 3
|
|
551
|
-
---
|
|
552
|
-
|
|
553
|
-
## Snippet / Code Reference
|
|
554
|
-
|
|
555
|
-
```objc
|
|
556
|
-
// Add observer (in init or setup)
|
|
557
|
-
[self.targetObject addObserver:self
|
|
558
|
-
forKeyPath:@"property"
|
|
559
|
-
options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld
|
|
560
|
-
context:NULL];
|
|
561
|
-
|
|
562
|
-
// Observe changes
|
|
563
|
-
- (void)observeValueForKeyPath:(NSString *)keyPath
|
|
564
|
-
ofObject:(id)object
|
|
565
|
-
change:(NSDictionary *)change
|
|
566
|
-
context:(void *)context {
|
|
567
|
-
if ([keyPath isEqualToString:@"property"]) {
|
|
568
|
-
id newValue = change[NSKeyValueChangeNewKey];
|
|
569
|
-
// Handle change
|
|
570
|
-
}
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
// Remove observer (in dealloc, CRITICAL)
|
|
574
|
-
- (void)dealloc {
|
|
575
|
-
[self.targetObject removeObserver:self forKeyPath:@"property"];
|
|
576
|
-
}
|
|
577
|
-
```
|
|
578
|
-
|
|
579
|
-
## AI Context / Usage Guide
|
|
580
|
-
|
|
581
|
-
必须在 dealloc 中移除,否则会导致 EXC_BAD_ACCESS;使用 weakly-held reference 避免循环引用;可用 context 参数区分多个观察者。
|
|
582
|
-
```
|
|
583
|
-
|
|
584
|
-
---
|
|
585
|
-
|
|
586
598
|
## Introducing and using new knowledge
|
|
587
599
|
|
|
588
600
|
**New knowledge** means content not yet in the knowledge base, or just submitted as candidates (new Recipe, new doc). How to add and use it:
|