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.
Files changed (290) hide show
  1. package/README.md +230 -324
  2. package/bin/api-server.js +1 -1
  3. package/bin/cli.js +204 -244
  4. package/bin/mcp-server.js +5 -3
  5. package/config/knowledge-base.config.js +132 -132
  6. package/dashboard/dist/assets/{icons-CEfgGaZi.js → icons-Cdq22n2i.js} +95 -100
  7. package/dashboard/dist/assets/index-ClkyPkDX.js +133 -0
  8. package/dashboard/dist/assets/index-t4QrJwv1.css +1 -0
  9. package/dashboard/dist/index.html +3 -3
  10. package/lib/bootstrap.js +8 -8
  11. package/lib/cli/AiScanService.js +86 -40
  12. package/lib/cli/KnowledgeSyncService.js +113 -74
  13. package/lib/cli/SetupService.js +439 -277
  14. package/lib/cli/UpgradeService.js +63 -100
  15. package/lib/core/AstAnalyzer.js +276 -597
  16. package/lib/core/ast/ProjectGraph.js +101 -40
  17. package/lib/core/ast/ensure-grammars.js +232 -0
  18. package/lib/core/ast/index.js +115 -0
  19. package/lib/core/ast/lang-dart.js +661 -0
  20. package/lib/core/ast/lang-go.js +530 -0
  21. package/lib/core/ast/lang-java.js +435 -0
  22. package/lib/core/ast/lang-javascript.js +272 -0
  23. package/lib/core/ast/lang-kotlin.js +423 -0
  24. package/lib/core/ast/lang-objc.js +388 -0
  25. package/lib/core/ast/lang-python.js +371 -0
  26. package/lib/core/ast/lang-swift.js +337 -0
  27. package/lib/core/ast/lang-typescript.js +503 -0
  28. package/lib/core/capability/CapabilityProbe.js +18 -9
  29. package/lib/core/constitution/Constitution.js +2 -3
  30. package/lib/core/constitution/ConstitutionValidator.js +65 -24
  31. package/lib/core/discovery/DartDiscoverer.js +534 -0
  32. package/lib/core/discovery/DiscovererRegistry.js +83 -0
  33. package/lib/core/discovery/GenericDiscoverer.js +225 -0
  34. package/lib/core/discovery/GoDiscoverer.js +541 -0
  35. package/lib/core/discovery/JvmDiscoverer.js +506 -0
  36. package/lib/core/discovery/NodeDiscoverer.js +466 -0
  37. package/lib/core/discovery/ProjectDiscoverer.js +93 -0
  38. package/lib/core/discovery/PythonDiscoverer.js +338 -0
  39. package/lib/core/discovery/SpmDiscoverer.js +5 -0
  40. package/lib/core/discovery/index.js +53 -0
  41. package/lib/core/enhancement/EnhancementPack.js +71 -0
  42. package/lib/core/enhancement/EnhancementRegistry.js +47 -0
  43. package/lib/core/enhancement/android-enhancement.js +102 -0
  44. package/lib/core/enhancement/django-enhancement.js +70 -0
  45. package/lib/core/enhancement/fastapi-enhancement.js +63 -0
  46. package/lib/core/enhancement/go-grpc-enhancement.js +152 -0
  47. package/lib/core/enhancement/go-web-enhancement.js +201 -0
  48. package/lib/core/enhancement/index.js +65 -0
  49. package/lib/core/enhancement/node-server-enhancement.js +88 -0
  50. package/lib/core/enhancement/react-enhancement.js +86 -0
  51. package/lib/core/enhancement/spring-enhancement.js +112 -0
  52. package/lib/core/enhancement/vue-enhancement.js +96 -0
  53. package/lib/core/gateway/Gateway.js +8 -9
  54. package/lib/core/gateway/GatewayActionRegistry.js +1 -1
  55. package/lib/core/permission/PermissionManager.js +12 -8
  56. package/lib/domain/index.js +13 -9
  57. package/lib/domain/knowledge/KnowledgeEntry.js +111 -101
  58. package/lib/domain/knowledge/KnowledgeRepository.js +0 -1
  59. package/lib/domain/knowledge/Lifecycle.js +22 -22
  60. package/lib/domain/knowledge/index.js +9 -12
  61. package/lib/domain/knowledge/values/Constraints.js +31 -21
  62. package/lib/domain/knowledge/values/Content.js +21 -13
  63. package/lib/domain/knowledge/values/Quality.js +31 -18
  64. package/lib/domain/knowledge/values/Reasoning.js +20 -12
  65. package/lib/domain/knowledge/values/Relations.js +37 -25
  66. package/lib/domain/knowledge/values/Stats.js +18 -12
  67. package/lib/domain/knowledge/values/index.js +4 -3
  68. package/lib/domain/snippet/Snippet.js +35 -10
  69. package/lib/external/ai/AiFactory.js +48 -16
  70. package/lib/external/ai/AiProvider.js +184 -90
  71. package/lib/external/ai/providers/ClaudeProvider.js +25 -12
  72. package/lib/external/ai/providers/GoogleGeminiProvider.js +59 -30
  73. package/lib/external/ai/providers/MockProvider.js +9 -3
  74. package/lib/external/ai/providers/OpenAiProvider.js +51 -29
  75. package/lib/external/mcp/McpServer.js +66 -36
  76. package/lib/external/mcp/errorHandler.js +23 -11
  77. package/lib/external/mcp/handlers/LanguageExtensions.js +138 -53
  78. package/lib/external/mcp/handlers/TargetClassifier.js +52 -16
  79. package/lib/external/mcp/handlers/bootstrap/pipeline/BootstrapSnapshot.js +81 -20
  80. package/lib/external/mcp/handlers/bootstrap/pipeline/EpisodicMemory.js +71 -42
  81. package/lib/external/mcp/handlers/bootstrap/pipeline/IncrementalBootstrap.js +9 -17
  82. package/lib/external/mcp/handlers/bootstrap/pipeline/ToolResultCache.js +14 -9
  83. package/lib/external/mcp/handlers/bootstrap/pipeline/dimension-context.js +15 -7
  84. package/lib/external/mcp/handlers/bootstrap/pipeline/orchestrator.js +352 -153
  85. package/lib/external/mcp/handlers/bootstrap/pipeline/tier-scheduler.js +52 -12
  86. package/lib/external/mcp/handlers/bootstrap/skills.js +143 -39
  87. package/lib/external/mcp/handlers/bootstrap.js +691 -168
  88. package/lib/external/mcp/handlers/browse.js +66 -22
  89. package/lib/external/mcp/handlers/candidate.js +118 -35
  90. package/lib/external/mcp/handlers/consolidated.js +49 -17
  91. package/lib/external/mcp/handlers/guard.js +104 -39
  92. package/lib/external/mcp/handlers/knowledge.js +60 -36
  93. package/lib/external/mcp/handlers/search.js +43 -14
  94. package/lib/external/mcp/handlers/skill.js +120 -45
  95. package/lib/external/mcp/handlers/structure.js +240 -86
  96. package/lib/external/mcp/handlers/system.js +42 -12
  97. package/lib/external/mcp/handlers/wiki.js +58 -33
  98. package/lib/external/mcp/tools.js +306 -123
  99. package/lib/http/HttpServer.js +72 -47
  100. package/lib/http/middleware/RateLimiter.js +5 -3
  101. package/lib/http/middleware/errorHandler.js +6 -1
  102. package/lib/http/middleware/requestLogger.js +14 -3
  103. package/lib/http/middleware/roleResolver.js +30 -23
  104. package/lib/http/routes/ai.js +387 -265
  105. package/lib/http/routes/auth.js +81 -61
  106. package/lib/http/routes/candidates.js +430 -320
  107. package/lib/http/routes/commands.js +289 -189
  108. package/lib/http/routes/extract.js +158 -125
  109. package/lib/http/routes/guardRules.js +309 -217
  110. package/lib/http/routes/knowledge.js +213 -154
  111. package/lib/http/routes/modules.js +578 -0
  112. package/lib/http/routes/monitoring.js +6 -6
  113. package/lib/http/routes/recipes.js +104 -93
  114. package/lib/http/routes/search.js +361 -305
  115. package/lib/http/routes/skills.js +145 -98
  116. package/lib/http/routes/snippets.js +42 -30
  117. package/lib/http/routes/spm.js +3 -405
  118. package/lib/http/routes/violations.js +113 -93
  119. package/lib/http/routes/wiki.js +211 -170
  120. package/lib/http/utils/routeHelpers.js +3 -1
  121. package/lib/http/utils/sse-sessions.js +16 -6
  122. package/lib/http/utils/sse.js +15 -5
  123. package/lib/infrastructure/audit/AuditLogger.js +5 -2
  124. package/lib/infrastructure/audit/AuditStore.js +10 -7
  125. package/lib/infrastructure/cache/CacheService.js +3 -1
  126. package/lib/infrastructure/cache/GraphCache.js +8 -4
  127. package/lib/infrastructure/cache/UnifiedCacheAdapter.js +1 -1
  128. package/lib/infrastructure/config/ConfigLoader.js +9 -5
  129. package/lib/infrastructure/config/Defaults.js +30 -10
  130. package/lib/infrastructure/config/Paths.js +28 -8
  131. package/lib/infrastructure/config/TriggerSymbol.js +22 -10
  132. package/lib/infrastructure/database/DatabaseConnection.js +15 -10
  133. package/lib/infrastructure/database/migrations/001_initial_schema.js +0 -1
  134. package/lib/infrastructure/external/ClipboardManager.js +6 -2
  135. package/lib/infrastructure/external/NativeUi.js +50 -43
  136. package/lib/infrastructure/external/OpenBrowser.js +14 -17
  137. package/lib/infrastructure/external/XcodeAutomation.js +14 -258
  138. package/lib/infrastructure/logging/Logger.js +46 -30
  139. package/lib/infrastructure/monitoring/ErrorTracker.js +7 -5
  140. package/lib/infrastructure/monitoring/PerformanceMonitor.js +12 -4
  141. package/lib/infrastructure/paths/HeaderResolver.js +25 -9
  142. package/lib/infrastructure/paths/PathFinder.js +34 -12
  143. package/lib/infrastructure/plugin/PluginManager.js +26 -8
  144. package/lib/infrastructure/realtime/RealtimeService.js +2 -2
  145. package/lib/infrastructure/vector/Chunker.js +22 -7
  146. package/lib/infrastructure/vector/IndexingPipeline.js +46 -22
  147. package/lib/infrastructure/vector/JsonVectorAdapter.js +90 -53
  148. package/lib/infrastructure/vector/VectorStore.js +28 -10
  149. package/lib/injection/ServiceContainer.js +247 -93
  150. package/lib/platform/ios/index.js +63 -0
  151. package/lib/platform/ios/routes/spm.js +437 -0
  152. package/lib/platform/ios/snippet/PlaceholderConverter.js +55 -0
  153. package/lib/platform/ios/snippet/XcodeCodec.js +112 -0
  154. package/lib/{service → platform/ios}/spm/DependencyGraph.js +41 -17
  155. package/lib/{service → platform/ios}/spm/PackageSwiftParser.js +41 -14
  156. package/lib/{service → platform/ios}/spm/PolicyEngine.js +9 -4
  157. package/lib/platform/ios/spm/SpmDiscoverer.js +122 -0
  158. package/lib/{service → platform/ios}/spm/SpmService.js +385 -127
  159. package/lib/{service/automation → platform/ios/xcode}/SaveEventFilter.js +8 -7
  160. package/lib/platform/ios/xcode/XcodeAutomation.js +350 -0
  161. package/lib/{service/automation → platform/ios/xcode}/XcodeIntegration.js +325 -145
  162. package/lib/repository/base/BaseRepository.js +7 -9
  163. package/lib/repository/knowledge/KnowledgeRepository.impl.js +98 -75
  164. package/lib/repository/token/TokenUsageStore.js +4 -2
  165. package/lib/service/automation/ActionPipeline.js +1 -1
  166. package/lib/service/automation/AutomationOrchestrator.js +8 -4
  167. package/lib/service/automation/ContextCollector.js +7 -5
  168. package/lib/service/automation/DirectiveDetector.js +23 -16
  169. package/lib/service/automation/FileWatcher.js +112 -56
  170. package/lib/service/automation/TriggerResolver.js +6 -4
  171. package/lib/service/automation/handlers/AlinkHandler.js +24 -12
  172. package/lib/service/automation/handlers/CreateHandler.js +19 -20
  173. package/lib/service/automation/handlers/DraftHandler.js +14 -8
  174. package/lib/service/automation/handlers/GuardHandler.js +93 -63
  175. package/lib/service/automation/handlers/HeaderHandler.js +1 -6
  176. package/lib/service/automation/handlers/SearchHandler.js +155 -88
  177. package/lib/service/bootstrap/BootstrapTaskManager.js +77 -35
  178. package/lib/service/candidate/SimilarityService.js +25 -9
  179. package/lib/service/chat/AnalystAgent.js +50 -24
  180. package/lib/service/chat/CandidateGuardrail.js +143 -17
  181. package/lib/service/chat/ChatAgent.js +759 -243
  182. package/lib/service/chat/ContextWindow.js +116 -71
  183. package/lib/service/chat/ConversationStore.js +77 -36
  184. package/lib/service/chat/EpisodicConsolidator.js +47 -23
  185. package/lib/service/chat/HandoffProtocol.js +98 -22
  186. package/lib/service/chat/Memory.js +34 -14
  187. package/lib/service/chat/ProducerAgent.js +40 -20
  188. package/lib/service/chat/ProjectSemanticMemory.js +109 -78
  189. package/lib/service/chat/ReasoningLayer.js +148 -70
  190. package/lib/service/chat/ReasoningTrace.js +44 -32
  191. package/lib/service/chat/TaskPipeline.js +39 -19
  192. package/lib/service/chat/ToolRegistry.js +48 -29
  193. package/lib/service/chat/WorkingMemory.js +44 -18
  194. package/lib/service/chat/tools.js +1096 -494
  195. package/lib/service/context/RecipeExtractor.js +132 -51
  196. package/lib/service/cursor/CursorDeliveryPipeline.js +82 -37
  197. package/lib/service/cursor/KnowledgeCompressor.js +25 -22
  198. package/lib/service/cursor/RulesGenerator.js +13 -7
  199. package/lib/service/cursor/SkillsSyncer.js +77 -27
  200. package/lib/service/cursor/TokenBudget.js +2 -2
  201. package/lib/service/cursor/TopicClassifier.js +54 -20
  202. package/lib/service/guard/ComplianceReporter.js +55 -43
  203. package/lib/service/guard/ExclusionManager.js +67 -29
  204. package/lib/service/guard/GuardCheckEngine.js +381 -86
  205. package/lib/service/guard/GuardFeedbackLoop.js +22 -10
  206. package/lib/service/guard/GuardService.js +29 -19
  207. package/lib/service/guard/RuleLearner.js +55 -23
  208. package/lib/service/guard/SourceFileCollector.js +27 -20
  209. package/lib/service/guard/ViolationsStore.js +43 -38
  210. package/lib/service/knowledge/CodeEntityGraph.js +147 -82
  211. package/lib/service/knowledge/ConfidenceRouter.js +12 -10
  212. package/lib/service/knowledge/KnowledgeFileWriter.js +147 -56
  213. package/lib/service/knowledge/KnowledgeGraphService.js +81 -34
  214. package/lib/service/knowledge/KnowledgeService.js +222 -112
  215. package/lib/service/module/ModuleService.js +969 -0
  216. package/lib/service/quality/FeedbackCollector.js +27 -15
  217. package/lib/service/quality/QualityScorer.js +78 -24
  218. package/lib/service/recipe/RecipeCandidateValidator.js +110 -44
  219. package/lib/service/recipe/RecipeParser.js +78 -45
  220. package/lib/service/search/CoarseRanker.js +43 -28
  221. package/lib/service/search/CrossEncoderReranker.js +32 -21
  222. package/lib/service/search/InvertedIndex.js +21 -7
  223. package/lib/service/search/MultiSignalRanker.js +90 -28
  224. package/lib/service/search/RetrievalFunnel.js +45 -24
  225. package/lib/service/search/SearchEngine.js +255 -103
  226. package/lib/service/skills/EventAggregator.js +32 -15
  227. package/lib/service/skills/SignalCollector.js +140 -64
  228. package/lib/service/skills/SkillAdvisor.js +79 -42
  229. package/lib/service/skills/SkillHooks.js +16 -14
  230. package/lib/service/snippet/PlaceholderConverter.js +5 -0
  231. package/lib/service/snippet/SnippetFactory.js +116 -99
  232. package/lib/service/snippet/SnippetInstaller.js +234 -62
  233. package/lib/service/snippet/codecs/SnippetCodec.js +67 -0
  234. package/lib/service/snippet/codecs/VSCodeCodec.js +102 -0
  235. package/lib/service/snippet/codecs/XcodeCodec.js +5 -0
  236. package/lib/service/wiki/WikiGenerator.js +637 -263
  237. package/lib/shared/DimensionCopyRegistry.js +472 -0
  238. package/lib/shared/LanguageService.js +399 -0
  239. package/lib/shared/PathGuard.js +45 -28
  240. package/lib/shared/RecipeReadinessChecker.js +72 -12
  241. package/lib/shared/constants.js +41 -41
  242. package/lib/shared/errors/BaseError.js +2 -2
  243. package/lib/shared/errors/index.js +4 -4
  244. package/lib/shared/similarity.js +25 -8
  245. package/lib/shared/token-utils.js +6 -2
  246. package/lib/shared/utils/common.js +12 -4
  247. package/package.json +49 -13
  248. package/scripts/bench-real-projects.mjs +256 -0
  249. package/scripts/build-native-ui.js +30 -30
  250. package/scripts/clear-old-vector-index.js +5 -35
  251. package/scripts/clear-vector-cache.js +7 -37
  252. package/scripts/collect-test-project-stats.mjs +160 -0
  253. package/scripts/diagnose-mcp.js +41 -32
  254. package/scripts/ensure-parse-package.js +6 -9
  255. package/scripts/generate-recipe-drafts.js +116 -77
  256. package/scripts/init-db.js +3 -20
  257. package/scripts/init-snippets.js +305 -0
  258. package/scripts/init-vector-db.js +173 -170
  259. package/scripts/install-cursor-skill.js +148 -104
  260. package/scripts/install-full.js +8 -21
  261. package/scripts/install-vscode-copilot.js +146 -145
  262. package/scripts/migrate-md-to-knowledge.mjs +139 -151
  263. package/scripts/postinstall-safe.js +5 -17
  264. package/scripts/recipe-audit.js +106 -82
  265. package/scripts/release.js +283 -323
  266. package/scripts/setup-mcp-config.js +60 -52
  267. package/scripts/verify-context-api.js +20 -20
  268. package/skills/autosnippet-analysis/SKILL.md +10 -6
  269. package/skills/autosnippet-candidates/SKILL.md +27 -26
  270. package/skills/autosnippet-coldstart/SKILL.md +555 -38
  271. package/skills/autosnippet-concepts/SKILL.md +349 -337
  272. package/skills/autosnippet-create/SKILL.md +5 -5
  273. package/skills/autosnippet-reference-dart/SKILL.md +543 -0
  274. package/skills/autosnippet-reference-go/SKILL.md +539 -0
  275. package/skills/autosnippet-reference-java/SKILL.md +534 -0
  276. package/skills/autosnippet-reference-jsts/SKILL.md +41 -9
  277. package/skills/autosnippet-reference-kotlin/SKILL.md +526 -0
  278. package/skills/autosnippet-reference-objc/SKILL.md +29 -6
  279. package/skills/autosnippet-reference-python/SKILL.md +800 -0
  280. package/skills/autosnippet-reference-swift/SKILL.md +70 -14
  281. package/skills/autosnippet-structure/SKILL.md +4 -4
  282. package/templates/cursor-rules/autosnippet-conventions.mdc +2 -2
  283. package/templates/recipes-setup/README.md +2 -2
  284. package/templates/recipes-setup/_template.md +1 -1
  285. package/dashboard/dist/assets/index-Bun3ld_J.css +0 -1
  286. package/dashboard/dist/assets/index-_Sk_Dmg3.js +0 -143
  287. package/resources/asd-entry/main.swift +0 -159
  288. package/scripts/build-asd-entry.js +0 -51
  289. package/scripts/init-xcode-snippets.js +0 -311
  290. package/template.json +0 -39
