Files
Mert Koseoglu 6262c13283 fix(memory): adapter-aware persistent memory across all 14 platforms
v1.0.100's "Unified Persistent Memory" feature was Claude-centric.
Auto-memory, prior session, and persist memory all hardcoded ~/.claude/,
breaking 13 of 14 platforms. Plus a worktree filename mismatch broke
Claude Code too on worktree sessions.

Architectural fix: adds 3 methods to HookAdapter interface so every
adapter declares its own conventions:
  - getConfigDir()        — ~/.claude, ~/.codex, ~/.qwen, ~/.gemini, etc.
  - getInstructionFiles() — ['CLAUDE.md'], ['AGENTS.md'], ['QWEN.md'], etc.
  - getMemoryDir()        — ~/.claude/memory, ~/.codex/memories, etc.

BaseAdapter ships sensible defaults derived from sessionDirSegments;
only the 11 non-Claude adapters override (Claude inherits).

Wiring changes:
  - searchAutoMemory() now accepts an adapter, dispatches via methods
  - ctx_search timeline uses _detectedAdapter.getConfigDir()
  - ctx_search timeline SessionDB filename now includes worktree suffix
    (matches what session-snapshot/session-extract write to)
  - extract.ts rule detection covers AGENTS.md, GEMINI.md, QWEN.md,
    KIRO.md, copilot-instructions.md, context-mode.mdc, and any
    *.md inside a memory/memories directory

Bonus fixes (from PR #376):
  - OpenCode/KiloCode cache path: now packages/context-mode@latest/
    layout (silently changed by upstream late 2024 — broke doctor/upgrade)
  - OpenCode SessionStart equivalent via experimental.chat.messages.transform
    — prior-session continuity now works on OpenCode/KiloCode

Tests added (8 new files, 65 new tests, all green):
  - tests/adapters/base-adapter-memory.test.ts        (4)
  - tests/adapters/claude-code-memory.test.ts          (3)
  - tests/adapters/memory-conventions.test.ts         (36)
  - tests/core/auto-memory-adapter.test.ts             (5)
  - tests/core/cache-plugin-root.test.ts               (2)
  - tests/core/server-timeline-adapter.test.ts         (3)
  - tests/opencode-session-start.test.ts               (2)
  - tests/session/extract-rule-detection.test.ts      (10)

Closes architectural root cause of #367 follow-ups.
Supersedes #379 (Codex), #370 (Qwen), #376 (OpenCode/KiloCode portions).

Co-Authored-By: Marcus Neufeldt <MarcusNeufeldt@users.noreply.github.com>
Co-Authored-By: btxbtxbtx <btxbtxbtx@users.noreply.github.com>
Co-Authored-By: Mickey Lazarevic <mikij@users.noreply.github.com>
2026-05-02 18:29:09 +03:00

34 lines
1.4 KiB
TypeScript

import "../setup-home";
import { describe, it, expect } from "vitest";
import { readFileSync } from "node:fs";
import { resolve } from "node:path";
/**
* Slice 7 — OpenCode/KiloCode silently changed where they store npm
* plugins (now `packages/context-mode@latest/node_modules/context-mode`).
* The old `node_modules/context-mode` path no longer exists, so doctor
* + upgrade reported false negatives.
*
* Static guard against regression of the published path layout.
* (Per PR #376.)
*/
const CLI_SRC = readFileSync(resolve(__dirname, "../../src/cli.ts"), "utf-8");
describe("cachePluginRoot — OpenCode/KiloCode 2025+ layout", () => {
it("uses the new packages/context-mode@latest layout on POSIX", () => {
// The string `context-mode@latest` should appear in cli.ts (was missing
// before PR #376). Spread args mean we don't expect a single literal path.
expect(CLI_SRC).toMatch(/"context-mode@latest"/);
expect(CLI_SRC).toMatch(/\.cache/);
});
it("uses the matching packages/context-mode@latest layout on Windows", () => {
// Path segments are passed via spread so the literal substring won't appear
// sequentially; instead assert the spread + Windows branch are both present.
expect(CLI_SRC).toMatch(/process\.platform\s*===\s*"win32"/);
expect(CLI_SRC).toMatch(/"packages"\s*,\s*"context-mode@latest"/);
expect(CLI_SRC).toMatch(/AppData[\s\S]{0,200}Local/);
});
});