nightshift-mcp 2.0.1 → 2.1.1

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 (50) hide show
  1. package/README.md +46 -15
  2. package/dist/agent-spawner.d.ts +9 -0
  3. package/dist/agent-spawner.d.ts.map +1 -1
  4. package/dist/agent-spawner.js +88 -5
  5. package/dist/agent-spawner.js.map +1 -1
  6. package/dist/daemon.d.ts +19 -5
  7. package/dist/daemon.d.ts.map +1 -1
  8. package/dist/daemon.js +220 -36
  9. package/dist/daemon.js.map +1 -1
  10. package/dist/database.d.ts +2 -2
  11. package/dist/database.d.ts.map +1 -1
  12. package/dist/database.js +4 -4
  13. package/dist/database.js.map +1 -1
  14. package/dist/index.js +219 -1146
  15. package/dist/index.js.map +1 -1
  16. package/dist/orchestrator.d.ts +12 -1
  17. package/dist/orchestrator.d.ts.map +1 -1
  18. package/dist/orchestrator.js +245 -15
  19. package/dist/orchestrator.js.map +1 -1
  20. package/dist/pipeline.d.ts +61 -0
  21. package/dist/pipeline.d.ts.map +1 -0
  22. package/dist/pipeline.js +227 -0
  23. package/dist/pipeline.js.map +1 -0
  24. package/dist/project-context.d.ts +28 -0
  25. package/dist/project-context.d.ts.map +1 -0
  26. package/dist/project-context.js +45 -0
  27. package/dist/project-context.js.map +1 -0
  28. package/dist/run-logger.d.ts +61 -0
  29. package/dist/run-logger.d.ts.map +1 -0
  30. package/dist/run-logger.js +219 -0
  31. package/dist/run-logger.js.map +1 -0
  32. package/dist/tools/agents.d.ts +3 -0
  33. package/dist/tools/agents.d.ts.map +1 -1
  34. package/dist/tools/agents.js +148 -5
  35. package/dist/tools/agents.js.map +1 -1
  36. package/dist/tools/bugs.d.ts.map +1 -1
  37. package/dist/tools/bugs.js +48 -22
  38. package/dist/tools/bugs.js.map +1 -1
  39. package/dist/tools/chat.d.ts.map +1 -1
  40. package/dist/tools/chat.js +47 -20
  41. package/dist/tools/chat.js.map +1 -1
  42. package/dist/tools/prd.d.ts.map +1 -1
  43. package/dist/tools/prd.js +67 -31
  44. package/dist/tools/prd.js.map +1 -1
  45. package/dist/tools/progress.d.ts.map +1 -1
  46. package/dist/tools/progress.js +22 -7
  47. package/dist/tools/progress.js.map +1 -1
  48. package/dist/tools/utility.js +2 -2
  49. package/dist/tools/utility.js.map +1 -1
  50. package/package.json +1 -1
