Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/gymcoach/agent.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec

metadata:
Expand Down
4 changes: 2 additions & 2 deletions packages/adapter-claude/src/__tests__/claude-adapter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { AgentSpecManifest } from '@agentspec/sdk'
// ── Fixtures ──────────────────────────────────────────────────────────────────

const baseManifest: AgentSpecManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: {
name: 'test-agent',
Expand Down Expand Up @@ -90,7 +90,7 @@ describe('buildContext()', () => {

it('serialises all manifest fields', () => {
const ctx = buildContext({ manifest: baseManifest })
expect(ctx).toContain('"apiVersion": "agentspec.io/v1"')
expect(ctx).toContain('"apiVersion": "agentspec.io/v1alpha1"')
expect(ctx).toContain('"provider": "groq"')
})

Expand Down
2 changes: 1 addition & 1 deletion packages/adapter-claude/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const REPAIR_SYSTEM_PROMPT =
`Return ONLY a JSON object with this exact shape (no other text):\n` +
`{"files":{"agent.yaml":"<corrected YAML>"},"installCommands":[],"envVars":[]}\n\n` +
`## AgentSpec v1 schema rules (enforce all of these):\n` +
`- Top-level keys: apiVersion: "agentspec.io/v1", kind: "AgentSpec"\n` +
`- Top-level keys: apiVersion: "agentspec.io/v1alpha1", kind: "AgentSpec"\n` +
`- metadata: name (slug a-z0-9-), version (semver), description\n` +
`- spec.model: provider, id (never "name"), apiKey: "$env:VAR"\n` +
`- spec.model.fallback: provider, id, apiKey, triggerOn (array of strings)\n` +
Expand Down
22 changes: 11 additions & 11 deletions packages/cli/src/__tests__/commands.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ vi.mock('@agentspec/sdk', () => ({
migrateManifest: mockMigrateManifest,
detectVersion: mockDetectVersion,
isLatestVersion: mockIsLatestVersion,
LATEST_API_VERSION: 'agentspec.io/v1',
LATEST_API_VERSION: 'agentspec.io/v1alpha1',
}))

vi.mock('node:fs', () => ({
Expand All @@ -82,7 +82,7 @@ vi.mock('@clack/prompts', () => ({
// ── Test data ─────────────────────────────────────────────────────────────────

const mockManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: {
name: 'test-agent',
Expand All @@ -104,7 +104,7 @@ const mockManifest = {
const mockLoadResult = {
manifest: mockManifest,
filePath: '/fake/agent.yaml',
raw: 'apiVersion: agentspec.io/v1',
raw: 'apiVersion: agentspec.io/v1alpha1',
baseDir: '/fake',
}

Expand Down Expand Up @@ -179,7 +179,7 @@ describe('validate command', () => {
expect(parsed.valid).toBe(true)
expect(parsed.agentName).toBe('test-agent')
expect(parsed.version).toBe('1.0.0')
expect(parsed.apiVersion).toBe('agentspec.io/v1')
expect(parsed.apiVersion).toBe('agentspec.io/v1alpha1')
})

it('throws ExitError(1) when loadManifest throws (text mode)', async () => {
Expand Down Expand Up @@ -735,14 +735,14 @@ describe('migrate command', () => {

const validYaml = 'apiVersion: agentspec/v1alpha1\nkind: AgentSpec\nmetadata:\n name: old-agent\n'
const migratedObj = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: { name: 'old-agent' },
}

it('prints "already at latest version" when already up to date', async () => {
mockReadFileSync.mockReturnValue('apiVersion: agentspec.io/v1\nkind: AgentSpec\n')
mockDetectVersion.mockReturnValue('agentspec.io/v1')
mockReadFileSync.mockReturnValue('apiVersion: agentspec.io/v1alpha1\nkind: AgentSpec\n')
mockDetectVersion.mockReturnValue('agentspec.io/v1alpha1')
mockIsLatestVersion.mockReturnValue(true)
await run(['/fake/agent.yaml'])
expect(logOutput()).toContain('latest')
Expand All @@ -755,7 +755,7 @@ describe('migrate command', () => {
mockIsLatestVersion.mockReturnValue(false)
mockMigrateManifest.mockReturnValue({
result: migratedObj,
migrationsApplied: ['agentspec/v1alpha1 → agentspec.io/v1'],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should remain v1 as a target, same for others

migrationsApplied: ['agentspec/v1alpha1 → agentspec.io/v1alpha1'],
})
await run(['/fake/agent.yaml'])
expect(mockWriteFileSync).toHaveBeenCalled()
Expand All @@ -769,7 +769,7 @@ describe('migrate command', () => {
mockIsLatestVersion.mockReturnValue(false)
mockMigrateManifest.mockReturnValue({
result: migratedObj,
migrationsApplied: ['agentspec/v1alpha1 → agentspec.io/v1'],
migrationsApplied: ['agentspec/v1alpha1 → agentspec.io/v1alpha1'],
})
await run(['/fake/agent.yaml'])
expect(logOutput()).toContain('agentspec/v1alpha1')
Expand All @@ -781,7 +781,7 @@ describe('migrate command', () => {
mockIsLatestVersion.mockReturnValue(false)
mockMigrateManifest.mockReturnValue({
result: migratedObj,
migrationsApplied: ['agentspec/v1alpha1 → agentspec.io/v1'],
migrationsApplied: ['agentspec/v1alpha1 → agentspec.io/v1alpha1'],
})
await run(['/fake/agent.yaml', '--dry-run'])
expect(mockWriteFileSync).not.toHaveBeenCalled()
Expand Down Expand Up @@ -850,7 +850,7 @@ describe('init command', () => {
await run(['--yes'])
expect(mockWriteFileSync).toHaveBeenCalledOnce()
const content = mockWriteFileSync.mock.calls[0][1] as string
expect(content).toContain('apiVersion: agentspec.io/v1')
expect(content).toContain('apiVersion: agentspec.io/v1alpha1')
expect(content).toContain('my-agent')
})

Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/__tests__/deploy-k8s.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { generateK8sManifests } from '../deploy/k8s.js'
// ── Fixtures ──────────────────────────────────────────────────────────────────

const minimalManifest: AgentSpecManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: {
name: 'my-agent',
Expand All @@ -34,7 +34,7 @@ const minimalManifest: AgentSpecManifest = {
}

const fullManifest: AgentSpecManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: {
name: 'budget-assistant',
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/__tests__/evaluate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ let logSpy: ReturnType<typeof vi.spyOn>
let errorSpy: ReturnType<typeof vi.spyOn>

const mockManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: { name: 'test-agent', version: '1.0.0', description: 'A test agent' },
spec: {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/__tests__/generate-policy.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ import {
// ── Test fixtures ──────────────────────────────────────────────────────────────

const fullManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: { name: 'gymcoach', version: '1.0.0', description: 'AI fitness coach' },
spec: {
Expand Down Expand Up @@ -98,7 +98,7 @@ const fullManifest = {
} as const

const minimalManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: { name: 'minimal-agent', version: '1.0.0', description: 'Minimal agent' },
spec: {
Expand Down
4 changes: 2 additions & 2 deletions packages/cli/src/__tests__/scan-builder.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ describe('slugify', () => {
// ── buildManifestFromDetection() ─────────────────────────────────────────────

describe('buildManifestFromDetection — top-level structure', () => {
it('sets apiVersion: "agentspec.io/v1"', () => {
it('sets apiVersion: "agentspec.io/v1alpha1"', () => {
const result = buildManifestFromDetection(minimalDetection)
expect(result.apiVersion).toBe('agentspec.io/v1')
expect(result.apiVersion).toBe('agentspec.io/v1alpha1')
})

it('sets kind: "AgentSpec"', () => {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/__tests__/scan.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ describe('scan — CLI integration', () => {
writeFileSync(join(srcDir, 'agent.yaml'), 'name: old')
await runScan(srcDir, ['--update'])
const content = readFileSync(join(srcDir, 'agent.yaml'), 'utf-8')
expect(content).toContain('apiVersion: agentspec.io/v1')
expect(content).toContain('apiVersion: agentspec.io/v1alpha1')
})

it('--dry-run prints to stdout and does not write a file', async () => {
Expand Down
37 changes: 34 additions & 3 deletions packages/cli/src/commands/init.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Command } from 'commander'
import { writeFileSync, existsSync } from 'node:fs'
import { resolve, join } from 'node:path'
import { writeFileSync, existsSync, mkdirSync } from 'node:fs'
import { resolve, join, dirname } from 'node:path'
import chalk from 'chalk'
import * as p from '@clack/prompts'
import { printHeader } from '../utils/output.js'
Expand Down Expand Up @@ -126,6 +126,37 @@ export function registerInitCommand(program: Command): void {

writeFileSync(outFile, yaml, 'utf-8')

// Create stub files referenced by $file: in the manifest so the
// quick-start flow (init → validate → health → generate) works out of
// the box without confusing "file not found" errors.
const stubs: Array<{ path: string; content: string }> = [
{
path: join(outDir, 'prompts', 'system.md'),
content:
`# System Prompt\n\n` +
`You are a helpful AI assistant named ${name}.\n\n` +
`## Guidelines\n\n` +
`- Be concise and accurate\n` +
`- Ask for clarification when unsure\n` +
`- Always respond in the user's language\n`,
},
]

if (includeEval) {
stubs.push({
path: join(outDir, 'eval', 'datasets', 'qa.jsonl'),
content: JSON.stringify({ input: 'Hello', expected_output: 'Hi! How can I help you?' }) + '\n',
})
}

for (const stub of stubs) {
if (!existsSync(stub.path)) {
mkdirSync(dirname(stub.path), { recursive: true })
writeFileSync(stub.path, stub.content, 'utf-8')
console.log(chalk.gray(` ✓ Created ${stub.path}`))
}
}

if (!opts.yes) p.outro(chalk.green(`✓ Created ${outFile}`))
else console.log(chalk.green(`\n ✓ Created ${outFile}\n`))

Expand All @@ -150,7 +181,7 @@ function generateManifest(opts: {
includeEval: boolean
}): string {
const sections: string[] = [
`apiVersion: agentspec.io/v1
`apiVersion: agentspec.io/v1alpha1
kind: AgentSpec

metadata:
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/scan-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ export function slugify(s: string): string {
*/
export function buildManifestFromDetection(d: ScanDetection): AgentSpecManifest {
return {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: buildMetadata(d),
spec: {
Expand Down
2 changes: 1 addition & 1 deletion packages/cli/src/commands/validate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export function registerValidateCommand(program: Command): void {

printHeader('AgentSpec Validate')
printSuccess(
`Manifest valid — ${chalk.cyan(manifest.metadata.name)} v${manifest.metadata.version} (agentspec.io/v1)`,
`Manifest valid — ${chalk.cyan(manifest.metadata.name)} v${manifest.metadata.version} (agentspec.io/v1alpha1)`,
)
console.log(chalk.gray(` Provider : ${manifest.spec.model.provider}/${manifest.spec.model.id}`))
console.log(chalk.gray(` Tools : ${manifest.spec.tools?.length ?? 0}`))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentObservation
metadata:
name: fitness-tracker
Expand Down
2 changes: 1 addition & 1 deletion packages/operator/demo/fitness-tracker/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ metadata:
agentspec.io/agent: fitness-tracker
data:
agent.yaml: |
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec
metadata:
name: fitness-tracker
Expand Down
2 changes: 1 addition & 1 deletion packages/operator/demo/gymcoach/agentobservation.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentObservation
metadata:
name: gymcoach
Expand Down
2 changes: 1 addition & 1 deletion packages/operator/demo/gymcoach/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ metadata:
agentspec.io/agent: gymcoach
data:
agent.yaml: |
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec
metadata:
name: gymcoach
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ metadata:
agentspec.io/agent: research-agent
data:
agent.yaml: |
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec
metadata:
name: research-agent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ metadata:
agentspec.io/agent: voice-assistant
data:
agent.yaml: |
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec
metadata:
name: voice-assistant
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentObservation
metadata:
name: research-agent
Expand Down
2 changes: 1 addition & 1 deletion packages/operator/demo/research-agent/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ metadata:
agentspec.io/agent: research-agent
data:
agent.yaml: |
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec
metadata:
name: research-agent
Expand Down
2 changes: 1 addition & 1 deletion packages/operator/demo/trading-bot/agentobservation.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentObservation
metadata:
name: trading-bot
Expand Down
2 changes: 1 addition & 1 deletion packages/operator/demo/trading-bot/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ metadata:
agentspec.io/agent: trading-bot
data:
agent.yaml: |
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec
metadata:
name: trading-bot
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentObservation
metadata:
name: voice-assistant
Expand Down
2 changes: 1 addition & 1 deletion packages/operator/demo/voice-assistant/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ metadata:
agentspec.io/agent: voice-assistant
data:
agent.yaml: |
apiVersion: agentspec.io/v1
apiVersion: agentspec.io/v1alpha1
kind: AgentSpec
metadata:
name: voice-assistant
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/src/__tests__/audit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const allRules = [
]

const minimalManifest: AgentSpecManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: {
name: 'test-agent',
Expand Down
2 changes: 1 addition & 1 deletion packages/sdk/src/__tests__/generate-registry.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import type { AgentSpecManifest } from '../schema/manifest.schema.js'
// ── Fixtures ──────────────────────────────────────────────────────────────────

const testManifest: AgentSpecManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: { name: 'test-agent', version: '1.0.0', description: 'test' },
spec: {
Expand Down
4 changes: 2 additions & 2 deletions packages/sdk/src/__tests__/health-index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ afterEach(() => {
// ── Fixtures ──────────────────────────────────────────────────────────────────

const baseManifest: AgentSpecManifest = {
apiVersion: 'agentspec.io/v1',
apiVersion: 'agentspec.io/v1alpha1',
kind: 'AgentSpec',
metadata: { name: 'health-idx-agent', version: '1.0.0', description: 'test' },
spec: {
Expand All @@ -66,7 +66,7 @@ describe('runHealthCheck — subagent agentspec ref', () => {

it('returns pass for subagent when manifest file exists', async () => {
const subPath = 'sub-agent.yaml'
writeFileSync(join(tmpDir, subPath), 'apiVersion: agentspec.io/v1')
writeFileSync(join(tmpDir, subPath), 'apiVersion: agentspec.io/v1alpha1')

const manifest: AgentSpecManifest = {
...baseManifest,
Expand Down
Loading