@brianlovin/notion-skills
Version:
Sync agent skills from a Notion database to Claude Code, Codex, OpenCode, Cursor, Gemini CLI.
80 lines • 2.54 kB
JavaScript
import { mkdir, readFile, writeFile, rm } from "node:fs/promises";
import { dirname } from "node:path";
import { SCOPE_FILE } from "./paths.js";
import { deriveKey, sanitiseSources } from "./sources.js";
function isV2(raw) {
return raw.version === 2 && Array.isArray(raw.sources);
}
/**
* Promote a v1 scope into v2 by wrapping its single database into a
* source. The key is derived from the database title; the source is
* marked default since it's the only one. The migration is in-memory —
* the on-disk file isn't rewritten until the next save (so a read-only
* inspection like `list` doesn't mutate state behind the user's back).
*/
export function migrateV1ToV2(v1) {
const title = v1.database_title ?? "Skills Store";
const key = deriveKey(title, new Set());
const source = {
key,
name: title,
database_id: v1.database_id,
data_source_id: v1.data_source_id,
default: true,
added_at: new Date().toISOString(),
};
return {
version: 2,
sources: [source],
targets: v1.targets ?? [],
gen_agent: v1.gen_agent,
};
}
/**
* Load the active scope from `~/.notion-skills/scope.json`. Returns
* null if the file doesn't exist (notion-skills hasn't been initialised
* yet). Auto-migrates v1 in memory; calls to `writeScope` persist the
* migration on next write.
*/
export async function getScope() {
const raw = await readJson(SCOPE_FILE);
if (!raw)
return null;
const v2 = isV2(raw) ? raw : migrateV1ToV2(raw);
return {
version: 2,
sources: sanitiseSources(v2.sources),
targets: v2.targets ?? [],
gen_agent: v2.gen_agent,
path: SCOPE_FILE,
};
}
export async function writeScope(scope) {
const payload = {
version: 2,
sources: sanitiseSources(scope.sources),
targets: scope.targets,
gen_agent: scope.gen_agent,
};
await writeJson(SCOPE_FILE, payload);
}
export async function deleteScope() {
await rm(SCOPE_FILE, { force: true });
}
// ---------- helpers ----------
async function readJson(file) {
try {
const raw = await readFile(file, "utf8");
return JSON.parse(raw);
}
catch (err) {
if (err.code === "ENOENT")
return null;
throw err;
}
}
async function writeJson(file, value) {
await mkdir(dirname(file), { recursive: true });
await writeFile(file, JSON.stringify(value, null, 2) + "\n", "utf8");
}
//# sourceMappingURL=scope.js.map