@@ -0,0 +1,227 @@
1
+ /**
2
+ * NightShift Pipeline Configuration
3
+ *
4
+ * Defines agent pipelines for story execution.
5
+ * Zero config required — auto-detects available agents and uses smart defaults.
6
+ * Users can customize via set_pipeline tool or nightshift.config.json.
7
+ */
8
+ import * as fs from "fs";
9
+ import * as path from "path";
10
+ import { canAgentRun } from "./agent-spawner.js";
11
+ // ============================================
12
+ // Built-in Defaults
13
+ // ============================================
14
+ const DEFAULT_PIPELINES = {
15
+ pipelines: {
16
+ default: [
17
+ { agent: "gemini", role: "planner", optional: true, timeout: 600 },
18
+ { agent: "codex", role: "implementer", optional: false, timeout: 900 },
19
+ { agent: "claude", role: "verifier", optional: true, timeout: 120 },
20
+ ],
21
+ frontend: [
22
+ { agent: "gemini", role: "planner", optional: true, timeout: 600 },
23
+ { agent: "codex", role: "implementer", optional: false, timeout: 900 },
24
+ { agent: "claude", role: "verifier", optional: true, timeout: 120 },
25
+ ],
26
+ backend: [
27
+ { agent: "ollama", role: "drafter", optional: true, timeout: 300 },
28
+ { agent: "codex", role: "implementer", optional: false, timeout: 900 },
29
+ { agent: "claude", role: "verifier", optional: true, timeout: 120 },
30
+ ],
31
+ research: [
32
+ { agent: "gemini", role: "researcher", optional: false, timeout: 600 },
33
+ ],
34
+ quick: [
35
+ { agent: "codex", role: "implementer", optional: false, timeout: 600 },
36
+ ],
37
+ },
38
+ tagRouting: {
39
+ frontend: "frontend",
40
+ ui: "frontend",
41
+ react: "frontend",
42
+ css: "frontend",
43
+ api: "backend",
44
+ backend: "backend",
45
+ database: "backend",
46
+ db: "backend",
47
+ research: "research",
48
+ analysis: "research",
49
+ quick: "quick",
50
+ hotfix: "quick",
51
+ },
52
+ };
53
+ // ============================================
54
+ // Config File Management
55
+ // ============================================
56
+ const CONFIG_FILENAME = "nightshift.config.json";
57
+ /**
58
+ * Load pipeline config. Merges: defaults → config file → runtime overrides.
59
+ */
60
+ export function loadPipelineConfig(projectPath) {
61
+ const configFile = path.join(projectPath, CONFIG_FILENAME);
62
+ // Start with defaults
63
+ let config = JSON.parse(JSON.stringify(DEFAULT_PIPELINES));
64
+ // Merge config file if it exists
65
+ if (fs.existsSync(configFile)) {
66
+ try {
67
+ const fileConfig = JSON.parse(fs.readFileSync(configFile, "utf-8"));
68
+ // Merge pipelines (file overrides defaults, doesn't replace all)
69
+ if (fileConfig.pipelines) {
70
+ config.pipelines = { ...config.pipelines, ...fileConfig.pipelines };
71
+ }
72
+ if (fileConfig.tagRouting) {
73
+ config.tagRouting = { ...config.tagRouting, ...fileConfig.tagRouting };
74
+ }
75
+ }
76
+ catch {
77
+ // Bad config file — use defaults silently
78
+ }
79
+ }
80
+ // Check for runtime override in .robot-chat
81
+ const runtimeFile = path.join(projectPath, ".robot-chat", "pipeline-override.json");
82
+ if (fs.existsSync(runtimeFile)) {
83
+ try {
84
+ const runtimeConfig = JSON.parse(fs.readFileSync(runtimeFile, "utf-8"));
85
+ if (runtimeConfig.pipelines) {
86
+ config.pipelines = { ...config.pipelines, ...runtimeConfig.pipelines };
87
+ }
88
+ if (runtimeConfig.tagRouting) {
89
+ config.tagRouting = { ...config.tagRouting, ...runtimeConfig.tagRouting };
90
+ }
91
+ }
92
+ catch {
93
+ // Bad runtime file — ignore
94
+ }
95
+ }
96
+ return config;
97
+ }
98
+ /**
99
+ * Save a runtime pipeline override (persists across tool calls but not across projects).
100
+ */
101
+ export function savePipelineOverride(projectPath, overrides) {
102
+ const dir = path.join(projectPath, ".robot-chat");
103
+ if (!fs.existsSync(dir)) {
104
+ fs.mkdirSync(dir, { recursive: true });
105
+ }
106
+ const runtimeFile = path.join(dir, "pipeline-override.json");
107
+ // Load existing overrides and merge
108
+ let existing = {};
109
+ if (fs.existsSync(runtimeFile)) {
110
+ try {
111
+ existing = JSON.parse(fs.readFileSync(runtimeFile, "utf-8"));
112
+ }
113
+ catch { /* ignore */ }
114
+ }
115
+ const merged = {
116
+ pipelines: { ...existing.pipelines, ...overrides.pipelines },
117
+ tagRouting: { ...existing.tagRouting, ...overrides.tagRouting },
118
+ };
119
+ fs.writeFileSync(runtimeFile, JSON.stringify(merged, null, 2), "utf-8");
120
+ }
121
+ /**
122
+ * Clear runtime pipeline overrides (revert to defaults + config file).
123
+ */
124
+ export function clearPipelineOverride(projectPath) {
125
+ const runtimeFile = path.join(projectPath, ".robot-chat", "pipeline-override.json");
126
+ if (fs.existsSync(runtimeFile)) {
127
+ fs.unlinkSync(runtimeFile);
128
+ }
129
+ }
130
+ // ============================================
131
+ // Pipeline Resolution
132
+ // ============================================
133
+ /**
134
+ * Pick the right pipeline for a story based on its tags.
135
+ * Falls back to "default" if no tags match.
136
+ */
137
+ export function resolvePipelineName(config, storyTags) {
138
+ if (!storyTags || storyTags.length === 0 || !config.tagRouting) {
139
+ return "default";
140
+ }
141
+ // Check each tag against routing rules
142
+ for (const tag of storyTags) {
143
+ const normalizedTag = tag.toLowerCase().trim();
144
+ const pipelineName = config.tagRouting[normalizedTag];
145
+ if (pipelineName && config.pipelines[pipelineName]) {
146
+ return pipelineName;
147
+ }
148
+ }
149
+ return "default";
150
+ }
151
+ /**
152
+ * Get the executable pipeline for a story — filters out unavailable agents.
153
+ * Returns only steps that can actually run right now.
154
+ */
155
+ export async function resolveExecutablePipeline(projectPath, storyTags, pipelineName) {
156
+ const config = loadPipelineConfig(projectPath);
157
+ // Resolve which pipeline to use
158
+ const name = pipelineName || resolvePipelineName(config, storyTags);
159
+ const pipeline = config.pipelines[name] || config.pipelines["default"];
160
+ if (!pipeline) {
161
+ return { name, steps: [], skipped: [] };
162
+ }
163
+ // Check agent availability
164
+ const steps = [];
165
+ const skipped = [];
166
+ for (const step of pipeline) {
167
+ const status = await canAgentRun(step.agent);
168
+ if (status.canRun) {
169
+ steps.push(step);
170
+ }
171
+ else if (step.optional !== false) {
172
+ // Optional step, skip silently
173
+ skipped.push({ agent: step.agent, role: step.role, reason: status.reason || "not available" });
174
+ }
175
+ else {
176
+ // Required step not available — try to find a substitute
177
+ const substitute = await findSubstitute(step);
178
+ if (substitute) {
179
+ steps.push({ ...step, agent: substitute });
180
+ skipped.push({ agent: step.agent, role: step.role, reason: `substituted with ${substitute}` });
181
+ }
182
+ else {
183
+ skipped.push({ agent: step.agent, role: step.role, reason: status.reason || "not available (required, no substitute)" });
184
+ }
185
+ }
186
+ }
187
+ return { name, steps, skipped };
188
+ }
189
+ /**
190
+ * Find a substitute agent for a required step that can't run.
191
+ */
192
+ async function findSubstitute(step) {
193
+ // Substitution preferences by role
194
+ const substitutions = {
195
+ planner: ["claude", "ollama"],
196
+ drafter: ["gemini", "claude"],
197
+ implementer: ["claude", "vibe", "ollama"],
198
+ verifier: ["codex", "gemini"],
199
+ reviewer: ["claude", "gemini"],
200
+ researcher: ["claude", "ollama"],
201
+ fixer: ["claude", "codex"],
202
+ };
203
+ const candidates = substitutions[step.role] || ["claude", "codex", "gemini"];
204
+ for (const candidate of candidates) {
205
+ if (candidate === step.agent)
206
+ continue; // already failed
207
+ const status = await canAgentRun(candidate);
208
+ if (status.canRun)
209
+ return candidate;
210
+ }
211
+ return null;
212
+ }
213
+ /**
214
+ * Get all available pipeline names and their steps.
215
+ */
216
+ export function listPipelines(projectPath) {
217
+ const config = loadPipelineConfig(projectPath);
218
+ return config.pipelines;
219
+ }
220
+ /**
221
+ * Get the tag routing rules.
222
+ */
223
+ export function getTagRouting(projectPath) {
224
+ const config = loadPipelineConfig(projectPath);
225
+ return config.tagRouting || {};
226
+ }
227
+ //# sourceMappingURL=pipeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pipeline.js","sourceRoot":"","sources":["../src/pipeline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import { ChatManager } from "./chat-manager.js";
2
+ import { RalphManager } from "./ralph-manager.js";
3
+ import { WorkflowManager } from "./workflow-manager.js";
4
+ import { ContextStore } from "./context-store.js";
5
+ import { TraceManager } from "./trace-manager.js";
6
+ export interface ProjectManagers {
7
+ projectPath: string;
8
+ chatManager: ChatManager;
9
+ ralphManager: RalphManager;
10
+ workflowManager: WorkflowManager;
11
+ contextStore: ContextStore;
12
+ traceManager: TraceManager;
13
+ }
14
+ export interface ProjectFilesReport {
15
+ prdJson: boolean;
16
+ progressTxt: boolean;
17
+ bugsJson: boolean;
18
+ gitignore: boolean;
19
+ robotChatDir: boolean;
20
+ chatTxt: boolean;
21
+ workflowJson: boolean;
22
+ contextDir: boolean;
23
+ traceJson: boolean;
24
+ }
25
+ export declare function validateProjectPath(projectPath: string): string;
26
+ export declare function getProjectFilesReport(projectPath: string): ProjectFilesReport;
27
+ export declare function createProjectManagers(projectPath: string): ProjectManagers;
28
+ //# sourceMappingURL=project-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context.d.ts","sourceRoot":"","sources":["../src/project-context.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,WAAW,CAAC;IACzB,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,EAAE,eAAe,CAAC;IACjC,YAAY,EAAE,YAAY,CAAC;IAC3B,YAAY,EAAE,YAAY,CAAC;CAC5B;AAED,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,OAAO,CAAC;IACjB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,EAAE,OAAO,CAAC;IACnB,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,OAAO,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAa/D;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,kBAAkB,CAe7E;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,CAW1E"}
@@ -0,0 +1,45 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ import { ChatManager } from "./chat-manager.js";
4
+ import { RalphManager } from "./ralph-manager.js";
5
+ import { WorkflowManager } from "./workflow-manager.js";
6
+ import { ContextStore } from "./context-store.js";
7
+ import { TraceManager } from "./trace-manager.js";
8
+ export function validateProjectPath(projectPath) {
9
+ const resolvedPath = path.resolve(projectPath);
10
+ if (!fs.existsSync(resolvedPath)) {
11
+ throw new Error(`Project path does not exist: ${resolvedPath}`);
12
+ }
13
+ const stat = fs.statSync(resolvedPath);
14
+ if (!stat.isDirectory()) {
15
+ throw new Error(`Project path is not a directory: ${resolvedPath}`);
16
+ }
17
+ return resolvedPath;
18
+ }
19
+ export function getProjectFilesReport(projectPath) {
20
+ const resolvedPath = validateProjectPath(projectPath);
21
+ const robotChatDir = path.join(resolvedPath, ".robot-chat");
22
+ return {
23
+ prdJson: fs.existsSync(path.join(resolvedPath, "prd.json")),
24
+ progressTxt: fs.existsSync(path.join(resolvedPath, "progress.txt")),
25
+ bugsJson: fs.existsSync(path.join(resolvedPath, "bugs.json")),
26
+ gitignore: fs.existsSync(path.join(resolvedPath, ".gitignore")),
27
+ robotChatDir: fs.existsSync(robotChatDir),
28
+ chatTxt: fs.existsSync(path.join(robotChatDir, "chat.txt")),
29
+ workflowJson: fs.existsSync(path.join(robotChatDir, "workflow.json")),
30
+ contextDir: fs.existsSync(path.join(robotChatDir, "context")),
31
+ traceJson: fs.existsSync(path.join(robotChatDir, "trace.json")),
32
+ };
33
+ }
34
+ export function createProjectManagers(projectPath) {
35
+ const resolvedPath = validateProjectPath(projectPath);
36
+ return {
37
+ projectPath: resolvedPath,
38
+ chatManager: new ChatManager(resolvedPath),
39
+ ralphManager: new RalphManager(resolvedPath),
40
+ workflowManager: new WorkflowManager(resolvedPath),
41
+ contextStore: new ContextStore(resolvedPath),
42
+ traceManager: new TraceManager(resolvedPath),
43
+ };
44
+ }
45
+ //# sourceMappingURL=project-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"project-context.js","sourceRoot":"","sources":["../src/project-context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAuBlD,MAAM,UAAU,mBAAmB,CAAC,WAAmB;IACrD,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAE/C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,gCAAgC,YAAY,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IACvC,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,oCAAoC,YAAY,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,MAAM,YAAY,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IACtD,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC;IAE5D,OAAO;QACL,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC3D,WAAW,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;QACnE,QAAQ,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QAC7D,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAC/D,YAAY,EAAE,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;QACzC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QAC3D,YAAY,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,eAAe,CAAC,CAAC;QACrE,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;QAC7D,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;KAChE,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,WAAmB;IACvD,MAAM,YAAY,GAAG,mBAAmB,CAAC,WAAW,CAAC,CAAC;IAEtD,OAAO;QACL,WAAW,EAAE,YAAY;QACzB,WAAW,EAAE,IAAI,WAAW,CAAC,YAAY,CAAC;QAC1C,YAAY,EAAE,IAAI,YAAY,CAAC,YAAY,CAAC;QAC5C,eAAe,EAAE,IAAI,eAAe,CAAC,YAAY,CAAC;QAClD,YAAY,EAAE,IAAI,YAAY,CAAC,YAAY,CAAC;QAC5C,YAAY,EAAE,IAAI,YAAY,CAAC,YAAY,CAAC;KAC7C,CAAC;AACJ,CAAC"}
@@ -0,0 +1,61 @@
1
+ import type { AgentType } from "./agent-spawner.js";
2
+ export interface RunLogEntry {
3
+ timestamp: string;
4
+ agent: AgentType;
5
+ role?: string;
6
+ storyId?: string;
7
+ duration_seconds: number;
8
+ status: "completed" | "failed" | "rate_limited" | "timeout";
9
+ exitCode: number | null;
10
+ tokens?: TokenUsage;
11
+ rateLimitInfo?: RateLimitInfo;
12
+ toolsUsed?: string[];
13
+ }
14
+ export interface TokenUsage {
15
+ input?: number;
16
+ output?: number;
17
+ total?: number;
18
+ model?: string;
19
+ cost_estimate_usd?: number;
20
+ }
21
+ export interface RateLimitInfo {
22
+ detected: boolean;
23
+ retryAfter?: number;
24
+ provider?: string;
25
+ }
26
+ /**
27
+ * Parse token usage from agent output. Each agent reports differently.
28
+ */
29
+ export declare function parseTokensFromOutput(agent: AgentType, output: string): TokenUsage | undefined;
30
+ /**
31
+ * Detect rate limiting from agent output.
32
+ */
33
+ export declare function detectRateLimit(output: string): RateLimitInfo | undefined;
34
+ /**
35
+ * Parse tool/command usage from agent output.
36
+ * Detects MCP tool calls, shell commands, file operations, etc.
37
+ */
38
+ export declare function parseToolsUsed(output: string): string[] | undefined;
39
+ /**
40
+ * Append a run log entry to the project's runs.jsonl file.
41
+ */
42
+ export declare function appendRunLog(projectPath: string, entry: RunLogEntry): void;
43
+ /**
44
+ * Read all run log entries from the project's runs.jsonl file.
45
+ */
46
+ export declare function readRunLog(projectPath: string, limit?: number): RunLogEntry[];
47
+ /**
48
+ * Get aggregate stats from the run log.
49
+ */
50
+ export declare function getRunStats(projectPath: string): {
51
+ totalRuns: number;
52
+ byAgent: Record<string, {
53
+ runs: number;
54
+ totalTokens: number;
55
+ avgDuration: number;
56
+ }>;
57
+ totalTokens: number;
58
+ totalDuration: number;
59
+ rateLimitCount: number;
60
+ };
61
+ //# sourceMappingURL=run-logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-logger.d.ts","sourceRoot":"","sources":["../src/run-logger.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAMpD,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,gBAAgB,EAAE,MAAM,CAAC;IACzB,MAAM,EAAE,WAAW,GAAG,QAAQ,GAAG,cAAc,GAAG,SAAS,CAAC;IAC5D,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,aAAa,CAAC,EAAE,aAAa,CAAC;IAC9B,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,SAAS,CA6D9F;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS,CA0BzE;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAwCnE;AAMD;;GAEG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,GAAG,IAAI,CAc1E;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,EAAE,CAY7E;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,GAAG;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpF,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,CAuCA"}
@@ -0,0 +1,219 @@
1
+ import * as fs from "fs";
2
+ import * as path from "path";
3
+ // ============================================
4
+ // Token Parsing
5
+ // ============================================
6
+ /**
7
+ * Parse token usage from agent output. Each agent reports differently.
8
+ */
9
+ export function parseTokensFromOutput(agent, output) {
10
+ if (!output)
11
+ return undefined;
12
+ switch (agent) {
13
+ case "codex": {
14
+ // Codex reports tokens at the end of output, e.g. "108,712" or "tokens used: 14079"
15
+ // Also: "tokens used**" pattern seen in logs
16
+ const tokensUsedMatch = output.match(/tokens?\s*used[*:]*\s*([\d,]+)/i);
17
+ if (tokensUsedMatch) {
18
+ const total = parseInt(tokensUsedMatch[1].replace(/,/g, ""), 10);
19
+ if (!isNaN(total))
20
+ return { total, model: "gpt-5.4" };
21
+ }
22
+ // Bare large number at end of output (Codex sometimes just prints the count)
23
+ const bareNumberMatch = output.match(/\n([\d,]{4,})\s*$/);
24
+ if (bareNumberMatch) {
25
+ const total = parseInt(bareNumberMatch[1].replace(/,/g, ""), 10);
26
+ if (!isNaN(total) && total > 100)
27
+ return { total, model: "gpt-5.4" };
28
+ }
29
+ return undefined;
30
+ }
31
+ case "ollama": {
32
+ // Ollama API returns: prompt_eval_count, eval_count in JSON responses
33
+ const promptEvalMatch = output.match(/"prompt_eval_count"\s*:\s*(\d+)/);
34
+ const evalMatch = output.match(/"eval_count"\s*:\s*(\d+)/);
35
+ if (promptEvalMatch || evalMatch) {
36
+ const input = promptEvalMatch ? parseInt(promptEvalMatch[1], 10) : undefined;
37
+ const outputTokens = evalMatch ? parseInt(evalMatch[1], 10) : undefined;
38
+ const total = (input || 0) + (outputTokens || 0);
39
+ const model = process.env.NIGHTSHIFT_OLLAMA_MODEL || "qwen3:8b";
40
+ return { input, output: outputTokens, total: total || undefined, model };
41
+ }
42
+ return undefined;
43
+ }
44
+ case "gemini": {
45
+ // Gemini CLI may report: "Token count: N" or usage stats
46
+ const tokenCountMatch = output.match(/token[s]?\s*(?:count|usage|used)[:\s]*([\d,]+)/i);
47
+ if (tokenCountMatch) {
48
+ const total = parseInt(tokenCountMatch[1].replace(/,/g, ""), 10);
49
+ if (!isNaN(total))
50
+ return { total };
51
+ }
52
+ return undefined;
53
+ }
54
+ case "claude": {
55
+ // Claude Code --print mode may report token usage
56
+ const inputMatch = output.match(/input[_ ]tokens?[:\s]*([\d,]+)/i);
57
+ const outputMatch = output.match(/output[_ ]tokens?[:\s]*([\d,]+)/i);
58
+ if (inputMatch || outputMatch) {
59
+ const input = inputMatch ? parseInt(inputMatch[1].replace(/,/g, ""), 10) : undefined;
60
+ const outputTokens = outputMatch ? parseInt(outputMatch[1].replace(/,/g, ""), 10) : undefined;
61
+ const total = (input || 0) + (outputTokens || 0);
62
+ return { input, output: outputTokens, total: total || undefined };
63
+ }
64
+ return undefined;
65
+ }
66
+ default:
67
+ return undefined;
68
+ }
69
+ }
70
+ // ============================================
71
+ // Rate Limit Detection
72
+ // ============================================
73
+ /**
74
+ * Detect rate limiting from agent output.
75
+ */
76
+ export function detectRateLimit(output) {
77
+ if (!output)
78
+ return undefined;
79
+ // HTTP 429
80
+ const has429 = /\b429\b/.test(output) && /rate|limit|quota|capacity|exhausted/i.test(output);
81
+ // Explicit rate limit messages
82
+ const hasRateLimit = /(?:error|failed|rejected|denied|exceeded).*(?:rate.?limit|quota.?exceeded|too many requests|capacity.*exhausted|exhausted.*capacity|throttl)|(?:rate.?limit|quota.?exceeded|too many requests|capacity.*exhausted|exhausted.*capacity|throttl).*(?:error|failed|rejected|denied|exceeded)/i.test(output);
83
+ // Retry-after header or message
84
+ const retryMatch = output.match(/retry.?after[:\s]*(\d+)/i)
85
+ || output.match(/reset after (\d+)s/i)
86
+ || output.match(/wait (\d+)\s*s/i);
87
+ if (!has429 && !hasRateLimit)
88
+ return undefined;
89
+ const retryAfter = retryMatch ? parseInt(retryMatch[1], 10) : undefined;
90
+ // Try to identify provider
91
+ let provider;
92
+ if (/openai|gpt/i.test(output))
93
+ provider = "openai";
94
+ else if (/anthropic|claude/i.test(output))
95
+ provider = "anthropic";
96
+ else if (/google|gemini/i.test(output))
97
+ provider = "google";
98
+ else if (/ollama/i.test(output))
99
+ provider = "ollama";
100
+ return { detected: true, retryAfter, provider };
101
+ }
102
+ // ============================================
103
+ // Tool Usage Parsing
104
+ // ============================================
105
+ /**
106
+ * Parse tool/command usage from agent output.
107
+ * Detects MCP tool calls, shell commands, file operations, etc.
108
+ */
109
+ export function parseToolsUsed(output) {
110
+ if (!output)
111
+ return undefined;
112
+ const tools = new Set();
113
+ // MCP tool calls (e.g., "nightshift - read_prd", "Tool: read_file")
114
+ const mcpToolMatches = output.matchAll(/(?:Tool|tool_use|nightshift)\s*[-:]?\s*(\w+)/g);
115
+ for (const match of mcpToolMatches) {
116
+ const toolName = match[1];
117
+ // Filter out noise words
118
+ if (toolName && toolName.length > 2 && !/^(the|and|for|was|use|has)$/i.test(toolName)) {
119
+ tools.add(toolName);
120
+ }
121
+ }
122
+ // Claude Code tool patterns: "Read(file)", "Edit(file)", "Bash(cmd)", "Write(file)"
123
+ const claudeToolMatches = output.matchAll(/\b(Read|Edit|Write|Bash|Glob|Grep|Agent|WebSearch|WebFetch)\s*\(/g);
124
+ for (const match of claudeToolMatches) {
125
+ tools.add(match[1]);
126
+ }
127
+ // Codex tool patterns: "exec", "read_file", "write_file", "shell"
128
+ const codexToolMatches = output.matchAll(/\b(exec|read_file|write_file|shell|list_dir|patch_file)\b/g);
129
+ for (const match of codexToolMatches) {
130
+ tools.add(match[1]);
131
+ }
132
+ // Gemini tool patterns: "ReadFile", "WriteFile", "ExecuteCommand"
133
+ const geminiToolMatches = output.matchAll(/\b(ReadFile|WriteFile|ExecuteCommand|SearchFiles|ListDirectory)\b/g);
134
+ for (const match of geminiToolMatches) {
135
+ tools.add(match[1]);
136
+ }
137
+ // Shell commands (common patterns)
138
+ const shellMatches = output.matchAll(/(?:^|\n)\s*\$?\s*(npm|npx|git|tsc|vitest|eslint|prettier|node)\b/gm);
139
+ for (const match of shellMatches) {
140
+ tools.add(`shell:${match[1]}`);
141
+ }
142
+ return tools.size > 0 ? Array.from(tools) : undefined;
143
+ }
144
+ // ============================================
145
+ // Run Logger
146
+ // ============================================
147
+ /**
148
+ * Append a run log entry to the project's runs.jsonl file.
149
+ */
150
+ export function appendRunLog(projectPath, entry) {
151
+ const robotChatDir = path.join(projectPath, ".robot-chat");
152
+ if (!fs.existsSync(robotChatDir)) {
153
+ fs.mkdirSync(robotChatDir, { recursive: true });
154
+ }
155
+ const logFile = path.join(robotChatDir, "runs.jsonl");
156
+ const line = JSON.stringify(entry) + "\n";
157
+ try {
158
+ fs.appendFileSync(logFile, line, "utf-8");
159
+ }
160
+ catch {
161
+ // Non-critical — best effort logging
162
+ }
163
+ }
164
+ /**
165
+ * Read all run log entries from the project's runs.jsonl file.
166
+ */
167
+ export function readRunLog(projectPath, limit) {
168
+ const logFile = path.join(projectPath, ".robot-chat", "runs.jsonl");
169
+ if (!fs.existsSync(logFile))
170
+ return [];
171
+ try {
172
+ const content = fs.readFileSync(logFile, "utf-8");
173
+ const lines = content.trim().split("\n").filter(Boolean);
174
+ const entries = lines.map((line) => JSON.parse(line));
175
+ return limit ? entries.slice(-limit) : entries;
176
+ }
177
+ catch {
178
+ return [];
179
+ }
180
+ }
181
+ /**
182
+ * Get aggregate stats from the run log.
183
+ */
184
+ export function getRunStats(projectPath) {
185
+ const entries = readRunLog(projectPath);
186
+ const byAgent = {};
187
+ let totalTokens = 0;
188
+ let totalDuration = 0;
189
+ let rateLimitCount = 0;
190
+ for (const entry of entries) {
191
+ if (!byAgent[entry.agent]) {
192
+ byAgent[entry.agent] = { runs: 0, totalTokens: 0, avgDuration: 0, totalDuration: 0 };
193
+ }
194
+ const agentStats = byAgent[entry.agent];
195
+ agentStats.runs++;
196
+ agentStats.totalDuration += entry.duration_seconds;
197
+ agentStats.avgDuration = Math.round(agentStats.totalDuration / agentStats.runs);
198
+ if (entry.tokens?.total) {
199
+ agentStats.totalTokens += entry.tokens.total;
200
+ totalTokens += entry.tokens.total;
201
+ }
202
+ totalDuration += entry.duration_seconds;
203
+ if (entry.status === "rate_limited")
204
+ rateLimitCount++;
205
+ }
206
+ // Clean up totalDuration from output
207
+ const result = {};
208
+ for (const [agent, stats] of Object.entries(byAgent)) {
209
+ result[agent] = { runs: stats.runs, totalTokens: stats.totalTokens, avgDuration: stats.avgDuration };
210
+ }
211
+ return {
212
+ totalRuns: entries.length,
213
+ byAgent: result,
214
+ totalTokens,
215
+ totalDuration,
216
+ rateLimitCount,
217
+ };
218
+ }
219
+ //# sourceMappingURL=run-logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run-logger.js","sourceRoot":"","sources":["../src/run-logger.ts"],"names":[],"mappings":"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"}
@@ -8,5 +8,8 @@ export declare const getAgentStatusTool: import("../tool-registry.js").ToolDefin
8
8
  export declare const listRunningAgentsTool: import("../tool-registry.js").ToolDefinition;
9
9
  export declare const getDaemonStatusTool: import("../tool-registry.js").ToolDefinition;
10
10
  export declare const stopDaemonTool: import("../tool-registry.js").ToolDefinition;
11
+ export declare const getRunStatsTool: import("../tool-registry.js").ToolDefinition;
12
+ export declare const getPipelineTool: import("../tool-registry.js").ToolDefinition;
13
+ export declare const setPipelineTool: import("../tool-registry.js").ToolDefinition;
11
14
  export declare const agentTools: import("../tool-registry.js").ToolDefinition[];
12
15
  //# sourceMappingURL=agents.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/tools/agents.ts"],"names":[],"mappings":"AAkEA,eAAO,MAAM,mBAAmB,8CAsC9B,CAAC;AAEH,eAAO,MAAM,cAAc,8CAqFzB,CAAC;AAEH,eAAO,MAAM,wBAAwB,8CAoDnC,CAAC;AAEH,eAAO,MAAM,aAAa,8CAqLxB,CAAC;AAEH,eAAO,MAAM,gBAAgB,8CAoK3B,CAAC;AAEH,eAAO,MAAM,WAAW,8CAsJtB,CAAC;AAEH,eAAO,MAAM,kBAAkB,8CAwC7B,CAAC;AAEH,eAAO,MAAM,qBAAqB,8CAwChC,CAAC;AAEH,eAAO,MAAM,mBAAmB,8CAsB9B,CAAC;AAEH,eAAO,MAAM,cAAc,8CA4CzB,CAAC;AAGH,eAAO,MAAM,UAAU,gDAWtB,CAAC"}
1
+ {"version":3,"file":"agents.d.ts","sourceRoot":"","sources":["../../src/tools/agents.ts"],"names":[],"mappings":"AA0EA,eAAO,MAAM,mBAAmB,8CAsC9B,CAAC;AAEH,eAAO,MAAM,cAAc,8CAiGzB,CAAC;AAEH,eAAO,MAAM,wBAAwB,8CAuDnC,CAAC;AAEH,eAAO,MAAM,aAAa,8CA6LxB,CAAC;AAEH,eAAO,MAAM,gBAAgB,8CAoK3B,CAAC;AAEH,eAAO,MAAM,WAAW,8CAsJtB,CAAC;AAEH,eAAO,MAAM,kBAAkB,8CAyC7B,CAAC;AAEH,eAAO,MAAM,qBAAqB,8CAyChC,CAAC;AAEH,eAAO,MAAM,mBAAmB,8CAsB9B,CAAC;AAEH,eAAO,MAAM,cAAc,8CA4CzB,CAAC;AAEH,eAAO,MAAM,eAAe,8CAgC1B,CAAC;AAEH,eAAO,MAAM,eAAe,8CA8B1B,CAAC;AAEH,eAAO,MAAM,eAAe,8CA0D1B,CAAC;AAGH,eAAO,MAAM,UAAU,gDActB,CAAC"}