openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
107 lines (106 loc) • 5.7 kB
JavaScript
import { i as getNodeSqliteKysely, n as executeSqliteQuerySync, r as executeSqliteQueryTakeFirstSync } from "./kysely-sync-BMSZn9yz.mjs";
import { t as createOpenClawStateSchemaEnsurer } from "./openclaw-state-feature-schema-Dx40P1CC.mjs";
//#region src/agents/worktrees/name.ts
const WORKTREE_NAME_MAX_LENGTH = 64;
/** Converts a short human-readable title into a valid managed-worktree name. */
function slugifyWorktreeTitle(title) {
const slug = title.normalize("NFKD").replace(/\p{M}/gu, "").toLowerCase().replace(/&/g, " and ").replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
if (slug.length <= WORKTREE_NAME_MAX_LENGTH) return slug || void 0;
const truncated = slug.slice(0, WORKTREE_NAME_MAX_LENGTH);
const wordBoundary = truncated.lastIndexOf("-");
return wordBoundary > 0 ? truncated.slice(0, wordBoundary) : truncated;
}
//#endregion
//#region src/projects/project-registry.kernel.ts
const PROJECT_ID_MAX_LENGTH = 64;
const ensureProjectRegistrySchema = createOpenClawStateSchemaEnsurer({
table: "projects",
operationLabel: "projects.registry.schema.ensure"
});
function rowToProject(row) {
return {
id: row.id,
displayName: row.display_name,
repoRoot: row.repo_root,
...row.origin_url ? { originUrl: row.origin_url } : {},
source: row.source
};
}
function allocateProjectId(base, existing) {
if (!existing.has(base)) return base;
for (let suffixNumber = 2;; suffixNumber += 1) {
const suffix = `-${suffixNumber}`;
const candidate = `${base.slice(0, PROJECT_ID_MAX_LENGTH - suffix.length).replace(/-+$/u, "")}${suffix}`;
if (!existing.has(candidate)) return candidate;
}
}
function insertProjectRegistryInDatabase(database, input) {
const db = getNodeSqliteKysely(database);
const sameRoot = executeSqliteQueryTakeFirstSync(database, db.selectFrom("projects").selectAll().where("repo_root", "=", input.repoRoot));
if (sameRoot) return rowToProject(sameRoot);
if (input.source === "cloned" && input.originUrl) {
const duplicate = executeSqliteQueryTakeFirstSync(database, db.selectFrom("projects").selectAll().where("origin_url", "=", input.originUrl));
if (duplicate) return rowToProject(duplicate);
}
const existing = new Set(executeSqliteQuerySync(database, db.selectFrom("projects").select("id")).rows.map((row) => row.id));
const id = allocateProjectId(slugifyWorktreeTitle(input.displayName) ?? "project", existing);
const now = Date.now();
const row = {
id,
display_name: input.displayName,
repo_root: input.repoRoot,
origin_url: input.originUrl ?? null,
source: input.source,
created_at_ms: now,
updated_at_ms: now
};
executeSqliteQuerySync(database, db.insertInto("projects").values(row));
return rowToProject(row);
}
function listProjectRegistryInDatabase(database) {
const db = getNodeSqliteKysely(database);
return executeSqliteQuerySync(database, db.selectFrom("projects").selectAll()).rows.map(rowToProject);
}
function resolveProjectRegistryInDatabase(database, id) {
const db = getNodeSqliteKysely(database);
const row = executeSqliteQueryTakeFirstSync(database, db.selectFrom("projects").selectAll().where("id", "=", id));
return row ? rowToProject(row) : void 0;
}
function resolveRecordedProjectRootInDatabase(database, repoRoot) {
const db = getNodeSqliteKysely(database);
return executeSqliteQueryTakeFirstSync(database, db.selectFrom("projects").select("repo_root").where("repo_root", "=", repoRoot))?.repo_root;
}
function matchesProjectRecord(row, project) {
return row.id === project.id && row.repo_root === project.repoRoot && row.source === project.source && (row.origin_url ?? void 0) === project.originUrl;
}
function readMatchingProjectRow(database, project) {
const db = getNodeSqliteKysely(database);
const row = executeSqliteQueryTakeFirstSync(database, db.selectFrom("projects").selectAll().where("id", "=", project.id));
return row && matchesProjectRecord(row, project) ? row : void 0;
}
function resolveProjectCloneRefreshOwnerInDatabase(database, project) {
const current = readMatchingProjectRow(database, project);
return current?.source === "cloned" ? rowToProject(current) : void 0;
}
function removeProjectRegistryInDatabase(database, project) {
if (!readMatchingProjectRow(database, project)) return false;
const db = getNodeSqliteKysely(database);
return executeSqliteQuerySync(database, db.deleteFrom("projects").where("id", "=", project.id)).numAffectedRows === 1n;
}
function removeProjectCheckoutReferenceInDatabase(database, project) {
const db = getNodeSqliteKysely(database);
const current = executeSqliteQueryTakeFirstSync(database, db.selectFrom("projects").selectAll().where("id", "=", project.id));
if (!current) return "missing";
if (current.source !== "cloned" || current.repo_root !== project.repoRoot) return "changed";
executeSqliteQuerySync(database, db.deleteFrom("projects").where("id", "=", project.id));
const sibling = executeSqliteQueryTakeFirstSync(database, db.selectFrom("projects").selectAll().where("repo_root", "=", project.repoRoot).orderBy("id", "asc"));
if (!sibling) return "final";
if (sibling.source === "registered") executeSqliteQuerySync(database, db.updateTable("projects").set({
source: "cloned",
origin_url: sibling.origin_url ?? current.origin_url,
updated_at_ms: Date.now()
}).where("id", "=", sibling.id));
return "remaining";
}
//#endregion
export { removeProjectRegistryInDatabase as a, resolveRecordedProjectRootInDatabase as c, removeProjectCheckoutReferenceInDatabase as i, slugifyWorktreeTitle as l, insertProjectRegistryInDatabase as n, resolveProjectCloneRefreshOwnerInDatabase as o, listProjectRegistryInDatabase as r, resolveProjectRegistryInDatabase as s, ensureProjectRegistrySchema as t };