bopodev-api 0.1.2 → 0.1.3
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/package.json +4 -4
- package/src/server.ts +50 -10
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "bopodev-api",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"nanoid": "^5.1.5",
|
|
16
16
|
"ws": "^8.19.0",
|
|
17
17
|
"zod": "^4.1.5",
|
|
18
|
-
"bopodev-agent-sdk": "0.1.
|
|
19
|
-
"bopodev-contracts": "0.1.
|
|
20
|
-
"bopodev-db": "0.1.
|
|
18
|
+
"bopodev-agent-sdk": "0.1.3",
|
|
19
|
+
"bopodev-contracts": "0.1.3",
|
|
20
|
+
"bopodev-db": "0.1.3"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@types/cors": "^2.8.19",
|
package/src/server.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createServer } from "node:http";
|
|
2
|
+
import { sql } from "drizzle-orm";
|
|
2
3
|
import { bootstrapDatabase } from "bopodev-db";
|
|
3
4
|
import { checkRuntimeCommandHealth } from "bopodev-agent-sdk";
|
|
5
|
+
import type { RuntimeCommandHealth } from "bopodev-agent-sdk";
|
|
4
6
|
import { createApp } from "./app";
|
|
5
7
|
import { loadGovernanceRealtimeSnapshot } from "./realtime/governance";
|
|
6
8
|
import { loadOfficeSpaceRealtimeSnapshot } from "./realtime/office-space";
|
|
@@ -12,21 +14,35 @@ async function main() {
|
|
|
12
14
|
const port = Number(process.env.PORT ?? 4020);
|
|
13
15
|
const { db } = await bootstrapDatabase(dbPath);
|
|
14
16
|
const codexCommand = process.env.BOPO_CODEX_COMMAND ?? "codex";
|
|
17
|
+
const skipCodexPreflight = process.env.BOPO_SKIP_CODEX_PREFLIGHT === "1";
|
|
18
|
+
const codexHealthRequired =
|
|
19
|
+
!skipCodexPreflight &&
|
|
20
|
+
(process.env.BOPO_REQUIRE_CODEX_HEALTH === "1" || (await hasCodexAgentsConfigured(db)));
|
|
15
21
|
const getRuntimeHealth = async () => {
|
|
16
|
-
const codex =
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
const codex = codexHealthRequired
|
|
23
|
+
? await checkRuntimeCommandHealth(codexCommand, {
|
|
24
|
+
timeoutMs: 5_000
|
|
25
|
+
})
|
|
26
|
+
: {
|
|
27
|
+
command: codexCommand,
|
|
28
|
+
available: skipCodexPreflight ? false : true,
|
|
29
|
+
exitCode: null,
|
|
30
|
+
elapsedMs: 0,
|
|
31
|
+
error: skipCodexPreflight
|
|
32
|
+
? "Skipped by configuration: BOPO_SKIP_CODEX_PREFLIGHT=1."
|
|
33
|
+
: "Skipped: no Codex agents configured."
|
|
34
|
+
};
|
|
19
35
|
return {
|
|
20
36
|
codex
|
|
21
37
|
};
|
|
22
38
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
39
|
+
if (codexHealthRequired) {
|
|
40
|
+
const startupCodexHealth = await checkRuntimeCommandHealth(codexCommand, {
|
|
41
|
+
timeoutMs: 5_000
|
|
42
|
+
});
|
|
43
|
+
if (!startupCodexHealth.available) {
|
|
44
|
+
emitCodexPreflightWarning(startupCodexHealth);
|
|
45
|
+
}
|
|
30
46
|
}
|
|
31
47
|
|
|
32
48
|
const server = createServer();
|
|
@@ -50,3 +66,27 @@ async function main() {
|
|
|
50
66
|
}
|
|
51
67
|
|
|
52
68
|
void main();
|
|
69
|
+
|
|
70
|
+
async function hasCodexAgentsConfigured(db: Awaited<ReturnType<typeof bootstrapDatabase>>["db"]) {
|
|
71
|
+
const result = await db.execute(sql`
|
|
72
|
+
SELECT id
|
|
73
|
+
FROM agents
|
|
74
|
+
WHERE provider_type = 'codex'
|
|
75
|
+
LIMIT 1
|
|
76
|
+
`);
|
|
77
|
+
return (result.rows ?? []).length > 0;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function emitCodexPreflightWarning(health: RuntimeCommandHealth) {
|
|
81
|
+
const red = process.stderr.isTTY ? "\x1b[31m" : "";
|
|
82
|
+
const yellow = process.stderr.isTTY ? "\x1b[33m" : "";
|
|
83
|
+
const reset = process.stderr.isTTY ? "\x1b[0m" : "";
|
|
84
|
+
const symbol = `${red}✖${reset}`;
|
|
85
|
+
process.stderr.write(
|
|
86
|
+
`${symbol} ${yellow}Codex preflight failed${reset}: command '${health.command}' is unavailable.\n`
|
|
87
|
+
);
|
|
88
|
+
process.stderr.write(` Install Codex CLI or set BOPO_SKIP_CODEX_PREFLIGHT=1 for local dev.\n`);
|
|
89
|
+
if (process.env.BOPO_VERBOSE_STARTUP_WARNINGS === "1") {
|
|
90
|
+
process.stderr.write(` Details: ${JSON.stringify(health)}\n`);
|
|
91
|
+
}
|
|
92
|
+
}
|