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.
Files changed (102) hide show
  1. package/dashboard/dist/assets/{icons-C1dUryS-.js → icons-BofcEZ3f.js} +1 -1
  2. package/dashboard/dist/assets/index-SiN1GChm.js +128 -0
  3. package/dashboard/dist/index.html +2 -2
  4. package/dist/bin/cli.d.ts +0 -1
  5. package/dist/bin/cli.js +0 -133
  6. package/dist/lib/cli/SetupService.d.ts +46 -2
  7. package/dist/lib/cli/SetupService.js +2 -27
  8. package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.d.ts +2 -5
  9. package/dist/lib/{platform/ios/spm → core/discovery}/SpmDiscoverer.js +159 -44
  10. package/dist/lib/core/discovery/index.d.ts +1 -1
  11. package/dist/lib/core/discovery/index.js +2 -2
  12. package/dist/lib/external/mcp/handlers/guard.js +6 -3
  13. package/dist/lib/http/HttpServer.js +0 -6
  14. package/dist/lib/http/routes/commands.d.ts +1 -1
  15. package/dist/lib/http/routes/commands.js +1 -66
  16. package/dist/lib/http/routes/remote.js +0 -5
  17. package/dist/lib/injection/ServiceMap.d.ts +0 -9
  18. package/dist/lib/injection/modules/AppModule.d.ts +2 -3
  19. package/dist/lib/injection/modules/AppModule.js +3 -30
  20. package/dist/lib/service/module/ModuleService.js +3 -13
  21. package/dist/lib/service/search/SearchEngine.js +1 -1
  22. package/dist/lib/shared/constants.d.ts +0 -15
  23. package/dist/lib/shared/constants.js +0 -10
  24. package/dist/scripts/release.js +2 -10
  25. package/package.json +4 -19
  26. package/dashboard/dist/assets/index-DdvZE4Yd.js +0 -128
  27. package/dist/lib/http/routes/snippets.d.ts +0 -6
  28. package/dist/lib/http/routes/snippets.js +0 -49
  29. package/dist/lib/platform/ClipboardManager.d.ts +0 -24
  30. package/dist/lib/platform/ClipboardManager.js +0 -142
  31. package/dist/lib/platform/NativeUi.d.ts +0 -53
  32. package/dist/lib/platform/NativeUi.js +0 -284
  33. package/dist/lib/platform/ios/index.d.ts +0 -38
  34. package/dist/lib/platform/ios/index.js +0 -42
  35. package/dist/lib/platform/ios/routes/spm.d.ts +0 -9
  36. package/dist/lib/platform/ios/routes/spm.js +0 -371
  37. package/dist/lib/platform/ios/snippet/PlaceholderConverter.d.ts +0 -21
  38. package/dist/lib/platform/ios/snippet/PlaceholderConverter.js +0 -48
  39. package/dist/lib/platform/ios/snippet/XcodeCodec.d.ts +0 -23
  40. package/dist/lib/platform/ios/snippet/XcodeCodec.js +0 -96
  41. package/dist/lib/platform/ios/spm/DependencyGraph.d.ts +0 -56
  42. package/dist/lib/platform/ios/spm/DependencyGraph.js +0 -195
  43. package/dist/lib/platform/ios/spm/PackageSwiftParser.d.ts +0 -69
  44. package/dist/lib/platform/ios/spm/PackageSwiftParser.js +0 -231
  45. package/dist/lib/platform/ios/spm/PathFinder.d.ts +0 -28
  46. package/dist/lib/platform/ios/spm/PathFinder.js +0 -117
  47. package/dist/lib/platform/ios/spm/PolicyEngine.d.ts +0 -44
  48. package/dist/lib/platform/ios/spm/PolicyEngine.js +0 -79
  49. package/dist/lib/platform/ios/spm/SpmHelper.d.ts +0 -102
  50. package/dist/lib/platform/ios/spm/SpmHelper.js +0 -464
  51. package/dist/lib/platform/ios/xcode/HeaderResolver.d.ts +0 -33
  52. package/dist/lib/platform/ios/xcode/HeaderResolver.js +0 -90
  53. package/dist/lib/platform/ios/xcode/SaveEventFilter.d.ts +0 -66
  54. package/dist/lib/platform/ios/xcode/SaveEventFilter.js +0 -142
  55. package/dist/lib/platform/ios/xcode/XcodeAutomation.d.ts +0 -71
  56. package/dist/lib/platform/ios/xcode/XcodeAutomation.js +0 -327
  57. package/dist/lib/platform/ios/xcode/XcodeImportResolver.d.ts +0 -130
  58. package/dist/lib/platform/ios/xcode/XcodeImportResolver.js +0 -404
  59. package/dist/lib/platform/ios/xcode/XcodeIntegration.d.ts +0 -89
  60. package/dist/lib/platform/ios/xcode/XcodeIntegration.js +0 -588
  61. package/dist/lib/platform/ios/xcode/XcodeWriteUtils.d.ts +0 -99
  62. package/dist/lib/platform/ios/xcode/XcodeWriteUtils.js +0 -190
  63. package/dist/lib/service/automation/ActionPipeline.d.ts +0 -34
  64. package/dist/lib/service/automation/ActionPipeline.js +0 -53
  65. package/dist/lib/service/automation/AutomationOrchestrator.d.ts +0 -86
  66. package/dist/lib/service/automation/AutomationOrchestrator.js +0 -57
  67. package/dist/lib/service/automation/ContextCollector.d.ts +0 -24
  68. package/dist/lib/service/automation/ContextCollector.js +0 -35
  69. package/dist/lib/service/automation/DirectiveDetector.d.ts +0 -51
  70. package/dist/lib/service/automation/DirectiveDetector.js +0 -112
  71. package/dist/lib/service/automation/FileWatcher.d.ts +0 -51
  72. package/dist/lib/service/automation/FileWatcher.js +0 -366
  73. package/dist/lib/service/automation/TriggerResolver.d.ts +0 -36
  74. package/dist/lib/service/automation/TriggerResolver.js +0 -62
  75. package/dist/lib/service/automation/handlers/AlinkHandler.d.ts +0 -7
  76. package/dist/lib/service/automation/handlers/AlinkHandler.js +0 -80
  77. package/dist/lib/service/automation/handlers/CreateHandler.d.ts +0 -11
  78. package/dist/lib/service/automation/handlers/CreateHandler.js +0 -170
  79. package/dist/lib/service/automation/handlers/GuardHandler.d.ts +0 -17
  80. package/dist/lib/service/automation/handlers/GuardHandler.js +0 -218
  81. package/dist/lib/service/automation/handlers/HeaderHandler.d.ts +0 -2
  82. package/dist/lib/service/automation/handlers/HeaderHandler.js +0 -32
  83. package/dist/lib/service/automation/handlers/SearchHandler.d.ts +0 -11
  84. package/dist/lib/service/automation/handlers/SearchHandler.js +0 -278
  85. package/dist/lib/service/snippet/SnippetFactory.d.ts +0 -101
  86. package/dist/lib/service/snippet/SnippetFactory.js +0 -145
  87. package/dist/lib/service/snippet/SnippetInstaller.d.ts +0 -91
  88. package/dist/lib/service/snippet/SnippetInstaller.js +0 -276
  89. package/dist/lib/service/snippet/codecs/SnippetCodec.d.ts +0 -44
  90. package/dist/lib/service/snippet/codecs/SnippetCodec.js +0 -35
  91. package/dist/lib/service/snippet/codecs/VSCodeCodec.d.ts +0 -27
  92. package/dist/lib/service/snippet/codecs/VSCodeCodec.js +0 -82
  93. package/dist/scripts/build-native-ui.d.ts +0 -3
  94. package/dist/scripts/build-native-ui.js +0 -62
  95. package/dist/scripts/init-snippets.d.ts +0 -30
  96. package/dist/scripts/init-snippets.js +0 -298
  97. package/dist/scripts/install-full.d.ts +0 -7
  98. package/dist/scripts/install-full.js +0 -38
  99. package/resources/native-ui/README.md +0 -29
  100. package/resources/native-ui/combined-window.swift +0 -494
  101. package/resources/native-ui/main.swift +0 -598
  102. package/scripts/postinstall-safe.mjs +0 -89
