Clean up actions and payloads (#98)
* Clean up actions and payloads * Clean up action * Cleanup
This commit is contained in:
committed by
pullfrog[bot]
parent
5c60791b34
commit
9e019d89d2
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { type ChildProcess, spawn } from "node:child_process";
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const BashParams = type({
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const GetCheckSuiteLogs = type({
|
||||
|
||||
+10
-10
@@ -2,9 +2,9 @@ import { writeFileSync } from "node:fs";
|
||||
import { join } from "node:path";
|
||||
import type { Octokit, RestEndpointMethodTypes } from "@octokit/rest";
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import { log } from "../utils/cli.ts";
|
||||
import { $ } from "../utils/shell.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
type PullFile = RestEndpointMethodTypes["pulls"]["listFiles"]["response"]["data"][number];
|
||||
@@ -118,7 +118,7 @@ export async function checkoutPrBranch(
|
||||
params: CheckoutPrBranchParams
|
||||
): Promise<CheckoutPrBranchResult> {
|
||||
const { octokit, owner, name, token, pullNumber } = params;
|
||||
log.info(`🔀 checking out PR #${pullNumber}...`);
|
||||
log.info(`» checking out PR #${pullNumber}...`);
|
||||
|
||||
// fetch PR metadata
|
||||
const pr = await octokit.rest.pulls.get({
|
||||
@@ -149,7 +149,7 @@ export async function checkoutPrBranch(
|
||||
log.debug(`already on PR branch ${localBranch}, skipping checkout`);
|
||||
} else {
|
||||
// fetch base branch so origin/<base> exists for diff operations
|
||||
log.debug(`📥 fetching base branch (${baseBranch})...`);
|
||||
log.debug(`» fetching base branch (${baseBranch})...`);
|
||||
$("git", ["fetch", "--no-tags", "origin", baseBranch]);
|
||||
|
||||
// checkout base branch first to avoid "refusing to fetch into current branch" error
|
||||
@@ -157,18 +157,18 @@ export async function checkoutPrBranch(
|
||||
$("git", ["checkout", "-B", baseBranch, `origin/${baseBranch}`]);
|
||||
|
||||
// fetch PR branch using pull/{n}/head refspec (works for both fork and same-repo PRs)
|
||||
log.debug(`🌿 fetching PR #${pullNumber} (${localBranch})...`);
|
||||
log.debug(`» fetching PR #${pullNumber} (${localBranch})...`);
|
||||
$("git", ["fetch", "--no-tags", "origin", `pull/${pullNumber}/head:${localBranch}`]);
|
||||
|
||||
// checkout the branch
|
||||
$("git", ["checkout", localBranch]);
|
||||
log.debug(`✓ checked out PR #${pullNumber}`);
|
||||
log.debug(`» checked out PR #${pullNumber}`);
|
||||
}
|
||||
|
||||
// ensure base branch is fetched (needed for diff operations)
|
||||
// fetch if we skipped checkout (already on branch) - otherwise already fetched above
|
||||
if (alreadyOnBranch) {
|
||||
log.debug(`📥 fetching base branch (${baseBranch})...`);
|
||||
log.debug(`» fetching base branch (${baseBranch})...`);
|
||||
$("git", ["fetch", "--no-tags", "origin", baseBranch]);
|
||||
}
|
||||
|
||||
@@ -182,23 +182,23 @@ export async function checkoutPrBranch(
|
||||
// add fork as a named remote (suppress logging to avoid "error: remote already exists" spam)
|
||||
try {
|
||||
$("git", ["remote", "add", remoteName, forkUrl], { log: false });
|
||||
log.debug(`📌 added remote '${remoteName}' for fork ${headRepo.full_name}`);
|
||||
log.debug(`» added remote '${remoteName}' for fork ${headRepo.full_name}`);
|
||||
} catch {
|
||||
// remote already exists, update its URL
|
||||
$("git", ["remote", "set-url", remoteName, forkUrl], { log: false });
|
||||
log.debug(`📌 updated remote '${remoteName}' for fork ${headRepo.full_name}`);
|
||||
log.debug(`» updated remote '${remoteName}' for fork ${headRepo.full_name}`);
|
||||
}
|
||||
|
||||
// set branch push config so `git push` knows where to push
|
||||
$("git", ["config", `branch.${localBranch}.pushRemote`, remoteName]);
|
||||
// set merge ref so git knows the remote branch name (may differ from local)
|
||||
$("git", ["config", `branch.${localBranch}.merge`, `refs/heads/${headBranch}`]);
|
||||
log.debug(`📌 configured branch '${localBranch}' to push to '${remoteName}/${headBranch}'`);
|
||||
log.debug(`» configured branch '${localBranch}' to push to '${remoteName}/${headBranch}'`);
|
||||
|
||||
// warn if maintainer can't modify (push will likely fail)
|
||||
if (!pr.data.maintainer_can_modify) {
|
||||
log.warning(
|
||||
`⚠️ fork PR has maintainer_can_modify=false - push operations will fail. ` +
|
||||
`» fork PR has maintainer_can_modify=false - push operations will fail. ` +
|
||||
`ask the PR author to enable "Allow edits from maintainers" or the fork may be owned by an organization.`
|
||||
);
|
||||
}
|
||||
|
||||
+37
-34
@@ -1,16 +1,11 @@
|
||||
import { type } from "arktype";
|
||||
import type { Payload } from "../external.ts";
|
||||
import { agentsManifest } from "../external.ts";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import { fetchWorkflowRunInfo } from "../utils/api.ts";
|
||||
import type { Agent } from "../agents/index.ts";
|
||||
import { buildPullfrogFooter, stripExistingFooter } from "../utils/buildPullfrogFooter.ts";
|
||||
import { writeSummary } from "../utils/cli.ts";
|
||||
import {
|
||||
createOctokit,
|
||||
getGitHubInstallationToken,
|
||||
type OctokitWithPlugins,
|
||||
parseRepoContext,
|
||||
} from "../utils/github.ts";
|
||||
import { createOctokit, type OctokitWithPlugins, parseRepoContext } from "../utils/github.ts";
|
||||
import { getGitHubInstallationToken } from "../utils/token.ts";
|
||||
import { fetchWorkflowRunInfo } from "../utils/workflowRun.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
/**
|
||||
@@ -21,22 +16,19 @@ import { execute, tool } from "./shared.ts";
|
||||
export const LEAPING_INTO_ACTION_PREFIX = "Leaping into action";
|
||||
|
||||
interface BuildCommentFooterParams {
|
||||
payload: Payload;
|
||||
agent: Agent | undefined;
|
||||
octokit?: OctokitWithPlugins | undefined;
|
||||
customParts?: string[] | undefined;
|
||||
}
|
||||
|
||||
async function buildCommentFooter({
|
||||
payload,
|
||||
agent,
|
||||
octokit,
|
||||
customParts,
|
||||
}: BuildCommentFooterParams): Promise<string> {
|
||||
const repoContext = parseRepoContext();
|
||||
const runId = process.env.GITHUB_RUN_ID;
|
||||
|
||||
const agentName = payload.agent;
|
||||
const agentInfo = agentName ? agentsManifest[agentName] : null;
|
||||
|
||||
let workflowRunHtmlUrl: string | undefined;
|
||||
if (runId && octokit) {
|
||||
try {
|
||||
@@ -56,8 +48,8 @@ async function buildCommentFooter({
|
||||
const footerParams = {
|
||||
triggeredBy: true,
|
||||
agent: {
|
||||
displayName: agentInfo?.displayName || "Unknown agent",
|
||||
url: agentInfo?.url || "https://pullfrog.com",
|
||||
displayName: agent?.displayName || "Unknown agent",
|
||||
url: agent?.url || "https://pullfrog.com",
|
||||
},
|
||||
workflowRun: runId
|
||||
? {
|
||||
@@ -88,13 +80,14 @@ function buildImplementPlanLink(
|
||||
return `[Implement plan ➔](${apiUrl}/trigger/${owner}/${repo}/${issueNumber}?action=implement&comment_id=${commentId})`;
|
||||
}
|
||||
|
||||
async function addFooter(
|
||||
body: string,
|
||||
payload: Payload,
|
||||
octokit?: OctokitWithPlugins
|
||||
): Promise<string> {
|
||||
interface AddFooterCtx {
|
||||
agent?: Agent | undefined;
|
||||
octokit?: OctokitWithPlugins | undefined;
|
||||
}
|
||||
|
||||
async function addFooter(ctx: AddFooterCtx, body: string): Promise<string> {
|
||||
const bodyWithoutFooter = stripExistingFooter(body);
|
||||
const footer = await buildCommentFooter({ payload, octokit });
|
||||
const footer = await buildCommentFooter({ agent: ctx.agent, octokit: ctx.octokit });
|
||||
return `${bodyWithoutFooter}${footer}`;
|
||||
}
|
||||
|
||||
@@ -110,7 +103,7 @@ export function CreateCommentTool(ctx: ToolContext) {
|
||||
"Create a comment on a GitHub issue. NOTE: Do NOT use this for progress updates or status summaries - use report_progress instead, which updates the existing progress comment.",
|
||||
parameters: Comment,
|
||||
execute: execute(async ({ issueNumber, body }) => {
|
||||
const bodyWithFooter = await addFooter(body, ctx.payload, ctx.octokit);
|
||||
const bodyWithFooter = await addFooter(ctx, body);
|
||||
|
||||
const result = await ctx.octokit.rest.issues.createComment({
|
||||
owner: ctx.owner,
|
||||
@@ -140,7 +133,7 @@ export function EditCommentTool(ctx: ToolContext) {
|
||||
description: "Edit a GitHub issue comment by its ID",
|
||||
parameters: EditComment,
|
||||
execute: execute(async ({ commentId, body }) => {
|
||||
const bodyWithFooter = await addFooter(body, ctx.payload, ctx.octokit);
|
||||
const bodyWithFooter = await addFooter(ctx, body);
|
||||
|
||||
const result = await ctx.octokit.rest.issues.updateComment({
|
||||
owner: ctx.owner,
|
||||
@@ -218,8 +211,7 @@ export async function reportProgress(
|
||||
| undefined
|
||||
> {
|
||||
const existingCommentId = getProgressCommentId();
|
||||
const issueNumber =
|
||||
ctx.toolState.prNumber ?? ctx.toolState.issueNumber ?? ctx.payload.event.issue_number;
|
||||
const issueNumber = ctx.toolState.prNumber ?? ctx.toolState.issueNumber ?? ctx.event.issue_number;
|
||||
const isPlanMode = ctx.toolState.selectedMode === "Plan";
|
||||
|
||||
// if we already have a progress comment, update it
|
||||
@@ -231,7 +223,7 @@ export async function reportProgress(
|
||||
|
||||
const bodyWithoutFooter = stripExistingFooter(body);
|
||||
const footer = await buildCommentFooter({
|
||||
payload: ctx.payload,
|
||||
agent: ctx.agent,
|
||||
octokit: ctx.octokit,
|
||||
customParts,
|
||||
});
|
||||
@@ -264,7 +256,7 @@ export async function reportProgress(
|
||||
}
|
||||
|
||||
// for new comments, we need to create first, then update with Plan link if in Plan mode
|
||||
const initialBody = await addFooter(body, ctx.payload, ctx.octokit);
|
||||
const initialBody = await addFooter(ctx, body);
|
||||
|
||||
const result = await ctx.octokit.rest.issues.createComment({
|
||||
owner: ctx.owner,
|
||||
@@ -282,7 +274,7 @@ export async function reportProgress(
|
||||
const customParts = [buildImplementPlanLink(ctx.owner, ctx.name, issueNumber, result.data.id)];
|
||||
const bodyWithoutFooter = stripExistingFooter(body);
|
||||
const footer = await buildCommentFooter({
|
||||
payload: ctx.payload,
|
||||
agent: ctx.agent,
|
||||
octokit: ctx.octokit,
|
||||
customParts,
|
||||
});
|
||||
@@ -382,6 +374,10 @@ export async function deleteProgressComment(ctx: ToolContext): Promise<boolean>
|
||||
return true;
|
||||
}
|
||||
|
||||
interface EnsureProgressCommentUpdatedParams {
|
||||
disableProgressComment: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the progress comment is updated with a generic error message if it was never updated.
|
||||
* This should be called after agent execution completes to handle cases where the agent
|
||||
@@ -390,12 +386,19 @@ export async function deleteProgressComment(ctx: ToolContext): Promise<boolean>
|
||||
* Works even if MCP context is not initialized (e.g., if error occurs before MCP server starts).
|
||||
* Will fetch comment ID from database if not available in environment variable.
|
||||
*/
|
||||
export async function ensureProgressCommentUpdated(payload?: Payload): Promise<void> {
|
||||
export async function ensureProgressCommentUpdated(
|
||||
params: EnsureProgressCommentUpdatedParams
|
||||
): Promise<void> {
|
||||
// skip if comment was already updated during execution
|
||||
if (progressComment.wasUpdated) {
|
||||
return;
|
||||
}
|
||||
|
||||
// skip if progress comments are disabled
|
||||
if (params.disableProgressComment) {
|
||||
return;
|
||||
}
|
||||
|
||||
// try to get comment ID from env var first, then from database if needed
|
||||
let existingCommentId = getProgressCommentId();
|
||||
|
||||
@@ -453,8 +456,8 @@ export async function ensureProgressCommentUpdated(payload?: Payload): Promise<v
|
||||
|
||||
The workflow encountered an error before any progress could be reported. Please check the ${workflowRunLink} for details.`;
|
||||
|
||||
// add footer if we have payload, otherwise use plain message
|
||||
const body = payload ? await addFooter(errorMessage, payload, octokit) : errorMessage;
|
||||
// add footer without agent info (we don't have context here)
|
||||
const body = await addFooter({ octokit }, errorMessage);
|
||||
|
||||
await octokit.rest.issues.updateComment({
|
||||
owner: repoContext.owner,
|
||||
@@ -479,7 +482,7 @@ export function ReplyToReviewCommentTool(ctx: ToolContext) {
|
||||
"Reply to a PR review comment thread. Call this for EACH comment you address. Keep replies extremely brief (1 sentence max).",
|
||||
parameters: ReplyToReviewComment,
|
||||
execute: execute(async ({ pull_number, comment_id, body }) => {
|
||||
const bodyWithFooter = await addFooter(body, ctx.payload, ctx.octokit);
|
||||
const bodyWithFooter = await addFooter(ctx, body);
|
||||
|
||||
const result = await ctx.octokit.rest.pulls.createReplyForReviewComment({
|
||||
owner: ctx.owner,
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
/**
|
||||
* Simple MCP configuration helper for adding our minimal GitHub comment server
|
||||
*/
|
||||
|
||||
import type { McpHttpServerConfig } from "@anthropic-ai/claude-agent-sdk";
|
||||
import { ghPullfrogMcpName } from "../external.ts";
|
||||
|
||||
export type McpName = typeof ghPullfrogMcpName;
|
||||
|
||||
export type McpConfigs = Record<McpName, McpHttpServerConfig>;
|
||||
|
||||
export function createMcpConfigs(mcpServerUrl: string): McpConfigs {
|
||||
return {
|
||||
[ghPullfrogMcpName]: {
|
||||
type: "http",
|
||||
url: mcpServerUrl,
|
||||
},
|
||||
};
|
||||
}
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { $ } from "../utils/shell.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import type { PrepResult } from "../prep/index.ts";
|
||||
import { runPrepPhase } from "../prep/index.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { log } from "../utils/cli.ts";
|
||||
import { containsSecrets } from "../utils/secrets.ts";
|
||||
import { $ } from "../utils/shell.ts";
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const Issue = type({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const GetIssueComments = type({
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const GetIssueEvents = type({
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const IssueInfo = type({
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const AddLabelsParams = type({
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import { agentsManifest } from "../external.ts";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { buildPullfrogFooter, stripExistingFooter } from "../utils/buildPullfrogFooter.ts";
|
||||
import { log } from "../utils/cli.ts";
|
||||
import { containsSecrets } from "../utils/secrets.ts";
|
||||
@@ -14,12 +13,9 @@ export const PullRequest = type({
|
||||
});
|
||||
|
||||
function buildPrBodyWithFooter(ctx: ToolContext, body: string): string {
|
||||
const agentName = ctx.payload.agent;
|
||||
const agentInfo = agentName ? agentsManifest[agentName] : null;
|
||||
|
||||
const footer = buildPullfrogFooter({
|
||||
triggeredBy: true,
|
||||
agent: agentInfo ? { displayName: agentInfo.displayName, url: agentInfo.url } : undefined,
|
||||
agent: { displayName: ctx.agent.displayName, url: ctx.agent.url },
|
||||
workflowRun: ctx.runId
|
||||
? { owner: ctx.owner, repo: ctx.name, runId: ctx.runId, jobId: ctx.jobId }
|
||||
: undefined,
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const PullRequestInfo = type({
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { RestEndpointMethodTypes } from "@octokit/rest";
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { buildPullfrogFooter } from "../utils/buildPullfrogFooter.ts";
|
||||
import { log } from "../utils/cli.ts";
|
||||
import { deleteProgressComment } from "./comment.ts";
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
// graphql query to fetch all review threads with comments and replies
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
import { type } from "arktype";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
import { execute, tool } from "./shared.ts";
|
||||
|
||||
export const SelectMode = type({
|
||||
|
||||
+38
-4
@@ -1,9 +1,44 @@
|
||||
import "./arkConfig.ts";
|
||||
import { createServer } from "node:net";
|
||||
// this must be imported first
|
||||
import type { Octokit } from "@octokit/rest";
|
||||
import { FastMCP, type Tool } from "fastmcp";
|
||||
import { ghPullfrogMcpName } from "../external.ts";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import type { Agent } from "../agents/index.ts";
|
||||
import { ghPullfrogMcpName, type PayloadEvent } from "../external.ts";
|
||||
import type { Mode } from "../modes.ts";
|
||||
import type { PrepResult } from "../prep/index.ts";
|
||||
|
||||
export interface ToolState {
|
||||
prNumber?: number;
|
||||
issueNumber?: number;
|
||||
selectedMode?: string;
|
||||
review?: {
|
||||
id: number;
|
||||
nodeId: string;
|
||||
};
|
||||
dependencyInstallation?: {
|
||||
status: "not_started" | "in_progress" | "completed" | "failed";
|
||||
promise: Promise<PrepResult[]> | undefined;
|
||||
results: PrepResult[] | undefined;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ToolContext {
|
||||
owner: string;
|
||||
name: string;
|
||||
repo: { default_branch: string; private: boolean };
|
||||
githubInstallationToken: string;
|
||||
octokit: Octokit;
|
||||
agent: Agent;
|
||||
event: PayloadEvent;
|
||||
disableProgressComment: boolean;
|
||||
modes: Mode[];
|
||||
toolState: ToolState;
|
||||
runId: string;
|
||||
jobId: string | undefined;
|
||||
}
|
||||
|
||||
import { BashTool } from "./bash.ts";
|
||||
import { CheckoutPrTool } from "./checkout.ts";
|
||||
import { GetCheckSuiteLogsTool } from "./checkSuite.ts";
|
||||
import {
|
||||
@@ -29,7 +64,6 @@ import { CreatePullRequestReviewTool } from "./review.ts";
|
||||
import { GetReviewCommentsTool, ListPullRequestReviewsTool } from "./reviewComments.ts";
|
||||
import { SelectModeTool } from "./selectMode.ts";
|
||||
import { addTools } from "./shared.ts";
|
||||
import { BashTool } from "./bash.ts";
|
||||
|
||||
/**
|
||||
* Find an available port starting from the given port
|
||||
@@ -98,7 +132,7 @@ export async function startMcpHttpServer(
|
||||
BashTool(ctx),
|
||||
];
|
||||
|
||||
if (!ctx.payload.disableProgressComment) {
|
||||
if (!ctx.disableProgressComment) {
|
||||
tools.push(ReportProgressTool(ctx));
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,8 +1,8 @@
|
||||
import type { StandardSchemaV1 } from "@standard-schema/spec";
|
||||
import { encode as toonEncode } from "@toon-format/toon";
|
||||
import type { FastMCP, Tool } from "fastmcp";
|
||||
import type { ToolContext } from "../main.ts";
|
||||
import { formatJsonValue, log } from "../utils/cli.ts";
|
||||
import type { ToolContext } from "./server.ts";
|
||||
|
||||
export const tool = <const params>(toolDef: Tool<any, StandardSchemaV1<params>>) => toolDef;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user