@dmmulroy/overseer 0.7.0 → 0.8.2

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 (62) hide show
  1. package/bin/os +20 -134
  2. package/{dist → host/dist}/api/index.d.ts +1 -2
  3. package/{dist → host/dist}/api/index.js +1 -2
  4. package/{dist → host/dist}/api/learnings.d.ts +0 -1
  5. package/{dist → host/dist}/api/learnings.js +2 -2
  6. package/{dist → host/dist}/api/tasks.d.ts +0 -1
  7. package/{dist → host/dist}/api/tasks.js +0 -1
  8. package/host/dist/cli.d.ts +18 -0
  9. package/{dist → host/dist}/cli.js +22 -6
  10. package/{dist → host/dist}/decoder.d.ts +0 -1
  11. package/{dist → host/dist}/decoder.js +0 -1
  12. package/{dist → host/dist}/executor.d.ts +0 -1
  13. package/{dist → host/dist}/executor.js +0 -1
  14. package/host/dist/index.d.ts +2 -0
  15. package/host/dist/index.js +136 -0
  16. package/{dist/server.d.ts → host/dist/mcp.d.ts} +2 -3
  17. package/{dist/server.js → host/dist/mcp.js} +4 -5
  18. package/{dist → host/dist}/types.d.ts +0 -1
  19. package/{dist → host/dist}/types.js +0 -1
  20. package/host/dist/ui.d.ts +462 -0
  21. package/host/dist/ui.js +278 -0
  22. package/package.json +15 -12
  23. package/ui/dist/assets/index-71exl-6F.css +1 -0
  24. package/ui/dist/assets/index-CwXwWbGm.js +112 -0
  25. package/{dist/ui/static → ui/dist}/index.html +3 -3
  26. package/dist/api/index.d.ts.map +0 -1
  27. package/dist/api/index.js.map +0 -1
  28. package/dist/api/learnings.d.ts.map +0 -1
  29. package/dist/api/learnings.js.map +0 -1
  30. package/dist/api/tasks.d.ts.map +0 -1
  31. package/dist/api/tasks.js.map +0 -1
  32. package/dist/cli.d.ts +0 -5
  33. package/dist/cli.d.ts.map +0 -1
  34. package/dist/cli.js.map +0 -1
  35. package/dist/decoder.d.ts.map +0 -1
  36. package/dist/decoder.js.map +0 -1
  37. package/dist/executor.d.ts.map +0 -1
  38. package/dist/executor.js.map +0 -1
  39. package/dist/index.d.ts +0 -3
  40. package/dist/index.d.ts.map +0 -1
  41. package/dist/index.js +0 -10
  42. package/dist/index.js.map +0 -1
  43. package/dist/server.d.ts.map +0 -1
  44. package/dist/server.js.map +0 -1
  45. package/dist/tests/executor.test.d.ts +0 -2
  46. package/dist/tests/executor.test.d.ts.map +0 -1
  47. package/dist/tests/executor.test.js +0 -169
  48. package/dist/tests/executor.test.js.map +0 -1
  49. package/dist/tests/integration.test.d.ts +0 -2
  50. package/dist/tests/integration.test.d.ts.map +0 -1
  51. package/dist/tests/integration.test.js +0 -543
  52. package/dist/tests/integration.test.js.map +0 -1
  53. package/dist/tests/server.test.d.ts +0 -2
  54. package/dist/tests/server.test.d.ts.map +0 -1
  55. package/dist/tests/server.test.js +0 -53
  56. package/dist/tests/server.test.js.map +0 -1
  57. package/dist/types.d.ts.map +0 -1
  58. package/dist/types.js.map +0 -1
  59. package/dist/ui/server.js +0 -5
  60. package/dist/ui/server.js.map +0 -7
  61. package/dist/ui/static/assets/index-DnoPgzO1.js +0 -112
  62. package/dist/ui/static/assets/index-KqpkQhtL.css +0 -1
package/bin/os CHANGED
@@ -1,8 +1,9 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Unified CLI entry point
4
- * - `os mcp` → starts MCP server (Node, codemode)
5
- * - `os <cmd>` forwards to native binary
4
+ *
5
+ * Delegates all commands to the native binary.
6
+ * The native binary handles spawning Node for `ui` and `mcp` commands.
6
7
  */
7
8
  import { existsSync, readFileSync } from "node:fs";
8
9
  import { execSync, spawn } from "node:child_process";
