speccore 6.91.2 → 6.97.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 (114) hide show
  1. package/.agents/skills/spec-ask/SKILL.md +34 -11
  2. package/.agents/skills/speccore-router/SKILL.md +8 -2
  3. package/dist/cli.js +15 -1
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/analyze.d.ts.map +1 -1
  6. package/dist/commands/analyze.js +11 -2
  7. package/dist/commands/analyze.js.map +1 -1
  8. package/dist/commands/ask.d.ts.map +1 -1
  9. package/dist/commands/ask.js +13 -2
  10. package/dist/commands/ask.js.map +1 -1
  11. package/dist/commands/code-index.d.ts +2 -0
  12. package/dist/commands/code-index.d.ts.map +1 -1
  13. package/dist/commands/code-index.js +48 -3
  14. package/dist/commands/code-index.js.map +1 -1
  15. package/dist/commands/doctor.d.ts +5 -0
  16. package/dist/commands/doctor.d.ts.map +1 -0
  17. package/dist/commands/doctor.js +304 -0
  18. package/dist/commands/doctor.js.map +1 -0
  19. package/dist/commands/execute.d.ts.map +1 -1
  20. package/dist/commands/execute.js +42 -0
  21. package/dist/commands/execute.js.map +1 -1
  22. package/dist/commands/init.d.ts +24 -0
  23. package/dist/commands/init.d.ts.map +1 -1
  24. package/dist/commands/init.js +17 -10
  25. package/dist/commands/init.js.map +1 -1
  26. package/dist/commands/notify.d.ts +13 -0
  27. package/dist/commands/notify.d.ts.map +1 -0
  28. package/dist/commands/notify.js +63 -0
  29. package/dist/commands/notify.js.map +1 -0
  30. package/dist/commands/recommend.d.ts +13 -0
  31. package/dist/commands/recommend.d.ts.map +1 -0
  32. package/dist/commands/recommend.js +37 -0
  33. package/dist/commands/recommend.js.map +1 -0
  34. package/dist/commands/status.d.ts.map +1 -1
  35. package/dist/commands/status.js +33 -1
  36. package/dist/commands/status.js.map +1 -1
  37. package/dist/commands/update.d.ts.map +1 -1
  38. package/dist/commands/update.js +22 -8
  39. package/dist/commands/update.js.map +1 -1
  40. package/dist/core/ask-config.d.ts.map +1 -1
  41. package/dist/core/ask-config.js +5 -2
  42. package/dist/core/ask-config.js.map +1 -1
  43. package/dist/core/ask-engine.d.ts +6 -1
  44. package/dist/core/ask-engine.d.ts.map +1 -1
  45. package/dist/core/ask-engine.js +70 -6
  46. package/dist/core/ask-engine.js.map +1 -1
  47. package/dist/core/code-graph/incremental-build.d.ts +11 -0
  48. package/dist/core/code-graph/incremental-build.d.ts.map +1 -0
  49. package/dist/core/code-graph/incremental-build.js +207 -0
  50. package/dist/core/code-graph/incremental-build.js.map +1 -0
  51. package/dist/core/code-graph/index.d.ts +2 -0
  52. package/dist/core/code-graph/index.d.ts.map +1 -1
  53. package/dist/core/code-graph/index.js +7 -1
  54. package/dist/core/code-graph/index.js.map +1 -1
  55. package/dist/core/code-graph/requirement-linker.d.ts +25 -0
  56. package/dist/core/code-graph/requirement-linker.d.ts.map +1 -0
  57. package/dist/core/code-graph/requirement-linker.js +192 -0
  58. package/dist/core/code-graph/requirement-linker.js.map +1 -0
  59. package/dist/core/error-diagnosis.d.ts +20 -0
  60. package/dist/core/error-diagnosis.d.ts.map +1 -0
  61. package/dist/core/error-diagnosis.js +155 -0
  62. package/dist/core/error-diagnosis.js.map +1 -0
  63. package/dist/core/intent-recognition.d.ts +7 -0
  64. package/dist/core/intent-recognition.d.ts.map +1 -1
  65. package/dist/core/intent-recognition.js +118 -10
  66. package/dist/core/intent-recognition.js.map +1 -1
  67. package/dist/core/lock-manager.d.ts +33 -0
  68. package/dist/core/lock-manager.d.ts.map +1 -0
  69. package/dist/core/lock-manager.js +144 -0
  70. package/dist/core/lock-manager.js.map +1 -0
  71. package/dist/core/notification.d.ts +39 -0
  72. package/dist/core/notification.d.ts.map +1 -0
  73. package/dist/core/notification.js +172 -0
  74. package/dist/core/notification.js.map +1 -0
  75. package/dist/core/prompt-builder.d.ts.map +1 -1
  76. package/dist/core/prompt-builder.js +26 -84
  77. package/dist/core/prompt-builder.js.map +1 -1
  78. package/dist/core/prompt-plugins/agents-plugin.d.ts +3 -0
  79. package/dist/core/prompt-plugins/agents-plugin.d.ts.map +1 -0
  80. package/dist/core/prompt-plugins/agents-plugin.js +34 -0
  81. package/dist/core/prompt-plugins/agents-plugin.js.map +1 -0
  82. package/dist/core/prompt-plugins/analyze-graph-plugin.d.ts +3 -0
  83. package/dist/core/prompt-plugins/analyze-graph-plugin.d.ts.map +1 -0
  84. package/dist/core/prompt-plugins/analyze-graph-plugin.js +48 -0
  85. package/dist/core/prompt-plugins/analyze-graph-plugin.js.map +1 -0
  86. package/dist/core/prompt-plugins/execute-graph-plugin.d.ts +3 -0
  87. package/dist/core/prompt-plugins/execute-graph-plugin.d.ts.map +1 -0
  88. package/dist/core/prompt-plugins/execute-graph-plugin.js +117 -0
  89. package/dist/core/prompt-plugins/execute-graph-plugin.js.map +1 -0
  90. package/dist/core/prompt-plugins/execute-rules-plugin.d.ts +3 -0
  91. package/dist/core/prompt-plugins/execute-rules-plugin.d.ts.map +1 -0
  92. package/dist/core/prompt-plugins/execute-rules-plugin.js +41 -0
  93. package/dist/core/prompt-plugins/execute-rules-plugin.js.map +1 -0
  94. package/dist/core/prompt-plugins/index.d.ts +10 -0
  95. package/dist/core/prompt-plugins/index.d.ts.map +1 -0
  96. package/dist/core/prompt-plugins/index.js +41 -0
  97. package/dist/core/prompt-plugins/index.js.map +1 -0
  98. package/dist/core/prompt-plugins/types.d.ts +47 -0
  99. package/dist/core/prompt-plugins/types.d.ts.map +1 -0
  100. package/dist/core/prompt-plugins/types.js +28 -0
  101. package/dist/core/prompt-plugins/types.js.map +1 -0
  102. package/dist/core/smart-recommend.d.ts +16 -0
  103. package/dist/core/smart-recommend.d.ts.map +1 -0
  104. package/dist/core/smart-recommend.js +149 -0
  105. package/dist/core/smart-recommend.js.map +1 -0
  106. package/dist/core/usage-analytics.d.ts +41 -0
  107. package/dist/core/usage-analytics.d.ts.map +1 -0
  108. package/dist/core/usage-analytics.js +162 -0
  109. package/dist/core/usage-analytics.js.map +1 -0
  110. package/dist/core/user-context.d.ts +9 -0
  111. package/dist/core/user-context.d.ts.map +1 -0
  112. package/dist/core/user-context.js +53 -0
  113. package/dist/core/user-context.js.map +1 -0
  114. package/package.json +3 -2
