autosnippet 3.2.22 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dashboard/dist/assets/{icons-C1dUryS-.js → icons-BofcEZ3f.js} +1 -1
- package/dashboard/dist/assets/index-SiN1GChm.js +128 -0
- package/dashboard/dist/index.html +2 -2
- package/dist/bin/cli.d.ts +0 -1
- package/dist/bin/cli.js +0 -133
- package/dist/lib/cli/SetupService.d.ts +46 -2
- package/dist/lib/cli/SetupService.js +2 -27
- package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.d.ts +2 -5
- package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.js +159 -44
- package/dist/lib/core/discovery/index.d.ts +1 -1
- package/dist/lib/core/discovery/index.js +2 -2
- package/dist/lib/external/mcp/handlers/guard.js +6 -3
- package/dist/lib/http/HttpServer.js +0 -6
- package/dist/lib/http/routes/commands.d.ts +1 -1
- package/dist/lib/http/routes/commands.js +1 -66
- package/dist/lib/http/routes/remote.js +0 -5
- package/dist/lib/injection/ServiceMap.d.ts +0 -9
- package/dist/lib/injection/modules/AppModule.d.ts +2 -3
- package/dist/lib/injection/modules/AppModule.js +3 -30
- package/dist/lib/service/module/ModuleService.js +3 -13
- package/dist/lib/service/search/SearchEngine.js +1 -1
- package/dist/lib/shared/constants.d.ts +0 -15
- package/dist/lib/shared/constants.js +0 -10
- package/dist/scripts/release.js +2 -10
- package/package.json +4 -19
- package/dashboard/dist/assets/index-DdvZE4Yd.js +0 -128
- package/dist/lib/http/routes/snippets.d.ts +0 -6
- package/dist/lib/http/routes/snippets.js +0 -49
- package/dist/lib/platform/ClipboardManager.d.ts +0 -24
- package/dist/lib/platform/ClipboardManager.js +0 -142
- package/dist/lib/platform/NativeUi.d.ts +0 -53
- package/dist/lib/platform/NativeUi.js +0 -284
- package/dist/lib/platform/ios/index.d.ts +0 -38
- package/dist/lib/platform/ios/index.js +0 -42
- package/dist/lib/platform/ios/routes/spm.d.ts +0 -9
- package/dist/lib/platform/ios/routes/spm.js +0 -371
- package/dist/lib/platform/ios/snippet/PlaceholderConverter.d.ts +0 -21
- package/dist/lib/platform/ios/snippet/PlaceholderConverter.js +0 -48
- package/dist/lib/platform/ios/snippet/XcodeCodec.d.ts +0 -23
- package/dist/lib/platform/ios/snippet/XcodeCodec.js +0 -96
- package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +0 -56
- package/dist/lib/platform/ios/spm/DependencyGraph.js +0 -195
- package/dist/lib/platform/ios/spm/PackageSwiftParser.d.ts +0 -69
- package/dist/lib/platform/ios/spm/PackageSwiftParser.js +0 -231
- package/dist/lib/platform/ios/spm/PathFinder.d.ts +0 -28
- package/dist/lib/platform/ios/spm/PathFinder.js +0 -117
- package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +0 -44
- package/dist/lib/platform/ios/spm/PolicyEngine.js +0 -79
- package/dist/lib/platform/ios/spm/SpmHelper.d.ts +0 -102
- package/dist/lib/platform/ios/spm/SpmHelper.js +0 -464
- package/dist/lib/platform/ios/xcode/HeaderResolver.d.ts +0 -33
- package/dist/lib/platform/ios/xcode/HeaderResolver.js +0 -90
- package/dist/lib/platform/ios/xcode/SaveEventFilter.d.ts +0 -66
- package/dist/lib/platform/ios/xcode/SaveEventFilter.js +0 -142
- package/dist/lib/platform/ios/xcode/XcodeAutomation.d.ts +0 -71
- package/dist/lib/platform/ios/xcode/XcodeAutomation.js +0 -327
- package/dist/lib/platform/ios/xcode/XcodeImportResolver.d.ts +0 -130
- package/dist/lib/platform/ios/xcode/XcodeImportResolver.js +0 -404
- package/dist/lib/platform/ios/xcode/XcodeIntegration.d.ts +0 -89
- package/dist/lib/platform/ios/xcode/XcodeIntegration.js +0 -588
- package/dist/lib/platform/ios/xcode/XcodeWriteUtils.d.ts +0 -99
- package/dist/lib/platform/ios/xcode/XcodeWriteUtils.js +0 -190
- package/dist/lib/service/automation/ActionPipeline.d.ts +0 -34
- package/dist/lib/service/automation/ActionPipeline.js +0 -53
- package/dist/lib/service/automation/AutomationOrchestrator.d.ts +0 -86
- package/dist/lib/service/automation/AutomationOrchestrator.js +0 -57
- package/dist/lib/service/automation/ContextCollector.d.ts +0 -24
- package/dist/lib/service/automation/ContextCollector.js +0 -35
- package/dist/lib/service/automation/DirectiveDetector.d.ts +0 -51
- package/dist/lib/service/automation/DirectiveDetector.js +0 -112
- package/dist/lib/service/automation/FileWatcher.d.ts +0 -51
- package/dist/lib/service/automation/FileWatcher.js +0 -366
- package/dist/lib/service/automation/TriggerResolver.d.ts +0 -36
- package/dist/lib/service/automation/TriggerResolver.js +0 -62
- package/dist/lib/service/automation/handlers/AlinkHandler.d.ts +0 -7
- package/dist/lib/service/automation/handlers/AlinkHandler.js +0 -80
- package/dist/lib/service/automation/handlers/CreateHandler.d.ts +0 -11
- package/dist/lib/service/automation/handlers/CreateHandler.js +0 -170
- package/dist/lib/service/automation/handlers/GuardHandler.d.ts +0 -17
- package/dist/lib/service/automation/handlers/GuardHandler.js +0 -218
- package/dist/lib/service/automation/handlers/HeaderHandler.d.ts +0 -2
- package/dist/lib/service/automation/handlers/HeaderHandler.js +0 -32
- package/dist/lib/service/automation/handlers/SearchHandler.d.ts +0 -11
- package/dist/lib/service/automation/handlers/SearchHandler.js +0 -278
- package/dist/lib/service/snippet/SnippetFactory.d.ts +0 -101
- package/dist/lib/service/snippet/SnippetFactory.js +0 -145
- package/dist/lib/service/snippet/SnippetInstaller.d.ts +0 -91
- package/dist/lib/service/snippet/SnippetInstaller.js +0 -276
- package/dist/lib/service/snippet/codecs/SnippetCodec.d.ts +0 -44
- package/dist/lib/service/snippet/codecs/SnippetCodec.js +0 -35
- package/dist/lib/service/snippet/codecs/VSCodeCodec.d.ts +0 -27
- package/dist/lib/service/snippet/codecs/VSCodeCodec.js +0 -82
- package/dist/scripts/build-native-ui.d.ts +0 -3
- package/dist/scripts/build-native-ui.js +0 -62
- package/dist/scripts/init-snippets.d.ts +0 -30
- package/dist/scripts/init-snippets.js +0 -298
- package/dist/scripts/install-full.d.ts +0 -7
- package/dist/scripts/install-full.js +0 -38
- package/resources/native-ui/README.md +0 -29
- package/resources/native-ui/combined-window.swift +0 -494
- package/resources/native-ui/main.swift +0 -598
- package/scripts/postinstall-safe.mjs +0 -89
|
@@ -1,190 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* XcodeWriteUtils — Xcode 写入与插入工具函数
|
|
3
|
-
*
|
|
4
|
-
* 从 XcodeIntegration.js 拆分,负责:
|
|
5
|
-
* - 通用工具函数(sleep, withAutoSnippetNote)
|
|
6
|
-
* - SPM 依赖决策逻辑
|
|
7
|
-
* - Xcode osascript 写入
|
|
8
|
-
* - 文件写入回退
|
|
9
|
-
* - 粘贴行号偏移计算
|
|
10
|
-
*/
|
|
11
|
-
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
12
|
-
import { saveEventFilter } from './SaveEventFilter.js';
|
|
13
|
-
export function sleep(ms) {
|
|
14
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
|
-
}
|
|
16
|
-
/** 在 import 行末尾附加来源标记注释 */
|
|
17
|
-
export function withAutoSnippetNote(importLine) {
|
|
18
|
-
if (!importLine) {
|
|
19
|
-
return importLine;
|
|
20
|
-
}
|
|
21
|
-
const note = '// AutoSnippet: 自动插入';
|
|
22
|
-
if (importLine.includes(note)) {
|
|
23
|
-
return importLine;
|
|
24
|
-
}
|
|
25
|
-
return `${importLine} ${note}`;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* 将 SpmHelper.ensureDependency 返回值映射为三种动作:
|
|
29
|
-
* continue — 依赖已存在
|
|
30
|
-
* block — 循环/反向依赖,禁止插入
|
|
31
|
-
* review — 依赖缺失但可添加,需用户确认
|
|
32
|
-
*/
|
|
33
|
-
export function evaluateDepResult(ensureResult, from, to) {
|
|
34
|
-
if (ensureResult.exists) {
|
|
35
|
-
return { action: 'continue' };
|
|
36
|
-
}
|
|
37
|
-
if (!ensureResult.canAdd) {
|
|
38
|
-
return { action: 'block', reason: ensureResult.reason || 'cycleBlocked', from, to };
|
|
39
|
-
}
|
|
40
|
-
return { action: 'review', reason: ensureResult.reason || 'missingDependency', from, to };
|
|
41
|
-
}
|
|
42
|
-
/**
|
|
43
|
-
* 公共依赖审查弹窗逻辑(insertHeaders 和 _preflightDeps 共享)
|
|
44
|
-
*
|
|
45
|
-
* @param ctx { spmService, currentTarget, mod, ensureResult, NU, depWarnings, label }
|
|
46
|
-
* @returns }
|
|
47
|
-
*/
|
|
48
|
-
export function handleDepReview(ctx) {
|
|
49
|
-
const { spmService, currentTarget, mod, ensureResult, NU, depWarnings, label = '' } = ctx;
|
|
50
|
-
const fixMode = spmService.getFixMode();
|
|
51
|
-
const buttons = fixMode === 'fix'
|
|
52
|
-
? ['直接插入(信任架构)', '提示操作插入', '自动修复依赖', '取消操作']
|
|
53
|
-
: ['直接插入(信任架构)', '提示操作插入', '取消操作'];
|
|
54
|
-
const crossTag = ensureResult.crossPackage ? ' (跨包)' : '';
|
|
55
|
-
const prefix = label ? `[${label}] ` : '';
|
|
56
|
-
const userChoice = NU.promptWithButtons(`检测到依赖缺失:${currentTarget} -> ${mod}${crossTag}\n\n请选择处理方式:`, buttons, 'AutoSnippet SPM 依赖决策');
|
|
57
|
-
if (userChoice === '取消操作' ||
|
|
58
|
-
(!userChoice && !['直接插入(信任架构)', '提示操作插入', '自动修复依赖'].includes(userChoice))) {
|
|
59
|
-
return { blocked: true };
|
|
60
|
-
}
|
|
61
|
-
if (userChoice === '提示操作插入') {
|
|
62
|
-
depWarnings.set(mod, `${currentTarget} -> ${mod}`);
|
|
63
|
-
}
|
|
64
|
-
if (userChoice === '自动修复依赖') {
|
|
65
|
-
const fixResult = spmService.addDependency(currentTarget, mod);
|
|
66
|
-
if (fixResult.ok) {
|
|
67
|
-
NU.notify(`已补齐依赖:${currentTarget} -> ${mod}`, 'AutoSnippet SPM');
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
console.warn(` ⚠️ ${prefix}自动修复失败: ${fixResult.error},继续插入`);
|
|
71
|
-
depWarnings.set(mod, `${currentTarget} -> ${mod}`);
|
|
72
|
-
}
|
|
73
|
-
}
|
|
74
|
-
return { blocked: false };
|
|
75
|
-
}
|
|
76
|
-
// ═══════════════════════════════════════════════════════════════
|
|
77
|
-
// Xcode osascript 单条 import 写入
|
|
78
|
-
// ═══════════════════════════════════════════════════════════════
|
|
79
|
-
/**
|
|
80
|
-
* 通过 Xcode 自动化插入一条 import,保持 Xcode Undo 可用。
|
|
81
|
-
*
|
|
82
|
-
* 流程:保存剪贴板 → 写入 import 内容 → osascript 跳转+粘贴 → 恢复剪贴板
|
|
83
|
-
*
|
|
84
|
-
* @param importLine 完整的 import 文本
|
|
85
|
-
* @param insertLine 1-based 行号
|
|
86
|
-
* @param XA XcodeAutomation 模块
|
|
87
|
-
* @param CM ClipboardManager 模块
|
|
88
|
-
*/
|
|
89
|
-
export function writeImportLineXcode(importLine, insertLine, XA, CM) {
|
|
90
|
-
if (!XA.isXcodeRunning()) {
|
|
91
|
-
return false;
|
|
92
|
-
}
|
|
93
|
-
try {
|
|
94
|
-
const contentToWrite = `${String(importLine).trim()}\n`;
|
|
95
|
-
const previousClipboard = CM.read();
|
|
96
|
-
CM.write(contentToWrite);
|
|
97
|
-
const ok = XA.insertAtLineStartInXcode(insertLine);
|
|
98
|
-
// 始终恢复剪贴板
|
|
99
|
-
if (typeof previousClipboard === 'string') {
|
|
100
|
-
CM.write(previousClipboard);
|
|
101
|
-
}
|
|
102
|
-
return ok;
|
|
103
|
-
}
|
|
104
|
-
catch {
|
|
105
|
-
return false;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
// ═══════════════════════════════════════════════════════════════
|
|
109
|
-
// 文件写入回退
|
|
110
|
-
// ═══════════════════════════════════════════════════════════════
|
|
111
|
-
/**
|
|
112
|
-
* 纯文件写入插入单条 import。
|
|
113
|
-
* Xcode 会因文件变更而自动 reload。
|
|
114
|
-
*/
|
|
115
|
-
export function writeImportLineFile(filePath, importLine, isSwift) {
|
|
116
|
-
try {
|
|
117
|
-
const content = readFileSync(filePath, 'utf8');
|
|
118
|
-
const lines = content.split('\n');
|
|
119
|
-
let lastImportIdx = -1;
|
|
120
|
-
for (let i = 0; i < lines.length; i++) {
|
|
121
|
-
const t = lines[i].trim();
|
|
122
|
-
if (isSwift) {
|
|
123
|
-
if (t.startsWith('import ') && !t.startsWith('import (')) {
|
|
124
|
-
lastImportIdx = i;
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
else {
|
|
128
|
-
if (t.startsWith('#import ') || t.startsWith('#include ') || t.startsWith('@import ')) {
|
|
129
|
-
lastImportIdx = i;
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
const insertAt = lastImportIdx >= 0 ? lastImportIdx + 1 : 0;
|
|
134
|
-
lines.splice(insertAt, 0, importLine);
|
|
135
|
-
const newContent = lines.join('\n');
|
|
136
|
-
saveEventFilter.markWrite(filePath, newContent);
|
|
137
|
-
writeFileSync(filePath, newContent, 'utf8');
|
|
138
|
-
return true;
|
|
139
|
-
}
|
|
140
|
-
catch {
|
|
141
|
-
return false;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
// ═══════════════════════════════════════════════════════════════
|
|
145
|
-
// 粘贴行号偏移计算
|
|
146
|
-
// ═══════════════════════════════════════════════════════════════
|
|
147
|
-
/** 查找文件中最后一个 import 行的行号(1-based,0 表示无 import) */
|
|
148
|
-
export function getLastImportLine(filePath) {
|
|
149
|
-
try {
|
|
150
|
-
if (!existsSync(filePath)) {
|
|
151
|
-
return 0;
|
|
152
|
-
}
|
|
153
|
-
const content = readFileSync(filePath, 'utf8');
|
|
154
|
-
const lines = content.split(/\r?\n/);
|
|
155
|
-
let lastIdx = -1;
|
|
156
|
-
for (let i = 0; i < lines.length; i++) {
|
|
157
|
-
const t = lines[i].trim();
|
|
158
|
-
if (t.startsWith('#import ') ||
|
|
159
|
-
t.startsWith('@import ') ||
|
|
160
|
-
t.startsWith('#include ') ||
|
|
161
|
-
t.startsWith('import ')) {
|
|
162
|
-
lastIdx = i;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
return lastIdx >= 0 ? lastIdx + 1 : 0;
|
|
166
|
-
}
|
|
167
|
-
catch {
|
|
168
|
-
return 0;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
/**
|
|
172
|
-
* 计算代码粘贴行号
|
|
173
|
-
*
|
|
174
|
-
* 如果 headers 插入在 trigger 行之前(import 区),trigger 行号需要向下偏移。
|
|
175
|
-
*/
|
|
176
|
-
export function computePasteLineNumber(triggerLineNumber, headerInsertCount, filePath, options = {}) {
|
|
177
|
-
const expectedCount = Number.isFinite(options.expectedHeaderCount)
|
|
178
|
-
? options.expectedHeaderCount
|
|
179
|
-
: headerInsertCount;
|
|
180
|
-
if (expectedCount > 0) {
|
|
181
|
-
if (options.forceOffset) {
|
|
182
|
-
return triggerLineNumber + expectedCount;
|
|
183
|
-
}
|
|
184
|
-
const headerInsertPosition = getLastImportLine(filePath);
|
|
185
|
-
if (headerInsertPosition > 0 && headerInsertPosition < triggerLineNumber) {
|
|
186
|
-
return triggerLineNumber + expectedCount;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
return triggerLineNumber;
|
|
190
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ActionPipeline — 自动化动作管线
|
|
3
|
-
* 按顺序执行注册的 action handlers
|
|
4
|
-
*/
|
|
5
|
-
export declare class ActionPipeline {
|
|
6
|
-
#private;
|
|
7
|
-
constructor();
|
|
8
|
-
/**
|
|
9
|
-
* 注册动作处理器
|
|
10
|
-
* @param type 触发类型
|
|
11
|
-
* @param handler async (trigger, context) => result
|
|
12
|
-
*/
|
|
13
|
-
register(type: string, handler: (trigger: Record<string, unknown>, context: Record<string, unknown>) => Promise<unknown>): void;
|
|
14
|
-
/**
|
|
15
|
-
* 执行管线
|
|
16
|
-
* @param trigger
|
|
17
|
-
* @returns >}
|
|
18
|
-
*/
|
|
19
|
-
execute(trigger: {
|
|
20
|
-
type: string;
|
|
21
|
-
name?: string;
|
|
22
|
-
params?: Record<string, unknown>;
|
|
23
|
-
}, context: Record<string, unknown>): Promise<{
|
|
24
|
-
success: boolean;
|
|
25
|
-
result: unknown;
|
|
26
|
-
error?: undefined;
|
|
27
|
-
} | {
|
|
28
|
-
success: boolean;
|
|
29
|
-
error: string;
|
|
30
|
-
result?: undefined;
|
|
31
|
-
}>;
|
|
32
|
-
/** 获取已注册的动作类型 */
|
|
33
|
-
getRegisteredTypes(): any[];
|
|
34
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ActionPipeline — 自动化动作管线
|
|
3
|
-
* 按顺序执行注册的 action handlers
|
|
4
|
-
*/
|
|
5
|
-
import Logger from '../../infrastructure/logging/Logger.js';
|
|
6
|
-
export class ActionPipeline {
|
|
7
|
-
#actions; // Map<type, handler>
|
|
8
|
-
#logger;
|
|
9
|
-
constructor() {
|
|
10
|
-
this.#actions = new Map();
|
|
11
|
-
this.#logger = Logger.getInstance();
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* 注册动作处理器
|
|
15
|
-
* @param type 触发类型
|
|
16
|
-
* @param handler async (trigger, context) => result
|
|
17
|
-
*/
|
|
18
|
-
register(type, handler) {
|
|
19
|
-
this.#actions.set(type, handler);
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* 执行管线
|
|
23
|
-
* @param trigger
|
|
24
|
-
* @returns >}
|
|
25
|
-
*/
|
|
26
|
-
async execute(trigger, context) {
|
|
27
|
-
const handler = this.#actions.get(trigger.type);
|
|
28
|
-
if (!handler) {
|
|
29
|
-
// 尝试通用 handler
|
|
30
|
-
const fallback = this.#actions.get('*');
|
|
31
|
-
if (fallback) {
|
|
32
|
-
return this.#runHandler(fallback, trigger, context);
|
|
33
|
-
}
|
|
34
|
-
this.#logger.warn(`[ActionPipeline] 未找到 handler: ${trigger.type}`);
|
|
35
|
-
return { success: false, error: `未知触发类型: ${trigger.type}` };
|
|
36
|
-
}
|
|
37
|
-
return this.#runHandler(handler, trigger, context);
|
|
38
|
-
}
|
|
39
|
-
/** 获取已注册的动作类型 */
|
|
40
|
-
getRegisteredTypes() {
|
|
41
|
-
return [...this.#actions.keys()];
|
|
42
|
-
}
|
|
43
|
-
async #runHandler(handler, trigger, context) {
|
|
44
|
-
try {
|
|
45
|
-
const result = await handler(trigger, context);
|
|
46
|
-
return { success: true, result };
|
|
47
|
-
}
|
|
48
|
-
catch (err) {
|
|
49
|
-
this.#logger.error(`[ActionPipeline] handler 异常:`, err.message);
|
|
50
|
-
return { success: false, error: err.message };
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AutomationOrchestrator — 自动化编排器
|
|
3
|
-
* 整合 TriggerResolver + ContextCollector + ActionPipeline
|
|
4
|
-
*/
|
|
5
|
-
import { ActionPipeline } from './ActionPipeline.js';
|
|
6
|
-
import { ContextCollector } from './ContextCollector.js';
|
|
7
|
-
import { TriggerResolver } from './TriggerResolver.js';
|
|
8
|
-
export declare class AutomationOrchestrator {
|
|
9
|
-
#private;
|
|
10
|
-
constructor(options?: {
|
|
11
|
-
triggerResolver?: TriggerResolver;
|
|
12
|
-
contextCollector?: ContextCollector;
|
|
13
|
-
pipeline?: ActionPipeline;
|
|
14
|
-
});
|
|
15
|
-
/**
|
|
16
|
-
* 执行自动化流程
|
|
17
|
-
* @param trigger 原始触发
|
|
18
|
-
* @param context 原始上下文
|
|
19
|
-
* @returns >}
|
|
20
|
-
*/
|
|
21
|
-
run(trigger: string | Record<string, unknown>, context?: Record<string, unknown>): Promise<{
|
|
22
|
-
resolvedTrigger: {
|
|
23
|
-
type: string;
|
|
24
|
-
name: string;
|
|
25
|
-
params: {
|
|
26
|
-
option: string;
|
|
27
|
-
};
|
|
28
|
-
raw: string;
|
|
29
|
-
} | {
|
|
30
|
-
type: string;
|
|
31
|
-
name: string;
|
|
32
|
-
params: {
|
|
33
|
-
option?: undefined;
|
|
34
|
-
};
|
|
35
|
-
raw: string;
|
|
36
|
-
} | {
|
|
37
|
-
type: string;
|
|
38
|
-
name: string;
|
|
39
|
-
params: Record<string, unknown>;
|
|
40
|
-
raw: Record<string, unknown>;
|
|
41
|
-
} | {
|
|
42
|
-
type: string;
|
|
43
|
-
raw: never;
|
|
44
|
-
name?: undefined;
|
|
45
|
-
params?: undefined;
|
|
46
|
-
};
|
|
47
|
-
success: boolean;
|
|
48
|
-
result: unknown;
|
|
49
|
-
error?: undefined;
|
|
50
|
-
} | {
|
|
51
|
-
resolvedTrigger: {
|
|
52
|
-
type: string;
|
|
53
|
-
name: string;
|
|
54
|
-
params: {
|
|
55
|
-
option: string;
|
|
56
|
-
};
|
|
57
|
-
raw: string;
|
|
58
|
-
} | {
|
|
59
|
-
type: string;
|
|
60
|
-
name: string;
|
|
61
|
-
params: {
|
|
62
|
-
option?: undefined;
|
|
63
|
-
};
|
|
64
|
-
raw: string;
|
|
65
|
-
} | {
|
|
66
|
-
type: string;
|
|
67
|
-
name: string;
|
|
68
|
-
params: Record<string, unknown>;
|
|
69
|
-
raw: Record<string, unknown>;
|
|
70
|
-
} | {
|
|
71
|
-
type: string;
|
|
72
|
-
raw: never;
|
|
73
|
-
name?: undefined;
|
|
74
|
-
params?: undefined;
|
|
75
|
-
};
|
|
76
|
-
success: boolean;
|
|
77
|
-
error: string;
|
|
78
|
-
result?: undefined;
|
|
79
|
-
}>;
|
|
80
|
-
/** 注册动作处理器 */
|
|
81
|
-
registerAction(type: string, handler: (trigger: Record<string, unknown>, context: Record<string, unknown>) => Promise<unknown>): void;
|
|
82
|
-
/** 获取执行历史 */
|
|
83
|
-
getHistory(): Record<string, unknown>[];
|
|
84
|
-
/** 获取管线 */
|
|
85
|
-
getPipeline(): ActionPipeline;
|
|
86
|
-
}
|
|
@@ -1,57 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* AutomationOrchestrator — 自动化编排器
|
|
3
|
-
* 整合 TriggerResolver + ContextCollector + ActionPipeline
|
|
4
|
-
*/
|
|
5
|
-
import Logger from '../../infrastructure/logging/Logger.js';
|
|
6
|
-
import { ActionPipeline } from './ActionPipeline.js';
|
|
7
|
-
import { ContextCollector } from './ContextCollector.js';
|
|
8
|
-
import { TriggerResolver } from './TriggerResolver.js';
|
|
9
|
-
export class AutomationOrchestrator {
|
|
10
|
-
#triggerResolver;
|
|
11
|
-
#contextCollector;
|
|
12
|
-
#pipeline;
|
|
13
|
-
#logger;
|
|
14
|
-
#history;
|
|
15
|
-
constructor(options = {}) {
|
|
16
|
-
this.#triggerResolver = options.triggerResolver || new TriggerResolver();
|
|
17
|
-
this.#contextCollector = options.contextCollector || new ContextCollector();
|
|
18
|
-
this.#pipeline = options.pipeline || new ActionPipeline();
|
|
19
|
-
this.#logger = Logger.getInstance();
|
|
20
|
-
this.#history = [];
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* 执行自动化流程
|
|
24
|
-
* @param trigger 原始触发
|
|
25
|
-
* @param context 原始上下文
|
|
26
|
-
* @returns >}
|
|
27
|
-
*/
|
|
28
|
-
async run(trigger, context = {}) {
|
|
29
|
-
const resolvedTrigger = this.#triggerResolver.resolve(trigger);
|
|
30
|
-
const collectedContext = this.#contextCollector.collect(context);
|
|
31
|
-
this.#logger.info(`[AutomationOrchestrator] run type=${resolvedTrigger.type} name=${resolvedTrigger.name || ''}`);
|
|
32
|
-
const pipelineResult = await this.#pipeline.execute(resolvedTrigger, collectedContext);
|
|
33
|
-
const record = {
|
|
34
|
-
trigger: resolvedTrigger,
|
|
35
|
-
context: { filePath: collectedContext.filePath, language: collectedContext.language },
|
|
36
|
-
result: pipelineResult,
|
|
37
|
-
timestamp: new Date().toISOString(),
|
|
38
|
-
};
|
|
39
|
-
this.#history.push(record);
|
|
40
|
-
if (this.#history.length > 200) {
|
|
41
|
-
this.#history = this.#history.slice(-200);
|
|
42
|
-
}
|
|
43
|
-
return { ...pipelineResult, resolvedTrigger };
|
|
44
|
-
}
|
|
45
|
-
/** 注册动作处理器 */
|
|
46
|
-
registerAction(type, handler) {
|
|
47
|
-
this.#pipeline.register(type, handler);
|
|
48
|
-
}
|
|
49
|
-
/** 获取执行历史 */
|
|
50
|
-
getHistory() {
|
|
51
|
-
return [...this.#history];
|
|
52
|
-
}
|
|
53
|
-
/** 获取管线 */
|
|
54
|
-
getPipeline() {
|
|
55
|
-
return this.#pipeline;
|
|
56
|
-
}
|
|
57
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ContextCollector — 自动化上下文收集器
|
|
3
|
-
* 收集并规范化自动化执行所需的上下文信息
|
|
4
|
-
*/
|
|
5
|
-
export declare class ContextCollector {
|
|
6
|
-
#private;
|
|
7
|
-
/**
|
|
8
|
-
* 收集上下文
|
|
9
|
-
* @param rawContext 原始上下文
|
|
10
|
-
* @returns 规范化的上下文
|
|
11
|
-
*/
|
|
12
|
-
collect(rawContext?: Record<string, unknown>): {
|
|
13
|
-
filePath: {} | null;
|
|
14
|
-
content: {} | null;
|
|
15
|
-
language: {} | null;
|
|
16
|
-
projectRoot: {} | null;
|
|
17
|
-
user: {};
|
|
18
|
-
timestamp: string;
|
|
19
|
-
environment: {
|
|
20
|
-
platform: NodeJS.Platform;
|
|
21
|
-
nodeVersion: string;
|
|
22
|
-
};
|
|
23
|
-
};
|
|
24
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ContextCollector — 自动化上下文收集器
|
|
3
|
-
* 收集并规范化自动化执行所需的上下文信息
|
|
4
|
-
*/
|
|
5
|
-
import { LanguageService } from '../../shared/LanguageService.js';
|
|
6
|
-
export class ContextCollector {
|
|
7
|
-
/**
|
|
8
|
-
* 收集上下文
|
|
9
|
-
* @param rawContext 原始上下文
|
|
10
|
-
* @returns 规范化的上下文
|
|
11
|
-
*/
|
|
12
|
-
collect(rawContext = {}) {
|
|
13
|
-
return {
|
|
14
|
-
...rawContext,
|
|
15
|
-
filePath: rawContext.filePath || null,
|
|
16
|
-
content: rawContext.content || null,
|
|
17
|
-
language: rawContext.language ||
|
|
18
|
-
this.#detectLanguage(rawContext.filePath),
|
|
19
|
-
projectRoot: rawContext.projectRoot || null,
|
|
20
|
-
user: rawContext.user || 'default',
|
|
21
|
-
timestamp: new Date().toISOString(),
|
|
22
|
-
environment: {
|
|
23
|
-
platform: process.platform,
|
|
24
|
-
nodeVersion: process.version,
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
#detectLanguage(filePath) {
|
|
29
|
-
if (!filePath) {
|
|
30
|
-
return null;
|
|
31
|
-
}
|
|
32
|
-
const lang = LanguageService.inferLang(filePath);
|
|
33
|
-
return lang === 'unknown' ? null : lang;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DirectiveDetector - 文件内指令检测器
|
|
3
|
-
*
|
|
4
|
-
* 检测 // as:c(创建)、// as:s(搜索)、// as:a(审计)等指令
|
|
5
|
-
* V2 ESM 版本,对应 V1 DirectiveDetector.js
|
|
6
|
-
*/
|
|
7
|
-
/** 指令标记常量 */
|
|
8
|
-
export declare const MARKS: {
|
|
9
|
-
HEADER_INCLUDE: string;
|
|
10
|
-
HEADER_IMPORT: string;
|
|
11
|
-
HEADER_INCLUDE_SHORT: string;
|
|
12
|
-
HEADER_IMPORT_SHORT: string;
|
|
13
|
-
CREATE_SHORT: string;
|
|
14
|
-
CREATE_ALIAS: string;
|
|
15
|
-
AUDIT_SHORT: string;
|
|
16
|
-
AUDIT_ALIAS: string;
|
|
17
|
-
SEARCH_SHORT: string;
|
|
18
|
-
SEARCH_LONG: string;
|
|
19
|
-
SEARCH_ALIAS: string;
|
|
20
|
-
ALINK: string;
|
|
21
|
-
};
|
|
22
|
-
/** 正则表达式 */
|
|
23
|
-
export declare const REGEX: {
|
|
24
|
-
CREATE_LINE: RegExp;
|
|
25
|
-
CREATE_REMOVE: RegExp;
|
|
26
|
-
HEADER_OBJC: RegExp;
|
|
27
|
-
HEADER_SWIFT: RegExp;
|
|
28
|
-
IMPORT_OBJC: RegExp;
|
|
29
|
-
IMPORT_SWIFT: RegExp;
|
|
30
|
-
SEARCH_MARK: RegExp;
|
|
31
|
-
};
|
|
32
|
-
/**
|
|
33
|
-
* 检测文件内容中的所有触发指令
|
|
34
|
-
*
|
|
35
|
-
* @param data 文件内容
|
|
36
|
-
* @param filename 文件名
|
|
37
|
-
* @returns {{ importArray: string[], headerLine: string|null, alinkLine: string|null,
|
|
38
|
-
* createLine: string|null, createOption: string|null,
|
|
39
|
-
* guardLine: string|null, searchLine: string|null, isSwift: boolean, language: string }}
|
|
40
|
-
*/
|
|
41
|
-
export declare function detectTriggers(data: string, filename: string): {
|
|
42
|
-
importArray: string[];
|
|
43
|
-
headerLine: string | null;
|
|
44
|
-
alinkLine: string | null;
|
|
45
|
-
createLine: string | null;
|
|
46
|
-
createOption: string | null;
|
|
47
|
-
guardLine: string | null;
|
|
48
|
-
searchLine: string | null;
|
|
49
|
-
isSwift: boolean;
|
|
50
|
-
language: string;
|
|
51
|
-
};
|
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* DirectiveDetector - 文件内指令检测器
|
|
3
|
-
*
|
|
4
|
-
* 检测 // as:c(创建)、// as:s(搜索)、// as:a(审计)等指令
|
|
5
|
-
* V2 ESM 版本,对应 V1 DirectiveDetector.js
|
|
6
|
-
*/
|
|
7
|
-
import { stripTriggerPrefix, TRIGGER_SYMBOL } from '../../infrastructure/config/TriggerSymbol.js';
|
|
8
|
-
import { LanguageService } from '../../shared/LanguageService.js';
|
|
9
|
-
/** 指令标记常量 */
|
|
10
|
-
export const MARKS = {
|
|
11
|
-
HEADER_INCLUDE: '// autosnippet:include ',
|
|
12
|
-
HEADER_IMPORT: '// autosnippet:import ',
|
|
13
|
-
HEADER_INCLUDE_SHORT: '// as:include ',
|
|
14
|
-
HEADER_IMPORT_SHORT: '// as:import ',
|
|
15
|
-
CREATE_SHORT: '// as:create',
|
|
16
|
-
CREATE_ALIAS: '// as:c',
|
|
17
|
-
AUDIT_SHORT: '// as:audit',
|
|
18
|
-
AUDIT_ALIAS: '// as:a',
|
|
19
|
-
SEARCH_SHORT: '// as:search',
|
|
20
|
-
SEARCH_LONG: '// autosnippet:search',
|
|
21
|
-
SEARCH_ALIAS: '// as:s',
|
|
22
|
-
ALINK: 'alink',
|
|
23
|
-
};
|
|
24
|
-
/** 正则表达式 */
|
|
25
|
-
export const REGEX = {
|
|
26
|
-
CREATE_LINE: /^\/\/\s*as:(?:create|c)(?:\s+(-[cf]))?\s*$/,
|
|
27
|
-
CREATE_REMOVE: /^@?\s*\/\/\s*as:(?:create|c)(?:\s+-[cf])?\s*\r?\n?/gm,
|
|
28
|
-
HEADER_OBJC: /^@?\/\/\s*(?:autosnippet|as):include\s+(?:<([A-Za-z0-9_]+)\/([A-Za-z0-9_+.-]+\.h)>|"([A-Za-z0-9_+./-]+\.h)")(\s+.+)?$/,
|
|
29
|
-
HEADER_SWIFT: /^@?\/\/\s*(?:autosnippet|as):import\s+\w+$/,
|
|
30
|
-
IMPORT_OBJC: /^#import\s*<[A-Za-z0-9_]+\/[A-Za-z0-9_+.-]+\.h>$/,
|
|
31
|
-
IMPORT_SWIFT: /^import\s*\w+$/,
|
|
32
|
-
SEARCH_MARK: /\/\/\s*(?:autosnippet|as):(?:search|s)(\s|$)/,
|
|
33
|
-
};
|
|
34
|
-
/** 推断文件语言 —— 委托给 LanguageService */
|
|
35
|
-
function _inferLanguage(filename) {
|
|
36
|
-
return LanguageService.inferLang(filename);
|
|
37
|
-
}
|
|
38
|
-
/**
|
|
39
|
-
* 检测文件内容中的所有触发指令
|
|
40
|
-
*
|
|
41
|
-
* @param data 文件内容
|
|
42
|
-
* @param filename 文件名
|
|
43
|
-
* @returns {{ importArray: string[], headerLine: string|null, alinkLine: string|null,
|
|
44
|
-
* createLine: string|null, createOption: string|null,
|
|
45
|
-
* guardLine: string|null, searchLine: string|null, isSwift: boolean, language: string }}
|
|
46
|
-
*/
|
|
47
|
-
export function detectTriggers(data, filename) {
|
|
48
|
-
const language = _inferLanguage(filename);
|
|
49
|
-
const isSwift = language === 'swift';
|
|
50
|
-
// Import/header 自动插入目前仅支持 ObjC/Swift(Xcode 工作流)
|
|
51
|
-
const isApple = isSwift || language === 'objectivec';
|
|
52
|
-
const currImportReg = isSwift ? REGEX.IMPORT_SWIFT : REGEX.IMPORT_OBJC;
|
|
53
|
-
const _currHeaderReg = isSwift ? REGEX.HEADER_SWIFT : REGEX.HEADER_OBJC;
|
|
54
|
-
const triggers = {
|
|
55
|
-
importArray: [],
|
|
56
|
-
headerLine: null,
|
|
57
|
-
alinkLine: null,
|
|
58
|
-
createLine: null,
|
|
59
|
-
createOption: null,
|
|
60
|
-
guardLine: null,
|
|
61
|
-
searchLine: null,
|
|
62
|
-
isSwift, // backward compat
|
|
63
|
-
language, // v3.1 多语言标识
|
|
64
|
-
};
|
|
65
|
-
const lines = data.split('\n');
|
|
66
|
-
for (const line of lines) {
|
|
67
|
-
const lineVal = line.trim();
|
|
68
|
-
const normalizedLineVal = stripTriggerPrefix(lineVal);
|
|
69
|
-
// import 收集(仅 ObjC/Swift — Xcode 头文件工作流)
|
|
70
|
-
if (isApple && currImportReg.test(lineVal)) {
|
|
71
|
-
triggers.importArray.push(lineVal);
|
|
72
|
-
}
|
|
73
|
-
// header 指令
|
|
74
|
-
if (_isHeaderDirective(normalizedLineVal)) {
|
|
75
|
-
triggers.headerLine = normalizedLineVal;
|
|
76
|
-
}
|
|
77
|
-
// alink 指令
|
|
78
|
-
if (lineVal.startsWith(TRIGGER_SYMBOL) && lineVal.endsWith(TRIGGER_SYMBOL + MARKS.ALINK)) {
|
|
79
|
-
triggers.alinkLine = lineVal;
|
|
80
|
-
}
|
|
81
|
-
// create 指令
|
|
82
|
-
const createMatch = normalizedLineVal.match(REGEX.CREATE_LINE);
|
|
83
|
-
if (createMatch) {
|
|
84
|
-
triggers.createLine = lineVal;
|
|
85
|
-
triggers.createOption = createMatch[1] === '-c' ? 'c' : createMatch[1] === '-f' ? 'f' : null;
|
|
86
|
-
}
|
|
87
|
-
// guard/audit 指令
|
|
88
|
-
if (_isGuardDirective(normalizedLineVal)) {
|
|
89
|
-
triggers.guardLine = normalizedLineVal;
|
|
90
|
-
}
|
|
91
|
-
// search 指令
|
|
92
|
-
if (_isSearchDirective(normalizedLineVal)) {
|
|
93
|
-
triggers.searchLine = normalizedLineVal;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
return triggers;
|
|
97
|
-
}
|
|
98
|
-
function _isHeaderDirective(line) {
|
|
99
|
-
return (line.startsWith(MARKS.HEADER_INCLUDE) ||
|
|
100
|
-
line.startsWith(MARKS.HEADER_IMPORT) ||
|
|
101
|
-
line.startsWith(MARKS.HEADER_INCLUDE_SHORT) ||
|
|
102
|
-
line.startsWith(MARKS.HEADER_IMPORT_SHORT));
|
|
103
|
-
}
|
|
104
|
-
function _isGuardDirective(line) {
|
|
105
|
-
// 精确匹配: // as:audit 或 // as:a,后面只能是空格或行尾
|
|
106
|
-
return /^\/\/\s*as:(?:audit|a)(?:\s|$)/.test(line);
|
|
107
|
-
}
|
|
108
|
-
function _isSearchDirective(line) {
|
|
109
|
-
return (line.startsWith(MARKS.SEARCH_SHORT) ||
|
|
110
|
-
line.startsWith(MARKS.SEARCH_LONG) ||
|
|
111
|
-
line.startsWith(MARKS.SEARCH_ALIAS));
|
|
112
|
-
}
|