diff --git a/packages/plugins/plugin-llm-wiki/src/templates.ts b/packages/plugins/plugin-llm-wiki/src/templates.ts index d22917c8f5f..8526b501475 100644 --- a/packages/plugins/plugin-llm-wiki/src/templates.ts +++ b/packages/plugins/plugin-llm-wiki/src/templates.ts @@ -5,6 +5,7 @@ export const REQUIRED_WIKI_DIRECTORIES = [ "wiki", "wiki/sources", "wiki/projects", + "wiki/areas", "wiki/entities", "wiki/concepts", "wiki/synthesis", @@ -57,6 +58,7 @@ export const BOOTSTRAP_FILES: ReadonlyArray<{ path: string; contents: string }> { path: "raw/.gitkeep", contents: "" }, { path: "wiki/sources/.gitkeep", contents: "" }, { path: "wiki/projects/.gitkeep", contents: "" }, + { path: "wiki/areas/.gitkeep", contents: "" }, { path: "wiki/entities/.gitkeep", contents: "" }, { path: "wiki/concepts/.gitkeep", contents: "" }, { path: "wiki/synthesis/.gitkeep", contents: "" }, diff --git a/packages/plugins/plugin-llm-wiki/src/wiki.ts b/packages/plugins/plugin-llm-wiki/src/wiki.ts index 1a7ee94c798..5601c0ad57c 100644 --- a/packages/plugins/plugin-llm-wiki/src/wiki.ts +++ b/packages/plugins/plugin-llm-wiki/src/wiki.ts @@ -1745,6 +1745,7 @@ export async function createPaperclipDistillationWorkItem(ctx: PluginContext, in const wikiId = normalizeWikiId(input.wikiId); const itemId = randomUUID(); const scope = paperclipCursorScopeMetadata(input); + const idempotencyKey = input.idempotencyKey ?? `${input.kind}:${scope.sourceScope}:${scope.scopeKey}`; if (input.kind === "backfill" && !scope.projectId && !scope.rootIssueId) { throw new Error("Backfill work items must target a projectId or rootIssueId; whole-company backfill is not allowed."); } @@ -1765,7 +1766,7 @@ export async function createPaperclipDistillationWorkItem(ctx: PluginContext, in scope.projectId, scope.rootIssueId, input.requestedByIssueId ?? null, - input.idempotencyKey ?? null, + idempotencyKey, jsonParam({ sourceScope: scope.sourceScope, ...(input.metadata ?? {}), diff --git a/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts b/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts index fef8cb2e676..b588bdf61d2 100644 --- a/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts +++ b/packages/plugins/plugin-llm-wiki/tests/plugin.spec.ts @@ -1434,13 +1434,19 @@ Route sidebar state stays attached to the selected wiki page. metadata: { window: "last-30-days" }, idempotencyKey: "backfill:last-30-days", }); + await harness.performAction("create-paperclip-distillation-work-item", { + companyId: COMPANY_ID, + kind: "manual", + projectId: "77777777-7777-4777-8777-777777777780", + }); const workItemWrites = harness.dbExecutes.filter((execute) => execute.sql.includes("paperclip_distillation_work_items")); - expect(workItemWrites).toHaveLength(3); - expect(workItemWrites.map((write) => write.params?.[3])).toEqual(["manual", "retry", "backfill"]); + expect(workItemWrites).toHaveLength(4); + expect(workItemWrites.map((write) => write.params?.[3])).toEqual(["manual", "retry", "backfill", "manual"]); expect(String(workItemWrites[0].params?.[9])).toContain('"sourceScope":"project"'); expect(String(workItemWrites[1].params?.[9])).toContain('"sourceScope":"root_issue"'); expect(String(workItemWrites[2].params?.[9])).toContain('"sourceScope":"project"'); + expect(workItemWrites[3].params?.[8]).toBe("manual:project:77777777-7777-4777-8777-777777777780"); await expect(harness.performAction("create-paperclip-distillation-work-item", { companyId: COMPANY_ID, @@ -1939,6 +1945,7 @@ Route sidebar state stays attached to the selected wiki page. "raw/.gitkeep", "wiki/sources/.gitkeep", "wiki/projects/.gitkeep", + "wiki/areas/.gitkeep", "wiki/entities/.gitkeep", "wiki/concepts/.gitkeep", "wiki/synthesis/.gitkeep",