@@ -71,137 +72,22 @@ function getBinaryPath() {
71
72
  }
72
73
 
73
74
  const args = process.argv.slice(2);
74
- const command = args[0];
75
75
 
76
- // Handle `os mcp` - start MCP server
77
- if (command === "mcp") {
78
- const binaryPath = getBinaryPath();
79
- process.env.OVERSEER_CLI_PATH = binaryPath;
80
-
81
- const serverPath = join(__dirname, "..", "dist", "index.js");
82
- import(serverPath).catch((err) => {
83
- console.error("Failed to start MCP server:", err.message);
84
- process.exit(1);
85
- });
86
- }
87
- // Handle `os ui` - start Task Viewer webapp
88
- else if (command === "ui") {
89
- startUiServer(args.slice(1));
90
- }
91
- // All other commands - passthrough to native binary
92
- else {
93
- const child = spawn(getBinaryPath(), args, {
94
- stdio: "inherit",
95
- });
96
-
97
- child.on("error", (err) => {
98
- console.error(`Failed to run os: ${err.message}`);
99
- process.exit(1);
100
- });
101
-
102
- child.on("exit", (code, signal) => {
103
- if (signal) {
104
- process.kill(process.pid, signal);
105
- } else {
106
- process.exit(code ?? 0);
107
- }
108
- });
109
- }
110
-
111
- /**
112
- * Start the UI server
113
- * Usage: os ui [port] [--port PORT] [--no-open]
114
- */
115
- function startUiServer(uiArgs) {
116
- // Parse args: positional port, --port flag, --no-open flag
117
- let port = null;
118
- let openBrowser = true; // Default: open browser
119
-
120
- for (let i = 0; i < uiArgs.length; i++) {
121
- const arg = uiArgs[i];
122
- if (arg === "--port" && i + 1 < uiArgs.length) {
123
- port = parseInt(uiArgs[++i], 10);
124
- } else if (arg === "--no-open") {
125
- openBrowser = false;
126
- } else if (arg === "--help" || arg === "-h") {
127
- console.log(`Usage: os ui [port] [--port PORT] [--no-open]
128
-
129
- Options:
130
- port Port number (positional, default: 6969)
131
- --port PORT Port number (explicit flag)
132
- --no-open Don't open browser automatically
133
-
134
- Examples:
135
- os ui # Start and open browser
136
- os ui 8080 # Port 8080, open browser
137
- os ui --port 3000 # Port 3000, open browser
138
- os ui --no-open # Start without opening browser`);
139
- process.exit(0);
140
- } else if (/^\d+$/.test(arg) && port === null) {
141
- // Positional port number
142
- port = parseInt(arg, 10);
143
- }
76
+ // All commands delegate to the native binary
77
+ // The binary handles `ui` and `mcp` by spawning Node with the host package
78
+ const child = spawn(getBinaryPath(), args, {
79
+ stdio: "inherit",
80
+ });
81
+
82
+ child.on("error", (err) => {
83
+ console.error(`Failed to run os: ${err.message}`);
84
+ process.exit(1);
85
+ });
86
+
87
+ child.on("exit", (code, signal) => {
88
+ if (signal) {
89
+ process.kill(process.pid, signal);
90
+ } else {
91
+ process.exit(code ?? 0);
144
92
  }
145
-
146
- // Port precedence: --port > positional > PORT env > 6969
147
- if (port === null && process.env.PORT) {
148
- port = parseInt(process.env.PORT, 10);
149
- }
150
- if (port === null || isNaN(port)) {
151
- port = 6969;
152
- }
153
-
154
- // Graceful shutdown handler
155
- const shutdown = () => {
156
- process.stdout.write('\x1b[0m'); // Reset terminal attributes
157
- console.log('\nServer stopped');
158
- process.exit(0);
159
- };
160
- process.on('SIGINT', shutdown);
161
- process.on('SIGTERM', shutdown);
162
-
163
- // Set up environment for the UI server
164
- const binaryPath = getBinaryPath();
165
- process.env.OVERSEER_CLI_PATH = binaryPath;
166
- process.env.PORT = String(port);
167
- process.env.NODE_ENV = "production";
168
-
169
- // Preserve original cwd for CLI calls (must happen before chdir)
170
- process.env.OVERSEER_CLI_CWD = process.cwd();
171
-
172
- // Static files are in dist/ui/static/ relative to package root
173
- const uiDir = join(__dirname, "..", "dist", "ui");
174
- process.env.OVERSEER_UI_STATIC_ROOT = join(uiDir, "static");
175
-
176
- // Change cwd to ui dir (serveStatic needs relative path from cwd)
177
- process.chdir(uiDir);
178
-
179
- const serverPath = join(uiDir, "server.js");
180
-
181
- if (!existsSync(serverPath)) {
182
- console.error("UI server not found. The package may not have been built correctly.");
183
- console.error(`Expected: ${serverPath}`);
184
- process.exit(1);
185
- }
186
-
187
- // Open browser after server starts (default behavior)
188
- if (openBrowser) {
189
- // Delay to let server start
190
- setTimeout(() => {
191
- const url = `http://localhost:${port}`;
192
- const openCmd =
193
- platform === "darwin" ? "open" :
194
- platform === "win32" ? "start" : "xdg-open";
195
- try {
196
- execSync(`${openCmd} ${url}`, { stdio: "ignore" });
197
- } catch {
198
- // Ignore errors (e.g., no display)
199
- }
200
- }, 500);
201
- }
202
-
203
- import(serverPath).catch((err) => {
204
- console.error("Failed to start UI server:", err.message);
205
- process.exit(1);
206
- });
207
- }
93
+ });
@@ -1,6 +1,5 @@
1
1
  /**
2
- * API exports
2
+ * API exports for VM sandbox
3
3
  */
4
4
  export { tasks } from "./tasks.js";
5
5
  export { learnings } from "./learnings.js";
6
- //# sourceMappingURL=index.d.ts.map
@@ -1,6 +1,5 @@
1
1
  /**
2
- * API exports
2
+ * API exports for VM sandbox
3
3
  */
4
4
  export { tasks } from "./tasks.js";
5
5
  export { learnings } from "./learnings.js";
6
- //# sourceMappingURL=index.js.map
@@ -9,4 +9,3 @@ export declare const learnings: {
9
9
  */
10
10
  list(taskId: string): Promise<Learning[]>;
11
11
  };
12
- //# sourceMappingURL=learnings.d.ts.map
@@ -6,6 +6,7 @@
6
6
  * This API only provides read access for viewing learnings.
7
7
  */
8
8
  import { callCli } from "../cli.js";
9
+ import { decodeLearnings } from "../decoder.js";
9
10
  /**
10
11
  * Learnings API exposed to VM sandbox
11
12
  */
@@ -15,7 +16,6 @@ export const learnings = {
15
16
  * Includes learnings bubbled from completed child tasks.
16
17
  */
17
18
  async list(taskId) {
18
- return (await callCli(["learning", "list", taskId]));
19
+ return decodeLearnings(await callCli(["learning", "list", taskId])).unwrap("learnings.list");
19
20
  },
20
21
  };
21
- //# sourceMappingURL=learnings.js.map
@@ -118,4 +118,3 @@ export declare const tasks: {
118
118
  */
119
119
  progress(rootId?: string): Promise<TaskProgress>;
120
120
  };
121
- //# sourceMappingURL=tasks.d.ts.map
@@ -181,4 +181,3 @@ export const tasks = {
181
181
  return decodeTaskProgress(await callCli(args)).unwrap("tasks.progress");
182
182
  },
183
183
  };
