VS Code Extension for OSSA Manifest Authoring
Objective
Build a Visual Studio Code extension that provides intelligent authoring support for OSSA agent manifests with validation, auto-completion, and snippets.
Scope
Create a VS Code extension with:
- Real-time schema validation as you type
- IntelliSense auto-completion for properties
- Snippets for common patterns (runtime configs, capabilities, etc.)
- Hover documentation for all fields
- Validation warnings/errors in Problems panel
- Quick fixes for common issues
Technical Approach
// src/extension.ts
import * as vscode from 'vscode';
import Ajv from 'ajv';
import * as yaml from 'yaml';
export function activate(context: vscode.ExtensionContext) {
const ajv = new Ajv();
const schema = require('../schemas/ossa-1.0.schema.json');
const validate = ajv.compile(schema);
// Register diagnostics provider
const diagnosticCollection = vscode.languages.createDiagnosticCollection('ossa');
vscode.workspace.onDidChangeTextDocument(event => {
if (isOssaManifest(event.document)) {
validateDocument(event.document, diagnosticCollection, validate);
}
});
// Register completion provider
context.subscriptions.push(
vscode.languages.registerCompletionItemProvider(
{ pattern: '**/.ossa.yml' },
new OssaCompletionProvider(schema),
':', ' '
)
);
// Register hover provider
context.subscriptions.push(
vscode.languages.registerHoverProvider(
{ pattern: '**/.ossa.yml' },
new OssaHoverProvider(schema)
)
);
// Register code actions for quick fixes
context.subscriptions.push(
vscode.languages.registerCodeActionsProvider(
{ pattern: '**/.ossa.yml' },
new OssaCodeActionProvider()
)
);
}
function validateDocument(
document: vscode.TextDocument,
collection: vscode.DiagnosticCollection,
validate: any
) {
const text = document.getText();
try {
const manifest = yaml.parse(text);
const valid = validate(manifest);
if (\!valid) {
const diagnostics: vscode.Diagnostic[] = validate.errors.map(error => {
const line = findLineForProperty(text, error.instancePath);
const range = new vscode.Range(line, 0, line, 999);
return new vscode.Diagnostic(
range,
error.message,
vscode.DiagnosticSeverity.Error
);
});
collection.set(document.uri, diagnostics);
} else {
collection.delete(document.uri);
}
} catch (e) {
// YAML parsing error
const diagnostic = new vscode.Diagnostic(
new vscode.Range(0, 0, 0, 999),
`Invalid YAML: ${e.message}`,
vscode.DiagnosticSeverity.Error
);
collection.set(document.uri, [diagnostic]);
}
}
class OssaCompletionProvider implements vscode.CompletionItemProvider {
constructor(private schema: any) {}
provideCompletionItems(
document: vscode.TextDocument,
position: vscode.Position
): vscode.CompletionItem[] {
const line = document.lineAt(position).text;
const context = this.getContext(document, position);
if (context === 'runtime.type') {
return ['docker', 'k8s', 'local', 'serverless', 'edge'].map(type => {
const item = new vscode.CompletionItem(type, vscode.CompletionItemKind.Value);
item.detail = `Runtime type: ${type}`;
return item;
});
}
if (context === 'role') {
return this.schema.$defs.AgentRole.enum.map(role => {
const item = new vscode.CompletionItem(role, vscode.CompletionItemKind.Value);
item.documentation = new vscode.MarkdownString(`Agent role: **${role}**`);
return item;
});
}
// Return all top-level properties if at root
if (context === 'root') {
return Object.keys(this.schema.properties).map(prop => {
const item = new vscode.CompletionItem(prop, vscode.CompletionItemKind.Property);
item.insertText = new vscode.SnippetString(`${prop}: $0`);
return item;
});
}
return [];
}
}
class OssaHoverProvider implements vscode.HoverProvider {
constructor(private schema: any) {}
provideHover(
document: vscode.TextDocument,
position: vscode.Position
): vscode.Hover | undefined {
const range = document.getWordRangeAtPosition(position);
const word = document.getText(range);
const propertySchema = this.findPropertySchema(word);
if (propertySchema?.description) {
return new vscode.Hover(
new vscode.MarkdownString(propertySchema.description)
);
}
}
}
class OssaCodeActionProvider implements vscode.CodeActionProvider {
provideCodeActions(
document: vscode.TextDocument,
range: vscode.Range,
context: vscode.CodeActionContext
): vscode.CodeAction[] {
const actions: vscode.CodeAction[] = [];
for (const diagnostic of context.diagnostics) {
if (diagnostic.message.includes('missing required')) {
const fix = new vscode.CodeAction(
'Add missing required fields',
vscode.CodeActionKind.QuickFix
);
fix.edit = new vscode.WorkspaceEdit();
// ... generate missing fields
actions.push(fix);
}
}
return actions;
}
}
Snippets Configuration
{
"OSSA Agent Manifest": {
"prefix": "ossa",
"body": [
"ossaVersion: '1.0'",
"agent:",
" id: ${1:agent-id}",
" name: ${2:Agent Name}",
" version: ${3:1.0.0}",
" role: ${4|compliance,chat,orchestration,audit,workflow|}",
" runtime:",
" type: ${5|docker,k8s,local|}",
" image: ${6:image:tag}",
" capabilities:",
" - name: ${7:capability_name}",
" description: ${8:Capability description}",
" input_schema:",
" type: object",
" output_schema:",
" type: object"
]
},
"OSSA Capability": {
"prefix": "ossa-capability",
"body": [
"- name: ${1:capability_name}",
" description: ${2:Description}",
" input_schema:",
" type: object",
" properties:",
" ${3:param}: { type: ${4:string} }",
" output_schema:",
" type: object",
" properties:",
" ${5:result}: { type: ${6:string} }"
]
}
}
Acceptance Criteria
-
Real-time validation with Ajv + OSSA 1.0 schema -
IntelliSense for all properties, enums, and values -
10+ snippets for common patterns -
Hover documentation from schema descriptions -
Quick fixes for missing required fields -
Diagnostics in Problems panel -
Works with both .yml and .yaml files -
Published to VS Code Marketplace -
README with screenshots and usage examples -
Supports JSON format as well as YAML
Files to Create
-
vscode-extension/src/extension.ts
- Main extension -
vscode-extension/package.json
- Extension manifest -
vscode-extension/snippets/ossa.json
- Snippet definitions -
vscode-extension/schemas/ossa-1.0.schema.json
- Bundled schema
Similar Tools
- YAML Language Server (RedHat)
- Kubernetes extension (Microsoft)
- OpenAPI Editor (42Crunch)