// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0 import { readFileSync } from "node:fs" import { buildRegistry, type ModuleManifest, type Token } from "@conusai-kit/core" import { generateConvex } from "@conusai-kit/data-convex" import { guidesModule } from "@conusai-kit/guides" // kit:guides import { supportModule } from "@conusai-kit/support" // kit:support import { accountDataOf } from "@conusai-kit/tenancy" import { describe, expect, it } from "vitest" import { composedClientModules } from "../apps/web/src/ui/client-module-list.js" import { helpFor } from "../apps/web/src/ui/help.js" import { convexModules } from "../convex/lib/convexModules.mjs" import { agentModule, assistantAppModule } from "../modules/agent/index.js" // kit:agent import { custodyModule } from "../modules/custody.js" import { documentsModule } from "../modules/documents/index.js" // kit:documents import { moduleInclusion, OPTIONAL_MODULE_IDS, validateInclusion } from "../modules/inclusion.js" import { appModules } from "../modules/index.js" import { knowledgeModule } from "../modules/knowledge/index.js" // kit:knowledge import { modulePages } from "../modules/pages.js" describe("fresh module admission", () => { it.runIf(moduleInclusion.everAdopted.length === 0)( "registers no optional procedure, job, permission, page or rights obligation", () => { expect(moduleInclusion).toEqual({ schemaVersion: 1, selected: [], everAdopted: [] }) const config = JSON.parse(readFileSync(new URL("../conusai.json", import.meta.url), "utf8")) expect( config.token.permissions.filter((scope: string) => /^(ocr:|ai:|ai_tools:|knowledge[.:]|guides:|support:)/.test(scope), ), ).toEqual([]) const registry = buildRegistry([...appModules]) expect(appModules.some((m) => OPTIONAL_MODULE_IDS.some((id) => id === m.id) || m.id === "assistant")).toBe(false) expect(Object.keys(modulePages)).toEqual(["notes"]) expect(accountDataOf(registry).some((share) => ["guides", "support", "assistant"].includes(share.key))).toBe( false, ) }, ) it.runIf(moduleInclusion.everAdopted.length === 0)("mounts no optional help section/client", () => { expect( helpFor({ locale: "en" } as never, { title: "Help", sections: "Sections", guides: "Guides", support: "Support" }) .any, ).toBe(false) expect(composedClientModules.modules).toEqual([]) expect(composedClientModules.providers).toEqual([]) expect(composedClientModules.slots).toEqual([]) }) it("refuses unbounded fields, IDs, versions and selected-without-custody", () => { for (const value of [ { schemaVersion: 2, selected: [], everAdopted: [] }, { schemaVersion: 1, selected: ["agent"], everAdopted: [] }, { schemaVersion: 1, selected: [], everAdopted: ["customer"] }, { schemaVersion: 1, selected: [], everAdopted: [], subject: "synthetic" }, ]) expect(() => validateInclusion(value)).toThrow() }) }) describe("retained manifests", () => { it.each([ documentsModule, // kit:documents knowledgeModule, // kit:knowledge agentModule, // kit:agent assistantAppModule, // kit:agent guidesModule, // kit:guides supportModule, // kit:support ])("retains $id schema under its original identity without interactive admission", (original) => { const retained = custodyModule(original) expect(retained.id).toBe(original.id) expect(retained.repositories).toBe(original.repositories) expect(retained.migrations).toBe(original.migrations) for (const key of [ "procedures", "permissions", "collections", "ui", "serviceRequirements", "extensionPoints", ] as const) expect(retained[key]).toBeUndefined() expect((retained.extends ?? []).every((entry) => entry.point.id === "tenancy.account")).toBe(true) }) it("retains exactly the original rights hooks and retention/removal jobs", () => { const withRights: ModuleManifest[] = [ guidesModule, // kit:guides supportModule, // kit:support assistantAppModule, // kit:agent ] for (const manifest of withRights) expect(custodyModule(manifest).extends).toEqual( manifest.extends?.filter((entry) => entry.point.id === "tenancy.account"), ) // kit:agent:begin expect(Object.keys(custodyModule(agentModule).jobs ?? {})).toEqual(["agent.runs.expire"]) expect(Object.keys(custodyModule(assistantAppModule).jobs ?? {})).toEqual(["assistant.conversations.expire"]) const schedules = custodyModule(agentModule).schedules expect(typeof schedules === "function" ? schedules({}) : []).toHaveLength(1) // kit:agent:end // kit:knowledge:begin const retained = custodyModule(knowledgeModule) expect(Object.keys(retained.jobs ?? {})).toEqual(["knowledge.remove"]) expect(retained.events?.subscribes?.map((entry) => entry.event.name)).toEqual([ "files.FileDeleted", "knowledge.documentRemoveRequested", ]) // kit:knowledge:end }) }) it.runIf(moduleInclusion.everAdopted.length === 0)( "does not construct optional provider ports on a fresh web/worker boot", async () => { const { Container } = await import("@conusai-kit/core") const { bindWebPorts } = await import("../apps/web/src/server/ports.js") const { bindModulePorts } = await import("../apps/worker/src/ports.js") const optionalPorts: Token[] = [ (await import("../modules/documents/index.js")).DOCUMENT_OCR, // kit:documents (await import("@conusai-kit/guides")).GUIDES_PLATFORM, // kit:guides (await import("@conusai-kit/support")).SUPPORT_PLATFORM, // kit:support (await import("../modules/knowledge/index.js")).KNOWLEDGE_SEARCH, // kit:knowledge ] const platform = { mode: "fake", deployment: { CONUSAI_API_URL: "http://127.0.0.1:1/api", CONUSAI_API_TOKEN: "synthetic" }, objectStore: {}, audit: {}, usage: {}, } for (const key of ["models", "documents", "model"]) Object.defineProperty(platform, key, { get: () => { throw new Error("optional provider constructed at boot") }, }) const registry = buildRegistry([...appModules]) for (const bind of [bindWebPorts, bindModulePorts]) { const container = new Container() bind(container, platform as never, registry) for (const token of optionalPorts) expect(container.has(token)).toBe(false) } }, ) describe("committed Convex projection", () => { const root = new URL("..", import.meta.url) it("commits generated wrappers that forward explicit idempotency keys to the kernel", () => { // The same profile filter as below: the Postgres-only modules are not Convex-deployed yet. const convexBound = appModules.filter( (module) => module.profiles === undefined || module.profiles.includes("convex"), ) const registry = buildRegistry([...convexModules(convexBound)]) const generated = generateConvex(registry, { header: "// SPDX-License-Identifier: LicenseRef-ConusAI-Template-1.0\n", }) for (const file of generated) { expect(readFileSync(new URL(`convex/${file.path}`, root), "utf8"), file.path).toBe(file.content) } const proposal = generated.find(({ path }) => path === "generated/proposals.ts") expect(proposal?.content).toContain( 'ctx.run("proposals.proposal.create", input, idempotencyKey === undefined ? undefined : { idempotencyKey })', ) }) })