openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
115 lines (114 loc) • 4.99 kB
JavaScript
import { Et as array, Rn as string, Tn as object, wn as number, yt as _enum } from "./schemas-zxit8y5H.js";
import { a as sha256Hex } from "./crypto-digest-C4hqTb_e.js";
import { a as updateConfigMachineState, r as readConfigMachineState, t as deleteConfigMachineState } from "./config-machine-state-BCereLZr.js";
import { i as resolveWorkspaceStateIdentity } from "./workspace-state-identity-UVKTnO1Z.js";
//#region src/state/onboarding-recommendations.ts
const OnboardingRecommendationMatchSchema = object({
appLabel: string(),
candidateId: string(),
tier: _enum(["recommended", "optional"]),
reason: string(),
candidate: object({
id: string(),
displayName: string(),
summary: string(),
source: _enum([
"official-plugin",
"official-channel",
"official-provider",
"clawhub-skill"
]),
downloads: number().optional()
})
});
const OnboardingRecommendationMatchesSchema = array(OnboardingRecommendationMatchSchema);
function canonicalInventory(inventory) {
return inventory.map((app) => ({
label: app.label,
...app.bundleId ? { bundleId: app.bundleId } : {}
})).toSorted((left, right) => left.label.localeCompare(right.label, "en", { sensitivity: "base" }) || (left.bundleId ?? "").localeCompare(right.bundleId ?? ""));
}
function hashOnboardingRecommendationInventory(inventory) {
return sha256Hex(JSON.stringify(canonicalInventory(inventory)));
}
function readOnboardingRecommendations(configKey, options = {}) {
const record = readConfigMachineState(configKey, options);
return record ? {
...record,
matches: OnboardingRecommendationMatchesSchema.parse(record.matches)
} : null;
}
function matchesExpectedOnboardingRecommendations(current, expected) {
return current.inventoryHash === expected.inventoryHash && JSON.stringify(current.matches) === JSON.stringify(expected.matches) && current.offeredAt === expected.offeredAt && current.acceptedAt === expected.acceptedAt && current.updatedAt === expected.updatedAt;
}
function writeOnboardingRecommendationsOffer(configKey, params, databaseOptions = {}) {
const nowMs = params.nowMs ?? Date.now();
const inventoryHash = hashOnboardingRecommendationInventory(params.inventory);
const matches = OnboardingRecommendationMatchesSchema.parse(params.matches);
const acceptedAt = params.answered ? nowMs : null;
return updateConfigMachineState(configKey, (existing) => {
if (typeof existing?.acceptedAt === "number") return existing;
return {
inventoryHash,
matches,
offeredAt: nowMs,
acceptedAt,
updatedAt: nowMs
};
}, databaseOptions);
}
function acknowledgeOnboardingRecommendations(configKey, params = {}, databaseOptions = {}) {
const nowMs = params.nowMs ?? Date.now();
let acknowledged = null;
updateConfigMachineState(configKey, (existing) => {
if (!existing) return;
if (params.expected && !matchesExpectedOnboardingRecommendations(existing, params.expected)) return existing;
acknowledged = typeof existing.acceptedAt === "number" ? existing : {
...existing,
acceptedAt: nowMs,
updatedAt: nowMs
};
return acknowledged;
}, databaseOptions);
return acknowledged;
}
function updatePendingOnboardingRecommendations(configKey, params, databaseOptions = {}) {
const nowMs = params.nowMs ?? Date.now();
const matches = OnboardingRecommendationMatchesSchema.parse(params.matches);
let updated = null;
updateConfigMachineState(configKey, (existing) => {
if (!existing || typeof existing.acceptedAt === "number" || !matchesExpectedOnboardingRecommendations(existing, params.expected)) return existing;
updated = {
...existing,
matches,
updatedAt: nowMs
};
return updated;
}, databaseOptions);
return updated;
}
function clearPendingOnboardingRecommendations(configKey, params, databaseOptions = {}) {
let cleared = false;
updateConfigMachineState(configKey, (existing) => {
if (!existing || existing.acceptedAt !== null || !matchesExpectedOnboardingRecommendations(existing, params.expected)) return existing;
cleared = true;
}, databaseOptions);
return cleared;
}
function clearOnboardingRecommendations(configKey, databaseOptions = {}) {
return deleteConfigMachineState(configKey, databaseOptions);
}
function createOnboardingRecommendationsStore(params) {
const configKey = `onboarding.recommendations.${resolveWorkspaceStateIdentity(params.workspaceDir).workspaceKey}`;
const database = params.database ?? {};
return {
read: () => readOnboardingRecommendations(configKey, database),
writeOffer: (offer) => writeOnboardingRecommendationsOffer(configKey, offer, database),
acknowledge: (options) => acknowledgeOnboardingRecommendations(configKey, options, database),
updatePending: (options) => updatePendingOnboardingRecommendations(configKey, options, database),
clearPending: (options) => clearPendingOnboardingRecommendations(configKey, options, database),
clear: () => clearOnboardingRecommendations(configKey, database)
};
}
//#endregion
export { createOnboardingRecommendationsStore as t };