@castlemilk/omega 0.6.7 → 0.6.9

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 (54) hide show
  1. package/dist/cli.js +33 -0
  2. package/dist/server/dist/app.d.ts.map +1 -1
  3. package/dist/server/dist/app.js +2 -0
  4. package/dist/server/dist/app.js.map +1 -1
  5. package/dist/server/dist/routes/metrics.d.ts +4 -0
  6. package/dist/server/dist/routes/metrics.d.ts.map +1 -0
  7. package/dist/server/dist/routes/metrics.js +97 -0
  8. package/dist/server/dist/routes/metrics.js.map +1 -0
  9. package/dist/server/node_modules/@omega/agent/dist/executor.d.ts.map +1 -1
  10. package/dist/server/node_modules/@omega/agent/dist/executor.js +48 -64
  11. package/dist/server/node_modules/@omega/agent/dist/executor.js.map +1 -1
  12. package/dist/server/node_modules/@omega/agent/dist/logger.d.ts +15 -0
  13. package/dist/server/node_modules/@omega/agent/dist/logger.d.ts.map +1 -0
  14. package/dist/server/node_modules/@omega/agent/dist/logger.js +43 -0
  15. package/dist/server/node_modules/@omega/agent/dist/logger.js.map +1 -0
  16. package/dist/server/node_modules/@omega/agent/dist/planner.d.ts.map +1 -1
  17. package/dist/server/node_modules/@omega/agent/dist/planner.js +6 -2
  18. package/dist/server/node_modules/@omega/agent/dist/planner.js.map +1 -1
  19. package/dist/server/node_modules/@omega/agent/dist/prompts.d.ts +7 -4
  20. package/dist/server/node_modules/@omega/agent/dist/prompts.d.ts.map +1 -1
  21. package/dist/server/node_modules/@omega/agent/dist/prompts.js +31 -67
  22. package/dist/server/node_modules/@omega/agent/dist/prompts.js.map +1 -1
  23. package/dist/server/node_modules/@omega/agent/dist/tool-definitions.d.ts +3 -0
  24. package/dist/server/node_modules/@omega/agent/dist/tool-definitions.d.ts.map +1 -0
  25. package/dist/server/node_modules/@omega/agent/dist/tool-definitions.js +70 -0
  26. package/dist/server/node_modules/@omega/agent/dist/tool-definitions.js.map +1 -0
  27. package/dist/server/node_modules/@omega/agent/dist/tools.d.ts +1 -0
  28. package/dist/server/node_modules/@omega/agent/dist/tools.d.ts.map +1 -1
  29. package/dist/server/node_modules/@omega/agent/dist/tools.js +20 -0
  30. package/dist/server/node_modules/@omega/agent/dist/tools.js.map +1 -1
  31. package/dist/server/pglite-data/base/5/1247 +0 -0
  32. package/dist/server/pglite-data/base/5/1249 +0 -0
  33. package/dist/server/pglite-data/base/5/1259 +0 -0
  34. package/dist/server/pglite-data/base/5/16394 +0 -0
  35. package/dist/server/pglite-data/base/5/16404 +0 -0
  36. package/dist/server/pglite-data/base/5/16406 +0 -0
  37. package/dist/server/pglite-data/base/5/16421 +0 -0
  38. package/dist/server/pglite-data/base/5/16510 +0 -0
  39. package/dist/server/pglite-data/base/5/2604 +0 -0
  40. package/dist/server/pglite-data/base/5/2606 +0 -0
  41. package/dist/server/pglite-data/base/5/2610 +0 -0
  42. package/dist/server/pglite-data/base/5/2620 +0 -0
  43. package/dist/server/pglite-data/base/5/pg_internal.init +0 -0
  44. package/dist/server/pglite-data/global/pg_control +0 -0
  45. package/dist/server/pglite-data/global/pg_internal.init +0 -0
  46. package/dist/server/pglite-data/pg_wal/000000010000000000000001 +0 -0
  47. package/dist/server/pglite-data/pg_xact/0000 +0 -0
  48. package/dist/server/pglite-data/postmaster.pid +1 -1
  49. package/dist/server/src/app.ts +2 -0
  50. package/dist/server/src/routes/metrics.ts +112 -0
  51. package/dist/web/dist/assets/index-CP84vBfp.js +40 -0
  52. package/dist/web/dist/assets/index-DE4b_m6Q.css +1 -0
  53. package/dist/web/dist/index.html +2 -2
  54. package/package.json +3 -3