184
- //# sourceMappingURL=tasks.js.map
@@ -0,0 +1,18 @@
1
+ export interface CliConfig {
2
+ /** Path to the os binary */
3
+ cliPath: string;
4
+ /** Working directory for CLI commands */
5
+ cwd: string;
6
+ }
7
+ /**
8
+ * Configure the CLI bridge
9
+ */
10
+ export declare function configureCli(newConfig: CliConfig): void;
11
+ /**
12
+ * Get current CLI config
13
+ */
14
+ export declare function getCliConfig(): CliConfig;
15
+ /**
16
+ * Execute os CLI command with --json flag
17
+ */
18
+ export declare function callCli(args: string[]): Promise<unknown>;
@@ -1,19 +1,36 @@
1
1
  /**
2
2
  * CLI bridge - spawns `os` binary and parses JSON output
3
+ *
4
+ * Configuration is passed via constructor, not environment variables.
5
+ * This allows the Rust CLI to set paths correctly when spawning.
3
6
  */
4
7
  import { spawn } from "node:child_process";
5
8
  import { CliError, CliTimeoutError } from "./types.js";
6
9
  const CLI_TIMEOUT_MS = 30_000;
7
- // Allow override via env var (useful for tests)
8
- const CLI_PATH = process.env.OVERSEER_CLI_PATH || "os";
9
- const CLI_CWD = process.env.OVERSEER_CLI_CWD || process.cwd();
10
+ // Global config, set by main entry point
11
+ let config = {
12
+ cliPath: "os",
13
+ cwd: process.cwd(),
14
+ };
15
+ /**
16
+ * Configure the CLI bridge
17
+ */
18
+ export function configureCli(newConfig) {
19
+ config = newConfig;
20
+ }
21
+ /**
22
+ * Get current CLI config
23
+ */
24
+ export function getCliConfig() {
25
+ return config;
26
+ }
10
27
  /**
11
28
  * Execute os CLI command with --json flag
12
29
  */
