Files
open-design/apps/daemon/tests/memory-tree.test.ts
f1a0b60c6c chore: unify product name display to OpenDesign repo-wide (#6998)
* chore: unify product name display to OpenDesign repo-wide

Rename the user-facing product name from "Open Design" to "OpenDesign"
across documentation, web/desktop UI strings, i18n locales, prompts,
plugin/skill/design-system content, changelogs, and specs, matching the
landing-page rename already in flight.

Deliberately excluded so installed-app identity stays untouched:
- packages/release PRODUCT_NAME and everything derived from it
  (app bundle names, installer/registry identity, updater feeds)
- tools/pack, tools/release, apps/packaged, landing page (PR #6983)
- mocks/ recorded traces and LICENSE
- test fixtures and comments that encode real on-disk install paths
  (Open Design.app, Program Files\Open Design, AppData paths)

Validated with pnpm guard, pnpm typecheck, and targeted web/desktop/host
test runs over the renamed strings.

* fix(web): keep two-letter author monogram for CamelCase brand names

authorInitials split words on whitespace only, so the renamed single-token
author name "OpenDesign" produced a one-letter monogram. Treat lower-to-upper
CamelCase boundaries as word breaks so the avatar fallback stays "OD".

* fix(release): restore spaced Windows source artifact names in win.ps1

tools/pack still derives builder outputs from the unchanged PRODUCT_NAME
("Open Design"), so the asset script must look for the spaced filenames.
Matches the mac/mac-intel/linux asset scripts, which were already kept on
the original names.

---------

Co-authored-by: Joey <236967869+joeylee12629-star@users.noreply.github.com>
2026-08-18 07:09:45 +00:00

112 lines
3.3 KiB
TypeScript

import { promises as fsp } from 'node:fs';
import os from 'node:os';
import path from 'node:path';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import {
buildMemoryTree,
memoryDir,
readMemoryEntry,
updateMemoryTreeNode,
upsertMemoryEntry,
} from '../src/memory.js';
let dataDir = '';
beforeEach(async () => {
dataDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'od-memory-tree-'));
});
afterEach(async () => {
await fsp.rm(dataDir, { recursive: true, force: true });
});
describe('memory tree helpers', () => {
it('derives folder and entry nodes from the markdown memory store', async () => {
await upsertMemoryEntry(
dataDir,
{
name: 'Design agent goal',
description: 'OpenDesign should evolve from accepted work',
type: 'project',
body: '- Keep design-system extraction in the loop',
},
{ silent: true },
);
const tree = await buildMemoryTree(dataDir);
expect(tree).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: 'folder:project',
kind: 'folder',
path: '/project',
childrenCount: 1,
}),
expect.objectContaining({
id: 'project_design_agent_goal',
parentId: 'folder:project',
kind: 'entry',
path: '/project/project_design_agent_goal',
scope: 'project',
}),
]),
);
});
it('edits and moves an entry through the tree-aware patch helper', async () => {
const entry = await upsertMemoryEntry(
dataDir,
{
name: 'Reusable pattern',
description: 'Skill candidate',
type: 'reference',
body: '- Draft artifacts with provenance',
},
{ silent: true },
);
const updated = await updateMemoryTreeNode(dataDir, entry.id, {
name: 'Reusable pattern',
description: 'Skill candidate promoted from automation',
type: 'project',
body: '- Draft artifacts with provenance\n- Promote repeatable work into skills',
});
expect(updated.type).toBe('project');
expect(updated.description).toContain('promoted from automation');
expect(updated.body).toContain('Promote repeatable work into skills');
const stored = await readMemoryEntry(dataDir, entry.id);
expect(stored?.type).toBe('project');
const tree = await buildMemoryTree(dataDir);
expect(tree).toEqual(
expect.arrayContaining([
expect.objectContaining({
id: entry.id,
parentId: 'folder:project',
path: `/project/${entry.id}`,
}),
]),
);
});
it('rejects derived folder edits', async () => {
await expect(
updateMemoryTreeNode(dataDir, 'folder:project', { name: 'Project' }),
).rejects.toThrow('memory tree folders are derived');
});
it('returns an empty folder tree when the store is empty', async () => {
await fsp.rm(memoryDir(dataDir), { recursive: true, force: true });
const tree = await buildMemoryTree(dataDir);
// One folder per memory type: profile, user, feedback, project, reference,
// rule (the two new types — profile + rule — added two folders).
expect(tree.filter((node) => node.kind === 'folder')).toHaveLength(6);
expect(tree.filter((node) => node.kind === 'entry')).toHaveLength(0);
});
});