mirror of
https://github.com/clawdbot/clawdbot.git
synced 2026-01-31 11:27:45 +01:00
fix: restore tsc build and plugin install tests
This commit is contained in:
@@ -1083,10 +1083,11 @@ export function createExecTool(
|
||||
timeoutMs: DEFAULT_APPROVAL_TIMEOUT_MS,
|
||||
},
|
||||
);
|
||||
decision =
|
||||
const decisionValue =
|
||||
decisionResult && typeof decisionResult === "object"
|
||||
? (decisionResult.decision ?? null)
|
||||
: null;
|
||||
? (decisionResult as { decision?: unknown }).decision
|
||||
: undefined;
|
||||
decision = typeof decisionValue === "string" ? decisionValue : null;
|
||||
} catch {
|
||||
emitExecSystemEvent(
|
||||
`Exec denied (node=${nodeId} id=${approvalId}, approval-request-failed): ${commandText}`,
|
||||
@@ -1177,28 +1178,32 @@ export function createExecTool(
|
||||
}
|
||||
|
||||
const startedAt = Date.now();
|
||||
const raw = await callGatewayTool<{
|
||||
payload: {
|
||||
exitCode: number;
|
||||
success?: string;
|
||||
stdout?: string;
|
||||
stderr?: string;
|
||||
error?: string;
|
||||
};
|
||||
}>("node.invoke", { timeoutMs: invokeTimeoutMs }, buildInvokeParams(false, null));
|
||||
const payload = raw?.payload ?? {};
|
||||
const raw = await callGatewayTool(
|
||||
"node.invoke",
|
||||
{ timeoutMs: invokeTimeoutMs },
|
||||
buildInvokeParams(false, null),
|
||||
);
|
||||
const payload =
|
||||
raw && typeof raw === "object" ? (raw as { payload?: unknown }).payload : undefined;
|
||||
const payloadObj =
|
||||
payload && typeof payload === "object" ? (payload as Record<string, unknown>) : {};
|
||||
const stdout = typeof payloadObj.stdout === "string" ? payloadObj.stdout : "";
|
||||
const stderr = typeof payloadObj.stderr === "string" ? payloadObj.stderr : "";
|
||||
const errorText = typeof payloadObj.error === "string" ? payloadObj.error : "";
|
||||
const success = typeof payloadObj.success === "boolean" ? payloadObj.success : false;
|
||||
const exitCode = typeof payloadObj.exitCode === "number" ? payloadObj.exitCode : null;
|
||||
return {
|
||||
content: [
|
||||
{
|
||||
type: "text",
|
||||
text: payload.stdout || payload.stderr || payload.error || "",
|
||||
text: stdout || stderr || errorText || "",
|
||||
},
|
||||
],
|
||||
details: {
|
||||
status: payload.success ? "completed" : "failed",
|
||||
exitCode: payload.exitCode ?? null,
|
||||
status: success ? "completed" : "failed",
|
||||
exitCode,
|
||||
durationMs: Date.now() - startedAt,
|
||||
aggregated: [payload.stdout, payload.stderr, payload.error].filter(Boolean).join("\n"),
|
||||
aggregated: [stdout, stderr, errorText].filter(Boolean).join("\n"),
|
||||
cwd: workdir,
|
||||
} satisfies ExecToolDetails,
|
||||
};
|
||||
@@ -1261,10 +1266,11 @@ export function createExecTool(
|
||||
timeoutMs: DEFAULT_APPROVAL_TIMEOUT_MS,
|
||||
},
|
||||
);
|
||||
decision =
|
||||
const decisionValue =
|
||||
decisionResult && typeof decisionResult === "object"
|
||||
? (decisionResult.decision ?? null)
|
||||
: null;
|
||||
? (decisionResult as { decision?: unknown }).decision
|
||||
: undefined;
|
||||
decision = typeof decisionValue === "string" ? decisionValue : null;
|
||||
} catch {
|
||||
emitExecSystemEvent(
|
||||
`Exec denied (gateway id=${approvalId}, approval-request-failed): ${commandText}`,
|
||||
|
||||
@@ -361,7 +361,7 @@ async function mapWithConcurrency<T, R>(
|
||||
opts?: { onProgress?: (completed: number, total: number) => void },
|
||||
): Promise<R[]> {
|
||||
const limit = Math.max(1, Math.floor(concurrency));
|
||||
const results: R[] = Array.from({ length: items.length });
|
||||
const results: R[] = Array.from({ length: items.length }, () => undefined as R);
|
||||
let nextIndex = 0;
|
||||
let completed = 0;
|
||||
|
||||
|
||||
@@ -869,7 +869,7 @@ export async function runEmbeddedAttempt(
|
||||
const lastAssistant = messagesSnapshot
|
||||
.slice()
|
||||
.toReversed()
|
||||
.find((m) => m?.role === "assistant");
|
||||
.find((m) => m.role === "assistant");
|
||||
|
||||
const toolMetasNormalized = toolMetas
|
||||
.filter(
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import type { OpenClawConfig } from "../config/config.js";
|
||||
import { SkillsInstallPreferences } from "./skills/types.js";
|
||||
import type { SkillsInstallPreferences } from "./skills/types.js";
|
||||
|
||||
export {
|
||||
hasBinary,
|
||||
@@ -38,7 +38,7 @@ export function resolveSkillsInstallPreferences(config?: OpenClawConfig): Skills
|
||||
const preferBrew = raw?.preferBrew ?? true;
|
||||
const managerRaw = typeof raw?.nodeManager === "string" ? raw.nodeManager.trim() : "";
|
||||
const manager = managerRaw.toLowerCase();
|
||||
const nodeManager =
|
||||
const nodeManager: SkillsInstallPreferences["nodeManager"] =
|
||||
manager === "pnpm" || manager === "yarn" || manager === "bun" || manager === "npm"
|
||||
? manager
|
||||
: "npm";
|
||||
|
||||
@@ -382,10 +382,11 @@ export async function runSubagentAnnounceFlow(params: {
|
||||
},
|
||||
timeoutMs: waitMs + 2000,
|
||||
});
|
||||
const waitError = typeof wait?.error === "string" ? wait.error : undefined;
|
||||
if (wait?.status === "timeout") {
|
||||
outcome = { status: "timeout" };
|
||||
} else if (wait?.status === "error") {
|
||||
outcome = { status: "error", error: wait.error };
|
||||
outcome = { status: "error", error: waitError };
|
||||
} else if (wait?.status === "ok") {
|
||||
outcome = { status: "ok" };
|
||||
}
|
||||
|
||||
@@ -355,8 +355,9 @@ async function waitForSubagentCompletion(runId: string, waitTimeoutMs: number) {
|
||||
entry.endedAt = Date.now();
|
||||
mutated = true;
|
||||
}
|
||||
const waitError = typeof wait.error === "string" ? wait.error : undefined;
|
||||
entry.outcome =
|
||||
wait.status === "error" ? { status: "error", error: wait.error } : { status: "ok" };
|
||||
wait.status === "error" ? { status: "error", error: waitError } : { status: "ok" };
|
||||
mutated = true;
|
||||
if (mutated) {
|
||||
persistSubagentRuns();
|
||||
|
||||
@@ -149,10 +149,10 @@ async function callBrowserProxy(params: {
|
||||
(typeof payload?.payloadJSON === "string" && payload.payloadJSON
|
||||
? (JSON.parse(payload.payloadJSON) as BrowserProxyResult)
|
||||
: null);
|
||||
if (!parsed || typeof parsed !== "object") {
|
||||
if (!parsed || typeof parsed !== "object" || !("result" in parsed)) {
|
||||
throw new Error("browser proxy failed");
|
||||
}
|
||||
return parsed;
|
||||
return parsed as BrowserProxyResult;
|
||||
}
|
||||
|
||||
async function persistProxyFiles(files: BrowserProxyFile[] | undefined) {
|
||||
|
||||
@@ -26,7 +26,7 @@ export function resolveGatewayOptions(opts?: GatewayCallOptions) {
|
||||
return { url, token, timeoutMs };
|
||||
}
|
||||
|
||||
export async function callGatewayTool<T = unknown>(
|
||||
export async function callGatewayTool<T = Record<string, unknown>>(
|
||||
method: string,
|
||||
opts: GatewayCallOptions,
|
||||
params?: unknown,
|
||||
|
||||
@@ -383,9 +383,8 @@ export const handleSubagentsCommand: CommandHandler = async (params, allowTextCo
|
||||
},
|
||||
timeoutMs: 10_000,
|
||||
});
|
||||
if (response?.runId) {
|
||||
runId = response.runId;
|
||||
}
|
||||
const responseRunId = typeof response?.runId === "string" ? response.runId : undefined;
|
||||
if (responseRunId) runId = responseRunId;
|
||||
} catch (err) {
|
||||
const messageText =
|
||||
err instanceof Error ? err.message : typeof err === "string" ? err : "error";
|
||||
@@ -405,10 +404,11 @@ export const handleSubagentsCommand: CommandHandler = async (params, allowTextCo
|
||||
};
|
||||
}
|
||||
if (wait?.status === "error") {
|
||||
const waitError = typeof wait.error === "string" ? wait.error : "unknown error";
|
||||
return {
|
||||
shouldContinue: false,
|
||||
reply: {
|
||||
text: `⚠️ Subagent error: ${wait.error ?? "unknown error"} (run ${runId.slice(0, 8)}).`,
|
||||
text: `⚠️ Subagent error: ${waitError} (run ${runId.slice(0, 8)}).`,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -254,8 +254,7 @@ export function registerGatewayCli(program: Command) {
|
||||
return;
|
||||
}
|
||||
const rich = isRich();
|
||||
const obj =
|
||||
result && typeof result === "object" ? (result as Record<string, unknown>) : {};
|
||||
const obj: Record<string, unknown> = result && typeof result === "object" ? result : {};
|
||||
const durationMs = typeof obj.durationMs === "number" ? obj.durationMs : null;
|
||||
defaultRuntime.log(colorize(rich, theme.heading, "Gateway Health"));
|
||||
defaultRuntime.log(
|
||||
|
||||
@@ -107,10 +107,8 @@ export function registerNodesStatusCommands(nodes: Command) {
|
||||
const connectedOnly = Boolean(opts.connected);
|
||||
const sinceMs = parseSinceMs(opts.lastConnected, "Invalid --last-connected");
|
||||
const result = await callGatewayCli("node.list", opts, {});
|
||||
const obj =
|
||||
typeof result === "object" && result !== null
|
||||
? (result as Record<string, unknown>)
|
||||
: {};
|
||||
const obj: Record<string, unknown> =
|
||||
typeof result === "object" && result !== null ? result : {};
|
||||
const { ok, warn, muted } = getNodesTheme();
|
||||
const tableWidth = Math.max(60, (process.stdout.columns ?? 120) - 1);
|
||||
const now = Date.now();
|
||||
@@ -227,10 +225,8 @@ export function registerNodesStatusCommands(nodes: Command) {
|
||||
return;
|
||||
}
|
||||
|
||||
const obj =
|
||||
typeof result === "object" && result !== null
|
||||
? (result as Record<string, unknown>)
|
||||
: {};
|
||||
const obj: Record<string, unknown> =
|
||||
typeof result === "object" && result !== null ? result : {};
|
||||
const displayName = typeof obj.displayName === "string" ? obj.displayName : nodeId;
|
||||
const connected = Boolean(obj.connected);
|
||||
const paired = Boolean(obj.paired);
|
||||
|
||||
@@ -268,7 +268,7 @@ export async function channelsStatusCommand(
|
||||
runtime.log(JSON.stringify(payload, null, 2));
|
||||
return;
|
||||
}
|
||||
runtime.log(formatGatewayChannelsStatusLines(payload as Record<string, unknown>).join("\n"));
|
||||
runtime.log(formatGatewayChannelsStatusLines(payload).join("\n"));
|
||||
} catch (err) {
|
||||
runtime.error(`Gateway not reachable: ${String(err)}`);
|
||||
const cfg = await requireValidConfig(runtime);
|
||||
|
||||
@@ -30,7 +30,7 @@ export async function checkGatewayHealth(params: {
|
||||
|
||||
if (healthOk) {
|
||||
try {
|
||||
const status = await callGateway<Record<string, unknown>>({
|
||||
const status = await callGateway({
|
||||
method: "channels.status",
|
||||
params: { probe: true, timeoutMs: 5000 },
|
||||
timeoutMs: 6000,
|
||||
|
||||
@@ -230,7 +230,7 @@ export async function statusAllCommand(
|
||||
: { error: gatewayProbe?.error ?? "gateway unreachable" };
|
||||
|
||||
const channelsStatus = gatewayReachable
|
||||
? await callGateway<Record<string, unknown>>({
|
||||
? await callGateway({
|
||||
method: "channels.status",
|
||||
params: { probe: false, timeoutMs: opts?.timeoutMs ?? 10_000 },
|
||||
timeoutMs: Math.min(8000, opts?.timeoutMs ?? 10_000),
|
||||
|
||||
@@ -127,7 +127,7 @@ export async function scanStatus(
|
||||
|
||||
progress.setLabel("Querying channel status…");
|
||||
const channelsStatus = gatewayReachable
|
||||
? await callGateway<Record<string, unknown>>({
|
||||
? await callGateway({
|
||||
method: "channels.status",
|
||||
params: {
|
||||
probe: false,
|
||||
|
||||
@@ -16,6 +16,14 @@ type DiscordChannelSummary = {
|
||||
archived?: boolean;
|
||||
};
|
||||
|
||||
type DiscordChannelPayload = {
|
||||
id?: string;
|
||||
name?: string;
|
||||
type?: number;
|
||||
guild_id?: string;
|
||||
thread_metadata?: { archived?: boolean };
|
||||
};
|
||||
|
||||
export type DiscordChannelResolution = {
|
||||
input: string;
|
||||
resolved: boolean;
|
||||
@@ -83,27 +91,23 @@ async function listGuildChannels(
|
||||
fetcher: typeof fetch,
|
||||
guildId: string,
|
||||
): Promise<DiscordChannelSummary[]> {
|
||||
const raw = await fetchDiscord<Array<DiscordChannelSummary>>(
|
||||
const raw = await fetchDiscord<DiscordChannelPayload[]>(
|
||||
`/guilds/${guildId}/channels`,
|
||||
token,
|
||||
fetcher,
|
||||
);
|
||||
return raw
|
||||
.filter((channel) => Boolean(channel.id) && "name" in channel)
|
||||
.map((channel) => {
|
||||
const archived =
|
||||
"thread_metadata" in channel
|
||||
? (channel as { thread_metadata?: { archived?: boolean } }).thread_metadata?.archived
|
||||
: undefined;
|
||||
const archived = channel.thread_metadata?.archived;
|
||||
return {
|
||||
id: channel.id,
|
||||
name: "name" in channel ? (channel.name ?? "") : "",
|
||||
id: typeof channel.id === "string" ? channel.id : "",
|
||||
name: typeof channel.name === "string" ? channel.name : "",
|
||||
guildId,
|
||||
type: channel.type,
|
||||
archived,
|
||||
};
|
||||
})
|
||||
.filter((channel) => Boolean(channel.name));
|
||||
.filter((channel) => Boolean(channel.id) && Boolean(channel.name));
|
||||
}
|
||||
|
||||
async function fetchChannel(
|
||||
@@ -111,18 +115,12 @@ async function fetchChannel(
|
||||
fetcher: typeof fetch,
|
||||
channelId: string,
|
||||
): Promise<DiscordChannelSummary | null> {
|
||||
const raw = await fetchDiscord<DiscordChannelSummary & { guild_id: string }>(
|
||||
`/channels/${channelId}`,
|
||||
token,
|
||||
fetcher,
|
||||
);
|
||||
if (!raw || !("guild_id" in raw)) {
|
||||
return null;
|
||||
}
|
||||
const raw = await fetchDiscord<DiscordChannelPayload>(`/channels/${channelId}`, token, fetcher);
|
||||
if (!raw || typeof raw.guild_id !== "string" || typeof raw.id !== "string") return null;
|
||||
return {
|
||||
id: raw.id,
|
||||
name: "name" in raw ? (raw.name ?? "") : "",
|
||||
guildId: raw.guild_id ?? "",
|
||||
name: typeof raw.name === "string" ? raw.name : "",
|
||||
guildId: raw.guild_id,
|
||||
type: raw.type,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -109,7 +109,9 @@ export function buildGatewayConnectionDetails(
|
||||
};
|
||||
}
|
||||
|
||||
export async function callGateway<T = unknown>(opts: CallGatewayOptions): Promise<T> {
|
||||
export async function callGateway<T = Record<string, unknown>>(
|
||||
opts: CallGatewayOptions,
|
||||
): Promise<T> {
|
||||
const timeoutMs = opts.timeoutMs ?? 10_000;
|
||||
const config = opts.config ?? loadConfig();
|
||||
const isRemoteMode = config.gateway?.mode === "remote";
|
||||
|
||||
@@ -411,7 +411,7 @@ export class GatewayClient {
|
||||
return null;
|
||||
}
|
||||
|
||||
async request<T = unknown>(
|
||||
async request<T = Record<string, unknown>>(
|
||||
method: string,
|
||||
params?: unknown,
|
||||
opts?: { expectFinal?: boolean },
|
||||
|
||||
@@ -329,7 +329,7 @@ describeLive("gateway live (cli backend)", () => {
|
||||
providerId === "codex-cli"
|
||||
? `Please include the token CLI-BACKEND-${nonce} in your reply.`
|
||||
: `Reply with exactly: CLI backend OK ${nonce}.`;
|
||||
const payload = await client.request<Record<string, unknown>>(
|
||||
const payload = await client.request(
|
||||
"agent",
|
||||
{
|
||||
sessionKey,
|
||||
@@ -356,7 +356,7 @@ describeLive("gateway live (cli backend)", () => {
|
||||
providerId === "codex-cli"
|
||||
? `Please include the token CLI-RESUME-${resumeNonce} in your reply.`
|
||||
: `Reply with exactly: CLI backend RESUME OK ${resumeNonce}.`;
|
||||
const resumePayload = await client.request<Record<string, unknown>>(
|
||||
const resumePayload = await client.request(
|
||||
"agent",
|
||||
{
|
||||
sessionKey,
|
||||
@@ -383,7 +383,7 @@ describeLive("gateway live (cli backend)", () => {
|
||||
const imageBase64 = renderCatNoncePngBase64(imageCode);
|
||||
const runIdImage = randomUUID();
|
||||
|
||||
const imageProbe = await client.request<Record<string, unknown>>(
|
||||
const imageProbe = await client.request(
|
||||
"agent",
|
||||
{
|
||||
sessionKey,
|
||||
|
||||
@@ -603,10 +603,10 @@ async function runGatewayModelSuite(params: GatewayModelSuiteParams) {
|
||||
// Ensure session exists + override model for this run.
|
||||
// Reset between models: avoids cross-provider transcript incompatibilities
|
||||
// (notably OpenAI Responses requiring reasoning replay for function_call items).
|
||||
await client.request<Record<string, unknown>>("sessions.reset", {
|
||||
await client.request("sessions.reset", {
|
||||
key: sessionKey,
|
||||
});
|
||||
await client.request<Record<string, unknown>>("sessions.patch", {
|
||||
await client.request("sessions.patch", {
|
||||
key: sessionKey,
|
||||
model: modelKey,
|
||||
});
|
||||
@@ -1164,11 +1164,11 @@ describeLive("gateway live (dev agent, profile keys)", () => {
|
||||
try {
|
||||
const sessionKey = `agent:${agentId}:live-zai-fallback`;
|
||||
|
||||
await client.request<Record<string, unknown>>("sessions.patch", {
|
||||
await client.request("sessions.patch", {
|
||||
key: sessionKey,
|
||||
model: "anthropic/claude-opus-4-5",
|
||||
});
|
||||
await client.request<Record<string, unknown>>("sessions.reset", {
|
||||
await client.request("sessions.reset", {
|
||||
key: sessionKey,
|
||||
});
|
||||
|
||||
@@ -1200,7 +1200,7 @@ describeLive("gateway live (dev agent, profile keys)", () => {
|
||||
throw new Error(`anthropic tool probe missing nonce: ${toolText}`);
|
||||
}
|
||||
|
||||
await client.request<Record<string, unknown>>("sessions.patch", {
|
||||
await client.request("sessions.patch", {
|
||||
key: sessionKey,
|
||||
model: "zai/glm-4.7",
|
||||
});
|
||||
|
||||
@@ -109,7 +109,7 @@ describe("gateway e2e", () => {
|
||||
try {
|
||||
const sessionKey = "agent:dev:mock-openai";
|
||||
|
||||
await client.request<Record<string, unknown>>("sessions.patch", {
|
||||
await client.request("sessions.patch", {
|
||||
key: sessionKey,
|
||||
model: "openai/gpt-5.2",
|
||||
});
|
||||
|
||||
@@ -125,7 +125,7 @@ export async function sendMessageIMessage(
|
||||
const client = opts.client ?? (await createIMessageRpcClient({ cliPath, dbPath }));
|
||||
const shouldClose = !opts.client;
|
||||
try {
|
||||
const result = await client.request<Record<string, unknown>>("send", params, {
|
||||
const result = await client.request("send", params, {
|
||||
timeoutMs: opts.timeoutMs,
|
||||
});
|
||||
const resolvedId = resolveMessageId(result);
|
||||
|
||||
@@ -106,7 +106,7 @@ describe("installPluginFromArchive", () => {
|
||||
}),
|
||||
"utf-8",
|
||||
);
|
||||
fs.writeFileSync(path.join(pkgDir, "dist", "index.js"), "export {};", "utf-8");
|
||||
fs.writeFileSync(path.join(pkgDir, "dist", "index.mjs"), "export {};", "utf-8");
|
||||
|
||||
const archivePath = packToArchive({
|
||||
pkgDir,
|
||||
@@ -127,7 +127,7 @@ describe("installPluginFromArchive", () => {
|
||||
expect(result.pluginId).toBe("voice-call");
|
||||
expect(result.targetDir).toBe(path.join(stateDir, "extensions", "voice-call"));
|
||||
expect(fs.existsSync(path.join(result.targetDir, "package.json"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.js"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.mjs"))).toBe(true);
|
||||
});
|
||||
|
||||
it("rejects installing when plugin already exists", async () => {
|
||||
@@ -203,7 +203,7 @@ describe("installPluginFromArchive", () => {
|
||||
expect(result.pluginId).toBe("zipper");
|
||||
expect(result.targetDir).toBe(path.join(stateDir, "extensions", "zipper"));
|
||||
expect(fs.existsSync(path.join(result.targetDir, "package.json"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.js"))).toBe(true);
|
||||
expect(fs.existsSync(path.join(result.targetDir, "dist", "index.mjs"))).toBe(true);
|
||||
});
|
||||
|
||||
it("allows updates when mode is update", async () => {
|
||||
|
||||
@@ -45,10 +45,10 @@ export async function configureGatewayForOnboarding(
|
||||
10,
|
||||
);
|
||||
|
||||
let bind =
|
||||
let bind: GatewayWizardSettings["bind"] =
|
||||
flow === "quickstart"
|
||||
? quickstartGateway.bind
|
||||
: await prompter.select({
|
||||
: await prompter.select<GatewayWizardSettings["bind"]>({
|
||||
message: "Gateway bind",
|
||||
options: [
|
||||
{ value: "loopback", label: "Loopback (127.0.0.1)" },
|
||||
@@ -107,10 +107,10 @@ export async function configureGatewayForOnboarding(
|
||||
initialValue: "token",
|
||||
})) as GatewayAuthChoice);
|
||||
|
||||
const tailscaleMode =
|
||||
const tailscaleMode: GatewayWizardSettings["tailscaleMode"] =
|
||||
flow === "quickstart"
|
||||
? quickstartGateway.tailscaleMode
|
||||
: await prompter.select({
|
||||
: await prompter.select<GatewayWizardSettings["tailscaleMode"]>({
|
||||
message: "Tailscale exposure",
|
||||
options: [
|
||||
{ value: "off", label: "Off", hint: "No Tailscale exposure" },
|
||||
|
||||
@@ -240,7 +240,7 @@ describe("provider timeouts (e2e)", () => {
|
||||
|
||||
try {
|
||||
const sessionKey = "agent:dev:timeout-fallback";
|
||||
await client.request<Record<string, unknown>>("sessions.patch", {
|
||||
await client.request("sessions.patch", {
|
||||
key: sessionKey,
|
||||
model: "primary/gpt-5.2",
|
||||
});
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"module": "NodeNext",
|
||||
"moduleResolution": "NodeNext",
|
||||
"lib": ["DOM", "DOM.Iterable", "ES2023", "ScriptHost"],
|
||||
"noEmit": true,
|
||||
"noEmitOnError": true,
|
||||
"outDir": "dist",
|
||||
|
||||
Reference in New Issue
Block a user