@@ -1,51 +0,0 @@
1
- /**
2
- * FileWatcher - V2 文件监听主服务(精简版)
3
- *
4
- * 监控项目文件变更,检测 // as:c、// as:s、// as:a 等指令并自动处理。
5
- * 具体指令逻辑已拆分至 handlers/ 和 XcodeIntegration.js。
6
- *
7
- * 用法:
8
- * const watcher = new FileWatcher(specPath, projectRoot, { quiet: false });
9
- * watcher.start();
10
- */
11
- export declare class FileWatcher {
12
- _debounceTimers: Map<string, ReturnType<typeof setTimeout>>;
13
- _timeoutHead: ReturnType<typeof setTimeout> | undefined;
14
- _timeoutLink: ReturnType<typeof setTimeout> | undefined;
15
- _watcher: import('chokidar').FSWatcher | null;
16
- exts: string[] | null;
17
- onEvent: ((event: string, path: string) => void) | null;
18
- pathPrefix: string | null;
19
- projectRoot: string;
20
- quiet: boolean;
21
- specPath: string;
22
- /**
23
- * @param specPath boxspec.json 绝对路径
24
- * @param projectRoot 项目根目录
25
- * @param [opts.exts] 可选扩展名列表
26
- * @param [opts.pathPrefix] 可选路径前缀过滤
27
- * @param [opts.onEvent] 可选事件回调
28
- */
29
- constructor(specPath: string, projectRoot: string, opts?: {
30
- quiet?: boolean;
31
- pathPrefix?: string;
32
- onEvent?: ((event: string, path: string) => void) | null;
33
- exts?: string[];
34
- });
35
- /** 启动文件监听 */
36
- start(): import("chokidar").FSWatcher;
37
- /** 停止监听,释放所有资源 */
38
- stop(): Promise<void>;
39
- _processFile(fullPath: string, relativePath: string): Promise<void>;
40
- /** 追加候选项(通过 ServiceContainer 或 HTTP API) */
41
- _appendCandidates(items: Record<string, unknown>[], source: string): Promise<void>;
42
- /** 为候选解析头文件 */
43
- _resolveHeadersIfNeeded(item: Record<string, unknown>, relativePath: string, text: string): Promise<void>;
44
- /** 打开 Dashboard 页面 */
45
- _openDashboard(path: string): void;
46
- /** macOS 通知 */
47
- _notify(msg: string): void;
48
- /** 防抖 */
49
- _debounce(key: string, fn: () => void): void;
50
- }
51
- export default FileWatcher;
@@ -1,366 +0,0 @@
1
- /**
2
- * FileWatcher - V2 文件监听主服务(精简版)
3
- *
4
- * 监控项目文件变更,检测 // as:c、// as:s、// as:a 等指令并自动处理。
5
- * 具体指令逻辑已拆分至 handlers/ 和 XcodeIntegration.js。
6
- *
7
- * 用法:
8
- * const watcher = new FileWatcher(specPath, projectRoot, { quiet: false });
9
- * watcher.start();
10
- */
11
- import { accessSync, readFileSync, statSync } from 'node:fs';
12
- import { basename, join, normalize } from 'node:path';
13
- import { watch as chokidarWatch } from 'chokidar';
14
- import { saveEventFilter } from '../../platform/ios/xcode/SaveEventFilter.js';
15
- import { FILE_WATCHER } from '../../shared/constants.js';
16
- import { detectTriggers, REGEX } from './DirectiveDetector.js';
17
- import { handleAlink } from './handlers/AlinkHandler.js';
18
- /* ── Handler imports ── */
19
- import { handleCreate } from './handlers/CreateHandler.js';
20
- import { handleGuard } from './handlers/GuardHandler.js';
21
- import { handleHeader } from './handlers/HeaderHandler.js';
22
- import { handleSearch } from './handlers/SearchHandler.js';
23
- /* ────────── 配置 ────────── */
24
- const DEFAULT_FILE_PATTERN = [
25
- // ObjC/Swift
26
- '**/*.m',
27
- '**/*.h',
28
- '**/*.mm',
29
- '**/*.swift',
30
- // JS/TS
31
- '**/*.js',
32
- '**/*.ts',
33
- '**/*.jsx',
34
- '**/*.tsx',
35
- '**/*.vue',
36
- '**/*.svelte',
37
- // Python
38
- '**/*.py',
39
- // JVM
40
- '**/*.java',
41
- '**/*.kt',
42
- '**/*.kts',
43
- // Other languages
44
- '**/*.go',
45
- '**/*.rs',
46
- '**/*.rb',
47
- // C/C++
48
- '**/*.c',
49
- '**/*.cpp',
50
- '**/*.cc',
51
- '**/*.hpp',
52
- ];
53
- const IGNORED = [
54
- '**/node_modules/**',
55
- '**/.git/**',
56
- '**/.mgit/**',
57
- '**/.easybox/**',
58
- '**/xcuserdata/**',
59
- '**/.build/**',
60
- '**/*.swp',
61
- '**/*.tmp',
62
- '**/*~.m',
63
- '**/*~.h',
64
- '**/DerivedData/**',
65
- '**/Pods/**',
66
- '**/Carthage/**',
67
- '**/__pycache__/**',
68
- '**/.venv/**',
69
- '**/venv/**',
70
- '**/build/**',
71
- '**/target/**',
72
- '**/.gradle/**',
73
- '**/dist/**',
74
- '**/.next/**',
75
- '**/.nuxt/**',
76
- ];
77
- const DEBOUNCE_DELAY = FILE_WATCHER.DEBOUNCE_DELAY_MS;
78
- /* ────────── FileWatcher ────────── */
79
- export class FileWatcher {
80
- _debounceTimers;
81
- _timeoutHead;
82
- _timeoutLink;
83
- _watcher;
84
- exts;
85
- onEvent;
86
- pathPrefix;
87
- projectRoot;
88
- quiet;
89
- specPath;
90
- /**
91
- * @param specPath boxspec.json 绝对路径
92
- * @param projectRoot 项目根目录
93
- * @param [opts.exts] 可选扩展名列表
94
- * @param [opts.pathPrefix] 可选路径前缀过滤
95
- * @param [opts.onEvent] 可选事件回调
96
- */
97
- constructor(specPath, projectRoot, opts = {}) {
98
- this.specPath = specPath;
99
- this.projectRoot = projectRoot;
100
- this.quiet = !!opts.quiet;
101
- this.pathPrefix = opts.pathPrefix || null;
102
- this.onEvent = opts.onEvent || null;
103
- this.exts = opts.exts || null;
104
- this._debounceTimers = new Map();
105
- this._watcher = null;
106
- this._timeoutLink = undefined;
107
- this._timeoutHead = undefined;
108
- }
109
- /** 启动文件监听 */
110
- start() {
111
- const watchRoot = this.projectRoot;
112
- const filePattern = this.exts
113
- ? this.exts.map((e) => `**/*${e.startsWith('.') ? e : `.${e}`}`)
114
- : DEFAULT_FILE_PATTERN;
115
- if (!this.quiet) {
116
- }
117
- this._watcher = chokidarWatch(filePattern, {
118
- cwd: watchRoot,
119
- ignored: IGNORED,
120
- ignoreInitial: true,
121
- persistent: true,
122
- });
123
- const handleEvent = (relativePath) => {
124
- const fullPath = join(watchRoot, relativePath);
125
- if (process.env.ASD_DEBUG === '1') {
126
- }
127
- if (this.pathPrefix && !normalize(relativePath).startsWith(normalize(this.pathPrefix))) {
128
- return;
129
- }
130
- this._debounce(fullPath, () => {
131
- this._processFile(fullPath, relativePath);
132
- });
133
- };
134
- this._watcher.on('change', handleEvent);
135
- this._watcher.on('add', handleEvent);
136
- this._watcher.on('error', (err) => {
137
- const msg = err instanceof Error ? err.message : String(err);
138
- console.error('文件监听错误:', msg);
139
- });
140
- this._watcher.on('ready', () => {
141
- if (!this.quiet) {
142
- }
143
- if (process.env.ASD_DEBUG === '1') {
144
- }
145
- });
146
- return this._watcher;
147
- }
148
- /** 停止监听,释放所有资源 */
149
- async stop() {
150
- if (this._watcher) {
151
- // 移除所有事件监听器,避免泄漏
152
- this._watcher.removeAllListeners();
153
- await this._watcher.close();
154
- this._watcher = null;
155
- }
156
- // 清理所有防抖定时器
157
- for (const timer of this._debounceTimers.values()) {
158
- clearTimeout(timer);
159
- }
160
- this._debounceTimers.clear();
161
- // 清理 handler 级别的延时定时器
162
- if (this._timeoutLink) {
163
- clearTimeout(this._timeoutLink);
164
- this._timeoutLink = undefined;
165
- }
166
- if (this._timeoutHead) {
167
- clearTimeout(this._timeoutHead);
168
- this._timeoutHead = undefined;
169
- }
170
- }
171
- /* ────────── 内部:文件处理(分派到 handlers) ────────── */
172
- async _processFile(fullPath, relativePath) {
173
- try {
174
- accessSync(fullPath);
175
- const stat = statSync(fullPath);
176
- if (stat.isDirectory() || stat.size > FILE_WATCHER.MAX_FILE_SIZE_BYTES) {
177
- return;
178
- }
179
- }
180
- catch {
181
- return;
182
- }
183
- let data;
184
- try {
185
- data = readFileSync(fullPath, 'utf8');
186
- }
187
- catch (err) {
188
- console.error(`❌ 读取文件失败: ${fullPath}`, err.message);
189
- return;
190
- }
191
- // ── 保存事件过滤:self-write / 内容未变 / Xcode 非前台 ──
192
- const verdict = saveEventFilter.shouldProcess(fullPath, data);
193
- if (!verdict.process) {
194
- if (process.env.ASD_DEBUG === '1') {
195
- }
196
- return;
197
- }
198
- if (process.env.ASD_DEBUG === '1') {
199
- }
200
- const filename = basename(fullPath);
201
- // 检测指令
202
- const triggers = detectTriggers(data, filename);
203
- if (process.env.ASD_DEBUG === '1') {
204
- }
205
- // // as:c — 创建候选
206
- if (triggers.createLine) {
207
- await handleCreate(this, fullPath, relativePath, triggers.createOption);
208
- }
209
- // // as:a — Guard 检查
210
- if (triggers.guardLine) {
211
- await handleGuard(this, fullPath, data, triggers.guardLine);
212
- }
213
- // // as:s — 搜索
214
- if (triggers.searchLine) {
215
- await handleSearch(this, fullPath, relativePath, triggers.searchLine);
216
- }
217
- // alink
218
- if (triggers.alinkLine) {
219
- clearTimeout(this._timeoutLink);
220
- this._timeoutLink = setTimeout(() => {
221
- handleAlink(triggers.alinkLine).catch((err) => {
222
- console.warn(`[Watcher] alink handler failed: ${err.message}`);
223
- });
224
- }, DEBOUNCE_DELAY);
225
- }
226
- // ── 更新内容哈希(处理完毕后记录状态,供下次变更比对) ──
227
- saveEventFilter.updateHash(fullPath, data);
228
- // header 指令
229
- if (triggers.headerLine) {
230
- const isMatch = triggers.isSwift
231
- ? REGEX.HEADER_SWIFT.test(triggers.headerLine)
232
- : REGEX.HEADER_OBJC.test(triggers.headerLine);
233
- if (isMatch) {
234
- clearTimeout(this._timeoutHead);
235
- this._timeoutHead = setTimeout(() => {
236
- handleHeader(this, fullPath, triggers.headerLine, triggers.importArray, triggers.isSwift).catch((err) => {
237
- console.warn(`[Watcher] header handler failed: ${err.message}`);
238
- });
239
- }, DEBOUNCE_DELAY);
240
- }
241
- }
242
- }
243
- /* ────────── 工具方法(供 handlers 通过 watcher 引用调用) ────────── */
244
- /** 追加候选项(通过 ServiceContainer 或 HTTP API) */
245
- async _appendCandidates(items, source) {
246
- // 过滤空 title / 空 code 的无效条目
247
- const validItems = items.filter((item) => {
248
- const title = String(item.title || '').trim();
249
- const code = String(item.code || '').trim();
250
- if (!title || !code) {
251
- console.warn(`[Watcher] 跳过无效候选: title=${JSON.stringify(title)}, code length=${code.length}`);
252
- return false;
253
- }
254
- return true;
255
- });
256
- if (validItems.length === 0) {
257
- throw new Error('所有候选条目缺少 title 或 code,无法提交');
258
- }
259
- // 优先 ServiceContainer
260
- let serviceError = null;
261
- try {
262
- const { ServiceContainer } = await import('../../injection/ServiceContainer.js');
263
- const container = ServiceContainer.getInstance();
264
- const knowledgeService = container.get('knowledgeService');
265
- const context = { userId: 'filewatcher' };
266
- for (const item of validItems) {
267
- await knowledgeService.create({
268
- content: {
269
- pattern: String(item.code || ''),
270
- },
271
- language: String(item.language || 'objc'),
272
- category: String(item.category || 'Utility'),
273
- source: source || 'watch',
274
- title: String(item.title || ''),
275
- description: String(item.summary || item.description || ''),
276
- moduleName: String(item.moduleName || 'watch-create'),
277
- trigger: String(item.trigger || ''),
278
- headers: (item.headers || []),
279
- tags: (item.tags || []),
280
- }, context);
281
- }
282
- return;
283
- }
284
- catch (err) {
285
- serviceError = err;
286
- console.warn('[Watcher] KnowledgeService 创建失败,尝试 HTTP 回退:', err.message);
287
- }
288
- // 回退:HTTP API(使用 knowledge 端点而非 candidates)
289
- const dashboardUrl = process.env.ASD_DASHBOARD_URL || 'http://localhost:3000';
290
- try {
291
- for (const item of validItems) {
292
- const resp = await fetch(`${dashboardUrl}/api/v1/knowledge`, {
293
- method: 'POST',
294
- headers: { 'Content-Type': 'application/json' },
295
- body: JSON.stringify({
296
- title: item.title,
297
- content: { pattern: item.code || '' },
298
- language: item.language || 'objc',
299
- category: item.category || 'Utility',
300
- source: source || 'watch',
301
- description: item.summary || item.description || '',
302
- moduleName: item.moduleName || 'watch-create',
303
- trigger: item.trigger || '',
304
- headers: item.headers || [],
305
- }),
306
- });
307
- if (!resp.ok) {
308
- throw new Error(`HTTP ${resp.status}`);
309
- }
310
- }
311
- return;
312
- }
313
- catch (err) {
314
- console.warn(`[Watcher] HTTP 候选提交也失败: ${err.message}`);
315
- }
316
- // 两条路径都失败 → 抛出原始错误
317
- throw serviceError || new Error('候选提交失败:ServiceContainer 和 HTTP 均不可用');
318
- }
319
- /** 为候选解析头文件 */
320
- async _resolveHeadersIfNeeded(item, relativePath, text) {
321
- if (relativePath && (!item.headers || !item.headers.length)) {
322
- try {
323
- const HeaderResolver = await import('../../platform/ios/xcode/HeaderResolver.js');
324
- const resolved = await HeaderResolver.resolveHeadersForText(this.projectRoot, relativePath, text);
325
- if (resolved?.headers && resolved.headers.length > 0) {
326
- item.headers = resolved.headers;
327
- item.headerPaths = resolved.headerPaths;
328
- item.moduleName = resolved.moduleName;
329
- }
330
- }
331
- catch {
332
- // 头文件解析失败不阻塞
333
- }
334
- }
335
- }
336
- /** 打开 Dashboard 页面 */
337
- _openDashboard(path) {
338
- const base = process.env.ASD_DASHBOARD_URL || 'http://localhost:3000';
339
- const url = `${base}${path}`;
340
- import('../../platform/OpenBrowser.js')
341
- .then(({ openBrowserReuseTab }) => openBrowserReuseTab(url, base))
342
- .catch(() => { });
343
- }
344
- /** macOS 通知 */
345
- _notify(msg) {
346
- import('../../platform/NativeUi.js').then((NU) => NU.notify(msg)).catch(() => { });
347
- }
348
- /** 防抖 */
349
- _debounce(key, fn) {
350
- if (this._debounceTimers.has(key)) {
351
- clearTimeout(this._debounceTimers.get(key));
352
- }
353
- this._debounceTimers.set(key, setTimeout(() => {
354
- this._debounceTimers.delete(key);
355
- Promise.resolve()
356
- .then(() => fn())
357
- .catch((err) => {
358
- console.error('[Watch] 处理文件失败:', err.message);
359
- if (process.env.ASD_DEBUG === '1') {
360
- console.error(err.stack);
361
- }
362
- });
363
- }, DEBOUNCE_DELAY));
364
- }
365
- }
366
- export default FileWatcher;
@@ -1,36 +0,0 @@
1
- /**
2
- * TriggerResolver — 触发器规范化
3
- * 将原始触发输入规范化为标准格式,添加类型标签
4
- */
5
- export declare class TriggerResolver {
6
- #private;
7
- /**
8
- * 规范化触发器
9
- * @returns }
10
- */
11
- resolve(trigger: string | Record<string, unknown>): {
12
- type: string;
13
- name: string;
14
- params: {
15
- option: string;
16
- };
17
- raw: string;
18
- } | {
19
- type: string;
20
- name: string;
21
- params: {
22
- option?: undefined;
23
- };
24
- raw: string;
25
- } | {
26
- type: string;
27
- name: string;
28
- params: Record<string, unknown>;
29
- raw: Record<string, unknown>;
30
- } | {
31
- type: string;
32
- raw: never;
33
- name?: undefined;
34
- params?: undefined;
35
- };
36
- }
@@ -1,62 +0,0 @@
1
- /**
2
- * TriggerResolver — 触发器规范化
3
- * 将原始触发输入规范化为标准格式,添加类型标签
4
- */
5
- export class TriggerResolver {
6
- /**
7
- * 规范化触发器
8
- * @returns }
9
- */
10
- resolve(trigger) {
11
- if (typeof trigger === 'string') {
12
- return this.#resolveString(trigger);
13
- }
14
- if (trigger && typeof trigger === 'object') {
15
- return {
16
- type: String(trigger.type || 'unknown'),
17
- name: String(trigger.name || ''),
18
- params: trigger.params || {},
19
- raw: trigger,
20
- };
21
- }
22
- return { type: 'unknown', raw: trigger };
23
- }
24
- #resolveString(input) {
25
- const trimmed = input.trim();
26
- // 检测 as:xxx 格式
27
- const asMatch = trimmed.match(/^as:(\w+)\s*(.*)/);
28
- if (asMatch) {
29
- return {
30
- type: this.#mapDirectiveType(asMatch[1]),
31
- name: asMatch[1],
32
- params: { option: asMatch[2].trim() },
33
- raw: input,
34
- };
35
- }
36
- // 检测事件类型格式 file:changed, timer:cron
37
- const eventMatch = trimmed.match(/^(\w+):(\w+)\s*(.*)/);
38
- if (eventMatch) {
39
- return {
40
- type: eventMatch[1],
41
- name: eventMatch[2],
42
- params: { option: eventMatch[3].trim() },
43
- raw: input,
44
- };
45
- }
46
- return { type: 'custom', name: trimmed, params: {}, raw: input };
47
- }
48
- #mapDirectiveType(name) {
49
- const map = {
50
- search: 'search',
51
- s: 'search',
52
- create: 'create',
53
- c: 'create',
54
- audit: 'audit',
55
- a: 'audit',
56
- include: 'injection',
57
- import: 'injection',
58
- alink: 'alink',
59
- };
60
- return map[name] || 'directive';
61
- }
62
- }
@@ -1,7 +0,0 @@
1
- /**
2
- * AlinkHandler — 处理 alink 指令
3
- *
4
- * 解析编辑器中的 alink 触发行,提取 completionKey,
5
- * 通过数据库查找匹配的 Recipe,打开 Dashboard 详情页。
6
- */
7
- export declare function handleAlink(alinkLine: string): Promise<void>;
@@ -1,80 +0,0 @@
1
- /**
2
- * AlinkHandler — 处理 alink 指令
3
- *
4
- * 解析编辑器中的 alink 触发行,提取 completionKey,
5
- * 通过数据库查找匹配的 Recipe,打开 Dashboard 详情页。
6
- */
7
- import { and, eq } from 'drizzle-orm';
8
- import { getServiceContainer } from '#inject/ServiceContainer.js';
9
- import { knowledgeEntries } from '../../../infrastructure/database/drizzle/schema.js';
10
- export async function handleAlink(alinkLine) {
11
- const { TRIGGER_SYMBOL } = await import('../../../infrastructure/config/TriggerSymbol.js');
12
- let completionKey = null;
13
- const alinkMark = 'alink';
14
- if (alinkLine.includes(TRIGGER_SYMBOL)) {
15
- const parts = alinkLine
16
- .split(TRIGGER_SYMBOL)
17
- .map((p) => p.trim())
18
- .filter(Boolean);
19
- if (parts.length >= 2 && parts[parts.length - 1] === alinkMark) {
20
- completionKey = parts[parts.length - 2];
21
- }
22
- }
23
- if (completionKey != null) {
24
- try {
25
- // 从 DI 容器获取数据库实例,查找匹配 trigger 的 Recipe
26
- const container = getServiceContainer();
27
- const db = container.get('database');
28
- let recipeId = null;
29
- if (db) {
30
- const rawDb = typeof db.getDb === 'function' ? db.getDb() : db;
31
- try {
32
- // ★ Drizzle 类型安全 — 精确匹配 trigger
33
- const drizzle = typeof db.getDrizzle === 'function' ? db.getDrizzle() : null;
34
- if (!drizzle) {
35
- throw new Error('Drizzle not available');
36
- }
37
- const row = drizzle
38
- .select({ id: knowledgeEntries.id })
39
- .from(knowledgeEntries)
40
- .where(and(eq(knowledgeEntries.trigger, completionKey), eq(knowledgeEntries.lifecycle, 'active')))
41
- .limit(1)
42
- .get();
43
- if (row) {
44
- recipeId = row.id;
45
- }
46
- }
47
- catch {
48
- // DB 查询失败时回退到搜索
49
- }
50
- // 若精确匹配失败,尝试模糊搜索(保留 raw SQL — LIKE + ESCAPE)
51
- if (!recipeId) {
52
- try {
53
- const rawDb2 = (typeof db.getDb === 'function' ? db.getDb() : db);
54
- const escaped = completionKey.replace(/[%_\\]/g, (ch) => `\\${ch}`);
55
- const row = rawDb2
56
- .prepare("SELECT id FROM knowledge_entries WHERE (trigger LIKE ? ESCAPE '\\' OR title LIKE ? ESCAPE '\\') AND lifecycle = 'active' LIMIT 1")
57
- .get(`%${escaped}%`, `%${escaped}%`);
58
- if (row) {
59
- recipeId = row.id;
60
- }
61
- }
62
- catch {
63
- /* silent */
64
- }
65
- }
66
- }
67
- // 构建 Dashboard URL 并打开
68
- const port = process.env.ASD_DASHBOARD_PORT || 3000;
69
- const host = process.env.ASD_DASHBOARD_HOST || 'localhost';
70
- const url = recipeId
71
- ? `http://${host}:${port}/#/recipes/${recipeId}`
72
- : `http://${host}:${port}/#/search?q=${encodeURIComponent(completionKey)}`;
73
- const open = (await import('open')).default;
74
- await open(url);
75
- }
76
- catch (err) {
77
- console.warn(`[alink] Failed to open link: ${err.message}`);
78
- }
79
- }
80
- }
@@ -1,11 +0,0 @@
1
- /**
2
- * CreateHandler — 处理 // as:c 指令
3
- * 从 FileWatcher 拆分,负责候选创建逻辑
4
- */
5
- /**
6
- * 处理 // as:c 指令
7
- * @param createOption 'c' | 'f' | undefined
8
- */
9
- export declare function handleCreate(watcher: import('../FileWatcher.js').FileWatcher, fullPath: string, relativePath: string, createOption: string | null): Promise<void>;
10
- /** 查找 // as:c 的行号 (1-based) */
11
- export declare function findCreateLineNumber(content: string): number;