Files
fusion/packages/dashboard/app/components/__tests__/nativeStructureChatRef.test.ts
gsxdsm bc4b679598 FN-8291: add inline native structure previews to chat
Enable chat users to inspect and open referenced native structures inline.

- Render clickable inline previews for native structure references across chat surfaces.
- Route preview actions to their corresponding task, mission, goal, and other dashboard views.
- Add regression coverage, dashboard documentation, and a CLI changeset.

Files changed:
 ...fn-8291-chat-native-structure-inline-preview.md |   7 +
 docs/dashboard-guide.md                            |   5 +-
 packages/dashboard/app/App.tsx                     |  31 +++
 .../app/components/StandardChatSurface.tsx         | 226 ++++++++++++++++--
 ...andardChatSurface.nativeStructureEmbed.test.tsx | 257 +++++++++++++++++++++
 .../__tests__/nativeStructureChatRef.test.ts       |  54 +++++
 .../app/components/nativeStructureChatRef.ts       |  58 +++++
 .../app/components/nativeStructureNavigation.ts    |  21 ++
 8 files changed, 635 insertions(+), 24 deletions(-)

Fusion-Task-Id: FN-8291

Fusion-Task-Lineage: 9db2c0fa-494e-4779-93f3-3309eed8565a

Co-authored-by: Fusion (runfusion.ai) <noreply@runfusion.ai>
2026-07-18 19:36:57 -07:00

55 lines
2.0 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { nativeStructureChatRefMatcher, parseNativeStructureChatRef } from "../nativeStructureChatRef";
describe("parseNativeStructureChatRef", () => {
it.each([
"mission",
"milestone",
"roadmap-item",
"research-finding",
"eval-result",
"goal",
] as const)("parses the canonical %s form", (kind) => {
expect(parseNativeStructureChatRef(`fusion://${kind}/ID-001`)).toEqual({ kind, id: "ID-001" });
});
it.each([
"mission:M-001",
"fusion://unknown-kind/R-001",
"fusion://mission/",
"fusion://mission/M-001/extra",
"fusion://mission/M%2F001",
"fusion://mission/M%5C001",
"fusion://mission/%20",
"https://mission/M-001",
])("rejects malformed or unsupported reference %s", (value) => {
expect(parseNativeStructureChatRef(value)).toBeNull();
});
it("matches a bare canonical token within surrounding text without swallowing it", () => {
const source = "Read fusion://mission/M-001, then continue.";
const matches = Array.from(source.matchAll(nativeStructureChatRefMatcher));
expect(matches.map((match) => match[0])).toEqual(["fusion://mission/M-001,"]);
expect(source.slice(0, matches[0]!.index)).toBe("Read ");
expect(matches[0]![1]).toBe("fusion://mission/M-001");
expect(matches[0]![2]).toBe(",");
expect(source.slice((matches[0]!.index ?? 0) + matches[0]![0].length)).toBe(" then continue.");
});
it.each([
"fusion://mission/M-001?query",
"fusion://mission/M-001#fragment",
"fusion://mission/M-001/extra",
"fusion://mission/M-001%2Fextra",
])("does not match a valid prefix of malformed bare token %s", (value) => {
expect(Array.from(value.matchAll(nativeStructureChatRefMatcher))).toEqual([]);
});
it("keeps defined terminal prose punctuation outside the canonical token", () => {
const matches = Array.from("See fusion://mission/M.001.".matchAll(nativeStructureChatRefMatcher));
expect(matches[0]![1]).toBe("fusion://mission/M.001");
expect(matches[0]![2]).toBe(".");
});
});