@@ -1,159 +0,0 @@
1
- #!/usr/bin/env swift
2
- /*
3
- * AutoSnippet 完整性校验入口(Swift,仅 macOS)
4
- * 读 checksums.json,校验关键文件 SHA-256,通过则设置 ASD_VERIFIED=1 并 spawn node bin/asd-cli.js。
5
- * 收到 SIGINT/SIGTERM 时转发给子进程,避免 asd ui 按 Ctrl+C 后 Node 成为孤儿进程占用 3000 端口。
6
- * 构建:node scripts/build-asd-entry.js,产物 bin/asd-verify。
7
- */
8
-
9
- import Foundation
10
- import CryptoKit
11
- import Dispatch
12
-
13
- func fail(_ msg: String) -> Never {
14
- fputs(msg + "\n", stderr)
15
- exit(1)
16
- }
17
-
18
- /// 从可执行路径解析包根目录(bin/asd-verify 的上级的上级)
19
- func getPackageRoot() -> String? {
20
- let argv0 = CommandLine.arguments[0]
21
- let path = (argv0 as NSString).standardizingPath
22
- var url = URL(fileURLWithPath: path)
23
- if path != (path as NSString).resolvingSymlinksInPath {
24
- url = URL(fileURLWithPath: (path as NSString).resolvingSymlinksInPath)
25
- }
26
- var dir = url.deletingLastPathComponent().path // bin
27
- dir = (dir as NSString).deletingLastPathComponent // package root
28
- return dir
29
- }
30
-
31
- /// 文件内容 SHA-256 小写 hex
32
- func sha256Hex(filePath: String) -> String? {
33
- guard let data = try? Data(contentsOf: URL(fileURLWithPath: filePath)) else { return nil }
34
- let hash = SHA256.hash(data: data)
35
- return hash.map { String(format: "%02x", $0) }.joined()
36
- }
37
-
38
- /// 校验 checksums.json 中列出的文件。拒绝 relPath 含 ".." 或为绝对路径。
39
- /// 根据环境变量决定是否打印详细信息(开发者模式)。
40
- func verifyIntegrity(root: String, checksumsPath: String, debugMode: Bool) -> Bool {
41
- guard let data = try? Data(contentsOf: URL(fileURLWithPath: checksumsPath)) else {
42
- if debugMode {
43
- fputs("asd: 无法读取 checksums.json\n", stderr)
44
- }
45
- return false
46
- }
47
- guard let json = try? JSONSerialization.jsonObject(with: data),
48
- let entries = json as? [String: String] else {
49
- if debugMode {
50
- fputs("asd: checksums.json 格式无效\n", stderr)
51
- }
52
- return false
53
- }
54
- let rootNorm = (root as NSString).standardizingPath
55
- for (relPath, expectedHex) in entries {
56
- if relPath.hasPrefix("/") || relPath.contains("..") {
57
- if debugMode {
58
- fputs("asd: 校验拒绝非法路径: \(relPath)\n", stderr)
59
- }
60
- return false
61
- }
62
- let fullPath = (root as NSString).appendingPathComponent(relPath)
63
- let fullNorm = (fullPath as NSString).standardizingPath
64
- let rootSlash = rootNorm.hasSuffix("/") ? rootNorm : rootNorm + "/"
65
- guard fullNorm == rootNorm || fullNorm.hasPrefix(rootSlash) else {
66
- if debugMode {
67
- fputs("asd: 校验拒绝路径逃逸: \(relPath)\n", stderr)
68
- }
69
- return false
70
- }
71
- guard let actualHex = sha256Hex(filePath: fullPath) else {
72
- if debugMode {
73
- fputs("asd: 完整性校验失败: \(relPath)\n", stderr)
74
- } else {
75
- fputs("asd: 完整性校验失败\n", stderr)
76
- }
77
- return false
78
- }
79
- if actualHex.lowercased() != expectedHex.lowercased() {
80
- if debugMode {
81
- fputs("asd: 完整性校验失败: \(relPath)\n", stderr)
82
- } else {
83
- fputs("asd: 完整性校验失败\n", stderr)
84
- }
85
- return false
86
- }
87
- }
88
- return true
89
- }
90
-
91
- /// 执行 node bin/asd-cli.js [args...],将调用时的 cwd 传入 ASD_CWD,校验通过则设 ASD_VERIFIED=1。
92
- /// 收到 SIGINT/SIGTERM 时转发给子进程,避免 asd ui 按 Ctrl+C 后 Node 未退出导致 3000 端口被占用。
93
- func spawnNode(root: String, integrityVerified: Bool) -> Int32 {
94
- let asnipPath = (root as NSString).appendingPathComponent("bin/asd-cli.js")
95
- guard FileManager.default.fileExists(atPath: asnipPath) else {
96
- fail("asd: 未找到 bin/asd-cli.js")
97
- }
98
- let nodeArgs = ["node", asnipPath] + Array(CommandLine.arguments.dropFirst())
99
- let process = Process()
100
- process.executableURL = URL(fileURLWithPath: "/usr/bin/env")
101
- process.arguments = nodeArgs
102
- process.currentDirectoryURL = URL(fileURLWithPath: root)
103
- var env = ProcessInfo.processInfo.environment
104
- env["ASD_CWD"] = FileManager.default.currentDirectoryPath
105
- if integrityVerified {
106
- env["ASD_VERIFIED"] = "1"
107
- }
108
- process.environment = env
109
- process.standardInput = FileHandle.standardInput
110
- process.standardOutput = FileHandle.standardOutput
111
- process.standardError = FileHandle.standardError
112
- do {
113
- try process.run()
114
- // 转发 SIGINT/SIGTERM 给子进程,避免 Ctrl+C 后仅 asd-verify 退出、Node 成为孤儿占用端口
115
- signal(SIGINT, SIG_IGN)
116
- signal(SIGTERM, SIG_IGN)
117
- let queue = DispatchQueue.main
118
- let sigintSource = DispatchSource.makeSignalSource(signal: SIGINT, queue: queue)
119
- let sigtermSource = DispatchSource.makeSignalSource(signal: SIGTERM, queue: queue)
120
- sigintSource.setEventHandler { process.terminate() }
121
- sigtermSource.setEventHandler { process.terminate() }
122
- sigintSource.resume()
123
- sigtermSource.resume()
124
- process.waitUntilExit()
125
- return process.terminationStatus
126
- } catch {
127
- fail("asd: 启动 node 失败: \(error.localizedDescription)")
128
- }
129
- }
130
-
131
- // MARK: - Main
132
- // 使用环境变量 ASD_SKIP_CHECKSUMS=1 或 ASD_SKIP_ENTRY_CHECK=1 可跳过完整性校验(仅限开发者模式)
133
- // 使用环境变量 ASD_DEBUG=1 可打印详细校验信息
134
-
135
- let skipChecksums = ProcessInfo.processInfo.environment["ASD_SKIP_CHECKSUMS"] == "1" ||
136
- ProcessInfo.processInfo.environment["ASD_SKIP_ENTRY_CHECK"] == "1"
137
- let debugMode = ProcessInfo.processInfo.environment["ASD_DEBUG"] == "1"
138
-
139
- guard let root = getPackageRoot() else {
140
- fail("asd: 无法解析包根目录")
141
- }
142
-
143
- let checksumsPath = (root as NSString).appendingPathComponent("checksums.json")
144
- var integrityVerified = false
145
-
146
- // 如果开发者模式跳过校验,直接启动 Node
147
- if skipChecksums {
148
- if debugMode {
149
- fputs("asd: 开发者模式,跳过完整性校验\n", stderr)
150
- }
151
- integrityVerified = false
152
- } else if FileManager.default.fileExists(atPath: checksumsPath) {
153
- if !verifyIntegrity(root: root, checksumsPath: checksumsPath, debugMode: debugMode) {
154
- exit(1)
155
- }
156
- integrityVerified = true
157
- }
158
-
159
- exit(spawnNode(root: root, integrityVerified: integrityVerified))
@@ -1,51 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * 构建 asd 完整性校验入口(Swift,仅 macOS)。产物:bin/asd-verify。
5
- * 若不存在或构建失败,将直接使用 node bin/cli.js。
6
- */
7
-
8
- import { fileURLToPath } from 'node:url';
9
- import { dirname } from 'node:path';
10
- const __filename = fileURLToPath(import.meta.url);
11
- const __dirname = dirname(__filename);
12
-
13
- import { execSync } from 'node:child_process';
14
- import path from 'node:path';
15
- import fs from 'node:fs';
16
-
17
- if (process.platform !== 'darwin') process.exit(0);
18
-
19
- const root = path.resolve(__dirname, '..');
20
- const src = path.join(root, 'resources', 'asd-entry', 'main.swift');
21
- const out = path.join(root, 'bin', 'asd-verify');
22
-
23
- // 检查是否在发布流程中
24
- const isPublishing = process.env.npm_lifecycle_event === 'prepublishOnly';
25
-
26
- try {
27
- fs.mkdirSync(path.join(root, 'bin'), { recursive: true });
28
- execSync(`swiftc "${src}" -o "${out}"`, { cwd: root, stdio: 'pipe' });
29
-
30
- // 验证构建结果
31
- if (fs.existsSync(out)) {
32
- console.log('✅ ASD Entry 构建成功');
33
- }
34
- } catch (err) {
35
- // 如果在发布流程中构建失败,应该报错
36
- if (isPublishing) {
37
- console.error('❌ ASD Entry 构建失败(发布流程中)');
38
- console.error('请确保:');
39
- console.error(' 1. 当前系统是 macOS');
40
- console.error(' 2. 已安装 Xcode Command Line Tools: xcode-select --install');
41
- console.error(' 3. Swift 编译器可用: which swiftc');
42
- process.exit(1);
43
- }
44
-
45
- // 在用户安装时,如果已有预编译的二进制文件,静默跳过
46
- if (fs.existsSync(out)) {
47
- console.log('ℹ️ 使用预编译的 ASD Entry');
48
- } else {
49
- console.log('⚠️ ASD Entry 未构建(将使用 Node.js 入口)');
50
- }
51
- }
@@ -1,311 +0,0 @@
1
- #!/usr/bin/env node
2
-
3
- /**
4
- * Xcode Snippet 初始化脚本
5
- * 自动为 AutoSnippet 添加快速输入 Snippets 到 Xcode
6
- *
7
- * 用法:
8
- * node scripts/init-xcode-snippets.js
9
- * npm run init-snippets
10
- */
11
-
12
- import { execSync } from 'node:child_process';
13
- import fs from 'node:fs';
14
- import path from 'node:path';
15
- import os from 'node:os';
16
-
17
- class XcodeSnippetInitializer {
18
- constructor() {
19
- this.snippetsDir = path.join(
20
- os.homedir(),
21
- 'Library/Developer/Xcode/UserData/CodeSnippets'
22
- );
23
-
24
- this.snippets = [
25
- {
26
- id: 'com.autosnippet.search.long',
27
- shortcut: 'ass',
28
- title: 'AutoSnippet: Search (Long)',
29
- summary: 'Search and insert Recipe/Snippet from knowledge base',
30
- content: '// as:search <#keyword#>',
31
- scopes: ['All']
32
- },
33
- {
34
- id: 'com.autosnippet.create',
35
- shortcut: 'asc',
36
- title: 'AutoSnippet: Create Recipe',
37
- summary: 'Create new Recipe (Dashboard or clipboard/file)',
38
- content: '// as:create <#-c or -f#>',
39
- scopes: ['All']
40
- },
41
- {
42
- id: 'com.autosnippet.audit',
43
- shortcut: 'asa',
44
- title: 'AutoSnippet: Audit Code',
45
- summary: 'AI code review against knowledge base',
46
- content: '// as:audit <#keyword or scope (file/target/project)#>',
47
- scopes: ['All']
48
- }
49
- ];
50
- }
51
-
52
- /**
53
- * 生成 plist 格式的 Snippet 文件内容
54
- */
55
- generateSnippetPlist(snippet) {
56
- const escapedContent = snippet.content
57
- .replace(/&/g, '&amp;')
58
- .replace(/</g, '&lt;')
59
- .replace(/>/g, '&gt;')
60
- .replace(/"/g, '&quot;')
61
- .replace(/'/g, '&apos;');
62
-
63
- const scopesXml = snippet.scopes
64
- .map(scope => ` <string>${scope}</string>`)
65
- .join('\n');
66
-
67
- return `<?xml version="1.0" encoding="UTF-8"?>
68
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
69
- <plist version="1.0">
70
- <dict>
71
- <key>IDECodeSnippetCompletionPrefix</key>
72
- <string>${snippet.shortcut}</string>
73
- <key>IDECodeSnippetCompletionScopes</key>
74
- <array>
75
- ${scopesXml}
76
- </array>
77
- <key>IDECodeSnippetContents</key>
78
- <string>${escapedContent}</string>
79
- <key>IDECodeSnippetIdentifier</key>
80
- <string>${snippet.id}</string>
81
- <key>IDECodeSnippetLanguage</key>
82
- <string>Xcode.SourceCodeLanguage.Generic</string>
83
- <key>IDECodeSnippetRelatedIdentifiers</key>
84
- <array/>
85
- <key>IDECodeSnippetSummary</key>
86
- <string>${snippet.summary}</string>
87
- <key>IDECodeSnippetTitle</key>
88
- <string>${snippet.title}</string>
89
- <key>IDECodeSnippetUserSnippet</key>
90
- <true/>
91
- <key>IDECodeSnippetVersion</key>
92
- <integer>2</integer>
93
- </dict>
94
- </plist>`;
95
- }
96
-
97
- /**
98
- * 创建或更新 Snippet 文件
99
- */
100
- createSnippet(snippet) {
101
- try {
102
- const filename = `${snippet.id}.codesnippet`;
103
- const filePath = path.join(this.snippetsDir, filename);
104
- const content = this.generateSnippetPlist(snippet);
105
-
106
- fs.writeFileSync(filePath, content, 'utf8');
107
- console.log(` ✅ ${snippet.title}`);
108
- console.log(` 快捷键: ${snippet.shortcut}`);
109
- console.log(` 内容: ${snippet.content}`);
110
- return true;
111
- } catch (err) {
112
- console.warn(` ❌ ${snippet.title}: ${err.message}`);
113
- return false;
114
- }
115
- }
116
-
117
- /**
118
- * 检查 Snippets 目录是否存在
119
- */
120
- ensureSnippetsDir() {
121
- if (!fs.existsSync(this.snippetsDir)) {
122
- try {
123
- fs.mkdirSync(this.snippetsDir, { recursive: true });
124
- console.log(`✅ 创建 Snippets 目录: ${this.snippetsDir}`);
125
- return true;
126
- } catch (err) {
127
- console.error(`❌ 无法创建 Snippets 目录: ${err.message}`);
128
- return false;
129
- }
130
- }
131
- return true;
132
- }
133
-
134
- /**
135
- * 检查 Xcode 是否已安装
136
- */
137
- checkXcodeInstalled() {
138
- try {
139
- execSync('xcode-select -p', { stdio: 'ignore' });
140
- return true;
141
- } catch (_) {
142
- return false;
143
- }
144
- }
145
-
146
- /**
147
- * 初始化所有 Snippets
148
- */
149
- async initialize() {
150
- console.log('\n🚀 AutoSnippet Xcode Snippets 初始化\n');
151
-
152
- // 检查平台
153
- if (process.platform !== 'darwin') {
154
- console.log('⚠️ 此脚本仅支持 macOS');
155
- return false;
156
- }
157
-
158
- // 检查 Xcode
159
- if (!this.checkXcodeInstalled()) {
160
- console.log('⚠️ 未检测到 Xcode,Snippets 可能无法正常工作');
161
- console.log(' 请确保已安装 Xcode 或运行: xcode-select --install\n');
162
- }
163
-
164
- // 创建目录
165
- if (!this.ensureSnippetsDir()) {
166
- return false;
167
- }
168
-
169
- // 创建 Snippets
170
- console.log('\n📝 创建 Snippets:\n');
171
- let successCount = 0;
172
- for (const snippet of this.snippets) {
173
- if (this.createSnippet(snippet)) {
174
- successCount++;
175
- }
176
- }
177
-
178
- // 总结
179
- console.log(`\n${successCount}/${this.snippets.length} 个 Snippets 已创建\n`);
180
-
181
- if (successCount === this.snippets.length) {
182
- console.log('✅ 所有 Snippets 已成功添加到 Xcode!\n');
183
- console.log('📌 快速开始:');
184
- console.log(' 1. 在 Xcode 中打开任何源代码文件');
185
- console.log(' 2. 输入 "ass" 并按 Tab 自动完成');
186
- console.log(' 3. 在提示中输入关键词并保存');
187
- console.log(' 4. AutoSnippet watch 会自动处理\n');
188
- console.log('📚 可用快捷键:');
189
- this.snippets.forEach(s => {
190
- console.log(` • ${s.shortcut.padEnd(6)} → ${s.title}`);
191
- });
192
- console.log();
193
- return true;
194
- } else {
195
- console.log('⚠️ 部分 Snippets 创建失败,请检查权限');
196
- return false;
197
- }
198
- }
199
-
200
- /**
201
- * 列出已安装的 Snippets
202
- */
203
- listSnippets() {
204
- console.log('\n📋 AutoSnippet Snippets 清单\n');
205
-
206
- if (!fs.existsSync(this.snippetsDir)) {
207
- console.log('未找到 Snippets 目录');
208
- return;
209
- }
210
-
211
- const files = fs.readdirSync(this.snippetsDir);
212
- const autoSnippets = files.filter(f => f.startsWith('com.autosnippet'));
213
-
214
- if (autoSnippets.length === 0) {
215
- console.log('未安装任何 AutoSnippet Snippets');
216
- } else {
217
- autoSnippets.forEach(file => {
218
- const filePath = path.join(this.snippetsDir, file);
219
- const stat = fs.statSync(filePath);
220
- console.log(` ✓ ${file}`);
221
- console.log(` 大小: ${(stat.size / 1024).toFixed(2)} KB`);
222
- console.log(` 更新: ${stat.mtime.toLocaleString('zh-CN')}`);
223
- });
224
- }
225
- console.log();
226
- }
227
-
228
- /**
229
- * 移除所有 AutoSnippet Snippets
230
- */
231
- removeSnippets() {
232
- console.log('\n🗑️ 移除 AutoSnippet Snippets\n');
233
-
234
- if (!fs.existsSync(this.snippetsDir)) {
235
- console.log('未找到 Snippets 目录');
236
- return;
237
- }
238
-
239
- const files = fs.readdirSync(this.snippetsDir);
240
- const autoSnippets = files.filter(f => f.startsWith('com.autosnippet'));
241
-
242
- let removedCount = 0;
243
- autoSnippets.forEach(file => {
244
- try {
245
- const filePath = path.join(this.snippetsDir, file);
246
- fs.unlinkSync(filePath);
247
- console.log(` ✓ 已移除: ${file}`);
248
- removedCount++;
249
- } catch (err) {
250
- console.warn(` ✗ 移除失败: ${file}`);
251
- }
252
- });
253
-
254
- console.log(`\n已移除 ${removedCount} 个 Snippets\n`);
255
- }
256
- }
257
-
258
- // 命令行接口
259
- async function main() {
260
- const command = process.argv[2] || 'init';
261
- const initializer = new XcodeSnippetInitializer();
262
-
263
- switch (command) {
264
- case 'init':
265
- await initializer.initialize();
266
- break;
267
- case 'list':
268
- initializer.listSnippets();
269
- break;
270
- case 'remove':
271
- initializer.removeSnippets();
272
- break;
273
- case 'help':
274
- console.log(`
275
- 用法: node scripts/init-xcode-snippets.js [命令]
276
-
277
- 命令:
278
- init 初始化 AutoSnippet Snippets(默认)
279
- list 列出已安装的 Snippets
280
- remove 移除所有 AutoSnippet Snippets
281
- help 显示此帮助信息
282
-
283
- 示例:
284
- node scripts/init-xcode-snippets.js init
285
- node scripts/init-xcode-snippets.js list
286
- `);
287
- break;
288
- default:
289
- console.log(`未知命令: ${command}`);
290
- console.log('使用 "help" 查看可用命令');
291
- process.exit(1);
292
- }
293
- }
294
-
295
- // 导出供其他脚本使用
296
- export default {
297
- XcodeSnippetInitializer,
298
- initialize: async () => {
299
- const initializer = new XcodeSnippetInitializer();
300
- return initializer.initialize();
301
- }
302
- };
303
-
304
- // 如果直接执行此文件
305
- const isMain = process.argv[1] && import.meta.url === `file://${process.argv[1]}`;
306
- if (isMain) {
307
- main().catch(err => {
308
- console.error('❌ 初始化失败:', err.message);
309
- process.exit(1);
310
- });
311
- }
package/template.json DELETED
@@ -1,39 +0,0 @@
1
- {
2
- "list": [
3
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",
4
- "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n",
5
- "<plist version=\"1.0\">\n",
6
- "<dict>\n",
7
-
8
- "\t<key>IDECodeSnippetCompletionPrefix</key>\n",
9
- "{completion}",
10
-
11
- "\t<key>IDECodeSnippetCompletionScopes</key>\n",
12
- "\t<array>\n",
13
- "\t\t<string>All</string>\n",
14
- "\t</array>\n",
15
-
16
- "\t<key>IDECodeSnippetContents</key>\n",
17
- "{content}",
18
-
19
- "\t<key>IDECodeSnippetIdentifier</key>\n",
20
- "{identifier}",
21
-
22
- "\t<key>IDECodeSnippetLanguage</key>\n",
23
- "{language}",
24
-
25
- "\t<key>IDECodeSnippetSummary</key>\n",
26
- "{summary}",
27
-
28
- "\t<key>IDECodeSnippetTitle</key>\n",
29
- "{title}",
30
-
31
- "\t<key>IDECodeSnippetUserSnippet</key>\n",
32
- "\t<true/>\n",
33
- "\t<key>IDECodeSnippetVersion</key>\n",
34
- "\t<integer>2</integer>\n",
35
-
36
- "</dict>\n",
37
- "</plist>\n"
38
- ]
39
- }