mirror of
https://github.com/harivansh-afk/sandbox-agent.git
synced 2026-04-19 00:25:23 +00:00
Integrate OpenHandoff factory workspace (#212)
This commit is contained in:
parent
3d9476ed0b
commit
bf282199b5
251 changed files with 42824 additions and 692 deletions
128
factory/packages/backend/src/services/create-flow.ts
Normal file
128
factory/packages/backend/src/services/create-flow.ts
Normal file
|
|
@ -0,0 +1,128 @@
|
|||
export interface ResolveCreateFlowDecisionInput {
|
||||
task: string;
|
||||
explicitTitle?: string;
|
||||
explicitBranchName?: string;
|
||||
localBranches: string[];
|
||||
handoffBranches: 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 handoff";
|
||||
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 handoff"}`;
|
||||
}
|
||||
|
||||
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 handoff").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) || "handoff";
|
||||
|
||||
const branchBase = explicitBranch && explicitBranch.length > 0 ? explicitBranch : generatedBase;
|
||||
|
||||
const existingBranches = new Set(input.localBranches.map((value) => value.trim()).filter((value) => value.length > 0));
|
||||
const existingHandoffBranches = new Set(
|
||||
input.handoffBranches.map((value) => value.trim()).filter((value) => value.length > 0)
|
||||
);
|
||||
const conflicts = (name: string): boolean =>
|
||||
existingBranches.has(name) || existingHandoffBranches.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