@meetopenbot/codex 1.1.0 → 1.2.0
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/README.md +6 -7
- package/dist/index.js +217 -51
- package/package.json +10 -11
package/README.md
CHANGED
|
@@ -2,22 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
OpenAI Codex runtime plugin for OpenBot. Each `agent:invoke` starts or resumes a Codex SDK thread in the channel workspace.
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Auth
|
|
6
|
+
|
|
7
|
+
On cloud, `authMode: credits` (the default) uses your workspace credit balance via OpenBot. For BYOK, set `authMode: byok` and add `OPENAI_API_KEY` (or `CODEX_API_KEY`) under workspace settings — there is no API key field in plugin config.
|
|
6
8
|
|
|
7
|
-
|
|
9
|
+
Locally, Codex always uses BYOK from `CODEX_API_KEY` / `OPENAI_API_KEY`.
|
|
8
10
|
|
|
9
|
-
|
|
10
|
-
- `CODEX_API_KEY`
|
|
11
|
-
- `OPENAI_API_KEY`
|
|
11
|
+
## Config
|
|
12
12
|
|
|
13
13
|
Optional:
|
|
14
14
|
|
|
15
|
+
- `authMode` — cloud only: `credits` (default) or `byok`
|
|
15
16
|
- `model` — Codex model id (e.g. `gpt-5.6`). Omit to use the CLI default.
|
|
16
17
|
- `sandboxMode` — `read-only` | `workspace-write` | `danger-full-access` (default `workspace-write`)
|
|
17
18
|
- `approvalPolicy` — `never` | `on-request` | `on-failure` | `untrusted` (default `never`)
|
|
18
|
-
- `workingDirectory` — override the channel cwd
|
|
19
19
|
- `skipGitRepoCheck` — default `true` for non-git channel workspaces
|
|
20
|
-
- `baseURL` — custom OpenAI-compatible endpoint
|
|
21
20
|
- `codexPathOverride` — path to a local `codex` binary (`CODEX_PATH` / `CODEX_CLI_PATH` also work)
|
|
22
21
|
|
|
23
22
|
Codex conversation state is stored as `codexThreadId` on the OpenBot thread, not as the OpenBot thread id.
|
package/dist/index.js
CHANGED
|
@@ -3,11 +3,86 @@ import {
|
|
|
3
3
|
definePlugin,
|
|
4
4
|
shouldHandleInvoke,
|
|
5
5
|
agentOutput,
|
|
6
|
-
uiWidget
|
|
6
|
+
uiWidget,
|
|
7
|
+
toolTraceWidget,
|
|
8
|
+
buildDiffWidget,
|
|
9
|
+
diffFileFromWrite,
|
|
10
|
+
resolveRunDiffFiles,
|
|
11
|
+
snapshotWorkspace
|
|
7
12
|
} from "@meetopenbot/plugin-sdk";
|
|
13
|
+
import { readFileSync } from "node:fs";
|
|
14
|
+
import { join } from "node:path";
|
|
8
15
|
import {
|
|
9
16
|
Codex
|
|
10
17
|
} from "@openai/codex-sdk";
|
|
18
|
+
|
|
19
|
+
// cloud-mode.ts
|
|
20
|
+
var isCloudMode = () => process.env.OPENBOT_CLOUD_MODE === "1";
|
|
21
|
+
var defaultAuthMode = () => isCloudMode() ? "credits" : "byok";
|
|
22
|
+
function resolveAuthMode(config) {
|
|
23
|
+
if (config.authMode === "byok" || config.authMode === "credits") {
|
|
24
|
+
return config.authMode;
|
|
25
|
+
}
|
|
26
|
+
return defaultAuthMode();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// credits-auth.ts
|
|
30
|
+
var INTEGRATIONS_TOKEN_HEADER = "x-openbot-integrations-token";
|
|
31
|
+
var CREDITS_API_KEY_PLACEHOLDER = "openbot-credits";
|
|
32
|
+
var CREDITS_PROVIDER_ID = "openbot_credits";
|
|
33
|
+
function resolveCreditsAuthConfig() {
|
|
34
|
+
const baseUrl = process.env.OPENBOT_INTEGRATIONS_BASE_URL?.trim();
|
|
35
|
+
const token = process.env.OPENBOT_INTEGRATIONS_TOKEN?.trim();
|
|
36
|
+
if (!baseUrl || !token) return void 0;
|
|
37
|
+
return { baseUrl: baseUrl.replace(/\/$/, ""), token };
|
|
38
|
+
}
|
|
39
|
+
function creditsProviderBaseUrl(config) {
|
|
40
|
+
return `${config.baseUrl}/openai/v1`;
|
|
41
|
+
}
|
|
42
|
+
function buildCreditsCodexConfig(config) {
|
|
43
|
+
return {
|
|
44
|
+
model_provider: CREDITS_PROVIDER_ID,
|
|
45
|
+
model_providers: {
|
|
46
|
+
[CREDITS_PROVIDER_ID]: {
|
|
47
|
+
name: "OpenBot Credits",
|
|
48
|
+
base_url: creditsProviderBaseUrl(config),
|
|
49
|
+
env_key: "CODEX_API_KEY",
|
|
50
|
+
wire_api: "responses",
|
|
51
|
+
supports_websockets: false,
|
|
52
|
+
http_headers: {
|
|
53
|
+
[INTEGRATIONS_TOKEN_HEADER]: config.token
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
function isCreditsErrorMessage(message) {
|
|
60
|
+
const lower = message.toLowerCase();
|
|
61
|
+
return lower.includes("insufficient_credits") || lower.includes("insufficient credits") || lower.includes("402");
|
|
62
|
+
}
|
|
63
|
+
function isAuthErrorMessage(message) {
|
|
64
|
+
const lower = message.toLowerCase();
|
|
65
|
+
return lower.includes("api key") || lower.includes("apikey") || lower.includes("401") || lower.includes("unauthorized") || lower.includes("authentication") || lower.includes("not logged in") || lower.includes("login");
|
|
66
|
+
}
|
|
67
|
+
function isIntegrationsProviderError(message) {
|
|
68
|
+
const lower = message.toLowerCase();
|
|
69
|
+
return lower.includes("provider api key not configured") || lower.includes("503") && lower.includes("provider");
|
|
70
|
+
}
|
|
71
|
+
var CREDITS_NOT_CONFIGURED_MESSAGE = "OpenBot Credits is not configured on this runtime. The cloud host must set OPENBOT_INTEGRATIONS_BASE_URL and OPENBOT_INTEGRATIONS_TOKEN (try redeploying the workspace).";
|
|
72
|
+
var CREDITS_PROVIDER_UNAVAILABLE_MESSAGE = "OpenBot Credits could not reach OpenAI \u2014 the platform provider API key is not configured yet. Try again later or switch this agent to BYOK mode.";
|
|
73
|
+
var CREDITS_AUTH_FAILED_MESSAGE = "Codex could not authenticate via OpenBot Credits. Check your workspace credit balance in settings, or switch this agent to BYOK mode.";
|
|
74
|
+
function creditsErrorMessage(message) {
|
|
75
|
+
if (isIntegrationsProviderError(message)) {
|
|
76
|
+
return CREDITS_PROVIDER_UNAVAILABLE_MESSAGE;
|
|
77
|
+
}
|
|
78
|
+
if (isCreditsErrorMessage(message)) {
|
|
79
|
+
return "Insufficient workspace credits. Add credits in workspace settings or switch this agent to BYOK mode.";
|
|
80
|
+
}
|
|
81
|
+
if (isAuthErrorMessage(message)) return CREDITS_AUTH_FAILED_MESSAGE;
|
|
82
|
+
return void 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// index.ts
|
|
11
86
|
var SANDBOX_MODES = [
|
|
12
87
|
"read-only",
|
|
13
88
|
"workspace-write",
|
|
@@ -28,21 +103,8 @@ var LEGACY_APPROVAL = {
|
|
|
28
103
|
always: "on-request",
|
|
29
104
|
automatic: "on-request"
|
|
30
105
|
};
|
|
31
|
-
var AUTH_ERROR_PATTERNS = [
|
|
32
|
-
"api key",
|
|
33
|
-
"apikey",
|
|
34
|
-
"unauthorized",
|
|
35
|
-
"401",
|
|
36
|
-
"authentication",
|
|
37
|
-
"not logged in",
|
|
38
|
-
"login"
|
|
39
|
-
];
|
|
40
106
|
var asRecord = (value) => value && typeof value === "object" && !Array.isArray(value) ? value : {};
|
|
41
107
|
var asString = (value) => typeof value === "string" && value.trim() ? value.trim() : void 0;
|
|
42
|
-
var isAuthErrorMessage = (message) => {
|
|
43
|
-
const lower = message.toLowerCase();
|
|
44
|
-
return AUTH_ERROR_PATTERNS.some((pattern) => lower.includes(pattern));
|
|
45
|
-
};
|
|
46
108
|
var readPersistedThreadId = (state) => {
|
|
47
109
|
const source = state.threadDetails?.state ?? state.channelDetails?.state;
|
|
48
110
|
const record = asRecord(source);
|
|
@@ -81,18 +143,41 @@ var parseModel = (value) => {
|
|
|
81
143
|
var itemWidget = (item) => {
|
|
82
144
|
switch (item.type) {
|
|
83
145
|
case "command_execution":
|
|
84
|
-
return {
|
|
146
|
+
return {
|
|
147
|
+
title: "Command",
|
|
148
|
+
body: [item.command, item.aggregated_output].filter(Boolean).join("\n\n")
|
|
149
|
+
};
|
|
85
150
|
case "file_change":
|
|
86
151
|
return {
|
|
87
152
|
title: "File change",
|
|
88
153
|
body: item.changes.map((change) => `${change.kind} ${change.path}`).join("\n")
|
|
89
154
|
};
|
|
155
|
+
case "mcp_tool_call":
|
|
156
|
+
return {
|
|
157
|
+
title: `${item.server}: ${item.tool}`,
|
|
158
|
+
body: item.error?.message ?? (item.result ? JSON.stringify(item.result, null, 2) : "")
|
|
159
|
+
};
|
|
160
|
+
case "web_search":
|
|
161
|
+
return { title: "Web search", body: item.query };
|
|
90
162
|
case "error":
|
|
91
163
|
return { title: "Error", body: item.message };
|
|
92
164
|
default:
|
|
93
165
|
return null;
|
|
94
166
|
}
|
|
95
167
|
};
|
|
168
|
+
var collectCodexChange = (path, kind, cwd, files) => {
|
|
169
|
+
if (kind === "add") {
|
|
170
|
+
try {
|
|
171
|
+
files.set(path, diffFileFromWrite(path, readFileSync(join(cwd, path), "utf8")));
|
|
172
|
+
return;
|
|
173
|
+
} catch {
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
files.set(path, {
|
|
177
|
+
path,
|
|
178
|
+
status: kind === "delete" ? "deleted" : kind === "add" ? "added" : "modified"
|
|
179
|
+
});
|
|
180
|
+
};
|
|
96
181
|
var errorText = (error) => error instanceof Error ? error.message : "Codex request failed.";
|
|
97
182
|
var buildApiKeyWidget = (agentId, threadId, reason) => uiWidget({
|
|
98
183
|
agentId,
|
|
@@ -127,11 +212,14 @@ var plugin = definePlugin({
|
|
|
127
212
|
configSchema: {
|
|
128
213
|
type: "object",
|
|
129
214
|
properties: {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
215
|
+
...isCloudMode() ? {
|
|
216
|
+
authMode: {
|
|
217
|
+
type: "string",
|
|
218
|
+
description: "Credits \u2014 use your workspace credit balance via OpenBot. BYOK \u2014 bring your own OpenAI API key.",
|
|
219
|
+
enum: ["credits", "byok"],
|
|
220
|
+
default: "credits"
|
|
221
|
+
}
|
|
222
|
+
} : {},
|
|
135
223
|
model: {
|
|
136
224
|
type: "string",
|
|
137
225
|
description: "Codex model id (e.g. gpt-5.6). Leave empty to use the CLI default."
|
|
@@ -148,19 +236,11 @@ var plugin = definePlugin({
|
|
|
148
236
|
description: "When to require approval: never | on-request | on-failure | untrusted",
|
|
149
237
|
default: "never"
|
|
150
238
|
},
|
|
151
|
-
workingDirectory: {
|
|
152
|
-
type: "string",
|
|
153
|
-
description: "Override the channel working directory"
|
|
154
|
-
},
|
|
155
239
|
skipGitRepoCheck: {
|
|
156
240
|
type: "boolean",
|
|
157
241
|
description: "Skip the Codex git-repo check (needed for non-git channel workspaces)",
|
|
158
242
|
default: true
|
|
159
243
|
},
|
|
160
|
-
baseURL: {
|
|
161
|
-
type: "string",
|
|
162
|
-
description: "Custom OpenAI-compatible endpoint"
|
|
163
|
-
},
|
|
164
244
|
codexPathOverride: {
|
|
165
245
|
type: "string",
|
|
166
246
|
description: "Path to a local Codex CLI binary"
|
|
@@ -169,24 +249,27 @@ var plugin = definePlugin({
|
|
|
169
249
|
},
|
|
170
250
|
factory: (context) => {
|
|
171
251
|
const config = context.config;
|
|
172
|
-
const
|
|
252
|
+
const authMode = resolveAuthMode(config);
|
|
173
253
|
const codexPathOverride = asString(config.codexPathOverride) ?? process.env.CODEX_PATH ?? process.env.CODEX_CLI_PATH;
|
|
174
254
|
const model = parseModel(config.model);
|
|
175
255
|
const sandboxMode = parseSandboxMode(config.sandboxMode);
|
|
176
256
|
const approvalPolicy = parseApprovalPolicy(config.approvalPolicy);
|
|
177
257
|
const skipGitRepoCheck = config.skipGitRepoCheck !== false;
|
|
178
|
-
const
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
...apiKey && { apiKey },
|
|
258
|
+
const createClient = () => {
|
|
259
|
+
if (authMode === "credits") {
|
|
260
|
+
const credits = resolveCreditsAuthConfig();
|
|
261
|
+
if (!credits) return CREDITS_NOT_CONFIGURED_MESSAGE;
|
|
262
|
+
return new Codex({
|
|
263
|
+
apiKey: credits.token || CREDITS_API_KEY_PLACEHOLDER,
|
|
185
264
|
...codexPathOverride && { codexPathOverride },
|
|
186
|
-
|
|
265
|
+
config: buildCreditsCodexConfig(credits)
|
|
187
266
|
});
|
|
188
267
|
}
|
|
189
|
-
|
|
268
|
+
const apiKey = process.env.CODEX_API_KEY ?? process.env.OPENAI_API_KEY;
|
|
269
|
+
return new Codex({
|
|
270
|
+
...asString(apiKey) && { apiKey: asString(apiKey) },
|
|
271
|
+
...codexPathOverride && { codexPathOverride }
|
|
272
|
+
});
|
|
190
273
|
};
|
|
191
274
|
return (builder) => {
|
|
192
275
|
builder.on("agent:invoke", async function* (event, ctx) {
|
|
@@ -201,7 +284,16 @@ var plugin = definePlugin({
|
|
|
201
284
|
});
|
|
202
285
|
return;
|
|
203
286
|
}
|
|
204
|
-
const
|
|
287
|
+
const clientOrError = createClient();
|
|
288
|
+
if (typeof clientOrError === "string") {
|
|
289
|
+
yield agentOutput({
|
|
290
|
+
agentId: context.agentId,
|
|
291
|
+
content: clientOrError,
|
|
292
|
+
threadId: openbotThreadId
|
|
293
|
+
});
|
|
294
|
+
return;
|
|
295
|
+
}
|
|
296
|
+
const workingDirectory = ctx.state.channelDetails?.cwd || process.cwd();
|
|
205
297
|
const threadOptions = {
|
|
206
298
|
workingDirectory,
|
|
207
299
|
skipGitRepoCheck,
|
|
@@ -210,8 +302,16 @@ var plugin = definePlugin({
|
|
|
210
302
|
...model && { model }
|
|
211
303
|
};
|
|
212
304
|
const savedId = readPersistedThreadId(ctx.state);
|
|
213
|
-
const thread = savedId ?
|
|
305
|
+
const thread = savedId ? clientOrError.resumeThread(savedId, threadOptions) : clientOrError.startThread(threadOptions);
|
|
214
306
|
const fail = function* (message) {
|
|
307
|
+
if (authMode === "credits") {
|
|
308
|
+
yield agentOutput({
|
|
309
|
+
agentId: context.agentId,
|
|
310
|
+
content: creditsErrorMessage(message) ?? `Error: ${message}`,
|
|
311
|
+
threadId: openbotThreadId
|
|
312
|
+
});
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
215
315
|
if (isAuthErrorMessage(message)) {
|
|
216
316
|
yield buildApiKeyWidget(context.agentId, openbotThreadId, message);
|
|
217
317
|
}
|
|
@@ -225,6 +325,8 @@ var plugin = definePlugin({
|
|
|
225
325
|
const { events } = await thread.runStreamed(content, {
|
|
226
326
|
signal: context.abortSignal
|
|
227
327
|
});
|
|
328
|
+
const snapshot = snapshotWorkspace(workingDirectory);
|
|
329
|
+
const changedFiles = /* @__PURE__ */ new Map();
|
|
228
330
|
for await (const chunk of events) {
|
|
229
331
|
if (chunk.type === "thread.started") {
|
|
230
332
|
await persistThreadId(ctx.state, context.storage, chunk.thread_id);
|
|
@@ -238,34 +340,98 @@ var plugin = definePlugin({
|
|
|
238
340
|
yield* fail(chunk.message);
|
|
239
341
|
return;
|
|
240
342
|
}
|
|
241
|
-
if (chunk.type !== "item.completed") continue;
|
|
343
|
+
if (chunk.type !== "item.started" && chunk.type !== "item.completed") continue;
|
|
242
344
|
if (chunk.item.type === "agent_message") {
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
345
|
+
if (chunk.type === "item.completed") {
|
|
346
|
+
yield agentOutput({
|
|
347
|
+
agentId: context.agentId,
|
|
348
|
+
content: chunk.item.text,
|
|
349
|
+
threadId: openbotThreadId
|
|
350
|
+
});
|
|
351
|
+
}
|
|
248
352
|
continue;
|
|
249
353
|
}
|
|
354
|
+
if (chunk.type === "item.completed" && chunk.item.type === "file_change" && chunk.item.status === "completed") {
|
|
355
|
+
for (const change of chunk.item.changes) {
|
|
356
|
+
collectCodexChange(change.path, change.kind, workingDirectory, changedFiles);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
250
359
|
const widget = itemWidget(chunk.item);
|
|
251
360
|
if (!widget) continue;
|
|
252
361
|
yield uiWidget({
|
|
253
362
|
agentId: context.agentId,
|
|
254
363
|
threadId: openbotThreadId,
|
|
255
|
-
widget: {
|
|
256
|
-
kind: "message",
|
|
364
|
+
widget: toolTraceWidget({
|
|
257
365
|
widgetId: `codex_${chunk.item.id}`,
|
|
366
|
+
groupId: "codex:tools",
|
|
258
367
|
title: widget.title,
|
|
259
368
|
body: widget.body,
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
369
|
+
state: chunk.type === "item.completed" && (chunk.item.type === "command_execution" && chunk.item.status === "failed" || chunk.item.type === "file_change" && chunk.item.status === "failed" || chunk.item.type === "mcp_tool_call" && chunk.item.status === "failed" || chunk.item.type === "error") ? "error" : chunk.type === "item.completed" ? "submitted" : void 0
|
|
370
|
+
})
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
const diff = buildDiffWidget({
|
|
374
|
+
widgetId: `codex-diff:${openbotThreadId ?? "run"}:${Date.now()}`,
|
|
375
|
+
files: resolveRunDiffFiles({
|
|
376
|
+
snapshot,
|
|
377
|
+
fallback: changedFiles.values()
|
|
378
|
+
})
|
|
379
|
+
});
|
|
380
|
+
if (diff) {
|
|
381
|
+
yield uiWidget({
|
|
382
|
+
agentId: context.agentId,
|
|
383
|
+
threadId: openbotThreadId,
|
|
384
|
+
widget: diff
|
|
263
385
|
});
|
|
264
386
|
}
|
|
265
387
|
} catch (error) {
|
|
266
388
|
yield* fail(errorText(error));
|
|
267
389
|
}
|
|
268
390
|
});
|
|
391
|
+
builder.on("client:ui:widget:response", async function* (event, ctx) {
|
|
392
|
+
const { metadata, values, widgetId } = event.data ?? {};
|
|
393
|
+
if (!metadata || metadata.type !== "api_key_request") return;
|
|
394
|
+
if (metadata.source !== "codex") return;
|
|
395
|
+
const apiKey = values?.apiKey;
|
|
396
|
+
if (typeof apiKey !== "string" || !apiKey) return;
|
|
397
|
+
const envVar = typeof metadata.envVar === "string" ? metadata.envVar : "OPENAI_API_KEY";
|
|
398
|
+
const storage = context.storage;
|
|
399
|
+
if (!storage) {
|
|
400
|
+
yield agentOutput({
|
|
401
|
+
agentId: context.agentId,
|
|
402
|
+
content: "[codex] no storage available; cannot persist API key.",
|
|
403
|
+
threadId: ctx.state.threadId
|
|
404
|
+
});
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
try {
|
|
408
|
+
await storage.createVariable({ key: envVar, value: apiKey, secret: true });
|
|
409
|
+
process.env[envVar] = apiKey;
|
|
410
|
+
process.env.CODEX_API_KEY = apiKey;
|
|
411
|
+
yield uiWidget({
|
|
412
|
+
agentId: context.agentId,
|
|
413
|
+
widget: {
|
|
414
|
+
widgetId: widgetId ?? `codex_api_key_saved_${Date.now()}`,
|
|
415
|
+
kind: "message",
|
|
416
|
+
title: "API Key Saved",
|
|
417
|
+
body: `Saved ${envVar} as a workspace variable. You can now continue the conversation.`,
|
|
418
|
+
state: "submitted"
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
yield agentOutput({
|
|
422
|
+
agentId: context.agentId,
|
|
423
|
+
content: "Saved OpenAI API key to workspace variables. Re-send your last message to retry.",
|
|
424
|
+
threadId: ctx.state.threadId
|
|
425
|
+
});
|
|
426
|
+
} catch (error) {
|
|
427
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
428
|
+
yield agentOutput({
|
|
429
|
+
agentId: context.agentId,
|
|
430
|
+
content: `[codex] failed to save API key: ${errorMessage}`,
|
|
431
|
+
threadId: ctx.state.threadId
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
});
|
|
269
435
|
};
|
|
270
436
|
}
|
|
271
437
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetopenbot/codex",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "OpenAI Codex agent plugin for OpenBot",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -17,20 +17,19 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"dist"
|
|
19
19
|
],
|
|
20
|
-
"scripts": {
|
|
21
|
-
"build": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod && node ../../scripts/write-plugin-declaration.mjs",
|
|
22
|
-
"dev": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod --watch",
|
|
23
|
-
"typecheck": "tsc --noEmit --allowImportingTsExtensions --module ESNext --moduleResolution Bundler --target ES2022 --skipLibCheck index.ts",
|
|
24
|
-
"prepack": "pnpm build"
|
|
25
|
-
},
|
|
26
20
|
"dependencies": {
|
|
27
|
-
"@
|
|
28
|
-
"@
|
|
21
|
+
"@openai/codex-sdk": "0.148.0",
|
|
22
|
+
"@meetopenbot/plugin-sdk": "^0.2.0"
|
|
29
23
|
},
|
|
30
24
|
"devDependencies": {
|
|
31
25
|
"@types/node": "^25.6.0",
|
|
32
26
|
"esbuild": "^0.21.0",
|
|
33
27
|
"zod": "^4.4.3"
|
|
34
28
|
},
|
|
35
|
-
"types": "./dist/index.d.ts"
|
|
36
|
-
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"scripts": {
|
|
31
|
+
"build": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod && node ../../scripts/write-plugin-declaration.mjs",
|
|
32
|
+
"dev": "esbuild index.ts --bundle --platform=node --format=esm --outfile=dist/index.js --external:@meetopenbot/plugin-sdk --external:@openai/codex-sdk --external:zod --watch",
|
|
33
|
+
"typecheck": "tsc --noEmit --allowImportingTsExtensions --module ESNext --moduleResolution Bundler --target ES2022 --skipLibCheck index.ts"
|
|
34
|
+
}
|
|
35
|
+
}
|