Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d71f4db3d7 | |||
| 13cde95d51 | |||
| 52882e1d74 |
@@ -67,6 +67,7 @@ jobs:
|
||||
| `use_vertex` | Use Google Vertex AI with OIDC authentication instead of direct Anthropic API | No | `false` |
|
||||
| `allowed_tools` | Additional tools for Claude to use (the base GitHub tools will always be included) | No | "" |
|
||||
| `disallowed_tools` | Tools that Claude should never use | No | "" |
|
||||
| `claude_args` | Additional arguments forwarded verbatim to the Claude CLI (e.g. `--json-schema /path/to/schema.json`). See [Structured output](#structured-output). Requires a Claude CLI new enough to support the flags used. | No | "" |
|
||||
| `custom_instructions` | Additional custom instructions to include in the prompt for Claude | No | "" |
|
||||
| `assignee_trigger` | The assignee username that triggers the action (e.g. @claude). Only used for issue and PR assignment | No | - |
|
||||
| `trigger_phrase` | The trigger phrase to look for in comments, issue/PR bodies, and issue titles | No | `@claude` |
|
||||
@@ -77,6 +78,53 @@ jobs:
|
||||
|
||||
> **Note**: This action is currently in beta. Features and APIs may change as we continue to improve the integration.
|
||||
|
||||
## Outputs
|
||||
|
||||
| Output | Description |
|
||||
| ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `execution_file` | Path to the JSON file containing the Claude Code execution log |
|
||||
| `structured_output` | JSON string of the schema-validated result, set only when `--json-schema` is passed via `claude_args`. Parse with `fromJSON()` or `jq`. |
|
||||
| `branch_name` | The branch created by Claude Code for this execution (issue flows) |
|
||||
|
||||
## Structured output
|
||||
|
||||
`claude_args` forwards arbitrary flags straight to the Claude CLI. The primary use case is asking the model for a **schema-validated result** instead of having the agent write it to a file. When you pass `--json-schema`, the action surfaces the validated object as the `structured_output` action output (no agent-written file required).
|
||||
|
||||
```yaml
|
||||
- uses: ryan/claude-code-gitea-action@gitea
|
||||
id: review
|
||||
with:
|
||||
gitea_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
direct_prompt: "Review this PR and return a verdict that matches the schema."
|
||||
# Prefer the file-path form — it has no spaces or `$` for the shell
|
||||
# tokenizer to mangle, so a schema containing $ref/$defs round-trips safely.
|
||||
claude_args: --json-schema ${{ github.workspace }}/.gitea/review-schema.json
|
||||
|
||||
- name: Use the verdict
|
||||
shell: bash
|
||||
run: |
|
||||
echo '${{ steps.review.outputs.structured_output }}' | jq -r '.decision'
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
- **Use the file-path form** (`--json-schema /path/to/schema.json`). The action reads the file and passes its contents to the CLI **inline**, so the file-path form works even on CLIs whose `--json-schema` only accepts an inline string (including the default-pinned `2.1.160`). The path is preferred because it has no spaces or `$` for the shell to mangle, so a schema with `$ref`/`$defs` round-trips intact. An inline schema also works if single-quoted (`--json-schema '{"type":"object"}'`) so the shell treats it as one literal token and does not expand `$` (e.g. `$ref`).
|
||||
- If the `--json-schema` value is a path that can't be read, or the file isn't valid JSON, the run **fails loudly** with a clear error (rather than the CLI silently emitting empty output).
|
||||
- If `--json-schema` is supplied but the model returns no structured result, the run **fails loudly** rather than emitting an empty output.
|
||||
- **Claude CLI version.** The default-installed CLI (`2.1.160`) supports `--json-schema`, and the action inlines a file-path schema for you — so the file-path form is not version-sensitive. If you pin `path_to_claude_code_executable` (e.g. a pre-baked runner image), that baked CLI must still be new enough to support the `--json-schema` flag itself — bump it independently. See [Version pins](#version-pins).
|
||||
|
||||
### Version pins
|
||||
|
||||
This fork runs Claude via the vendored `base-action/` (invoked directly, not the external `anthropics/claude-code-base-action`). The moving pieces:
|
||||
|
||||
| Component | Where it's pinned | Current value |
|
||||
| -------------------------------------- | -------------------------------------------------- | ------------- |
|
||||
| Claude CLI (default install) | `action.yml` → "Install Claude" step | `2.1.160` |
|
||||
| Claude CLI (pre-baked runner image) | the runner image's Dockerfile (`CLAUDE_CLI_VERSION`) | set by you |
|
||||
|
||||
If you consume this action through a pre-baked runner image that sets `path_to_claude_code_executable`, the action's own install step is skipped — so enabling `--json-schema` there requires **rebuilding that runner image** with a `--json-schema`-capable CLI and restarting the runner. That is outside this repository.
|
||||
|
||||
## Gitea Configuration
|
||||
|
||||
This action has been enhanced to work with Gitea installations. The main differences from GitHub are:
|
||||
|
||||
+40
-40
@@ -81,6 +81,10 @@ inputs:
|
||||
description: "Enable automatic fallback to specified model when default model is overloaded"
|
||||
required: false
|
||||
default: ""
|
||||
claude_args:
|
||||
description: "Additional arguments to pass directly to the Claude CLI, forwarded verbatim (e.g. '--json-schema /path/to/schema.json' to get schema-validated output via the structured_output output; a file path given to --json-schema is read and inlined automatically, so it works on the default-installed CLI). Requires a Claude CLI new enough to support the flags used (see README)."
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
# Auth configuration
|
||||
anthropic_api_key:
|
||||
@@ -131,6 +135,9 @@ outputs:
|
||||
execution_file:
|
||||
description: "Path to the Claude Code execution output file"
|
||||
value: ${{ steps.claude-code.outputs.execution_file }}
|
||||
structured_output:
|
||||
description: "JSON string of the schema-validated result when --json-schema is provided in claude_args (parse with fromJSON() or jq)"
|
||||
value: ${{ steps.claude-code.outputs.structured_output }}
|
||||
branch_name:
|
||||
description: "The branch created by Claude Code for this execution"
|
||||
value: ${{ steps.prepare.outputs.CLAUDE_BRANCH }}
|
||||
@@ -177,10 +184,13 @@ runs:
|
||||
if: steps.prepare.outputs.contains_trigger == 'true'
|
||||
shell: bash
|
||||
run: |
|
||||
# Install Claude Code if no custom executable is provided
|
||||
# Install Claude Code if no custom executable is provided.
|
||||
# Version must be new enough to support any flags passed via claude_args
|
||||
# (e.g. --json-schema). Runner images that bake their own CLI via
|
||||
# path_to_claude_code_executable must bump their pin independently.
|
||||
if [ -z "${{ inputs.path_to_claude_code_executable }}" ]; then
|
||||
echo "Installing Claude Code..."
|
||||
curl -fsSL https://claude.ai/install.sh | bash -s 1.0.117
|
||||
curl -fsSL https://claude.ai/install.sh | bash -s 2.1.160
|
||||
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
||||
else
|
||||
echo "Using custom Claude Code executable: ${{ inputs.path_to_claude_code_executable }}"
|
||||
@@ -189,51 +199,41 @@ runs:
|
||||
echo "$CLAUDE_DIR" >> "$GITHUB_PATH"
|
||||
fi
|
||||
# TODO pass claude_code_executable as input and use it here
|
||||
|
||||
- name: Run Claude Code
|
||||
id: claude-code
|
||||
if: steps.prepare.outputs.contains_trigger == 'true'
|
||||
uses: anthropics/claude-code-base-action@v0.0.63
|
||||
with:
|
||||
prompt_file: /tmp/claude-prompts/claude-prompt.txt
|
||||
allowed_tools: ${{ env.ALLOWED_TOOLS }}
|
||||
disallowed_tools: ${{ env.DISALLOWED_TOOLS }}
|
||||
max_turns: ${{ inputs.max_turns }}
|
||||
timeout_minutes: ${{ inputs.timeout_minutes }}
|
||||
model: ${{ inputs.model || inputs.anthropic_model }}
|
||||
mcp_config: ${{ steps.prepare.outputs.mcp_config }}
|
||||
use_bedrock: ${{ inputs.use_bedrock }}
|
||||
use_vertex: ${{ inputs.use_vertex }}
|
||||
anthropic_api_key: ${{ inputs.anthropic_api_key }}
|
||||
claude_code_oauth_token: ${{ inputs.claude_code_oauth_token }}
|
||||
settings: ${{ inputs.settings }}
|
||||
system_prompt: ${{ inputs.system_prompt }}
|
||||
append_system_prompt: ${{ inputs.append_system_prompt }}
|
||||
claude_env: ${{ inputs.claude_env }}
|
||||
fallback_model: ${{ inputs.fallback_model }}
|
||||
use_node_cache: ${{ inputs.use_node_cache }}
|
||||
shell: bash
|
||||
run: |
|
||||
bun run ${{ github.action_path }}/base-action/src/index.ts
|
||||
env:
|
||||
# Core configuration
|
||||
PROMPT_FILE: /tmp/claude-prompts/claude-prompt.txt
|
||||
ALLOWED_TOOLS: ${{ env.ALLOWED_TOOLS }}
|
||||
DISALLOWED_TOOLS: ${{ env.DISALLOWED_TOOLS }}
|
||||
TIMEOUT_MINUTES: ${{ inputs.timeout_minutes }}
|
||||
MODEL: ${{ inputs.model || inputs.anthropic_model }}
|
||||
# Core configuration. The vendored base-action reads these INPUT_* env
|
||||
# vars directly (see base-action/src/index.ts), so we map them here
|
||||
# instead of delegating to the external claude-code-base-action. This
|
||||
# lets us forward claude_args and surface structured_output while
|
||||
# keeping the Gitea adaptations this fork relies on.
|
||||
CLAUDE_CODE_ACTION: "1"
|
||||
INPUT_PROMPT_FILE: /tmp/claude-prompts/claude-prompt.txt
|
||||
INPUT_ALLOWED_TOOLS: ${{ env.ALLOWED_TOOLS }}
|
||||
INPUT_DISALLOWED_TOOLS: ${{ env.DISALLOWED_TOOLS }}
|
||||
INPUT_MAX_TURNS: ${{ inputs.max_turns }}
|
||||
INPUT_TIMEOUT_MINUTES: ${{ inputs.timeout_minutes }}
|
||||
INPUT_MCP_CONFIG: ${{ steps.prepare.outputs.mcp_config }}
|
||||
INPUT_SETTINGS: ${{ inputs.settings }}
|
||||
INPUT_SYSTEM_PROMPT: ${{ inputs.system_prompt }}
|
||||
INPUT_APPEND_SYSTEM_PROMPT: ${{ inputs.append_system_prompt }}
|
||||
INPUT_CLAUDE_ENV: ${{ inputs.claude_env }}
|
||||
INPUT_FALLBACK_MODEL: ${{ inputs.fallback_model }}
|
||||
INPUT_CLAUDE_ARGS: ${{ inputs.claude_args }}
|
||||
ANTHROPIC_MODEL: ${{ inputs.model || inputs.anthropic_model }}
|
||||
MCP_CONFIG: ${{ steps.prepare.outputs.mcp_config }}
|
||||
USE_BEDROCK: ${{ inputs.use_bedrock }}
|
||||
USE_VERTEX: ${{ inputs.use_vertex }}
|
||||
|
||||
# Provider selection (base-action validate-env reads the '1'/'' form).
|
||||
CLAUDE_CODE_USE_BEDROCK: ${{ inputs.use_bedrock == 'true' && '1' || '' }}
|
||||
CLAUDE_CODE_USE_VERTEX: ${{ inputs.use_vertex == 'true' && '1' || '' }}
|
||||
|
||||
# Auth configuration
|
||||
ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }}
|
||||
CLAUDE_CODE_OAUTH_TOKEN: ${{ inputs.claude_code_oauth_token }}
|
||||
|
||||
# New settings support
|
||||
SETTINGS: ${{ inputs.settings }}
|
||||
SYSTEM_PROMPT: ${{ inputs.system_prompt }}
|
||||
APPEND_SYSTEM_PROMPT: ${{ inputs.append_system_prompt }}
|
||||
CLAUDE_ENV: ${{ inputs.claude_env }}
|
||||
FALLBACK_MODEL: ${{ inputs.fallback_model }}
|
||||
USE_NODE_CACHE: ${{ inputs.use_node_cache }}
|
||||
|
||||
# GitHub token for repository access
|
||||
GITHUB_TOKEN: ${{ steps.prepare.outputs.GITHUB_TOKEN }}
|
||||
GITEA_API_URL: ${{ env.GITHUB_SERVER_URL }}
|
||||
@@ -242,7 +242,7 @@ runs:
|
||||
CLAUDE_GIT_NAME: ${{ inputs.claude_git_name }}
|
||||
CLAUDE_GIT_EMAIL: ${{ inputs.claude_git_email }}
|
||||
|
||||
# Provider configuration (for future cloud provider support)
|
||||
# Provider configuration (for cloud provider support)
|
||||
ANTHROPIC_BASE_URL: ${{ env.ANTHROPIC_BASE_URL }}
|
||||
AWS_REGION: ${{ env.AWS_REGION }}
|
||||
AWS_ACCESS_KEY_ID: ${{ env.AWS_ACCESS_KEY_ID }}
|
||||
|
||||
@@ -55,6 +55,10 @@ inputs:
|
||||
description: "Custom environment variables to pass to Claude Code execution (YAML multiline format)"
|
||||
required: false
|
||||
default: ""
|
||||
claude_args:
|
||||
description: "Additional arguments to pass directly to the Claude CLI (e.g. '--json-schema /path/to/schema.json'). Forwarded verbatim after the action-managed arguments."
|
||||
required: false
|
||||
default: ""
|
||||
|
||||
# Action settings
|
||||
timeout_minutes:
|
||||
@@ -92,6 +96,9 @@ outputs:
|
||||
execution_file:
|
||||
description: "Path to the JSON file containing Claude Code execution log"
|
||||
value: ${{ steps.run_claude.outputs.execution_file }}
|
||||
structured_output:
|
||||
description: "JSON string of the schema-validated result when --json-schema is provided in claude_args (parse with fromJSON() or jq)"
|
||||
value: ${{ steps.run_claude.outputs.structured_output }}
|
||||
|
||||
runs:
|
||||
using: "composite"
|
||||
@@ -143,6 +150,7 @@ runs:
|
||||
INPUT_TIMEOUT_MINUTES: ${{ inputs.timeout_minutes }}
|
||||
INPUT_CLAUDE_ENV: ${{ inputs.claude_env }}
|
||||
INPUT_FALLBACK_MODEL: ${{ inputs.fallback_model }}
|
||||
INPUT_CLAUDE_ARGS: ${{ inputs.claude_args }}
|
||||
|
||||
# Provider configuration
|
||||
ANTHROPIC_API_KEY: ${{ inputs.anthropic_api_key }}
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "@anthropic-ai/claude-code-base-action",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"shell-quote": "^1.8.1",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.12",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"prettier": "3.5.3",
|
||||
"typescript": "^5.8.3",
|
||||
},
|
||||
@@ -31,12 +34,16 @@
|
||||
|
||||
"@types/react": ["@types/react@19.1.8", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-AwAfQ2Wa5bCx9WP8nZL2uMZWod7J7/JSplxbTmBQ5ms6QpqNYm672H0Vu9ZVKVngQ+ii4R/byguVEUZQyeg44g=="],
|
||||
|
||||
"@types/shell-quote": ["@types/shell-quote@1.7.5", "", {}, "sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw=="],
|
||||
|
||||
"bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="],
|
||||
|
||||
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
|
||||
|
||||
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
|
||||
|
||||
"shell-quote": ["shell-quote@1.8.4", "", {}, "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ=="],
|
||||
|
||||
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
|
||||
|
||||
"typescript": ["typescript@5.8.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ=="],
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
"typecheck": "tsc --noEmit"
|
||||
},
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1"
|
||||
"@actions/core": "^1.10.1",
|
||||
"shell-quote": "^1.8.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "^1.2.12",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"prettier": "3.5.3",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ async function run() {
|
||||
claudeEnv: process.env.INPUT_CLAUDE_ENV,
|
||||
fallbackModel: process.env.INPUT_FALLBACK_MODEL,
|
||||
model: process.env.ANTHROPIC_MODEL,
|
||||
claudeArgs: process.env.INPUT_CLAUDE_ARGS,
|
||||
});
|
||||
} catch (error) {
|
||||
core.setFailed(`Action failed with error: ${error}`);
|
||||
|
||||
@@ -2,8 +2,9 @@ import * as core from "@actions/core";
|
||||
import { exec } from "child_process";
|
||||
import { promisify } from "util";
|
||||
import { unlink, writeFile, stat } from "fs/promises";
|
||||
import { createWriteStream } from "fs";
|
||||
import { createWriteStream, readFileSync } from "fs";
|
||||
import { spawn } from "child_process";
|
||||
import { parse as parseShellArgs } from "shell-quote";
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
|
||||
@@ -22,14 +23,159 @@ export type ClaudeOptions = {
|
||||
fallbackModel?: string;
|
||||
timeoutMinutes?: string;
|
||||
model?: string;
|
||||
// Raw, additional arguments forwarded verbatim to the Claude CLI. Mirrors the
|
||||
// upstream v1 `claude_args` passthrough so downstream workflows can use newer
|
||||
// CLI flags (e.g. `--json-schema`) without this fork enumerating each one.
|
||||
claudeArgs?: string;
|
||||
};
|
||||
|
||||
type PreparedConfig = {
|
||||
claudeArgs: string[];
|
||||
promptPath: string;
|
||||
env: Record<string, string>;
|
||||
// True when the forwarded claude_args request schema-validated output
|
||||
// (`--json-schema`), which means we must surface `structured_output`.
|
||||
hasJsonSchema: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Strip full comment lines (first non-whitespace char is `#`) from a shell
|
||||
* argument string before tokenizing. Inline `#` inside a quoted value is left
|
||||
* untouched — shell-quote handles quoting. Ported from upstream
|
||||
* claude-code-base-action's claude_args parsing.
|
||||
*/
|
||||
function stripShellComments(input: string): string {
|
||||
return input
|
||||
.split("\n")
|
||||
.filter((line) => !line.trim().startsWith("#"))
|
||||
.join("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Tokenize the raw `claude_args` string into individual CLI argument tokens
|
||||
* using shell-quote, so quoted values (e.g. `--json-schema '{"$ref": ...}'`)
|
||||
* survive as a single token. Non-string tokens (shell operators/globs) are
|
||||
* dropped, matching upstream behavior. Returns [] for empty/whitespace input.
|
||||
*/
|
||||
export function parseClaudeArgs(claudeArgs?: string): string[] {
|
||||
if (!claudeArgs?.trim()) {
|
||||
return [];
|
||||
}
|
||||
return parseShellArgs(stripShellComments(claudeArgs)).filter(
|
||||
(arg): arg is string => typeof arg === "string",
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolve a single `--json-schema` value. The Claude CLI's `--json-schema`
|
||||
* flag accepts an *inline* JSON string. The documented (and recommended) form
|
||||
* passes a file *path* so a schema containing `$ref`/`$defs` survives shell
|
||||
* tokenization without `$` expansion — but CLIs that only accept inline schemas
|
||||
* (including the default-pinned 2.1.160) silently ignore a path and emit no
|
||||
* structured output. To make the file-path form work everywhere, we read the
|
||||
* file in-process and return its contents as compact inline JSON; because this
|
||||
* value is handed to the CLI as an argv element (never through a shell), the
|
||||
* `$` characters are safe. Values that are already inline JSON (the trimmed
|
||||
* value starts with `{` or `[`) are passed through untouched.
|
||||
*/
|
||||
function resolveJsonSchemaValue(value: string): string {
|
||||
const trimmed = value.trim();
|
||||
if (trimmed.startsWith("{") || trimmed.startsWith("[")) {
|
||||
return value; // Already an inline JSON schema — leave exactly as supplied.
|
||||
}
|
||||
|
||||
let contents: string;
|
||||
try {
|
||||
contents = readFileSync(value, "utf8");
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`Failed to read --json-schema file "${value}": ${
|
||||
e instanceof Error ? e.message : String(e)
|
||||
}`,
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
return JSON.stringify(JSON.parse(contents));
|
||||
} catch (e) {
|
||||
throw new Error(
|
||||
`--json-schema file "${value}" is not valid JSON: ${
|
||||
e instanceof Error ? e.message : String(e)
|
||||
}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Walk tokenized CLI args and inline any file-path value supplied to
|
||||
* `--json-schema` (both the `--json-schema <path>` and `--json-schema=<path>`
|
||||
* forms). See {@link resolveJsonSchemaValue} for why. Non-schema args and
|
||||
* already-inline schemas are returned unchanged.
|
||||
*/
|
||||
export function inlineJsonSchemaArgs(args: string[]): string[] {
|
||||
const result: string[] = [];
|
||||
const PREFIX = "--json-schema=";
|
||||
|
||||
for (let i = 0; i < args.length; i++) {
|
||||
const arg = args[i];
|
||||
if (arg === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg === "--json-schema") {
|
||||
result.push(arg);
|
||||
const value = args[i + 1];
|
||||
if (value !== undefined) {
|
||||
result.push(resolveJsonSchemaValue(value));
|
||||
i++; // Consume the value token we just inlined.
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg.startsWith(PREFIX)) {
|
||||
const value = arg.slice(PREFIX.length);
|
||||
result.push(`${PREFIX}${resolveJsonSchemaValue(value)}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
result.push(arg);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate the schema-validated result emitted by the Claude CLI. With
|
||||
* `--output-format stream-json` the CLI prints one JSON object per line and the
|
||||
* final `{"type":"result", ...}` event carries a `structured_output` field when
|
||||
* `--json-schema` was supplied. We scan from the end (the result is last) and
|
||||
* return the first `structured_output` we find. Returns undefined when absent.
|
||||
*/
|
||||
export function extractStructuredOutput(output: string): unknown {
|
||||
const lines = output.split("\n");
|
||||
for (let i = lines.length - 1; i >= 0; i--) {
|
||||
const line = lines[i]?.trim();
|
||||
if (!line) {
|
||||
continue;
|
||||
}
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(line);
|
||||
} catch {
|
||||
continue; // Not a JSON line (e.g. human-readable log output)
|
||||
}
|
||||
if (
|
||||
parsed &&
|
||||
typeof parsed === "object" &&
|
||||
"structured_output" in parsed &&
|
||||
(parsed as { structured_output?: unknown }).structured_output != null
|
||||
) {
|
||||
return (parsed as { structured_output: unknown }).structured_output;
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function parseCustomEnvVars(claudeEnv?: string): Record<string, string> {
|
||||
if (!claudeEnv || claudeEnv.trim() === "") {
|
||||
return {};
|
||||
@@ -107,6 +253,18 @@ export function prepareRunConfig(
|
||||
}
|
||||
}
|
||||
|
||||
// Forward any additional raw CLI arguments verbatim, after the args this
|
||||
// action manages. Empty/unset claude_args leaves the arg list byte-identical
|
||||
// to before this feature, preserving behavior for existing callers. A
|
||||
// file-path value passed to `--json-schema` is inlined here so it works on
|
||||
// CLIs that only accept inline schemas (e.g. the default-pinned 2.1.160).
|
||||
const extraArgs = inlineJsonSchemaArgs(parseClaudeArgs(options.claudeArgs));
|
||||
claudeArgs.push(...extraArgs);
|
||||
|
||||
const hasJsonSchema = extraArgs.some(
|
||||
(arg) => arg === "--json-schema" || arg.startsWith("--json-schema="),
|
||||
);
|
||||
|
||||
// Parse custom environment variables
|
||||
const customEnv = parseCustomEnvVars(options.claudeEnv);
|
||||
|
||||
@@ -114,6 +272,7 @@ export function prepareRunConfig(
|
||||
claudeArgs,
|
||||
promptPath,
|
||||
env: customEnv,
|
||||
hasJsonSchema,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -309,8 +468,30 @@ export async function runClaude(promptPath: string, options: ClaudeOptions) {
|
||||
core.warning(`Failed to process output for execution metrics: ${e}`);
|
||||
}
|
||||
|
||||
core.setOutput("conclusion", "success");
|
||||
core.setOutput("execution_file", EXECUTION_FILE);
|
||||
|
||||
// When claude_args requested schema-validated output, surface it as the
|
||||
// `structured_output` action output. Fail loudly (rather than emit empty)
|
||||
// if the schema was requested but no structured result came back, matching
|
||||
// upstream claude-code-base-action behavior.
|
||||
if (config.hasJsonSchema) {
|
||||
const structuredOutput = extractStructuredOutput(output);
|
||||
if (structuredOutput == null) {
|
||||
core.setOutput("conclusion", "failure");
|
||||
core.setFailed(
|
||||
"--json-schema was provided in claude_args but Claude did not return structured_output.",
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
core.setOutput("structured_output", JSON.stringify(structuredOutput));
|
||||
const fieldCount =
|
||||
typeof structuredOutput === "object"
|
||||
? Object.keys(structuredOutput as object).length
|
||||
: 0;
|
||||
core.info(`Set structured_output with ${fieldCount} field(s)`);
|
||||
}
|
||||
|
||||
core.setOutput("conclusion", "success");
|
||||
} else {
|
||||
core.setOutput("conclusion", "failure");
|
||||
|
||||
|
||||
@@ -1,7 +1,16 @@
|
||||
#!/usr/bin/env bun
|
||||
|
||||
import { describe, test, expect } from "bun:test";
|
||||
import { prepareRunConfig, type ClaudeOptions } from "../src/run-claude";
|
||||
import { describe, test, expect, beforeAll, afterAll } from "bun:test";
|
||||
import { mkdtempSync, writeFileSync, rmSync } from "fs";
|
||||
import { tmpdir } from "os";
|
||||
import { join } from "path";
|
||||
import {
|
||||
prepareRunConfig,
|
||||
parseClaudeArgs,
|
||||
inlineJsonSchemaArgs,
|
||||
extractStructuredOutput,
|
||||
type ClaudeOptions,
|
||||
} from "../src/run-claude";
|
||||
|
||||
describe("prepareRunConfig", () => {
|
||||
test("should prepare config with basic arguments", () => {
|
||||
@@ -294,4 +303,237 @@ describe("prepareRunConfig", () => {
|
||||
expect(prepared.env).toEqual({});
|
||||
});
|
||||
});
|
||||
|
||||
describe("claude_args passthrough", () => {
|
||||
test("empty/undefined claude_args leaves the arg list byte-identical", () => {
|
||||
const baseline = prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
allowedTools: "Bash,Read",
|
||||
maxTurns: "3",
|
||||
});
|
||||
const withEmpty = prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
allowedTools: "Bash,Read",
|
||||
maxTurns: "3",
|
||||
claudeArgs: "",
|
||||
});
|
||||
const withWhitespace = prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
allowedTools: "Bash,Read",
|
||||
maxTurns: "3",
|
||||
claudeArgs: " \n ",
|
||||
});
|
||||
|
||||
const expected = [
|
||||
"-p",
|
||||
"--verbose",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--allowedTools",
|
||||
"Bash,Read",
|
||||
"--max-turns",
|
||||
"3",
|
||||
];
|
||||
expect(baseline.claudeArgs).toEqual(expected);
|
||||
expect(withEmpty.claudeArgs).toEqual(expected);
|
||||
expect(withWhitespace.claudeArgs).toEqual(expected);
|
||||
expect(baseline.hasJsonSchema).toBe(false);
|
||||
});
|
||||
|
||||
test("claude_args tokens are appended after the managed arguments", () => {
|
||||
const prepared = prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
maxTurns: "3",
|
||||
claudeArgs: `--output-format json --json-schema '{"type":"object"}'`,
|
||||
});
|
||||
|
||||
expect(prepared.claudeArgs).toEqual([
|
||||
"-p",
|
||||
"--verbose",
|
||||
"--output-format",
|
||||
"stream-json",
|
||||
"--max-turns",
|
||||
"3",
|
||||
"--output-format",
|
||||
"json",
|
||||
"--json-schema",
|
||||
'{"type":"object"}',
|
||||
]);
|
||||
expect(prepared.hasJsonSchema).toBe(true);
|
||||
});
|
||||
|
||||
test("a single-quoted inline JSON schema survives as one token (incl. $ref)", () => {
|
||||
const schema = '{"$ref":"#/$defs/Verdict","type":"object"}';
|
||||
const tokens = parseClaudeArgs(`--json-schema '${schema}'`);
|
||||
expect(tokens).toEqual(["--json-schema", schema]);
|
||||
});
|
||||
|
||||
test("comment lines are stripped before tokenizing", () => {
|
||||
const tokens = parseClaudeArgs(
|
||||
"# leading comment\n--max-turns 5\n # indented comment\n--verbose",
|
||||
);
|
||||
expect(tokens).toEqual(["--max-turns", "5", "--verbose"]);
|
||||
});
|
||||
|
||||
test("hasJsonSchema is detected for both space and equals forms", () => {
|
||||
expect(
|
||||
prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
claudeArgs: `--json-schema '{"type":"object"}'`,
|
||||
}).hasJsonSchema,
|
||||
).toBe(true);
|
||||
expect(
|
||||
prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
claudeArgs: `--json-schema='{"type":"object"}'`,
|
||||
}).hasJsonSchema,
|
||||
).toBe(true);
|
||||
expect(
|
||||
prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
claudeArgs: "--max-turns 3",
|
||||
}).hasJsonSchema,
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("inlineJsonSchemaArgs (issue #3 — file-path schemas)", () => {
|
||||
let dir: string;
|
||||
|
||||
beforeAll(() => {
|
||||
dir = mkdtempSync(join(tmpdir(), "json-schema-test-"));
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
rmSync(dir, { recursive: true, force: true });
|
||||
});
|
||||
|
||||
test("passes through args that don't touch --json-schema", () => {
|
||||
const args = ["-p", "--max-turns", "3", "--verbose"];
|
||||
expect(inlineJsonSchemaArgs(args)).toEqual(args);
|
||||
});
|
||||
|
||||
test("leaves an already-inline JSON schema untouched (space form)", () => {
|
||||
const inline = '{"type":"object","properties":{"x":{"type":"string"}}}';
|
||||
expect(inlineJsonSchemaArgs(["--json-schema", inline])).toEqual([
|
||||
"--json-schema",
|
||||
inline,
|
||||
]);
|
||||
});
|
||||
|
||||
test("leaves an already-inline JSON schema untouched (equals form)", () => {
|
||||
const inline = '{"type":"object"}';
|
||||
expect(inlineJsonSchemaArgs([`--json-schema=${inline}`])).toEqual([
|
||||
`--json-schema=${inline}`,
|
||||
]);
|
||||
});
|
||||
|
||||
test("inlines a file-path schema (space form)", () => {
|
||||
const schema = { type: "object", required: ["decision"] };
|
||||
const file = join(dir, "space.json");
|
||||
writeFileSync(file, JSON.stringify(schema, null, 2));
|
||||
|
||||
expect(inlineJsonSchemaArgs(["--json-schema", file])).toEqual([
|
||||
"--json-schema",
|
||||
JSON.stringify(schema),
|
||||
]);
|
||||
});
|
||||
|
||||
test("inlines a file-path schema (equals form)", () => {
|
||||
const schema = { type: "object" };
|
||||
const file = join(dir, "equals.json");
|
||||
writeFileSync(file, JSON.stringify(schema));
|
||||
|
||||
expect(inlineJsonSchemaArgs([`--json-schema=${file}`])).toEqual([
|
||||
`--json-schema=${JSON.stringify(schema)}`,
|
||||
]);
|
||||
});
|
||||
|
||||
// The reason the file-path form exists: a schema with $ref/$defs must
|
||||
// round-trip without the shell expanding `$`. Inlining in-process and
|
||||
// handing the result to spawn() as an argv element keeps it intact.
|
||||
test("inlines a file-path schema containing $ref/$defs intact", () => {
|
||||
const schema = {
|
||||
$ref: "#/$defs/Verdict",
|
||||
$defs: {
|
||||
Verdict: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["decision"],
|
||||
properties: {
|
||||
decision: { type: "string", enum: ["approve", "reject"] },
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
const file = join(dir, "ref-schema.json");
|
||||
writeFileSync(file, JSON.stringify(schema, null, 2));
|
||||
|
||||
const [flag, value] = inlineJsonSchemaArgs(["--json-schema", file]);
|
||||
expect(flag).toBe("--json-schema");
|
||||
expect(value).toContain("$ref");
|
||||
expect(value).toContain("$defs");
|
||||
expect(JSON.parse(value as string)).toEqual(schema);
|
||||
});
|
||||
|
||||
test("throws a clear error when the schema file is missing", () => {
|
||||
const missing = join(dir, "does-not-exist.json");
|
||||
expect(() => inlineJsonSchemaArgs(["--json-schema", missing])).toThrow(
|
||||
/Failed to read --json-schema file/,
|
||||
);
|
||||
});
|
||||
|
||||
test("throws a clear error when the schema file is not valid JSON", () => {
|
||||
const file = join(dir, "invalid.json");
|
||||
writeFileSync(file, "{ this is not json ");
|
||||
expect(() => inlineJsonSchemaArgs(["--json-schema", file])).toThrow(
|
||||
/is not valid JSON/,
|
||||
);
|
||||
});
|
||||
|
||||
test("prepareRunConfig inlines a file-path schema end-to-end", () => {
|
||||
const schema = { $ref: "#/$defs/V", $defs: { V: { type: "object" } } };
|
||||
const file = join(dir, "prepare.json");
|
||||
writeFileSync(file, JSON.stringify(schema, null, 2));
|
||||
|
||||
const prepared = prepareRunConfig("/tmp/test-prompt.txt", {
|
||||
claudeArgs: `--json-schema ${file}`,
|
||||
});
|
||||
|
||||
expect(prepared.hasJsonSchema).toBe(true);
|
||||
const idx = prepared.claudeArgs.indexOf("--json-schema");
|
||||
expect(idx).toBeGreaterThanOrEqual(0);
|
||||
expect(prepared.claudeArgs[idx + 1]).toBe(JSON.stringify(schema));
|
||||
});
|
||||
});
|
||||
|
||||
describe("extractStructuredOutput", () => {
|
||||
test("returns structured_output from the stream-json result event", () => {
|
||||
const verdict = { decision: "approve", score: 9 };
|
||||
const output = [
|
||||
JSON.stringify({ type: "system", subtype: "init" }),
|
||||
JSON.stringify({ type: "assistant", message: { content: [] } }),
|
||||
JSON.stringify({
|
||||
type: "result",
|
||||
subtype: "success",
|
||||
is_error: false,
|
||||
structured_output: verdict,
|
||||
}),
|
||||
].join("\n");
|
||||
|
||||
expect(extractStructuredOutput(output)).toEqual(verdict);
|
||||
});
|
||||
|
||||
test("returns undefined when no structured_output is present", () => {
|
||||
const output = [
|
||||
JSON.stringify({ type: "system", subtype: "init" }),
|
||||
JSON.stringify({ type: "result", subtype: "success", is_error: false }),
|
||||
].join("\n");
|
||||
|
||||
expect(extractStructuredOutput(output)).toBeUndefined();
|
||||
});
|
||||
|
||||
test("ignores non-JSON lines and trailing whitespace", () => {
|
||||
const verdict = { ok: true };
|
||||
const output = `Running Claude...\n${JSON.stringify({
|
||||
type: "result",
|
||||
structured_output: verdict,
|
||||
})}\n\n`;
|
||||
|
||||
expect(extractStructuredOutput(output)).toEqual(verdict);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,22 +1,25 @@
|
||||
{
|
||||
"lockfileVersion": 1,
|
||||
"configVersion": 0,
|
||||
"workspaces": {
|
||||
"": {
|
||||
"name": "@anthropic-ai/claude-code-action",
|
||||
"dependencies": {
|
||||
"@actions/core": "^1.10.1",
|
||||
"@actions/github": "^6.0.1",
|
||||
"@anthropic-ai/sdk": "^0.30.0",
|
||||
"@modelcontextprotocol/sdk": "^1.11.0",
|
||||
"@octokit/graphql": "^8.2.2",
|
||||
"@octokit/rest": "^21.1.1",
|
||||
"@octokit/rest": "^22.0.0",
|
||||
"@octokit/webhooks-types": "^7.6.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"shell-quote": "^1.8.1",
|
||||
"zod": "^3.24.4",
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "1.2.11",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"prettier": "3.5.3",
|
||||
"typescript": "^5.8.3",
|
||||
},
|
||||
@@ -33,6 +36,8 @@
|
||||
|
||||
"@actions/io": ["@actions/io@1.1.3", "", {}, "sha512-wi9JjgKLYS7U/z8PPbco+PvTb/nRWjeoFlJ1Qer83k/3C5PHQi28hiVdeE2kHXmIL99mQFawx8qt/JPjZilJ8Q=="],
|
||||
|
||||
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.30.1", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }, "sha512-nuKvp7wOIz6BFei8WrTdhmSsx5mwnArYyJgh4+vYu3V4J0Ltb8Xm3odPm51n1aSI0XxNCrDl7O88cxCtUdAkaw=="],
|
||||
|
||||
"@fastify/busboy": ["@fastify/busboy@2.1.1", "", {}, "sha512-vBZP4NlzfOlerQTnba4aqZoMhE/a9HY7HRqoOPaETQcSQuWEIyZMHGfVu6w9wGtGK5fED5qRs2DteVCjOH60sA=="],
|
||||
|
||||
"@modelcontextprotocol/sdk": ["@modelcontextprotocol/sdk@1.16.0", "", { "dependencies": { "ajv": "^6.12.6", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", "eventsource": "^3.0.2", "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", "zod": "^3.23.8", "zod-to-json-schema": "^3.24.1" } }, "sha512-8ofX7gkZcLj9H9rSd50mCgm3SSF8C7XoclxJuLoV0Cz3rEQ1tv9MZRYYvJtm9n1BiEQQMzSmE/w2AEkNacLYfg=="],
|
||||
@@ -43,13 +48,13 @@
|
||||
|
||||
"@octokit/endpoint": ["@octokit/endpoint@9.0.6", "", { "dependencies": { "@octokit/types": "^13.1.0", "universal-user-agent": "^6.0.0" } }, "sha512-H1fNTMA57HbkFESSt3Y9+FBICv+0jFceJFPWDePYlR/iMGrwM5ph+Dd4XRQs+8X+PUFURLQgX9ChPfhJ/1uNQw=="],
|
||||
|
||||
"@octokit/graphql": ["@octokit/graphql@8.2.2", "", { "dependencies": { "@octokit/request": "^9.2.3", "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-Yi8hcoqsrXGdt0yObxbebHXFOiUA+2v3n53epuOg1QUgOB6c4XzvisBNVXJSl8RYA5KrDuSL2yq9Qmqe5N0ryA=="],
|
||||
"@octokit/graphql": ["@octokit/graphql@7.1.1", "", { "dependencies": { "@octokit/request": "^8.4.1", "@octokit/types": "^13.0.0", "universal-user-agent": "^6.0.0" } }, "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g=="],
|
||||
|
||||
"@octokit/openapi-types": ["@octokit/openapi-types@25.1.0", "", {}, "sha512-idsIggNXUKkk0+BExUn1dQ92sfysJrje03Q0bv0e+KPLrvyqZF8MnBpFz8UNfYDwB3Ie7Z0TByjWfzxt7vseaA=="],
|
||||
"@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
|
||||
|
||||
"@octokit/plugin-paginate-rest": ["@octokit/plugin-paginate-rest@9.2.2", "", { "dependencies": { "@octokit/types": "^12.6.0" }, "peerDependencies": { "@octokit/core": "5" } }, "sha512-u3KYkGF7GcZnSD/3UP0S7K5XUFT2FkOQdcfXZGZQPGv3lm4F2Xbf71lvjldr8c1H3nNbF+33cLEkWYbokGWqiQ=="],
|
||||
|
||||
"@octokit/plugin-request-log": ["@octokit/plugin-request-log@5.3.1", "", { "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-n/lNeCtq+9ofhC15xzmJCNKP2BWTv8Ih2TTy+jatNCCq/gQP/V7rK3fjIfuz0pDWDALO/o/4QY4hyOF6TQQFUw=="],
|
||||
"@octokit/plugin-request-log": ["@octokit/plugin-request-log@6.0.0", "", { "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-UkOzeEN3W91/eBq9sPZNQ7sUBvYCqYbrrD8gTbBuGtHEuycE4/awMXcYvx6sVYo7LypPhmQwwpUe4Yyu4QZN5Q=="],
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods": ["@octokit/plugin-rest-endpoint-methods@10.4.1", "", { "dependencies": { "@octokit/types": "^12.6.0" }, "peerDependencies": { "@octokit/core": "5" } }, "sha512-xV1b+ceKV9KytQe3zCVqjg+8GTGfDYwaT1ATU5isiUyVtlVAO3HNdzpS4sr4GBx4hxQ46s7ITtZrAsxG22+rVg=="],
|
||||
|
||||
@@ -57,9 +62,9 @@
|
||||
|
||||
"@octokit/request-error": ["@octokit/request-error@5.1.1", "", { "dependencies": { "@octokit/types": "^13.1.0", "deprecation": "^2.0.0", "once": "^1.4.0" } }, "sha512-v9iyEQJH6ZntoENr9/yXxjuezh4My67CBSu9r6Ve/05Iu5gNgnisNWOsoJHTP6k0Rr0+HQIpnH+kyammu90q/g=="],
|
||||
|
||||
"@octokit/rest": ["@octokit/rest@21.1.1", "", { "dependencies": { "@octokit/core": "^6.1.4", "@octokit/plugin-paginate-rest": "^11.4.2", "@octokit/plugin-request-log": "^5.3.1", "@octokit/plugin-rest-endpoint-methods": "^13.3.0" } }, "sha512-sTQV7va0IUVZcntzy1q3QqPm/r8rWtDCqpRAmb8eXXnKkjoQEtFe3Nt5GTVsHft+R6jJoHeSiVLcgcvhtue/rg=="],
|
||||
"@octokit/rest": ["@octokit/rest@22.0.1", "", { "dependencies": { "@octokit/core": "^7.0.6", "@octokit/plugin-paginate-rest": "^14.0.0", "@octokit/plugin-request-log": "^6.0.0", "@octokit/plugin-rest-endpoint-methods": "^17.0.0" } }, "sha512-Jzbhzl3CEexhnivb1iQ0KJ7s5vvjMWcmRtq5aUsKmKDrRW6z3r84ngmiFKFvpZjpiU/9/S6ITPFRpn5s/3uQJw=="],
|
||||
|
||||
"@octokit/types": ["@octokit/types@14.1.0", "", { "dependencies": { "@octokit/openapi-types": "^25.1.0" } }, "sha512-1y6DgTy8Jomcpu33N+p5w58l6xyt55Ar2I91RPiIA0xCJBXyUAhXCcmZaDWSANiha7R9a6qJJ2CRomGPZ6f46g=="],
|
||||
"@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
|
||||
"@octokit/webhooks-types": ["@octokit/webhooks-types@7.6.1", "", {}, "sha512-S8u2cJzklBC0FgTwWVLaM8tMrDuDMVE4xiTK4EYXM9GntyvrdbSoxqDQa+Fh57CCNApyIpyeqPhhFEmHPfrXgw=="],
|
||||
|
||||
@@ -69,8 +74,14 @@
|
||||
|
||||
"@types/node-fetch": ["@types/node-fetch@2.6.12", "", { "dependencies": { "@types/node": "*", "form-data": "^4.0.0" } }, "sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA=="],
|
||||
|
||||
"@types/shell-quote": ["@types/shell-quote@1.7.5", "", {}, "sha512-+UE8GAGRPbJVQDdxi16dgadcBfQ+KG2vgZhV1+3A1XmHbmwcdwhCUwIdy+d3pAGrbvgRoVSjeI9vOWyq376Yzw=="],
|
||||
|
||||
"abort-controller": ["abort-controller@3.0.0", "", { "dependencies": { "event-target-shim": "^5.0.0" } }, "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg=="],
|
||||
|
||||
"accepts": ["accepts@2.0.0", "", { "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" } }, "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng=="],
|
||||
|
||||
"agentkeepalive": ["agentkeepalive@4.6.0", "", { "dependencies": { "humanize-ms": "^1.2.1" } }, "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ=="],
|
||||
|
||||
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
|
||||
|
||||
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||
@@ -129,6 +140,8 @@
|
||||
|
||||
"etag": ["etag@1.8.1", "", {}, "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg=="],
|
||||
|
||||
"event-target-shim": ["event-target-shim@5.0.1", "", {}, "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ=="],
|
||||
|
||||
"eventsource": ["eventsource@3.0.7", "", { "dependencies": { "eventsource-parser": "^3.0.1" } }, "sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA=="],
|
||||
|
||||
"eventsource-parser": ["eventsource-parser@3.0.3", "", {}, "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA=="],
|
||||
@@ -137,8 +150,6 @@
|
||||
|
||||
"express-rate-limit": ["express-rate-limit@7.5.1", "", { "peerDependencies": { "express": ">= 4.11" } }, "sha512-7iN8iPMDzOMHPUYllBEsQdWVB6fPDMPqwjBaFrgr4Jgr/+okjvzAy+UHlYYL/Vs0OsOrMkwS6PJDkFlJwoxUnw=="],
|
||||
|
||||
"fast-content-type-parse": ["fast-content-type-parse@2.0.1", "", {}, "sha512-nGqtvLrj5w0naR6tDPfB4cUmYCqouzyQiz6C5y/LtcDllJdrcc6WaWW6iXyIIOErTa/XRybj28aasdn4LkVk6Q=="],
|
||||
|
||||
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
|
||||
|
||||
"fast-json-stable-stringify": ["fast-json-stable-stringify@2.1.0", "", {}, "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="],
|
||||
@@ -149,6 +160,10 @@
|
||||
|
||||
"form-data": ["form-data@4.0.4", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "hasown": "^2.0.2", "mime-types": "^2.1.12" } }, "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow=="],
|
||||
|
||||
"form-data-encoder": ["form-data-encoder@1.7.2", "", {}, "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A=="],
|
||||
|
||||
"formdata-node": ["formdata-node@4.4.1", "", { "dependencies": { "node-domexception": "1.0.0", "web-streams-polyfill": "4.0.0-beta.3" } }, "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ=="],
|
||||
|
||||
"formdata-polyfill": ["formdata-polyfill@4.0.10", "", { "dependencies": { "fetch-blob": "^3.1.2" } }, "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g=="],
|
||||
|
||||
"forwarded": ["forwarded@0.2.0", "", {}, "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow=="],
|
||||
@@ -171,6 +186,8 @@
|
||||
|
||||
"http-errors": ["http-errors@2.0.0", "", { "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", "setprototypeof": "1.2.0", "statuses": "2.0.1", "toidentifier": "1.0.1" } }, "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ=="],
|
||||
|
||||
"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.6.3", "", { "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" } }, "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw=="],
|
||||
|
||||
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
||||
@@ -183,6 +200,8 @@
|
||||
|
||||
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
|
||||
|
||||
"json-with-bigint": ["json-with-bigint@3.5.8", "", {}, "sha512-eq/4KP6K34kwa7TcFdtvnftvHCD9KvHOGGICWwMFc4dOOKF5t4iYqnfLK8otCRCRv06FXOzGGyqE8h8ElMvvdw=="],
|
||||
|
||||
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||
|
||||
"media-typer": ["media-typer@1.1.0", "", {}, "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw=="],
|
||||
@@ -245,6 +264,8 @@
|
||||
|
||||
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
||||
|
||||
"shell-quote": ["shell-quote@1.8.4", "", {}, "sha512-VsC6n6vz1ihYYyZZwX7YZSF5l5x36ca17OC+a69h94YqB7X6XLwf+5MOgynYir2SLFUbl8gIYvBo8K8RoNQ6bQ=="],
|
||||
|
||||
"side-channel": ["side-channel@1.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3", "side-channel-list": "^1.0.0", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" } }, "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw=="],
|
||||
|
||||
"side-channel-list": ["side-channel-list@1.0.0", "", { "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.3" } }, "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA=="],
|
||||
@@ -257,6 +278,8 @@
|
||||
|
||||
"toidentifier": ["toidentifier@1.0.1", "", {}, "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA=="],
|
||||
|
||||
"tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
|
||||
|
||||
"tunnel": ["tunnel@0.0.6", "", {}, "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg=="],
|
||||
|
||||
"type-is": ["type-is@2.0.1", "", { "dependencies": { "content-type": "^1.0.5", "media-typer": "^1.1.0", "mime-types": "^3.0.0" } }, "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw=="],
|
||||
@@ -267,7 +290,7 @@
|
||||
|
||||
"undici-types": ["undici-types@6.21.0", "", {}, "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ=="],
|
||||
|
||||
"universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="],
|
||||
"universal-user-agent": ["universal-user-agent@6.0.1", "", {}, "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ=="],
|
||||
|
||||
"unpipe": ["unpipe@1.0.0", "", {}, "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ=="],
|
||||
|
||||
@@ -275,7 +298,11 @@
|
||||
|
||||
"vary": ["vary@1.1.2", "", {}, "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg=="],
|
||||
|
||||
"web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
|
||||
"web-streams-polyfill": ["web-streams-polyfill@4.0.0-beta.3", "", {}, "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug=="],
|
||||
|
||||
"webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
|
||||
|
||||
"whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
|
||||
|
||||
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
||||
|
||||
@@ -285,79 +312,69 @@
|
||||
|
||||
"zod-to-json-schema": ["zod-to-json-schema@3.24.6", "", { "peerDependencies": { "zod": "^3.24.1" } }, "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg=="],
|
||||
|
||||
"@octokit/core/@octokit/graphql": ["@octokit/graphql@7.1.1", "", { "dependencies": { "@octokit/request": "^8.4.1", "@octokit/types": "^13.0.0", "universal-user-agent": "^6.0.0" } }, "sha512-3mkDltSfcDUoa176nlGoA32RGjeWjl3K7F/BwHwRMJUW/IteSa4bnSV8p2ThNkcIcZU2umkZWxwETSSCJf2Q7g=="],
|
||||
"@anthropic-ai/sdk/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
|
||||
|
||||
"@octokit/core/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
|
||||
"@octokit/core/universal-user-agent": ["universal-user-agent@6.0.1", "", {}, "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ=="],
|
||||
|
||||
"@octokit/endpoint/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
|
||||
"@octokit/endpoint/universal-user-agent": ["universal-user-agent@6.0.1", "", {}, "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ=="],
|
||||
|
||||
"@octokit/graphql/@octokit/request": ["@octokit/request@9.2.4", "", { "dependencies": { "@octokit/endpoint": "^10.1.4", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "fast-content-type-parse": "^2.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-q8ybdytBmxa6KogWlNa818r0k1wlqzNC+yNkcQDECHvQo8Vmstrg18JwqJHdJdUiHD2sjlwBgSm9kHkOKe2iyA=="],
|
||||
"@anthropic-ai/sdk/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
|
||||
|
||||
"@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core": ["@octokit/core@6.1.6", "", { "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.2.2", "@octokit/request": "^9.2.3", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "before-after-hook": "^3.0.2", "universal-user-agent": "^7.0.0" } }, "sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA=="],
|
||||
"@octokit/plugin-request-log/@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="],
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@12.6.0", "", { "dependencies": { "@octokit/openapi-types": "^20.0.0" } }, "sha512-1rhSOfRa6H9w4YwK0yrf5faDaDTb+yLyBUKOCV4xtCDB5VmIPqd/v9yr9o6SAzOAlRxMiRiCic6JVM1/kunVkw=="],
|
||||
|
||||
"@octokit/request/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
"@octokit/rest/@octokit/core": ["@octokit/core@7.0.6", "", { "dependencies": { "@octokit/auth-token": "^6.0.0", "@octokit/graphql": "^9.0.3", "@octokit/request": "^10.0.6", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "before-after-hook": "^4.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-DhGl4xMVFGVIyMwswXeyzdL4uXD5OGILGX5N8Y+f6W7LhC1Ze2poSNrkF/fedpVDHEEZ+PHFW0vL14I+mm8K3Q=="],
|
||||
|
||||
"@octokit/request/universal-user-agent": ["universal-user-agent@6.0.1", "", {}, "sha512-yCzhz6FN2wU1NiiQRogkTQszlQSlpWaw8SvVegAc+bDxbzHgh1vX8uIe8OYyMH6DwH+sdTJsgMl36+mSMdRJIQ=="],
|
||||
"@octokit/rest/@octokit/plugin-paginate-rest": ["@octokit/plugin-paginate-rest@14.0.0", "", { "dependencies": { "@octokit/types": "^16.0.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-fNVRE7ufJiAA3XUrha2omTA39M6IXIc6GIZLvlbsm8QOQCYvpq/LkMNGyFlB1d8hTDzsAXa3OKtybdMAYsV/fw=="],
|
||||
|
||||
"@octokit/request-error/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
|
||||
"@octokit/rest/@octokit/core": ["@octokit/core@6.1.6", "", { "dependencies": { "@octokit/auth-token": "^5.0.0", "@octokit/graphql": "^8.2.2", "@octokit/request": "^9.2.3", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "before-after-hook": "^3.0.2", "universal-user-agent": "^7.0.0" } }, "sha512-kIU8SLQkYWGp3pVKiYzA5OSaNF5EE03P/R8zEmmrG6XwOg5oBjXyQVVIauQ0dgau4zYhpZEhJrvIYt6oM+zZZA=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-paginate-rest": ["@octokit/plugin-paginate-rest@11.6.0", "", { "dependencies": { "@octokit/types": "^13.10.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-n5KPteiF7pWKgBIBJSk8qzoZWcUkza2O6A0za97pMGVrGfPdltxrfmfF5GucHYvHGZD8BdaZmmHGz5cX/3gdpw=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-rest-endpoint-methods": ["@octokit/plugin-rest-endpoint-methods@13.5.0", "", { "dependencies": { "@octokit/types": "^13.10.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-9Pas60Iv9ejO3WlAX3maE1+38c5nqbJXV5GrncEfkndIpZrJ/WPMRd2xYDcPPEt5yzpxcjw9fWNoPhsSGzqKqw=="],
|
||||
"@octokit/rest/@octokit/plugin-rest-endpoint-methods": ["@octokit/plugin-rest-endpoint-methods@17.0.0", "", { "dependencies": { "@octokit/types": "^16.0.0" }, "peerDependencies": { "@octokit/core": ">=6" } }, "sha512-B5yCyIlOJFPqUUeiD0cnBJwWJO8lkJs5d8+ze9QDP6SvfiXSz1BF+91+0MeI1d2yxgOhU/O+CvtiZ9jSkHhFAw=="],
|
||||
|
||||
"accepts/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
|
||||
|
||||
"express/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
|
||||
|
||||
"fetch-blob/web-streams-polyfill": ["web-streams-polyfill@3.3.3", "", {}, "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw=="],
|
||||
|
||||
"send/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
|
||||
|
||||
"type-is/mime-types": ["mime-types@3.0.1", "", { "dependencies": { "mime-db": "^1.54.0" } }, "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA=="],
|
||||
|
||||
"@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
|
||||
|
||||
"@octokit/endpoint/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
|
||||
|
||||
"@octokit/graphql/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@10.1.4", "", { "dependencies": { "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA=="],
|
||||
|
||||
"@octokit/graphql/@octokit/request/@octokit/request-error": ["@octokit/request-error@6.1.8", "", { "dependencies": { "@octokit/types": "^14.0.0" } }, "sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ=="],
|
||||
"@anthropic-ai/sdk/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
|
||||
|
||||
"@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@5.1.2", "", {}, "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw=="],
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/request": ["@octokit/request@9.2.4", "", { "dependencies": { "@octokit/endpoint": "^10.1.4", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "fast-content-type-parse": "^2.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-q8ybdytBmxa6KogWlNa818r0k1wlqzNC+yNkcQDECHvQo8Vmstrg18JwqJHdJdUiHD2sjlwBgSm9kHkOKe2iyA=="],
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/request-error": ["@octokit/request-error@6.1.8", "", { "dependencies": { "@octokit/types": "^14.0.0" } }, "sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ=="],
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/request": ["@octokit/request@10.0.10", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "content-type": "^2.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="],
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="],
|
||||
|
||||
"@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@20.0.0", "", {}, "sha512-EtqRBEjp1dL/15V7WiX5LJMIxxkdiGJnabzYx5Apx4FkQIFgAfKumXeYAqqJCj1s+BMX4cPFIFC4OLCR6stlnA=="],
|
||||
|
||||
"@octokit/request-error/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
|
||||
"@octokit/rest/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@6.0.0", "", {}, "sha512-P4YJBPdPSpWTQ1NU4XYdvHvXJJDxM6YwpS0FZHRgP7YFkdVxsWcpWGy/NVqlAA7PcPCnMacXlRm1y2PFZRWL/w=="],
|
||||
|
||||
"@octokit/request/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
|
||||
"@octokit/rest/@octokit/core/@octokit/graphql": ["@octokit/graphql@9.0.3", "", { "dependencies": { "@octokit/request": "^10.0.6", "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.0" } }, "sha512-grAEuupr/C1rALFnXTv6ZQhFuL1D8G5y8CN04RgrO4FIPMrtm+mcZzFG7dcBm+nq+1ppNixu+Jd78aeJOYxlGA=="],
|
||||
|
||||
"@octokit/rest/@octokit/core/@octokit/auth-token": ["@octokit/auth-token@5.1.2", "", {}, "sha512-JcQDsBdg49Yky2w2ld20IHAlwr8d/d8N6NiOXbtuoPCqzbsiJgF633mVUw3x4mo0H5ypataQIX7SFu3yy44Mpw=="],
|
||||
"@octokit/rest/@octokit/core/@octokit/request": ["@octokit/request@10.0.10", "", { "dependencies": { "@octokit/endpoint": "^11.0.3", "@octokit/request-error": "^7.0.2", "@octokit/types": "^16.0.0", "content-type": "^2.0.0", "json-with-bigint": "^3.5.3", "universal-user-agent": "^7.0.2" } }, "sha512-KxNC2pTqqhszMNrf12ZRd4PonRgyJdsM4F/jySiddQK+DsRcfBtUvqn8t7UsyZhnRJHvX46OohDt5N3VqIWC2w=="],
|
||||
|
||||
"@octokit/rest/@octokit/core/@octokit/request": ["@octokit/request@9.2.4", "", { "dependencies": { "@octokit/endpoint": "^10.1.4", "@octokit/request-error": "^6.1.8", "@octokit/types": "^14.0.0", "fast-content-type-parse": "^2.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-q8ybdytBmxa6KogWlNa818r0k1wlqzNC+yNkcQDECHvQo8Vmstrg18JwqJHdJdUiHD2sjlwBgSm9kHkOKe2iyA=="],
|
||||
"@octokit/rest/@octokit/core/@octokit/request-error": ["@octokit/request-error@7.1.0", "", { "dependencies": { "@octokit/types": "^16.0.0" } }, "sha512-KMQIfq5sOPpkQYajXHwnhjCC0slzCNScLHs9JafXc4RAJI+9f+jNDlBNaIMTvazOPLgb4BnlhGJOTbnN0wIjPw=="],
|
||||
|
||||
"@octokit/rest/@octokit/core/@octokit/request-error": ["@octokit/request-error@6.1.8", "", { "dependencies": { "@octokit/types": "^14.0.0" } }, "sha512-WEi/R0Jmq+IJKydWlKDmryPcmdYSVjL3ekaiEL1L9eo1sUnqMJ+grqmC9cjk7CA7+b2/T397tO5d8YLOH3qYpQ=="],
|
||||
"@octokit/rest/@octokit/core/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/rest/@octokit/core/before-after-hook": ["before-after-hook@3.0.2", "", {}, "sha512-Nik3Sc0ncrMK4UUdXQmAnRtzmNQTAAXmXIopizwZ1W1t8QmfJj+zL4OA2I7XPTPW5z5TDqv4hRo/JzouDJnX3A=="],
|
||||
"@octokit/rest/@octokit/core/before-after-hook": ["before-after-hook@4.0.0", "", {}, "sha512-q6tR3RPqIB1pMiTRMFcZwuG5T8vwp+vUvEG0vuI6B+Rikh5BfPp2fQ82c925FOs+b0lcFQ8CFrL+KbilfZFhOQ=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
"@octokit/rest/@octokit/core/universal-user-agent": ["universal-user-agent@7.0.3", "", {}, "sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@13.10.0", "", { "dependencies": { "@octokit/openapi-types": "^24.2.0" } }, "sha512-ifLaO34EbbPj0Xgro4G5lP5asESjwHracYJvVaPIyXMuiuXLlhic3S47cBdTb+jfODkTE5YtGCLt3Ay3+J97sA=="],
|
||||
"@octokit/rest/@octokit/plugin-paginate-rest/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-rest-endpoint-methods/@octokit/types": ["@octokit/types@16.0.0", "", { "dependencies": { "@octokit/openapi-types": "^27.0.0" } }, "sha512-sKq+9r1Mm4efXW1FCk7hFSeJo4QKreL/tTbR0rz/qx/r1Oa2VV83LTA/H/MuCOX7uCIJmQVRKBcbmWoySjAnSg=="],
|
||||
|
||||
"accepts/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
|
||||
|
||||
@@ -367,12 +384,20 @@
|
||||
|
||||
"type-is/mime-types/mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
|
||||
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@10.1.4", "", { "dependencies": { "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA=="],
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="],
|
||||
|
||||
"@octokit/rest/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@10.1.4", "", { "dependencies": { "@octokit/types": "^14.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-OlYOlZIsfEVZm5HCSR8aSg02T2lbUWOsCQoPKfTXJwDzcHQBrVBGdGXb89dv2Kw2ToZaRtudp8O3ZIYoaOjKlA=="],
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/request/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
|
||||
"@octokit/plugin-request-log/@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@24.2.0", "", {}, "sha512-9sIH3nSUttelJSXUrmGzl7QUBFul0/mB8HRYl3fOlgHbIWG+WnYDXU3v/2zMtAvuzZ/ed00Ei6on975FhBfzrg=="],
|
||||
"@octokit/rest/@octokit/core/@octokit/request/@octokit/endpoint": ["@octokit/endpoint@11.0.3", "", { "dependencies": { "@octokit/types": "^16.0.0", "universal-user-agent": "^7.0.2" } }, "sha512-FWFlNxghg4HrXkD3ifYbS/IdL/mDHjh9QcsNyhQjN8dplUoZbejsdpmuqdA76nxj2xoWPs7p8uX2SNr9rYu0Ag=="],
|
||||
|
||||
"@octokit/rest/@octokit/core/@octokit/request/content-type": ["content-type@2.0.0", "", {}, "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ=="],
|
||||
|
||||
"@octokit/rest/@octokit/core/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-paginate-rest/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
|
||||
"@octokit/rest/@octokit/plugin-rest-endpoint-methods/@octokit/types/@octokit/openapi-types": ["@octokit/openapi-types@27.0.0", "", {}, "sha512-whrdktVs1h6gtR+09+QsNk2+FO+49j6ga1c55YZudfEG+oKJVvJLQi3zkOm5JjiUXAagWK2tI2kTGKJ2Ys7MGA=="],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Example: schema-validated PR review verdict via `claude_args` + `structured_output`.
|
||||
#
|
||||
# Instead of having the agent write its verdict to a file, this asks Claude for a
|
||||
# result that conforms to a JSON Schema and reads it back from the action output.
|
||||
# The default-installed Claude CLI (2.1.160) supports `--json-schema`; the
|
||||
# action reads the schema file below and passes it to the CLI inline, so the
|
||||
# file-path form works out of the box (see README → "Structured output"). If
|
||||
# you consume this action through a pre-baked runner image
|
||||
# (path_to_claude_code_executable), that image's CLI must still support the
|
||||
# `--json-schema` flag.
|
||||
|
||||
name: Claude PR Review (structured output)
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, synchronize]
|
||||
|
||||
jobs:
|
||||
review:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
issues: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
# The schema the verdict must conform to. Using a file (rather than an
|
||||
# inline string) keeps the value free of spaces and `$` characters, so a
|
||||
# schema with $ref/$defs survives shell tokenization intact.
|
||||
- name: Write review schema
|
||||
shell: bash
|
||||
run: |
|
||||
mkdir -p .gitea
|
||||
cat > .gitea/review-schema.json <<'JSON'
|
||||
{
|
||||
"type": "object",
|
||||
"additionalProperties": false,
|
||||
"required": ["decision", "summary"],
|
||||
"properties": {
|
||||
"decision": { "type": "string", "enum": ["approve", "request_changes", "comment"] },
|
||||
"summary": { "type": "string" }
|
||||
}
|
||||
}
|
||||
JSON
|
||||
|
||||
- name: Run Claude review
|
||||
id: review
|
||||
uses: ryan/claude-code-gitea-action@gitea
|
||||
with:
|
||||
gitea_token: ${{ secrets.GITEA_TOKEN }}
|
||||
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
||||
direct_prompt: |
|
||||
Review the changes in this pull request and return your verdict
|
||||
strictly matching the provided JSON schema.
|
||||
claude_args: --json-schema ${{ github.workspace }}/.gitea/review-schema.json
|
||||
|
||||
- name: Act on the verdict
|
||||
shell: bash
|
||||
env:
|
||||
VERDICT: ${{ steps.review.outputs.structured_output }}
|
||||
run: |
|
||||
echo "Decision: $(echo "$VERDICT" | jq -r '.decision')"
|
||||
echo "Summary: $(echo "$VERDICT" | jq -r '.summary')"
|
||||
@@ -17,12 +17,14 @@
|
||||
"@octokit/rest": "^22.0.0",
|
||||
"@octokit/webhooks-types": "^7.6.1",
|
||||
"node-fetch": "^3.3.2",
|
||||
"shell-quote": "^1.8.1",
|
||||
"zod": "^3.24.4"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/bun": "1.2.11",
|
||||
"@types/node": "^20.0.0",
|
||||
"@types/node-fetch": "^2.6.12",
|
||||
"@types/shell-quote": "^1.7.5",
|
||||
"prettier": "3.5.3",
|
||||
"typescript": "^5.8.3"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user