Improve schema setup and Notion ingest UX

This commit is contained in:
Luca Martial 2026-05-11 12:34:33 -07:00
parent 155613c794
commit 72a4ace13c
21 changed files with 540 additions and 118 deletions

View file

@ -100,6 +100,50 @@ describe('WikiWriteTool', () => {
expect(result.markdown).toMatch(/content.*or.*replacements/i);
});
it('updates frontmatter only on an existing page while preserving content', async () => {
const { tool, wikiService } = makeTool({
wikiService: {
readPage: vi.fn().mockResolvedValue({
pageKey: 'orbit-customers',
frontmatter: {
summary: 'Customer source details',
usage_mode: 'auto',
sort_order: 0,
tags: ['notion'],
refs: ['notion:old'],
sl_refs: ['postgres-warehouse/orbit_analytics.customer'],
},
content: '# Orbit Customers\n\nSource: Notion - Orbit Customers Source.',
}),
},
});
const result = await tool.call(
{
key: 'orbit-customers',
summary: 'Customer source details mapped to the warehouse customer view',
sl_refs: ['postgres-warehouse/orbit_analytics.customer', 'dbt-main/customer'],
} as any,
baseContext,
);
expect(result.structured).toEqual({ success: true, key: 'orbit-customers', action: 'updated' });
expect(wikiService.writePage).toHaveBeenCalledWith(
'USER',
'u',
'orbit-customers',
expect.objectContaining({
summary: 'Customer source details mapped to the warehouse customer view',
tags: ['notion'],
refs: ['notion:old'],
sl_refs: ['postgres-warehouse/orbit_analytics.customer', 'dbt-main/customer'],
}),
'# Orbit Customers\n\nSource: Notion - Orbit Customers Source.',
expect.any(String),
expect.any(String),
);
});
it('writes historic-SQL frontmatter fields', async () => {
const { tool, wikiService } = makeTool();

View file

@ -77,6 +77,7 @@ export class WikiWriteTool extends BaseTool<typeof wikiWriteInputSchema> {
get description(): string {
return `<purpose>
Create or update a knowledge page. Provide content for create/rewrite, or replacements for targeted edits.
For existing pages, you may provide only frontmatter fields such as summary, tags, refs, or sl_refs to update metadata while preserving content.
tags/refs/sl_refs use REPLACE semantics: omit to keep existing on update, [] to clear, [values] to set.
</purpose>`;
}
@ -90,17 +91,20 @@ tags/refs/sl_refs use REPLACE semantics: omit to keep existing on update, [] to
const writesGlobal = !!context.session;
const skipIndex = context.session?.isWorktreeScoped === true;
if (!input.content && (!input.replacements || input.replacements.length === 0)) {
const scope: BlockScope = writesGlobal ? 'GLOBAL' : 'USER';
const scopeId = scope === 'USER' ? context.userId : null;
const existing = await wikiService.readPage(scope, scopeId, input.key);
const content = input.content;
const hasContent = typeof content === 'string' && content.length > 0;
const hasReplacements = !!input.replacements && input.replacements.length > 0;
if (!existing && !hasContent && !hasReplacements) {
return {
markdown: 'Error: provide either content (for create/rewrite) or replacements (for edits).',
structured: { success: false, key: input.key },
};
}
const scope: BlockScope = writesGlobal ? 'GLOBAL' : 'USER';
const scopeId = scope === 'USER' ? context.userId : null;
const existing = await wikiService.readPage(scope, scopeId, input.key);
if (!existing && !input.content) {
return {
markdown: `Page "${input.key}" does not exist. Provide content to create it.`,
@ -140,9 +144,9 @@ tags/refs/sl_refs use REPLACE semantics: omit to keep existing on update, [] to
fingerprints: input.fingerprints === undefined ? existingFm?.fingerprints : input.fingerprints,
};
if (input.content) {
finalContent = normalizeAccidentalEscapedMarkdownNewlines(input.content);
} else {
if (hasContent) {
finalContent = normalizeAccidentalEscapedMarkdownNewlines(content);
} else if (hasReplacements) {
const editResult = applySqlEdits(existing?.content ?? '', input.replacements ?? []);
if (!editResult.success) {
return {
@ -151,6 +155,8 @@ tags/refs/sl_refs use REPLACE semantics: omit to keep existing on update, [] to
};
}
finalContent = editResult.sql;
} else {
finalContent = existing?.content ?? '';
}
await wikiService.writePage(scope, scopeId, input.key, finalFm, finalContent, SYSTEM_AUTHOR, SYSTEM_EMAIL);