@@ -1,83 +1,44 @@
1
- const CODE_FENCE = '```';
2
- export const AGENT_SYSTEM_PROMPT = `You are Omega, an autonomous software engineering agent running inside a project repository. Your job is to plan and execute a given improvement task, then validate the result.
1
+ export const AGENT_SYSTEM_PROMPT = `You are Omega, an autonomous software engineering agent running inside a project repository.
3
2
 
4
- You have access to the following tools/functions. Use them to inspect, modify, run commands, reason, and finish the task. Always respond by calling one or more tools.
3
+ Your job is to complete the user's task by calling tools. Do not write prose or explanations outside tool calls. Prefer targeted edits over full rewrites.
5
4
 
6
5
  Available tools:
7
6
 
8
- 1. read_file
9
- Description: Read the contents of a file relative to the project root.
10
- Parameters: { "path": "relative path from project root" }
11
-
12
- 2. write_file
13
- Description: Write content to a file relative to the project root. Creates parent directories if needed.
14
- Parameters: { "path": "relative path from project root", "content": "file content" }
15
-
16
- 3. run_command
17
- Description: Run a single simple command in the project root. The command is split on spaces and executed directly (no shell pipes, redirects, && or ; chains). Prefer pnpm/npm/node commands.
18
- Parameters: { "command": "simple shell command" }
19
-
20
- 4. think
21
- Description: Record reasoning or a plan step. Use this before writing code.
22
- Parameters: { "thought": "your reasoning" }
23
-
24
- 5. finish
25
- Description: Mark the task complete.
26
- Parameters: { "summary": "what was done", "success": true | false }
27
-
28
- 6. publish
29
- Description: Request that the changes be built, tested, and published. Only use after validation passes.
30
- Parameters: { "version": "optional version override, e.g. 0.4.0" }
7
+ - read_file: Read a file relative to project root. Arguments: { "path": "relative/path" }
8
+ - write_file: Overwrite or create a file. Arguments: { "path": "relative/path", "content": "full file content" }
9
+ - edit_file: Replace one exact occurrence of old_string with new_string in an existing file. Use this for small changes. Arguments: { "path": "relative/path", "old_string": "...", "new_string": "..." }
10
+ - run_command: Run a single simple command. No pipes (|), &&, ;, redirects, or globs. Prefer pnpm/npm/node. Arguments: { "command": "pnpm lint" }
11
+ - think: Record a reasoning step. Arguments: { "thought": "..." }
12
+ - finish: Mark the task complete. Arguments: { "summary": "what was done", "success": true }. Use summary, not message.
13
+ - publish: Request build/test/publish. Only after validation passes. Arguments: { "version": "optional" }
31
14
 
32
15
  Rules:
33
- - Work in small, verifiable steps.
34
- - Always think before writing or running commands.
35
- - Prefer editing existing files over creating new ones when possible.
36
- - Run tests and lint after making changes.
37
- - Do not expose secrets.
38
- - Do not run destructive commands (rm -rf, git reset --hard, etc).
39
- - If a step fails, use think to reason and try a fix.
40
- - Finish only when the task is truly complete or you cannot proceed.
41
- - IMPORTANT: Do not just describe what you would do. Use tools to actually do it.
42
- - If the model/API supports native tool calls, use them.
43
- - Otherwise output strict JSON: {"tool_calls":[{"id":"1","name":"tool_name","arguments":{}}]}.
44
- - As a last resort you may use Markdown action blocks:
45
- ### Action: think
46
- reasoning text
47
- ### Action: run_command
48
- ${CODE_FENCE}bash
49
- command here
50
- ${CODE_FENCE}
51
- ### Action: write_file
52
- ${CODE_FENCE}filepath: path/to/file
53
- content here
54
- ${CODE_FENCE}
55
- ### Action: finish
56
- summary text`;
57
- export const FORCE_ACTION_PROMPT = `You have been thinking without taking action. Stop describing plans and execute the next concrete step using a tool. Read a file, write a file, or run a command.`;
58
- export const TEXT_TOOLS_SYSTEM_PROMPT = `You are Omega, an autonomous software engineering agent running inside a project repository. Your job is to plan and execute the user's improvement task, then validate the result.
16
+ 1. Read the task, then use think to plan.
17
+ 2. Use edit_file for small changes; write_file only when creating a file or rewriting most of it.
18
+ 3. Run validation commands (pnpm lint, pnpm test) after edits.
19
+ 4. Do not expose secrets or run destructive commands.
20
+ 5. Finish only when the task is done. Always include summary and success.`;
21
+ export const FORCE_ACTION_PROMPT = `You have been thinking without taking action. Stop describing plans and execute the next concrete step using a tool. Use edit_file or run_command.`;
22
+ export const TEXT_TOOLS_SYSTEM_PROMPT = `You are Omega, an autonomous software engineering agent running inside a project repository.
59
23
 
