feat: publish HoloLake model-native living system source
This commit is contained in:
parent
6ad10edde1
commit
c395dd3a99
2467 changed files with 615073 additions and 0 deletions
|
|
@ -0,0 +1,226 @@
|
|||
import { test, expect, type Page } from '@playwright/test'
|
||||
import { findCommand, openCommandPalette, sendShortcut } from './helpers'
|
||||
|
||||
interface MockEntry {
|
||||
path: string
|
||||
filename: string
|
||||
title: string
|
||||
isA: string
|
||||
aliases: string[]
|
||||
belongsTo: string[]
|
||||
relatedTo: string[]
|
||||
status: string | null
|
||||
archived: boolean
|
||||
modifiedAt: number | null
|
||||
createdAt: number | null
|
||||
fileSize: number
|
||||
snippet: string
|
||||
wordCount: number
|
||||
relationships: Record<string, string[]>
|
||||
outgoingLinks: string[]
|
||||
properties: Record<string, unknown>
|
||||
template: null
|
||||
sort: null
|
||||
}
|
||||
|
||||
interface VaultSeed {
|
||||
label: string
|
||||
path: string
|
||||
noteTitle?: string
|
||||
}
|
||||
|
||||
interface EntryOptions {
|
||||
fileName?: string
|
||||
isA?: string
|
||||
snippet?: string
|
||||
}
|
||||
|
||||
function untitledNoteRow(page: Page) {
|
||||
return page.getByText(/^Untitled Note(?: \d+)?$/i).first()
|
||||
}
|
||||
|
||||
async function expectFreshVaultSeedEntries(page: Page) {
|
||||
await expect(page.getByText('AGENTS.md — Tolaria Vault', { exact: true })).toBeVisible()
|
||||
await expect(page.getByText('CLAUDE.md', { exact: true })).toBeVisible()
|
||||
await expect(page.getByText('Config', { exact: true })).toHaveCount(0)
|
||||
}
|
||||
|
||||
async function installEmptyVaultMocks(
|
||||
page: Page,
|
||||
config: {
|
||||
createdVaultPath: string
|
||||
initialVaults: VaultSeed[]
|
||||
activeVault: string | null
|
||||
},
|
||||
) {
|
||||
await page.addInitScript((mockConfig) => {
|
||||
const gettingStartedPath = '/Users/mock/Documents/Getting Started'
|
||||
|
||||
function buildEntry(vaultPath: string, title: string, options: EntryOptions = {}): MockEntry {
|
||||
const defaultStem = title.toLowerCase().replace(/[^a-z0-9]+/g, '-').replace(/(^-|-$)/g, '')
|
||||
const filename = options.fileName ?? `${defaultStem}.md`
|
||||
return {
|
||||
path: `${vaultPath}/${filename}`,
|
||||
filename,
|
||||
title,
|
||||
isA: options.isA ?? 'Note',
|
||||
aliases: [],
|
||||
belongsTo: [],
|
||||
relatedTo: [],
|
||||
status: null,
|
||||
archived: false,
|
||||
modifiedAt: 1700000000,
|
||||
createdAt: null,
|
||||
fileSize: 256,
|
||||
snippet: options.snippet ?? `${title} snippet`,
|
||||
wordCount: 12,
|
||||
relationships: {},
|
||||
outgoingLinks: [],
|
||||
properties: {},
|
||||
template: null,
|
||||
sort: null,
|
||||
}
|
||||
}
|
||||
|
||||
function buildFreshVaultSeedEntries(vaultPath: string): MockEntry[] {
|
||||
return [
|
||||
buildEntry(vaultPath, 'AGENTS.md — Tolaria Vault', { fileName: 'AGENTS.md' }),
|
||||
buildEntry(vaultPath, 'CLAUDE.md', { fileName: 'CLAUDE.md' }),
|
||||
buildEntry(vaultPath, 'Type', { fileName: 'type.md', isA: 'Type' }),
|
||||
buildEntry(vaultPath, 'Note', { fileName: 'note.md', isA: 'Type' }),
|
||||
]
|
||||
}
|
||||
|
||||
function syncEntryContent(entry: MockEntry) {
|
||||
allContent[entry.path] = `# ${entry.title}\n\n${entry.snippet}`
|
||||
}
|
||||
|
||||
let savedVaults = mockConfig.initialVaults.map(({ label, path }) => ({ label, path }))
|
||||
let activeVault = mockConfig.activeVault
|
||||
let hiddenDefaults: string[] = []
|
||||
|
||||
const entriesByVault = Object.fromEntries(
|
||||
mockConfig.initialVaults.map((vault) => [
|
||||
vault.path,
|
||||
vault.noteTitle ? [buildEntry(vault.path, vault.noteTitle)] : [],
|
||||
]),
|
||||
) satisfies Record<string, MockEntry[]>
|
||||
|
||||
const allContent = Object.fromEntries(
|
||||
Object.values(entriesByVault)
|
||||
.flat()
|
||||
.map((entry) => [entry.path, `# ${entry.title}\n\n${entry.snippet}`]),
|
||||
)
|
||||
|
||||
localStorage.clear()
|
||||
localStorage.setItem('tolaria:claude-code-onboarding-dismissed', '1')
|
||||
|
||||
Object.defineProperty(window, 'prompt', {
|
||||
configurable: true,
|
||||
value: () => mockConfig.createdVaultPath,
|
||||
})
|
||||
|
||||
let ref: Record<string, unknown> | null = null
|
||||
|
||||
Object.defineProperty(window, '__mockHandlers', {
|
||||
configurable: true,
|
||||
set(value) {
|
||||
ref = value as Record<string, unknown>
|
||||
ref.load_vault_list = () => ({
|
||||
vaults: [...savedVaults],
|
||||
active_vault: activeVault,
|
||||
hidden_defaults: [...hiddenDefaults],
|
||||
})
|
||||
ref.save_vault_list = (args: {
|
||||
list: {
|
||||
vaults: Array<{ label: string; path: string }>
|
||||
active_vault: string | null
|
||||
hidden_defaults?: string[]
|
||||
}
|
||||
}) => {
|
||||
savedVaults = [...args.list.vaults]
|
||||
activeVault = args.list.active_vault
|
||||
hiddenDefaults = [...(args.list.hidden_defaults ?? [])]
|
||||
return null
|
||||
}
|
||||
ref.get_default_vault_path = () => gettingStartedPath
|
||||
ref.check_vault_exists = (args: { path?: string }) =>
|
||||
savedVaults.some((vault) => vault.path === args.path)
|
||||
|| args.path === mockConfig.createdVaultPath
|
||||
ref.create_empty_vault = (args: { targetPath?: string | null }) => {
|
||||
if (args.targetPath !== mockConfig.createdVaultPath) {
|
||||
throw new Error(`Unexpected empty vault target: ${args.targetPath}`)
|
||||
}
|
||||
entriesByVault[mockConfig.createdVaultPath] = buildFreshVaultSeedEntries(mockConfig.createdVaultPath)
|
||||
entriesByVault[mockConfig.createdVaultPath].forEach(syncEntryContent)
|
||||
return mockConfig.createdVaultPath
|
||||
}
|
||||
ref.list_vault = (args: { path?: string }) => entriesByVault[args.path ?? activeVault ?? ''] ?? []
|
||||
ref.list_vault_folders = () => []
|
||||
ref.list_views = () => []
|
||||
ref.get_all_content = () => allContent
|
||||
ref.get_note_content = (args: { path?: string }) => allContent[args.path ?? ''] ?? ''
|
||||
ref.get_modified_files = () => []
|
||||
ref.get_file_history = () => []
|
||||
},
|
||||
get() {
|
||||
return ref
|
||||
},
|
||||
})
|
||||
}, config)
|
||||
}
|
||||
|
||||
test('keyboard onboarding can create an empty vault and the first note', async ({ page }) => {
|
||||
await installEmptyVaultMocks(page, {
|
||||
createdVaultPath: '/Users/mock/Documents/Fresh Vault',
|
||||
initialVaults: [],
|
||||
activeVault: null,
|
||||
})
|
||||
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' })
|
||||
|
||||
await expect(page.getByTestId('welcome-screen')).toBeVisible()
|
||||
await expect(page.getByTestId('welcome-create-new')).toContainText('Create empty vault')
|
||||
await expect(page.getByTestId('welcome-create-vault')).toBeFocused()
|
||||
|
||||
await page.keyboard.press('Tab')
|
||||
await expect(page.getByTestId('welcome-create-new')).toBeFocused()
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
await expect(page.getByTestId('note-list-container')).toBeVisible({ timeout: 5_000 })
|
||||
await expectFreshVaultSeedEntries(page)
|
||||
await sendShortcut(page, 'n', ['Control'])
|
||||
await expect(untitledNoteRow(page)).toBeVisible({ timeout: 5_000 })
|
||||
})
|
||||
|
||||
test('command palette and bottom bar expose empty-vault creation from the active app shell', async ({ page }) => {
|
||||
await installEmptyVaultMocks(page, {
|
||||
createdVaultPath: '/Users/mock/Documents/Client Vault',
|
||||
initialVaults: [{ label: 'Work Vault', path: '/Users/mock/Work', noteTitle: 'Work Home' }],
|
||||
activeVault: '/Users/mock/Work',
|
||||
})
|
||||
|
||||
await page.goto('/', { waitUntil: 'domcontentloaded' })
|
||||
|
||||
await expect(page.getByTestId('note-list-container')).toBeVisible({ timeout: 5_000 })
|
||||
await expect(page.getByTestId('status-vault-trigger')).toContainText('Work Vault')
|
||||
|
||||
await openCommandPalette(page)
|
||||
expect(await findCommand(page, 'Create Empty Vault')).toBe(true)
|
||||
await page.keyboard.press('Escape')
|
||||
|
||||
const trigger = page.getByTestId('status-vault-trigger')
|
||||
await trigger.focus()
|
||||
await expect(trigger).toBeFocused()
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
const createEmptyItem = page.getByTestId('vault-menu-create-empty')
|
||||
await createEmptyItem.focus()
|
||||
await expect(createEmptyItem).toBeFocused()
|
||||
await page.keyboard.press('Enter')
|
||||
|
||||
await expect(trigger).toContainText('Client Vault')
|
||||
await expectFreshVaultSeedEntries(page)
|
||||
await sendShortcut(page, 'n', ['Control'])
|
||||
await expect(untitledNoteRow(page)).toBeVisible({ timeout: 5_000 })
|
||||
})
|
||||
Loading…
Reference in a new issue