@winspan/claude-forge 8.28.1 → 8.30.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/README.md +68 -215
- package/dist/capability/execution-manager.d.ts +59 -0
- package/dist/capability/execution-manager.d.ts.map +1 -0
- package/dist/capability/execution-manager.js +168 -0
- package/dist/capability/execution-manager.js.map +1 -0
- package/dist/capability/executor/background-executor.d.ts +57 -0
- package/dist/capability/executor/background-executor.d.ts.map +1 -0
- package/dist/capability/executor/background-executor.js +299 -0
- package/dist/capability/executor/background-executor.js.map +1 -0
- package/dist/capability/executor/foreground-executor.d.ts +26 -0
- package/dist/capability/executor/foreground-executor.d.ts.map +1 -0
- package/dist/capability/executor/foreground-executor.js +82 -0
- package/dist/capability/executor/foreground-executor.js.map +1 -0
- package/dist/capability/executor/orchestrator.d.ts +25 -0
- package/dist/capability/executor/orchestrator.d.ts.map +1 -0
- package/dist/capability/executor/orchestrator.js +79 -0
- package/dist/capability/executor/orchestrator.js.map +1 -0
- package/dist/capability/executor/stream-parser.d.ts +73 -0
- package/dist/capability/executor/stream-parser.d.ts.map +1 -0
- package/dist/capability/executor/stream-parser.js +56 -0
- package/dist/capability/executor/stream-parser.js.map +1 -0
- package/dist/capability/executor/types.d.ts +44 -0
- package/dist/capability/executor/types.d.ts.map +1 -0
- package/dist/capability/executor/types.js +9 -0
- package/dist/capability/executor/types.js.map +1 -0
- package/dist/capability/executor/worker-auth-probe.d.ts +30 -0
- package/dist/capability/executor/worker-auth-probe.d.ts.map +1 -0
- package/dist/capability/executor/worker-auth-probe.js +99 -0
- package/dist/capability/executor/worker-auth-probe.js.map +1 -0
- package/dist/capability/methodology-planner.d.ts.map +1 -1
- package/dist/capability/methodology-planner.js +10 -7
- package/dist/capability/methodology-planner.js.map +1 -1
- package/dist/capability/types.d.ts +10 -1
- package/dist/capability/types.d.ts.map +1 -1
- package/dist/core/storage/sqlite.d.ts +18 -0
- package/dist/core/storage/sqlite.d.ts.map +1 -1
- package/dist/core/storage/sqlite.js +75 -4
- package/dist/core/storage/sqlite.js.map +1 -1
- package/dist/daemon/handlers/methodology-formatter.d.ts +7 -0
- package/dist/daemon/handlers/methodology-formatter.d.ts.map +1 -1
- package/dist/daemon/handlers/methodology-formatter.js +46 -0
- package/dist/daemon/handlers/methodology-formatter.js.map +1 -1
- package/dist/daemon/handlers/post-tool-use.d.ts.map +1 -1
- package/dist/daemon/handlers/post-tool-use.js +6 -3
- package/dist/daemon/handlers/post-tool-use.js.map +1 -1
- package/dist/daemon/handlers/stop.d.ts +6 -1
- package/dist/daemon/handlers/stop.d.ts.map +1 -1
- package/dist/daemon/handlers/stop.js +45 -1
- package/dist/daemon/handlers/stop.js.map +1 -1
- package/dist/daemon/handlers/user-prompt.d.ts.map +1 -1
- package/dist/daemon/handlers/user-prompt.js +34 -1
- package/dist/daemon/handlers/user-prompt.js.map +1 -1
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +20 -1
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/methodology-pending-queue.d.ts +33 -0
- package/dist/daemon/methodology-pending-queue.d.ts.map +1 -0
- package/dist/daemon/methodology-pending-queue.js +120 -0
- package/dist/daemon/methodology-pending-queue.js.map +1 -0
- package/dist/web/server.d.ts +6 -0
- package/dist/web/server.d.ts.map +1 -1
- package/dist/web/server.js +127 -7
- package/dist/web/server.js.map +1 -1
- package/dist/web/static/assets/AIConfig-nZgwaowr.js +2 -0
- package/dist/web/static/assets/AIConfig-nZgwaowr.js.map +1 -0
- package/dist/web/static/assets/Agents-BZGXKWC7.js +2 -0
- package/dist/web/static/assets/Agents-BZGXKWC7.js.map +1 -0
- package/dist/web/static/assets/CodeBlock--H53gk46.js +2 -0
- package/dist/web/static/assets/CodeBlock--H53gk46.js.map +1 -0
- package/dist/web/static/assets/Dashboard-qUCxXFSI.js +2 -0
- package/dist/web/static/assets/Dashboard-qUCxXFSI.js.map +1 -0
- package/dist/web/static/assets/Drawer-DeKukfwJ.js +2 -0
- package/dist/web/static/assets/Drawer-DeKukfwJ.js.map +1 -0
- package/dist/web/static/assets/Events-CnA3f740.js +2 -0
- package/dist/web/static/assets/Events-CnA3f740.js.map +1 -0
- package/dist/web/static/assets/ExecutionTrace-ClPfFIQa.js +2 -0
- package/dist/web/static/assets/ExecutionTrace-ClPfFIQa.js.map +1 -0
- package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js +2 -0
- package/dist/web/static/assets/MarkdownRenderer-CCIz1MOz.js.map +1 -0
- package/dist/web/static/assets/Methodologies-CAXUXeox.js +2 -0
- package/dist/web/static/assets/Methodologies-CAXUXeox.js.map +1 -0
- package/dist/web/static/assets/MethodologyDetail-Do1taSKM.js +2 -0
- package/dist/web/static/assets/MethodologyDetail-Do1taSKM.js.map +1 -0
- package/dist/web/static/assets/Routing-CFmM7JuB.js +2 -0
- package/dist/web/static/assets/Routing-CFmM7JuB.js.map +1 -0
- package/dist/web/static/assets/SessionDetail-DzTue2xK.js +2 -0
- package/dist/web/static/assets/SessionDetail-DzTue2xK.js.map +1 -0
- package/dist/web/static/assets/Sessions-DwWOKgnl.js +2 -0
- package/dist/web/static/assets/Sessions-DwWOKgnl.js.map +1 -0
- package/dist/web/static/assets/Skills-DhM6ALhr.js +2 -0
- package/dist/web/static/assets/Skills-DhM6ALhr.js.map +1 -0
- package/dist/web/static/assets/charts-CLrM0_uM.js +37 -0
- package/dist/web/static/assets/charts-CLrM0_uM.js.map +1 -0
- package/dist/web/static/assets/date-fns-CZ_bHujz.js +2 -0
- package/dist/web/static/assets/date-fns-CZ_bHujz.js.map +1 -0
- package/dist/web/static/assets/export-CEzDNM66.js +4 -0
- package/dist/web/static/assets/export-CEzDNM66.js.map +1 -0
- package/dist/web/static/assets/index-CVWult53.css +1 -0
- package/dist/web/static/assets/index-DUYj2ek1.js +3 -0
- package/dist/web/static/assets/index-DUYj2ek1.js.map +1 -0
- package/dist/web/static/assets/lucide-DjB4fWNj.js +227 -0
- package/dist/web/static/assets/lucide-DjB4fWNj.js.map +1 -0
- package/dist/web/static/assets/query-C99w429o.js +2 -0
- package/dist/web/static/assets/query-C99w429o.js.map +1 -0
- package/dist/web/static/assets/react-router-I-HqunH7.js +20 -0
- package/dist/web/static/assets/react-router-I-HqunH7.js.map +1 -0
- package/dist/web/static/assets/react-vendor-CSp-GLFF.js +49 -0
- package/dist/web/static/assets/react-vendor-CSp-GLFF.js.map +1 -0
- package/dist/web/static/assets/syntax-highlighter-44FakypI.js +9 -0
- package/dist/web/static/assets/syntax-highlighter-44FakypI.js.map +1 -0
- package/dist/web/static/assets/vendor-CMMjVdZs.js +64 -0
- package/dist/web/static/assets/vendor-CMMjVdZs.js.map +1 -0
- package/dist/web/static/index.html +8 -2
- package/package.json +1 -1
- package/dist/web/static/assets/index-CtylfoaN.css +0 -1
- package/dist/web/static/assets/index-DnaQt27h.js +0 -388
- package/dist/web/static/assets/index-DnaQt27h.js.map +0 -1
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Methodology Pending Inject Queue
|
|
3
|
+
*
|
|
4
|
+
* 前台模式下,Claude 主对话有时会忽略 UserPromptSubmit 注入的阶段指令
|
|
5
|
+
* (3 小时进度 0% 就是这种情况)。Stop hook 检测到这种情况时,把"下
|
|
6
|
+
* 一次要注入的指令"写入队列;UserPromptSubmit 在下一轮响应前消费一次。
|
|
7
|
+
*
|
|
8
|
+
* 进程内 Map + 磁盘 JSON 双层:daemon 重启时从磁盘恢复。
|
|
9
|
+
*/
|
|
10
|
+
export interface PendingDirective {
|
|
11
|
+
session_id: string;
|
|
12
|
+
execution_id: number;
|
|
13
|
+
phase_index: number;
|
|
14
|
+
directive: string;
|
|
15
|
+
enqueued_at: number;
|
|
16
|
+
reason: 'stop-fallback' | 'cold-restart' | 'idle-timeout';
|
|
17
|
+
}
|
|
18
|
+
export declare class MethodologyPendingQueue {
|
|
19
|
+
private memory;
|
|
20
|
+
private queueDir;
|
|
21
|
+
constructor(queueDir?: string);
|
|
22
|
+
private loadFromDisk;
|
|
23
|
+
private filePath;
|
|
24
|
+
enqueue(entry: PendingDirective): void;
|
|
25
|
+
consume(session_id: string): PendingDirective | null;
|
|
26
|
+
peek(session_id: string): PendingDirective | null;
|
|
27
|
+
size(): number;
|
|
28
|
+
purgeByExecutionId(execution_id: number): void;
|
|
29
|
+
}
|
|
30
|
+
export declare function getMethodologyPendingQueue(): MethodologyPendingQueue;
|
|
31
|
+
export declare function _resetMethodologyPendingQueueForTest(): void;
|
|
32
|
+
export declare function getPendingQueueDir(): string;
|
|
33
|
+
//# sourceMappingURL=methodology-pending-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methodology-pending-queue.d.ts","sourceRoot":"","sources":["../../src/daemon/methodology-pending-queue.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,eAAe,GAAG,cAAc,GAAG,cAAc,CAAC;CAC3D;AAED,qBAAa,uBAAuB;IAClC,OAAO,CAAC,MAAM,CAAuC;IACrD,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,CAAC,EAAE,MAAM;IAK7B,OAAO,CAAC,YAAY;IAwBpB,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI;IActC,OAAO,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAiBpD,IAAI,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB,GAAG,IAAI;IAIjD,IAAI,IAAI,MAAM;IAKd,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI;CAW/C;AAID,wBAAgB,0BAA0B,IAAI,uBAAuB,CAGpE;AAGD,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAGD,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Methodology Pending Inject Queue
|
|
3
|
+
*
|
|
4
|
+
* 前台模式下,Claude 主对话有时会忽略 UserPromptSubmit 注入的阶段指令
|
|
5
|
+
* (3 小时进度 0% 就是这种情况)。Stop hook 检测到这种情况时,把"下
|
|
6
|
+
* 一次要注入的指令"写入队列;UserPromptSubmit 在下一轮响应前消费一次。
|
|
7
|
+
*
|
|
8
|
+
* 进程内 Map + 磁盘 JSON 双层:daemon 重启时从磁盘恢复。
|
|
9
|
+
*/
|
|
10
|
+
import { existsSync, mkdirSync, readdirSync, readFileSync, unlinkSync, writeFileSync } from 'fs';
|
|
11
|
+
import path from 'path';
|
|
12
|
+
import { homedir } from 'os';
|
|
13
|
+
import { logger } from '../core/utils/logger.js';
|
|
14
|
+
const DEFAULT_QUEUE_DIR = path.join(homedir(), '.claude-forge', 'pending-inject');
|
|
15
|
+
function resolveQueueDir() {
|
|
16
|
+
return process.env.CLAUDE_FORGE_PENDING_DIR || DEFAULT_QUEUE_DIR;
|
|
17
|
+
}
|
|
18
|
+
export class MethodologyPendingQueue {
|
|
19
|
+
memory = new Map();
|
|
20
|
+
queueDir;
|
|
21
|
+
constructor(queueDir) {
|
|
22
|
+
this.queueDir = queueDir ?? resolveQueueDir();
|
|
23
|
+
this.loadFromDisk();
|
|
24
|
+
}
|
|
25
|
+
loadFromDisk() {
|
|
26
|
+
try {
|
|
27
|
+
if (!existsSync(this.queueDir)) {
|
|
28
|
+
mkdirSync(this.queueDir, { recursive: true });
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
const files = readdirSync(this.queueDir).filter(f => f.endsWith('.json'));
|
|
32
|
+
for (const file of files) {
|
|
33
|
+
try {
|
|
34
|
+
const raw = readFileSync(path.join(this.queueDir, file), 'utf-8');
|
|
35
|
+
const entry = JSON.parse(raw);
|
|
36
|
+
this.memory.set(entry.session_id, entry);
|
|
37
|
+
}
|
|
38
|
+
catch (err) {
|
|
39
|
+
logger.debug(`[MethodologyPendingQueue] skip corrupt ${file}: ${err}`);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
if (this.memory.size > 0) {
|
|
43
|
+
logger.info(`[MethodologyPendingQueue] restored ${this.memory.size} pending directives`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
logger.warn(`[MethodologyPendingQueue] loadFromDisk failed: ${err}`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
filePath(session_id) {
|
|
51
|
+
const safe = session_id.replace(/[^a-zA-Z0-9_-]/g, '_');
|
|
52
|
+
return path.join(this.queueDir, `${safe}.json`);
|
|
53
|
+
}
|
|
54
|
+
enqueue(entry) {
|
|
55
|
+
this.memory.set(entry.session_id, entry);
|
|
56
|
+
try {
|
|
57
|
+
if (!existsSync(this.queueDir))
|
|
58
|
+
mkdirSync(this.queueDir, { recursive: true });
|
|
59
|
+
writeFileSync(this.filePath(entry.session_id), JSON.stringify(entry, null, 2), 'utf-8');
|
|
60
|
+
logger.info(`[MethodologyPendingQueue] enqueued ${entry.reason} for session=${entry.session_id.slice(0, 8)} phase=${entry.phase_index}`);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
logger.warn(`[MethodologyPendingQueue] persist failed: ${err}`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// 取出并移除。返回 null 如果没有待注入。
|
|
67
|
+
consume(session_id) {
|
|
68
|
+
const entry = this.memory.get(session_id);
|
|
69
|
+
if (!entry)
|
|
70
|
+
return null;
|
|
71
|
+
this.memory.delete(session_id);
|
|
72
|
+
try {
|
|
73
|
+
const fp = this.filePath(session_id);
|
|
74
|
+
if (existsSync(fp))
|
|
75
|
+
unlinkSync(fp);
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
logger.debug(`[MethodologyPendingQueue] cleanup failed: ${err}`);
|
|
79
|
+
}
|
|
80
|
+
logger.info(`[MethodologyPendingQueue] consumed ${entry.reason} for session=${session_id.slice(0, 8)} phase=${entry.phase_index}`);
|
|
81
|
+
return entry;
|
|
82
|
+
}
|
|
83
|
+
// 对外只用于调试/可观测,不建议修改返回值
|
|
84
|
+
peek(session_id) {
|
|
85
|
+
return this.memory.get(session_id) ?? null;
|
|
86
|
+
}
|
|
87
|
+
size() {
|
|
88
|
+
return this.memory.size;
|
|
89
|
+
}
|
|
90
|
+
// 强制清理指定 execution 的所有 pending(execution 被 cancel / 完成时调用)
|
|
91
|
+
purgeByExecutionId(execution_id) {
|
|
92
|
+
for (const [sid, entry] of this.memory.entries()) {
|
|
93
|
+
if (entry.execution_id === execution_id) {
|
|
94
|
+
this.memory.delete(sid);
|
|
95
|
+
try {
|
|
96
|
+
const fp = this.filePath(sid);
|
|
97
|
+
if (existsSync(fp))
|
|
98
|
+
unlinkSync(fp);
|
|
99
|
+
}
|
|
100
|
+
catch { /* ignore */ }
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
// Daemon 单例
|
|
106
|
+
let _instance = null;
|
|
107
|
+
export function getMethodologyPendingQueue() {
|
|
108
|
+
if (!_instance)
|
|
109
|
+
_instance = new MethodologyPendingQueue();
|
|
110
|
+
return _instance;
|
|
111
|
+
}
|
|
112
|
+
// 测试用 reset
|
|
113
|
+
export function _resetMethodologyPendingQueueForTest() {
|
|
114
|
+
_instance = null;
|
|
115
|
+
}
|
|
116
|
+
// 暴露给外部(用于避免测试时写真实 HOME)
|
|
117
|
+
export function getPendingQueueDir() {
|
|
118
|
+
return resolveQueueDir();
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=methodology-pending-queue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"methodology-pending-queue.js","sourceRoot":"","sources":["../../src/daemon/methodology-pending-queue.ts"],"names":[],"mappings":"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"}
|
package/dist/web/server.d.ts
CHANGED
|
@@ -7,12 +7,18 @@ import type { SQLiteStorage } from '../core/storage/sqlite.js';
|
|
|
7
7
|
import type { RuleEngine } from '../engine/rule-engine.js';
|
|
8
8
|
import type { AgentRouter } from '../engine/agent-router.js';
|
|
9
9
|
import type { AgentRegistry } from '../agents/registry.js';
|
|
10
|
+
import type { ExecutionManager } from '../capability/execution-manager.js';
|
|
11
|
+
import type { MethodologyRegistry } from '../capability/methodology-registry.js';
|
|
12
|
+
import type { MethodologyPlanner } from '../capability/methodology-planner.js';
|
|
10
13
|
export interface WebServerOptions {
|
|
11
14
|
port: number;
|
|
12
15
|
storage: SQLiteStorage;
|
|
13
16
|
ruleEngine: RuleEngine;
|
|
14
17
|
router?: AgentRouter;
|
|
15
18
|
agents?: AgentRegistry;
|
|
19
|
+
executionManager?: ExecutionManager;
|
|
20
|
+
methodologyRegistry?: MethodologyRegistry;
|
|
21
|
+
methodologyPlanner?: MethodologyPlanner;
|
|
16
22
|
}
|
|
17
23
|
export declare class WebServer {
|
|
18
24
|
private options;
|
package/dist/web/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/web/server.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,uCAAuC,CAAC;AACjF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,sCAAsC,CAAC;AAW/E,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,aAAa,CAAC;IACvB,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,mBAAmB,CAAC,EAAE,mBAAmB,CAAC;IAC1C,kBAAkB,CAAC,EAAE,kBAAkB,CAAC;CACzC;AAED,qBAAa,SAAS;IAMR,OAAO,CAAC,OAAO;IAL3B,OAAO,CAAC,GAAG,CAAsB;IACjC,OAAO,CAAC,MAAM,CAA0D;IACxE,OAAO,CAAC,MAAM,CAAC,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAC,CAAc;gBAET,OAAO,EAAE,gBAAgB;IAQ7C,OAAO,CAAC,WAAW;IAiiFb,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAgBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAO5B"}
|
package/dist/web/server.js
CHANGED
|
@@ -9,6 +9,7 @@ import path from 'path';
|
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import { homedir } from 'os';
|
|
11
11
|
import yaml from 'js-yaml';
|
|
12
|
+
import { WorkerAuthError } from '../capability/executor/worker-auth-probe.js';
|
|
12
13
|
import { Recommender } from '../engine/recommender.js';
|
|
13
14
|
import { logger } from '../core/utils/logger.js';
|
|
14
15
|
import { ErrorHandler } from '../core/utils/error-handler.js';
|
|
@@ -686,7 +687,7 @@ export class WebServer {
|
|
|
686
687
|
});
|
|
687
688
|
});
|
|
688
689
|
// Methodology Execution: cancel a running execution
|
|
689
|
-
this.app.post('/api/methodology-executions/:id/cancel', (req, res) => {
|
|
690
|
+
this.app.post('/api/methodology-executions/:id/cancel', async (req, res) => {
|
|
690
691
|
const executionId = parseInt(req.params.id);
|
|
691
692
|
const db = storage.getDatabase();
|
|
692
693
|
const execution = db.prepare('SELECT * FROM methodology_executions WHERE id = ?').get(executionId);
|
|
@@ -698,12 +699,26 @@ export class WebServer {
|
|
|
698
699
|
res.status(400).json({ error: `Cannot cancel execution in ${execution.status} state` });
|
|
699
700
|
return;
|
|
700
701
|
}
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
702
|
+
// Prefer ExecutionManager — it kills the worker process for background mode
|
|
703
|
+
if (this.options.executionManager) {
|
|
704
|
+
try {
|
|
705
|
+
await this.options.executionManager.cancel(executionId);
|
|
706
|
+
}
|
|
707
|
+
catch (err) {
|
|
708
|
+
logger.warn(`[web] cancel via ExecutionManager failed: ${err}`);
|
|
709
|
+
res.status(500).json({ error: `Cancel failed: ${err instanceof Error ? err.message : String(err)}` });
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
// Fallback: DB-only cancel (pre-Phase-C behavior)
|
|
715
|
+
db.prepare(`
|
|
716
|
+
UPDATE methodology_executions
|
|
717
|
+
SET status = 'cancelled', completed_at = ?
|
|
718
|
+
WHERE id = ?
|
|
719
|
+
`).run(Date.now(), executionId);
|
|
720
|
+
}
|
|
721
|
+
// Mark any still-running phase rows as cancelled
|
|
707
722
|
db.prepare(`
|
|
708
723
|
UPDATE phase_executions
|
|
709
724
|
SET status = 'cancelled', completed_at = ?
|
|
@@ -711,6 +726,111 @@ export class WebServer {
|
|
|
711
726
|
`).run(Date.now(), executionId);
|
|
712
727
|
res.json({ success: true, message: 'Execution cancelled' });
|
|
713
728
|
});
|
|
729
|
+
// Methodology Execution: start a new execution (Phase C)
|
|
730
|
+
// Body: { session_id, methodology_id?, plan?, mode: 'foreground' | 'background', requirement? }
|
|
731
|
+
this.app.post('/api/methodology-executions', async (req, res) => {
|
|
732
|
+
const { executionManager, methodologyRegistry } = this.options;
|
|
733
|
+
if (!executionManager || !methodologyRegistry) {
|
|
734
|
+
res.status(503).json({ error: 'Execution manager not available' });
|
|
735
|
+
return;
|
|
736
|
+
}
|
|
737
|
+
const { session_id, methodology_id, plan, mode } = req.body ?? {};
|
|
738
|
+
if (!session_id) {
|
|
739
|
+
res.status(400).json({ error: 'session_id is required' });
|
|
740
|
+
return;
|
|
741
|
+
}
|
|
742
|
+
if (mode !== 'foreground' && mode !== 'background') {
|
|
743
|
+
res.status(400).json({ error: 'mode must be foreground or background' });
|
|
744
|
+
return;
|
|
745
|
+
}
|
|
746
|
+
let planObj = null;
|
|
747
|
+
if (plan && typeof plan === 'object' && Array.isArray(plan.phases)) {
|
|
748
|
+
planObj = plan;
|
|
749
|
+
}
|
|
750
|
+
else if (methodology_id) {
|
|
751
|
+
const methodology = methodologyRegistry.get(methodology_id);
|
|
752
|
+
if (!methodology) {
|
|
753
|
+
res.status(404).json({ error: `methodology ${methodology_id} not found` });
|
|
754
|
+
return;
|
|
755
|
+
}
|
|
756
|
+
const templates = methodology.phase_templates ?? {};
|
|
757
|
+
const phaseIds = Object.keys(templates);
|
|
758
|
+
if (phaseIds.length === 0) {
|
|
759
|
+
res.status(400).json({ error: `methodology ${methodology_id} has no phase_templates` });
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
planObj = {
|
|
763
|
+
methodology_id: methodology.id,
|
|
764
|
+
rationale: `Started via API (default phases from ${methodology.id})`,
|
|
765
|
+
phases: phaseIds.map(id => {
|
|
766
|
+
const tpl = templates[id];
|
|
767
|
+
return {
|
|
768
|
+
id,
|
|
769
|
+
agent: tpl.agent,
|
|
770
|
+
prompt: tpl.description ?? tpl.prompt_template.slice(0, 400),
|
|
771
|
+
rationale: 'default phase from methodology template',
|
|
772
|
+
};
|
|
773
|
+
}),
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
else {
|
|
777
|
+
res.status(400).json({ error: 'either methodology_id or plan must be provided' });
|
|
778
|
+
return;
|
|
779
|
+
}
|
|
780
|
+
try {
|
|
781
|
+
const id = executionManager.start({
|
|
782
|
+
session_id,
|
|
783
|
+
methodology_id: planObj.methodology_id,
|
|
784
|
+
plan: planObj,
|
|
785
|
+
mode,
|
|
786
|
+
});
|
|
787
|
+
res.status(201).json({ id, mode });
|
|
788
|
+
}
|
|
789
|
+
catch (err) {
|
|
790
|
+
logger.warn(`[web] start execution failed: ${err}`);
|
|
791
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
792
|
+
const isAuthError = err instanceof WorkerAuthError
|
|
793
|
+
|| (err instanceof Error && err.code === 'AUTH_REQUIRED')
|
|
794
|
+
|| message.includes('Background mode requires');
|
|
795
|
+
if (isAuthError) {
|
|
796
|
+
res.status(503).json({ error: message, code: 'AUTH_REQUIRED' });
|
|
797
|
+
}
|
|
798
|
+
else {
|
|
799
|
+
res.status(500).json({ error: message });
|
|
800
|
+
}
|
|
801
|
+
}
|
|
802
|
+
});
|
|
803
|
+
// Methodology Execution: SSE stream of executor events (Phase C)
|
|
804
|
+
this.app.get('/api/methodology-executions/events', (req, res) => {
|
|
805
|
+
const { executionManager } = this.options;
|
|
806
|
+
if (!executionManager) {
|
|
807
|
+
res.status(503).json({ error: 'Execution manager not available' });
|
|
808
|
+
return;
|
|
809
|
+
}
|
|
810
|
+
const filterId = req.query.execution_id ? parseInt(String(req.query.execution_id)) : null;
|
|
811
|
+
res.setHeader('Content-Type', 'text/event-stream');
|
|
812
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
813
|
+
res.setHeader('Connection', 'keep-alive');
|
|
814
|
+
res.flushHeaders();
|
|
815
|
+
const unsub = executionManager.subscribe(ev => {
|
|
816
|
+
if (filterId !== null && ev.execution_id !== filterId)
|
|
817
|
+
return;
|
|
818
|
+
try {
|
|
819
|
+
res.write(`event: ${ev.type}\ndata: ${JSON.stringify(ev)}\n\n`);
|
|
820
|
+
}
|
|
821
|
+
catch { /* client gone */ }
|
|
822
|
+
});
|
|
823
|
+
const heartbeat = setInterval(() => {
|
|
824
|
+
try {
|
|
825
|
+
res.write(`: heartbeat ${Date.now()}\n\n`);
|
|
826
|
+
}
|
|
827
|
+
catch { /* ignore */ }
|
|
828
|
+
}, 25_000);
|
|
829
|
+
req.on('close', () => {
|
|
830
|
+
clearInterval(heartbeat);
|
|
831
|
+
unsub();
|
|
832
|
+
});
|
|
833
|
+
});
|
|
714
834
|
// Methodology Execution: delete an execution
|
|
715
835
|
this.app.delete('/api/methodology-executions/:id', (req, res) => {
|
|
716
836
|
const executionId = parseInt(req.params.id);
|