60
24
  You MUST respond with a single JSON object containing a "tool_calls" array. Do not output markdown, explanations, or reasoning outside the JSON.
61
25
 
62
26
  Available tools (use ONLY these exact names):
63
27
 
64
- - read_file: { "path": "relative path from project root" }
65
- - write_file: { "path": "relative path from project root", "content": "file content" }
66
- - run_command: { "command": "simple shell command (no pipes, &&, ;, or redirects)" }
28
+ - read_file: { "path": "relative/path" }
29
+ - write_file: { "path": "relative/path", "content": "full file content" }
30
+ - edit_file: { "path": "relative/path", "old_string": "...", "new_string": "..." }
31
+ - run_command: { "command": "simple command, no pipes/&&/;/redirects" }
67
32
  - think: { "thought": "reasoning text" }
68
33
  - finish: { "summary": "what was done", "success": true | false }
69
- - publish: { "version": "optional version override" }
34
+ - publish: { "version": "optional" }
70
35
 
71
36
  Rules:
72
- - Read the user's task carefully and execute exactly that.
73
- - Work in small, verifiable steps.
74
- - Always think before writing or running commands.
75
- - Prefer editing existing files over creating new ones when possible.
76
- - Run tests and lint after making changes.
77
- - Do not expose secrets.
78
- - Do not run destructive commands.
79
- - Finish only when the task is truly complete or you cannot proceed.
80
- - IMPORTANT: Do not describe what you would do. Output JSON tool_calls and actually do it.`;
37
+ - Plan with think, then act.
38
+ - Use edit_file for small changes; write_file only for new files or large rewrites.
39
+ - Run validation (pnpm lint, pnpm test) after edits.
40
+ - Do not expose secrets or run destructive commands.
41
+ - Finish only when done. Use summary, not message.`;
81
42
  export function buildTaskPrompt(title, description) {
82
43
  const parts = [`Task: ${title}`];
83
44
  if (description)
@@ -85,8 +46,11 @@ export function buildTaskPrompt(title, description) {
85
46
  parts.push('Start by using the think tool to create a plan.');
86
47
  return parts.join('\n\n');
87
48
  }
88
- export function buildToolResultPrompt(results) {
89
- return `Tool results:\n${results
49
+ export function buildToolResultPrompt(task, results) {
50
+ const taskReminder = [`Task: ${task.title}`];
51
+ if (task.description)
52
+ taskReminder.push(`Description: ${task.description}`);
53
+ return `${taskReminder.join('\n')}\n\nTool results:\n${results
90
54
  .map((r) => `[${r.toolCallId}]\n${r.output}`)
91
55
  .join('\n\n')}\n\nDecide the next tool call(s).`;
92
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,GAAG,KAAK,CAAC;AAEzB,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IA8C/B,UAAU;;IAEV,UAAU;;IAEV,UAAU;;IAEV,UAAU;;eAEC,CAAC;AAEhB,MAAM,CAAC,MAAM,mBAAmB,GAAG,mKAAmK,CAAC;AAEvM,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;;;;2FAsBmD,CAAC;AAE5F,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,WAAoB;IACjE,MAAM,KAAK,GAAG,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;IACjC,IAAI,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAiD;IACrF,OAAO,kBAAkB,OAAO;SAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;SAC5C,IAAI,CAAC,MAAM,CAAC,mCAAmC,CAAC;AACrD,CAAC"}
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;;;;;;;;;;;;;;;;0EAmBuC,CAAC;AAE3E,MAAM,CAAC,MAAM,mBAAmB,GAAG,oJAAoJ,CAAC;AAExL,MAAM,CAAC,MAAM,wBAAwB,GAAG;;;;;;;;;;;;;;;;;;;mDAmBW,CAAC;AAEpD,MAAM,UAAU,eAAe,CAAC,KAAa,EAAE,WAAoB;IACjE,MAAM,KAAK,GAAG,CAAC,SAAS,KAAK,EAAE,CAAC,CAAC;IACjC,IAAI,WAAW;QAAE,KAAK,CAAC,IAAI,CAAC,gBAAgB,WAAW,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,iDAAiD,CAAC,CAAC;IAC9D,OAAO,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,qBAAqB,CACnC,IAA6C,EAC7C,OAAiD;IAEjD,MAAM,YAAY,GAAG,CAAC,SAAS,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC7C,IAAI,IAAI,CAAC,WAAW;QAAE,YAAY,CAAC,IAAI,CAAC,gBAAgB,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5E,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,sBAAsB,OAAO;SAC3D,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,UAAU,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC;SAC5C,IAAI,CAAC,MAAM,CAAC,mCAAmC,CAAC;AACrD,CAAC"}
@@ -0,0 +1,3 @@
1
+ import type { ToolDefinition } from '@omega/core';
2
+ export declare const AGENT_TOOLS: ToolDefinition[];
3
+ //# sourceMappingURL=tool-definitions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-definitions.d.ts","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD,eAAO,MAAM,WAAW,EAAE,cAAc,EAqEvC,CAAC"}
@@ -0,0 +1,70 @@
1
+ export const AGENT_TOOLS = [
2
+ {
3
+ name: 'read_file',
4
+ description: 'Read a file relative to project root.',
5
+ parameters: {
6
+ type: 'object',
7
+ properties: { path: { type: 'string' } },
8
+ required: ['path'],
9
+ },
10
+ },
11
+ {
12
+ name: 'write_file',
13
+ description: 'Write content to a file relative to project root.',
14
+ parameters: {
15
+ type: 'object',
16
+ properties: { path: { type: 'string' }, content: { type: 'string' } },
17
+ required: ['path', 'content'],
18
+ },
19
+ },
20
+ {
21
+ name: 'edit_file',
22
+ description: 'Apply a targeted edit to an existing file relative to project root. Replaces one occurrence of old_string with new_string.',
23
+ parameters: {
24
+ type: 'object',
25
+ properties: {
26
+ path: { type: 'string' },
27
+ old_string: { type: 'string' },
28
+ new_string: { type: 'string' },
29
+ },
30
+ required: ['path', 'old_string', 'new_string'],
31
+ },
32
+ },
33
+ {
34
+ name: 'run_command',
35
+ description: 'Run a shell command in the project root.',
36
+ parameters: {
37
+ type: 'object',
38
+ properties: { command: { type: 'string' } },
39
+ required: ['command'],
40
+ },
41
+ },
42
+ {
43
+ name: 'think',
44
+ description: 'Record reasoning.',
45
+ parameters: {
46
+ type: 'object',
47
+ properties: { thought: { type: 'string' } },
48
+ required: ['thought'],
49
+ },
50
+ },
51
+ {
52
+ name: 'finish',
53
+ description: 'Mark the task complete.',
54
+ parameters: {
55
+ type: 'object',
56
+ properties: { summary: { type: 'string' }, success: { type: 'boolean' } },
57
+ required: ['summary', 'success'],
58
+ },
59
+ },
60
+ {
61
+ name: 'publish',
62
+ description: 'Build, validate, and publish the project.',
63
+ parameters: {
64
+ type: 'object',
65
+ properties: { version: { type: 'string' } },
66
+ required: [],
67
+ },
68
+ },
69
+ ];
70
+ //# sourceMappingURL=tool-definitions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-definitions.js","sourceRoot":"","sources":["../src/tool-definitions.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,WAAW,GAAqB;IAC3C;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,uCAAuC;QACpD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACxC,QAAQ,EAAE,CAAC,MAAM,CAAC;SACnB;KACF;IACD;QACE,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,mDAAmD;QAChE,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YACrE,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,CAAC;SAC9B;KACF;IACD;QACE,IAAI,EAAE,WAAW;QACjB,WAAW,EACT,4HAA4H;QAC9H,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE;gBACV,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBACxB,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;gBAC9B,UAAU,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE;aAC/B;YACD,QAAQ,EAAE,CAAC,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC;SAC/C;KACF;IACD;QACE,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,0CAA0C;QACvD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YAC3C,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;IACD;QACE,IAAI,EAAE,OAAO;QACb,WAAW,EAAE,mBAAmB;QAChC,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YAC3C,QAAQ,EAAE,CAAC,SAAS,CAAC;SACtB;KACF;IACD;QACE,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,yBAAyB;QACtC,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE;YACzE,QAAQ,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;SACjC;KACF;IACD;QACE,IAAI,EAAE,SAAS;QACf,WAAW,EAAE,2CAA2C;QACxD,UAAU,EAAE;YACV,IAAI,EAAE,QAAQ;YACd,UAAU,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE;YAC3C,QAAQ,EAAE,EAAE;SACb;KACF;CACF,CAAC"}
@@ -4,6 +4,7 @@ export interface ToolResult {
4
4
  }
5
5
  export declare function readFile(projectPath: string, filePath: string): Promise<ToolResult>;
6
6
  export declare function writeFile(projectPath: string, filePath: string, content: string): Promise<ToolResult>;
7
+ export declare function editFile(projectPath: string, filePath: string, oldString: string, newString: string): Promise<ToolResult>;
7
8
  export declare function runCommand(projectPath: string, command: string): Promise<ToolResult>;
8
9
  export declare function think(_projectPath: string, thought: string): ToolResult;
9
10
  export declare function executeTool(projectPath: string, name: string, arguments_: Record<string, unknown>): Promise<ToolResult>;
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAqBD,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAWzF;AAED,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,CAAC,CAYrB;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAc1F;AAED,wBAAgB,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvE;AASD,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,UAAU,CAAC,CAarB"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;CAChB;AAqBD,wBAAsB,QAAQ,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAWzF;AAED,wBAAsB,SAAS,CAC7B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,UAAU,CAAC,CAYrB;AAED,wBAAsB,QAAQ,CAC5B,WAAW,EAAE,MAAM,EACnB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,UAAU,CAAC,CAgBrB;AAED,wBAAsB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CAc1F;AAED,wBAAgB,KAAK,CAAC,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,UAAU,CAEvE;AASD,wBAAsB,WAAW,CAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAClC,OAAO,CAAC,UAAU,CAAC,CAoBrB"}
@@ -47,6 +47,24 @@ export async function writeFile(projectPath, filePath, content) {
47
47
  return { success: false, output: err instanceof Error ? err.message : String(err) };
48
48
  }
49
49
  }
50
+ export async function editFile(projectPath, filePath, oldString, newString) {
51
+ const target = path.resolve(projectPath, filePath);
52
+ if (!target.startsWith(path.resolve(projectPath))) {
53
+ return { success: false, output: 'Path traversal blocked' };
54
+ }
55
+ try {
56
+ const content = await fs.readFile(target, 'utf-8');
57
+ if (!content.includes(oldString)) {
58
+ return { success: false, output: `old_string not found in ${filePath}` };
59
+ }
60
+ const updated = content.replace(oldString, newString);
61
+ await fs.writeFile(target, updated, 'utf-8');
62
+ return { success: true, output: `Edited ${filePath}` };
63
+ }
64
+ catch (err) {
65
+ return { success: false, output: err instanceof Error ? err.message : String(err) };
66
+ }
67
+ }
50
68
  export async function runCommand(projectPath, command) {
51
69
  try {
52
70
  sanitizeCommand(command);
@@ -81,6 +99,8 @@ export async function executeTool(projectPath, name, arguments_) {
81
99
  return readFile(projectPath, argString(arguments_.path));
82
100
  case 'write_file':
83
101
  return writeFile(projectPath, argString(arguments_.path), argString(arguments_.content));
102
+ case 'edit_file':
103
+ return editFile(projectPath, argString(arguments_.path), argString(arguments_.old_string), argString(arguments_.new_string));
84
104
  case 'run_command':
85
105
  return runCommand(projectPath, argString(arguments_.command));
86
106
  case 'think':
@@ -1 +1 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  -42
2
2
  /pglite/data
3
- 1783041467
3
+ 1783045795
4
4
  5432
5
5
 
6
6
 
@@ -5,6 +5,7 @@ import { projectRoutes } from './routes/projects.js';
5
5
  import { taskRoutes } from './routes/tasks.js';
6
6
  import { providerRoutes } from './routes/providers.js';
7
7
  import { routerRoutes } from './routes/router.js';
8
+ import { metricsRoutes } from './routes/metrics.js';
8
9
 
9
10
  export const app: express.Express = express();
10
11
 
@@ -15,6 +16,7 @@ app.use('/projects', projectRoutes(prisma));
15
16
  app.use('/tasks', taskRoutes(prisma));
16
17
  app.use('/providers', providerRoutes(prisma));
17
18
  app.use('/router', routerRoutes(prisma));
19
+ app.use('/metrics', metricsRoutes(prisma));
18
20
 
19
21
  app.use((err: unknown, _req: express.Request, res: express.Response, _next: express.NextFunction) => {
20
22
  console.error(err);
@@ -0,0 +1,112 @@
1
+ import { Router } from 'express';
2
+ import type { PrismaClient } from '@omega/db';
3
+ import fs from 'node:fs/promises';
4
+ import path from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
6
+ import { asyncHandler } from '../lib/async-handler.js';
7
+
8
+ const __filename = fileURLToPath(import.meta.url);
9
+ const root = path.resolve(__filename, '..', '..', '..', '..');
10
+ const reportsDir = path.join(root, '.omega', 'reports');
11
+
12
+ async function latestReport(pattern: RegExp): Promise<{ file: string; data: unknown } | undefined> {
13
+ try {
14
+ const files = await fs.readdir(reportsDir);
15
+ const matches = files
16
+ .filter((f) => pattern.test(f))
17
+ .sort()
18
+ .reverse();
19
+ const latest = matches[0];
20
+ if (!latest) return undefined;
21
+ const raw = await fs.readFile(path.join(reportsDir, latest), 'utf-8');
22
+ const data = latest.endsWith('.json') ? (JSON.parse(raw) as unknown) : raw;
23
+ return { file: latest, data };
24
+ } catch {
25
+ return undefined;
26
+ }
27
+ }
28
+
29
+ function durationMs(start: Date, end: Date | null): number | undefined {
30
+ if (!end) return undefined;
31
+ return end.getTime() - start.getTime();
32
+ }
33
+
34
+ export function metricsRoutes(prisma: PrismaClient): Router {
35
+ const r = Router();
36
+
37
+ r.get('/', asyncHandler(async (_req, res) => {
38
+ const [
39
+ tasks,
40
+ agentRuns,
41
+ ] = await Promise.all([
42
+ prisma.task.findMany({
43
+ select: { status: true, provider: true, model: true },
44
+ }),
45
+ prisma.agentRun.findMany({
46
+ take: 10,
47
+ orderBy: { createdAt: 'desc' },
48
+ include: { task: { select: { title: true } } },
49
+ }),
50
+ ]);
51
+
52
+ const taskCounts = {
53
+ todo: 0,
54
+ in_progress: 0,
55
+ done: 0,
56
+ failed: 0,
57
+ };
58
+ const providerUsage: Record<string, number> = {};
59
+ const modelUsage: Record<string, number> = {};
60
+
61
+ for (const task of tasks) {
62
+ taskCounts[task.status as keyof typeof taskCounts]++;
63
+ if (task.provider && task.model) {
64
+ const key = `${task.provider}/${task.model}`;
65
+ providerUsage[key] = (providerUsage[key] ?? 0) + 1;
66
+ }
67
+ if (task.model) {
68
+ modelUsage[task.model] = (modelUsage[task.model] ?? 0) + 1;
69
+ }
70
+ }
71
+
72
+ const completedRuns = agentRuns.filter((r) => r.resultStatus !== 'running');
73
+ const avgDurationMs =
74
+ completedRuns.length > 0
75
+ ? Math.round(
76
+ completedRuns.reduce((sum, r) => sum + (durationMs(r.createdAt, r.updatedAt) ?? 0), 0) /
77
+ completedRuns.length
78
+ )
79
+ : 0;
80
+
81
+ const recentRuns = agentRuns.map((r) => ({
82
+ id: r.id,
83
+ taskId: r.taskId,
84
+ title: r.task.title,
85
+ branch: r.branch,
86
+ resultStatus: r.resultStatus,
87
+ baseCommit: r.baseCommit,
88
+ validationSummary: r.validationSummary,
89
+ publishedVersion: r.publishedVersion,
90
+ durationMs: durationMs(r.createdAt, r.updatedAt),
91
+ createdAt: r.createdAt,
92
+ }));
93
+
94
+ const e2eReport = await latestReport(/^e2e-raw-/);
95
+ const benchmarkReport = await latestReport(/^benchmark-/);
96
+
97
+ res.json({
98
+ taskCounts,
99
+ totalTasks: tasks.length,
100
+ providerUsage,
101
+ modelUsage,
102
+ avgDurationMs,
103
+ recentRuns,
104
+ latestReports: {
105
+ e2e: e2eReport,
106
+ benchmark: benchmarkReport,
107
+ },
108
+ });
109
+ }));
110
+
111
+ return r;
112
+ }