import assert from 'node:assert/strict'; import fs from 'node:fs'; import path from 'node:path'; const root = path.resolve(new URL('..', import.meta.url).pathname); function read(relativePath) { const absolutePath = path.join(root, relativePath); assert.ok(fs.existsSync(absolutePath), `missing guarded file: ${relativePath}`); return fs.readFileSync(absolutePath, 'utf8'); } function assertIncludes(source, snippet, label) { assert.ok(source.includes(snippet), `${label} must include guarded snippet: ${snippet}`); } function assertExcludes(source, snippet, label) { assert.ok(!source.includes(snippet), `${label} must not regress to: ${snippet}`); } const useTKMindChat = read('src/hooks/useTKMindChat.ts'); assertIncludes(useTKMindChat, 'FINISH_SYNC_RETRY_DELAYS_MS', 'useTKMindChat.ts'); assertIncludes( useTKMindChat, 'mergeConversationSnapshot(localMessages, detail.messages)', 'useTKMindChat.ts', ); assertIncludes(useTKMindChat, 'chat-finish-sync.mjs', 'useTKMindChat.ts'); assertExcludes( useTKMindChat, 'messagesRef.current = detail.messages;\n messageHistoryLoadedCountRef.current = detail.messages.length', 'useTKMindChat.ts Finish sync', ); const messageTs = read('src/utils/message.ts'); assertIncludes(messageTs, 'deriveUserFacingText', 'message.ts'); assertIncludes(messageTs, 'deriveAssistantFacingText', 'message.ts'); assertIncludes(messageTs, 'chat-finish-sync.mjs', 'message.ts'); const conversationDisplay = read('conversation-display.mjs'); assertIncludes(conversationDisplay, 'TASK_ROUTING_HINT_RE', 'conversation-display.mjs'); assertIncludes(conversationDisplay, 'deriveUserFacingText', 'conversation-display.mjs'); assertIncludes(conversationDisplay, 'deriveAssistantFacingText', 'conversation-display.mjs'); const chatSkills = read('chat-skills.mjs'); assertIncludes(chatSkills, 'stripKnownChatSkillPrompt', 'chat-skills.mjs'); const server = read('server.mjs'); assertIncludes(server, 'canUseSnapshotCache', 'server.mjs'); assertIncludes(server, 'hintMc != null && hintUa != null', 'server.mjs'); const publicFinishSync = read('mindspace-public-finish-sync.mjs'); assertIncludes(publicFinishSync, 'applyPublicHtmlEdit', 'mindspace-public-finish-sync.mjs'); assertIncludes(publicFinishSync, 'isEditLikeHtmlTool', 'mindspace-public-finish-sync.mjs'); console.log('chat finish sync source guards ok');