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
|
@@ -1,73 +1,69 @@
|
|
|
1
|
-
import DatabaseConnection from '../infrastructure/database/DatabaseConnection.js';
|
|
2
|
-
import Logger from '../infrastructure/logging/Logger.js';
|
|
3
|
-
import AuditStore from '../infrastructure/audit/AuditStore.js';
|
|
4
|
-
import AuditLogger from '../infrastructure/audit/AuditLogger.js';
|
|
5
|
-
import Gateway from '../core/gateway/Gateway.js';
|
|
6
1
|
import { readdirSync, statSync } from 'node:fs';
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
import { KnowledgeRepositoryImpl } from '../repository/knowledge/KnowledgeRepository.impl.js';
|
|
10
|
-
import { KnowledgeFileWriter } from '../service/knowledge/KnowledgeFileWriter.js';
|
|
2
|
+
import { extname as pathExtname, join as pathJoin, relative as pathRelative } from 'node:path';
|
|
11
3
|
import { KnowledgeSyncService } from '../cli/KnowledgeSyncService.js';
|
|
12
|
-
|
|
13
|
-
import
|
|
14
|
-
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import
|
|
18
|
-
import
|
|
19
|
-
import
|
|
20
|
-
|
|
21
|
-
// ───
|
|
22
|
-
import {
|
|
23
|
-
|
|
4
|
+
// ─── v3.0: AST ProjectGraph ──────────────────────────
|
|
5
|
+
import ProjectGraph from '../core/ast/ProjectGraph.js';
|
|
6
|
+
// ─── v3.1: Multi-Language Discovery + Enhancement ────────
|
|
7
|
+
import { getDiscovererRegistry } from '../core/discovery/index.js';
|
|
8
|
+
import { getEnhancementRegistry, initEnhancementRegistry } from '../core/enhancement/index.js';
|
|
9
|
+
import Gateway from '../core/gateway/Gateway.js';
|
|
10
|
+
import AuditLogger from '../infrastructure/audit/AuditLogger.js';
|
|
11
|
+
import AuditStore from '../infrastructure/audit/AuditStore.js';
|
|
12
|
+
import { GraphCache } from '../infrastructure/cache/GraphCache.js';
|
|
13
|
+
// ─── P3: Infrastructure ──────────────────────────────
|
|
14
|
+
import { EventBus } from '../infrastructure/event/EventBus.js';
|
|
15
|
+
import Logger from '../infrastructure/logging/Logger.js';
|
|
16
|
+
import { getRealtimeService as _getRealtimeService } from '../infrastructure/realtime/RealtimeService.js';
|
|
17
|
+
import { IndexingPipeline } from '../infrastructure/vector/IndexingPipeline.js';
|
|
24
18
|
// ─── P0: Vector Storage ──────────────────────────────
|
|
25
19
|
import { JsonVectorAdapter } from '../infrastructure/vector/JsonVectorAdapter.js';
|
|
26
|
-
import {
|
|
27
|
-
|
|
28
|
-
// ─── P1: Injection / Snippet ─────────────────
|
|
29
|
-
import { RecipeParser } from '../service/recipe/RecipeParser.js';
|
|
30
|
-
import { RecipeCandidateValidator } from '../service/recipe/RecipeCandidateValidator.js';
|
|
31
|
-
import { SnippetInstaller } from '../service/snippet/SnippetInstaller.js';
|
|
32
|
-
|
|
33
|
-
// ─── P1: Guard Advanced ──────────────────────────────
|
|
34
|
-
import { ExclusionManager } from '../service/guard/ExclusionManager.js';
|
|
35
|
-
import { RuleLearner } from '../service/guard/RuleLearner.js';
|
|
36
|
-
import { ViolationsStore } from '../service/guard/ViolationsStore.js';
|
|
37
|
-
import { ComplianceReporter } from '../service/guard/ComplianceReporter.js';
|
|
38
|
-
import { GuardFeedbackLoop } from '../service/guard/GuardFeedbackLoop.js';
|
|
39
|
-
|
|
20
|
+
import { KnowledgeRepositoryImpl } from '../repository/knowledge/KnowledgeRepository.impl.js';
|
|
40
21
|
// ─── P1: Token Usage Tracking ─────────────────────────
|
|
41
22
|
import { TokenUsageStore } from '../repository/token/TokenUsageStore.js';
|
|
42
|
-
|
|
43
|
-
// ─── P2: Quality ──────────────────────────────────────
|
|
44
|
-
import { QualityScorer } from '../service/quality/QualityScorer.js';
|
|
45
|
-
import { FeedbackCollector } from '../service/quality/FeedbackCollector.js';
|
|
46
|
-
|
|
47
|
-
// ─── P2: SPM ──────────────────────────────────────────
|
|
48
|
-
import { SpmService } from '../service/spm/SpmService.js';
|
|
49
|
-
// ─── P2: Content Extraction ─────────────────────────────────────
|
|
50
|
-
import { RecipeExtractor } from '../service/context/RecipeExtractor.js';
|
|
51
23
|
// ─── P2: Automation ───────────────────────────────────
|
|
52
24
|
import { AutomationOrchestrator } from '../service/automation/AutomationOrchestrator.js';
|
|
53
|
-
|
|
25
|
+
import { BootstrapTaskManager } from '../service/bootstrap/BootstrapTaskManager.js';
|
|
26
|
+
import { ChatAgent } from '../service/chat/ChatAgent.js';
|
|
54
27
|
// ─── P2: ChatAgent (统一 AI Agent) ────────────────────
|
|
55
28
|
import { ToolRegistry } from '../service/chat/ToolRegistry.js';
|
|
56
|
-
import { ChatAgent } from '../service/chat/ChatAgent.js';
|
|
57
29
|
import { ALL_TOOLS } from '../service/chat/tools.js';
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
// ─── v3.0: AST ProjectGraph ──────────────────────────
|
|
61
|
-
import ProjectGraph from '../core/ast/ProjectGraph.js';
|
|
62
|
-
import { GraphCache } from '../infrastructure/cache/GraphCache.js';
|
|
63
|
-
|
|
64
|
-
// ─── P3: Infrastructure ──────────────────────────────
|
|
65
|
-
import { EventBus } from '../infrastructure/event/EventBus.js';
|
|
66
|
-
import { BootstrapTaskManager } from '../service/bootstrap/BootstrapTaskManager.js';
|
|
67
|
-
import { getRealtimeService as _getRealtimeService } from '../infrastructure/realtime/RealtimeService.js';
|
|
68
|
-
|
|
30
|
+
// ─── P2: Content Extraction ─────────────────────────────────────
|
|
31
|
+
import { RecipeExtractor } from '../service/context/RecipeExtractor.js';
|
|
69
32
|
// ─── P3: Cursor Delivery Pipeline ──────────────────────
|
|
70
33
|
import { CursorDeliveryPipeline } from '../service/cursor/CursorDeliveryPipeline.js';
|
|
34
|
+
import { ComplianceReporter } from '../service/guard/ComplianceReporter.js';
|
|
35
|
+
// ─── P1: Guard Advanced ──────────────────────────────
|
|
36
|
+
import { ExclusionManager } from '../service/guard/ExclusionManager.js';
|
|
37
|
+
import { GuardCheckEngine } from '../service/guard/GuardCheckEngine.js';
|
|
38
|
+
import { GuardFeedbackLoop } from '../service/guard/GuardFeedbackLoop.js';
|
|
39
|
+
import { GuardService } from '../service/guard/GuardService.js';
|
|
40
|
+
import { RuleLearner } from '../service/guard/RuleLearner.js';
|
|
41
|
+
import { ViolationsStore } from '../service/guard/ViolationsStore.js';
|
|
42
|
+
import { CodeEntityGraph } from '../service/knowledge/CodeEntityGraph.js';
|
|
43
|
+
import { ConfidenceRouter } from '../service/knowledge/ConfidenceRouter.js';
|
|
44
|
+
import { KnowledgeFileWriter } from '../service/knowledge/KnowledgeFileWriter.js';
|
|
45
|
+
import { KnowledgeGraphService } from '../service/knowledge/KnowledgeGraphService.js';
|
|
46
|
+
import { KnowledgeService } from '../service/knowledge/KnowledgeService.js';
|
|
47
|
+
import { FeedbackCollector } from '../service/quality/FeedbackCollector.js';
|
|
48
|
+
// ─── P2: Quality ──────────────────────────────────────
|
|
49
|
+
import { QualityScorer } from '../service/quality/QualityScorer.js';
|
|
50
|
+
import { RecipeCandidateValidator } from '../service/recipe/RecipeCandidateValidator.js';
|
|
51
|
+
// ─── P1: Injection / Snippet ─────────────────
|
|
52
|
+
import { RecipeParser } from '../service/recipe/RecipeParser.js';
|
|
53
|
+
// ─── P0: Advanced Search ──────────────────────────────
|
|
54
|
+
import { RetrievalFunnel } from '../service/search/RetrievalFunnel.js';
|
|
55
|
+
import { SearchEngine } from '../service/search/SearchEngine.js';
|
|
56
|
+
import { SkillHooks } from '../service/skills/SkillHooks.js';
|
|
57
|
+
import { SnippetFactory } from '../service/snippet/SnippetFactory.js';
|
|
58
|
+
import { SnippetInstaller } from '../service/snippet/SnippetInstaller.js';
|
|
59
|
+
import { XcodeCodec } from '../service/snippet/codecs/XcodeCodec.js';
|
|
60
|
+
import { VSCodeCodec } from '../service/snippet/codecs/VSCodeCodec.js';
|
|
61
|
+
// ─── P2: SPM ──────────────────────────────────────────
|
|
62
|
+
import { SpmService } from '../platform/ios/spm/SpmService.js';
|
|
63
|
+
// ─── v3.2: ModuleService (统一多语言模块扫描) ──────────
|
|
64
|
+
import { ModuleService } from '../service/module/ModuleService.js';
|
|
65
|
+
import { DimensionCopy } from '../shared/DimensionCopyRegistry.js';
|
|
66
|
+
import { LanguageService } from '../shared/LanguageService.js';
|
|
71
67
|
|
|
72
68
|
/**
|
|
73
69
|
* DependencyInjection 容器
|
|
@@ -139,8 +135,8 @@ export class ServiceContainer {
|
|
|
139
135
|
try {
|
|
140
136
|
const { getAvailableFallbacks, createProvider } = this.singletons._aiFactory;
|
|
141
137
|
const providerName = this.singletons.aiProvider.name?.replace('-', '') || '';
|
|
142
|
-
const fbCandidates =
|
|
143
|
-
? getAvailableFallbacks(providerName) : [];
|
|
138
|
+
const fbCandidates =
|
|
139
|
+
typeof getAvailableFallbacks === 'function' ? getAvailableFallbacks(providerName) : [];
|
|
144
140
|
for (const fb of fbCandidates) {
|
|
145
141
|
try {
|
|
146
142
|
const fbProvider = createProvider({ provider: fb });
|
|
@@ -149,9 +145,13 @@ export class ServiceContainer {
|
|
|
149
145
|
this.logger.info('Embedding fallback provider created', { provider: fb });
|
|
150
146
|
break;
|
|
151
147
|
}
|
|
152
|
-
} catch {
|
|
148
|
+
} catch {
|
|
149
|
+
/* skip */
|
|
150
|
+
}
|
|
153
151
|
}
|
|
154
|
-
} catch {
|
|
152
|
+
} catch {
|
|
153
|
+
/* no embed fallback available */
|
|
154
|
+
}
|
|
155
155
|
}
|
|
156
156
|
|
|
157
157
|
// RecipeExtractor 实例(用于工具增强)
|
|
@@ -160,12 +160,28 @@ export class ServiceContainer {
|
|
|
160
160
|
// 注册基础设施依赖
|
|
161
161
|
this._registerInfrastructure();
|
|
162
162
|
|
|
163
|
+
// ═══ AI Provider 热重载标记 ═══
|
|
164
|
+
// 记录哪些 singleton key 持有 aiProvider 引用,在 reloadAiProvider() 时需要清除
|
|
165
|
+
this._aiDependentSingletons = [
|
|
166
|
+
'chatAgent',
|
|
167
|
+
'searchEngine',
|
|
168
|
+
'retrievalFunnel',
|
|
169
|
+
'indexingPipeline',
|
|
170
|
+
];
|
|
171
|
+
|
|
163
172
|
// 注册仓储
|
|
164
173
|
this._registerRepositories();
|
|
165
174
|
|
|
166
175
|
// 注册服务
|
|
167
176
|
this._registerServices();
|
|
168
177
|
|
|
178
|
+
// v3.1: 初始化 Enhancement Pack 注册表(异步加载所有框架增强包)
|
|
179
|
+
try {
|
|
180
|
+
await initEnhancementRegistry();
|
|
181
|
+
} catch (e) {
|
|
182
|
+
this.logger.warn('Enhancement registry init failed (non-blocking)', { error: e.message });
|
|
183
|
+
}
|
|
184
|
+
|
|
169
185
|
this.logger.info('Service container initialized successfully');
|
|
170
186
|
} catch (error) {
|
|
171
187
|
this.logger.error('Error initializing service container', {
|
|
@@ -175,6 +191,60 @@ export class ServiceContainer {
|
|
|
175
191
|
}
|
|
176
192
|
}
|
|
177
193
|
|
|
194
|
+
/**
|
|
195
|
+
* 热重载 AI Provider(API Key 变更后调用,无需重启进程)
|
|
196
|
+
*
|
|
197
|
+
* 流程:
|
|
198
|
+
* 1. 替换 singletons.aiProvider
|
|
199
|
+
* 2. 重新创建 _embedProvider(如果主 provider 不支持 embedding)
|
|
200
|
+
* 3. 清除已缓存的依赖 AI 的 singleton(ChatAgent / SearchEngine 等),
|
|
201
|
+
* 下次 get() 时会用新 provider 重新创建
|
|
202
|
+
*
|
|
203
|
+
* @param {import('../external/ai/AiProvider.js').AiProvider} newProvider
|
|
204
|
+
*/
|
|
205
|
+
reloadAiProvider(newProvider) {
|
|
206
|
+
const old = this.singletons.aiProvider;
|
|
207
|
+
this.singletons.aiProvider = newProvider;
|
|
208
|
+
|
|
209
|
+
// 重新创建 embedding fallback provider
|
|
210
|
+
this.singletons._embedProvider = null;
|
|
211
|
+
if (newProvider && !newProvider.supportsEmbedding?.()) {
|
|
212
|
+
try {
|
|
213
|
+
const { getAvailableFallbacks, createProvider } = this.singletons._aiFactory || {};
|
|
214
|
+
if (typeof getAvailableFallbacks === 'function') {
|
|
215
|
+
const providerName = newProvider.name?.replace('-', '') || '';
|
|
216
|
+
const fbCandidates = getAvailableFallbacks(providerName);
|
|
217
|
+
for (const fb of fbCandidates) {
|
|
218
|
+
try {
|
|
219
|
+
const fbProvider = createProvider({ provider: fb });
|
|
220
|
+
if (fbProvider.supportsEmbedding?.()) {
|
|
221
|
+
this.singletons._embedProvider = fbProvider;
|
|
222
|
+
this.logger.info('Embedding fallback provider re-created', { provider: fb });
|
|
223
|
+
break;
|
|
224
|
+
}
|
|
225
|
+
} catch { /* skip */ }
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
} catch { /* no embed fallback available */ }
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// 清除持有旧 aiProvider 引用的 singleton 缓存
|
|
232
|
+
// 下次调用 container.get() 时会使用新 provider 重建
|
|
233
|
+
const cleared = [];
|
|
234
|
+
for (const key of this._aiDependentSingletons || []) {
|
|
235
|
+
if (this.singletons[key]) {
|
|
236
|
+
this.singletons[key] = null;
|
|
237
|
+
cleared.push(key);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
this.logger.info('AI provider hot-reloaded', {
|
|
242
|
+
old: old?.constructor?.name || 'none',
|
|
243
|
+
new: newProvider?.constructor?.name || 'none',
|
|
244
|
+
clearedSingletons: cleared,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
|
|
178
248
|
/**
|
|
179
249
|
* 注册基础设施依赖
|
|
180
250
|
*/
|
|
@@ -182,7 +252,9 @@ export class ServiceContainer {
|
|
|
182
252
|
// Database(使用 Bootstrap 注入的实例,或延迟报错)
|
|
183
253
|
this.register('database', () => {
|
|
184
254
|
if (!this.singletons.database) {
|
|
185
|
-
throw new Error(
|
|
255
|
+
throw new Error(
|
|
256
|
+
'Database not initialized. Ensure Bootstrap.initialize() is called before using ServiceContainer.'
|
|
257
|
+
);
|
|
186
258
|
}
|
|
187
259
|
return this.singletons.database;
|
|
188
260
|
});
|
|
@@ -230,9 +302,16 @@ export class ServiceContainer {
|
|
|
230
302
|
const eventBus = this.get('eventBus');
|
|
231
303
|
// 延迟 getter: RealtimeService 在 HTTP server 启动后才可用,CLI 模式下不可用
|
|
232
304
|
const getRS = () => {
|
|
233
|
-
try {
|
|
305
|
+
try {
|
|
306
|
+
return _getRealtimeService();
|
|
307
|
+
} catch {
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
234
310
|
};
|
|
235
|
-
this.singletons.bootstrapTaskManager = new BootstrapTaskManager({
|
|
311
|
+
this.singletons.bootstrapTaskManager = new BootstrapTaskManager({
|
|
312
|
+
eventBus,
|
|
313
|
+
getRealtimeService: getRS,
|
|
314
|
+
});
|
|
236
315
|
}
|
|
237
316
|
return this.singletons.bootstrapTaskManager;
|
|
238
317
|
});
|
|
@@ -311,11 +390,7 @@ export class ServiceContainer {
|
|
|
311
390
|
const knowledgeRepository = this.get('knowledgeRepository');
|
|
312
391
|
const auditLogger = this.get('auditLogger');
|
|
313
392
|
const gateway = this.get('gateway');
|
|
314
|
-
this.singletons.guardService = new GuardService(
|
|
315
|
-
knowledgeRepository,
|
|
316
|
-
auditLogger,
|
|
317
|
-
gateway
|
|
318
|
-
);
|
|
393
|
+
this.singletons.guardService = new GuardService(knowledgeRepository, auditLogger, gateway);
|
|
319
394
|
}
|
|
320
395
|
return this.singletons.guardService;
|
|
321
396
|
});
|
|
@@ -333,7 +408,8 @@ export class ServiceContainer {
|
|
|
333
408
|
this.register('codeEntityGraph', () => {
|
|
334
409
|
if (!this.singletons.codeEntityGraph) {
|
|
335
410
|
const database = this.get('database');
|
|
336
|
-
const projectRoot =
|
|
411
|
+
const projectRoot =
|
|
412
|
+
this.singletons._projectRoot || process.env.ASD_PROJECT_DIR || process.cwd();
|
|
337
413
|
this.singletons.codeEntityGraph = new CodeEntityGraph(database, { projectRoot });
|
|
338
414
|
}
|
|
339
415
|
return this.singletons.codeEntityGraph;
|
|
@@ -346,7 +422,10 @@ export class ServiceContainer {
|
|
|
346
422
|
const aiProvider = this.singletons.aiProvider || null;
|
|
347
423
|
const embedProvider = this.singletons._embedProvider || aiProvider;
|
|
348
424
|
const vectorStore = this.get('vectorStore');
|
|
349
|
-
this.singletons.searchEngine = new SearchEngine(database, {
|
|
425
|
+
this.singletons.searchEngine = new SearchEngine(database, {
|
|
426
|
+
aiProvider: embedProvider,
|
|
427
|
+
vectorStore,
|
|
428
|
+
});
|
|
350
429
|
}
|
|
351
430
|
return this.singletons.searchEngine;
|
|
352
431
|
});
|
|
@@ -373,7 +452,10 @@ export class ServiceContainer {
|
|
|
373
452
|
const vectorStore = this.get('vectorStore');
|
|
374
453
|
const aiProvider = this.singletons.aiProvider || null;
|
|
375
454
|
const embedProvider = this.singletons._embedProvider || aiProvider;
|
|
376
|
-
this.singletons.retrievalFunnel = new RetrievalFunnel({
|
|
455
|
+
this.singletons.retrievalFunnel = new RetrievalFunnel({
|
|
456
|
+
vectorStore,
|
|
457
|
+
aiProvider: embedProvider,
|
|
458
|
+
});
|
|
377
459
|
}
|
|
378
460
|
return this.singletons.retrievalFunnel;
|
|
379
461
|
});
|
|
@@ -383,7 +465,7 @@ export class ServiceContainer {
|
|
|
383
465
|
if (!this.singletons.vectorStore) {
|
|
384
466
|
const projectRoot = this.singletons._projectRoot || process.cwd();
|
|
385
467
|
const store = new JsonVectorAdapter(projectRoot);
|
|
386
|
-
store.initSync();
|
|
468
|
+
store.initSync(); // 从磁盘加载已有 vector_index.json
|
|
387
469
|
this.singletons.vectorStore = store;
|
|
388
470
|
}
|
|
389
471
|
return this.singletons.vectorStore;
|
|
@@ -395,7 +477,10 @@ export class ServiceContainer {
|
|
|
395
477
|
const vectorStore = this.get('vectorStore');
|
|
396
478
|
const aiProvider = this.singletons.aiProvider || null;
|
|
397
479
|
const embedProvider = this.singletons._embedProvider || aiProvider;
|
|
398
|
-
this.singletons.indexingPipeline = new IndexingPipeline({
|
|
480
|
+
this.singletons.indexingPipeline = new IndexingPipeline({
|
|
481
|
+
vectorStore,
|
|
482
|
+
aiProvider: embedProvider,
|
|
483
|
+
});
|
|
399
484
|
}
|
|
400
485
|
return this.singletons.indexingPipeline;
|
|
401
486
|
});
|
|
@@ -416,24 +501,39 @@ export class ServiceContainer {
|
|
|
416
501
|
return this.singletons.recipeCandidateValidator;
|
|
417
502
|
});
|
|
418
503
|
|
|
419
|
-
// SnippetFactory (
|
|
504
|
+
// SnippetFactory (V4: codec-driven, IDE-agnostic)
|
|
420
505
|
this.register('snippetFactory', () => {
|
|
421
506
|
if (!this.singletons.snippetFactory) {
|
|
422
507
|
const knowledgeRepo = this.get('knowledgeRepository');
|
|
423
|
-
|
|
508
|
+
const factory = new SnippetFactory(knowledgeRepo);
|
|
509
|
+
// 注册 IDE codecs
|
|
510
|
+
factory.registerCodec(new XcodeCodec());
|
|
511
|
+
factory.registerCodec(new VSCodeCodec());
|
|
512
|
+
this.singletons.snippetFactory = factory;
|
|
424
513
|
}
|
|
425
514
|
return this.singletons.snippetFactory;
|
|
426
515
|
});
|
|
427
516
|
|
|
428
|
-
// SnippetInstaller
|
|
517
|
+
// SnippetInstaller (Xcode — 默认 codec)
|
|
429
518
|
this.register('snippetInstaller', () => {
|
|
430
519
|
if (!this.singletons.snippetInstaller) {
|
|
431
520
|
const factory = this.get('snippetFactory');
|
|
432
|
-
|
|
521
|
+
const codec = factory.getCodec('xcode');
|
|
522
|
+
this.singletons.snippetInstaller = new SnippetInstaller({ codec, snippetFactory: factory });
|
|
433
523
|
}
|
|
434
524
|
return this.singletons.snippetInstaller;
|
|
435
525
|
});
|
|
436
526
|
|
|
527
|
+
// SnippetInstaller (VSCode)
|
|
528
|
+
this.register('vscodeSnippetInstaller', () => {
|
|
529
|
+
if (!this.singletons.vscodeSnippetInstaller) {
|
|
530
|
+
const factory = this.get('snippetFactory');
|
|
531
|
+
const codec = factory.getCodec('vscode');
|
|
532
|
+
this.singletons.vscodeSnippetInstaller = new SnippetInstaller({ codec, snippetFactory: factory });
|
|
533
|
+
}
|
|
534
|
+
return this.singletons.vscodeSnippetInstaller;
|
|
535
|
+
});
|
|
536
|
+
|
|
437
537
|
// Guard: ExclusionManager
|
|
438
538
|
this.register('exclusionManager', () => {
|
|
439
539
|
if (!this.singletons.exclusionManager) {
|
|
@@ -470,7 +570,7 @@ export class ServiceContainer {
|
|
|
470
570
|
this.get('violationsStore'),
|
|
471
571
|
this.get('ruleLearner'),
|
|
472
572
|
this.get('exclusionManager'),
|
|
473
|
-
config.qualityGate || {}
|
|
573
|
+
config.qualityGate || {}
|
|
474
574
|
);
|
|
475
575
|
}
|
|
476
576
|
return this.singletons.complianceReporter;
|
|
@@ -482,7 +582,7 @@ export class ServiceContainer {
|
|
|
482
582
|
this.singletons.guardFeedbackLoop = new GuardFeedbackLoop(
|
|
483
583
|
this.get('violationsStore'),
|
|
484
584
|
this.get('feedbackCollector'),
|
|
485
|
-
{ guardCheckEngine: this.get('guardCheckEngine') }
|
|
585
|
+
{ guardCheckEngine: this.get('guardCheckEngine') }
|
|
486
586
|
);
|
|
487
587
|
}
|
|
488
588
|
return this.singletons.guardFeedbackLoop;
|
|
@@ -541,6 +641,38 @@ export class ServiceContainer {
|
|
|
541
641
|
return this.singletons.automationOrchestrator;
|
|
542
642
|
});
|
|
543
643
|
|
|
644
|
+
// ModuleService (统一多语言模块扫描,语言无关)
|
|
645
|
+
this.register('moduleService', () => {
|
|
646
|
+
if (!this.singletons.moduleService) {
|
|
647
|
+
const projectRoot = this.singletons._projectRoot || process.cwd();
|
|
648
|
+
this.singletons.moduleService = new ModuleService(projectRoot, {
|
|
649
|
+
aiFactory: this.singletons._aiFactory || null,
|
|
650
|
+
chatAgent: this.singletons.chatAgent || null,
|
|
651
|
+
qualityScorer: this.get('qualityScorer'),
|
|
652
|
+
recipeExtractor: this.singletons._recipeExtractor || null,
|
|
653
|
+
guardCheckEngine: this.get('guardCheckEngine'),
|
|
654
|
+
violationsStore: this.get('violationsStore'),
|
|
655
|
+
});
|
|
656
|
+
}
|
|
657
|
+
return this.singletons.moduleService;
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
// DiscovererRegistry (v3.1 多语言项目发现)
|
|
661
|
+
this.register('discovererRegistry', () => {
|
|
662
|
+
return getDiscovererRegistry();
|
|
663
|
+
});
|
|
664
|
+
|
|
665
|
+
// LanguageService (v3.1 统一语言映射服务 — 静态类,直接返回)
|
|
666
|
+
this.register('languageService', () => LanguageService);
|
|
667
|
+
|
|
668
|
+
// DimensionCopy (v3.1 维度文案注册表 — 静态类,直接返回)
|
|
669
|
+
this.register('dimensionCopy', () => DimensionCopy);
|
|
670
|
+
|
|
671
|
+
// EnhancementRegistry (v3.1 框架增强包)
|
|
672
|
+
this.register('enhancementRegistry', () => {
|
|
673
|
+
return getEnhancementRegistry();
|
|
674
|
+
});
|
|
675
|
+
|
|
544
676
|
// ToolRegistry (ChatAgent 的工具注册表)
|
|
545
677
|
this.register('toolRegistry', () => {
|
|
546
678
|
if (!this.singletons.toolRegistry) {
|
|
@@ -662,14 +794,14 @@ export class ServiceContainer {
|
|
|
662
794
|
changedPaths.push(fp);
|
|
663
795
|
}
|
|
664
796
|
}
|
|
665
|
-
const deletedPaths = Object.keys(oldHashes).filter(rel => !newHashes[rel]);
|
|
797
|
+
const deletedPaths = Object.keys(oldHashes).filter((rel) => !newHashes[rel]);
|
|
666
798
|
|
|
667
799
|
if (changedPaths.length === 0 && deletedPaths.length === 0) {
|
|
668
800
|
// 完全命中
|
|
669
801
|
this.singletons.projectGraph = graph;
|
|
670
802
|
this.logger.info(
|
|
671
803
|
`[ServiceContainer] ProjectGraph ⚡ 缓存命中 (${graph.getOverview().totalClasses} classes, ` +
|
|
672
|
-
|
|
804
|
+
`${Date.now() - startTime}ms)`
|
|
673
805
|
);
|
|
674
806
|
return graph;
|
|
675
807
|
}
|
|
@@ -684,7 +816,7 @@ export class ServiceContainer {
|
|
|
684
816
|
const overview = graph.getOverview();
|
|
685
817
|
this.logger.info(
|
|
686
818
|
`[ServiceContainer] ProjectGraph 增量更新: +${diff.added} ~${diff.updated} -${diff.deleted} ` +
|
|
687
|
-
|
|
819
|
+
`(${overview.totalClasses} classes, ${Date.now() - startTime}ms)`
|
|
688
820
|
);
|
|
689
821
|
return graph;
|
|
690
822
|
}
|
|
@@ -701,8 +833,8 @@ export class ServiceContainer {
|
|
|
701
833
|
|
|
702
834
|
this.logger.info(
|
|
703
835
|
`[ServiceContainer] ProjectGraph built: ${overview.totalClasses} classes, ` +
|
|
704
|
-
|
|
705
|
-
|
|
836
|
+
`${overview.totalProtocols} protocols, ${overview.totalCategories} categories ` +
|
|
837
|
+
`(${overview.buildTimeMs}ms) — 缓存已写入`
|
|
706
838
|
);
|
|
707
839
|
return graph;
|
|
708
840
|
} catch (err) {
|
|
@@ -721,29 +853,51 @@ export class ServiceContainer {
|
|
|
721
853
|
const DEFAULTS_EXT = { '.m': true, '.h': true, '.swift': true };
|
|
722
854
|
const extSet = new Set(options.extensions || Object.keys(DEFAULTS_EXT));
|
|
723
855
|
const excludePatterns = options.excludePatterns || [
|
|
724
|
-
'Pods/',
|
|
725
|
-
'
|
|
856
|
+
'Pods/',
|
|
857
|
+
'Carthage/',
|
|
858
|
+
'node_modules/',
|
|
859
|
+
'.build/',
|
|
860
|
+
'build/',
|
|
861
|
+
'DerivedData/',
|
|
862
|
+
'vendor/',
|
|
863
|
+
'.git/',
|
|
864
|
+
'__tests__/',
|
|
865
|
+
'Tests/',
|
|
726
866
|
];
|
|
727
867
|
const maxFiles = options.maxFiles || 500;
|
|
728
868
|
const maxFileSizeBytes = options.maxFileSizeBytes || 500_000;
|
|
729
869
|
const results = [];
|
|
730
870
|
|
|
731
871
|
function walk(dir) {
|
|
732
|
-
if (results.length >= maxFiles)
|
|
872
|
+
if (results.length >= maxFiles) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
733
875
|
let entries;
|
|
734
|
-
try {
|
|
876
|
+
try {
|
|
877
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
878
|
+
} catch {
|
|
879
|
+
return;
|
|
880
|
+
}
|
|
735
881
|
for (const entry of entries) {
|
|
736
|
-
if (results.length >= maxFiles)
|
|
882
|
+
if (results.length >= maxFiles) {
|
|
883
|
+
return;
|
|
884
|
+
}
|
|
737
885
|
const fullPath = pathJoin(dir, entry.name);
|
|
738
886
|
const relativePath = pathRelative(projectRoot, fullPath);
|
|
739
|
-
if (excludePatterns.some(p => relativePath.includes(p)))
|
|
887
|
+
if (excludePatterns.some((p) => relativePath.includes(p))) {
|
|
888
|
+
continue;
|
|
889
|
+
}
|
|
740
890
|
if (entry.isDirectory()) {
|
|
741
891
|
walk(fullPath);
|
|
742
892
|
} else if (entry.isFile() && extSet.has(pathExtname(entry.name))) {
|
|
743
893
|
try {
|
|
744
894
|
const stat = statSync(fullPath);
|
|
745
|
-
if (stat.size <= maxFileSizeBytes)
|
|
746
|
-
|
|
895
|
+
if (stat.size <= maxFileSizeBytes) {
|
|
896
|
+
results.push(fullPath);
|
|
897
|
+
}
|
|
898
|
+
} catch {
|
|
899
|
+
/* skip */
|
|
900
|
+
}
|
|
747
901
|
}
|
|
748
902
|
}
|
|
749
903
|
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @module platform/ios
|
|
3
|
+
* @description iOS + Xcode 平台支持模块
|
|
4
|
+
*
|
|
5
|
+
* 将所有 iOS/Xcode 特有功能集中到 lib/platform/ios/ 下:
|
|
6
|
+
*
|
|
7
|
+
* xcode/
|
|
8
|
+
* XcodeAutomation.js — AppleScript/osascript Xcode IDE 自动化
|
|
9
|
+
* XcodeIntegration.js — Xcode 代码自动插入 + Header 管理 + 依赖检查
|
|
10
|
+
* SaveEventFilter.js — 保存事件过滤(Xcode 焦点检测 + 内容哈希去重)
|
|
11
|
+
*
|
|
12
|
+
* snippet/
|
|
13
|
+
* XcodeCodec.js — Xcode .codesnippet (plist XML) 编解码
|
|
14
|
+
* PlaceholderConverter.js — Xcode <#…#> ↔ VSCode ${N:…} 占位符转换
|
|
15
|
+
*
|
|
16
|
+
* spm/
|
|
17
|
+
* SpmService.js — Swift Package Manager 服务(Target / 依赖 / 策略)
|
|
18
|
+
* SpmDiscoverer.js — SPM 项目自动发现(ProjectDiscoverer 接口)
|
|
19
|
+
* PackageSwiftParser.js — Package.swift 解析器
|
|
20
|
+
* DependencyGraph.js — SPM Target 依赖图
|
|
21
|
+
* PolicyEngine.js — 依赖策略引擎(层级检查 / 循环检测)
|
|
22
|
+
*
|
|
23
|
+
* routes/
|
|
24
|
+
* spm.js — /api/v1/spm/* REST 路由(向后兼容遗留端点)
|
|
25
|
+
*
|
|
26
|
+
* 旧路径保留了 re-export shim 确保向后兼容。
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
// ── Xcode IDE 自动化 ──
|
|
30
|
+
export {
|
|
31
|
+
isXcodeRunning,
|
|
32
|
+
isXcodeFrontmost,
|
|
33
|
+
jumpToLineInXcode,
|
|
34
|
+
cutLineInXcode,
|
|
35
|
+
deleteLineContentInXcode,
|
|
36
|
+
pasteInXcode,
|
|
37
|
+
selectAndPasteInXcode,
|
|
38
|
+
insertAtLineStartInXcode,
|
|
39
|
+
saveActiveDocumentInXcode,
|
|
40
|
+
} from './xcode/XcodeAutomation.js';
|
|
41
|
+
|
|
42
|
+
export {
|
|
43
|
+
insertHeaders,
|
|
44
|
+
insertCodeToXcode,
|
|
45
|
+
findTriggerLineNumber,
|
|
46
|
+
findImportInsertLine,
|
|
47
|
+
} from './xcode/XcodeIntegration.js';
|
|
48
|
+
|
|
49
|
+
export { saveEventFilter } from './xcode/SaveEventFilter.js';
|
|
50
|
+
|
|
51
|
+
// ── Xcode Snippet 编解码 ──
|
|
52
|
+
export { XcodeCodec } from './snippet/XcodeCodec.js';
|
|
53
|
+
export { PlaceholderConverter } from './snippet/PlaceholderConverter.js';
|
|
54
|
+
|
|
55
|
+
// ── Swift Package Manager ──
|
|
56
|
+
export { SpmService } from './spm/SpmService.js';
|
|
57
|
+
export { SpmDiscoverer } from './spm/SpmDiscoverer.js';
|
|
58
|
+
export { PackageSwiftParser } from './spm/PackageSwiftParser.js';
|
|
59
|
+
export { DependencyGraph } from './spm/DependencyGraph.js';
|
|
60
|
+
export { PolicyEngine } from './spm/PolicyEngine.js';
|
|
61
|
+
|
|
62
|
+
// ── SPM Legacy Routes ──
|
|
63
|
+
export { default as spmRouter } from './routes/spm.js';
|