Initial curated projectbrain source from 8a7b1e0651dbdab97d744cbd2e653ab3970ac6c5
This commit is contained in:
commit
5aa3e8d685
700 files changed
+132801
No files matched your search
@@ -0,0 +1,60 @@
|
||||
import { GiteaApiError } from "../integrations/gitea/client.js";
|
||||
import type { GiteaContent } from "../integrations/gitea/types.js";
|
||||
|
||||
export type ToolResult = { content: Array<{ type: "text"; text: string }>; structuredContent?: Record<string, unknown>; isError?: boolean };
|
||||
|
||||
export const MAX_MCP_READ_BYTES = 512 * 1024;
|
||||
|
||||
export const asResult = (data: unknown, message = "Operation completed"): ToolResult => ({ content: [{ type: "text", text: message }], structuredContent: data && typeof data === "object" && !Array.isArray(data) ? data as Record<string, unknown> : { data } });
|
||||
export const asStandardKnowledgeResult = (data: Record<string, unknown>): ToolResult => ({ content: [{ type: "text", text: JSON.stringify(data) }] });
|
||||
export const asCompactResult = (data: Record<string, unknown>, message: string): ToolResult => ({ content: [{ type: "text", text: message }], structuredContent: data });
|
||||
export const errorCode = (error: unknown) => error instanceof GiteaApiError ? error.code : error instanceof Error ? error.message : "MCP_OPERATION_FAILED";
|
||||
|
||||
export const operationRecovery = (code: string) => {
|
||||
if (/CHECKS_PENDING/.test(code)) return { action: "wait_and_resume", retryable: true, detail: "Required checks are still queued/running. Keep the same delivery, branch and PR; inspect status after the indicated wait and retry the merge with the current head." };
|
||||
if (/CI_|CHECKS_FAILED|VALIDATION_FAILED/.test(code)) return { action: "repair_and_revalidate", retryable: true, detail: "Read exact-head validation runs and the selected failed-job evidence. Fix the cause on the existing delivery branch. For canceled/transient runs, rerun the affected workflow. Sync successful evidence, then retry this PR's merge; never create a replacement branch or weaken checks." };
|
||||
if (/HEAD_CONFLICT|FILE_CONFLICT|AUTO_MODE_CONFLICT/.test(code)) return { action: "reload_current_state", retryable: true, detail: "Reload the existing delivery, branch head and affected file SHAs. Reconcile actual progress before retrying; do not replay stale writes." };
|
||||
if (/MERGE_UNCONFIRMED|PULL_REQUEST_NOT_READY/.test(code)) return { action: "reconcile_existing_pr", retryable: true, detail: "Read the existing PR and retry merge_feature_delivery with its expected head. An already merged PR is reconciled without another merge." };
|
||||
return { action: "inspect_existing_delivery", retryable: false, detail: "Read the existing delivery and repository state before acting. Do not create another branch to work around a tool error." };
|
||||
};
|
||||
|
||||
export const pageCollection = <T>(items: T[], cursor: number, pageSize: number) => ({ items: items.slice(cursor, cursor + pageSize), total: items.length, nextCursor: cursor + pageSize < items.length ? String(cursor + pageSize) : undefined });
|
||||
|
||||
export const compactRecord = (value: unknown): Record<string, unknown> => {
|
||||
if (!value || typeof value !== "object" || Array.isArray(value)) return { value };
|
||||
const item = value as Record<string, unknown>;
|
||||
const spec = item.spec && typeof item.spec === "object" && !Array.isArray(item.spec) ? item.spec as Record<string, unknown> : undefined;
|
||||
const summaryCandidate = [item.summary, item.contextSummary, item.rule, item.intent, item.content]
|
||||
.find((candidate): candidate is string => typeof candidate === "string" && candidate.length > 0);
|
||||
return Object.fromEntries(Object.entries({
|
||||
id: item.id,
|
||||
projectId: item.projectId,
|
||||
title: item.title,
|
||||
status: item.status ?? spec?.status,
|
||||
approvalState: item.approvalState,
|
||||
kind: item.kind,
|
||||
category: item.category,
|
||||
scope: item.scope,
|
||||
severity: item.severity,
|
||||
confidence: item.confidence,
|
||||
priority: item.priority,
|
||||
branch: spec?.branch,
|
||||
pullRequest: spec?.pullRequest,
|
||||
summary: summaryCandidate ? `${summaryCandidate.slice(0, 600)}${summaryCandidate.length > 600 ? "…" : ""}` : undefined,
|
||||
updatedAt: item.updatedAt,
|
||||
}).filter(([, field]) => field !== undefined));
|
||||
};
|
||||
|
||||
export const compactDelivery = (value: unknown) => compactRecord(value);
|
||||
|
||||
export const decodeFile = (content: GiteaContent) => {
|
||||
if (content.type !== "file" || content.encoding !== "base64" || typeof content.content !== "string") throw new Error("GITEA_CONTENT_NOT_FILE");
|
||||
if (content.size > MAX_MCP_READ_BYTES) throw new Error("MCP_FILE_READ_TOO_LARGE");
|
||||
return Buffer.from(content.content.replace(/\s/g, ""), "base64").toString("utf8");
|
||||
};
|
||||
|
||||
export const parseFetchId = (id: string) => {
|
||||
const match = id.match(/^gitea:\/\/([^/]+)\/([^/]+)\/(.+)$/);
|
||||
if (!match) throw new Error("MCP_FETCH_ID_INVALID");
|
||||
return { projectId: decodeURIComponent(match[1]), ref: decodeURIComponent(match[2]), path: decodeURIComponent(match[3]) };
|
||||
};
|
||||
Reference in new issue
Block a user