Support .archify diagram files (0.2.0)

.archify files are Archify JSON diagram sources. They open as JSON,
preview with the same commands, report validation problems, and get
completion from a schema that dispatches on diagram_type. Adds a
hello.archify example and tests for detection, the dispatching schema
and the VS Code behaviour.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-30 12:56:12 +03:00
co-authored by Claude Opus 5.5
parent 22815a9940
commit 30e2faa38c
15 changed files with 458 additions and 24 deletions
+45 -4
View File
@@ -33,7 +33,7 @@ async function check(name: string, body: () => Promise<void>): Promise<void> {
await body();
console.log(` ✔ ${name}`);
} catch (error) {
console.log(` ✖ ${name}`);
console.log(` ✖ ${name}\n ${error instanceof Error ? error.stack ?? error.message : String(error)}`);
throw error;
}
}
@@ -49,10 +49,51 @@ export async function run(): Promise<void> {
await waitFor('activation', () => extension.isActive);
});
await check('opens a live preview beside the source', async () => {
await check('.archify files open as JSON with the preview available', async () => {
const doc = await vscode.workspace.openTextDocument(workspaceFile('web-platform.archify'));
assert.equal(doc.languageId, 'json');
await vscode.window.showTextDocument(doc);
await vscode.commands.executeCommand('archify.showPreviewToSide');
const tabs = await waitFor('.archify preview tab', () => {
const found = webviewTabs('archify.preview').filter((tab) => /web-platform\.archify/.test(tab.label));
return found.length > 0 && found;
});
assert.equal(tabs.length, 1);
});
await check('.archify completion comes from the schema of its diagram_type', async () => {
const doc = await vscode.workspace.openTextDocument(workspaceFile('web-platform.archify'));
await vscode.window.showTextDocument(doc);
// Complete the value of the first component's "type".
const offset = doc.getText().indexOf('"type": "') + '"type": "'.length;
const position = doc.positionAt(offset);
let labels: string[] = [];
for (let attempt = 0; attempt < 50 && !labels.includes('backend'); attempt += 1) {
const list = await vscode.commands.executeCommand<vscode.CompletionList>('vscode.executeCompletionItemProvider', doc.uri, position);
labels = list.items.map((item) => (typeof item.label === 'string' ? item.label : item.label.label).replace(/"/g, ''));
if (!labels.includes('backend')) await new Promise((resolve) => setTimeout(resolve, 300));
}
assert.ok(labels.includes('backend') && labels.includes('database'), `offered: ${labels.join(', ')}`);
});
await check('.archify problems are reported against the file', async () => {
const good = await vscode.workspace.openTextDocument(workspaceFile('cache-miss.archify'));
const broken = good.getText().replace('"participants"', '"actors"');
const target = workspaceFile('broken.archify');
await vscode.workspace.fs.writeFile(target, new TextEncoder().encode(broken));
const doc = await vscode.workspace.openTextDocument(target);
await vscode.window.showTextDocument(doc);
const diagnostics = await waitFor('archify diagnostics on broken.archify', () => {
const found = vscode.languages.getDiagnostics(doc.uri).filter((d) => d.source === 'archify');
return found.length > 0 && found;
});
assert.ok(diagnostics.some((d) => d.severity === vscode.DiagnosticSeverity.Error));
});
await check('opens a live preview beside the source', async () => {
await vscode.commands.executeCommand('archify.showPreviewToSide', workspaceFile('production-deployment.architecture.json'));
const tabs = await waitFor('preview tab', () => {
const found = webviewTabs('archify.preview');
const found = webviewTabs('archify.preview').filter((tab) => /production-deployment/.test(tab.label));
return found.length > 0 && found;
});
assert.equal(tabs.length, 1);
@@ -107,7 +148,7 @@ export async function run(): Promise<void> {
await check('source-backed diagram previews with the evidence fallback', async () => {
const uri = workspaceFile('mco-runtime.architecture.json');
await vscode.commands.executeCommand('archify.showPreview', uri);
await waitFor('second preview tab', () => webviewTabs('archify.preview').length >= 2);
await waitFor('mco preview tab', () => webviewTabs('archify.preview').some((tab) => /mco-runtime/.test(tab.label)));
const doc = await vscode.workspace.openTextDocument(uri);
const diagnostics = await waitFor('evidence diagnostics', () => {
const found = vscode.languages.getDiagnostics(doc.uri).filter((d) => d.source === 'archify');