@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.
- package/bin/os +20 -134
- package/{dist → host/dist}/api/index.d.ts +1 -2
- package/{dist → host/dist}/api/index.js +1 -2
- package/{dist → host/dist}/api/learnings.d.ts +0 -1
- package/{dist → host/dist}/api/learnings.js +2 -2
- package/{dist → host/dist}/api/tasks.d.ts +0 -1
- package/{dist → host/dist}/api/tasks.js +0 -1
- package/host/dist/cli.d.ts +18 -0
- package/{dist → host/dist}/cli.js +22 -6
- package/{dist → host/dist}/decoder.d.ts +0 -1
- package/{dist → host/dist}/decoder.js +0 -1
- package/{dist → host/dist}/executor.d.ts +0 -1
- package/{dist → host/dist}/executor.js +0 -1
- package/host/dist/index.d.ts +2 -0
- package/host/dist/index.js +136 -0
- package/{dist/server.d.ts → host/dist/mcp.d.ts} +2 -3
- package/{dist/server.js → host/dist/mcp.js} +4 -5
- package/{dist → host/dist}/types.d.ts +0 -1
- package/{dist → host/dist}/types.js +0 -1
- package/host/dist/ui.d.ts +462 -0
- package/host/dist/ui.js +278 -0
- package/package.json +15 -12
- package/ui/dist/assets/index-71exl-6F.css +1 -0
- package/ui/dist/assets/index-CwXwWbGm.js +112 -0
- package/{dist/ui/static → ui/dist}/index.html +3 -3
- package/dist/api/index.d.ts.map +0 -1
- package/dist/api/index.js.map +0 -1
- package/dist/api/learnings.d.ts.map +0 -1
- package/dist/api/learnings.js.map +0 -1
- package/dist/api/tasks.d.ts.map +0 -1
- package/dist/api/tasks.js.map +0 -1
- package/dist/cli.d.ts +0 -5
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/decoder.d.ts.map +0 -1
- package/dist/decoder.js.map +0 -1
- package/dist/executor.d.ts.map +0 -1
- package/dist/executor.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -10
- package/dist/index.js.map +0 -1
- package/dist/server.d.ts.map +0 -1
- package/dist/server.js.map +0 -1
- package/dist/tests/executor.test.d.ts +0 -2
- package/dist/tests/executor.test.d.ts.map +0 -1
- package/dist/tests/executor.test.js +0 -169
- package/dist/tests/executor.test.js.map +0 -1
- package/dist/tests/integration.test.d.ts +0 -2
- package/dist/tests/integration.test.d.ts.map +0 -1
- package/dist/tests/integration.test.js +0 -543
- package/dist/tests/integration.test.js.map +0 -1
- package/dist/tests/server.test.d.ts +0 -2
- package/dist/tests/server.test.d.ts.map +0 -1
- package/dist/tests/server.test.js +0 -53
- package/dist/tests/server.test.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/ui/server.js +0 -5
- package/dist/ui/server.js.map +0 -7
- package/dist/ui/static/assets/index-DnoPgzO1.js +0 -112
- 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
|
-
*
|
|
5
|
-
*
|
|
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
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
}
|
|
91
|
-
|
|
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
|
+
});
|
|
@@ -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
|
|
@@ -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
|
-
//
|
|
8
|
-
|
|
9
|
-
|
|
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(
|
|
16
|
-
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
|
|
@@ -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
|
|
8
|
+
export declare function createMcpServer(): Server;
|
|
9
9
|
/**
|
|
10
10
|
* Start MCP server with stdio transport
|
|
11
11
|
*/
|
|
12
|
-
export declare function
|
|
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
|
|
147
|
+
export function createMcpServer() {
|
|
148
148
|
const server = new Server({
|
|
149
149
|
name: "overseer-mcp",
|
|
150
|
-
version: "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
|
|
233
|
-
const server =
|
|
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
|