From 60b0e305cae711f6c8f27cc03f8f9e94126c2ff4 Mon Sep 17 00:00:00 2001
From: PunGrumpy <108584943+PunGrumpy@users.noreply.github.com>
Date: Mon, 11 May 2026 20:35:43 +0700
Subject: [PATCH 1/7] refactor(agent): migrate to official @cursor/sdk and
composite action
---
.changeset/migrate-sdk.md | 5 +
__tests__/cursor-version.test.ts | 38 ---
__tests__/input.test.ts | 34 ++-
__tests__/installer.test.ts | 85 ------
__tests__/output.test.ts | 21 +-
__tests__/runner.test.ts | 286 ++++----------------
action.yml | 29 +-
bun.lock | 440 +++++++++++++++++++++++++++----
package.json | 11 +-
src/cursor-version.ts | 25 --
src/index.ts | 17 +-
src/input.ts | 36 +--
src/installer.ts | 297 ---------------------
src/output.ts | 38 +--
src/runner.ts | 415 +++--------------------------
src/types.ts | 19 +-
tsconfig.json | 1 +
tsdown.config.ts | 12 +
18 files changed, 561 insertions(+), 1248 deletions(-)
create mode 100644 .changeset/migrate-sdk.md
delete mode 100644 __tests__/cursor-version.test.ts
delete mode 100644 __tests__/installer.test.ts
delete mode 100644 src/cursor-version.ts
delete mode 100644 src/installer.ts
create mode 100644 tsdown.config.ts
diff --git a/.changeset/migrate-sdk.md b/.changeset/migrate-sdk.md
new file mode 100644
index 0000000..f60eb0d
--- /dev/null
+++ b/.changeset/migrate-sdk.md
@@ -0,0 +1,5 @@
+---
+"@pungrumpy/cursor-action": major
+---
+
+Migrate to the official `@cursor/sdk` and update action execution type to composite.
diff --git a/__tests__/cursor-version.test.ts b/__tests__/cursor-version.test.ts
deleted file mode 100644
index c7b7992..0000000
--- a/__tests__/cursor-version.test.ts
+++ /dev/null
@@ -1,38 +0,0 @@
-import { describe, expect, it } from "bun:test";
-
-import {
- extractLabVersionFromInstallScript,
- parseLabVersionString,
-} from "../src/cursor-version";
-
-describe("parseLabVersionString", () => {
- it("accepts lab build id with optional v prefix and trailing newline", () => {
- expect(parseLabVersionString("v2026.03.20-44cb435\n")).toBe(
- "2026.03.20-44cb435"
- );
- });
-
- it("rejects S3 AccessDenied XML bodies", () => {
- expect(
- parseLabVersionString(
- 'AccessDenied'
- )
- ).toBeNull();
- });
-});
-
-describe("extractLabVersionFromInstallScript", () => {
- it("parses DOWNLOAD_URL from bash installer", () => {
- const script = `DOWNLOAD_URL="https://downloads.cursor.com/lab/2026.03.20-44cb435/\${OS}/\${ARCH}/agent-cli-package.tar.gz"`;
- expect(extractLabVersionFromInstallScript(script)).toBe(
- "2026.03.20-44cb435"
- );
- });
-
- it("parses lab URL from PowerShell installer", () => {
- const script = `$downloadUrl = 'https://downloads.cursor.com/lab/2026.03.20-44cb435/'`;
- expect(extractLabVersionFromInstallScript(script)).toBe(
- "2026.03.20-44cb435"
- );
- });
-});
diff --git a/__tests__/input.test.ts b/__tests__/input.test.ts
index f819cf7..dbc4b93 100644
--- a/__tests__/input.test.ts
+++ b/__tests__/input.test.ts
@@ -43,28 +43,31 @@ describe("getInputs", () => {
expect(inputs.timeout).toBe(300);
});
- it("accepts a pinned semver version", () => {
+ it("warns if cursor-version is provided and not latest", () => {
setupInputs({ "cursor-version": "1.2.3" });
const inputs = getInputs();
expect(inputs.cursorVersion).toBe("1.2.3");
+ expect(mockWarning).toHaveBeenCalledWith(
+ expect.stringContaining("deprecated")
+ );
});
- it("accepts a pinned semver version with v prefix", () => {
- setupInputs({ "cursor-version": "v1.2.3" });
- const inputs = getInputs();
- expect(inputs.cursorVersion).toBe("v1.2.3");
- });
-
- it("accepts a pinned Cursor lab build id", () => {
- setupInputs({ "cursor-version": "2026.03.20-44cb435" });
+ it("treats empty cursor-version as omitted (undefined), matching optional typing", () => {
+ setupInputs({ "cursor-version": "" });
const inputs = getInputs();
- expect(inputs.cursorVersion).toBe("2026.03.20-44cb435");
+ expect(inputs.cursorVersion).toBeUndefined();
+ expect(mockWarning).not.toHaveBeenCalledWith(
+ expect.stringContaining("deprecated")
+ );
});
- it("accepts a pinned lab build id with v prefix", () => {
- setupInputs({ "cursor-version": "v2026.03.20-44cb435" });
+ it("trims cursor-version whitespace", () => {
+ setupInputs({ "cursor-version": " 1.0.0 " });
const inputs = getInputs();
- expect(inputs.cursorVersion).toBe("v2026.03.20-44cb435");
+ expect(inputs.cursorVersion).toBe("1.0.0");
+ expect(mockWarning).toHaveBeenCalledWith(
+ expect.stringContaining("deprecated")
+ );
});
it("throws on invalid permission value", () => {
@@ -87,11 +90,6 @@ describe("getInputs", () => {
expect(() => getInputs()).toThrow(/cannot be empty/);
});
- it("throws on invalid version format", () => {
- setupInputs({ "cursor-version": "not-a-version" });
- expect(() => getInputs()).toThrow(/Invalid 'cursor-version'/);
- });
-
it("warns on very long timeout", () => {
setupInputs({ timeout: "7200" });
getInputs();
diff --git a/__tests__/installer.test.ts b/__tests__/installer.test.ts
deleted file mode 100644
index b11422c..0000000
--- a/__tests__/installer.test.ts
+++ /dev/null
@@ -1,85 +0,0 @@
-import { beforeEach, describe, expect, it, mock } from "bun:test";
-
-import * as actionsHttpClient from "@actions/http-client";
-
-const mockHttpGet = mock();
-
-class MockHttpClient {
- public get = mockHttpGet;
-}
-
-mock.module("@actions/http-client", () => ({
- ...actionsHttpClient,
- HttpClient: MockHttpClient,
-}));
-
-const { buildDownloadUrl, resolveVersion } = await import("../src/installer");
-
-describe("resolveVersion", () => {
- beforeEach(() => {
- mock.clearAllMocks();
- });
-
- it("resolves latest from Cursor endpoint and normalizes v prefix", () => {
- mockHttpGet.mockResolvedValue({
- message: { statusCode: 200 },
- readBody: mock(() => Promise.resolve("v2026.03.20-44cb435\n")),
- });
-
- expect(resolveVersion("latest")).resolves.toBe("2026.03.20-44cb435");
- expect(mockHttpGet).toHaveBeenCalledTimes(1);
- expect(mockHttpGet).toHaveBeenCalledWith(
- "https://downloads.cursor.com/lab/latest-version"
- );
- });
-
- it("falls back to install script when latest-version is non-200", () => {
- const accessDeniedXml = `AccessDenied`;
- const bashSnippet = `DOWNLOAD_URL="https://downloads.cursor.com/lab/2026.03.20-44cb435/\${OS}/\${ARCH}/agent-cli-package.tar.gz"`;
-
- mockHttpGet
- .mockResolvedValueOnce({
- message: { statusCode: 403 },
- readBody: mock(() => Promise.resolve(accessDeniedXml)),
- })
- .mockResolvedValueOnce({
- message: { statusCode: 200 },
- readBody: mock(() =>
- Promise.resolve(`#!/usr/bin/env bash\n${bashSnippet}\n`)
- ),
- });
-
- expect(resolveVersion("latest")).resolves.toBe("2026.03.20-44cb435");
- expect(mockHttpGet).toHaveBeenCalledTimes(2);
- expect(mockHttpGet).toHaveBeenNthCalledWith(
- 1,
- "https://downloads.cursor.com/lab/latest-version"
- );
- expect(mockHttpGet).toHaveBeenNthCalledWith(
- 2,
- "https://cursor.com/install"
- );
- });
-
- it("returns pinned version without calling network", () => {
- expect(resolveVersion("v1.2.3")).resolves.toBe("1.2.3");
- expect(mockHttpGet).not.toHaveBeenCalled();
- });
-});
-
-describe("buildDownloadUrl", () => {
- it("uses windows path segment and zip extension for win32", () => {
- expect(buildDownloadUrl("1.2.3", "win32", "x64")).toBe(
- "https://downloads.cursor.com/lab/1.2.3/windows/x64/agent-cli-package.zip"
- );
- });
-
- it("uses tar.gz for linux and darwin", () => {
- expect(buildDownloadUrl("1.2.3", "linux", "arm64")).toBe(
- "https://downloads.cursor.com/lab/1.2.3/linux/arm64/agent-cli-package.tar.gz"
- );
- expect(buildDownloadUrl("1.2.3", "darwin", "x64")).toBe(
- "https://downloads.cursor.com/lab/1.2.3/darwin/x64/agent-cli-package.tar.gz"
- );
- });
-});
diff --git a/__tests__/output.test.ts b/__tests__/output.test.ts
index 0a76e72..eb19f26 100644
--- a/__tests__/output.test.ts
+++ b/__tests__/output.test.ts
@@ -36,17 +36,15 @@ describe("setOutputs", () => {
stderr: "",
stdout: "Here is my analysis.",
};
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(mockSetOutput).toHaveBeenCalledWith(
"summary",
"Here is my analysis."
);
expect(mockSetOutput).toHaveBeenCalledWith("exit-code", "0");
- expect(mockSetOutput).toHaveBeenCalledWith("cache-hit", "false");
expect(outputs.summary).toBe("Here is my analysis.");
expect(outputs.exitCode).toBe(0);
- expect(outputs.cacheHit).toBe(false);
expect(mockSummaryChain.write).toHaveBeenCalled();
});
@@ -56,9 +54,8 @@ describe("setOutputs", () => {
stderr: "",
stdout: JSON.stringify({ response: "JSON response text" }),
};
- const outputs = await setOutputs(result, true);
+ const outputs = await setOutputs(result);
expect(outputs.summary).toBe("JSON response text");
- expect(outputs.cacheHit).toBe(true);
});
it("extracts summary from JSON summary field", async () => {
@@ -67,7 +64,7 @@ describe("setOutputs", () => {
stderr: "",
stdout: JSON.stringify({ summary: "Summary field text" }),
};
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(outputs.summary).toBe("Summary field text");
});
@@ -77,7 +74,7 @@ describe("setOutputs", () => {
stderr: "",
stdout: JSON.stringify({ result: "Result field text" }),
};
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(outputs.summary).toBe("Result field text");
});
@@ -87,7 +84,7 @@ describe("setOutputs", () => {
stderr: "",
stdout: JSON.stringify({ output: "Output field text" }),
};
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(outputs.summary).toBe("Output field text");
});
@@ -97,13 +94,13 @@ describe("setOutputs", () => {
stderr: "",
stdout: JSON.stringify({ text: "Text field value" }),
};
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(outputs.summary).toBe("Text field value");
});
it("handles empty stdout gracefully", async () => {
const result = { exitCode: 0, stderr: "", stdout: "" };
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(outputs.summary).toBe("");
});
@@ -113,7 +110,7 @@ describe("setOutputs", () => {
stderr: "",
stdout: "\u001B[32mGreen text\u001B[0m",
};
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(outputs.summary).toBe("Green text");
});
@@ -123,7 +120,7 @@ describe("setOutputs", () => {
stderr: "something failed",
stdout: "error output",
};
- const outputs = await setOutputs(result, false);
+ const outputs = await setOutputs(result);
expect(outputs.exitCode).toBe(1);
expect(mockSetOutput).toHaveBeenCalledWith("exit-code", "1");
});
diff --git a/__tests__/runner.test.ts b/__tests__/runner.test.ts
index b7afc7e..f9d61e6 100644
--- a/__tests__/runner.test.ts
+++ b/__tests__/runner.test.ts
@@ -1,26 +1,10 @@
import { beforeEach, describe, expect, it, mock } from "bun:test";
import * as actionsCore from "@actions/core";
-import type { ExecOptions } from "@actions/exec";
import type { ActionInputs } from "../src/types";
-type ExecFn = (
- commandLine: string,
- args?: string[],
- options?: ExecOptions
-) => Promise;
-
-type GetExecOutputFn = (
- commandLine: string,
- args?: string[],
- options?: ExecOptions
-) => Promise<{ exitCode: number; stderr: string; stdout: string }>;
-
-const mockExec = mock();
-const mockGetExecOutput = mock();
const mockWarning = mock();
-
mock.module("@actions/core", () => ({
...actionsCore,
debug: mock(),
@@ -28,46 +12,19 @@ mock.module("@actions/core", () => ({
warning: mockWarning,
}));
-mock.module("@actions/exec", () => ({
- exec: mockExec,
- getExecOutput: mockGetExecOutput,
+const mockAgentCreate = mock();
+const mockAgentSend = mock();
+
+mock.module("@cursor/sdk", () => ({
+ Agent: {
+ create: mockAgentCreate,
+ },
}));
const { runAgent } = await import("../src/runner");
-/** All `exec` invocations from the last test run. */
-const getExecCalls = (): {
- args?: string[];
- commandLine: string;
- options?: ExecOptions;
-}[] =>
- mockExec.mock.calls.map((call) => {
- const [commandLine, args, options] = call as [
- string,
- string[] | undefined,
- ExecOptions | undefined,
- ];
- return { args, commandLine, options };
- });
-
-/** First `exec` invocation from the last test run (asserts the call exists). */
-const getExecCall = (): {
- args?: string[];
- commandLine: string;
- options?: ExecOptions;
-} => {
- const calls = getExecCalls();
- expect(calls.length).toBeGreaterThan(0);
- const [first] = calls;
- if (first === undefined) {
- throw new Error("expected exec to have been called");
- }
- return first;
-};
-
const baseInputs: ActionInputs = {
apiKey: "test-key",
- cursorVersion: "latest",
model: "auto",
permissions: "read-only",
prompt: "Analyze this code",
@@ -75,216 +32,71 @@ const baseInputs: ActionInputs = {
workingDirectory: ".",
};
+const mockStreamSuccess = async function* mockStreamSuccess() {
+ yield { text: "Hello from stream chunk 1. " };
+ yield { text: "And chunk 2." };
+};
+
+const mockStreamError = async function* mockStreamError() {
+ yield { text: "Starting..." };
+ throw new Error("Stream aborted");
+};
+
describe("runAgent", () => {
beforeEach(() => {
mock.clearAllMocks();
- mockGetExecOutput.mockImplementation((_cmd, args) => {
- if (args?.includes("--version")) {
- return Promise.resolve({
- exitCode: 0,
- stderr: "",
- stdout: "cursor-agent 9.9.9-test\n",
- });
- }
- return Promise.resolve({
- exitCode: 0,
- stderr: "",
- stdout: "OK\n",
- });
- });
- });
-
- it("calls cursor-agent with correct base args", async () => {
- mockExec.mockResolvedValue(0);
-
- const result = await runAgent(baseInputs);
- expect(result.cliVersion).toBe("cursor-agent 9.9.9-test");
- expect(mockExec).toHaveBeenCalledWith(
- "cursor-agent",
- expect.arrayContaining(["chat", "Analyze this code", "--no-interactive"]),
- expect.objectContaining({
- cwd: expect.any(String),
- env: expect.objectContaining({
- CURSOR_API_KEY: "test-key",
- NO_COLOR: "1",
- }),
- ignoreReturnCode: true,
- })
- );
- expect(mockGetExecOutput).toHaveBeenCalledWith(
- "cursor-agent",
- expect.arrayContaining(["-p", "--trust", "--output-format"]),
- expect.objectContaining({ silent: true })
- );
- });
-
- it("includes --model flag", async () => {
- mockExec.mockResolvedValue(0);
- await runAgent(baseInputs);
+ mockAgentCreate.mockResolvedValue({
+ send: mockAgentSend,
+ });
- const { args } = getExecCall();
- expect(args).toContain("--model");
- expect(args).toContain("auto");
+ mockAgentSend.mockResolvedValue({
+ result: Promise.resolve("Hello from stream chunk 1. And chunk 2."),
+ stream: mockStreamSuccess,
+ });
});
- it("includes read-only permission flag", async () => {
- mockExec.mockResolvedValue(0);
- await runAgent({ ...baseInputs, permissions: "read-only" });
-
- const { args } = getExecCall();
- expect(args).toContain("--allow-read");
- expect(args).not.toContain("--allow-write");
- });
+ it("calls Agent.create with correct inputs and returns successful response", async () => {
+ const result = await runAgent(baseInputs);
- it("includes read-write permission flags", async () => {
- mockExec.mockResolvedValue(0);
- await runAgent({ ...baseInputs, permissions: "read-write" });
+ expect(mockAgentCreate).toHaveBeenCalledWith({
+ apiKey: "test-key",
+ local: { cwd: expect.any(String) },
+ model: { id: "auto" },
+ });
- const { args } = getExecCall();
- expect(args).toContain("--allow-read");
- expect(args).toContain("--allow-write");
+ expect(mockAgentSend).toHaveBeenCalledWith("Analyze this code");
+ expect(result.exitCode).toBe(0);
+ expect(result.stdout).toBe("Hello from stream chunk 1. And chunk 2.");
+ expect(result.stderr).toBe("");
});
- it("includes full permission flags", async () => {
- mockExec.mockResolvedValue(0);
- await runAgent({ ...baseInputs, permissions: "full" });
-
- const { args } = getExecCall();
- expect(args).toContain("--allow-read");
- expect(args).toContain("--allow-write");
- expect(args).toContain("--allow-run");
- });
+ it("returns exitCode 1 and surfaces stderr when SDK throws an error", async () => {
+ mockAgentCreate.mockRejectedValue(new Error("Invalid API key"));
- it("returns correct exit code", async () => {
- mockExec.mockResolvedValue(42);
const result = await runAgent(baseInputs);
- expect(result.exitCode).toBe(42);
- expect(mockExec).toHaveBeenCalledTimes(2);
- });
-
- it("surfaces stderr in a warning when cursor-agent fails", async () => {
- mockExec.mockImplementation((_cmd, _args, options) => {
- options?.listeners?.stderr?.(Buffer.from("Invalid API key\n"));
- return Promise.resolve(1);
- });
- await runAgent(baseInputs);
-
- expect(mockExec).toHaveBeenCalledTimes(1);
- expect(mockWarning).toHaveBeenCalledWith(
- expect.stringContaining("cursor-agent stderr:")
- );
+ expect(result.exitCode).toBe(1);
+ expect(result.stderr).toContain("Invalid API key");
expect(mockWarning).toHaveBeenCalledWith(
expect.stringContaining("Invalid API key")
);
});
- it("does not fall back to print when chat fails with substantive stderr", async () => {
- mockExec.mockImplementation((_cmd, _args, options) => {
- options?.listeners?.stderr?.(Buffer.from("billing error for model\n"));
- return Promise.resolve(1);
+ it("returns exitCode 1 when stream throws an error", async () => {
+ mockAgentSend.mockResolvedValue({
+ get result() {
+ return Promise.reject(new Error("Stream aborted"));
+ },
+ stream: mockStreamError,
});
const result = await runAgent(baseInputs);
- expect(mockExec).toHaveBeenCalledTimes(1);
- expect(result.invocationMode).toBe("chat");
- expect(result.diagnostics).toContain("Auth/Entitlement preflight");
- expect(result.diagnostics).toContain("Primary (chat)");
- expect(result.diagnostics).not.toContain("Fallback (print)");
- });
-
- it("falls back to headless print when chat exits with no output", async () => {
- mockExec.mockResolvedValueOnce(1).mockResolvedValueOnce(0);
-
- const result = await runAgent(baseInputs);
-
- expect(mockExec).toHaveBeenCalledTimes(2);
- expect(mockGetExecOutput).toHaveBeenCalledWith(
- "cursor-agent",
- ["--version"],
- expect.objectContaining({ silent: true })
+ expect(result.exitCode).toBe(1);
+ expect(result.stderr).toContain("Stream aborted");
+ expect(mockWarning).toHaveBeenCalledWith(
+ expect.stringContaining("Stream aborted")
);
- const [, second] = getExecCalls();
- const [firstPrintArg] = second?.args ?? [];
- expect(firstPrintArg).toBe("-p");
- expect(second?.args).toContain("--trust");
- expect(second?.args).toContain("--output-format");
- expect(second?.args).toContain("text");
- expect(result.exitCode).toBe(0);
- expect(result.invocationMode).toBe("print");
- });
-
- it("falls back to print when stderr suggests unknown command", async () => {
- mockExec
- .mockImplementationOnce((_cmd, _args, options) => {
- options?.listeners?.stderr?.(
- Buffer.from("Error: unknown command chat\n")
- );
- return Promise.resolve(1);
- })
- .mockResolvedValueOnce(0);
-
- await runAgent(baseInputs);
-
- expect(mockExec).toHaveBeenCalledTimes(2);
- const [, secondUnknown] = getExecCalls();
- const [firstPrintArgUnknown] = secondUnknown?.args ?? [];
- expect(firstPrintArgUnknown).toBe("-p");
- });
-
- it("adds --force on print fallback for read-write permissions", async () => {
- mockExec.mockResolvedValueOnce(1).mockResolvedValueOnce(0);
-
- await runAgent({ ...baseInputs, permissions: "read-write" });
-
- const [, secondRw] = getExecCalls();
- const printArgs = secondRw?.args;
- expect(printArgs).toContain("--force");
- });
-
- it("does not add --force on print fallback for read-only", async () => {
- mockExec.mockResolvedValueOnce(1).mockResolvedValueOnce(0);
-
- await runAgent({ ...baseInputs, permissions: "read-only" });
-
- const [, secondRo] = getExecCalls();
- const printArgs = secondRo?.args;
- expect(printArgs).not.toContain("--force");
- });
-
- it("merges stderr and sets diagnostics when both invocations fail", async () => {
- mockExec
- .mockResolvedValueOnce(1)
- .mockImplementationOnce((_cmd, _args, options) => {
- options?.listeners?.stderr?.(Buffer.from("print mode failed\n"));
- return Promise.resolve(2);
- });
-
- const result = await runAgent(baseInputs);
-
- expect(result.exitCode).toBe(2);
- expect(result.invocationMode).toBe("print");
- expect(result.stderr).toContain("primary (chat)");
- expect(result.stderr).toContain("fallback (print -p)");
- expect(result.diagnostics).toContain("Hints:");
- expect(result.diagnostics).toContain("CURSOR_API_KEY");
- });
-
- it("sets CURSOR_DISABLE_UPDATE for pinned versions", async () => {
- mockExec.mockResolvedValue(0);
- await runAgent({ ...baseInputs, cursorVersion: "2026.03.20-44cb435" });
-
- const { options } = getExecCall();
- expect(options?.env?.CURSOR_DISABLE_UPDATE).toBe("1");
- });
-
- it("does not set CURSOR_DISABLE_UPDATE for latest", async () => {
- mockExec.mockResolvedValue(0);
- await runAgent({ ...baseInputs, cursorVersion: "latest" });
-
- const { options } = getExecCall();
- expect(options?.env?.CURSOR_DISABLE_UPDATE).toBeUndefined();
});
});
diff --git a/action.yml b/action.yml
index 7f0c97b..a5a14e0 100644
--- a/action.yml
+++ b/action.yml
@@ -1,5 +1,5 @@
name: "Cursor Action"
-description: "Install Cursor CLI and run cursor-agent in CI pipelines"
+description: "Run cursor-agent in CI pipelines using the official @cursor/sdk"
author: "PunGrumpy"
branding:
@@ -8,7 +8,7 @@ branding:
inputs:
cursor-version:
- description: "Cursor CLI build to install: 'latest' or exact lab id (e.g. from https://downloads.cursor.com/lab/latest-version, like '2026.03.20-44cb435')"
+ description: "(Deprecated) The SDK automatically manages the agent version."
required: false
default: "latest"
@@ -43,13 +43,28 @@ inputs:
outputs:
summary:
description: "Text summary returned by the cursor-agent"
+ value: ${{ steps.agent.outputs.summary }}
exit-code:
description: "Exit code from the cursor-agent process"
-
- cache-hit:
- description: "Whether the Cursor CLI binary was restored from cache"
+ value: ${{ steps.agent.outputs.exit-code }}
runs:
- using: "node24"
- main: "dist/index.js"
+ using: "composite"
+ steps:
+ - name: Install Action Dependencies
+ run: npm ci --omit=dev --prefix $GITHUB_ACTION_PATH
+ shell: bash
+
+ - name: Run Cursor Agent
+ id: agent
+ run: node $GITHUB_ACTION_PATH/dist/index.js
+ shell: bash
+ env:
+ INPUT_CURSOR_VERSION: ${{ inputs.cursor-version }}
+ INPUT_API_KEY: ${{ inputs.api-key }}
+ INPUT_PROMPT: ${{ inputs.prompt }}
+ INPUT_MODEL: ${{ inputs.model }}
+ INPUT_WORKING_DIRECTORY: ${{ inputs.working-directory }}
+ INPUT_PERMISSIONS: ${{ inputs.permissions }}
+ INPUT_TIMEOUT: ${{ inputs.timeout }}
diff --git a/bun.lock b/bun.lock
index c6777fa..c230252 100644
--- a/bun.lock
+++ b/bun.lock
@@ -5,19 +5,15 @@
"": {
"name": "@pungrumpy/cursor-action",
"dependencies": {
- "@actions/cache": "^6.0.0",
"@actions/core": "^3.0.0",
- "@actions/exec": "^3.0.0",
- "@actions/http-client": "^4.0.0",
- "@actions/io": "^3.0.2",
- "@actions/tool-cache": "^4.0.0",
+ "@cursor/sdk": "^1.0.12",
},
"devDependencies": {
"@changesets/cli": "^2.30.0",
"@types/bun": "latest",
- "@vercel/ncc": "^0.38.4",
"oxfmt": "^0.41.0",
"oxlint": "^1.56.0",
+ "tsdown": "^0.22.0",
"ultracite": "7.3.2",
},
"peerDependencies": {
@@ -26,47 +22,27 @@
},
},
"packages": {
- "@actions/cache": ["@actions/cache@6.0.0", "", { "dependencies": { "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/glob": "^0.6.1", "@actions/http-client": "^4.0.0", "@actions/io": "^3.0.0", "@azure/core-rest-pipeline": "^1.22.0", "@azure/storage-blob": "^12.30.0", "@protobuf-ts/runtime-rpc": "^2.11.1", "semver": "^7.7.3" } }, "sha512-+tCs634SyGBQJ3KU1rtAVabmN/gYiT9WgzTSJzWwdPCLmM3zWrdbysaErKv8HyI6OozClrxNvDgPjJimbHZZvw=="],
-
"@actions/core": ["@actions/core@3.0.0", "", { "dependencies": { "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0" } }, "sha512-zYt6cz+ivnTmiT/ksRVriMBOiuoUpDCJJlZ5KPl2/FRdvwU3f7MPh9qftvbkXJThragzUZieit2nyHUyw53Seg=="],
"@actions/exec": ["@actions/exec@3.0.0", "", { "dependencies": { "@actions/io": "^3.0.2" } }, "sha512-6xH/puSoNBXb72VPlZVm7vQ+svQpFyA96qdDBvhB8eNZOE8LtPf9L4oAsfzK/crCL8YZ+19fKYVnM63Sl+Xzlw=="],
- "@actions/glob": ["@actions/glob@0.6.1", "", { "dependencies": { "@actions/core": "^3.0.0", "minimatch": "^3.0.4" } }, "sha512-K4+2Ac5ILcf2ySdJCha+Pop9NcKjxqCL4xL4zI50dgB2PbXgC0+AcP011xfH4Of6b4QEJJg8dyZYv7zl4byTsw=="],
-
"@actions/http-client": ["@actions/http-client@4.0.0", "", { "dependencies": { "tunnel": "^0.0.6", "undici": "^6.23.0" } }, "sha512-QuwPsgVMsD6qaPD57GLZi9sqzAZCtiJT8kVBCDpLtxhL5MydQ4gS+DrejtZZPdIYyB1e95uCK9Luyds7ybHI3g=="],
"@actions/io": ["@actions/io@3.0.2", "", {}, "sha512-nRBchcMM+QK1pdjO7/idu86rbJI5YHUKCvKs0KxnSYbVe3F51UfGxuZX4Qy/fWlp6l7gWFwIkrOzN+oUK03kfw=="],
- "@actions/tool-cache": ["@actions/tool-cache@4.0.0", "", { "dependencies": { "@actions/core": "^3.0.0", "@actions/exec": "^3.0.0", "@actions/http-client": "^4.0.0", "@actions/io": "^3.0.0", "semver": "^7.7.3" } }, "sha512-L8P9HbXvpvqjZDveb/fdsa55IVC0trfPgQ4ZwGo6r5af6YDVdM9vMGPZ7rgY2fAT9gGj4PSYd6bYlg3p3jD78A=="],
-
- "@azure/abort-controller": ["@azure/abort-controller@2.1.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-nBrLsEWm4J2u5LpAPjxADTlq3trDgVZZXHNKabeXZtpq3d3AbN/KGO82R87rdDz5/lYB024rtEf10/q0urNgsA=="],
-
- "@azure/core-auth": ["@azure/core-auth@1.10.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-util": "^1.13.0", "tslib": "^2.6.2" } }, "sha512-ykRMW8PjVAn+RS6ww5cmK9U2CyH9p4Q88YJwvUslfuMmN98w/2rdGRLPqJYObapBCdzBVeDgYWdJnFPFb7qzpg=="],
-
- "@azure/core-client": ["@azure/core-client@1.10.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0", "@azure/core-tracing": "^1.3.0", "@azure/core-util": "^1.13.0", "@azure/logger": "^1.3.0", "tslib": "^2.6.2" } }, "sha512-Nh5PhEOeY6PrnxNPsEHRr9eimxLwgLlpmguQaHKBinFYA/RU9+kOYVOQqOrTsCL+KSxrLLl1gD8Dk5BFW/7l/w=="],
-
- "@azure/core-http-compat": ["@azure/core-http-compat@2.3.2", "", { "dependencies": { "@azure/abort-controller": "^2.1.2" }, "peerDependencies": { "@azure/core-client": "^1.10.0", "@azure/core-rest-pipeline": "^1.22.0" } }, "sha512-Tf6ltdKzOJEgxZeWLCjMxrxbodB/ZeCbzzA1A2qHbhzAjzjHoBVSUeSl/baT/oHAxhc4qdqVaDKnc2+iE932gw=="],
-
- "@azure/core-lro": ["@azure/core-lro@2.7.2", "", { "dependencies": { "@azure/abort-controller": "^2.0.0", "@azure/core-util": "^1.2.0", "@azure/logger": "^1.0.0", "tslib": "^2.6.2" } }, "sha512-0YIpccoX8m/k00O7mDDMdJpbr6mf1yWo2dfmxt5A8XVZVVMz2SSKaEbMCeJRvgQ0IaSlqhjT47p4hVIRRy90xw=="],
+ "@babel/generator": ["@babel/generator@8.0.0-rc.4", "", { "dependencies": { "@babel/parser": "^8.0.0-rc.4", "@babel/types": "^8.0.0-rc.4", "@jridgewell/gen-mapping": "^0.3.12", "@jridgewell/trace-mapping": "^0.3.28", "@types/jsesc": "^2.5.0", "jsesc": "^3.0.2" } }, "sha512-YZ+FuIgkj7KrIb2a2X1XiY0QYgDxAbVbYP64SjwJzOK3euCsUerzenh2oqdsmKuPSlhzmFOOklnxzHAzXagvpw=="],
- "@azure/core-paging": ["@azure/core-paging@1.6.2", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-YKWi9YuCU04B55h25cnOYZHxXYtEvQEbKST5vqRga7hWY9ydd3FZHdeQF8pyh+acWZvppw13M/LMGx0LABUVMA=="],
+ "@babel/helper-string-parser": ["@babel/helper-string-parser@8.0.0-rc.4", "", {}, "sha512-dluR3v287dp6YPF57kyKKrHPKffUeuxH1zQcF1WD30TeFzWXhDiVi1U6PkqaDB0++H1PeCwRhmYl4DvoerlPIw=="],
- "@azure/core-rest-pipeline": ["@azure/core-rest-pipeline@1.23.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.10.0", "@azure/core-tracing": "^1.3.0", "@azure/core-util": "^1.13.0", "@azure/logger": "^1.3.0", "@typespec/ts-http-runtime": "^0.3.4", "tslib": "^2.6.2" } }, "sha512-Evs1INHo+jUjwHi1T6SG6Ua/LHOQBCLuKEEE6efIpt4ZOoNonaT1kP32GoOcdNDbfqsD2445CPri3MubBy5DEQ=="],
+ "@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@8.0.0-rc.4", "", {}, "sha512-HTD3bskipk5MSm08twTW6832jzIXUhxMddy4NPPzIMuyMEsrs0ZgwAaMj5ubB5+6hMlUjDu17vNconEmwsmpYg=="],
- "@azure/core-tracing": ["@azure/core-tracing@1.3.1", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-9MWKevR7Hz8kNzzPLfX4EAtGM2b8mr50HPDBvio96bURP/9C+HjdH3sBlLSNNrvRAr5/k/svoH457gB5IKpmwQ=="],
+ "@babel/parser": ["@babel/parser@8.0.0-rc.4", "", { "dependencies": { "@babel/types": "^8.0.0-rc.4" }, "bin": "./bin/babel-parser.js" }, "sha512-0S/1yefMa15N4i2v3t8Fw9pgMHhf2gF6Lc1UEXI96Ls6FNAjqvHHZouZ2ZS/deqLhbMFtmfVeFac6iTsvFbLwA=="],
- "@azure/core-util": ["@azure/core-util@1.13.1", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-XPArKLzsvl0Hf0CaGyKHUyVgF7oDnhKoP85Xv6M4StF/1AhfORhZudHtOyf2s+FcbuQ9dPRAjB8J2KvRRMUK2A=="],
-
- "@azure/core-xml": ["@azure/core-xml@1.5.0", "", { "dependencies": { "fast-xml-parser": "^5.0.7", "tslib": "^2.8.1" } }, "sha512-D/sdlJBMJfx7gqoj66PKVmhDDaU6TKA49ptcolxdas29X7AfvLTmfAGLjAcIMBK7UZ2o4lygHIqVckOlQU3xWw=="],
-
- "@azure/logger": ["@azure/logger@1.3.0", "", { "dependencies": { "@typespec/ts-http-runtime": "^0.3.0", "tslib": "^2.6.2" } }, "sha512-fCqPIfOcLE+CGqGPd66c8bZpwAji98tZ4JI9i/mlTNTlsIWslCfpg48s/ypyLxZTump5sypjrKn2/kY7q8oAbA=="],
-
- "@azure/storage-blob": ["@azure/storage-blob@12.31.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-client": "^1.9.3", "@azure/core-http-compat": "^2.2.0", "@azure/core-lro": "^2.2.0", "@azure/core-paging": "^1.6.2", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/core-xml": "^1.4.5", "@azure/logger": "^1.1.4", "@azure/storage-common": "^12.3.0", "events": "^3.0.0", "tslib": "^2.8.1" } }, "sha512-DBgNv10aCSxopt92DkTDD0o9xScXeBqPKGmR50FPZQaEcH4JLQ+GEOGEDv19V5BMkB7kxr+m4h6il/cCDPvmHg=="],
+ "@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="],
- "@azure/storage-common": ["@azure/storage-common@12.3.0", "", { "dependencies": { "@azure/abort-controller": "^2.1.2", "@azure/core-auth": "^1.9.0", "@azure/core-http-compat": "^2.2.0", "@azure/core-rest-pipeline": "^1.19.1", "@azure/core-tracing": "^1.2.0", "@azure/core-util": "^1.11.0", "@azure/logger": "^1.1.4", "events": "^3.3.0", "tslib": "^2.8.1" } }, "sha512-/OFHhy86aG5Pe8dP5tsp+BuJ25JOAl9yaMU3WZbkeoiFMHFtJ7tu5ili7qEdBXNW9G5lDB19trwyI6V49F/8iQ=="],
+ "@babel/types": ["@babel/types@8.0.0-rc.4", "", { "dependencies": { "@babel/helper-string-parser": "^8.0.0-rc.4", "@babel/helper-validator-identifier": "^8.0.0-rc.4" } }, "sha512-bw30DV880P/VYtsjWWdoWmJpb9S2Vn1/PqayyccTELzRQ/HslIO7+BD9rNoZ4AAFOAjC1vrNeBCkAsyh6Ibfww=="],
- "@babel/runtime": ["@babel/runtime@7.29.2", "", {}, "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g=="],
+ "@bufbuild/protobuf": ["@bufbuild/protobuf@1.10.0", "", {}, "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag=="],
"@changesets/apply-release-plan": ["@changesets/apply-release-plan@7.1.0", "", { "dependencies": { "@changesets/config": "^3.1.3", "@changesets/get-version-range-type": "^0.4.0", "@changesets/git": "^3.0.4", "@changesets/should-skip-package": "^0.1.2", "@changesets/types": "^6.1.0", "@manypkg/get-packages": "^1.1.3", "detect-indent": "^6.0.0", "fs-extra": "^7.0.1", "lodash.startcase": "^4.4.0", "outdent": "^0.5.0", "prettier": "^2.7.1", "resolve-from": "^5.0.0", "semver": "^7.5.3" } }, "sha512-yq8ML3YS7koKQ/9bk1PqO0HMzApIFNwjlwCnwFEXMzNe8NpzeeYYKCmnhWJGkN8g7E51MnWaSbqRcTcdIxUgnQ=="],
@@ -106,18 +82,60 @@
"@clack/prompts": ["@clack/prompts@1.1.0", "", { "dependencies": { "@clack/core": "1.1.0", "sisteransi": "^1.0.5" } }, "sha512-pkqbPGtohJAvm4Dphs2M8xE29ggupihHdy1x84HNojZuMtFsHiUlRvqD24tM2+XmI+61LlfNceM3Wr7U5QES5g=="],
+ "@connectrpc/connect": ["@connectrpc/connect@1.7.0", "", { "peerDependencies": { "@bufbuild/protobuf": "^1.10.0" } }, "sha512-iNKdJRi69YP3mq6AePRT8F/HrxWCewrhxnLMNm0vpqXAR8biwzRtO6Hjx80C6UvtKJ5sFmffQT7I4Baecz389w=="],
+
+ "@connectrpc/connect-node": ["@connectrpc/connect-node@1.7.0", "", { "dependencies": { "undici": "^5.28.4" }, "peerDependencies": { "@bufbuild/protobuf": "^1.10.0", "@connectrpc/connect": "1.7.0" } }, "sha512-6vaPIkG/NyhxlYgytLoR9KYbPhczEboFB2OYWkA9qvUz1K7efXfeGrlRxoLtpa+r8VxyIOw73w5ktNe743nD+A=="],
+
+ "@cursor/sdk": ["@cursor/sdk@1.0.12", "", { "dependencies": { "@bufbuild/protobuf": "1.10.0", "@connectrpc/connect": "^1.6.1", "@connectrpc/connect-node": "^1.6.1", "@statsig/js-client": "3.31.0", "sqlite3": "^5.1.7", "zod": "^3.25.0" }, "optionalDependencies": { "@cursor/sdk-darwin-arm64": "1.0.12", "@cursor/sdk-darwin-x64": "1.0.12", "@cursor/sdk-linux-arm64": "1.0.12", "@cursor/sdk-linux-x64": "1.0.12", "@cursor/sdk-win32-x64": "1.0.12" } }, "sha512-jGx0wFY1N9uIdIKr303CfM6m/dLXmRCUnU/0yNP/oiOpkBXqgqaThGbgYbcOeVrYonMZc/DZJ9EydXOEPJLcbg=="],
+
+ "@cursor/sdk-darwin-arm64": ["@cursor/sdk-darwin-arm64@1.0.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-AOFx+aX+4SntAeC66YncHACXk5duxp+HzDrxxF4Tl93N6nLjHaHEKSAXbt87ivL34MCHop4v/3c70QzBhamB2g=="],
+
+ "@cursor/sdk-darwin-x64": ["@cursor/sdk-darwin-x64@1.0.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-/ZDAYFUrnPd8hAGRky9ZGcROqZSZ2b5W+aEjTdINzLhJ8x5ZNXtjaz0ZYSHabOn2BeErjXgTcq+4bX2/To4C1A=="],
+
+ "@cursor/sdk-linux-arm64": ["@cursor/sdk-linux-arm64@1.0.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-kAxNqiB3dPtlW9fVjjIZEdbIGEGLA9moOM3zYwsXh8J1Qw942nJYMGDGR4o8x0zglwZ24a1JpovvZamrCaC3Yw=="],
+
+ "@cursor/sdk-linux-x64": ["@cursor/sdk-linux-x64@1.0.12", "", { "os": "linux", "cpu": "x64" }, "sha512-RmBiBCPKMZC5McDerGk2Rk4P47xz2A+uzRoRgH6sMoOjklc33ry11iAZC0D5F5xH85chgY878086A/Q8+XrAuA=="],
+
+ "@cursor/sdk-win32-x64": ["@cursor/sdk-win32-x64@1.0.12", "", { "os": "win32", "cpu": "x64" }, "sha512-uH4shdHrKOdtNLapy1uuScJ9lL2Pc8zc9I9ZKC6b6bx+0UX6xLAqjPP7dqVPfO6D9u61yLq1Hs86XOLs5ZVkPA=="],
+
+ "@emnapi/core": ["@emnapi/core@1.10.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw=="],
+
+ "@emnapi/runtime": ["@emnapi/runtime@1.10.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA=="],
+
+ "@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w=="],
+
+ "@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="],
+
+ "@gar/promisify": ["@gar/promisify@1.1.3", "", {}, "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw=="],
+
"@inquirer/external-editor": ["@inquirer/external-editor@1.0.3", "", { "dependencies": { "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "peerDependencies": { "@types/node": ">=18" }, "optionalPeers": ["@types/node"] }, "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA=="],
+ "@jridgewell/gen-mapping": ["@jridgewell/gen-mapping@0.3.13", "", { "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.0", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA=="],
+
+ "@jridgewell/resolve-uri": ["@jridgewell/resolve-uri@3.1.2", "", {}, "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw=="],
+
+ "@jridgewell/sourcemap-codec": ["@jridgewell/sourcemap-codec@1.5.5", "", {}, "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og=="],
+
+ "@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.31", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.1.0", "@jridgewell/sourcemap-codec": "^1.4.14" } }, "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw=="],
+
"@manypkg/find-root": ["@manypkg/find-root@1.1.0", "", { "dependencies": { "@babel/runtime": "^7.5.5", "@types/node": "^12.7.1", "find-up": "^4.1.0", "fs-extra": "^8.1.0" } }, "sha512-mki5uBvhHzO8kYYix/WRy2WX8S3B5wdVSc9D6KcU5lQNglP2yt58/VfLuAK49glRXChosY8ap2oJ1qgma3GUVA=="],
"@manypkg/get-packages": ["@manypkg/get-packages@1.1.3", "", { "dependencies": { "@babel/runtime": "^7.5.5", "@changesets/types": "^4.0.1", "@manypkg/find-root": "^1.1.0", "fs-extra": "^8.1.0", "globby": "^11.0.0", "read-yaml-file": "^1.1.0" } }, "sha512-fo+QhuU3qE/2TQMQmbVMqaQ6EWbMhi4ABWP+O4AM1NqPBuy0OrApV5LO6BrrgnhtAHS2NH6RrVk9OL181tTi8A=="],
+ "@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.4", "", { "dependencies": { "@tybys/wasm-util": "^0.10.1" }, "peerDependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1" } }, "sha512-3NQNNgA1YSlJb/kMH1ildASP9HW7/7kYnRI2szWJaofaS1hWmbGI4H+d3+22aGzXXN9IJ+n+GiFVcGipJP18ow=="],
+
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
+ "@npmcli/fs": ["@npmcli/fs@1.1.1", "", { "dependencies": { "@gar/promisify": "^1.0.1", "semver": "^7.3.5" } }, "sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ=="],
+
+ "@npmcli/move-file": ["@npmcli/move-file@1.1.2", "", { "dependencies": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" } }, "sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg=="],
+
+ "@oxc-project/types": ["@oxc-project/types@0.129.0", "", {}, "sha512-3oz8m3FGdr2nDXVqmFUw7jolKliC4MoyXYIG2c7gpjBnzUWQpUGIYcXYKxTdTi+N2jusvt610ckTMkxdwHkYEg=="],
+
"@oxfmt/binding-android-arm-eabi": ["@oxfmt/binding-android-arm-eabi@0.41.0", "", { "os": "android", "cpu": "arm" }, "sha512-REfrqeMKGkfMP+m/ScX4f5jJBSmVNYcpoDF8vP8f8eYPDuPGZmzp56NIUsYmx3h7f6NzC6cE3gqh8GDWrJHCKw=="],
"@oxfmt/binding-android-arm64": ["@oxfmt/binding-android-arm64@0.41.0", "", { "os": "android", "cpu": "arm64" }, "sha512-s0b1dxNgb2KomspFV2LfogC2XtSJB42POXF4bMCLJyvQmAGos4ZtjGPfQreToQEaY0FQFjz3030ggI36rF1q5g=="],
@@ -194,78 +212,190 @@
"@oxlint/binding-win32-x64-msvc": ["@oxlint/binding-win32-x64-msvc@1.56.0", "", { "os": "win32", "cpu": "x64" }, "sha512-ZHa0clocjLmIDr+1LwoWtxRcoYniAvERotvwKUYKhH41NVfl0Y4LNbyQkwMZzwDvKklKGvGZ5+DAG58/Ik47tQ=="],
- "@protobuf-ts/runtime": ["@protobuf-ts/runtime@2.11.1", "", {}, "sha512-KuDaT1IfHkugM2pyz+FwiY80ejWrkH1pAtOBOZFuR6SXEFTsnb/jiQWQ1rCIrcKx2BtyxnxW6BWwsVSA/Ie+WQ=="],
+ "@quansync/fs": ["@quansync/fs@1.0.0", "", { "dependencies": { "quansync": "^1.0.0" } }, "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ=="],
+
+ "@rolldown/binding-android-arm64": ["@rolldown/binding-android-arm64@1.0.0", "", { "os": "android", "cpu": "arm64" }, "sha512-TWMZnRLMe63C2Lhyicviu7ZHaU4kxa6PS3rofvc9GmcvptzNN11BcfQ4Sl7MwTOsisQoa2keB/EBdNCAnUo8vA=="],
+
+ "@rolldown/binding-darwin-arm64": ["@rolldown/binding-darwin-arm64@1.0.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-6XcD+8k0gPVItNagEw78/qqcBDwKcwDYS8V2hRmVsfUSIrd8cWe/CBvRDI5toqFyPfj+FJr6t8U6Xj2P2prEew=="],
+
+ "@rolldown/binding-darwin-x64": ["@rolldown/binding-darwin-x64@1.0.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-iN/tWVXRQDWvmZlKdceP1Dwug9GDpEymhb9p4xnEe6zvCg5lFmzVljl+1qR1NVx3yfGpr2Na+CuLmv5IU8uzfQ=="],
+
+ "@rolldown/binding-freebsd-x64": ["@rolldown/binding-freebsd-x64@1.0.0", "", { "os": "freebsd", "cpu": "x64" }, "sha512-jjQMDvvwSOuhOwMszD/klSOjyWMM3zI64hWTj9KT5x4MxRbZAf+7vLQ6qouRhtsLVFHr3f0ILaJAfgENPiQdAQ=="],
+
+ "@rolldown/binding-linux-arm-gnueabihf": ["@rolldown/binding-linux-arm-gnueabihf@1.0.0", "", { "os": "linux", "cpu": "arm" }, "sha512-d//Dtg2x6/m3mbV64yUGNnDGNZaDGRpDLLNGerHQUVObuNaIQaaDp25yUiqGXtHEXX+NP2d0wAlmKgpYgIAJ2A=="],
+
+ "@rolldown/binding-linux-arm64-gnu": ["@rolldown/binding-linux-arm64-gnu@1.0.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-n7Ofp0mx+aB2cC+Sdy5YtMnXtY9lchnHbY+3Yt0uq9JsWQExf4f5Whu0tK0R8Jdc9S6RchTHjIFY7uc92puOVQ=="],
+
+ "@rolldown/binding-linux-arm64-musl": ["@rolldown/binding-linux-arm64-musl@1.0.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-EIVjy2cgd7uuMMo94FVkBp7F6DhcZAUwNURkSG3RwUmvAXR6s0ISxM81U+IydcZByPG0pZIHsf1b6kTxoFDgJA=="],
+
+ "@rolldown/binding-linux-ppc64-gnu": ["@rolldown/binding-linux-ppc64-gnu@1.0.0", "", { "os": "linux", "cpu": "ppc64" }, "sha512-JEwwOPcwTLAcpDQlqSmjEmfs63xJnSiUNIGvLcDLUHCWK4XowpS/7c7tUsUH6uT/ct6bMUTdXKfI8967FYj6mg=="],
+
+ "@rolldown/binding-linux-s390x-gnu": ["@rolldown/binding-linux-s390x-gnu@1.0.0", "", { "os": "linux", "cpu": "s390x" }, "sha512-0wjCFhLrihtAubnT9iA0N++0pSV0z5Hg7tNGdNJ4RFaINceHadoF+kiFGyY1qSSNVIAZtLotG8Ju1bgDPkjnFA=="],
+
+ "@rolldown/binding-linux-x64-gnu": ["@rolldown/binding-linux-x64-gnu@1.0.0", "", { "os": "linux", "cpu": "x64" }, "sha512-Dfn7iak9BcMMePxcoJfpSbWqnEyrp/dRF63/8qW/eHBdOZov6x5aShLLEYGYdIeSJ6vMLK/XCVB+lGIxm41bQA=="],
+
+ "@rolldown/binding-linux-x64-musl": ["@rolldown/binding-linux-x64-musl@1.0.0", "", { "os": "linux", "cpu": "x64" }, "sha512-5/utzzDmD/pD/bmuaUcbTf/sZYy0aztwIVlfpoW1fTjCZ0BaPOMVWGZL1zvgxyi7ZIVYWlxKONHmSbHuiOh8Jw=="],
+
+ "@rolldown/binding-openharmony-arm64": ["@rolldown/binding-openharmony-arm64@1.0.0", "", { "os": "none", "cpu": "arm64" }, "sha512-ouJs8VcUomfLfpbUECqFMRqdV4x6aeAK3MA4m6vTrJJjKyWTV5KnxZx7Jd9G+GlDaQQxubcba00x16OyJ1meig=="],
+
+ "@rolldown/binding-wasm32-wasi": ["@rolldown/binding-wasm32-wasi@1.0.0", "", { "dependencies": { "@emnapi/core": "1.10.0", "@emnapi/runtime": "1.10.0", "@napi-rs/wasm-runtime": "^1.1.4" }, "cpu": "none" }, "sha512-E+oHKGiDA+lsKMmFtffDDw91EryDT7uJocrIuCHqhm6bCTM6xFK+3gaCkYOHfPwQr0cCNarSM2xaELoQDz9jJg=="],
+
+ "@rolldown/binding-win32-arm64-msvc": ["@rolldown/binding-win32-arm64-msvc@1.0.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-yYK02n8Rngo+gbm1y6G0+7jk1sJ/2Wt7K0me0Y7k/ErBpyf+LJ2gFpqWVTcRV1rUepBlQRmpgWkTQCiiwrK0Ow=="],
+
+ "@rolldown/binding-win32-x64-msvc": ["@rolldown/binding-win32-x64-msvc@1.0.0", "", { "os": "win32", "cpu": "x64" }, "sha512-14bpChMahXRRXiTwahSl+zzHPW6qQTXtkMuJBFlbo+pqSAews2d4BdCSHfrJ/MBsCZtpmTafsY+1QhBzitcmdg=="],
+
+ "@rolldown/pluginutils": ["@rolldown/pluginutils@1.0.0", "", {}, "sha512-aKs/3GSWyV0mrhNmt/96/Z3yczC3yvrzYATCiCXQebBsGyYzjNdUphRVLeJQ67ySKVXRfMxt2lm12pmXvbPFQQ=="],
- "@protobuf-ts/runtime-rpc": ["@protobuf-ts/runtime-rpc@2.11.1", "", { "dependencies": { "@protobuf-ts/runtime": "^2.11.1" } }, "sha512-4CqqUmNA+/uMz00+d3CYKgElXO9VrEbucjnBFEjqI4GuDrEQ32MaI3q+9qPBvIGOlL4PmHXrzM32vBPWRhQKWQ=="],
+ "@statsig/client-core": ["@statsig/client-core@3.31.0", "", {}, "sha512-SuxQD6TmVszPG7FoMKwTk/uyBuVFk7XnxI3T/E0uyb7PL7GNjONtfsoh+NqBBVUJVse0CUeSFfgJPoZy1ZOslQ=="],
+
+ "@statsig/js-client": ["@statsig/js-client@3.31.0", "", { "dependencies": { "@statsig/client-core": "3.31.0" } }, "sha512-LFa5E0LjT6sTfZv3sNGoyRLSZ1078+agdgOA+Vm1ecjG+KbSOfBLTW7hMwimrJ29slRwbYDzbtKaPJo/R37N2g=="],
+
+ "@tootallnate/once": ["@tootallnate/once@1.1.2", "", {}, "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw=="],
+
+ "@tybys/wasm-util": ["@tybys/wasm-util@0.10.2", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-RoBvJ2X0wuKlWFIjrwffGw1IqZHKQqzIchKaadZZfnNpsAYp2mM0h36JtPCjNDAHGgYez/15uMBpfGwchhiMgg=="],
"@types/bun": ["@types/bun@1.3.11", "", { "dependencies": { "bun-types": "1.3.11" } }, "sha512-5vPne5QvtpjGpsGYXiFyycfpDF2ECyPcTSsFBMa0fraoxiQyMJ3SmuQIGhzPg2WJuWxVBoxWJ2kClYTcw/4fAg=="],
+ "@types/estree": ["@types/estree@1.0.8", "", {}, "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w=="],
+
+ "@types/jsesc": ["@types/jsesc@2.5.1", "", {}, "sha512-9VN+6yxLOPLOav+7PwjZbxiID2bVaeq0ED4qSQmdQTdjnXJSaCVKTR58t15oqH1H5t8Ng2ZX1SabJVoN9Q34bw=="],
+
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
- "@typespec/ts-http-runtime": ["@typespec/ts-http-runtime@0.3.4", "", { "dependencies": { "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.0", "tslib": "^2.6.2" } }, "sha512-CI0NhTrz4EBaa0U+HaaUZrJhPoso8sG7ZFya8uQoBA57fjzrjRSv87ekCjLZOFExN+gXE/z0xuN2QfH4H2HrLQ=="],
+ "abbrev": ["abbrev@1.1.1", "", {}, "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="],
+
+ "agent-base": ["agent-base@6.0.2", "", { "dependencies": { "debug": "4" } }, "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ=="],
- "@vercel/ncc": ["@vercel/ncc@0.38.4", "", { "bin": { "ncc": "dist/ncc/cli.js" } }, "sha512-8LwjnlP39s08C08J5NstzriPvW1SP8Zfpp1BvC2sI35kPeZnHfxVkCwu4/+Wodgnd60UtT1n8K8zw+Mp7J9JmQ=="],
+ "agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="],
- "agent-base": ["agent-base@7.1.4", "", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
+ "aggregate-error": ["aggregate-error@3.1.0", "", { "dependencies": { "clean-stack": "^2.0.0", "indent-string": "^4.0.0" } }, "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA=="],
"ansi-colors": ["ansi-colors@4.1.3", "", {}, "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw=="],
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
+ "ansis": ["ansis@4.3.0", "", {}, "sha512-44mvgtPvohuU/70DdY5Oz2AIrLJ9k6/5x4KmoSvPwO+5Moijo0+N9D0fKbbYZQWP1hNm5CpOf+E01jhxG/r8xg=="],
+
+ "aproba": ["aproba@2.1.0", "", {}, "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew=="],
+
+ "are-we-there-yet": ["are-we-there-yet@3.0.1", "", { "dependencies": { "delegates": "^1.0.0", "readable-stream": "^3.6.0" } }, "sha512-QZW4EDmGwlYur0Yyf/b2uGucHQMa8aFUP7eu9ddR73vvhFyt4V0Vl3QHPcTNJ8l6qYOBdxgXdnBXQrHilfRQBg=="],
+
"argparse": ["argparse@2.0.1", "", {}, "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="],
"array-union": ["array-union@2.1.0", "", {}, "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw=="],
+ "ast-kit": ["ast-kit@3.0.0-beta.1", "", { "dependencies": { "@babel/parser": "^8.0.0-beta.4", "estree-walker": "^3.0.3", "pathe": "^2.0.3" } }, "sha512-trmleAnZ2PxN/loHWVhhx1qeOHSRXq4TDsBBxq3GqeJitfk3+jTQ+v/C1km/KYq9M7wKqCewMh+/NAvVH7m+bw=="],
+
"balanced-match": ["balanced-match@4.0.4", "", {}, "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA=="],
+ "base64-js": ["base64-js@1.5.1", "", {}, "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA=="],
+
"better-path-resolve": ["better-path-resolve@1.0.0", "", { "dependencies": { "is-windows": "^1.0.0" } }, "sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g=="],
+ "bindings": ["bindings@1.5.0", "", { "dependencies": { "file-uri-to-path": "1.0.0" } }, "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ=="],
+
+ "birpc": ["birpc@4.0.0", "", {}, "sha512-LShSxJP0KTmd101b6DRyGBj57LZxSDYWKitQNW/mi8GRMvZb078Uf9+pveax1DrVL89vm7mWe+TovdI/UDOuPw=="],
+
+ "bl": ["bl@4.1.0", "", { "dependencies": { "buffer": "^5.5.0", "inherits": "^2.0.4", "readable-stream": "^3.4.0" } }, "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w=="],
+
"brace-expansion": ["brace-expansion@5.0.4", "", { "dependencies": { "balanced-match": "^4.0.2" } }, "sha512-h+DEnpVvxmfVefa4jFbCf5HdH5YMDXRsmKflpf1pILZWRFlTbJpxeU55nJl4Smt5HQaGzg1o6RHFPJaOqnmBDg=="],
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
+ "buffer": ["buffer@5.7.1", "", { "dependencies": { "base64-js": "^1.3.1", "ieee754": "^1.1.13" } }, "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ=="],
+
"bun-types": ["bun-types@1.3.11", "", { "dependencies": { "@types/node": "*" } }, "sha512-1KGPpoxQWl9f6wcZh57LvrPIInQMn2TQ7jsgxqpRzg+l0QPOFvJVH7HmvHo/AiPgwXy+/Thf6Ov3EdVn1vOabg=="],
+ "cac": ["cac@7.0.0", "", {}, "sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ=="],
+
+ "cacache": ["cacache@15.3.0", "", { "dependencies": { "@npmcli/fs": "^1.0.0", "@npmcli/move-file": "^1.0.1", "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "glob": "^7.1.4", "infer-owner": "^1.0.4", "lru-cache": "^6.0.0", "minipass": "^3.1.1", "minipass-collect": "^1.0.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.2", "mkdirp": "^1.0.3", "p-map": "^4.0.0", "promise-inflight": "^1.0.1", "rimraf": "^3.0.2", "ssri": "^8.0.1", "tar": "^6.0.2", "unique-filename": "^1.1.1" } }, "sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ=="],
+
"chardet": ["chardet@2.1.1", "", {}, "sha512-PsezH1rqdV9VvyNhxxOW32/d75r01NY7TQCmOqomRo15ZSOKbpTFVsfjghxo6JloQUCGnH4k1LGu0R4yCLlWQQ=="],
+ "chownr": ["chownr@2.0.0", "", {}, "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ=="],
+
"citty": ["citty@0.2.1", "", {}, "sha512-kEV95lFBhQgtogAPlQfJJ0WGVSokvLr/UEoFPiKKOXF7pl98HfUVUD0ejsuTCld/9xH9vogSywZ5KqHzXrZpqg=="],
+ "clean-stack": ["clean-stack@2.2.0", "", {}, "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A=="],
+
+ "color-support": ["color-support@1.1.3", "", { "bin": { "color-support": "bin.js" } }, "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="],
+
"commander": ["commander@14.0.3", "", {}, "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw=="],
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
+ "console-control-strings": ["console-control-strings@1.1.0", "", {}, "sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ=="],
+
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"debug": ["debug@4.4.3", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
+ "decompress-response": ["decompress-response@6.0.0", "", { "dependencies": { "mimic-response": "^3.1.0" } }, "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ=="],
+
+ "deep-extend": ["deep-extend@0.6.0", "", {}, "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="],
+
"deepmerge": ["deepmerge@4.3.1", "", {}, "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A=="],
+ "defu": ["defu@6.1.7", "", {}, "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ=="],
+
+ "delegates": ["delegates@1.0.0", "", {}, "sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ=="],
+
"detect-indent": ["detect-indent@6.1.0", "", {}, "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA=="],
+ "detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
+
"dir-glob": ["dir-glob@3.0.1", "", { "dependencies": { "path-type": "^4.0.0" } }, "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA=="],
+ "dts-resolver": ["dts-resolver@3.0.0", "", { "peerDependencies": { "oxc-resolver": ">=11.0.0" }, "optionalPeers": ["oxc-resolver"] }, "sha512-1T1f+z+4tl9XD+m+0HBgWoL/nm0bOIffyWaUuUSBlFg/86IWvfx+wjNaO/ybU0AJzG9/Mi5hBUgGV6zCmWEN7Q=="],
+
+ "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
+
+ "empathic": ["empathic@2.0.1", "", {}, "sha512-YGRs8knHhKHVShLkFET/rWAU8kmHbOV5LwN938RHI0pljAJ1Gf6SzXsSmRaEzcXTtOOmVqJ5+WtQPL5uigY50Q=="],
+
+ "encoding": ["encoding@0.1.13", "", { "dependencies": { "iconv-lite": "^0.6.2" } }, "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A=="],
+
+ "end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
+
"enquirer": ["enquirer@2.4.1", "", { "dependencies": { "ansi-colors": "^4.1.1", "strip-ansi": "^6.0.1" } }, "sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ=="],
+ "env-paths": ["env-paths@2.2.1", "", {}, "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A=="],
+
+ "err-code": ["err-code@2.0.3", "", {}, "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="],
+
"esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
- "events": ["events@3.3.0", "", {}, "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q=="],
+ "estree-walker": ["estree-walker@3.0.3", "", { "dependencies": { "@types/estree": "^1.0.0" } }, "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g=="],
+
+ "expand-template": ["expand-template@2.0.3", "", {}, "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg=="],
"extendable-error": ["extendable-error@0.1.7", "", {}, "sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg=="],
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
- "fast-xml-builder": ["fast-xml-builder@1.1.4", "", { "dependencies": { "path-expression-matcher": "^1.1.3" } }, "sha512-f2jhpN4Eccy0/Uz9csxh3Nu6q4ErKxf0XIsasomfOihuSUa3/xw6w8dnOtCDgEItQFJG8KyXPzQXzcODDrrbOg=="],
+ "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
- "fast-xml-parser": ["fast-xml-parser@5.5.8", "", { "dependencies": { "fast-xml-builder": "^1.1.4", "path-expression-matcher": "^1.2.0", "strnum": "^2.2.0" }, "bin": { "fxparser": "src/cli/cli.js" } }, "sha512-Z7Fh2nVQSb2d+poDViM063ix2ZGt9jmY1nWhPfHBOK2Hgnb/OW3P4Et3P/81SEej0J7QbWtJqxO05h8QYfK7LQ=="],
+ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
- "fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
+ "file-uri-to-path": ["file-uri-to-path@1.0.0", "", {}, "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="],
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
"find-up": ["find-up@4.1.0", "", { "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" } }, "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw=="],
+ "fs-constants": ["fs-constants@1.0.0", "", {}, "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow=="],
+
"fs-extra": ["fs-extra@7.0.1", "", { "dependencies": { "graceful-fs": "^4.1.2", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw=="],
+ "fs-minipass": ["fs-minipass@2.1.0", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg=="],
+
+ "fs.realpath": ["fs.realpath@1.0.0", "", {}, "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="],
+
+ "gauge": ["gauge@4.0.4", "", { "dependencies": { "aproba": "^1.0.3 || ^2.0.0", "color-support": "^1.1.3", "console-control-strings": "^1.1.0", "has-unicode": "^2.0.1", "signal-exit": "^3.0.7", "string-width": "^4.2.3", "strip-ansi": "^6.0.1", "wide-align": "^1.1.5" } }, "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg=="],
+
+ "get-tsconfig": ["get-tsconfig@5.0.0-beta.5", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-/6gFNr0N04nob252sTQxyFLi3eKFRqIg1I87YcqAMT1i6SQrSF6KujUEQrtrjMV0H/eejTCltLdDSTEMzHbnsQ=="],
+
+ "github-from-package": ["github-from-package@0.0.0", "", {}, "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw=="],
+
"glob": ["glob@13.0.6", "", { "dependencies": { "minimatch": "^10.2.2", "minipass": "^7.1.3", "path-scurry": "^2.0.2" } }, "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw=="],
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
@@ -274,20 +404,50 @@
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
- "http-proxy-agent": ["http-proxy-agent@7.0.2", "", { "dependencies": { "agent-base": "^7.1.0", "debug": "^4.3.4" } }, "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig=="],
+ "has-unicode": ["has-unicode@2.0.1", "", {}, "sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ=="],
+
+ "hookable": ["hookable@6.1.1", "", {}, "sha512-U9LYDy1CwhMCnprUfeAZWZGByVbhd54hwepegYTK7Pi5NvqEj63ifz5z+xukznehT7i6NIZRu89Ay1AZmRsLEQ=="],
- "https-proxy-agent": ["https-proxy-agent@7.0.6", "", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
+ "http-cache-semantics": ["http-cache-semantics@4.2.0", "", {}, "sha512-dTxcvPXqPvXBQpq5dUr6mEMJX4oIEFv6bwom3FDwKRDsuIjjJGANqhBuoAn9c1RQJIdAKav33ED65E2ys+87QQ=="],
+
+ "http-proxy-agent": ["http-proxy-agent@4.0.1", "", { "dependencies": { "@tootallnate/once": "1", "agent-base": "6", "debug": "4" } }, "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg=="],
+
+ "https-proxy-agent": ["https-proxy-agent@5.0.1", "", { "dependencies": { "agent-base": "6", "debug": "4" } }, "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA=="],
"human-id": ["human-id@4.1.3", "", { "bin": { "human-id": "dist/cli.js" } }, "sha512-tsYlhAYpjCKa//8rXZ9DqKEawhPoSytweBC2eNvcaDK+57RZLHGqNs3PZTQO6yekLFSuvA6AlnAfrw1uBvtb+Q=="],
+ "humanize-ms": ["humanize-ms@1.2.1", "", { "dependencies": { "ms": "^2.0.0" } }, "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ=="],
+
"iconv-lite": ["iconv-lite@0.7.2", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw=="],
+ "ieee754": ["ieee754@1.2.1", "", {}, "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA=="],
+
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
+ "import-without-cache": ["import-without-cache@0.4.0", "", {}, "sha512-NkJQA7oZ4YHQhd2+H3BoRFKF3d/XNsiKpHZCQEMH9pDX27hQQLsTyOocyRgaIVtf8gHX3Nt3LPkR4e5EdtPAGQ=="],
+
+ "imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
+
+ "indent-string": ["indent-string@4.0.0", "", {}, "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg=="],
+
+ "infer-owner": ["infer-owner@1.0.4", "", {}, "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A=="],
+
+ "inflight": ["inflight@1.0.6", "", { "dependencies": { "once": "^1.3.0", "wrappy": "1" } }, "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA=="],
+
+ "inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
+
+ "ini": ["ini@1.3.8", "", {}, "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="],
+
+ "ip-address": ["ip-address@10.2.0", "", {}, "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="],
+
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
+ "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
+
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
+ "is-lambda": ["is-lambda@1.0.1", "", {}, "sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ=="],
+
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-subdir": ["is-subdir@1.2.0", "", { "dependencies": { "better-path-resolve": "1.0.0" } }, "sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw=="],
@@ -298,6 +458,8 @@
"js-yaml": ["js-yaml@4.1.1", "", { "dependencies": { "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA=="],
+ "jsesc": ["jsesc@3.1.0", "", { "bin": { "jsesc": "bin/jsesc" } }, "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA=="],
+
"jsonc-parser": ["jsonc-parser@3.3.1", "", {}, "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ=="],
"jsonfile": ["jsonfile@4.0.0", "", { "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg=="],
@@ -308,20 +470,60 @@
"lru-cache": ["lru-cache@11.2.7", "", {}, "sha512-aY/R+aEsRelme17KGQa/1ZSIpLpNYYrhcrepKTZgE+W3WM16YMCaPwOHLHsmopZHELU0Ojin1lPVxKR0MihncA=="],
+ "make-fetch-happen": ["make-fetch-happen@9.1.0", "", { "dependencies": { "agentkeepalive": "^4.1.3", "cacache": "^15.2.0", "http-cache-semantics": "^4.1.0", "http-proxy-agent": "^4.0.1", "https-proxy-agent": "^5.0.0", "is-lambda": "^1.0.1", "lru-cache": "^6.0.0", "minipass": "^3.1.3", "minipass-collect": "^1.0.2", "minipass-fetch": "^1.3.2", "minipass-flush": "^1.0.5", "minipass-pipeline": "^1.2.4", "negotiator": "^0.6.2", "promise-retry": "^2.0.1", "socks-proxy-agent": "^6.0.0", "ssri": "^8.0.0" } }, "sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg=="],
+
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
+ "mimic-response": ["mimic-response@3.1.0", "", {}, "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ=="],
+
"minimatch": ["minimatch@10.2.4", "", { "dependencies": { "brace-expansion": "^5.0.2" } }, "sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg=="],
+ "minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
+
"minipass": ["minipass@7.1.3", "", {}, "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A=="],
+ "minipass-collect": ["minipass-collect@1.0.2", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA=="],
+
+ "minipass-fetch": ["minipass-fetch@1.4.1", "", { "dependencies": { "minipass": "^3.1.0", "minipass-sized": "^1.0.3", "minizlib": "^2.0.0" }, "optionalDependencies": { "encoding": "^0.1.12" } }, "sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw=="],
+
+ "minipass-flush": ["minipass-flush@1.0.7", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-TbqTz9cUwWyHS2Dy89P3ocAGUGxKjjLuR9z8w4WUTGAVgEj17/4nhgo2Du56i0Fm3Pm30g4iA8Lcqctc76jCzA=="],
+
+ "minipass-pipeline": ["minipass-pipeline@1.2.4", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A=="],
+
+ "minipass-sized": ["minipass-sized@1.0.3", "", { "dependencies": { "minipass": "^3.0.0" } }, "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g=="],
+
+ "minizlib": ["minizlib@2.1.2", "", { "dependencies": { "minipass": "^3.0.0", "yallist": "^4.0.0" } }, "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg=="],
+
+ "mkdirp": ["mkdirp@1.0.4", "", { "bin": { "mkdirp": "bin/cmd.js" } }, "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw=="],
+
+ "mkdirp-classic": ["mkdirp-classic@0.5.3", "", {}, "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A=="],
+
"mri": ["mri@1.2.0", "", {}, "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
+ "napi-build-utils": ["napi-build-utils@2.0.0", "", {}, "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA=="],
+
+ "negotiator": ["negotiator@0.6.4", "", {}, "sha512-myRT3DiWPHqho5PrJaIRyaMv2kgYf0mUVgBNOYMuCH5Ki1yEiQaf/ZJuQ62nvpc44wL5WDbTX7yGJi1Neevw8w=="],
+
+ "node-abi": ["node-abi@3.92.0", "", { "dependencies": { "semver": "^7.3.5" } }, "sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ=="],
+
+ "node-addon-api": ["node-addon-api@7.1.1", "", {}, "sha512-5m3bsyrjFWE1xf7nz7YXdN4udnVtXK6/Yfgn5qnahL6bCkf2yKt4k3nuTKAtT4r3IG8JNR2ncsIMdZuAzJjHQQ=="],
+
+ "node-gyp": ["node-gyp@8.4.1", "", { "dependencies": { "env-paths": "^2.2.0", "glob": "^7.1.4", "graceful-fs": "^4.2.6", "make-fetch-happen": "^9.1.0", "nopt": "^5.0.0", "npmlog": "^6.0.0", "rimraf": "^3.0.2", "semver": "^7.3.5", "tar": "^6.1.2", "which": "^2.0.2" }, "bin": { "node-gyp": "bin/node-gyp.js" } }, "sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w=="],
+
+ "nopt": ["nopt@5.0.0", "", { "dependencies": { "abbrev": "1" }, "bin": { "nopt": "bin/nopt.js" } }, "sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ=="],
+
+ "npmlog": ["npmlog@6.0.2", "", { "dependencies": { "are-we-there-yet": "^3.0.0", "console-control-strings": "^1.1.0", "gauge": "^4.0.3", "set-blocking": "^2.0.0" } }, "sha512-/vBvz5Jfr9dT/aFWd0FIRf+T/Q2WBsLENygUaFUqstqsycmZAP/t5BvFJTK0viFmSUxiUKTUplWy5vt+rvKIxg=="],
+
"nypm": ["nypm@0.6.5", "", { "dependencies": { "citty": "^0.2.0", "pathe": "^2.0.3", "tinyexec": "^1.0.2" }, "bin": { "nypm": "dist/cli.mjs" } }, "sha512-K6AJy1GMVyfyMXRVB88700BJqNUkByijGJM8kEHpLdcAt+vSQAVfkWWHYzuRXHSY6xA2sNc5RjTj0p9rE2izVQ=="],
+ "obug": ["obug@2.1.1", "", {}, "sha512-uTqF9MuPraAQ+IsnPf366RG4cP9RtUi7MLO1N3KEc+wb0a6yKpeL0lmk2IB1jY5KHPAlTc6T/JRdC/YqxHNwkQ=="],
+
+ "once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
+
"outdent": ["outdent@0.5.0", "", {}, "sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q=="],
"oxfmt": ["oxfmt@0.41.0", "", { "dependencies": { "tinypool": "2.1.0" }, "optionalDependencies": { "@oxfmt/binding-android-arm-eabi": "0.41.0", "@oxfmt/binding-android-arm64": "0.41.0", "@oxfmt/binding-darwin-arm64": "0.41.0", "@oxfmt/binding-darwin-x64": "0.41.0", "@oxfmt/binding-freebsd-x64": "0.41.0", "@oxfmt/binding-linux-arm-gnueabihf": "0.41.0", "@oxfmt/binding-linux-arm-musleabihf": "0.41.0", "@oxfmt/binding-linux-arm64-gnu": "0.41.0", "@oxfmt/binding-linux-arm64-musl": "0.41.0", "@oxfmt/binding-linux-ppc64-gnu": "0.41.0", "@oxfmt/binding-linux-riscv64-gnu": "0.41.0", "@oxfmt/binding-linux-riscv64-musl": "0.41.0", "@oxfmt/binding-linux-s390x-gnu": "0.41.0", "@oxfmt/binding-linux-x64-gnu": "0.41.0", "@oxfmt/binding-linux-x64-musl": "0.41.0", "@oxfmt/binding-openharmony-arm64": "0.41.0", "@oxfmt/binding-win32-arm64-msvc": "0.41.0", "@oxfmt/binding-win32-ia32-msvc": "0.41.0", "@oxfmt/binding-win32-x64-msvc": "0.41.0" }, "bin": { "oxfmt": "bin/oxfmt" } }, "sha512-sKLdJZdQ3bw6x9qKiT7+eID4MNEXlDHf5ZacfIircrq6Qwjk0L6t2/JQlZZrVHTXJawK3KaMuBoJnEJPcqCEdg=="],
@@ -342,7 +544,7 @@
"path-exists": ["path-exists@4.0.0", "", {}, "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w=="],
- "path-expression-matcher": ["path-expression-matcher@1.2.0", "", {}, "sha512-DwmPWeFn+tq7TiyJ2CxezCAirXjFxvaiD03npak3cRjlP9+OjTmSy1EpIrEbh+l6JgUundniloMLDQ/6VTdhLQ=="],
+ "path-is-absolute": ["path-is-absolute@1.0.1", "", {}, "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="],
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
@@ -354,73 +556,147 @@
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
- "picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+ "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
"pify": ["pify@4.0.1", "", {}, "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="],
+ "prebuild-install": ["prebuild-install@7.1.3", "", { "dependencies": { "detect-libc": "^2.0.0", "expand-template": "^2.0.3", "github-from-package": "0.0.0", "minimist": "^1.2.3", "mkdirp-classic": "^0.5.3", "napi-build-utils": "^2.0.0", "node-abi": "^3.3.0", "pump": "^3.0.0", "rc": "^1.2.7", "simple-get": "^4.0.0", "tar-fs": "^2.0.0", "tunnel-agent": "^0.6.0" }, "bin": { "prebuild-install": "bin.js" } }, "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug=="],
+
"prettier": ["prettier@2.8.8", "", { "bin": { "prettier": "bin-prettier.js" } }, "sha512-tdN8qQGvNjw4CHbY+XXk0JgCXn9QiF21a55rBe5LJAU+kDyC4WQn4+awm2Xfk2lQMk5fKup9XgzTZtGkjBdP9Q=="],
+ "promise-inflight": ["promise-inflight@1.0.1", "", {}, "sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g=="],
+
+ "promise-retry": ["promise-retry@2.0.1", "", { "dependencies": { "err-code": "^2.0.2", "retry": "^0.12.0" } }, "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g=="],
+
+ "pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="],
+
"quansync": ["quansync@0.2.11", "", {}, "sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA=="],
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
+ "rc": ["rc@1.2.8", "", { "dependencies": { "deep-extend": "^0.6.0", "ini": "~1.3.0", "minimist": "^1.2.0", "strip-json-comments": "~2.0.1" }, "bin": { "rc": "./cli.js" } }, "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw=="],
+
"read-yaml-file": ["read-yaml-file@1.1.0", "", { "dependencies": { "graceful-fs": "^4.1.5", "js-yaml": "^3.6.1", "pify": "^4.0.1", "strip-bom": "^3.0.0" } }, "sha512-VIMnQi/Z4HT2Fxuwg5KrY174U1VdUIASQVWXXyqtNRtxSr9IYkn1rsI6Tb6HsrHCmB7gVpNwX6JxPTHcH6IoTA=="],
+ "readable-stream": ["readable-stream@3.6.2", "", { "dependencies": { "inherits": "^2.0.3", "string_decoder": "^1.1.1", "util-deprecate": "^1.0.1" } }, "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA=="],
+
"resolve-from": ["resolve-from@5.0.0", "", {}, "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw=="],
+ "resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
+
+ "retry": ["retry@0.12.0", "", {}, "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow=="],
+
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
+ "rimraf": ["rimraf@3.0.2", "", { "dependencies": { "glob": "^7.1.3" }, "bin": { "rimraf": "bin.js" } }, "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA=="],
+
+ "rolldown": ["rolldown@1.0.0", "", { "dependencies": { "@oxc-project/types": "=0.129.0", "@rolldown/pluginutils": "1.0.0" }, "optionalDependencies": { "@rolldown/binding-android-arm64": "1.0.0", "@rolldown/binding-darwin-arm64": "1.0.0", "@rolldown/binding-darwin-x64": "1.0.0", "@rolldown/binding-freebsd-x64": "1.0.0", "@rolldown/binding-linux-arm-gnueabihf": "1.0.0", "@rolldown/binding-linux-arm64-gnu": "1.0.0", "@rolldown/binding-linux-arm64-musl": "1.0.0", "@rolldown/binding-linux-ppc64-gnu": "1.0.0", "@rolldown/binding-linux-s390x-gnu": "1.0.0", "@rolldown/binding-linux-x64-gnu": "1.0.0", "@rolldown/binding-linux-x64-musl": "1.0.0", "@rolldown/binding-openharmony-arm64": "1.0.0", "@rolldown/binding-wasm32-wasi": "1.0.0", "@rolldown/binding-win32-arm64-msvc": "1.0.0", "@rolldown/binding-win32-x64-msvc": "1.0.0" }, "bin": { "rolldown": "bin/cli.mjs" } }, "sha512-yD986aXDESFGS95spT1LAv0jssywP4npMEjmMHyN2/5+eE8qQJUype2AaKkRiLgBgyD0LFlubwAht7VmY8rGoA=="],
+
+ "rolldown-plugin-dts": ["rolldown-plugin-dts@0.25.0", "", { "dependencies": { "@babel/generator": "8.0.0-rc.4", "@babel/helper-validator-identifier": "8.0.0-rc.4", "@babel/parser": "8.0.0-rc.4", "ast-kit": "^3.0.0-beta.1", "birpc": "^4.0.0", "dts-resolver": "^3.0.0", "get-tsconfig": "5.0.0-beta.5", "obug": "^2.1.1" }, "peerDependencies": { "@ts-macro/tsc": "^0.3.6", "@typescript/native-preview": ">=7.0.0-dev.20260325.1", "rolldown": "^1.0.0", "typescript": "^6.0.0", "vue-tsc": "~3.2.0" }, "optionalPeers": ["@ts-macro/tsc", "@typescript/native-preview", "typescript", "vue-tsc"] }, "sha512-GE3uDZgUuA9l6g+1u928TRmadd5IVhaWiwpWast2kCyLv9tYJJCC6E5HHkV0HGmwC5ZL73xh12/PRZI+KZ2vdQ=="],
+
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
+ "safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
+
"safer-buffer": ["safer-buffer@2.1.2", "", {}, "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="],
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
+ "set-blocking": ["set-blocking@2.0.0", "", {}, "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="],
+
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"signal-exit": ["signal-exit@4.1.0", "", {}, "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw=="],
+ "simple-concat": ["simple-concat@1.0.1", "", {}, "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q=="],
+
+ "simple-get": ["simple-get@4.0.1", "", { "dependencies": { "decompress-response": "^6.0.0", "once": "^1.3.1", "simple-concat": "^1.0.0" } }, "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA=="],
+
"sisteransi": ["sisteransi@1.0.5", "", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
"slash": ["slash@3.0.0", "", {}, "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q=="],
+ "smart-buffer": ["smart-buffer@4.2.0", "", {}, "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg=="],
+
+ "socks": ["socks@2.8.9", "", { "dependencies": { "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" } }, "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw=="],
+
+ "socks-proxy-agent": ["socks-proxy-agent@6.2.1", "", { "dependencies": { "agent-base": "^6.0.2", "debug": "^4.3.3", "socks": "^2.6.2" } }, "sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ=="],
+
"spawndamnit": ["spawndamnit@3.0.1", "", { "dependencies": { "cross-spawn": "^7.0.5", "signal-exit": "^4.0.1" } }, "sha512-MmnduQUuHCoFckZoWnXsTg7JaiLBJrKFj9UI2MbRPGaJeVpsLcVBu6P/IGZovziM/YBsellCmsprgNA+w0CzVg=="],
"sprintf-js": ["sprintf-js@1.0.3", "", {}, "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g=="],
+ "sqlite3": ["sqlite3@5.1.7", "", { "dependencies": { "bindings": "^1.5.0", "node-addon-api": "^7.0.0", "prebuild-install": "^7.1.1", "tar": "^6.1.11" }, "optionalDependencies": { "node-gyp": "8.x" } }, "sha512-GGIyOiFaG+TUra3JIfkI/zGP8yZYLPQ0pl1bH+ODjiX57sPhrLU5sQJn1y9bDKZUFYkX1crlrPfSYt0BKKdkog=="],
+
+ "ssri": ["ssri@8.0.1", "", { "dependencies": { "minipass": "^3.1.1" } }, "sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ=="],
+
+ "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
+
+ "string_decoder": ["string_decoder@1.3.0", "", { "dependencies": { "safe-buffer": "~5.2.0" } }, "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA=="],
+
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-bom": ["strip-bom@3.0.0", "", {}, "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA=="],
- "strnum": ["strnum@2.2.1", "", {}, "sha512-BwRvNd5/QoAtyW1na1y1LsJGQNvRlkde6Q/ipqqEaivoMdV+B1OMOTVdwR+N/cwVUcIt9PYyHmV8HyexCZSupg=="],
+ "strip-json-comments": ["strip-json-comments@2.0.1", "", {}, "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ=="],
+
+ "tar": ["tar@6.2.1", "", { "dependencies": { "chownr": "^2.0.0", "fs-minipass": "^2.0.0", "minipass": "^5.0.0", "minizlib": "^2.1.1", "mkdirp": "^1.0.3", "yallist": "^4.0.0" } }, "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A=="],
+
+ "tar-fs": ["tar-fs@2.1.4", "", { "dependencies": { "chownr": "^1.1.1", "mkdirp-classic": "^0.5.2", "pump": "^3.0.0", "tar-stream": "^2.1.4" } }, "sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ=="],
+
+ "tar-stream": ["tar-stream@2.2.0", "", { "dependencies": { "bl": "^4.0.3", "end-of-stream": "^1.4.1", "fs-constants": "^1.0.0", "inherits": "^2.0.3", "readable-stream": "^3.1.1" } }, "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ=="],
"term-size": ["term-size@2.2.1", "", {}, "sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg=="],
- "tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="],
+ "tinyexec": ["tinyexec@1.1.2", "", {}, "sha512-dAqSqE/RabpBKI8+h26GfLq6Vb3JVXs30XYQjdMjaj/c2tS8IYYMbIzP599KtRj7c57/wYApb3QjgRgXmrCukA=="],
+
+ "tinyglobby": ["tinyglobby@0.2.16", "", { "dependencies": { "fdir": "^6.5.0", "picomatch": "^4.0.4" } }, "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg=="],
"tinypool": ["tinypool@2.1.0", "", {}, "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw=="],
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
+ "tree-kill": ["tree-kill@1.2.2", "", { "bin": { "tree-kill": "cli.js" } }, "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A=="],
+
+ "tsdown": ["tsdown@0.22.0", "", { "dependencies": { "ansis": "^4.2.0", "cac": "^7.0.0", "defu": "^6.1.7", "empathic": "^2.0.0", "hookable": "^6.1.1", "import-without-cache": "^0.4.0", "obug": "^2.1.1", "picomatch": "^4.0.4", "rolldown": "^1.0.0", "rolldown-plugin-dts": "^0.25.0", "semver": "^7.7.4", "tinyexec": "^1.1.2", "tinyglobby": "^0.2.16", "tree-kill": "^1.2.2", "unconfig-core": "^7.5.0" }, "peerDependencies": { "@arethetypeswrong/core": "^0.18.1", "@tsdown/css": "0.22.0", "@tsdown/exe": "0.22.0", "@vitejs/devtools": "*", "publint": "^0.3.8", "tsx": "*", "typescript": "^5.0.0 || ^6.0.0", "unplugin-unused": "^0.5.0", "unrun": "*" }, "optionalPeers": ["@arethetypeswrong/core", "@tsdown/css", "@tsdown/exe", "@vitejs/devtools", "publint", "tsx", "typescript", "unplugin-unused", "unrun"], "bin": { "tsdown": "./dist/run.mjs" } }, "sha512-FgW0hHb27nGQA/+F3d5+U9wKXkfilk9DVkc5+7x/ZqF03g+Hoz/eeApT32jqxATt9eRoR+1jxk7MUMON+O4CXw=="],
+
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
+ "tunnel-agent": ["tunnel-agent@0.6.0", "", { "dependencies": { "safe-buffer": "^5.0.1" } }, "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w=="],
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"ultracite": ["ultracite@7.3.2", "", { "dependencies": { "@clack/prompts": "^1.1.0", "commander": "^14.0.3", "deepmerge": "^4.3.1", "glob": "^13.0.6", "jsonc-parser": "^3.3.1", "nypm": "^0.6.5" }, "peerDependencies": { "oxlint": "^1.0.0" }, "optionalPeers": ["oxlint"], "bin": { "ultracite": "dist/index.js" } }, "sha512-JV2TdeBDc1aaj3wFzXLjRcBlUZkXBdShMLAjHh9YLK0rXPSK42CzHqfWXUfibFUAUiUGNwoOFnIpS45EaJAcdg=="],
+ "unconfig-core": ["unconfig-core@7.5.0", "", { "dependencies": { "@quansync/fs": "^1.0.0", "quansync": "^1.0.0" } }, "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w=="],
+
"undici": ["undici@6.24.1", "", {}, "sha512-sC+b0tB1whOCzbtlx20fx3WgCXwkW627p4EA9uM+/tNNPkSS+eSEld6pAs9nDv7WbY1UUljBMYPtu9BCOrCWKA=="],
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
+ "unique-filename": ["unique-filename@1.1.1", "", { "dependencies": { "unique-slug": "^2.0.0" } }, "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ=="],
+
+ "unique-slug": ["unique-slug@2.0.2", "", { "dependencies": { "imurmurhash": "^0.1.4" } }, "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w=="],
+
"universalify": ["universalify@0.1.2", "", {}, "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="],
+ "util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
+
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
- "@actions/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
+ "wide-align": ["wide-align@1.1.5", "", { "dependencies": { "string-width": "^1.0.2 || 2 || 3 || 4" } }, "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg=="],
+
+ "wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
+
+ "yallist": ["yallist@4.0.0", "", {}, "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="],
+
+ "zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
+
+ "@connectrpc/connect-node/undici": ["undici@5.29.0", "", { "dependencies": { "@fastify/busboy": "^2.0.0" } }, "sha512-raqeBD6NQK4SkWhQzeYKd1KmIG6dllBOTt55Rmkt4HtI9mwdWtJljnrXjAFUBLTSN67HWrOIZ3EPF4kjUw80Bg=="],
"@manypkg/find-root/@types/node": ["@types/node@12.20.55", "", {}, "sha512-J8xLz7q2OFulZ2cyGTLE1TbbZcjpno7FaN6zdJNrgAdrJ+DZzh/uFR6YrTb4C+nXakvud8Q4+rbhoIWlYQbUFQ=="],
@@ -430,12 +706,74 @@
"@manypkg/get-packages/fs-extra": ["fs-extra@8.1.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^4.0.0", "universalify": "^0.1.0" } }, "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g=="],
+ "@quansync/fs/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="],
+
+ "cacache/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
+
+ "cacache/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
+
+ "cacache/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "cacache/p-map": ["p-map@4.0.0", "", { "dependencies": { "aggregate-error": "^3.0.0" } }, "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ=="],
+
+ "encoding/iconv-lite": ["iconv-lite@0.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
+
+ "fs-minipass/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "gauge/signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
+
+ "make-fetch-happen/lru-cache": ["lru-cache@6.0.0", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA=="],
+
+ "make-fetch-happen/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
+
+ "minipass-collect/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "minipass-fetch/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "minipass-flush/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "minipass-pipeline/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "minipass-sized/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "minizlib/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "node-gyp/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
+
+ "nypm/tinyexec": ["tinyexec@1.0.4", "", {}, "sha512-u9r3uZC0bdpGOXtlxUIdwf9pkmvhqJdrVCH9fapQtgy/OeTTMZ1nqH7agtvEfmGui6e1XxjcdrlxvxJvc3sMqw=="],
+
"read-yaml-file/js-yaml": ["js-yaml@3.14.2", "", { "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" }, "bin": { "js-yaml": "bin/js-yaml.js" } }, "sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg=="],
- "@actions/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
+ "rimraf/glob": ["glob@7.2.3", "", { "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^3.1.1", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } }, "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q=="],
+
+ "ssri/minipass": ["minipass@3.3.6", "", { "dependencies": { "yallist": "^4.0.0" } }, "sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw=="],
+
+ "tar/minipass": ["minipass@5.0.0", "", {}, "sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ=="],
+
+ "tar-fs/chownr": ["chownr@1.1.4", "", {}, "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg=="],
+
+ "unconfig-core/quansync": ["quansync@1.0.0", "", {}, "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA=="],
+
+ "cacache/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
+
+ "node-gyp/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
"read-yaml-file/js-yaml/argparse": ["argparse@1.0.10", "", { "dependencies": { "sprintf-js": "~1.0.2" } }, "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg=="],
- "@actions/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
+ "rimraf/glob/minimatch": ["minimatch@3.1.5", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w=="],
+
+ "cacache/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
+
+ "node-gyp/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
+
+ "rimraf/glob/minimatch/brace-expansion": ["brace-expansion@1.1.12", "", { "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" } }, "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg=="],
+
+ "cacache/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
+
+ "node-gyp/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
+
+ "rimraf/glob/minimatch/brace-expansion/balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
}
}
diff --git a/package.json b/package.json
index 00dfb6d..ae47249 100644
--- a/package.json
+++ b/package.json
@@ -26,7 +26,8 @@
"registry": "https://registry.npmjs.org/"
},
"scripts": {
- "build": "ncc build src/index.ts --license licenses.txt",
+ "build": "tsdown",
+ "dev": "tsdown --watch",
"test": "bun test",
"test:coverage": "bun test --coverage",
"typecheck": "tsc --noEmit",
@@ -37,19 +38,15 @@
"changeset:publish": "bun run build && changeset publish"
},
"dependencies": {
- "@actions/cache": "^6.0.0",
"@actions/core": "^3.0.0",
- "@actions/exec": "^3.0.0",
- "@actions/http-client": "^4.0.0",
- "@actions/io": "^3.0.2",
- "@actions/tool-cache": "^4.0.0"
+ "@cursor/sdk": "^1.0.12"
},
"devDependencies": {
"@changesets/cli": "^2.30.0",
"@types/bun": "latest",
- "@vercel/ncc": "^0.38.4",
"oxfmt": "^0.41.0",
"oxlint": "^1.56.0",
+ "tsdown": "^0.22.0",
"ultracite": "7.3.2"
},
"peerDependencies": {
diff --git a/src/cursor-version.ts b/src/cursor-version.ts
deleted file mode 100644
index 63c37aa..0000000
--- a/src/cursor-version.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-/** Cursor CLI lab artifacts use build ids like `2026.03.20-44cb435`. */
-export const CURSOR_LAB_VERSION_RE = /^\d+\.\d+\.\d+(?:-[A-Za-z0-9]+)?$/;
-
-/**
- * Parses a plain-text latest-version response body (single line, optional `v` prefix).
- */
-export const parseLabVersionString = (body: string): string | null => {
- const firstLine =
- body.trim().replace(/^v/, "").split(/\r?\n/)[0]?.trim() ?? "";
- return CURSOR_LAB_VERSION_RE.test(firstLine) ? firstLine : null;
-};
-
-/**
- * Extracts the lab build id from the official bash or PowerShell install script body.
- */
-export const extractLabVersionFromInstallScript = (
- body: string
-): string | null => {
- const m = body.match(/https:\/\/downloads\.cursor\.com\/lab\/([^/'"\s]+)\//);
- const candidate = m?.[1]?.trim();
- if (!candidate || !CURSOR_LAB_VERSION_RE.test(candidate)) {
- return null;
- }
- return candidate;
-};
diff --git a/src/index.ts b/src/index.ts
index a4b1158..553eb98 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,33 +1,20 @@
-import { endGroup, info, setFailed, startGroup } from "@actions/core";
+import { endGroup, setFailed, startGroup } from "@actions/core";
import { getInputs } from "./input";
-import { installCursorCLI } from "./installer";
import { maskSecret, setOutputs } from "./output";
import { runAgent } from "./runner";
export const run = async (): Promise => {
try {
- // Parse & validate inputs
const inputs = getInputs();
-
- // Immediately mask secrets from any log output
maskSecret(inputs.apiKey);
- startGroup("š§ Installing Cursor CLI");
- const { cacheHit, resolvedVersion } = await installCursorCLI(
- inputs.cursorVersion
- );
- info(`Cursor CLI v${resolvedVersion} ready (cache hit: ${cacheHit})`);
- endGroup();
-
startGroup("š¤ Running cursor-agent");
const result = await runAgent(inputs);
endGroup();
- // Parse output and set all action outputs + job summary
- const outputs = await setOutputs(result, cacheHit);
+ const outputs = await setOutputs(result);
- // Fail the step if cursor-agent returned a non-zero exit code
if (outputs.exitCode !== 0) {
setFailed(
`cursor-agent exited with code ${outputs.exitCode}. ` +
diff --git a/src/input.ts b/src/input.ts
index 123ecd2..7b44df1 100644
--- a/src/input.ts
+++ b/src/input.ts
@@ -1,18 +1,13 @@
import { getInput, warning } from "@actions/core";
-import { CURSOR_LAB_VERSION_RE } from "./cursor-version";
import type { ActionInputs, Permission } from "./types";
const VALID_PERMISSIONS: Permission[] = ["read-only", "read-write", "full"];
-/**
- * Reads, validates, and returns all action inputs.
- * @returns The validated action inputs.
- * @throws Throws descriptive errors for invalid inputs so users get clear feedback.
- */
export const getInputs = (): ActionInputs => {
+ const cursorVersionRaw = getInput("cursor-version", { required: false });
const cursorVersion =
- getInput("cursor-version", { required: false }) || "latest";
+ cursorVersionRaw.trim().length > 0 ? cursorVersionRaw.trim() : undefined;
const apiKey = getInput("api-key", { required: true });
const prompt = getInput("prompt", { required: true });
const model = getInput("model", { required: false }) || "auto";
@@ -22,7 +17,13 @@ export const getInputs = (): ActionInputs => {
getInput("permissions", { required: false }) || "read-only";
const timeoutRaw = getInput("timeout", { required: false }) || "300";
- // Validate permissions
+ if (cursorVersion && cursorVersion !== "latest") {
+ warning(
+ "The 'cursor-version' input is deprecated. The Action now uses the official @cursor/sdk " +
+ "which automatically manages the agent version."
+ );
+ }
+
if (!VALID_PERMISSIONS.includes(permissionsRaw as Permission)) {
throw new Error(
`Invalid 'permissions' value: '${permissionsRaw}'. ` +
@@ -30,13 +31,13 @@ export const getInputs = (): ActionInputs => {
);
}
- // Validate timeout
const timeout = Number.parseInt(timeoutRaw, 10);
if (Number.isNaN(timeout) || timeout <= 0) {
throw new Error(
`Invalid 'timeout' value: '${timeoutRaw}'. Must be a positive integer (seconds).`
);
}
+
if (timeout > 3600) {
warning(
`Timeout is set to ${timeout}s (${Math.round(timeout / 60)}min). ` +
@@ -44,28 +45,13 @@ export const getInputs = (): ActionInputs => {
);
}
- // Validate version: "latest" or a published lab build id (see official install script / latest-version)
- const normalizedCursorVersion = cursorVersion.replace(/^v/, "");
- if (
- cursorVersion !== "latest" &&
- !CURSOR_LAB_VERSION_RE.test(normalizedCursorVersion)
- ) {
- throw new Error(
- `Invalid 'cursor-version' value: '${cursorVersion}'. ` +
- `Use 'latest', or pin an exact build id that exists on Cursor's CDN ` +
- `(e.g. the value from https://downloads.cursor.com/lab/latest-version, ` +
- `like '2026.03.20-44cb435'). Arbitrary values like '1.2.3' are not published and will fail to download.`
- );
- }
-
- // Validate prompt is not empty
if (!prompt.trim()) {
throw new Error("The 'prompt' input cannot be empty.");
}
return {
apiKey,
- cursorVersion,
+ ...(cursorVersion !== undefined ? { cursorVersion } : {}),
model,
permissions: permissionsRaw as Permission,
prompt,
diff --git a/src/installer.ts b/src/installer.ts
deleted file mode 100644
index 57e7e9a..0000000
--- a/src/installer.ts
+++ /dev/null
@@ -1,297 +0,0 @@
-import { execSync } from "node:child_process";
-import { promises as fs } from "node:fs";
-import { homedir } from "node:os";
-import path from "node:path";
-
-import { restoreCache, saveCache } from "@actions/cache";
-import { addPath, debug, info, warning } from "@actions/core";
-import { HttpClient } from "@actions/http-client";
-import { mkdirP } from "@actions/io";
-import {
- cacheDir,
- downloadTool,
- extractTar,
- extractZip,
- find,
-} from "@actions/tool-cache";
-
-import {
- extractLabVersionFromInstallScript,
- parseLabVersionString,
-} from "./cursor-version";
-import type { Arch, Platform } from "./types";
-
-const CURSOR_DOWNLOAD_BASE = "https://downloads.cursor.com/lab";
-const CURSOR_VERSION_URL = "https://downloads.cursor.com/lab/latest-version";
-const CURSOR_INSTALL_SCRIPT_URL = "https://cursor.com/install";
-
-const getPlatform = (): Platform => {
- const p = process.platform;
- if (p === "linux") {
- return "linux";
- }
- if (p === "darwin") {
- return "darwin";
- }
- if (p === "win32") {
- return "win32";
- }
-
- throw new Error(`Unsupported platform: ${p}`);
-};
-
-const getArch = (): Arch => {
- const a = process.arch;
- if (a === "x64") {
- return "x64";
- }
- if (a === "arm64") {
- return "arm64";
- }
- throw new Error(`Unsupported architecture: ${a}`);
-};
-
-const tryResolveLatestFromVersionUrl = async (
- client: HttpClient
-): Promise => {
- const response = await client.get(CURSOR_VERSION_URL);
- const statusCode = response.message.statusCode ?? 0;
- const body = await response.readBody();
- if (statusCode !== 200) {
- debug(
- `Cursor lab latest-version returned HTTP ${statusCode}; trying install script fallback.`
- );
- return null;
- }
- return parseLabVersionString(body);
-};
-
-const tryResolveLatestFromInstallScript = async (
- client: HttpClient
-): Promise => {
- const response = await client.get(CURSOR_INSTALL_SCRIPT_URL);
- const statusCode = response.message.statusCode ?? 0;
- const body = await response.readBody();
- if (statusCode !== 200) {
- throw new Error(
- `Cursor install script returned HTTP ${statusCode} (expected 200).`
- );
- }
- return extractLabVersionFromInstallScript(body);
-};
-
-/**
- * Resolves "latest" to a concrete lab build id via the version endpoint, with
- * fallback to the official install script (the lab endpoint often returns 403).
- */
-export const resolveVersion = async (version: string): Promise => {
- if (version !== "latest") {
- // Keep pinned versions local; no network call needed.
- return version.replace(/^v/, "");
- }
-
- debug("Resolving latest Cursor CLI version...");
- // Match `curl https://cursor.com/install` so cursor.com returns the shell script (not HTML).
- const client = new HttpClient("curl/8.5.0 (compatible; cursor-action)");
-
- try {
- const fromEndpoint = await tryResolveLatestFromVersionUrl(client);
- if (fromEndpoint) {
- debug(`Resolved latest version (lab endpoint): ${fromEndpoint}`);
- return fromEndpoint;
- }
-
- const fromScript = await tryResolveLatestFromInstallScript(client);
- if (fromScript) {
- debug(`Resolved latest version (install script): ${fromScript}`);
- return fromScript;
- }
-
- throw new Error(
- "Could not resolve latest Cursor CLI version: lab endpoint did not return a valid version " +
- "and the official install script did not contain a download URL. " +
- "Pin `cursor-version` to a known lab build id, or try again later."
- );
- } catch (error) {
- throw new Error(`Failed to resolve latest Cursor CLI version: ${error}`, {
- cause: error,
- });
- }
-};
-
-/**
- * Builds the download URL for the Cursor CLI tarball.
- * Pattern: https://downloads.cursor.com/lab/{version}/{platform}/{arch}/agent-cli-package.tar.gz
- */
-export const buildDownloadUrl = (
- version: string,
- platform: Platform,
- arch: Arch
-): string => {
- const ext = platform === "win32" ? "zip" : "tar.gz";
- const platformSegment = platform === "win32" ? "windows" : platform;
- return `${CURSOR_DOWNLOAD_BASE}/${version}/${platformSegment}/${arch}/agent-cli-package.${ext}`;
-};
-
-/** Bumped when install layout changes (e.g. copy full package vs single binary). */
-const CURSOR_CLI_CACHE_LAYOUT = "bundle-v1";
-
-const buildCacheKey = (
- version: string,
- platform: Platform,
- arch: Arch
-): string =>
- `cursor-cli-${platform}-${arch}-${version}-${CURSOR_CLI_CACHE_LAYOUT}`;
-
-/** Tool-cache version must match find() ā suffix invalidates old single-file caches. */
-const toolCacheVersion = (labVersion: string): string =>
- `${labVersion}-${CURSOR_CLI_CACHE_LAYOUT}`;
-
-const getBinaryName = (): string =>
- process.platform === "win32" ? "cursor-agent.exe" : "cursor-agent";
-
-const findBinary = async (dir: string, binaryName: string): Promise => {
- const search = async (currentDir: string): Promise => {
- const entries = await fs.readdir(currentDir, { withFileTypes: true });
- for (const entry of entries) {
- const fullPath = path.join(currentDir, entry.name);
- if (entry.isFile() && entry.name === binaryName) {
- return fullPath;
- }
- if (entry.isDirectory()) {
- const found = await search(fullPath);
- if (found) {
- return found;
- }
- }
- }
- return null;
- };
-
- const result = await search(dir);
- if (!result) {
- throw new Error(
- `Could not find '${binaryName}' binary in extracted archive at ${dir}`
- );
- }
- return result;
-};
-
-/**
- * Copies the extracted agent package (cursor-agent launcher + bundled node, etc.) into installDir.
- */
-const installAgentPackage = async (
- extractedPath: string,
- installDir: string,
- binaryName: string
-): Promise => {
- const binarySource = await findBinary(extractedPath, binaryName);
- const packageRoot = path.dirname(binarySource);
-
- await mkdirP(installDir);
- const entries = await fs.readdir(packageRoot, { withFileTypes: true });
- for (const entry of entries) {
- const from = path.join(packageRoot, entry.name);
- const to = path.join(installDir, entry.name);
- await fs.cp(from, to, { force: true, recursive: true });
- }
-
- const mainBin = path.join(installDir, binaryName);
- try {
- await fs.access(mainBin);
- if (process.platform !== "win32") {
- execSync(`chmod +x "${mainBin}"`);
- }
- } catch {
- // ignore
- }
-
- const nodeName = process.platform === "win32" ? "node.exe" : "node";
- const nodePath = path.join(installDir, nodeName);
- try {
- const st = await fs.stat(nodePath);
- if (st.isFile() && process.platform !== "win32") {
- execSync(`chmod +x "${nodePath}"`);
- }
- } catch {
- // bundled node may be absent on some platforms
- }
-};
-
-/**
- * Installer entry point
- * @returns Returns { binPath, cacheHit } where binPath is the directory added to PATH
- */
-export const installCursorCLI = async (
- requestedVersion: string
-): Promise<{
- binPath: string;
- cacheHit: boolean;
- resolvedVersion: string;
-}> => {
- const platform = getPlatform();
- const arch = getArch();
- const resolvedVersion = await resolveVersion(requestedVersion);
-
- info(`Installing Cursor CLI v${resolvedVersion} (${platform}/${arch})`);
-
- const tcVersion = toolCacheVersion(resolvedVersion);
-
- // Check @actions/tool-cache first (within-job cache)
- const cachedPath = find("cursor-agent", tcVersion, arch);
- if (cachedPath) {
- info(`Found Cursor CLI in tool cache: ${cachedPath}`);
- addPath(cachedPath);
- return { binPath: cachedPath, cacheHit: true, resolvedVersion };
- }
-
- // Check @actions/cache (cross-job cache)
- const installDir = path.join(homedir(), ".cursor-cli", resolvedVersion);
- const cacheKey = buildCacheKey(resolvedVersion, platform, arch);
- const cachePaths = [installDir];
-
- const restoredKey = await restoreCache(cachePaths, cacheKey);
- if (restoredKey) {
- info(`Restored Cursor CLI from cache (key: ${restoredKey})`);
- addPath(installDir);
- return { binPath: installDir, cacheHit: true, resolvedVersion };
- }
-
- // Download & Extract
- const downloadUrl = buildDownloadUrl(resolvedVersion, platform, arch);
- info(`Downloading Cursor CLI from: ${downloadUrl}`);
-
- let extractedPath: string;
- try {
- const archivePath = await downloadTool(downloadUrl);
- extractedPath = await (platform === "win32"
- ? extractZip(archivePath)
- : extractTar(archivePath));
- } catch (error) {
- throw new Error(
- `Failed to download Cursor CLI v${resolvedVersion}. ` +
- `Check that the version exists and the platform is supported. Error: ${error}`,
- { cause: error }
- );
- }
-
- const binaryName = getBinaryName();
- await installAgentPackage(extractedPath, installDir, binaryName);
-
- // Cache the install dir for future jobs
- try {
- await saveCache(cachePaths, cacheKey);
- info(`Cached Cursor CLI with key: ${cacheKey}`);
- } catch (error) {
- // Non-fatal: caching failure should not break the workflow
- warning(`Failed to save Cursor CLI to cache: ${error}`);
- }
-
- // Also register in tool-cache for within-job reuse
- await cacheDir(installDir, "cursor-agent", tcVersion, arch);
-
- addPath(installDir);
- info(`Cursor CLI v${resolvedVersion} installed to ${installDir}`);
-
- return { binPath: installDir, cacheHit: false, resolvedVersion };
-};
diff --git a/src/output.ts b/src/output.ts
index 83e1494..06e7d4f 100644
--- a/src/output.ts
+++ b/src/output.ts
@@ -8,11 +8,8 @@ const parseSummary = (stdout: string): string => {
return "";
}
- // Try JSON parse
try {
const parsed = JSON.parse(trimmed);
-
- // Handle common response shapes
if (typeof parsed === "object" && parsed !== null) {
if (typeof parsed.response === "string") {
return parsed.response.trim();
@@ -31,10 +28,9 @@ const parseSummary = (stdout: string): string => {
}
}
} catch {
- // Not JSON ā fall through to raw text handling
+ // Not JSON
}
- // Strip common ANSI escape codes that might leak through despite NO_COLOR=1
const clean = trimmed.replaceAll(
// eslint-disable-next-line no-control-regex
/\u001B\[[0-9;]*[mGKHF]/g,
@@ -53,17 +49,6 @@ const writeJobSummary = async (
? "ā
Success"
: `ā Failed (exit ${result.exitCode})`;
- const tableRows: [string, string][] = [
- ["Status", status],
- ["Exit Code", String(result.exitCode)],
- ];
- if (result.invocationMode) {
- tableRows.push(["Invocation mode", result.invocationMode]);
- }
- if (result.cliVersion) {
- tableRows.push(["cursor-agent --version", result.cliVersion]);
- }
-
await summary
.addHeading("Cursor Agent Run", 2)
.addTable([
@@ -71,7 +56,8 @@ const writeJobSummary = async (
{ data: "Field", header: true },
{ data: "Value", header: true },
],
- ...tableRows.map(([field, value]) => [field, value]),
+ ["Status", status],
+ ["Exit Code", String(result.exitCode)],
])
.addHeading("Agent Response", 3)
.addRaw(text ? `\n\`\`\`\n${text}\n\`\`\`\n` : "_No output was produced._");
@@ -79,14 +65,14 @@ const writeJobSummary = async (
const errText = result.stderr.trim();
if (errText) {
await summary
- .addHeading("cursor-agent stderr", 3)
+ .addHeading("Agent Error (stderr)", 3)
.addRaw(
`\n\`\`\`\n${errText.slice(0, 20_000)}${errText.length > 20_000 ? "\n⦠(truncated)" : ""}\n\`\`\`\n`
);
}
const diag = result.diagnostics?.trim();
- if (diag) {
+ if (diag && diag !== errText) {
await summary
.addHeading("Diagnostics", 3)
.addRaw(
@@ -97,32 +83,20 @@ const writeJobSummary = async (
await summary.write();
};
-/**
- * Sets all GitHub Actions outputs and writes a job summary.
- */
export const setOutputs = async (
- result: AgentResult,
- cacheHit: boolean
+ result: AgentResult
): Promise => {
const text = parseSummary(result.stdout);
- // Set outputs
setOutput("summary", text);
setOutput("exit-code", String(result.exitCode));
- setOutput("cache-hit", String(cacheHit));
- // Write to the GitHub Actions job summary (visible in the Actions UI)
await writeJobSummary(text, result);
return {
- cacheHit,
exitCode: result.exitCode,
summary: text,
};
};
-/**
- * Masks the API key in any log output (belt-and-suspenders on top of
- * the secret masking that @actions/core already applies).
- */
export const maskSecret = (apiKey: string): void => setSecret(apiKey);
diff --git a/src/runner.ts b/src/runner.ts
index 7c53aeb..58c33ea 100644
--- a/src/runner.ts
+++ b/src/runner.ts
@@ -1,403 +1,56 @@
import { resolve } from "node:path";
-import { debug, info, warning } from "@actions/core";
-import { exec, getExecOutput } from "@actions/exec";
-import type { ExecOptions } from "@actions/exec";
+import { info, warning } from "@actions/core";
+import { Agent } from "@cursor/sdk";
-import type { ActionInputs, AgentInvocationMode, AgentResult } from "./types";
+import type { ActionInputs, AgentResult } from "./types";
-const PERMISSION_FLAGS: Record = {
- full: ["--allow-read", "--allow-write", "--allow-run"],
- "read-only": ["--allow-read"],
- "read-write": ["--allow-read", "--allow-write"],
-};
-
-const buildChatArgs = (inputs: ActionInputs): string[] => {
- const args: string[] = [
- "chat",
- inputs.prompt,
- "--no-interactive",
- "--model",
- inputs.model,
- ];
-
- const permFlags = PERMISSION_FLAGS[inputs.permissions];
- args.push(...permFlags);
-
- return args;
-};
-
-/**
- * Headless print mode (`-p` / `--print`) per Cursor CLI docs; omits `chat` subcommand
- * and legacy `--allow-*` flags which may not apply to print mode.
- */
-const buildPrintArgs = (inputs: ActionInputs): string[] => {
- const args: string[] = [
- "-p",
- "--trust",
- "--output-format",
- "text",
- "--model",
- inputs.model,
- ];
-
- if (inputs.permissions === "read-write" || inputs.permissions === "full") {
- args.push("--force");
- }
-
- args.push(inputs.prompt);
- return args;
-};
-
-const buildPreflightArgs = (inputs: ActionInputs): string[] => [
- "-p",
- "--trust",
- "--output-format",
- "text",
- "--model",
- inputs.model,
- "Reply with OK and nothing else.",
-];
-
-const isEmptyIo = (stdout: string, stderr: string): boolean =>
- !stdout.trim() && !stderr.trim();
-
-const stderrSuggestsCliMismatch = (stderr: string): boolean => {
- const s = stderr.toLowerCase();
- return (
- s.includes("unknown command") ||
- s.includes("unrecognized") ||
- s.includes("invalid option") ||
- s.includes("did you mean") ||
- s.includes("error: unknown")
- );
-};
-
-const shouldTryPrintFallback = (result: {
- exitCode: number;
- stderr: string;
- stdout: string;
-}): boolean => {
- if (result.exitCode === 0) {
- return false;
- }
- if (isEmptyIo(result.stdout, result.stderr)) {
- return true;
- }
- return stderrSuggestsCliMismatch(result.stderr);
-};
-
-const fetchCliVersionLine = async (
- env: NonNullable,
- cwd: string
-): Promise => {
- try {
- const out = await getExecOutput("cursor-agent", ["--version"], {
- cwd,
- env,
- ignoreReturnCode: true,
- silent: true,
- });
- const line = (out.stdout || out.stderr).trim();
- return line || "(no output from cursor-agent --version)";
- } catch {
- return "(could not run cursor-agent --version)";
- }
-};
-
-const buildExecEnv = (
- inputs: ActionInputs
-): NonNullable => {
- const baseEnv = Object.fromEntries(
- Object.entries(process.env).filter(
- (entry): entry is [string, string] => entry[1] !== undefined
- )
- );
-
- return {
- ...baseEnv,
- CURSOR_API_KEY: inputs.apiKey,
- NO_COLOR: "1",
- ...(inputs.cursorVersion === "latest"
- ? {}
- : { CURSOR_DISABLE_UPDATE: "1" }),
- };
-};
-
-const runAgentOnce = async (
- args: string[],
- options: ExecOptions
-): Promise<{ exitCode: number; stderr: string; stdout: string }> => {
- let stdout = "";
- let stderr = "";
- const exitCode = await exec("cursor-agent", args, {
- ...options,
- ignoreReturnCode: true,
- listeners: {
- stderr: (data: Buffer) => {
- stderr += data.toString();
- debug(`cursor-agent stderr: ${data.toString().trim()}`);
- },
- stdout: (data: Buffer) => {
- stdout += data.toString();
- },
- },
- silent: false,
- });
- return { exitCode, stderr, stdout };
-};
-
-const runPreflightProbe = async (
- inputs: ActionInputs,
- options: ExecOptions
-): Promise<{ exitCode: number; stderr: string; stdout: string }> => {
- try {
- const out = await getExecOutput(
- "cursor-agent",
- buildPreflightArgs(inputs),
- {
- ...options,
- ignoreReturnCode: true,
- silent: true,
- }
- );
- return {
- exitCode: out.exitCode,
- stderr: out.stderr,
- stdout: out.stdout,
- };
- } catch {
- return {
- exitCode: 1,
- stderr: "",
- stdout: "",
- };
- }
-};
-
-const failureHints = (inputs: ActionInputs): string =>
- [
- "Confirm CURSOR_API_KEY is set and valid for Cursor Agent / headless use.",
- "Some accounts require a Pro/Business plan for agent features; API-key-only usage may be restricted.",
- `If using a custom model, ensure "${inputs.model}" is supported for your account.`,
- "Try pinning cursor-version to a known lab build id if the CLI contract changed.",
- ].join("\n");
-
-const buildDiagnostics = (
- cliVersion: string | undefined,
- inputs: ActionInputs,
- preflight: { exitCode: number; stderr: string; stdout: string },
- chat: { exitCode: number; stderr: string; stdout: string },
- print?: { exitCode: number; stderr: string; stdout: string }
-): string => {
- const parts: string[] = [
- `Invocation: primary=chat, fallback=headless print (-p)`,
- cliVersion ? `cursor-agent --version: ${cliVersion}` : "",
- `Model: ${inputs.model} | Permissions: ${inputs.permissions}`,
- "",
- `Auth/Entitlement preflight (print -p) exit ${preflight.exitCode}:`,
- preflight.stderr.trim() || preflight.stdout.trim()
- ? `stderr: ${preflight.stderr.trim() || "(empty)"}\nstdout: ${preflight.stdout.trim() || "(empty)"}`
- : "(no stdout/stderr)",
- "",
- `Primary (chat) exit ${chat.exitCode}:`,
- chat.stderr.trim() || chat.stdout.trim()
- ? `stderr: ${chat.stderr.trim() || "(empty)"}\nstdout: ${chat.stdout.trim() || "(empty)"}`
- : "(no stdout/stderr)",
- ];
- if (print) {
- parts.push(
- "",
- `Fallback (print) exit ${print.exitCode}:`,
- print.stderr.trim() || print.stdout.trim()
- ? `stderr: ${print.stderr.trim() || "(empty)"}\nstdout: ${print.stdout.trim() || "(empty)"}`
- : "(no stdout/stderr)"
- );
- }
- parts.push("", "Hints:", failureHints(inputs));
- return parts.filter(Boolean).join("\n");
-};
-
-const warnOnFailure = (
- exitCode: number,
- stdout: string,
- stderr: string,
- inputs: ActionInputs,
- extras?: { cliVersion?: string; invocationMode?: AgentInvocationMode }
-): void => {
- const errTail = stderr.trim();
- if (errTail) {
- const maxLen = 12_000;
- const clipped =
- errTail.length > maxLen
- ? `${errTail.slice(0, maxLen)}\n⦠(stderr truncated)`
- : errTail;
- warning(`cursor-agent stderr:\n${clipped}`);
- } else {
- const outTail = stdout.trim();
- if (outTail) {
- const maxLen = 4000;
- const clipped =
- outTail.length > maxLen
- ? `${outTail.slice(0, maxLen)}\n⦠(stdout truncated)`
- : outTail;
- warning(
- `cursor-agent exited with code ${exitCode} and empty stderr; stdout:\n${clipped}`
- );
- } else {
- const mode = extras?.invocationMode
- ? ` (mode: ${extras.invocationMode})`
- : "";
- const ver = extras?.cliVersion
- ? ` cursor-agent --version: ${extras.cliVersion}.`
- : "";
- warning(
- `cursor-agent exited with code ${exitCode} with no stdout or stderr${mode}${ver} ${failureHints(inputs).split("\n")[0]}`
- );
- }
- }
-};
-
-/**
- * Runs cursor-agent with the given inputs.
- * Captures stdout and stderr separately.
- * Does NOT throw on non-zero exit codes ā callers decide how to handle them.
- * @returns The stdout, stderr, and exit code.
- */
export const runAgent = async (inputs: ActionInputs): Promise => {
const cwd = resolve(inputs.workingDirectory);
- const env = buildExecEnv(inputs);
- const baseOptions: ExecOptions = {
- cwd,
- env,
- };
-
- info(`Running cursor-agent in: ${cwd}`);
+ info(`Running Cursor Agent in: ${cwd}`);
info(`Model: ${inputs.model} | Permissions: ${inputs.permissions}`);
- const preflight = await runPreflightProbe(inputs, baseOptions);
- if (preflight.exitCode !== 0) {
- warning(
- "Auth/entitlement preflight (`cursor-agent -p`) failed before main prompt run. " +
- "Continuing with normal invocation for additional diagnostics."
- );
- }
- const chatController = new AbortController();
- const chatTimeout = setTimeout(() => {
- chatController.abort();
- }, inputs.timeout * 1000);
+ let stdout = "";
+ let stderr = "";
+ let exitCode = 0;
- let chatResult: { exitCode: number; stderr: string; stdout: string };
try {
- chatResult = await runAgentOnce(buildChatArgs(inputs), baseOptions);
- } catch (error) {
- if (chatController.signal.aborted) {
- throw new Error(
- `cursor-agent timed out after ${inputs.timeout}s. ` +
- `Increase the 'timeout' input if your prompt requires longer processing.`,
- { cause: error }
- );
- }
- throw error;
- } finally {
- clearTimeout(chatTimeout);
- }
+ const agent = await Agent.create({
+ apiKey: inputs.apiKey,
+ local: { cwd },
+ model: { id: inputs.model },
+ });
- const cliVersion = await fetchCliVersionLine(env, cwd);
- debug(`cursor-agent --version: ${cliVersion}`);
+ const run = await agent.send(inputs.prompt);
- if (chatResult.exitCode === 0) {
- return {
- ...chatResult,
- cliVersion,
- invocationMode: "chat",
- };
- }
-
- if (!shouldTryPrintFallback(chatResult)) {
- warnOnFailure(
- chatResult.exitCode,
- chatResult.stdout,
- chatResult.stderr,
- inputs,
- {
- cliVersion,
- invocationMode: "chat",
+ for await (const event of run.stream()) {
+ if ("text" in event && typeof event.text === "string") {
+ stdout += event.text;
}
- );
- return {
- ...chatResult,
- cliVersion,
- diagnostics: buildDiagnostics(cliVersion, inputs, preflight, chatResult),
- invocationMode: "chat",
- };
- }
-
- info(
- "Primary `cursor-agent chat` failed in a way that suggests a CLI mismatch or silent failure; " +
- "retrying with headless print mode (`-p`, --output-format text)."
- );
-
- const printController = new AbortController();
- const printTimeout = setTimeout(() => {
- printController.abort();
- }, inputs.timeout * 1000);
+ }
- let printResult: { exitCode: number; stderr: string; stdout: string };
- try {
- printResult = await runAgentOnce(buildPrintArgs(inputs), baseOptions);
+ const finalResult = await run.result;
+ if (finalResult && typeof finalResult === "string") {
+ stdout = finalResult;
+ }
} catch (error) {
- if (printController.signal.aborted) {
- throw new Error(
- `cursor-agent timed out after ${inputs.timeout}s. ` +
- `Increase the 'timeout' input if your prompt requires longer processing.`,
- { cause: error }
- );
+ exitCode = 1;
+ if (error instanceof Error) {
+ stderr += error.message;
+ if (error.cause) {
+ stderr += `\nCause: ${error.cause}`;
+ }
+ } else {
+ stderr += String(error);
}
- throw error;
- } finally {
- clearTimeout(printTimeout);
- }
-
- if (printResult.exitCode === 0) {
- return {
- ...printResult,
- cliVersion,
- invocationMode: "print",
- };
+ warning(`Agent execution failed: ${stderr}`);
}
- warnOnFailure(
- printResult.exitCode,
- printResult.stdout,
- printResult.stderr,
- inputs,
- {
- cliVersion,
- invocationMode: "print",
- }
- );
-
- const mergedStderr = [
- "--- cursor-action: primary (chat) ---",
- chatResult.stderr.trim() || "(empty)",
- "--- cursor-action: fallback (print -p) ---",
- printResult.stderr.trim() || "(empty)",
- ].join("\n");
-
return {
- cliVersion,
- diagnostics: buildDiagnostics(
- cliVersion,
- inputs,
- preflight,
- chatResult,
- printResult
- ),
- exitCode: printResult.exitCode,
- invocationMode: "print",
- stderr: mergedStderr,
- stdout: printResult.stdout,
+ diagnostics: exitCode === 0 ? undefined : stderr,
+ exitCode,
+ stderr,
+ stdout,
};
};
diff --git a/src/types.ts b/src/types.ts
index 555e891..aee9cad 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -1,40 +1,23 @@
export type Permission = "read-only" | "read-write" | "full";
export interface ActionInputs {
- cursorVersion: string;
apiKey: string;
prompt: string;
model: string;
workingDirectory: string;
permissions: Permission;
timeout: number;
+ cursorVersion?: string;
}
export interface ActionOutputs {
summary: string;
exitCode: number;
- cacheHit: boolean;
}
-export interface CursorRelease {
- version: string;
- downloadUrl: string;
- checksum?: string;
-}
-
-export type AgentInvocationMode = "chat" | "print";
-
export interface AgentResult {
stdout: string;
stderr: string;
exitCode: number;
- /** Which argv shape produced this result (print is headless `-p` fallback). */
- invocationMode?: AgentInvocationMode;
- /** Output of `cursor-agent --version` when collected for diagnostics. */
- cliVersion?: string;
- /** Extra context for job summary / debugging when runs fail. */
diagnostics?: string;
}
-
-export type Platform = "linux" | "darwin" | "win32";
-export type Arch = "x64" | "arm64";
diff --git a/tsconfig.json b/tsconfig.json
index 58a9699..6999485 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -10,6 +10,7 @@
"incremental": false,
"isolatedModules": true,
"lib": ["es2022", "DOM", "DOM.Iterable"],
+ "types": ["bun"],
"module": "ESNext",
"moduleDetection": "force",
"moduleResolution": "Bundler",
diff --git a/tsdown.config.ts b/tsdown.config.ts
new file mode 100644
index 0000000..ba4403a
--- /dev/null
+++ b/tsdown.config.ts
@@ -0,0 +1,12 @@
+import { defineConfig } from 'tsdown';
+
+export default defineConfig({
+ entry: ['src/index.ts'],
+ format: ['esm'],
+ target: 'node20',
+ clean: true,
+ outExtensions: () => ({ js: ".js" }),
+ deps: {
+ neverBundle: ['@cursor/sdk', '@actions/core']
+ }
+});
From 99851e7cdacc0886161146703e821d6a0dadf38c Mon Sep 17 00:00:00 2001
From: PunGrumpy <108584943+PunGrumpy@users.noreply.github.com>
Date: Mon, 11 May 2026 21:39:15 +0700
Subject: [PATCH 2/7] feat(agent): add permissions and timeout options to agent
configuration
---
__tests__/runner.test.ts | 2 ++
src/runner.ts | 5 ++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/__tests__/runner.test.ts b/__tests__/runner.test.ts
index f9d61e6..402a159 100644
--- a/__tests__/runner.test.ts
+++ b/__tests__/runner.test.ts
@@ -63,6 +63,8 @@ describe("runAgent", () => {
apiKey: "test-key",
local: { cwd: expect.any(String) },
model: { id: "auto" },
+ permissions: "read-only",
+ timeout: 300,
});
expect(mockAgentSend).toHaveBeenCalledWith("Analyze this code");
diff --git a/src/runner.ts b/src/runner.ts
index 58c33ea..d8ae828 100644
--- a/src/runner.ts
+++ b/src/runner.ts
@@ -2,6 +2,7 @@ import { resolve } from "node:path";
import { info, warning } from "@actions/core";
import { Agent } from "@cursor/sdk";
+import type { AgentOptions } from "@cursor/sdk";
import type { ActionInputs, AgentResult } from "./types";
@@ -20,7 +21,9 @@ export const runAgent = async (inputs: ActionInputs): Promise => {
apiKey: inputs.apiKey,
local: { cwd },
model: { id: inputs.model },
- });
+ permissions: inputs.permissions,
+ timeout: inputs.timeout,
+ } as AgentOptions);
const run = await agent.send(inputs.prompt);
From a9396af783090bb278bfb021a1d7551b27deec38 Mon Sep 17 00:00:00 2001
From: PunGrumpy <108584943+PunGrumpy@users.noreply.github.com>
Date: Mon, 11 May 2026 21:46:20 +0700
Subject: [PATCH 3/7] chore(action): update entry point to use .mjs extension
and adjust configuration
---
README.md | 2 +-
action.yml | 6 +-----
package.json | 2 +-
tsdown.config.ts | 15 ++++++++-------
4 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index 24d70d7..d7e5953 100644
--- a/README.md
+++ b/README.md
@@ -161,7 +161,7 @@ env "INPUT_API-KEY=$CURSOR_API_KEY" \
"INPUT_MODEL=auto" \
"INPUT_PERMISSIONS=read-only" \
"INPUT_TIMEOUT=60" \
- node dist/index.js
+ node dist/index.mjs
```
## CI and release notes
diff --git a/action.yml b/action.yml
index a5a14e0..fb9fa43 100644
--- a/action.yml
+++ b/action.yml
@@ -52,13 +52,9 @@ outputs:
runs:
using: "composite"
steps:
- - name: Install Action Dependencies
- run: npm ci --omit=dev --prefix $GITHUB_ACTION_PATH
- shell: bash
-
- name: Run Cursor Agent
id: agent
- run: node $GITHUB_ACTION_PATH/dist/index.js
+ run: node $GITHUB_ACTION_PATH/dist/index.mjs
shell: bash
env:
INPUT_CURSOR_VERSION: ${{ inputs.cursor-version }}
diff --git a/package.json b/package.json
index ae47249..bba7861 100644
--- a/package.json
+++ b/package.json
@@ -19,7 +19,7 @@
"url": "git+https://github.com/PunGrumpy/cursor-action.git"
},
"type": "module",
- "main": "dist/index.js",
+ "main": "dist/index.mjs",
"module": "src/index.ts",
"publishConfig": {
"access": "public",
diff --git a/tsdown.config.ts b/tsdown.config.ts
index ba4403a..28d40ab 100644
--- a/tsdown.config.ts
+++ b/tsdown.config.ts
@@ -1,12 +1,13 @@
-import { defineConfig } from 'tsdown';
+import { defineConfig } from "tsdown";
export default defineConfig({
- entry: ['src/index.ts'],
- format: ['esm'],
- target: 'node20',
clean: true,
- outExtensions: () => ({ js: ".js" }),
deps: {
- neverBundle: ['@cursor/sdk', '@actions/core']
- }
+ alwaysBundle: ["@actions/core", "@cursor/sdk"],
+ onlyBundle: false,
+ },
+ entry: ["src/index.ts"],
+ format: ["esm"],
+ outExtensions: () => ({ js: ".mjs" }),
+ target: "node20",
});
From ee8d91b3655be9ba0a9684ac57f04091bd78f217 Mon Sep 17 00:00:00 2001
From: PunGrumpy <108584943+PunGrumpy@users.noreply.github.com>
Date: Mon, 11 May 2026 21:47:06 +0700
Subject: [PATCH 4/7] fix(input): correct cursorVersion condition to ensure
proper object structure
---
src/input.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/input.ts b/src/input.ts
index 7b44df1..7107e6c 100644
--- a/src/input.ts
+++ b/src/input.ts
@@ -51,7 +51,7 @@ export const getInputs = (): ActionInputs => {
return {
apiKey,
- ...(cursorVersion !== undefined ? { cursorVersion } : {}),
+ ...(cursorVersion === undefined ? {} : { cursorVersion }),
model,
permissions: permissionsRaw as Permission,
prompt,
From 6a2f44b99502258a04d15d9ef8f6f4ab08851f45 Mon Sep 17 00:00:00 2001
From: PunGrumpy <108584943+PunGrumpy@users.noreply.github.com>
Date: Mon, 11 May 2026 22:06:47 +0700
Subject: [PATCH 5/7] feat(runner): implement timeout handling and cancellation
support in runAgent function
---
__tests__/runner.test.ts | 58 ++++++++++++++++++++++++++++++++++++++--
src/runner.ts | 49 ++++++++++++++++++++++++---------
2 files changed, 93 insertions(+), 14 deletions(-)
diff --git a/__tests__/runner.test.ts b/__tests__/runner.test.ts
index 402a159..e28e33f 100644
--- a/__tests__/runner.test.ts
+++ b/__tests__/runner.test.ts
@@ -14,6 +14,7 @@ mock.module("@actions/core", () => ({
const mockAgentCreate = mock();
const mockAgentSend = mock();
+const mockRunCancel = mock(() => Promise.resolve());
mock.module("@cursor/sdk", () => ({
Agent: {
@@ -42,6 +43,24 @@ const mockStreamError = async function* mockStreamError() {
throw new Error("Stream aborted");
};
+/**
+ * Yields only after 1.1s so a 1s action timeout can fire first.
+ * @yields {{ text: string }}
+ */
+const streamAfter1100ms = async function* streamAfter1100msGen() {
+ await Bun.sleep(1100);
+ yield { text: "too late" };
+};
+
+/**
+ * Completes only after 1.2s when cancel is unsupported (timeout still scheduled).
+ * @yields {{ text: string }}
+ */
+const streamAfter1200ms = async function* streamAfter1200msGen() {
+ await Bun.sleep(1200);
+ yield { text: "ok" };
+};
+
describe("runAgent", () => {
beforeEach(() => {
mock.clearAllMocks();
@@ -51,8 +70,10 @@ describe("runAgent", () => {
});
mockAgentSend.mockResolvedValue({
+ cancel: mockRunCancel,
result: Promise.resolve("Hello from stream chunk 1. And chunk 2."),
stream: mockStreamSuccess,
+ supports: (op: string) => op === "cancel",
});
});
@@ -63,11 +84,13 @@ describe("runAgent", () => {
apiKey: "test-key",
local: { cwd: expect.any(String) },
model: { id: "auto" },
- permissions: "read-only",
- timeout: 300,
});
expect(mockAgentSend).toHaveBeenCalledWith("Analyze this code");
+ expect(mockWarning).toHaveBeenCalledWith(
+ expect.stringContaining("permissions")
+ );
+ expect(mockRunCancel).not.toHaveBeenCalled();
expect(result.exitCode).toBe(0);
expect(result.stdout).toBe("Hello from stream chunk 1. And chunk 2.");
expect(result.stderr).toBe("");
@@ -85,12 +108,43 @@ describe("runAgent", () => {
);
});
+ it("calls run.cancel when timeout elapses before the stream yields", async () => {
+ mockRunCancel.mockClear();
+ mockAgentSend.mockResolvedValue({
+ cancel: mockRunCancel,
+ result: Promise.resolve(""),
+ stream: streamAfter1100ms,
+ supports: (op: string) => op === "cancel",
+ });
+
+ await runAgent({ ...baseInputs, timeout: 1 });
+
+ expect(mockRunCancel).toHaveBeenCalled();
+ }, 5000);
+
+ it("does not call run.cancel when cancel is unsupported", async () => {
+ mockRunCancel.mockClear();
+ mockAgentSend.mockResolvedValue({
+ cancel: mockRunCancel,
+ result: Promise.resolve("done"),
+ stream: streamAfter1200ms,
+ supports: () => false,
+ });
+
+ const result = await runAgent({ ...baseInputs, timeout: 1 });
+
+ expect(mockRunCancel).not.toHaveBeenCalled();
+ expect(result.exitCode).toBe(0);
+ }, 5000);
+
it("returns exitCode 1 when stream throws an error", async () => {
mockAgentSend.mockResolvedValue({
+ cancel: mockRunCancel,
get result() {
return Promise.reject(new Error("Stream aborted"));
},
stream: mockStreamError,
+ supports: (op: string) => op === "cancel",
});
const result = await runAgent(baseInputs);
diff --git a/src/runner.ts b/src/runner.ts
index d8ae828..ba85ec8 100644
--- a/src/runner.ts
+++ b/src/runner.ts
@@ -2,7 +2,6 @@ import { resolve } from "node:path";
import { info, warning } from "@actions/core";
import { Agent } from "@cursor/sdk";
-import type { AgentOptions } from "@cursor/sdk";
import type { ActionInputs, AgentResult } from "./types";
@@ -10,7 +9,11 @@ export const runAgent = async (inputs: ActionInputs): Promise => {
const cwd = resolve(inputs.workingDirectory);
info(`Running Cursor Agent in: ${cwd}`);
- info(`Model: ${inputs.model} | Permissions: ${inputs.permissions}`);
+ info(`Model: ${inputs.model}`);
+ warning(
+ "The action `permissions` input is not applied by the Cursor SDK on Agent.create; " +
+ "effective tool access is auth-scoped (API key / account), not this field."
+ );
let stdout = "";
let stderr = "";
@@ -21,21 +24,43 @@ export const runAgent = async (inputs: ActionInputs): Promise => {
apiKey: inputs.apiKey,
local: { cwd },
model: { id: inputs.model },
- permissions: inputs.permissions,
- timeout: inputs.timeout,
- } as AgentOptions);
+ });
const run = await agent.send(inputs.prompt);
- for await (const event of run.stream()) {
- if ("text" in event && typeof event.text === "string") {
- stdout += event.text;
- }
+ const timeoutMs = inputs.timeout * 1000;
+ let cancelTimer: ReturnType | undefined;
+ if (timeoutMs > 0 && Number.isFinite(timeoutMs)) {
+ cancelTimer = setTimeout(() => {
+ // Fire-and-forget: timeout handler must not block the timer callback.
+ // eslint-disable-next-line no-void -- intentional detached async work
+ void (async () => {
+ if (run.supports("cancel")) {
+ try {
+ await run.cancel();
+ } catch {
+ // Best-effort cancel on timeout; errors are surfaced via stream/result.
+ }
+ }
+ })();
+ }, timeoutMs);
}
- const finalResult = await run.result;
- if (finalResult && typeof finalResult === "string") {
- stdout = finalResult;
+ try {
+ for await (const event of run.stream()) {
+ if ("text" in event && typeof event.text === "string") {
+ stdout += event.text;
+ }
+ }
+
+ const finalResult = await run.result;
+ if (finalResult && typeof finalResult === "string") {
+ stdout = finalResult;
+ }
+ } finally {
+ if (cancelTimer !== undefined) {
+ clearTimeout(cancelTimer);
+ }
}
} catch (error) {
exitCode = 1;
From 2c42c23d8db09c7ca6bcde76af14fa8a9008d2a5 Mon Sep 17 00:00:00 2001
From: PunGrumpy <108584943+PunGrumpy@users.noreply.github.com>
Date: Mon, 11 May 2026 22:08:29 +0700
Subject: [PATCH 6/7] feat(runner): integrate wait handling in runAgent for
improved result retrieval
---
__tests__/runner.test.ts | 17 +++++++++++------
src/runner.ts | 3 ++-
2 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/__tests__/runner.test.ts b/__tests__/runner.test.ts
index e28e33f..5644083 100644
--- a/__tests__/runner.test.ts
+++ b/__tests__/runner.test.ts
@@ -61,6 +61,13 @@ const streamAfter1200ms = async function* streamAfter1200msGen() {
yield { text: "ok" };
};
+const finishedWait = (result: string) => () =>
+ Promise.resolve({
+ id: "run-test",
+ result,
+ status: "finished" as const,
+ });
+
describe("runAgent", () => {
beforeEach(() => {
mock.clearAllMocks();
@@ -71,9 +78,9 @@ describe("runAgent", () => {
mockAgentSend.mockResolvedValue({
cancel: mockRunCancel,
- result: Promise.resolve("Hello from stream chunk 1. And chunk 2."),
stream: mockStreamSuccess,
supports: (op: string) => op === "cancel",
+ wait: finishedWait("Hello from stream chunk 1. And chunk 2."),
});
});
@@ -112,9 +119,9 @@ describe("runAgent", () => {
mockRunCancel.mockClear();
mockAgentSend.mockResolvedValue({
cancel: mockRunCancel,
- result: Promise.resolve(""),
stream: streamAfter1100ms,
supports: (op: string) => op === "cancel",
+ wait: finishedWait(""),
});
await runAgent({ ...baseInputs, timeout: 1 });
@@ -126,9 +133,9 @@ describe("runAgent", () => {
mockRunCancel.mockClear();
mockAgentSend.mockResolvedValue({
cancel: mockRunCancel,
- result: Promise.resolve("done"),
stream: streamAfter1200ms,
supports: () => false,
+ wait: finishedWait("done"),
});
const result = await runAgent({ ...baseInputs, timeout: 1 });
@@ -140,11 +147,9 @@ describe("runAgent", () => {
it("returns exitCode 1 when stream throws an error", async () => {
mockAgentSend.mockResolvedValue({
cancel: mockRunCancel,
- get result() {
- return Promise.reject(new Error("Stream aborted"));
- },
stream: mockStreamError,
supports: (op: string) => op === "cancel",
+ wait: finishedWait(""),
});
const result = await runAgent(baseInputs);
diff --git a/src/runner.ts b/src/runner.ts
index ba85ec8..38f016a 100644
--- a/src/runner.ts
+++ b/src/runner.ts
@@ -53,7 +53,8 @@ export const runAgent = async (inputs: ActionInputs): Promise => {
}
}
- const finalResult = await run.result;
+ await run.wait();
+ const finalResult = run.result;
if (finalResult && typeof finalResult === "string") {
stdout = finalResult;
}
From 5b08decd4708038530bfb4141a50ab5cdef63021 Mon Sep 17 00:00:00 2001
From: "coderabbitai[bot]"
<136622811+coderabbitai[bot]@users.noreply.github.com>
Date: Mon, 11 May 2026 15:21:49 +0000
Subject: [PATCH 7/7] fix: apply CodeRabbit auto-fixes
Fixed 1 file(s) based on 1 unresolved review comment.
Co-authored-by: CodeRabbit
---
tsdown.config.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tsdown.config.ts b/tsdown.config.ts
index 28d40ab..ea12e28 100644
--- a/tsdown.config.ts
+++ b/tsdown.config.ts
@@ -3,7 +3,7 @@ import { defineConfig } from "tsdown";
export default defineConfig({
clean: true,
deps: {
- alwaysBundle: ["@actions/core", "@cursor/sdk"],
+ alwaysBundle: ["@actions/core"],
onlyBundle: false,
},
entry: ["src/index.ts"],