@@ -0,0 +1,41 @@
1
+ export type EventType = 'command' | 'task_start' | 'task_complete' | 'task_fail' | 'iteration_create' | 'spec_generate';
2
+ export interface AnalyticsEvent {
3
+ type: EventType;
4
+ timestamp: string;
5
+ user: string;
6
+ command?: string;
7
+ task?: string;
8
+ iteration?: string;
9
+ durationMs?: number;
10
+ metadata?: Record<string, unknown>;
11
+ }
12
+ export interface UsageReport {
13
+ generatedAt: string;
14
+ user: string;
15
+ periodDays: number;
16
+ totalCommands: number;
17
+ commandFrequency: Record<string, number>;
18
+ totalTasks: number;
19
+ completedTasks: number;
20
+ failedTasks: number;
21
+ avgTaskDurationMin: number;
22
+ activeIterations: string[];
23
+ recommendations: string[];
24
+ }
25
+ /**
26
+ * 记录事件
27
+ */
28
+ export declare function recordEvent(cwd: string, event: Omit<AnalyticsEvent, 'timestamp' | 'user'>): Promise<void>;
29
+ /**
30
+ * 记录命令执行
31
+ */
32
+ export declare function recordCommand(cwd: string, command: string, durationMs?: number): Promise<void>;
33
+ /**
34
+ * 生成使用报告
35
+ */
36
+ export declare function generateUsageReport(cwd: string, periodDays?: number): Promise<UsageReport>;
37
+ /**
38
+ * 格式化报告为可读文本
39
+ */
40
+ export declare function formatUsageReport(report: UsageReport): string;
41
+ //# sourceMappingURL=usage-analytics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-analytics.d.ts","sourceRoot":"","sources":["../../src/core/usage-analytics.ts"],"names":[],"mappings":"AAWA,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,YAAY,GAAG,eAAe,GAAG,WAAW,GAAG,kBAAkB,GAAG,eAAe,CAAC;AAExH,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,SAAS,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACpC;AAED,MAAM,WAAW,WAAW;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAMD;;GAEG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,cAAc,EAAE,WAAW,GAAG,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAa/G;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEpG;AA0BD;;GAEG;AACH,wBAAsB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,SAAK,GAAG,OAAO,CAAC,WAAW,CAAC,CAqE5F;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAuC7D"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.recordEvent = recordEvent;
4
+ exports.recordCommand = recordCommand;
5
+ exports.generateUsageReport = generateUsageReport;
6
+ exports.formatUsageReport = formatUsageReport;
7
+ /**
8
+ * Usage Analytics — 使用模式分析
9
+ * v6.96.0: 记录命令使用频率、任务完成时间,输出使用报告
10
+ */
11
+ const path_1 = require("path");
12
+ const fs_extra_1 = require("fs-extra");
13
+ const user_context_1 = require("./user-context");
14
+ const ANALYTICS_DIR = '.speccore/local/analytics';
15
+ const EVENT_LOG = 'events.jsonl';
16
+ async function getAnalyticsPath(cwd) {
17
+ return (0, path_1.join)(cwd, ANALYTICS_DIR, EVENT_LOG);
18
+ }
19
+ /**
20
+ * 记录事件
21
+ */
22
+ async function recordEvent(cwd, event) {
23
+ const dir = (0, path_1.join)(cwd, ANALYTICS_DIR);
24
+ await (0, fs_extra_1.ensureDir)(dir);
25
+ const fullEvent = {
26
+ ...event,
27
+ timestamp: new Date().toISOString(),
28
+ user: (0, user_context_1.getCurrentUser)(),
29
+ };
30
+ const logPath = await getAnalyticsPath(cwd);
31
+ const line = JSON.stringify(fullEvent) + '\n';
32
+ await (0, fs_extra_1.writeFile)(logPath, line, { flag: 'a' });
33
+ }
34
+ /**
35
+ * 记录命令执行
36
+ */
37
+ async function recordCommand(cwd, command, durationMs) {
38
+ await recordEvent(cwd, { type: 'command', command, durationMs });
39
+ }
40
+ /**
41
+ * 加载所有事件
42
+ */
43
+ async function loadEvents(cwd, maxAgeDays = 30) {
44
+ const logPath = await getAnalyticsPath(cwd);
45
+ if (!(await (0, fs_extra_1.pathExists)(logPath)))
46
+ return [];
47
+ const content = await (0, fs_extra_1.readFile)(logPath, 'utf-8');
48
+ const lines = content.split('\n').filter(Boolean);
49
+ const cutoff = Date.now() - maxAgeDays * 24 * 60 * 60 * 1000;
50
+ const events = [];
51
+ for (const line of lines) {
52
+ try {
53
+ const e = JSON.parse(line);
54
+ if (new Date(e.timestamp).getTime() >= cutoff) {
55
+ events.push(e);
56
+ }
57
+ }
58
+ catch { /* 忽略损坏行 */ }
59
+ }
60
+ return events;
61
+ }
62
+ /**
63
+ * 生成使用报告
64
+ */
65
+ async function generateUsageReport(cwd, periodDays = 14) {
66
+ const events = await loadEvents(cwd, periodDays);
67
+ const commands = events.filter(e => e.type === 'command');
68
+ const commandFrequency = {};
69
+ for (const c of commands) {
70
+ const cmd = c.command || 'unknown';
71
+ commandFrequency[cmd] = (commandFrequency[cmd] || 0) + 1;
72
+ }
73
+ const taskStarts = events.filter(e => e.type === 'task_start');
74
+ const taskCompletes = events.filter(e => e.type === 'task_complete');
75
+ const taskFails = events.filter(e => e.type === 'task_fail');
76
+ // 计算平均任务耗时
77
+ let totalDuration = 0;
78
+ let durationCount = 0;
79
+ for (const tc of taskCompletes) {
80
+ if (tc.durationMs && tc.durationMs > 0) {
81
+ totalDuration += tc.durationMs;
82
+ durationCount++;
83
+ }
84
+ }
85
+ const avgTaskDurationMin = durationCount > 0
86
+ ? Math.round((totalDuration / durationCount / 60000) * 10) / 10
87
+ : 0;
88
+ const activeIterations = [...new Set(events.map(e => e.iteration).filter(Boolean))];
89
+ // 生成推荐
90
+ const recommendations = [];
91
+ if (taskCompletes.length === 0 && taskStarts.length > 0) {
92
+ recommendations.push('有进行中的任务但未记录完成,建议检查任务状态追踪');
93
+ }
94
+ if (!commandFrequency['code-index'] && !commandFrequency['ci']) {
95
+ recommendations.push('建议运行 speccore code-index --graph 构建代码知识图谱');
96
+ }
97
+ if ((commandFrequency['execute'] || 0) > 10 && (commandFrequency['doctor'] || 0) === 0) {
98
+ recommendations.push('执行频率较高,建议定期运行 speccore doctor 检查项目健康度');
99
+ }
100
+ if (taskFails.length > taskCompletes.length * 0.3) {
101
+ recommendations.push('任务失败率较高,建议运行 speccore analyze 重新评估需求');
102
+ }
103
+ if (activeIterations.length > 3) {
104
+ recommendations.push('活跃迭代较多,建议归档已完成的迭代');
105
+ }
106
+ if (recommendations.length === 0) {
107
+ recommendations.push('使用模式健康,继续保持!');
108
+ }
109
+ return {
110
+ generatedAt: new Date().toISOString(),
111
+ user: (0, user_context_1.getCurrentUser)(),
112
+ periodDays,
113
+ totalCommands: commands.length,
114
+ commandFrequency,
115
+ totalTasks: taskStarts.length,
116
+ completedTasks: taskCompletes.length,
117
+ failedTasks: taskFails.length,
118
+ avgTaskDurationMin,
119
+ activeIterations,
120
+ recommendations,
121
+ };
122
+ }
123
+ /**
124
+ * 格式化报告为可读文本
125
+ */
126
+ function formatUsageReport(report) {
127
+ const lines = [];
128
+ lines.push('');
129
+ lines.push(`📊 使用模式报告(近 ${report.periodDays} 天)`);
130
+ lines.push('');
131
+ lines.push(`操作者: ${report.user}`);
132
+ lines.push(`总命令数: ${report.totalCommands}`);
133
+ lines.push(`任务完成: ${report.completedTasks} / ${report.totalTasks}(失败 ${report.failedTasks})`);
134
+ if (report.avgTaskDurationMin > 0) {
135
+ lines.push(`平均任务耗时: ${report.avgTaskDurationMin} 分钟`);
136
+ }
137
+ lines.push('');
138
+ const topCommands = Object.entries(report.commandFrequency)
139
+ .sort((a, b) => b[1] - a[1])
140
+ .slice(0, 8);
141
+ if (topCommands.length > 0) {
142
+ lines.push('🔥 高频命令:');
143
+ for (const [cmd, count] of topCommands) {
144
+ lines.push(` ${cmd}: ${count} 次`);
145
+ }
146
+ lines.push('');
147
+ }
148
+ if (report.activeIterations.length > 0) {
149
+ lines.push('📁 活跃迭代:');
150
+ for (const iter of report.activeIterations) {
151
+ lines.push(` ${iter}`);
152
+ }
153
+ lines.push('');
154
+ }
155
+ lines.push('💡 智能推荐:');
156
+ for (const rec of report.recommendations) {
157
+ lines.push(` • ${rec}`);
158
+ }
159
+ lines.push('');
160
+ return lines.join('\n');
161
+ }
162
+ //# sourceMappingURL=usage-analytics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-analytics.js","sourceRoot":"","sources":["../../src/core/usage-analytics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /** 获取当前用户标识(git config → 环境变量 → 系统用户名) */
2
+ export declare function getCurrentUser(): string;
3
+ /** 设置当前用户(覆盖缓存) */
4
+ export declare function setCurrentUser(user: string): void;
5
+ /** 清除缓存(用于测试) */
6
+ export declare function clearUserCache(): void;
7
+ /** 获取用户标识的简短形式(用于文件名等) */
8
+ export declare function getUserSlug(): string;
9
+ //# sourceMappingURL=user-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-context.d.ts","sourceRoot":"","sources":["../../src/core/user-context.ts"],"names":[],"mappings":"AAQA,0CAA0C;AAC1C,wBAAgB,cAAc,IAAI,MAAM,CAuBvC;AAED,mBAAmB;AACnB,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAEjD;AAED,iBAAiB;AACjB,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,0BAA0B;AAC1B,wBAAgB,WAAW,IAAI,MAAM,CAMpC"}
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCurrentUser = getCurrentUser;
4
+ exports.setCurrentUser = setCurrentUser;
5
+ exports.clearUserCache = clearUserCache;
6
+ exports.getUserSlug = getUserSlug;
7
+ /**
8
+ * User Context — 多用户支持
9
+ * v6.95.0: 识别当前操作者,记录操作日志
10
+ */
11
+ const child_process_1 = require("child_process");
12
+ let cachedUser;
13
+ /** 获取当前用户标识(git config → 环境变量 → 系统用户名) */
14
+ function getCurrentUser() {
15
+ if (cachedUser)
16
+ return cachedUser;
17
+ // 1. 环境变量
18
+ const envUser = process.env.SPECCORE_USER;
19
+ if (envUser) {
20
+ cachedUser = envUser;
21
+ return envUser;
22
+ }
23
+ // 2. git config user.name
24
+ try {
25
+ const gitName = (0, child_process_1.execSync)('git config user.name', { encoding: 'utf-8', timeout: 3000 }).trim();
26
+ if (gitName) {
27
+ cachedUser = gitName;
28
+ return gitName;
29
+ }
30
+ }
31
+ catch { /* 忽略 */ }
32
+ // 3. 系统用户名
33
+ const sysUser = process.env.USER || process.env.USERNAME || 'unknown';
34
+ cachedUser = sysUser;
35
+ return sysUser;
36
+ }
37
+ /** 设置当前用户(覆盖缓存) */
38
+ function setCurrentUser(user) {
39
+ cachedUser = user;
40
+ }
41
+ /** 清除缓存(用于测试) */
42
+ function clearUserCache() {
43
+ cachedUser = undefined;
44
+ }
45
+ /** 获取用户标识的简短形式(用于文件名等) */
46
+ function getUserSlug() {
47
+ const user = getCurrentUser();
48
+ return user
49
+ .toLowerCase()
50
+ .replace(/[^a-z0-9]+/g, '-')
51
+ .replace(/^-|-$/g, '');
52
+ }
53
+ //# sourceMappingURL=user-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"user-context.js","sourceRoot":"","sources":["../../src/core/user-context.ts"],"names":[],"mappings":";;AASA,wCAuBC;AAGD,wCAEC;AAGD,wCAEC;AAGD,kCAMC;AAnDD;;;GAGG;AACH,iDAAyC;AAEzC,IAAI,UAA8B,CAAC;AAEnC,0CAA0C;AAC1C,SAAgB,cAAc;IAC5B,IAAI,UAAU;QAAE,OAAO,UAAU,CAAC;IAElC,UAAU;IACV,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC;IAC1C,IAAI,OAAO,EAAE,CAAC;QACZ,UAAU,GAAG,OAAO,CAAC;QACrB,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,0BAA0B;IAC1B,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,IAAA,wBAAQ,EAAC,sBAAsB,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9F,IAAI,OAAO,EAAE,CAAC;YACZ,UAAU,GAAG,OAAO,CAAC;YACrB,OAAO,OAAO,CAAC;QACjB,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,CAAC;IAEpB,WAAW;IACX,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,SAAS,CAAC;IACtE,UAAU,GAAG,OAAO,CAAC;IACrB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,mBAAmB;AACnB,SAAgB,cAAc,CAAC,IAAY;IACzC,UAAU,GAAG,IAAI,CAAC;AACpB,CAAC;AAED,iBAAiB;AACjB,SAAgB,cAAc;IAC5B,UAAU,GAAG,SAAS,CAAC;AACzB,CAAC;AAED,0BAA0B;AAC1B,SAAgB,WAAW;IACzB,MAAM,IAAI,GAAG,cAAc,EAAE,CAAC;IAC9B,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC;SAC3B,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;AAC3B,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "speccore",
3
- "version": "6.91.2",
3
+ "version": "6.97.0",
4
4
  "description": "SpecCore - Code by Spec, Not by Vibe.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -44,7 +44,8 @@
44
44
  "@types/fs-extra": "^11.0.4",
45
45
  "@types/js-yaml": "^4.0.9",
46
46
  "@types/node": "^20.10.5",
47
- "typescript": "^5.3.3"
47
+ "typescript": "^5.3.3",
48
+ "vitest": "^1.6.0"
48
49
  },
49
50
  "engines": {
50
51
  "node": ">=18.0.0"