@winspan/claude-forge 0.2.3 → 0.2.6
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/dist/autopilot/intent-engine.d.ts +3 -2
- package/dist/autopilot/intent-engine.d.ts.map +1 -1
- package/dist/autopilot/intent-engine.js +27 -19
- package/dist/autopilot/intent-engine.js.map +1 -1
- package/dist/autopilot/quality-gate.d.ts +1 -0
- package/dist/autopilot/quality-gate.d.ts.map +1 -1
- package/dist/autopilot/quality-gate.js +8 -4
- package/dist/autopilot/quality-gate.js.map +1 -1
- package/dist/cli/commands/logs.d.ts.map +1 -1
- package/dist/cli/commands/logs.js +90 -133
- package/dist/cli/commands/logs.js.map +1 -1
- package/dist/cli/tui.d.ts.map +1 -1
- package/dist/cli/tui.js +1 -3
- package/dist/cli/tui.js.map +1 -1
- package/dist/convention/convention-manager.d.ts +2 -0
- package/dist/convention/convention-manager.d.ts.map +1 -1
- package/dist/convention/convention-manager.js +51 -28
- package/dist/convention/convention-manager.js.map +1 -1
- package/dist/daemon/engine-registry/init-autopilot.d.ts.map +1 -1
- package/dist/daemon/engine-registry/init-autopilot.js +1 -0
- package/dist/daemon/engine-registry/init-autopilot.js.map +1 -1
- package/dist/daemon/engine-registry/init-distill.d.ts.map +1 -1
- package/dist/daemon/engine-registry/init-distill.js +8 -1
- package/dist/daemon/engine-registry/init-distill.js.map +1 -1
- package/dist/daemon/engine-registry/init-orchestration.d.ts.map +1 -1
- package/dist/daemon/engine-registry/init-orchestration.js +3 -1
- package/dist/daemon/engine-registry/init-orchestration.js.map +1 -1
- package/dist/daemon/engine-registry/init-pipeline.d.ts.map +1 -1
- package/dist/daemon/engine-registry/init-pipeline.js +3 -1
- package/dist/daemon/engine-registry/init-pipeline.js.map +1 -1
- package/dist/daemon/engine-registry/init-resume.d.ts.map +1 -1
- package/dist/daemon/engine-registry/init-resume.js +3 -1
- package/dist/daemon/engine-registry/init-resume.js.map +1 -1
- package/dist/daemon/handler-context.d.ts +8 -0
- package/dist/daemon/handler-context.d.ts.map +1 -1
- package/dist/daemon/handlers/session-cleanup.d.ts +23 -0
- package/dist/daemon/handlers/session-cleanup.d.ts.map +1 -0
- package/dist/daemon/handlers/session-cleanup.js +149 -0
- package/dist/daemon/handlers/session-cleanup.js.map +1 -0
- package/dist/daemon/handlers/stop-handler.d.ts +1 -0
- package/dist/daemon/handlers/stop-handler.d.ts.map +1 -1
- package/dist/daemon/handlers/stop-handler.js +21 -78
- package/dist/daemon/handlers/stop-handler.js.map +1 -1
- package/dist/daemon/handlers/user-prompt-handler.d.ts +4 -0
- package/dist/daemon/handlers/user-prompt-handler.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt-handler.js +53 -8
- package/dist/daemon/handlers/user-prompt-handler.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +30 -6
- package/dist/daemon/index.js.map +1 -1
- package/dist/distill/index.d.ts +8 -3
- package/dist/distill/index.d.ts.map +1 -1
- package/dist/distill/index.js +8 -8
- package/dist/distill/index.js.map +1 -1
- package/dist/distill/prompts.d.ts.map +1 -1
- package/dist/distill/prompts.js +14 -2
- package/dist/distill/prompts.js.map +1 -1
- package/dist/orchestration/index.d.ts.map +1 -1
- package/dist/orchestration/index.js +1 -0
- package/dist/orchestration/index.js.map +1 -1
- package/dist/pattern-engine/pattern-executor.d.ts.map +1 -1
- package/dist/pattern-engine/pattern-executor.js +43 -0
- package/dist/pattern-engine/pattern-executor.js.map +1 -1
- package/dist/pattern-engine/pattern-router.d.ts +2 -0
- package/dist/pattern-engine/pattern-router.d.ts.map +1 -1
- package/dist/pattern-engine/pattern-router.js +26 -4
- package/dist/pattern-engine/pattern-router.js.map +1 -1
- package/dist/pipeline/index.d.ts +1 -1
- package/dist/pipeline/index.js +1 -1
- package/dist/storage/sqlite.d.ts +5 -0
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +40 -0
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/utils/formatter.d.ts +9 -0
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +14 -0
- package/dist/utils/formatter.js.map +1 -1
- package/dist/utils/logger.d.ts +5 -4
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/logger.js +61 -65
- package/dist/utils/logger.js.map +1 -1
- package/package.json +1 -1
|
@@ -22,7 +22,7 @@ export declare class IntentEngine {
|
|
|
22
22
|
private api;
|
|
23
23
|
/** 项目结构缓存,TTL=2min,避免每次分析都读文件系统 */
|
|
24
24
|
private structureCache;
|
|
25
|
-
/** decisions.md 内容缓存,TTL=
|
|
25
|
+
/** decisions.md 内容缓存,TTL=5min */
|
|
26
26
|
private decisionsCache;
|
|
27
27
|
private static readonly CACHE_TTL_MS;
|
|
28
28
|
constructor(api: AIProvider);
|
|
@@ -34,7 +34,8 @@ export declare class IntentEngine {
|
|
|
34
34
|
/** 清理两个缓存 Map 中已过期的条目 */
|
|
35
35
|
private evictExpiredCache;
|
|
36
36
|
/**
|
|
37
|
-
*
|
|
37
|
+
* 快速放行:只过滤明确不涉及代码改动的操作。
|
|
38
|
+
* @param hasConversation 是否有会话上下文(多轮对话中)。有上下文时短输入可能是确认回复,应交给 AI 判断。
|
|
38
39
|
*/
|
|
39
40
|
private quickFilter;
|
|
40
41
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-engine.d.ts","sourceRoot":"","sources":["../../src/autopilot/intent-engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAa;IACxB,mCAAmC;IACnC,OAAO,CAAC,cAAc,CAAyD;IAC/E,iCAAiC;IACjC,OAAO,CAAC,cAAc,CAAyD;IAC/E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAiB;gBAEzC,GAAG,EAAE,UAAU;IAI3B;;;OAGG;IACG,OAAO,CACX,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,mBAAmB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"intent-engine.d.ts","sourceRoot":"","sources":["../../src/autopilot/intent-engine.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAG1D,MAAM,MAAM,gBAAgB,GAAG,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;AAEjE,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,gBAAgB,CAAC;IAC7B,gBAAgB,EAAE,OAAO,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;CAC3B;AAED;;;;;;;GAOG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,GAAG,CAAa;IACxB,mCAAmC;IACnC,OAAO,CAAC,cAAc,CAAyD;IAC/E,iCAAiC;IACjC,OAAO,CAAC,cAAc,CAAyD;IAC/E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAiB;gBAEzC,GAAG,EAAE,UAAU;IAI3B;;;OAGG;IACG,OAAO,CACX,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,MAAM,EACnB,SAAS,CAAC,EAAE,MAAM,EAClB,mBAAmB,CAAC,EAAE,MAAM,GAC3B,OAAO,CAAC,cAAc,CAAC;IAqB1B,yBAAyB;IACzB,OAAO,CAAC,iBAAiB;IAUzB;;;OAGG;IACH,OAAO,CAAC,WAAW;IAkEnB;;OAEG;YACW,SAAS;IA0EvB;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAiD3B;;;OAGG;IACH,OAAO,CAAC,eAAe;IAyBvB,OAAO,CAAC,aAAa;IAuBrB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAiB5B;;OAEG;IACH,iBAAiB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI;CAsB3D"}
|
|
@@ -13,9 +13,9 @@ export class IntentEngine {
|
|
|
13
13
|
api;
|
|
14
14
|
/** 项目结构缓存,TTL=2min,避免每次分析都读文件系统 */
|
|
15
15
|
structureCache = new Map();
|
|
16
|
-
/** decisions.md 内容缓存,TTL=
|
|
16
|
+
/** decisions.md 内容缓存,TTL=5min */
|
|
17
17
|
decisionsCache = new Map();
|
|
18
|
-
static CACHE_TTL_MS =
|
|
18
|
+
static CACHE_TTL_MS = 5 * 60 * 1000; // 5min
|
|
19
19
|
constructor(api) {
|
|
20
20
|
this.api = api;
|
|
21
21
|
}
|
|
@@ -25,9 +25,10 @@ export class IntentEngine {
|
|
|
25
25
|
*/
|
|
26
26
|
async analyze(userPrompt, projectPath, techStack, conversationHistory) {
|
|
27
27
|
// 快速放行:纯对话和无改动操作
|
|
28
|
-
|
|
28
|
+
// 注意:有会话上下文时(多轮对话中),短输入可能是确认回复,不应被快速过滤
|
|
29
|
+
const quickResult = this.quickFilter(userPrompt, !!conversationHistory);
|
|
29
30
|
if (quickResult) {
|
|
30
|
-
logger.info(`[意图引擎] 快速过滤:${quickResult.complexity}`);
|
|
31
|
+
logger.info(`[意图引擎] 快速过滤:${quickResult.complexity} | reason=${quickResult.reasoning}`);
|
|
31
32
|
return quickResult;
|
|
32
33
|
}
|
|
33
34
|
// 清理过期缓存条目(每次 analyze 时执行,避免长期积累)
|
|
@@ -54,10 +55,16 @@ export class IntentEngine {
|
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
/**
|
|
57
|
-
*
|
|
58
|
+
* 快速放行:只过滤明确不涉及代码改动的操作。
|
|
59
|
+
* @param hasConversation 是否有会话上下文(多轮对话中)。有上下文时短输入可能是确认回复,应交给 AI 判断。
|
|
58
60
|
*/
|
|
59
|
-
quickFilter(prompt) {
|
|
60
|
-
const lower = prompt.toLowerCase();
|
|
61
|
+
quickFilter(prompt, hasConversation) {
|
|
62
|
+
const lower = prompt.toLowerCase().trim();
|
|
63
|
+
// 确认类回复(同意/好的/是/继续/A/B/C 等)不应被截胡,直接透传给 Claude
|
|
64
|
+
const confirmPatterns = /^(同意|好的|好|是|是的|可以|行|ok|yes|sure|继续|go|proceed|确认|没问题|对|嗯|[a-c])$/i;
|
|
65
|
+
if (confirmPatterns.test(lower)) {
|
|
66
|
+
return null; // 交给 Claude 直接处理
|
|
67
|
+
}
|
|
61
68
|
// 纯对话 / 提问:不涉及改动
|
|
62
69
|
const conversationPatterns = [
|
|
63
70
|
/^(看|查看|显示|cat|show|read|explain|解释|描述)/i,
|
|
@@ -95,18 +102,19 @@ export class IntentEngine {
|
|
|
95
102
|
};
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
|
-
//
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
// 极短输入且不含动词:有会话上下文时不过滤(可能是对上轮问题的回复)
|
|
106
|
+
if (!hasConversation) {
|
|
107
|
+
const hasActionVerb = /修|改|加|删|实现|重构|优化|fix|add|remove|create|update|refactor|implement|build/i.test(lower);
|
|
108
|
+
if (prompt.length < 4 && !hasActionVerb) {
|
|
109
|
+
return {
|
|
110
|
+
complexity: 'simple',
|
|
111
|
+
requiresPipeline: false,
|
|
112
|
+
requirement: prompt,
|
|
113
|
+
reasoning: '极短输入且无改动动词(无会话上下文),判定为对话',
|
|
114
|
+
estimatedFiles: 0,
|
|
115
|
+
suggestedPhases: [],
|
|
116
|
+
};
|
|
117
|
+
}
|
|
110
118
|
}
|
|
111
119
|
return null; // 交给 AI 分析
|
|
112
120
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"intent-engine.js","sourceRoot":"","sources":["../../src/autopilot/intent-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAe5C;;;;;;;GAOG;AACH,MAAM,OAAO,YAAY;IACf,GAAG,CAAa;IACxB,mCAAmC;IAC3B,cAAc,GAAG,IAAI,GAAG,EAA8C,CAAC;IAC/E,iCAAiC;IACzB,cAAc,GAAG,IAAI,GAAG,EAA8C,CAAC;IACvE,MAAM,CAAU,YAAY,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC,OAAO;IAE7D,YAAY,GAAe;QACzB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,OAAO,CACX,UAAkB,EAClB,WAAmB,EACnB,SAAkB,EAClB,mBAA4B;QAE5B,iBAAiB;QACjB,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"intent-engine.js","sourceRoot":"","sources":["../../src/autopilot/intent-engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quality-gate.d.ts","sourceRoot":"","sources":["../../src/autopilot/quality-gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;IACnE,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,aAAa,CAA2D;IAChF,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAA0B;
|
|
1
|
+
{"version":3,"file":"quality-gate.d.ts","sourceRoot":"","sources":["../../src/autopilot/quality-gate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAE1D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,YAAY,CAAC;IACpB,MAAM,EAAE,YAAY,EAAE,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,GAAG,MAAM,GAAG,aAAa,CAAC;IACnE,KAAK,EAAE,YAAY,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,kBAAkB,CAAc;IACxC,OAAO,CAAC,aAAa,CAA2D;IAChF,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAM;gBAEpC,GAAG,EAAE,UAAU;IAI3B;;OAEG;IACH,cAAc,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI;IAIzC;;;OAGG;IACG,MAAM,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,aAAa,GAAG,IAAI,CAAC;IA6B9D;;OAEG;YACW,QAAQ;IAsDtB;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IA0BzE;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,GAAG,IAAI;IAgBxD;;OAEG;IACH,cAAc,IAAI,MAAM;IAyCxB;;OAEG;IACH,qBAAqB,IAAI,KAAK,CAAC;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,YAAY,EAAE,CAAA;KAAE,CAAC;IAM3E;;OAEG;IACH,KAAK,IAAI,IAAI;IAOb,OAAO,CAAC,WAAW;IAuCnB,OAAO,CAAC,aAAa;CAQtB"}
|
|
@@ -19,6 +19,7 @@ export class QualityGateEngine {
|
|
|
19
19
|
reviewHistory = [];
|
|
20
20
|
checkCount = 0;
|
|
21
21
|
skipPatterns = new Set(); // 用户多次忽略的检查类型
|
|
22
|
+
static MAX_HISTORY_LENGTH = 50; // 限制历史记录长度,避免内存泄漏
|
|
22
23
|
constructor(api) {
|
|
23
24
|
this.api = api;
|
|
24
25
|
}
|
|
@@ -39,8 +40,8 @@ export class QualityGateEngine {
|
|
|
39
40
|
return null;
|
|
40
41
|
// 节流:不是每次 Write/Edit 都审查,累积到一定量再审查
|
|
41
42
|
this.checkCount++;
|
|
42
|
-
if (this.checkCount %
|
|
43
|
-
return null; // 每
|
|
43
|
+
if (this.checkCount % 10 !== 0)
|
|
44
|
+
return null; // 每 10 次写入审查一次
|
|
44
45
|
const input = event.tool_input || {};
|
|
45
46
|
const filePath = input.file_path || '';
|
|
46
47
|
const content = input.content ||
|
|
@@ -226,8 +227,11 @@ ${suppressedCategories.length > 0 ? `## 已抑制的检查类别(不要重复
|
|
|
226
227
|
};
|
|
227
228
|
// 生成 directive
|
|
228
229
|
result.directive = this.generateDirective(result, filePath) || undefined;
|
|
229
|
-
//
|
|
230
|
-
this.reviewHistory.push({ result, accepted: true });
|
|
230
|
+
// 记录历史(环形缓冲,防止内存无限增长)
|
|
231
|
+
this.reviewHistory.push({ result, accepted: true });
|
|
232
|
+
if (this.reviewHistory.length > QualityGateEngine.MAX_HISTORY_LENGTH) {
|
|
233
|
+
this.reviewHistory = this.reviewHistory.slice(-QualityGateEngine.MAX_HISTORY_LENGTH);
|
|
234
|
+
}
|
|
231
235
|
return result;
|
|
232
236
|
}
|
|
233
237
|
catch (err) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quality-gate.js","sourceRoot":"","sources":["../../src/autopilot/quality-gate.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAmB5C;;;;;;;;;;;;;GAaG;AACH,MAAM,OAAO,iBAAiB;IACpB,GAAG,CAAa;IAChB,kBAAkB,GAAW,EAAE,CAAC;IAChC,aAAa,GAAwD,EAAE,CAAC;IACxE,UAAU,GAAW,CAAC,CAAC;IACvB,YAAY,GAAgB,IAAI,GAAG,EAAE,CAAC,CAAC,cAAc;
|
|
1
|
+
{"version":3,"file":"quality-gate.js","sourceRoot":"","sources":["../../src/autopilot/quality-gate.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"logs.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoQzC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiH1D"}
|
|
@@ -1,44 +1,39 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const DAEMON_LOG_BASE = 'daemon';
|
|
4
|
+
const EVENTS_DIR = path.join(os.homedir(), '.claude-forge');
|
|
5
|
+
const EVENTS_BASE = 'events';
|
|
7
6
|
const NOISY_EVENTS = new Set(['PreToolUse', 'PostToolUse']);
|
|
8
|
-
/** 与 logger.ts 中 todayStr() 一致:本地日历日 YYYY-MM-DD
|
|
9
|
-
function
|
|
7
|
+
/** 与 logger.ts 中 todayStr() 一致:本地日历日 YYYY-MM-DD */
|
|
8
|
+
function localDateSuffix() {
|
|
10
9
|
const now = new Date();
|
|
11
10
|
return (`${now.getFullYear()}-` +
|
|
12
11
|
`${String(now.getMonth() + 1).padStart(2, '0')}-` +
|
|
13
12
|
`${String(now.getDate()).padStart(2, '0')}`);
|
|
14
13
|
}
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* 当前事件日志路径(与守护进程写入对齐)
|
|
16
|
+
* 顺序:今日本地日期文件 → 目录下最新 events-*.jsonl → 默认 events.jsonl
|
|
18
17
|
*/
|
|
19
|
-
function
|
|
20
|
-
const
|
|
21
|
-
if (fs.existsSync(stable)) {
|
|
22
|
-
return stable;
|
|
23
|
-
}
|
|
24
|
-
const todayLocal = path.join(DAEMON_LOG_DIR, `${DAEMON_LOG_BASE}-${localDaemonDateSuffix()}.log`);
|
|
18
|
+
function currentEventsLogPath() {
|
|
19
|
+
const todayLocal = path.join(EVENTS_DIR, `${EVENTS_BASE}-${localDateSuffix()}.jsonl`);
|
|
25
20
|
if (fs.existsSync(todayLocal)) {
|
|
26
21
|
return todayLocal;
|
|
27
22
|
}
|
|
28
23
|
try {
|
|
29
24
|
const files = fs
|
|
30
|
-
.readdirSync(
|
|
31
|
-
.filter((f) => f.startsWith(`${
|
|
25
|
+
.readdirSync(EVENTS_DIR)
|
|
26
|
+
.filter((f) => f.startsWith(`${EVENTS_BASE}-`) && f.endsWith('.jsonl'))
|
|
32
27
|
.sort()
|
|
33
28
|
.reverse();
|
|
34
29
|
if (files.length > 0) {
|
|
35
|
-
return path.join(
|
|
30
|
+
return path.join(EVENTS_DIR, files[0]);
|
|
36
31
|
}
|
|
37
32
|
}
|
|
38
33
|
catch {
|
|
39
34
|
/* ignore */
|
|
40
35
|
}
|
|
41
|
-
return
|
|
36
|
+
return path.join(EVENTS_DIR, `${EVENTS_BASE}.jsonl`);
|
|
42
37
|
}
|
|
43
38
|
// ── ANSI ──────────────────────────────────────────────────────────────────────
|
|
44
39
|
const RESET = '\x1b[0m';
|
|
@@ -50,24 +45,58 @@ const YELLOW = '\x1b[33m';
|
|
|
50
45
|
const CYAN = '\x1b[36m';
|
|
51
46
|
const MAGENTA = '\x1b[35m';
|
|
52
47
|
const BLUE = '\x1b[34m';
|
|
53
|
-
|
|
48
|
+
const WHITE = '\x1b[37m';
|
|
49
|
+
const BG_RED = '\x1b[41m';
|
|
50
|
+
const BG_YELLOW = '\x1b[43m';
|
|
51
|
+
function levelBadge(level) {
|
|
54
52
|
switch (level) {
|
|
55
|
-
case 'error': return
|
|
56
|
-
case 'warn': return
|
|
57
|
-
case 'info': return
|
|
58
|
-
case 'debug': return DIM
|
|
59
|
-
default: return DIM
|
|
53
|
+
case 'error': return `${BG_RED}${WHITE}${BOLD} ERR ${RESET}`;
|
|
54
|
+
case 'warn': return `${BG_YELLOW}${WHITE}${BOLD} WRN ${RESET}`;
|
|
55
|
+
case 'info': return `${DIM} INF ${RESET}`;
|
|
56
|
+
case 'debug': return `${DIM} DBG ${RESET}`;
|
|
57
|
+
default: return `${DIM} ??? ${RESET}`;
|
|
60
58
|
}
|
|
61
59
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
|
|
60
|
+
/** 模块名 → 颜色映射,让同一模块的日志视觉一致 */
|
|
61
|
+
function moduleColor(mod) {
|
|
62
|
+
const m = mod.toLowerCase();
|
|
63
|
+
if (m.includes('意图') || m === 'intent')
|
|
64
|
+
return CYAN;
|
|
65
|
+
if (m.includes('画像') || m === 'profile')
|
|
66
|
+
return MAGENTA;
|
|
67
|
+
if (m.includes('pattern') || m.includes('模式'))
|
|
68
|
+
return GREEN;
|
|
69
|
+
if (m.includes('pipeline') || m.includes('编排'))
|
|
70
|
+
return YELLOW;
|
|
71
|
+
if (m.includes('规范') || m.includes('convention'))
|
|
72
|
+
return BLUE;
|
|
73
|
+
if (m.includes('质量') || m.includes('quality'))
|
|
74
|
+
return RED;
|
|
75
|
+
if (m.includes('技能') || m.includes('skill'))
|
|
76
|
+
return GREEN;
|
|
77
|
+
if (m.includes('知识') || m.includes('knowledge'))
|
|
78
|
+
return CYAN;
|
|
79
|
+
if (m.includes('文档') || m.includes('doc'))
|
|
80
|
+
return BLUE;
|
|
81
|
+
if (m.includes('蒸馏') || m.includes('distill'))
|
|
82
|
+
return MAGENTA;
|
|
83
|
+
if (m.includes('安全') || m.includes('auth'))
|
|
84
|
+
return RED;
|
|
85
|
+
if (m === 'userpromptsubmit' || m === 'stop')
|
|
86
|
+
return WHITE;
|
|
87
|
+
if (m === 'pretooluse' || m === 'posttooluse')
|
|
88
|
+
return DIM;
|
|
89
|
+
return DIM;
|
|
90
|
+
}
|
|
91
|
+
function moduleBadge(mod) {
|
|
92
|
+
const display = mod.padEnd(14).slice(0, 14);
|
|
93
|
+
return `${moduleColor(mod)}${display}${RESET}`;
|
|
66
94
|
}
|
|
67
95
|
function shortProject(p) {
|
|
68
96
|
if (!p)
|
|
69
97
|
return '—';
|
|
70
|
-
|
|
98
|
+
const parts = p.split('/');
|
|
99
|
+
return parts.slice(-1)[0] || parts.slice(-2).join('/');
|
|
71
100
|
}
|
|
72
101
|
function formatTime(ts, compact = false) {
|
|
73
102
|
if (!ts)
|
|
@@ -75,11 +104,11 @@ function formatTime(ts, compact = false) {
|
|
|
75
104
|
try {
|
|
76
105
|
const d = new Date(ts);
|
|
77
106
|
const pad = (n) => String(n).padStart(2, '0');
|
|
78
|
-
const date = `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
|
|
79
107
|
const time = `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
|
|
80
108
|
if (compact)
|
|
81
109
|
return time;
|
|
82
|
-
|
|
110
|
+
const ms = String(d.getMilliseconds()).padStart(3, '0');
|
|
111
|
+
return `${time}.${ms}`;
|
|
83
112
|
}
|
|
84
113
|
catch {
|
|
85
114
|
return ts;
|
|
@@ -99,10 +128,11 @@ function parseSince(since) {
|
|
|
99
128
|
}
|
|
100
129
|
}
|
|
101
130
|
function readEvents() {
|
|
102
|
-
|
|
131
|
+
const eventsPath = currentEventsLogPath();
|
|
132
|
+
if (!fs.existsSync(eventsPath))
|
|
103
133
|
return [];
|
|
104
134
|
return fs
|
|
105
|
-
.readFileSync(
|
|
135
|
+
.readFileSync(eventsPath, 'utf-8')
|
|
106
136
|
.split('\n')
|
|
107
137
|
.filter(Boolean)
|
|
108
138
|
.map(line => {
|
|
@@ -116,36 +146,26 @@ function readEvents() {
|
|
|
116
146
|
.filter((e) => e !== null);
|
|
117
147
|
}
|
|
118
148
|
function printEntry(e, compact) {
|
|
119
|
-
const time =
|
|
120
|
-
const proj = shortProject(e.project).padEnd(20);
|
|
121
|
-
const evt = (e.event || '').padEnd(16);
|
|
149
|
+
const time = formatTime(e.ts, compact);
|
|
122
150
|
const badge = levelBadge(e.level || 'info');
|
|
151
|
+
const mod = moduleBadge(e.event || '—');
|
|
152
|
+
const msg = e.msg || '';
|
|
123
153
|
if (compact) {
|
|
124
|
-
process.stdout.write(`${DIM}${time}${RESET} ${badge}
|
|
154
|
+
process.stdout.write(`${DIM}${time}${RESET} ${badge}${mod} ${msg}\n`);
|
|
125
155
|
}
|
|
126
156
|
else {
|
|
127
|
-
|
|
157
|
+
const proj = shortProject(e.project).padEnd(16).slice(0, 16);
|
|
158
|
+
process.stdout.write(`${DIM}${time}${RESET} ${badge}${mod} ${BLUE}${proj}${RESET} ${msg}\n`);
|
|
128
159
|
}
|
|
129
160
|
}
|
|
130
|
-
function printDaemonLogLine(line) {
|
|
131
|
-
const m = line.match(/^\[(.+?)\] \[(\w+)\] (.+)$/);
|
|
132
|
-
if (!m) {
|
|
133
|
-
process.stdout.write(`${DIM}${line}${RESET}\n`);
|
|
134
|
-
return;
|
|
135
|
-
}
|
|
136
|
-
const [, ts, level, msg] = m;
|
|
137
|
-
const time = ts.slice(0, 19).replace('T', ' ');
|
|
138
|
-
const badge = levelBadge(level.toLowerCase());
|
|
139
|
-
process.stdout.write(`${DIM}${time}${RESET} ${badge} ${msg}\n`);
|
|
140
|
-
}
|
|
141
161
|
// ── Follow 模式:tail -f events.jsonl ─────────────────────────────────────────
|
|
142
162
|
function followEvents(filters) {
|
|
143
|
-
|
|
144
|
-
|
|
163
|
+
const eventsPath = currentEventsLogPath();
|
|
164
|
+
if (!fs.existsSync(eventsPath)) {
|
|
165
|
+
process.stdout.write(`${DIM}等待事件日志创建...${RESET}\n`);
|
|
145
166
|
// 等文件创建
|
|
146
|
-
const
|
|
147
|
-
|
|
148
|
-
if (filename === path.basename(EVENTS_JSONL)) {
|
|
167
|
+
const watcher = fs.watch(EVENTS_DIR, (evtype, filename) => {
|
|
168
|
+
if (filename && filename.startsWith(EVENTS_BASE) && filename.endsWith('.jsonl')) {
|
|
149
169
|
watcher.close();
|
|
150
170
|
followFile(filters);
|
|
151
171
|
}
|
|
@@ -156,6 +176,8 @@ function followEvents(filters) {
|
|
|
156
176
|
}
|
|
157
177
|
function followFile(filters) {
|
|
158
178
|
process.stdout.write(`${BOLD}${GREEN}● 实时日志流(Ctrl+C 退出)${RESET}\n\n`);
|
|
179
|
+
let currentLogPath = currentEventsLogPath();
|
|
180
|
+
process.stdout.write(`${DIM}跟踪文件:${path.basename(currentLogPath)}${RESET}\n`);
|
|
159
181
|
// 先回放最近 10 条记录作为上下文
|
|
160
182
|
const allEvents = readEvents();
|
|
161
183
|
const recent = allEvents.slice(-10);
|
|
@@ -171,13 +193,23 @@ function followFile(filters) {
|
|
|
171
193
|
continue;
|
|
172
194
|
printEntry(e, filters.compact);
|
|
173
195
|
}
|
|
174
|
-
let fileSize = fs.statSync(
|
|
196
|
+
let fileSize = fs.existsSync(currentLogPath) ? fs.statSync(currentLogPath).size : 0;
|
|
175
197
|
const timer = setInterval(() => {
|
|
176
198
|
try {
|
|
177
|
-
|
|
199
|
+
// 每次轮询时重新获取当前日志路径(支持日期轮转)
|
|
200
|
+
const latestLogPath = currentEventsLogPath();
|
|
201
|
+
// 检测到日志文件切换(日期轮转)
|
|
202
|
+
if (latestLogPath !== currentLogPath) {
|
|
203
|
+
process.stdout.write(`${DIM}[日志文件切换: ${path.basename(latestLogPath)}]${RESET}\n`);
|
|
204
|
+
currentLogPath = latestLogPath;
|
|
205
|
+
fileSize = 0; // 重置文件位置
|
|
206
|
+
}
|
|
207
|
+
if (!fs.existsSync(currentLogPath))
|
|
208
|
+
return;
|
|
209
|
+
const stat = fs.statSync(currentLogPath);
|
|
178
210
|
if (stat.size <= fileSize)
|
|
179
211
|
return;
|
|
180
|
-
const fd = fs.openSync(
|
|
212
|
+
const fd = fs.openSync(currentLogPath, 'r');
|
|
181
213
|
const buf = Buffer.alloc(stat.size - fileSize);
|
|
182
214
|
fs.readSync(fd, buf, 0, buf.length, fileSize);
|
|
183
215
|
fs.closeSync(fd);
|
|
@@ -208,59 +240,6 @@ function followFile(filters) {
|
|
|
208
240
|
process.exit(0);
|
|
209
241
|
});
|
|
210
242
|
}
|
|
211
|
-
// ── daemon.log 实时跟踪 ────────────────────────────────────────────────────────
|
|
212
|
-
function followDaemonLog() {
|
|
213
|
-
process.stdout.write(`${BOLD}${GREEN}● Daemon 日志流(Ctrl+C 退出)${RESET}\n\n`);
|
|
214
|
-
let currentLogPath = currentDaemonLogPath();
|
|
215
|
-
let fileSize = fs.existsSync(currentLogPath) ? fs.statSync(currentLogPath).size : 0;
|
|
216
|
-
process.stdout.write(`${DIM}跟踪文件:${currentLogPath}${RESET}\n`);
|
|
217
|
-
if (!fs.existsSync(currentLogPath)) {
|
|
218
|
-
process.stdout.write(`${DIM}文件尚未创建,有新写入时会自动显示...${RESET}\n`);
|
|
219
|
-
}
|
|
220
|
-
else {
|
|
221
|
-
// 先回放最近 20 行作为上下文
|
|
222
|
-
try {
|
|
223
|
-
const content = fs.readFileSync(currentLogPath, 'utf-8');
|
|
224
|
-
const lines = content.split('\n').filter(Boolean);
|
|
225
|
-
const recent = lines.slice(-20);
|
|
226
|
-
for (const line of recent)
|
|
227
|
-
printDaemonLogLine(line);
|
|
228
|
-
}
|
|
229
|
-
catch { /* ignore */ }
|
|
230
|
-
}
|
|
231
|
-
// 使用轮询替代 fs.watch,动态检测日志文件路径变化
|
|
232
|
-
const timer = setInterval(() => {
|
|
233
|
-
try {
|
|
234
|
-
// 每次轮询时重新获取当前日志路径(支持日期轮转)
|
|
235
|
-
const latestLogPath = currentDaemonLogPath();
|
|
236
|
-
// 检测到日志文件切换(日期轮转)
|
|
237
|
-
if (latestLogPath !== currentLogPath) {
|
|
238
|
-
process.stdout.write(`${DIM}[日志文件切换: ${path.basename(latestLogPath)}]${RESET}\n`);
|
|
239
|
-
currentLogPath = latestLogPath;
|
|
240
|
-
fileSize = 0; // 重置文件位置
|
|
241
|
-
}
|
|
242
|
-
if (!fs.existsSync(currentLogPath))
|
|
243
|
-
return;
|
|
244
|
-
const stat = fs.statSync(currentLogPath);
|
|
245
|
-
if (stat.size <= fileSize)
|
|
246
|
-
return;
|
|
247
|
-
const fd = fs.openSync(currentLogPath, 'r');
|
|
248
|
-
const buf = Buffer.alloc(stat.size - fileSize);
|
|
249
|
-
fs.readSync(fd, buf, 0, buf.length, fileSize);
|
|
250
|
-
fs.closeSync(fd);
|
|
251
|
-
fileSize = stat.size;
|
|
252
|
-
const lines = buf.toString('utf-8').split('\n').filter(Boolean);
|
|
253
|
-
for (const line of lines)
|
|
254
|
-
printDaemonLogLine(line);
|
|
255
|
-
}
|
|
256
|
-
catch { /* ignore */ }
|
|
257
|
-
}, 500);
|
|
258
|
-
process.on('SIGINT', () => {
|
|
259
|
-
clearInterval(timer);
|
|
260
|
-
process.stdout.write('\n');
|
|
261
|
-
process.exit(0);
|
|
262
|
-
});
|
|
263
|
-
}
|
|
264
243
|
// ── 注册命令 ──────────────────────────────────────────────────────────────────
|
|
265
244
|
export function registerLogsCommand(program) {
|
|
266
245
|
program
|
|
@@ -272,32 +251,11 @@ export function registerLogsCommand(program) {
|
|
|
272
251
|
.option('-e, --event <type>', '按事件类型过滤(子字符串匹配)')
|
|
273
252
|
.option('--since <duration>', '时间过滤,如 30m、2h、1d')
|
|
274
253
|
.option('-f, --follow', '实时跟踪新事件(类似 tail -f)')
|
|
275
|
-
.option('--daemon', '跟踪 daemon.log(适合调试 daemon 内部日志)')
|
|
276
254
|
.option('--compact', '紧凑模式:省略项目列,只显示时间+级别+事件+消息')
|
|
277
255
|
.option('--raw', '输出原始 JSON(每行一个对象,适合管道处理)')
|
|
278
256
|
.option('--projects', '列出所有已记录的项目')
|
|
279
257
|
.option('--verbose', '显示全部事件(含 PreToolUse / PostToolUse)')
|
|
280
258
|
.action((opts) => {
|
|
281
|
-
// daemon.log 跟踪模式
|
|
282
|
-
if (opts.daemon) {
|
|
283
|
-
if (opts.follow) {
|
|
284
|
-
followDaemonLog();
|
|
285
|
-
return;
|
|
286
|
-
}
|
|
287
|
-
// 静态查看 daemon.log 尾部
|
|
288
|
-
const logPath = currentDaemonLogPath();
|
|
289
|
-
if (!fs.existsSync(logPath)) {
|
|
290
|
-
process.stdout.write('daemon 日志不存在\n');
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
const tail = Math.max(1, parseInt(opts.tail, 10) || 50);
|
|
294
|
-
const lines = fs.readFileSync(logPath, 'utf-8').split('\n').filter(Boolean);
|
|
295
|
-
const slice = lines.slice(-tail);
|
|
296
|
-
process.stdout.write(`${BOLD}${path.basename(logPath)}${RESET}(最近 ${tail} 行)\n\n`);
|
|
297
|
-
for (const line of slice)
|
|
298
|
-
printDaemonLogLine(line);
|
|
299
|
-
return;
|
|
300
|
-
}
|
|
301
259
|
// 实时跟踪 events.jsonl
|
|
302
260
|
if (opts.follow) {
|
|
303
261
|
followEvents({
|
|
@@ -364,9 +322,8 @@ export function registerLogsCommand(program) {
|
|
|
364
322
|
// 打印表头
|
|
365
323
|
const compact = opts.compact ?? false;
|
|
366
324
|
if (!compact) {
|
|
367
|
-
|
|
368
|
-
process.stdout.write(`${
|
|
369
|
-
process.stdout.write(`${DIM}${'─'.repeat(header.length)}${RESET}\n`);
|
|
325
|
+
process.stdout.write(`${BOLD}${DIM}${'时间'.padEnd(12)}${RESET}${BOLD} ${'级别'.padEnd(5)} ${'模块'.padEnd(14)} ${'项目'.padEnd(16)} 消息${RESET}\n`);
|
|
326
|
+
process.stdout.write(`${DIM}${'─'.repeat(90)}${RESET}\n`);
|
|
370
327
|
}
|
|
371
328
|
for (const e of filtered)
|
|
372
329
|
printEntry(e, compact);
|