Merge RepoSettings into Repo (#248)
* Merge RepoSettings into Repo Inline all RepoSettings fields (triggers, tools, instructions, scripts, defaultAgent) directly into the Repo model. Pivot Macro/Mode foreign keys from repoSettingsId to repoId. Drop the repo_settings table entirely. Migration backfills all existing data safely. Co-authored-by: Cursor <cursoragent@cursor.com> * Remove dead null-coalescing and defaultSettings fallback All settings fields are now NOT NULL on Repo, so ?? fallbacks in run-context are unnecessary. initialSettings is non-nullable, so the defaultSettings memo in RepoConsole was dead code. Co-authored-by: Cursor <cursoragent@cursor.com> * drop dead /workflows route, extract getAuthenticatedRepoContext helper - delete /api/repo/[owner]/[repo]/workflows/ (duplicate of /modes/, no consumers) - extract shared auth helper that returns { account, owner, repo, token, dbRepo, role } - update settings, macros, modes routes to use the helper Co-authored-by: Cursor <cursoragent@cursor.com> * type-safe API route returns via inferred NextResponse generics - add ApiResponse<T> utility type that extracts JSON body from route handlers - remove explicit return type annotations and dead interfaces from 5 routes - update 3 routes with existing type exports to use ApiResponse<typeof handler> - narrow error union in ReposTable fetchRepos Co-authored-by: Cursor <cursoragent@cursor.com> * run tests on push in addition to pull_request Co-authored-by: Cursor <cursoragent@cursor.com> * add rule: no --trailer flags on git commits Co-authored-by: Cursor <cursoragent@cursor.com> * move git trailer rule into Rules section Co-authored-by: Cursor <cursoragent@cursor.com> * consolidate Learnings into Rules section Co-authored-by: Cursor <cursoragent@cursor.com> --------- Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
committed by
pullfrog[bot]
parent
60da0e5749
commit
623e11c7ce
@@ -41449,28 +41449,35 @@ async function getIsCancelled(params) {
|
||||
}
|
||||
log.info("[post] no cancellation found, assuming failure");
|
||||
} catch (error2) {
|
||||
log.warning(`[post] failed to get job status: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
||||
log.warning(
|
||||
`[post] failed to get job status: ${error2 instanceof Error ? error2.message : String(error2)}`
|
||||
);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
async function runPostCleanup() {
|
||||
log.info("\xBB [post] starting post cleanup");
|
||||
const runIdStr = process.env.GITHUB_RUN_ID;
|
||||
if (!runIdStr)
|
||||
return log.info("\xBB [post] no GITHUB_RUN_ID available, skipping cleanup");
|
||||
if (!runIdStr) return log.info("\xBB [post] no GITHUB_RUN_ID available, skipping cleanup");
|
||||
let promptInput = null;
|
||||
try {
|
||||
const resolved = resolvePromptInput();
|
||||
if (typeof resolved !== "string") promptInput = resolved;
|
||||
} catch (error2) {
|
||||
log.warning(`[post] failed to resolve prompt input: ${error2 instanceof Error ? error2.message : String(error2)}`);
|
||||
log.warning(
|
||||
`[post] failed to resolve prompt input: ${error2 instanceof Error ? error2.message : String(error2)}`
|
||||
);
|
||||
}
|
||||
const token = getJobToken();
|
||||
const repoContext = parseRepoContext();
|
||||
const octokit = createOctokit(token);
|
||||
const commentId = await validateStuckProgressComment(promptInput, octokit, repoContext.owner, repoContext.name);
|
||||
if (!commentId)
|
||||
return log.info("\xBB [post] no stuck progress comment to update, skipping cleanup");
|
||||
const commentId = await validateStuckProgressComment(
|
||||
promptInput,
|
||||
octokit,
|
||||
repoContext.owner,
|
||||
repoContext.name
|
||||
);
|
||||
if (!commentId) return log.info("\xBB [post] no stuck progress comment to update, skipping cleanup");
|
||||
log.info(`\xBB [post] validated stuck comment: ${commentId}, updating with error message`);
|
||||
try {
|
||||
const body = buildErrorCommentBody({
|
||||
|
||||
@@ -68,8 +68,8 @@ async function validateStuckProgressComment(
|
||||
* While the job is still in_progress, the individual steps may have their conclusions set.
|
||||
*/
|
||||
async function getIsCancelled(params: {
|
||||
repoContext: ReturnType<typeof parseRepoContext>,
|
||||
octokit: ReturnType<typeof createOctokit>,
|
||||
repoContext: ReturnType<typeof parseRepoContext>;
|
||||
octokit: ReturnType<typeof createOctokit>;
|
||||
runIdStr: string;
|
||||
}): Promise<boolean> {
|
||||
try {
|
||||
@@ -85,7 +85,7 @@ async function getIsCancelled(params: {
|
||||
// So we match jobs that START with the job ID
|
||||
const currentJobName = process.env.GITHUB_JOB;
|
||||
const currentJob = currentJobName
|
||||
? jobs.jobs.find(j => j.name === currentJobName || j.name.startsWith(`${currentJobName} (`))
|
||||
? jobs.jobs.find((j) => j.name === currentJobName || j.name.startsWith(`${currentJobName} (`))
|
||||
: jobs.jobs[0]; // fallback to first job
|
||||
|
||||
if (!currentJob) {
|
||||
@@ -97,14 +97,16 @@ async function getIsCancelled(params: {
|
||||
if (currentJob.conclusion === "cancelled") return true; // whole job explicit cancellation
|
||||
|
||||
// but if it's still null, check steps for cancellation:
|
||||
const cancelledStep = currentJob.steps?.find(step => step.conclusion === "cancelled");
|
||||
const cancelledStep = currentJob.steps?.find((step) => step.conclusion === "cancelled");
|
||||
if (cancelledStep) {
|
||||
log.info(`[post] found cancelled step: ${cancelledStep.name}`);
|
||||
return true;
|
||||
}
|
||||
log.info("[post] no cancellation found, assuming failure");
|
||||
} catch (error) {
|
||||
log.warning(`[post] failed to get job status: ${error instanceof Error ? error.message : String(error)}`);
|
||||
log.warning(
|
||||
`[post] failed to get job status: ${error instanceof Error ? error.message : String(error)}`
|
||||
);
|
||||
}
|
||||
return false; // assuming failure
|
||||
}
|
||||
@@ -114,8 +116,7 @@ async function runPostCleanup(): Promise<void> {
|
||||
|
||||
const runIdStr = process.env.GITHUB_RUN_ID;
|
||||
|
||||
if (!runIdStr)
|
||||
return log.info("» [post] no GITHUB_RUN_ID available, skipping cleanup");
|
||||
if (!runIdStr) return log.info("» [post] no GITHUB_RUN_ID available, skipping cleanup");
|
||||
|
||||
// resolve prompt input once and use it for both issue number and comment ID extraction
|
||||
// only use the object form (JSON payload), not plain string prompts
|
||||
@@ -124,7 +125,9 @@ async function runPostCleanup(): Promise<void> {
|
||||
const resolved = resolvePromptInput();
|
||||
if (typeof resolved !== "string") promptInput = resolved;
|
||||
} catch (error) {
|
||||
log.warning(`[post] failed to resolve prompt input: ${error instanceof Error ? error.message : String(error)}`);
|
||||
log.warning(
|
||||
`[post] failed to resolve prompt input: ${error instanceof Error ? error.message : String(error)}`
|
||||
);
|
||||
}
|
||||
|
||||
// get job token for API calls
|
||||
@@ -133,10 +136,14 @@ async function runPostCleanup(): Promise<void> {
|
||||
const octokit = createOctokit(token);
|
||||
|
||||
// validate that progressCommentId from prompt input is stuck on "Leaping into action"
|
||||
const commentId = await validateStuckProgressComment(promptInput, octokit, repoContext.owner, repoContext.name);
|
||||
const commentId = await validateStuckProgressComment(
|
||||
promptInput,
|
||||
octokit,
|
||||
repoContext.owner,
|
||||
repoContext.name
|
||||
);
|
||||
|
||||
if (!commentId)
|
||||
return log.info("» [post] no stuck progress comment to update, skipping cleanup");
|
||||
if (!commentId) return log.info("» [post] no stuck progress comment to update, skipping cleanup");
|
||||
|
||||
log.info(`» [post] validated stuck comment: ${commentId}, updating with error message`);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user