@companyhelm/runner 0.0.14 → 0.0.17
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/dist/commands/register-commands.js +5 -0
- package/dist/commands/root.js +11 -3
- package/dist/commands/runner/start.js +23 -21
- package/dist/commands/sdk/codex/auth.js +103 -13
- package/dist/commands/sdk/codex/use-dedicated-auth.js +1 -0
- package/dist/commands/sdk/codex/use-host-auth.js +1 -0
- package/dist/commands/startup.js +1 -0
- package/package.json +2 -1
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.registerCommands = registerCommands;
|
|
4
|
+
const common_js_1 = require("./runner/common.js");
|
|
4
5
|
const register_runner_commands_js_1 = require("./runner/register-runner-commands.js");
|
|
6
|
+
const start_js_1 = require("./runner/start.js");
|
|
5
7
|
const shell_js_1 = require("./shell.js");
|
|
6
8
|
const register_sdk_commands_js_1 = require("./sdk/register-sdk-commands.js");
|
|
7
9
|
const status_js_1 = require("./status.js");
|
|
8
10
|
const register_thread_commands_js_1 = require("./thread/register-thread-commands.js");
|
|
9
11
|
function registerCommands(program) {
|
|
12
|
+
(0, common_js_1.addRunnerStartOptions)(program
|
|
13
|
+
.command("companyhelm-runner")
|
|
14
|
+
.description("Alias for starting the local CompanyHelm runner.")).action(start_js_1.runRunnerStartCommand);
|
|
10
15
|
(0, register_runner_commands_js_1.registerRunnerCommands)(program);
|
|
11
16
|
(0, status_js_1.registerStatusCommand)(program);
|
|
12
17
|
(0, register_thread_commands_js_1.registerThreadCommands)(program);
|
package/dist/commands/root.js
CHANGED
|
@@ -1661,15 +1661,17 @@ async function countSdkModels(cfg, sdkName) {
|
|
|
1661
1661
|
client.close();
|
|
1662
1662
|
}
|
|
1663
1663
|
}
|
|
1664
|
-
async function
|
|
1664
|
+
async function loadCodexSdkState(cfg) {
|
|
1665
1665
|
const { db, client } = await (0, db_js_1.initDb)(cfg.state_db_path);
|
|
1666
|
-
let codexSdk;
|
|
1667
1666
|
try {
|
|
1668
|
-
|
|
1667
|
+
return await db.select().from(schema_js_1.agentSdks).where((0, drizzle_orm_1.eq)(schema_js_1.agentSdks.name, "codex")).get() ?? undefined;
|
|
1669
1668
|
}
|
|
1670
1669
|
finally {
|
|
1671
1670
|
client.close();
|
|
1672
1671
|
}
|
|
1672
|
+
}
|
|
1673
|
+
async function refreshCodexModelsForRegistration(cfg, logger) {
|
|
1674
|
+
const codexSdk = await loadCodexSdkState(cfg);
|
|
1673
1675
|
if (!codexSdk || codexSdk.status !== "configured" || codexSdk.authentication === "unauthenticated") {
|
|
1674
1676
|
logger.info("Codex is not configured; registering runner with unconfigured Codex SDK state.");
|
|
1675
1677
|
return null;
|
|
@@ -2394,6 +2396,12 @@ async function handleCodexConfigurationRequest(cfg, commandChannel, request, req
|
|
|
2394
2396
|
await sendRequestError(commandChannel, "Unsupported Codex auth type.", requestId);
|
|
2395
2397
|
return;
|
|
2396
2398
|
}
|
|
2399
|
+
const codexSdk = await loadCodexSdkState(cfg);
|
|
2400
|
+
if (!codexSdk || codexSdk.status !== "configured" || codexSdk.authentication === "unauthenticated") {
|
|
2401
|
+
const sdkUpdate = await buildCodexAgentSdkUpdate(cfg, logger, protos_1.AgentSdkStatus.UNCONFIGURED);
|
|
2402
|
+
await sendAgentSdkUpdate(commandChannel, sdkUpdate, requestId);
|
|
2403
|
+
return;
|
|
2404
|
+
}
|
|
2397
2405
|
const codexRefreshErrorMessage = await refreshCodexModelsForRegistration(cfg, logger);
|
|
2398
2406
|
const sdkUpdate = await buildCodexAgentSdkUpdate(cfg, logger, codexRefreshErrorMessage ? protos_1.AgentSdkStatus.ERROR : protos_1.AgentSdkStatus.READY, codexRefreshErrorMessage ?? undefined);
|
|
2399
2407
|
await sendAgentSdkUpdate(commandChannel, sdkUpdate, requestId);
|
|
@@ -1,30 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runRunnerStartCommand = runRunnerStartCommand;
|
|
3
4
|
exports.registerRunnerStartCommand = registerRunnerStartCommand;
|
|
4
5
|
const root_js_1 = require("../root.js");
|
|
5
6
|
const common_js_1 = require("./common.js");
|
|
7
|
+
async function runRunnerStartCommand(options) {
|
|
8
|
+
if (options.daemon && !(0, root_js_1.isInternalDaemonChildProcess)()) {
|
|
9
|
+
await (0, root_js_1.runDetachedDaemonProcess)(options);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
await (0, root_js_1.runRootCommand)(options, (0, root_js_1.isInternalDaemonChildProcess)()
|
|
14
|
+
? {
|
|
15
|
+
onDaemonReady: () => {
|
|
16
|
+
(0, root_js_1.sendDaemonParentMessage)({ type: "daemon-ready" });
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
: undefined);
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
if ((0, root_js_1.isInternalDaemonChildProcess)()) {
|
|
23
|
+
(0, root_js_1.sendDaemonParentMessage)({ type: "daemon-error", message: (0, root_js_1.toErrorMessage)(error) });
|
|
24
|
+
}
|
|
25
|
+
throw error;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
6
28
|
function registerRunnerStartCommand(runnerCommand) {
|
|
7
29
|
(0, common_js_1.addRunnerStartOptions)(runnerCommand
|
|
8
30
|
.command("start")
|
|
9
|
-
.description("Start the local CompanyHelm runner daemon.")).action(
|
|
10
|
-
if (options.daemon && !(0, root_js_1.isInternalDaemonChildProcess)()) {
|
|
11
|
-
await (0, root_js_1.runDetachedDaemonProcess)(options);
|
|
12
|
-
return;
|
|
13
|
-
}
|
|
14
|
-
try {
|
|
15
|
-
await (0, root_js_1.runRootCommand)(options, (0, root_js_1.isInternalDaemonChildProcess)()
|
|
16
|
-
? {
|
|
17
|
-
onDaemonReady: () => {
|
|
18
|
-
(0, root_js_1.sendDaemonParentMessage)({ type: "daemon-ready" });
|
|
19
|
-
},
|
|
20
|
-
}
|
|
21
|
-
: undefined);
|
|
22
|
-
}
|
|
23
|
-
catch (error) {
|
|
24
|
-
if ((0, root_js_1.isInternalDaemonChildProcess)()) {
|
|
25
|
-
(0, root_js_1.sendDaemonParentMessage)({ type: "daemon-error", message: (0, root_js_1.toErrorMessage)(error) });
|
|
26
|
-
}
|
|
27
|
-
throw error;
|
|
28
|
-
}
|
|
29
|
-
});
|
|
31
|
+
.description("Start the local CompanyHelm runner daemon.")).action(runRunnerStartCommand);
|
|
30
32
|
}
|
|
@@ -40,12 +40,90 @@ exports.defaultUseDedicatedCodexAuthDependencies = {
|
|
|
40
40
|
spawnCommand: node_child_process_1.spawn,
|
|
41
41
|
spawnSyncCommand: node_child_process_1.spawnSync,
|
|
42
42
|
};
|
|
43
|
+
function resolveContainerPath(pathValue, containerHome) {
|
|
44
|
+
if (pathValue === "~") {
|
|
45
|
+
return containerHome;
|
|
46
|
+
}
|
|
47
|
+
if (pathValue.startsWith("~/")) {
|
|
48
|
+
return `${containerHome}${pathValue.slice(1)}`;
|
|
49
|
+
}
|
|
50
|
+
return pathValue;
|
|
51
|
+
}
|
|
52
|
+
function shellQuote(value) {
|
|
53
|
+
return `'${value.replace(/'/g, `'"'"'`)}'`;
|
|
54
|
+
}
|
|
55
|
+
function buildCodexLoginShellCommand(cfg, loginCommand) {
|
|
56
|
+
const hostInfo = (0, host_js_1.getHostInfo)(cfg.codex.codex_auth_path);
|
|
57
|
+
const containerAuthPath = resolveContainerPath(cfg.codex.codex_auth_path, cfg.agent_home_directory);
|
|
58
|
+
return [
|
|
59
|
+
`AGENT_USER=${shellQuote(cfg.agent_user)}`,
|
|
60
|
+
`AGENT_HOME=${shellQuote(cfg.agent_home_directory)}`,
|
|
61
|
+
`AGENT_UID=${shellQuote(String(hostInfo.uid))}`,
|
|
62
|
+
`AGENT_GID=${shellQuote(String(hostInfo.gid))}`,
|
|
63
|
+
`CODEX_AUTH_PATH=${shellQuote(containerAuthPath)}`,
|
|
64
|
+
`CODEX_LOGIN_COMMAND=${shellQuote(`source "$NVM_DIR/nvm.sh"; ${loginCommand}`)}`,
|
|
65
|
+
'EXISTING_UID_USER=""',
|
|
66
|
+
'if getent passwd "$AGENT_UID" >/dev/null 2>&1; then',
|
|
67
|
+
' EXISTING_UID_USER="$(getent passwd "$AGENT_UID" | cut -d: -f1)"',
|
|
68
|
+
' AGENT_USER="$EXISTING_UID_USER"',
|
|
69
|
+
'fi',
|
|
70
|
+
'AGENT_GROUP="$AGENT_USER"',
|
|
71
|
+
'if getent group "$AGENT_GID" >/dev/null 2>&1; then',
|
|
72
|
+
' AGENT_GROUP="$(getent group "$AGENT_GID" | cut -d: -f1)"',
|
|
73
|
+
'elif getent group "$AGENT_USER" >/dev/null 2>&1; then',
|
|
74
|
+
' groupmod -g "$AGENT_GID" "$AGENT_USER"',
|
|
75
|
+
' AGENT_GROUP="$AGENT_USER"',
|
|
76
|
+
'else',
|
|
77
|
+
' groupadd -g "$AGENT_GID" "$AGENT_USER"',
|
|
78
|
+
' AGENT_GROUP="$AGENT_USER"',
|
|
79
|
+
'fi',
|
|
80
|
+
'if id -u "$AGENT_USER" >/dev/null 2>&1; then',
|
|
81
|
+
' usermod -u "$AGENT_UID" -g "$AGENT_GROUP" -d "$AGENT_HOME" -s /bin/bash "$AGENT_USER" || true',
|
|
82
|
+
'else',
|
|
83
|
+
' useradd -m -d "$AGENT_HOME" -u "$AGENT_UID" -g "$AGENT_GROUP" -s /bin/bash "$AGENT_USER"',
|
|
84
|
+
'fi',
|
|
85
|
+
'mkdir -p "$AGENT_HOME" "$(dirname "$CODEX_AUTH_PATH")"',
|
|
86
|
+
'chown -R "$AGENT_UID:$AGENT_GID" "$AGENT_HOME" "$(dirname "$CODEX_AUTH_PATH")" || true',
|
|
87
|
+
'export HOME="$AGENT_HOME"',
|
|
88
|
+
'exec sudo -n -E -H -u "$AGENT_USER" bash -lc "$CODEX_LOGIN_COMMAND"',
|
|
89
|
+
].join("\n");
|
|
90
|
+
}
|
|
43
91
|
function isErrnoException(error) {
|
|
44
92
|
return error instanceof Error && "code" in error;
|
|
45
93
|
}
|
|
46
94
|
function buildDockerMissingError() {
|
|
47
95
|
return new Error("Docker is not installed or not available on PATH. Install Docker and retry.");
|
|
48
96
|
}
|
|
97
|
+
function readSpawnSyncText(output) {
|
|
98
|
+
if (typeof output === "string") {
|
|
99
|
+
return output.trim();
|
|
100
|
+
}
|
|
101
|
+
if (Buffer.isBuffer(output)) {
|
|
102
|
+
return output.toString("utf8").trim();
|
|
103
|
+
}
|
|
104
|
+
return "";
|
|
105
|
+
}
|
|
106
|
+
function describeSpawnSyncFailure(command, args, result) {
|
|
107
|
+
if (isErrnoException(result.error)) {
|
|
108
|
+
return `${command} ${args.join(" ")} failed to start: ${result.error.message}`;
|
|
109
|
+
}
|
|
110
|
+
const parts = [`${command} ${args.join(" ")}`];
|
|
111
|
+
if (typeof result.status === "number") {
|
|
112
|
+
parts.push(`exit code ${result.status}`);
|
|
113
|
+
}
|
|
114
|
+
if (result.signal) {
|
|
115
|
+
parts.push(`signal ${result.signal}`);
|
|
116
|
+
}
|
|
117
|
+
const stderr = readSpawnSyncText(result.stderr);
|
|
118
|
+
if (stderr.length > 0) {
|
|
119
|
+
parts.push(`stderr: ${stderr}`);
|
|
120
|
+
}
|
|
121
|
+
const stdout = readSpawnSyncText(result.stdout);
|
|
122
|
+
if (stdout.length > 0) {
|
|
123
|
+
parts.push(`stdout: ${stdout}`);
|
|
124
|
+
}
|
|
125
|
+
return parts.join(", ");
|
|
126
|
+
}
|
|
49
127
|
function ensureDockerAvailable(spawnSyncCommand) {
|
|
50
128
|
const result = spawnSyncCommand("docker", ["--version"], { stdio: "ignore" });
|
|
51
129
|
if (isErrnoException(result.error) && result.error.code === "ENOENT") {
|
|
@@ -64,9 +142,10 @@ async function runContainerizedCodexLogin(cfg, deps, options) {
|
|
|
64
142
|
(0, node_fs_1.mkdirSync)(configDir, { recursive: true });
|
|
65
143
|
}
|
|
66
144
|
const destPath = (0, node_path_1.join)(configDir, cfg.codex.codex_auth_file_path);
|
|
67
|
-
const containerAuthPath = cfg.codex.codex_auth_path;
|
|
145
|
+
const containerAuthPath = resolveContainerPath(cfg.codex.codex_auth_path, cfg.agent_home_directory);
|
|
68
146
|
let authCopied = false;
|
|
69
147
|
let combinedOutput = "";
|
|
148
|
+
let lastCopyFailure = null;
|
|
70
149
|
await new Promise((resolve, reject) => {
|
|
71
150
|
let settled = false;
|
|
72
151
|
let poll;
|
|
@@ -77,19 +156,17 @@ async function runContainerizedCodexLogin(cfg, deps, options) {
|
|
|
77
156
|
deps.spawnSyncCommand("docker", ["rm", "-f", options.containerName], { stdio: "ignore" });
|
|
78
157
|
};
|
|
79
158
|
const tryCopyAuthFile = () => {
|
|
80
|
-
const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
const cpResult = deps.spawnSyncCommand("docker", ["cp", `${options.containerName}:${containerAuthPath}`, destPath], {
|
|
87
|
-
stdio: "ignore",
|
|
159
|
+
const cpArgs = ["cp", `${options.containerName}:${containerAuthPath}`, destPath];
|
|
160
|
+
const cpResult = deps.spawnSyncCommand("docker", cpArgs, {
|
|
161
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
162
|
+
encoding: "utf8",
|
|
88
163
|
});
|
|
89
164
|
if (cpResult.status !== 0) {
|
|
165
|
+
lastCopyFailure = describeSpawnSyncFailure("docker", cpArgs, cpResult);
|
|
90
166
|
return false;
|
|
91
167
|
}
|
|
92
168
|
authCopied = true;
|
|
169
|
+
lastCopyFailure = null;
|
|
93
170
|
cleanup();
|
|
94
171
|
return true;
|
|
95
172
|
};
|
|
@@ -141,7 +218,14 @@ async function runContainerizedCodexLogin(cfg, deps, options) {
|
|
|
141
218
|
resolveOnce();
|
|
142
219
|
return;
|
|
143
220
|
}
|
|
144
|
-
|
|
221
|
+
const details = [];
|
|
222
|
+
if (lastCopyFailure) {
|
|
223
|
+
details.push(`Auth file copy failed from ${containerAuthPath}: ${lastCopyFailure}`);
|
|
224
|
+
}
|
|
225
|
+
if (combinedOutput.trim().length > 0) {
|
|
226
|
+
details.push(`Output: ${combinedOutput.trim()}`);
|
|
227
|
+
}
|
|
228
|
+
rejectOnce(new Error(`Codex login failed or was cancelled.${details.length > 0 ? ` ${details.join(" ")}` : ""}`));
|
|
145
229
|
});
|
|
146
230
|
});
|
|
147
231
|
return destPath;
|
|
@@ -232,6 +316,8 @@ async function runSetCodexHostAuth(cfg, overrides = {}) {
|
|
|
232
316
|
}
|
|
233
317
|
async function runDedicatedCodexAuth(cfg, db, deps) {
|
|
234
318
|
const containerName = `companyhelm-codex-auth-${Date.now()}`;
|
|
319
|
+
ensureDockerAvailable(deps.spawnSyncCommand);
|
|
320
|
+
const loginCommand = buildCodexLoginShellCommand(cfg, "codex login --device-auth");
|
|
235
321
|
deps.logInfo("Starting Codex login inside a container...");
|
|
236
322
|
deps.logInfo("A browser URL and device code will appear -- open it to complete authentication.");
|
|
237
323
|
const destPath = await runContainerizedCodexLogin(cfg, deps, {
|
|
@@ -244,7 +330,7 @@ async function runDedicatedCodexAuth(cfg, db, deps) {
|
|
|
244
330
|
"bash",
|
|
245
331
|
cfg.runtime_image,
|
|
246
332
|
"-lc",
|
|
247
|
-
|
|
333
|
+
loginCommand,
|
|
248
334
|
],
|
|
249
335
|
});
|
|
250
336
|
await setCodexDedicatedAuthInDb(db);
|
|
@@ -257,6 +343,8 @@ async function runCodexApiKeyAuth(cfg, apiKey, overrides = {}) {
|
|
|
257
343
|
try {
|
|
258
344
|
deps.logInfo("Starting Codex API key login inside a container...");
|
|
259
345
|
const containerName = `companyhelm-codex-auth-${Date.now()}`;
|
|
346
|
+
ensureDockerAvailable(deps.spawnSyncCommand);
|
|
347
|
+
const loginCommand = buildCodexLoginShellCommand(cfg, 'printf \'%s\\n\' "$CODEX_API_KEY" | codex login --with-api-key');
|
|
260
348
|
const destPath = await runContainerizedCodexLogin(cfg, deps, {
|
|
261
349
|
containerName,
|
|
262
350
|
dockerArgs: [
|
|
@@ -269,7 +357,7 @@ async function runCodexApiKeyAuth(cfg, apiKey, overrides = {}) {
|
|
|
269
357
|
"bash",
|
|
270
358
|
cfg.runtime_image,
|
|
271
359
|
"-lc",
|
|
272
|
-
|
|
360
|
+
loginCommand,
|
|
273
361
|
],
|
|
274
362
|
});
|
|
275
363
|
await setCodexApiKeyAuthInDb(db);
|
|
@@ -288,6 +376,8 @@ async function runCodexDeviceCodeAuth(cfg, onDeviceCode, overrides = {}) {
|
|
|
288
376
|
let onDeviceCodePromise = Promise.resolve();
|
|
289
377
|
deps.logInfo("Starting Codex device login inside a container...");
|
|
290
378
|
const containerName = `companyhelm-codex-auth-${Date.now()}`;
|
|
379
|
+
ensureDockerAvailable(deps.spawnSyncCommand);
|
|
380
|
+
const loginCommand = buildCodexLoginShellCommand(cfg, "codex login --device-auth");
|
|
291
381
|
const destPath = await runContainerizedCodexLogin(cfg, deps, {
|
|
292
382
|
containerName,
|
|
293
383
|
dockerArgs: [
|
|
@@ -298,7 +388,7 @@ async function runCodexDeviceCodeAuth(cfg, onDeviceCode, overrides = {}) {
|
|
|
298
388
|
"bash",
|
|
299
389
|
cfg.runtime_image,
|
|
300
390
|
"-lc",
|
|
301
|
-
|
|
391
|
+
loginCommand,
|
|
302
392
|
],
|
|
303
393
|
onOutput: (output) => {
|
|
304
394
|
const deviceCode = extractCodexDeviceCodeFromOutput(output);
|
|
@@ -5,6 +5,7 @@ exports.registerSdkCodexUseDedicatedAuthCommand = registerSdkCodexUseDedicatedAu
|
|
|
5
5
|
const config_js_1 = require("../../../config.js");
|
|
6
6
|
const auth_js_1 = require("./auth.js");
|
|
7
7
|
async function runSdkCodexUseDedicatedAuthCommand(cfg = config_js_1.config.parse({}), overrides = {}) {
|
|
8
|
+
cfg = config_js_1.config.parse(cfg);
|
|
8
9
|
const deps = { ...auth_js_1.defaultUseDedicatedCodexAuthDependencies, ...overrides };
|
|
9
10
|
await (0, auth_js_1.runUseDedicatedCodexAuth)(cfg, deps);
|
|
10
11
|
}
|
|
@@ -5,6 +5,7 @@ exports.registerSdkCodexUseHostAuthCommand = registerSdkCodexUseHostAuthCommand;
|
|
|
5
5
|
const config_js_1 = require("../../../config.js");
|
|
6
6
|
const auth_js_1 = require("./auth.js");
|
|
7
7
|
async function runSdkCodexUseHostAuthCommand(cfg = config_js_1.config.parse({}), overrides = {}) {
|
|
8
|
+
cfg = config_js_1.config.parse(cfg);
|
|
8
9
|
const deps = { ...auth_js_1.defaultSetCodexHostAuthDependencies, ...overrides };
|
|
9
10
|
const authPath = await (0, auth_js_1.runSetCodexHostAuth)(cfg, deps);
|
|
10
11
|
console.log(`Codex SDK configured with host authentication using ${authPath}.`);
|
package/dist/commands/startup.js
CHANGED
|
@@ -96,6 +96,7 @@ async function selectStartupAuthMode(options, deps) {
|
|
|
96
96
|
return authMode;
|
|
97
97
|
}
|
|
98
98
|
async function startup(cfg = config_js_1.config.parse({}), overrides = {}) {
|
|
99
|
+
cfg = config_js_1.config.parse(cfg);
|
|
99
100
|
const deps = { ...defaultStartupDependencies, ...overrides };
|
|
100
101
|
banner();
|
|
101
102
|
const s = deps.promptApi.spinner();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@companyhelm/runner",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.17",
|
|
4
4
|
"description": "Run the CompanyHelm runner in fully isolated Docker sandboxes.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -24,6 +24,7 @@
|
|
|
24
24
|
"test": "npm run build && vitest run",
|
|
25
25
|
"test:unit": "npm run build && vitest run tests/unit",
|
|
26
26
|
"test:integration": "npm run build && vitest run tests/integration",
|
|
27
|
+
"test:system:device-auth": "npm run build && COMPANYHELM_RUN_MANUAL_DEVICE_AUTH_TEST=1 vitest run --reporter=verbose tests/system/codex-device-auth.system.test.ts",
|
|
27
28
|
"db:generate": "drizzle-kit generate",
|
|
28
29
|
"db:migrate": "drizzle-kit migrate",
|
|
29
30
|
"generate:codex-app-server": "docker run --rm --user \"$(id -u):$(id -g)\" -e CODEX_HOME=/workspace/node_modules/.cache/codex -v \"$PWD:/workspace\" -w /workspace companyhelm/runner:$(tr -d '[:space:]' < RUNTIME_IMAGE_VERSION) bash -lc 'mkdir -p /workspace/node_modules/.cache/codex; source \"$NVM_DIR/nvm.sh\"; codex app-server generate-ts --out src/generated/codex-app-server'"
|