mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-18 21:00:49 +00:00
Rename Foundry handoffs to tasks (#239)
* Restore foundry onboarding stack * Consolidate foundry rename * Create foundry tasks without prompts * Rename Foundry handoffs to tasks
This commit is contained in:
parent
d30cc0bcc8
commit
d75e8c31d1
281 changed files with 9242 additions and 4356 deletions
122
foundry/packages/backend/src/services/create-flow.ts
Normal file
122
foundry/packages/backend/src/services/create-flow.ts
Normal file
|
|
@ -0,0 +1,122 @@
|
|||
export interface ResolveCreateFlowDecisionInput {
|
||||
task: string;
|
||||
explicitTitle?: string;
|
||||
explicitBranchName?: string;
|
||||
localBranches: string[];
|
||||
taskBranches: string[];
|
||||
}
|
||||
|
||||
export interface ResolveCreateFlowDecisionResult {
|
||||
title: string;
|
||||
branchName: string;
|
||||
}
|
||||
|
||||
function firstNonEmptyLine(input: string): string {
|
||||
const lines = input
|
||||
.split(/\r?\n/)
|
||||
.map((line) => line.trim())
|
||||
.filter((line) => line.length > 0);
|
||||
return lines[0] ?? "";
|
||||
}
|
||||
|
||||
export function deriveFallbackTitle(task: string, explicitTitle?: string): string {
|
||||
const source = (explicitTitle && explicitTitle.trim()) || firstNonEmptyLine(task) || "update task";
|
||||
const explicitPrefixMatch = source.match(/^\s*(feat|fix|docs|refactor):\s+(.+)$/i);
|
||||
if (explicitPrefixMatch) {
|
||||
const explicitTypePrefix = explicitPrefixMatch[1]!.toLowerCase();
|
||||
const explicitSummary = explicitPrefixMatch[2]!
|
||||
.split("")
|
||||
.map((char) => (/^[a-zA-Z0-9 -]$/.test(char) ? char : " "))
|
||||
.join("")
|
||||
.split(/\s+/)
|
||||
.filter((token) => token.length > 0)
|
||||
.join(" ")
|
||||
.slice(0, 62)
|
||||
.trim();
|
||||
|
||||
return `${explicitTypePrefix}: ${explicitSummary || "update task"}`;
|
||||
}
|
||||
|
||||
const lowered = source.toLowerCase();
|
||||
|
||||
const typePrefix =
|
||||
lowered.includes("fix") || lowered.includes("bug")
|
||||
? "fix"
|
||||
: lowered.includes("doc") || lowered.includes("readme")
|
||||
? "docs"
|
||||
: lowered.includes("refactor")
|
||||
? "refactor"
|
||||
: "feat";
|
||||
|
||||
const cleaned = source
|
||||
.split("")
|
||||
.map((char) => (/^[a-zA-Z0-9 -]$/.test(char) ? char : " "))
|
||||
.join("")
|
||||
.split(/\s+/)
|
||||
.filter((token) => token.length > 0)
|
||||
.join(" ");
|
||||
|
||||
const summary = (cleaned || "update task").slice(0, 62).trim();
|
||||
return `${typePrefix}: ${summary}`.trim();
|
||||
}
|
||||
|
||||
export function sanitizeBranchName(input: string): string {
|
||||
const normalized = input
|
||||
.toLowerCase()
|
||||
.split("")
|
||||
.map((char) => (/^[a-z0-9]$/.test(char) ? char : "-"))
|
||||
.join("");
|
||||
|
||||
let result = "";
|
||||
let previousDash = false;
|
||||
for (const char of normalized) {
|
||||
if (char === "-") {
|
||||
if (!previousDash && result.length > 0) {
|
||||
result += char;
|
||||
}
|
||||
previousDash = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
result += char;
|
||||
previousDash = false;
|
||||
}
|
||||
|
||||
const trimmed = result.replace(/-+$/g, "");
|
||||
if (trimmed.length <= 50) {
|
||||
return trimmed;
|
||||
}
|
||||
return trimmed.slice(0, 50).replace(/-+$/g, "");
|
||||
}
|
||||
|
||||
export function resolveCreateFlowDecision(input: ResolveCreateFlowDecisionInput): ResolveCreateFlowDecisionResult {
|
||||
const explicitBranch = input.explicitBranchName?.trim();
|
||||
const title = deriveFallbackTitle(input.task, input.explicitTitle);
|
||||
const generatedBase = sanitizeBranchName(title) || "task";
|
||||
|
||||
const branchBase = explicitBranch && explicitBranch.length > 0 ? explicitBranch : generatedBase;
|
||||
|
||||
const existingBranches = new Set(input.localBranches.map((value) => value.trim()).filter((value) => value.length > 0));
|
||||
const existingTaskBranches = new Set(input.taskBranches.map((value) => value.trim()).filter((value) => value.length > 0));
|
||||
const conflicts = (name: string): boolean => existingBranches.has(name) || existingTaskBranches.has(name);
|
||||
|
||||
if (explicitBranch && conflicts(branchBase)) {
|
||||
throw new Error(`Branch '${branchBase}' already exists. Choose a different --name/--branch value.`);
|
||||
}
|
||||
|
||||
if (explicitBranch) {
|
||||
return { title, branchName: branchBase };
|
||||
}
|
||||
|
||||
let candidate = branchBase;
|
||||
let index = 2;
|
||||
while (conflicts(candidate)) {
|
||||
candidate = `${branchBase}-${index}`;
|
||||
index += 1;
|
||||
}
|
||||
|
||||
return {
|
||||
title,
|
||||
branchName: candidate,
|
||||
};
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue