clitrigger 0.1.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/.env.example +9 -0
- package/LICENSE +21 -0
- package/README.md +186 -0
- package/bin/clitrigger.js +106 -0
- package/dist/client/assets/index-BkOCv65b.css +1 -0
- package/dist/client/assets/index-Fbf16Lh1.js +129 -0
- package/dist/client/index.html +24 -0
- package/dist/server/db/connection.d.ts +4 -0
- package/dist/server/db/connection.d.ts.map +1 -0
- package/dist/server/db/connection.js +24 -0
- package/dist/server/db/connection.js.map +1 -0
- package/dist/server/db/queries.d.ts +265 -0
- package/dist/server/db/queries.d.ts.map +1 -0
- package/dist/server/db/queries.js +836 -0
- package/dist/server/db/queries.js.map +1 -0
- package/dist/server/db/schema.d.ts +3 -0
- package/dist/server/db/schema.d.ts.map +1 -0
- package/dist/server/db/schema.js +325 -0
- package/dist/server/db/schema.js.map +1 -0
- package/dist/server/index.d.ts +5 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +207 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/middleware/auth.d.ts +5 -0
- package/dist/server/middleware/auth.d.ts.map +1 -0
- package/dist/server/middleware/auth.js +45 -0
- package/dist/server/middleware/auth.js.map +1 -0
- package/dist/server/plugins/github/index.d.ts +3 -0
- package/dist/server/plugins/github/index.d.ts.map +1 -0
- package/dist/server/plugins/github/index.js +18 -0
- package/dist/server/plugins/github/index.js.map +1 -0
- package/dist/server/plugins/github/router.d.ts +4 -0
- package/dist/server/plugins/github/router.d.ts.map +1 -0
- package/dist/server/plugins/github/router.js +250 -0
- package/dist/server/plugins/github/router.js.map +1 -0
- package/dist/server/plugins/gstack/index.d.ts +3 -0
- package/dist/server/plugins/gstack/index.d.ts.map +1 -0
- package/dist/server/plugins/gstack/index.js +36 -0
- package/dist/server/plugins/gstack/index.js.map +1 -0
- package/dist/server/plugins/jira/index.d.ts +3 -0
- package/dist/server/plugins/jira/index.d.ts.map +1 -0
- package/dist/server/plugins/jira/index.js +19 -0
- package/dist/server/plugins/jira/index.js.map +1 -0
- package/dist/server/plugins/jira/router.d.ts +4 -0
- package/dist/server/plugins/jira/router.d.ts.map +1 -0
- package/dist/server/plugins/jira/router.js +332 -0
- package/dist/server/plugins/jira/router.js.map +1 -0
- package/dist/server/plugins/notion/index.d.ts +3 -0
- package/dist/server/plugins/notion/index.d.ts.map +1 -0
- package/dist/server/plugins/notion/index.js +17 -0
- package/dist/server/plugins/notion/index.js.map +1 -0
- package/dist/server/plugins/notion/router.d.ts +4 -0
- package/dist/server/plugins/notion/router.d.ts.map +1 -0
- package/dist/server/plugins/notion/router.js +313 -0
- package/dist/server/plugins/notion/router.js.map +1 -0
- package/dist/server/plugins/registry.d.ts +8 -0
- package/dist/server/plugins/registry.d.ts.map +1 -0
- package/dist/server/plugins/registry.js +31 -0
- package/dist/server/plugins/registry.js.map +1 -0
- package/dist/server/plugins/types.d.ts +32 -0
- package/dist/server/plugins/types.d.ts.map +1 -0
- package/dist/server/plugins/types.js +2 -0
- package/dist/server/plugins/types.js.map +1 -0
- package/dist/server/resources/gstack-skills/LICENSE +21 -0
- package/dist/server/resources/gstack-skills/benchmark/SKILL.md +528 -0
- package/dist/server/resources/gstack-skills/careful/SKILL.md +59 -0
- package/dist/server/resources/gstack-skills/cso/SKILL.md +898 -0
- package/dist/server/resources/gstack-skills/investigate/SKILL.md +474 -0
- package/dist/server/resources/gstack-skills/qa/SKILL.md +1055 -0
- package/dist/server/resources/gstack-skills/qa-only/SKILL.md +672 -0
- package/dist/server/resources/gstack-skills/review/SKILL.md +1044 -0
- package/dist/server/resources/gstack-skills/skills-manifest.d.ts +9 -0
- package/dist/server/resources/gstack-skills/skills-manifest.d.ts.map +1 -0
- package/dist/server/resources/gstack-skills/skills-manifest.js +52 -0
- package/dist/server/resources/gstack-skills/skills-manifest.js.map +1 -0
- package/dist/server/resources/gstack-skills/skills-manifest.ts +59 -0
- package/dist/server/routes/auth.d.ts +3 -0
- package/dist/server/routes/auth.d.ts.map +1 -0
- package/dist/server/routes/auth.js +70 -0
- package/dist/server/routes/auth.js.map +1 -0
- package/dist/server/routes/debug-logs.d.ts +3 -0
- package/dist/server/routes/debug-logs.d.ts.map +1 -0
- package/dist/server/routes/debug-logs.js +43 -0
- package/dist/server/routes/debug-logs.js.map +1 -0
- package/dist/server/routes/discussions.d.ts +3 -0
- package/dist/server/routes/discussions.d.ts.map +1 -0
- package/dist/server/routes/discussions.js +544 -0
- package/dist/server/routes/discussions.js.map +1 -0
- package/dist/server/routes/execution.d.ts +3 -0
- package/dist/server/routes/execution.d.ts.map +1 -0
- package/dist/server/routes/execution.js +339 -0
- package/dist/server/routes/execution.js.map +1 -0
- package/dist/server/routes/github.d.ts +3 -0
- package/dist/server/routes/github.d.ts.map +1 -0
- package/dist/server/routes/github.js +251 -0
- package/dist/server/routes/github.js.map +1 -0
- package/dist/server/routes/images.d.ts +17 -0
- package/dist/server/routes/images.d.ts.map +1 -0
- package/dist/server/routes/images.js +152 -0
- package/dist/server/routes/images.js.map +1 -0
- package/dist/server/routes/jira.d.ts +3 -0
- package/dist/server/routes/jira.d.ts.map +1 -0
- package/dist/server/routes/jira.js +333 -0
- package/dist/server/routes/jira.js.map +1 -0
- package/dist/server/routes/logs.d.ts +3 -0
- package/dist/server/routes/logs.d.ts.map +1 -0
- package/dist/server/routes/logs.js +156 -0
- package/dist/server/routes/logs.js.map +1 -0
- package/dist/server/routes/models.d.ts +3 -0
- package/dist/server/routes/models.d.ts.map +1 -0
- package/dist/server/routes/models.js +65 -0
- package/dist/server/routes/models.js.map +1 -0
- package/dist/server/routes/notion.d.ts +3 -0
- package/dist/server/routes/notion.d.ts.map +1 -0
- package/dist/server/routes/notion.js +312 -0
- package/dist/server/routes/notion.js.map +1 -0
- package/dist/server/routes/pipelines.d.ts +3 -0
- package/dist/server/routes/pipelines.d.ts.map +1 -0
- package/dist/server/routes/pipelines.js +315 -0
- package/dist/server/routes/pipelines.js.map +1 -0
- package/dist/server/routes/plugins.d.ts +3 -0
- package/dist/server/routes/plugins.d.ts.map +1 -0
- package/dist/server/routes/plugins.js +71 -0
- package/dist/server/routes/plugins.js.map +1 -0
- package/dist/server/routes/projects.d.ts +3 -0
- package/dist/server/routes/projects.d.ts.map +1 -0
- package/dist/server/routes/projects.js +557 -0
- package/dist/server/routes/projects.js.map +1 -0
- package/dist/server/routes/schedules.d.ts +3 -0
- package/dist/server/routes/schedules.d.ts.map +1 -0
- package/dist/server/routes/schedules.js +247 -0
- package/dist/server/routes/schedules.js.map +1 -0
- package/dist/server/routes/todos.d.ts +3 -0
- package/dist/server/routes/todos.d.ts.map +1 -0
- package/dist/server/routes/todos.js +103 -0
- package/dist/server/routes/todos.js.map +1 -0
- package/dist/server/routes/tunnel.d.ts +3 -0
- package/dist/server/routes/tunnel.d.ts.map +1 -0
- package/dist/server/routes/tunnel.js +44 -0
- package/dist/server/routes/tunnel.js.map +1 -0
- package/dist/server/services/claude-manager.d.ts +42 -0
- package/dist/server/services/claude-manager.d.ts.map +1 -0
- package/dist/server/services/claude-manager.js +275 -0
- package/dist/server/services/claude-manager.js.map +1 -0
- package/dist/server/services/cli-adapters.d.ts +35 -0
- package/dist/server/services/cli-adapters.d.ts.map +1 -0
- package/dist/server/services/cli-adapters.js +139 -0
- package/dist/server/services/cli-adapters.js.map +1 -0
- package/dist/server/services/debug-logger.d.ts +35 -0
- package/dist/server/services/debug-logger.d.ts.map +1 -0
- package/dist/server/services/debug-logger.js +168 -0
- package/dist/server/services/debug-logger.js.map +1 -0
- package/dist/server/services/discussion-orchestrator.d.ts +47 -0
- package/dist/server/services/discussion-orchestrator.d.ts.map +1 -0
- package/dist/server/services/discussion-orchestrator.js +599 -0
- package/dist/server/services/discussion-orchestrator.js.map +1 -0
- package/dist/server/services/log-streamer.d.ts +45 -0
- package/dist/server/services/log-streamer.d.ts.map +1 -0
- package/dist/server/services/log-streamer.js +348 -0
- package/dist/server/services/log-streamer.js.map +1 -0
- package/dist/server/services/orchestrator.d.ts +69 -0
- package/dist/server/services/orchestrator.d.ts.map +1 -0
- package/dist/server/services/orchestrator.js +642 -0
- package/dist/server/services/orchestrator.js.map +1 -0
- package/dist/server/services/pipeline-orchestrator.d.ts +43 -0
- package/dist/server/services/pipeline-orchestrator.d.ts.map +1 -0
- package/dist/server/services/pipeline-orchestrator.js +503 -0
- package/dist/server/services/pipeline-orchestrator.js.map +1 -0
- package/dist/server/services/prompt-guard.d.ts +19 -0
- package/dist/server/services/prompt-guard.d.ts.map +1 -0
- package/dist/server/services/prompt-guard.js +43 -0
- package/dist/server/services/prompt-guard.js.map +1 -0
- package/dist/server/services/scheduler.d.ts +43 -0
- package/dist/server/services/scheduler.d.ts.map +1 -0
- package/dist/server/services/scheduler.js +199 -0
- package/dist/server/services/scheduler.js.map +1 -0
- package/dist/server/services/skill-injector.d.ts +17 -0
- package/dist/server/services/skill-injector.d.ts.map +1 -0
- package/dist/server/services/skill-injector.js +60 -0
- package/dist/server/services/skill-injector.js.map +1 -0
- package/dist/server/services/tunnel-manager.d.ts +42 -0
- package/dist/server/services/tunnel-manager.d.ts.map +1 -0
- package/dist/server/services/tunnel-manager.js +265 -0
- package/dist/server/services/tunnel-manager.js.map +1 -0
- package/dist/server/services/worktree-manager.d.ts +117 -0
- package/dist/server/services/worktree-manager.d.ts.map +1 -0
- package/dist/server/services/worktree-manager.js +400 -0
- package/dist/server/services/worktree-manager.js.map +1 -0
- package/dist/server/websocket/broadcaster.d.ts +12 -0
- package/dist/server/websocket/broadcaster.d.ts.map +1 -0
- package/dist/server/websocket/broadcaster.js +23 -0
- package/dist/server/websocket/broadcaster.js.map +1 -0
- package/dist/server/websocket/events.d.ts +94 -0
- package/dist/server/websocket/events.d.ts.map +1 -0
- package/dist/server/websocket/events.js +2 -0
- package/dist/server/websocket/events.js.map +1 -0
- package/dist/server/websocket/index.d.ts +3 -0
- package/dist/server/websocket/index.d.ts.map +1 -0
- package/dist/server/websocket/index.js +82 -0
- package/dist/server/websocket/index.js.map +1 -0
- package/package.json +68 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export interface TokenUsage {
|
|
2
|
+
input_tokens: number | null;
|
|
3
|
+
output_tokens: number | null;
|
|
4
|
+
cache_read_input_tokens: number | null;
|
|
5
|
+
cache_creation_input_tokens: number | null;
|
|
6
|
+
total_cost: number | null;
|
|
7
|
+
duration_ms: number | null;
|
|
8
|
+
num_turns: number | null;
|
|
9
|
+
context_window: number | null;
|
|
10
|
+
}
|
|
11
|
+
export declare class LogStreamer {
|
|
12
|
+
/** Accumulated token usage per task (todoId -> TokenUsage) */
|
|
13
|
+
private tokenUsageMap;
|
|
14
|
+
/** Tracks whether context exhaustion was detected for a task */
|
|
15
|
+
private contextExhaustedMap;
|
|
16
|
+
/**
|
|
17
|
+
* Attach to a CLI process stdout/stderr and save logs to DB.
|
|
18
|
+
* Used for Gemini/Codex (plain text output).
|
|
19
|
+
* stdout -> log_type: 'output'
|
|
20
|
+
* stderr -> log_type: 'error'
|
|
21
|
+
* Also detects git commit messages in output -> log_type: 'commit'
|
|
22
|
+
*/
|
|
23
|
+
streamToDb(todoId: string, stdout: NodeJS.ReadableStream, stderr: NodeJS.ReadableStream): void;
|
|
24
|
+
/**
|
|
25
|
+
* Attach to a Claude CLI process with stream-json output.
|
|
26
|
+
* JSON lines may come via stdout or stderr depending on environment
|
|
27
|
+
* (shell: true on Windows can redirect stderr to stdout).
|
|
28
|
+
* Both streams are parsed as JSON lines.
|
|
29
|
+
*/
|
|
30
|
+
streamJsonToDb(todoId: string, stdout: NodeJS.ReadableStream, stderr: NodeJS.ReadableStream, verbose?: boolean): void;
|
|
31
|
+
/**
|
|
32
|
+
* Process a single JSON line from Claude CLI stream-json output.
|
|
33
|
+
*/
|
|
34
|
+
private processJsonLine;
|
|
35
|
+
/**
|
|
36
|
+
* Check if context exhaustion was detected for a task. Consumes the flag.
|
|
37
|
+
*/
|
|
38
|
+
isContextExhausted(todoId: string): boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Get accumulated token usage for a task and clean up.
|
|
41
|
+
*/
|
|
42
|
+
getTokenUsage(todoId: string): TokenUsage | null;
|
|
43
|
+
}
|
|
44
|
+
export declare const logStreamer: LogStreamer;
|
|
45
|
+
//# sourceMappingURL=log-streamer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-streamer.d.ts","sourceRoot":"","sources":["../../../src/server/services/log-streamer.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,uBAAuB,EAAE,MAAM,GAAG,IAAI,CAAC;IACvC,2BAA2B,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3C,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAYD,qBAAa,WAAW;IACtB,8DAA8D;IAC9D,OAAO,CAAC,aAAa,CAAsC;IAC3D,gEAAgE;IAChE,OAAO,CAAC,mBAAmB,CAAmC;IAE9D;;;;;;OAMG;IACH,UAAU,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,GAAG,IAAI;IAiH9F;;;;;OAKG;IACH,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,MAAM,CAAC,cAAc,EAAE,OAAO,GAAE,OAAe,GAAG,IAAI;IAqC5H;;OAEG;IACH,OAAO,CAAC,eAAe;IA8IvB;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAM3C;;OAEG;IACH,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;CAWjD;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
|
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
import * as queries from '../db/queries.js';
|
|
2
|
+
import { broadcaster } from '../websocket/broadcaster.js';
|
|
3
|
+
const CONTEXT_EXHAUSTION_PATTERN = /context.*(window|limit|length|exceeded)|conversation.*(too long|limit)|token.*(limit|exceeded)|max.*context|context_length_exceeded/i;
|
|
4
|
+
/** Pattern to identify genuine error lines from stderr (everything else is treated as normal output) */
|
|
5
|
+
const STDERR_ERROR_PATTERN = /^(fatal|error|Error|ERROR|FATAL)[\s:]|Permission denied|ENOENT|EACCES|exited (?:with )?(?:code |status )?[1-9]|command not found|No such file|segmentation fault/i;
|
|
6
|
+
function classifyStderrLine(line) {
|
|
7
|
+
if (STDERR_ERROR_PATTERN.test(line) || CONTEXT_EXHAUSTION_PATTERN.test(line))
|
|
8
|
+
return 'error';
|
|
9
|
+
return 'output';
|
|
10
|
+
}
|
|
11
|
+
export class LogStreamer {
|
|
12
|
+
/** Accumulated token usage per task (todoId -> TokenUsage) */
|
|
13
|
+
tokenUsageMap = new Map();
|
|
14
|
+
/** Tracks whether context exhaustion was detected for a task */
|
|
15
|
+
contextExhaustedMap = new Map();
|
|
16
|
+
/**
|
|
17
|
+
* Attach to a CLI process stdout/stderr and save logs to DB.
|
|
18
|
+
* Used for Gemini/Codex (plain text output).
|
|
19
|
+
* stdout -> log_type: 'output'
|
|
20
|
+
* stderr -> log_type: 'error'
|
|
21
|
+
* Also detects git commit messages in output -> log_type: 'commit'
|
|
22
|
+
*/
|
|
23
|
+
streamToDb(todoId, stdout, stderr) {
|
|
24
|
+
const commitPattern = /commit\s+[0-9a-f]{7,40}/i;
|
|
25
|
+
stdout.setEncoding('utf8');
|
|
26
|
+
stderr.setEncoding('utf8');
|
|
27
|
+
let stdoutBuffer = '';
|
|
28
|
+
stdout.on('data', (chunk) => {
|
|
29
|
+
stdoutBuffer += chunk;
|
|
30
|
+
const lines = stdoutBuffer.split('\n');
|
|
31
|
+
stdoutBuffer = lines.pop() || '';
|
|
32
|
+
for (const line of lines) {
|
|
33
|
+
if (!line.trim())
|
|
34
|
+
continue;
|
|
35
|
+
try {
|
|
36
|
+
if (commitPattern.test(line)) {
|
|
37
|
+
queries.createTaskLog(todoId, 'commit', line.trim());
|
|
38
|
+
const hashMatch = line.match(/[0-9a-f]{7,40}/i);
|
|
39
|
+
broadcaster.broadcast({
|
|
40
|
+
type: 'todo:commit',
|
|
41
|
+
todoId,
|
|
42
|
+
commitHash: hashMatch ? hashMatch[0] : '',
|
|
43
|
+
message: line.trim(),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
queries.createTaskLog(todoId, 'output', line.trim());
|
|
48
|
+
broadcaster.broadcast({
|
|
49
|
+
type: 'todo:log',
|
|
50
|
+
todoId,
|
|
51
|
+
message: line.trim(),
|
|
52
|
+
logType: 'output',
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
// Todo may have been deleted — skip log but don't crash
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
stdout.on('end', () => {
|
|
62
|
+
if (stdoutBuffer.trim()) {
|
|
63
|
+
try {
|
|
64
|
+
if (commitPattern.test(stdoutBuffer)) {
|
|
65
|
+
queries.createTaskLog(todoId, 'commit', stdoutBuffer.trim());
|
|
66
|
+
const hashMatch = stdoutBuffer.match(/[0-9a-f]{7,40}/i);
|
|
67
|
+
broadcaster.broadcast({
|
|
68
|
+
type: 'todo:commit',
|
|
69
|
+
todoId,
|
|
70
|
+
commitHash: hashMatch ? hashMatch[0] : '',
|
|
71
|
+
message: stdoutBuffer.trim(),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
queries.createTaskLog(todoId, 'output', stdoutBuffer.trim());
|
|
76
|
+
broadcaster.broadcast({
|
|
77
|
+
type: 'todo:log',
|
|
78
|
+
todoId,
|
|
79
|
+
message: stdoutBuffer.trim(),
|
|
80
|
+
logType: 'output',
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
// Todo may have been deleted — skip log but don't crash
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
let stderrBuffer = '';
|
|
90
|
+
stderr.on('data', (chunk) => {
|
|
91
|
+
stderrBuffer += chunk;
|
|
92
|
+
const lines = stderrBuffer.split('\n');
|
|
93
|
+
stderrBuffer = lines.pop() || '';
|
|
94
|
+
for (const line of lines) {
|
|
95
|
+
if (!line.trim())
|
|
96
|
+
continue;
|
|
97
|
+
if (CONTEXT_EXHAUSTION_PATTERN.test(line)) {
|
|
98
|
+
this.contextExhaustedMap.set(todoId, true);
|
|
99
|
+
}
|
|
100
|
+
const logType = classifyStderrLine(line.trim());
|
|
101
|
+
try {
|
|
102
|
+
queries.createTaskLog(todoId, logType, line.trim());
|
|
103
|
+
broadcaster.broadcast({
|
|
104
|
+
type: 'todo:log',
|
|
105
|
+
todoId,
|
|
106
|
+
message: line.trim(),
|
|
107
|
+
logType,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Todo may have been deleted — skip log but don't crash
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
});
|
|
115
|
+
stderr.on('end', () => {
|
|
116
|
+
if (stderrBuffer.trim()) {
|
|
117
|
+
if (CONTEXT_EXHAUSTION_PATTERN.test(stderrBuffer)) {
|
|
118
|
+
this.contextExhaustedMap.set(todoId, true);
|
|
119
|
+
}
|
|
120
|
+
const logType = classifyStderrLine(stderrBuffer.trim());
|
|
121
|
+
try {
|
|
122
|
+
queries.createTaskLog(todoId, logType, stderrBuffer.trim());
|
|
123
|
+
broadcaster.broadcast({
|
|
124
|
+
type: 'todo:log',
|
|
125
|
+
todoId,
|
|
126
|
+
message: stderrBuffer.trim(),
|
|
127
|
+
logType,
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
// Todo may have been deleted — skip log but don't crash
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Attach to a Claude CLI process with stream-json output.
|
|
138
|
+
* JSON lines may come via stdout or stderr depending on environment
|
|
139
|
+
* (shell: true on Windows can redirect stderr to stdout).
|
|
140
|
+
* Both streams are parsed as JSON lines.
|
|
141
|
+
*/
|
|
142
|
+
streamJsonToDb(todoId, stdout, stderr, verbose = false) {
|
|
143
|
+
const commitPattern = /commit\s+[0-9a-f]{7,40}/i;
|
|
144
|
+
// Initialize token usage accumulator
|
|
145
|
+
this.tokenUsageMap.set(todoId, {
|
|
146
|
+
input_tokens: null, output_tokens: null,
|
|
147
|
+
cache_read_input_tokens: null, cache_creation_input_tokens: null,
|
|
148
|
+
total_cost: null, duration_ms: null, num_turns: null,
|
|
149
|
+
context_window: null,
|
|
150
|
+
});
|
|
151
|
+
stdout.setEncoding('utf8');
|
|
152
|
+
stderr.setEncoding('utf8');
|
|
153
|
+
// Helper to wire up JSON line parsing on a stream
|
|
154
|
+
const attachJsonParser = (stream) => {
|
|
155
|
+
let buffer = '';
|
|
156
|
+
stream.on('data', (chunk) => {
|
|
157
|
+
buffer += chunk;
|
|
158
|
+
const lines = buffer.split('\n');
|
|
159
|
+
buffer = lines.pop() || '';
|
|
160
|
+
for (const line of lines) {
|
|
161
|
+
if (!line.trim())
|
|
162
|
+
continue;
|
|
163
|
+
this.processJsonLine(todoId, line.trim(), commitPattern, verbose);
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
stream.on('end', () => {
|
|
167
|
+
if (buffer.trim()) {
|
|
168
|
+
this.processJsonLine(todoId, buffer.trim(), commitPattern, verbose);
|
|
169
|
+
}
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
attachJsonParser(stdout);
|
|
173
|
+
attachJsonParser(stderr);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Process a single JSON line from Claude CLI stream-json output.
|
|
177
|
+
*/
|
|
178
|
+
processJsonLine(todoId, line, commitPattern, verbose = false) {
|
|
179
|
+
let event;
|
|
180
|
+
try {
|
|
181
|
+
event = JSON.parse(line);
|
|
182
|
+
}
|
|
183
|
+
catch {
|
|
184
|
+
// Not valid JSON — log as raw error (fallback)
|
|
185
|
+
if (CONTEXT_EXHAUSTION_PATTERN.test(line)) {
|
|
186
|
+
this.contextExhaustedMap.set(todoId, true);
|
|
187
|
+
}
|
|
188
|
+
try {
|
|
189
|
+
queries.createTaskLog(todoId, 'error', line);
|
|
190
|
+
broadcaster.broadcast({ type: 'todo:log', todoId, message: line, logType: 'error' });
|
|
191
|
+
}
|
|
192
|
+
catch { /* ignore */ }
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
try {
|
|
196
|
+
switch (event.type) {
|
|
197
|
+
case 'assistant': {
|
|
198
|
+
// Extract response text from message.content[0].text
|
|
199
|
+
const message = event.message;
|
|
200
|
+
const content = message?.content;
|
|
201
|
+
if (content) {
|
|
202
|
+
for (const block of content) {
|
|
203
|
+
if (block.type === 'text' && typeof block.text === 'string') {
|
|
204
|
+
const text = block.text.trim();
|
|
205
|
+
if (!text)
|
|
206
|
+
break;
|
|
207
|
+
// Split into lines for commit detection and readable logging
|
|
208
|
+
const textLines = text.split('\n');
|
|
209
|
+
for (const textLine of textLines) {
|
|
210
|
+
if (!textLine.trim())
|
|
211
|
+
continue;
|
|
212
|
+
if (commitPattern.test(textLine)) {
|
|
213
|
+
queries.createTaskLog(todoId, 'commit', textLine.trim());
|
|
214
|
+
const hashMatch = textLine.match(/[0-9a-f]{7,40}/i);
|
|
215
|
+
broadcaster.broadcast({
|
|
216
|
+
type: 'todo:commit',
|
|
217
|
+
todoId,
|
|
218
|
+
commitHash: hashMatch ? hashMatch[0] : '',
|
|
219
|
+
message: textLine.trim(),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
queries.createTaskLog(todoId, 'output', textLine.trim());
|
|
224
|
+
broadcaster.broadcast({
|
|
225
|
+
type: 'todo:log',
|
|
226
|
+
todoId,
|
|
227
|
+
message: textLine.trim(),
|
|
228
|
+
logType: 'output',
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
else if (block.type === 'tool_use') {
|
|
234
|
+
// Log tool usage for visibility
|
|
235
|
+
const toolName = block.name || 'unknown';
|
|
236
|
+
let logMsg = `[Tool: ${toolName}]`;
|
|
237
|
+
if (verbose && block.input) {
|
|
238
|
+
const inputStr = JSON.stringify(block.input, null, 2);
|
|
239
|
+
logMsg += ` input: ${inputStr.length > 2000 ? inputStr.slice(0, 2000) + '...' : inputStr}`;
|
|
240
|
+
}
|
|
241
|
+
queries.createTaskLog(todoId, 'output', logMsg);
|
|
242
|
+
broadcaster.broadcast({ type: 'todo:log', todoId, message: logMsg, logType: 'output' });
|
|
243
|
+
}
|
|
244
|
+
else if (verbose && block.type === 'tool_result') {
|
|
245
|
+
const content = typeof block.content === 'string' ? block.content : JSON.stringify(block.content);
|
|
246
|
+
const logMsg = `[Result] ${content.length > 2000 ? content.slice(0, 2000) + '...' : content}`;
|
|
247
|
+
queries.createTaskLog(todoId, 'output', logMsg);
|
|
248
|
+
broadcaster.broadcast({ type: 'todo:log', todoId, message: logMsg, logType: 'output' });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
case 'error': {
|
|
255
|
+
// Check for context exhaustion in error events
|
|
256
|
+
const errorMsg = typeof event.error === 'string' ? event.error
|
|
257
|
+
: typeof event.message === 'string' ? event.message
|
|
258
|
+
: JSON.stringify(event);
|
|
259
|
+
if (CONTEXT_EXHAUSTION_PATTERN.test(errorMsg)) {
|
|
260
|
+
this.contextExhaustedMap.set(todoId, true);
|
|
261
|
+
}
|
|
262
|
+
try {
|
|
263
|
+
queries.createTaskLog(todoId, 'error', errorMsg);
|
|
264
|
+
broadcaster.broadcast({ type: 'todo:log', todoId, message: errorMsg, logType: 'error' });
|
|
265
|
+
}
|
|
266
|
+
catch { /* ignore */ }
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
case 'result': {
|
|
270
|
+
// Check if result indicates an error related to context
|
|
271
|
+
if (event.is_error) {
|
|
272
|
+
const resultText = typeof event.result === 'string' ? event.result : '';
|
|
273
|
+
if (CONTEXT_EXHAUSTION_PATTERN.test(resultText)) {
|
|
274
|
+
this.contextExhaustedMap.set(todoId, true);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
// Extract token usage data
|
|
278
|
+
const usage = this.tokenUsageMap.get(todoId);
|
|
279
|
+
if (usage) {
|
|
280
|
+
const apiUsage = event.usage;
|
|
281
|
+
if (apiUsage) {
|
|
282
|
+
usage.input_tokens = typeof apiUsage.input_tokens === 'number' ? apiUsage.input_tokens : null;
|
|
283
|
+
usage.output_tokens = typeof apiUsage.output_tokens === 'number' ? apiUsage.output_tokens : null;
|
|
284
|
+
usage.cache_read_input_tokens = typeof apiUsage.cache_read_input_tokens === 'number' ? apiUsage.cache_read_input_tokens : null;
|
|
285
|
+
usage.cache_creation_input_tokens = typeof apiUsage.cache_creation_input_tokens === 'number' ? apiUsage.cache_creation_input_tokens : null;
|
|
286
|
+
}
|
|
287
|
+
usage.total_cost = typeof event.total_cost_usd === 'number' ? event.total_cost_usd : null;
|
|
288
|
+
usage.duration_ms = typeof event.duration_ms === 'number' ? event.duration_ms : null;
|
|
289
|
+
usage.num_turns = typeof event.num_turns === 'number' ? event.num_turns : null;
|
|
290
|
+
// Extract contextWindow from modelUsage (first model entry)
|
|
291
|
+
const modelUsage = event.modelUsage;
|
|
292
|
+
if (modelUsage) {
|
|
293
|
+
const firstModel = Object.values(modelUsage)[0];
|
|
294
|
+
if (firstModel && typeof firstModel.contextWindow === 'number') {
|
|
295
|
+
usage.context_window = firstModel.contextWindow;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
break;
|
|
300
|
+
}
|
|
301
|
+
default:
|
|
302
|
+
if (verbose) {
|
|
303
|
+
const eventType = String(event.type || 'unknown');
|
|
304
|
+
let logMsg;
|
|
305
|
+
if (eventType === 'system') {
|
|
306
|
+
const msg = typeof event.message === 'string' ? event.message : JSON.stringify(event);
|
|
307
|
+
logMsg = `[System] ${msg}`;
|
|
308
|
+
}
|
|
309
|
+
else {
|
|
310
|
+
const summary = JSON.stringify(event);
|
|
311
|
+
logMsg = `[${eventType}] ${summary.length > 2000 ? summary.slice(0, 2000) + '...' : summary}`;
|
|
312
|
+
}
|
|
313
|
+
queries.createTaskLog(todoId, 'output', logMsg);
|
|
314
|
+
broadcaster.broadcast({ type: 'todo:log', todoId, message: logMsg, logType: 'output' });
|
|
315
|
+
}
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
// Parsing failure — ignore to keep streaming
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
/**
|
|
324
|
+
* Check if context exhaustion was detected for a task. Consumes the flag.
|
|
325
|
+
*/
|
|
326
|
+
isContextExhausted(todoId) {
|
|
327
|
+
const exhausted = this.contextExhaustedMap.get(todoId) ?? false;
|
|
328
|
+
this.contextExhaustedMap.delete(todoId);
|
|
329
|
+
return exhausted;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Get accumulated token usage for a task and clean up.
|
|
333
|
+
*/
|
|
334
|
+
getTokenUsage(todoId) {
|
|
335
|
+
const usage = this.tokenUsageMap.get(todoId);
|
|
336
|
+
if (!usage)
|
|
337
|
+
return null;
|
|
338
|
+
this.tokenUsageMap.delete(todoId);
|
|
339
|
+
this.contextExhaustedMap.delete(todoId);
|
|
340
|
+
// Return null if nothing was parsed
|
|
341
|
+
if (usage.input_tokens === null && usage.output_tokens === null && usage.total_cost === null) {
|
|
342
|
+
return null;
|
|
343
|
+
}
|
|
344
|
+
return usage;
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
export const logStreamer = new LogStreamer();
|
|
348
|
+
//# sourceMappingURL=log-streamer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log-streamer.js","sourceRoot":"","sources":["../../../src/server/services/log-streamer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { type ClaudeMode } from './claude-manager.js';
|
|
2
|
+
export declare class Orchestrator {
|
|
3
|
+
private staleCheckTimer;
|
|
4
|
+
/**
|
|
5
|
+
* Start periodic process liveness check.
|
|
6
|
+
* Detects tasks stuck in 'running' state whose process has already exited.
|
|
7
|
+
*/
|
|
8
|
+
startStaleProcessChecker(): void;
|
|
9
|
+
stopStaleProcessChecker(): void;
|
|
10
|
+
/**
|
|
11
|
+
* Find tasks marked 'running' whose process is no longer alive, and mark them as failed.
|
|
12
|
+
*/
|
|
13
|
+
private recoverStaleTasks;
|
|
14
|
+
private isProcessAlive;
|
|
15
|
+
/**
|
|
16
|
+
* Get the max concurrent setting for a project.
|
|
17
|
+
*/
|
|
18
|
+
private getMaxConcurrent;
|
|
19
|
+
/**
|
|
20
|
+
* Broadcast the current project status summary via WebSocket.
|
|
21
|
+
*/
|
|
22
|
+
private broadcastProjectStatus;
|
|
23
|
+
/**
|
|
24
|
+
* Start all pending todos for a project.
|
|
25
|
+
* Respects maxConcurrent limit. When a Claude process exits,
|
|
26
|
+
* the next queued todo is started automatically.
|
|
27
|
+
*/
|
|
28
|
+
startProject(projectId: string): Promise<void>;
|
|
29
|
+
/**
|
|
30
|
+
* Stop all running todos for a project.
|
|
31
|
+
* Keeps worktrees so users can inspect results.
|
|
32
|
+
*/
|
|
33
|
+
stopProject(projectId: string): Promise<void>;
|
|
34
|
+
/**
|
|
35
|
+
* Start a single todo by ID. If the todo has unsatisfied dependencies,
|
|
36
|
+
* automatically starts the topmost ancestor first and auto-chains down.
|
|
37
|
+
*/
|
|
38
|
+
startTodo(todoId: string, mode?: ClaudeMode): Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* Stop a single todo by ID.
|
|
41
|
+
*/
|
|
42
|
+
stopTodo(todoId: string): Promise<void>;
|
|
43
|
+
/**
|
|
44
|
+
* Internal: start a single todo with all the setup.
|
|
45
|
+
*/
|
|
46
|
+
private startSingleTodo;
|
|
47
|
+
/**
|
|
48
|
+
* Restart a task with the next CLI tool in the fallback chain after context exhaustion.
|
|
49
|
+
* Preserves the worktree and clears logs before restarting.
|
|
50
|
+
*/
|
|
51
|
+
private restartWithNextCli;
|
|
52
|
+
/**
|
|
53
|
+
* Check if a task's dependency is satisfied (no depends_on, or depends_on task is completed).
|
|
54
|
+
*/
|
|
55
|
+
private isDependencySatisfied;
|
|
56
|
+
/**
|
|
57
|
+
* Walk the depends_on chain upward and return unsatisfied ancestors (root-first order).
|
|
58
|
+
* Stops at a completed or running ancestor. Detects circular dependencies.
|
|
59
|
+
*/
|
|
60
|
+
private getUnsatisfiedAncestorChain;
|
|
61
|
+
/**
|
|
62
|
+
* Start pending children that directly depend on a completed parent task.
|
|
63
|
+
* Only starts tasks whose depends_on matches the given parentTodoId,
|
|
64
|
+
* preventing unrelated pending tasks from being auto-started.
|
|
65
|
+
*/
|
|
66
|
+
private startDependentChildren;
|
|
67
|
+
}
|
|
68
|
+
export declare const orchestrator: Orchestrator;
|
|
69
|
+
//# sourceMappingURL=orchestrator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.d.ts","sourceRoot":"","sources":["../../../src/server/services/orchestrator.ts"],"names":[],"mappings":"AAGA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAcrE,qBAAa,YAAY;IACvB,OAAO,CAAC,eAAe,CAA+C;IAEtE;;;OAGG;IACH,wBAAwB,IAAI,IAAI;IAKhC,uBAAuB,IAAI,IAAI;IAO/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAgBzB,OAAO,CAAC,cAAc;IAStB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAOxB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAa9B;;;;OAIG;IACG,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BpD;;;OAGG;IACG,WAAW,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASnD;;;OAGG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,GAAE,UAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAsC7E;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAkB7C;;OAEG;YACW,eAAe;IAoX7B;;;OAGG;YACW,kBAAkB;IAsDhC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAM7B;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IAuBnC;;;;OAIG;YACW,sBAAsB;CAoBrC;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
|