13
30
  export async function callCli(args) {
14
31
  return new Promise((resolve, reject) => {
15
- const proc = spawn(CLI_PATH, [...args, "--json"], {
16
- cwd: CLI_CWD,
32
+ const proc = spawn(config.cliPath, [...args, "--json"], {
33
+ cwd: config.cwd,
17
34
  stdio: ["ignore", "pipe", "pipe"],
18
35
  });
19
36
  const timeout = setTimeout(() => {
@@ -49,4 +66,3 @@ export async function callCli(args) {
49
66
  });
50
67
  });
51
68
  }
52
- //# sourceMappingURL=cli.js.map
@@ -50,4 +50,3 @@ export declare function decodeTaskTrees(v: unknown): Result<TaskTree[], DecodeEr
50
50
  */
51
51
  export declare function decodeTaskProgress(v: unknown): Result<TaskProgress, DecodeError>;
52
52
  export {};
53
- //# sourceMappingURL=decoder.d.ts.map
@@ -370,4 +370,3 @@ export function decodeTaskProgress(v) {
370
370
  }
371
371
  return Result.ok({ total, completed, ready, blocked });
372
372
  }
373
- //# sourceMappingURL=decoder.js.map
@@ -9,4 +9,3 @@ export declare class ExecutionError extends Error {
9
9
  readonly stackTrace?: string | undefined;
10
10
  constructor(message: string, stackTrace?: string | undefined);
11
11
  }
12
- //# sourceMappingURL=executor.d.ts.map
@@ -113,4 +113,3 @@ export class ExecutionError extends Error {
113
113
  this.name = "ExecutionError";
114
114
  }
115
115
  }
116
- //# sourceMappingURL=executor.js.map
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
@@ -0,0 +1,136 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Overseer Host - Unified entry point for MCP and UI servers
4
+ *
5
+ * Usage:
6
+ * overseer-host mcp --cli-path /path/to/os --cwd /path/to/repo
7
+ * overseer-host ui --cli-path /path/to/os --cwd /path/to/repo --static-root /path/to/dist --port 6969
8
+ */
9
+ import { configureCli } from "./cli.js";
10
+ import { startMcpServer } from "./mcp.js";
11
+ import { startUiServer } from "./ui.js";
12
+ function parseArgs(argv) {
13
+ const args = argv.slice(2); // Skip node and script
14
+ if (args.length === 0) {
15
+ printUsage();
16
+ process.exit(1);
17
+ }
18
+ const mode = args[0];
19
+ if (mode !== "mcp" && mode !== "ui") {
20
+ console.error(`Unknown mode: ${mode}`);
21
+ printUsage();
22
+ process.exit(1);
23
+ }
24
+ const result = {
25
+ mode,
26
+ cliPath: "os",
27
+ cwd: process.cwd(),
28
+ };
29
+ for (let i = 1; i < args.length; i++) {
30
+ const arg = args[i];
31
+ const next = args[i + 1];
32
+ switch (arg) {
33
+ case "--cli-path":
34
+ if (!next) {
35
+ console.error("--cli-path requires a value");
36
+ process.exit(1);
37
+ }
38
+ result.cliPath = next;
39
+ i++;
40
+ break;
41
+ case "--cwd":
42
+ if (!next) {
43
+ console.error("--cwd requires a value");
44
+ process.exit(1);
45
+ }
46
+ result.cwd = next;
47
+ i++;
48
+ break;
49
+ case "--static-root":
50
+ if (!next) {
51
+ console.error("--static-root requires a value");
52
+ process.exit(1);
53
+ }
54
+ result.staticRoot = next;
55
+ i++;
56
+ break;
57
+ case "--port":
58
+ if (!next) {
59
+ console.error("--port requires a value");
60
+ process.exit(1);
61
+ }
62
+ result.port = parseInt(next, 10);
63
+ if (isNaN(result.port)) {
64
+ console.error(`Invalid port: ${next}`);
65
+ process.exit(1);
66
+ }
67
+ i++;
68
+ break;
69
+ case "--help":
70
+ case "-h":
71
+ printUsage();
72
+ process.exit(0);
73
+ break;
74
+ default:
75
+ console.error(`Unknown argument: ${arg}`);
76
+ printUsage();
77
+ process.exit(1);
78
+ }
79
+ }
80
+ // Validate UI-specific args
81
+ if (mode === "ui") {
82
+ if (!result.staticRoot) {
83
+ console.error("UI mode requires --static-root");
84
+ process.exit(1);
85
+ }
86
+ if (!result.port) {
87
+ result.port = 6969;
88
+ }
89
+ }
90
+ return result;
91
+ }
92
+ function printUsage() {
93
+ console.log(`
94
+ Overseer Host - Unified MCP and UI server
95
+
96
+ Usage:
97
+ overseer-host <mode> [options]
98
+
99
+ Modes:
100
+ mcp Start MCP server (stdio)
101
+ ui Start UI server (HTTP)
102
+
103
+ Options:
104
+ --cli-path <path> Path to os binary (default: "os" in PATH)
105
+ --cwd <path> Working directory for CLI commands (default: current dir)
106
+
107
+ UI-specific options:
108
+ --static-root <path> Path to static files (required for UI mode)
109
+ --port <number> HTTP port (default: 6969)
110
+
111
+ Examples:
112
+ overseer-host mcp --cli-path /usr/local/bin/os --cwd /home/user/project
113
+ overseer-host ui --cli-path ./os --cwd . --static-root ./dist --port 8080
114
+ `.trim());
115
+ }
116
+ async function main() {
117
+ const args = parseArgs(process.argv);
118
+ // Configure CLI bridge
119
+ configureCli({
120
+ cliPath: args.cliPath,
121
+ cwd: args.cwd,
122
+ });
123
+ if (args.mode === "mcp") {
124
+ await startMcpServer();
125
+ }
126
+ else {
127
+ await startUiServer({
128
+ port: args.port ?? 6969,
129
+ staticRoot: args.staticRoot ?? "./dist",
130
+ });
131
+ }
132
+ }
133
+ main().catch((err) => {
134
+ console.error("Fatal error:", err);
135
+ process.exit(1);
136
+ });
@@ -5,9 +5,8 @@ import { Server } from "@modelcontextprotocol/sdk/server/index.js";
5
5
  /**
6
6
  * Create and configure MCP server
7
7
  */
8
- export declare function createServer(): Server;
8
+ export declare function createMcpServer(): Server;
9
9
  /**
10
10
  * Start MCP server with stdio transport
11
11
  */
12
- export declare function startServer(): Promise<void>;
13
- //# sourceMappingURL=server.d.ts.map
12
+ export declare function startMcpServer(): Promise<void>;
@@ -144,10 +144,10 @@ await tasks.complete(task.id, { result: "Implemented using jose library" });
144
144
  /**
145
145
  * Create and configure MCP server
146
146
  */
147
- export function createServer() {
147
+ export function createMcpServer() {
148
148
  const server = new Server({
149
149
  name: "overseer-mcp",
150
- version: "0.1.0",
150
+ version: "0.7.0",
151
151
  }, {
152
152
  capabilities: {
153
153
  tools: {},
@@ -229,10 +229,9 @@ export function createServer() {
229
229
  /**
230
230
  * Start MCP server with stdio transport
231
231
  */
232
- export async function startServer() {
233
- const server = createServer();
232
+ export async function startMcpServer() {
233
+ const server = createMcpServer();
234
234
  const transport = new StdioServerTransport();
235
235
  await server.connect(transport);
236
236
  console.error("Overseer MCP server running on stdio");
237
237
  }
238
- //# sourceMappingURL=server.js.map
@@ -106,4 +106,3 @@ export declare class CliTimeoutError extends Error {
106
106
  constructor(message?: string);
107
107
  }
108
108
  export {};
109
- //# sourceMappingURL=types.d.ts.map
@@ -39,4 +39,3 @@ export class CliTimeoutError extends Error {
39
39
  this.name = "CliTimeoutError";
40
40
  }
41
41
  }
42
- //# sourceMappingURL=types.js.map