import { describe, test } from 'node:test'; import assert from 'node:assert/strict'; import { execFileSync } from 'node:child_process'; import { mkdtempSync, rmSync, existsSync } from 'node:fs'; import { join, dirname } from 'node:path'; import { tmpdir } from 'node:os'; import { fileURLToPath } from 'node:url'; // M0-9: REMEMBER.md must materialize under the EXTERNAL data root (getDataRoot()), // not inside the plugin tree (the old anti-pattern wrote join(PLUGIN_ROOT, // 'REMEMBER.md')). session-start is a procedural hook with no exports, so we run // it as a subprocess with an isolated HOME + LINKEDIN_STUDIO_DATA and check where // REMEMBER.md lands. Pattern: user-prompt-context.test.mjs subprocess harness. const hookPath = join(dirname(fileURLToPath(import.meta.url)), '..', 'session-start.mjs'); describe('session-start — REMEMBER.md materializes external (M0-9)', () => { test('REMEMBER.md is created under the external data root, not the plugin tree', () => { const home = mkdtempSync(join(tmpdir(), 'lis-ss-home-')); const dataDir = mkdtempSync(join(tmpdir(), 'lis-ss-data-')); try { execFileSync('node', [hookPath], { input: '', env: { ...process.env, HOME: home, USERPROFILE: home, LINKEDIN_STUDIO_DATA: dataDir }, encoding: 'utf-8', }); assert.ok( existsSync(join(dataDir, 'REMEMBER.md')), 'REMEMBER.md must be created under the external data root', ); } finally { rmSync(home, { recursive: true, force: true }); rmSync(dataDir, { recursive: true, force: true }); } }); });