@autonomos/core 0.0.1 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,48 @@
1
+ ---
2
+ name: protocol-crystallize
3
+ description: 'Mandatory close-out procedure for any session. Invoked before declaring the session done. Forces the agent to crystallize learnings into AGENT.md files.'
4
+ ---
5
+
6
+ # Protocol Crystallize
7
+
8
+ **Goal:** Convert session activity into durable project knowledge.
9
+ **Your Role:** Reflective agent that improves the project for the next session.
10
+
11
+ ## STEP 0 — STOP
12
+
13
+ DO NOT close the session before every step below is complete.
14
+
15
+ ## STEP 1 — Worklog
16
+
17
+ Create or complete `.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md`. Free format, but MUST contain:
18
+
19
+ - A summary of what was done
20
+ - The technical decisions made and why
21
+ - The files modified
22
+ - Clear next steps (for the next session)
23
+
24
+ ## STEP 2 — Crystallize into AGENT.md files
25
+
26
+ Ask yourself these three questions. For each, you MUST answer honestly. Do NOT say "nothing new".
27
+
28
+ **Question 1:** `What did I learn of significance about this project during this session?` (preferences, constraints, discovered conventions, user corrections, etc.)
29
+
30
+ If the answer is not `nothing`, write it to the relevant AGENT.md (root or subfolder). No format is imposed. One line is enough if it is clear.
31
+
32
+ **Question 2:** `Has any AGENT.md entry been contradicted or superseded?` If yes, update the relevant AGENT.md entry **in place** — the file is a current-state document, not a changelog. Then record the change in the worklog of this session (e.g. `PREF-007: GSAP → Motion, superseded by PREF-009`). Do NOT append superseded entries to AGENT.md; do NOT keep both.
33
+
34
+ **Question 3:** `Is there something in the worklog that should have been in an AGENT.md and is not yet?` If yes, lift it out of the worklog and put it in the AGENT.md.
35
+
36
+ ## STEP 3 — Task status
37
+
38
+ Mark the task as `[x]` (or `[!]` if blocked) in `.autonomos/TASKS.md`.
39
+
40
+ ## STEP 4 — Final verification
41
+
42
+ RESPOND to the user with:
43
+
44
+ - `Task: [x] / [!] — [ID]`
45
+ - `Worklog created: .autonomos/worklogs/...`
46
+ - `AGENT.md updated: [yes / no, and why]`
47
+
48
+ If you cannot produce these three lines, the session is not complete. Resume from Step 1.
@@ -0,0 +1,50 @@
1
+ ---
2
+ name: protocol-session
3
+ description: 'Mandatory bootstrap for any new session on a project following the Autonomos protocol. Invoked at the start of every session, before any work begins.'
4
+ ---
5
+
6
+ # Protocol Session
7
+
8
+ **Goal:** Load all project context, identify the next task, and establish a clean working state.
9
+ **Your Role:** Disciplined agent that respects the project's accumulated knowledge.
10
+
11
+ ## STEP 0 — STOP
12
+
13
+ You are starting a new session. You MUST complete Steps 1, 2, and 3 before any other action.
14
+
15
+ DO NOT skip steps. DO NOT begin work before Step 3 is complete.
16
+
17
+ ## STEP 1 — Load context (three mandatory reads)
18
+
19
+ 1. Read the root `AGENT.md`. This is your project identity.
20
+ 2. Run `autonomos agents` (no argument) to get the **full tree of all AGENT.md files in the project**. Read each one. This is your full fractal context — it lets you discover shared packages, cross-cutting conventions, and traps before starting any work.
21
+ 3. Read the most recent file in `.autonomos/worklogs/`. This is the memory of the previous session — read it to avoid repeating the same mistakes.
22
+
23
+ RESPOND to the user with a 5-line maximum summary of what you have retained. You are FORBIDDEN to continue without this response.
24
+
25
+ ## STEP 2 — Identify the next task
26
+
27
+ Open `.autonomos/TASKS.md`. Identify the highest-priority task that is not yet `[x]`. If none qualify, ask the user what to work on.
28
+
29
+ RESPOND with: `Task selected: [ID] — [title]. Starting.`
30
+
31
+ ## STEP 3 — Mark the task and begin
32
+
33
+ - Edit `.autonomos/TASKS.md` to change this task's status from `[ ]` to `[/]`.
34
+ - NOW you may begin working.
35
+
36
+ ## REMINDER — applies to the entire session
37
+
38
+ - **RAPPEL 1:** For every non-trivial decision (library choice, naming, structure, framework), STOP and ask: "Does an AGENT.md say something about this?" If yes, apply it. If no, propose the decision to the user.
39
+ - **RAPPEL 2:** Every time you learn something important (the user corrects you, you discover a convention, you make a technical choice), STOP. Write it immediately to an AGENT.md (root or subfolder, depending on scope). Do NOT say "I'll note it later". It is NOW.
40
+ - **RAPPEL 3:** No format is imposed on AGENT.md content. One line is enough if it's clear. What matters is that the next session can use it.
41
+
42
+ ## FINAL STEP (MANDATORY before saying "session done")
43
+
44
+ You CANNOT end a session without all three of the following. DO NOT say "done" until each box is checked.
45
+
46
+ - [ ] Task status in TASKS.md is `[x]` (or `[!]` if blocked)
47
+ - [ ] A worklog exists at `.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md` containing: what was done, decisions made, files modified, and clear next steps
48
+ - [ ] You have asked the user the following question and recorded the answer in the worklog: `What did this session learn about this project that deserves to live in an AGENT.md?`
49
+
50
+ When all three boxes are checked, you may say `session complete`.
@@ -0,0 +1,37 @@
1
+ ---
2
+ name: protocol-task
3
+ description: 'Mandatory procedure for starting a new task within an active session. Invoked at task start, before any code is touched.'
4
+ ---
5
+
6
+ # Protocol Task
7
+
8
+ **Goal:** Confirm context, declare intent, and avoid scope drift.
9
+ **Your Role:** Disciplined agent that respects local conventions.
10
+
11
+ ## STEP 0 — STOP
12
+
13
+ You are about to begin a new task. DO NOT touch code before the end of Step 2.
14
+
15
+ ## STEP 1 — Build the precise fractal context for this task
16
+
17
+ 1. Run `autonomos agents <path-to-target-file-or-folder>` to get the **ordered list of ancestor AGENT.md files** for the file or folder you'll be working in. The output is root-first; non-existent ancestors are silently skipped.
18
+ 2. Read each returned AGENT.md **in order** (root → target). This is your precise fractal context for this task.
19
+ 3. If no local `AGENT.md` exists at the target AND you have worked in that folder multiple times before, propose to the user: `This folder has no AGENT.md yet. Should we create one to crystallize the conventions we have established here?`
20
+
21
+ ## STEP 2 — Declare the plan
22
+
23
+ State in 3 to 5 steps what you intend to do for this task. No more. The user must be able to say `OK` or adjust before you begin.
24
+
25
+ ## STEP 3 — Execute
26
+
27
+ Mark the task `[/]` in TASKS.md, then execute your plan.
28
+
29
+ ## DURING EXECUTION — three reminders
30
+
31
+ - **REMINDER 1:** For every non-trivial decision, consult the relevant AGENT.md.
32
+ - **REMINDER 2:** For every new learning, append a new line to an AGENT.md. If the new learning contradicts an existing one, replace the old entry in place and log the change in the worklog. AGENT.md stays a sharp current-state document, not a log.
33
+ - **REMINDER 3:** You may edit any AGENT.md at any time. No format is imposed. What matters is that the next session can use it.
34
+
35
+ ## END OF TASK
36
+
37
+ When the task is complete, mark it `[x]` in TASKS.md and invoke the `protocol-crystallize` workflow.
package/package.json CHANGED
@@ -1,27 +1,46 @@
1
1
  {
2
2
  "name": "@autonomos/core",
3
- "version": "0.0.1",
3
+ "version": "0.1.0",
4
4
  "description": "SDK and core definitions for the Agent Protocol",
5
5
  "type": "module",
6
- "main": "./dist/index.mjs",
7
6
  "types": "./dist/index.d.mts",
8
7
  "keywords": [
9
8
  "agent",
10
9
  "protocol",
11
10
  "ai",
12
- "workflow"
11
+ "workflow",
12
+ "ai-agent",
13
+ "mcp",
14
+ "autonomy"
13
15
  ],
14
16
  "author": "Autonomos",
15
17
  "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/saoudi-h/autonomos.git",
21
+ "directory": "packages/core"
22
+ },
23
+ "bugs": {
24
+ "url": "https://github.com/saoudi-h/autonomos/issues"
25
+ },
26
+ "homepage": "https://github.com/saoudi-h/autonomos/tree/main/packages/core#readme",
27
+ "publishConfig": {
28
+ "access": "public"
29
+ },
30
+ "files": [
31
+ "dist",
32
+ "README.md",
33
+ "LICENSE"
34
+ ],
16
35
  "devDependencies": {
36
+ "@tala-tools/eslint": "0.1.3",
37
+ "@tala-tools/prettier": "0.0.3",
38
+ "@tala-tools/tsconfig": "0.0.1",
39
+ "@tala-tools/tsdown": "0.1.3",
17
40
  "@types/js-yaml": "4.0.9",
18
41
  "typescript": "^5.0.0",
19
- "@repo/eslint": "1.0.0",
20
- "@repo/prettier": "1.0.0",
21
- "@repo/tsdown": "1.0.0",
22
42
  "@repo/vitest": "1.0.0"
23
43
  },
24
- "module": "./dist/index.mjs",
25
44
  "exports": {
26
45
  ".": "./dist/index.mjs",
27
46
  "./package.json": "./package.json"
@@ -32,13 +51,13 @@
32
51
  },
33
52
  "scripts": {
34
53
  "dev": "tsdown --watch",
35
- "build": "tsdown",
54
+ "build": "tsdown && cp ../../LICENSE .",
36
55
  "lint": "eslint . --max-warnings 0",
37
56
  "lint:fix": "eslint . --max-warnings 0 --fix",
38
57
  "format:check": "prettier \"**/*\" --ignore-unknown --list-different",
39
58
  "format:fix": "prettier \"**/*\" --ignore-unknown --write",
40
- "clean": "rimraf node_modules dist",
41
- "typecheck": "tsc -p tsconfig.json --noEmit",
59
+ "clean": "rimraf node_modules dist LICENSE",
60
+ "typecheck": "tsgo --noEmit",
42
61
  "test": "vitest",
43
62
  "test:ui": "vitest --ui",
44
63
  "test:run": "vitest run",
@@ -1,15 +0,0 @@
1
-
2
- > @autonomos/core@0.0.1 build /home/runner/work/autonomos/autonomos/packages/core
3
- > tsdown
4
-
5
- ℹ tsdown v0.18.4 powered by rolldown v1.0.0-beta.57
6
- ℹ config file: /home/runner/work/autonomos/autonomos/packages/core/tsdown.config.ts
7
- ℹ entry: src/index.ts
8
- ℹ tsconfig: tsconfig.json
9
- ℹ Build start
10
- ℹ dist/index.mjs  9.78 kB │ gzip: 4.19 kB
11
- ℹ dist/index.d.mts 17.09 kB │ gzip: 4.28 kB
12
- ℹ 2 files, total: 26.88 kB
13
- ✔ Build complete in 1302ms
14
- ✔ [publint] No issues found (329ms)
15
- 🙏 Build succeeded!
package/eslint.config.ts DELETED
@@ -1,18 +0,0 @@
1
- import type { Config } from '@repo/eslint'
2
- import { base } from '@repo/eslint'
3
- import { defineConfig } from 'eslint/config'
4
-
5
- const config: Config[] = defineConfig([
6
- ...base,
7
- {
8
- ignores: [
9
- 'eslint.config.ts',
10
- 'eslint-types.d.ts',
11
- 'prettier.config.mjs',
12
- 'lint-staged.config.mjs',
13
- 'tsdown.config.ts',
14
- ],
15
- },
16
- ])
17
-
18
- export default config
@@ -1,4 +0,0 @@
1
- export default {
2
- '**/*.{ts,tsx}': ['prettier --write', 'eslint --fix --no-warn-ignored'],
3
- '**/*.{json,md,mdx}': 'prettier --write',
4
- }
@@ -1,3 +0,0 @@
1
- import baseConfig from '@repo/prettier'
2
-
3
- export default baseConfig
package/src/constants.ts DELETED
@@ -1,35 +0,0 @@
1
- /**
2
- * Protocol version using SemVer
3
- * Alpha phase - not yet published to npm
4
- */
5
- export const PROTOCOL_VERSION = '0.1.0-alpha'
6
-
7
- /**
8
- * Directory name for Autonomos configuration
9
- */
10
- export const AUTONOMOS_DIR = '.autonomos'
11
-
12
- /**
13
- * Manifest filename
14
- */
15
- export const MANIFEST_FILE = 'manifest.json'
16
-
17
- /**
18
- * Protocol filename
19
- */
20
- export const PROTOCOL_FILE = 'PROTOCOL.md'
21
-
22
- /**
23
- * Tasks filename
24
- */
25
- export const TASKS_FILE = 'TASKS.md'
26
-
27
- /**
28
- * Agent context filename (at project root)
29
- */
30
- export const AGENT_FILE = 'AGENT.md'
31
-
32
- /**
33
- * Worklogs directory name
34
- */
35
- export const WORKLOGS_DIR = 'worklogs'
package/src/index.ts DELETED
@@ -1,17 +0,0 @@
1
- // Constants
2
- export * from './constants'
3
- export * from './schemas/manifest'
4
-
5
- // Types
6
- export * from './types'
7
-
8
- // Templates
9
- export * from './templates/agent'
10
- export * from './templates/manifest'
11
- export * from './templates/protocol'
12
- export * from './templates/tasks'
13
- export * from './templates/worklog'
14
-
15
- // Parsers
16
- export * from './parsers/agent-parser'
17
- export * from './parsers/task-parser'
@@ -1,61 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { AgentParser } from './agent-parser'
3
-
4
- describe('AgentParser', () => {
5
- it('should parse an AGENT.md with standard title correctly', () => {
6
- const markdown = '# AGENT CONTEXT: My Project\n\n## Section 1\nHello'
7
- const context = AgentParser.parse(markdown)
8
- expect(context.title).toBe('My Project')
9
- expect(context.sections).toHaveLength(1)
10
- expect(context.sections[0]!.title).toBe('Section 1')
11
- expect(context.sections[0]!.content).toBe('Hello')
12
- })
13
-
14
- it('should parse multiple sections correctly', () => {
15
- const markdown = `
16
- # AGENT CONTEXT: Test
17
- ## Context & Objectives
18
- Objective 1
19
- ## Workflow & Preferences
20
- Strict Linting
21
- `
22
- const context = AgentParser.parse(markdown)
23
- expect(context.sections).toHaveLength(2)
24
- expect(context.sections[0]!.title).toBe('Context & Objectives')
25
- expect(context.sections[0]!.content).toBe('Objective 1')
26
- expect(context.sections[1]!.title).toBe('Workflow & Preferences')
27
- expect(context.sections[1]!.content).toBe('Strict Linting')
28
- })
29
-
30
- it('should handle alternative title format', () => {
31
- const markdown = '# Simple Title\n## Content'
32
- const context = AgentParser.parse(markdown)
33
- expect(context.title).toBe('Simple Title')
34
- })
35
-
36
- it('should parse YAML frontmatter correctly', () => {
37
- const markdown = `---
38
- name: "Advanced Agent"
39
- stack: ["React", "Node"]
40
- status: "Active"
41
- ---
42
- # AGENT CONTEXT: Should ignore H1 if name exists
43
- ## Section 1
44
- Content`
45
- const context = AgentParser.parse(markdown)
46
- expect(context.title).toBe('Advanced Agent')
47
- expect(context.metadata).toEqual({
48
- name: 'Advanced Agent',
49
- stack: ['React', 'Node'],
50
- status: 'Active',
51
- })
52
- expect(context.sections).toHaveLength(1)
53
- expect(context.sections[0]!.title).toBe('Section 1')
54
- })
55
-
56
- it('should return default title if missing', () => {
57
- const markdown = '## No Title'
58
- const context = AgentParser.parse(markdown)
59
- expect(context.title).toBe('Unknown Agent')
60
- })
61
- })
@@ -1,80 +0,0 @@
1
- import yaml from 'js-yaml'
2
- import type { AgentContext, AgentSection } from '../types'
3
-
4
- export class AgentParser {
5
- /**
6
- * Parse an AGENT.md content into a structured AgentContext
7
- */
8
- static parse(markdown: string): AgentContext {
9
- let content = markdown
10
- let metadata: Record<string, any> = {}
11
-
12
- // Parse Frontmatter
13
- const frontmatterRegex = /^---\r?\n([\s\S]*?)\r?\n---/
14
- const match = markdown.match(frontmatterRegex)
15
- if (match) {
16
- try {
17
- metadata = yaml.load(match[1] as string) as Record<string, any>
18
- content = markdown.slice(match[0].length).trim()
19
- } catch (e) {
20
- console.error('Failed to parse Agent frontmatter:', e)
21
- }
22
- }
23
-
24
- const lines = content.split(/\r?\n/)
25
- const sections: AgentSection[] = []
26
- let title = metadata.name ?? 'Unknown Agent'
27
- let currentSection: AgentSection | null = null
28
- let currentContent: string[] = []
29
-
30
- for (const line of lines) {
31
- // Parse Title (Only if not already set by frontmatter)
32
- if (line.startsWith('# ') && !metadata.name) {
33
- const rawTitle = line.replace('# ', '').trim()
34
- // Handle "AGENT CONTEXT: [Name]" format
35
- if (rawTitle.toUpperCase().startsWith('AGENT CONTEXT:')) {
36
- title = rawTitle
37
- .slice(14)
38
- .replace(/^[:\s-]+/, '')
39
- .trim()
40
- } else {
41
- title = rawTitle
42
- }
43
- continue
44
- }
45
-
46
- // Parse Sections
47
- if (line.startsWith('## ')) {
48
- // Save previous section
49
- if (currentSection) {
50
- currentSection.content = currentContent.join('\n').trim()
51
- sections.push(currentSection)
52
- }
53
-
54
- currentSection = {
55
- title: line.replace('## ', '').trim(),
56
- content: '',
57
- }
58
- currentContent = []
59
- continue
60
- }
61
-
62
- // Collect content
63
- if (currentSection) {
64
- currentContent.push(line)
65
- }
66
- }
67
-
68
- // Save last section
69
- if (currentSection) {
70
- currentSection.content = currentContent.join('\n').trim()
71
- sections.push(currentSection)
72
- }
73
-
74
- return {
75
- title,
76
- sections,
77
- metadata,
78
- }
79
- }
80
- }
@@ -1,60 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { TaskParser } from './task-parser'
3
-
4
- describe('TaskParser', () => {
5
- it('should parse a TODO task correctly', () => {
6
- const markdown = '- [ ] **[TASK-01]** Initial task `Priority: 🔴 Critical` `Complexity: S`'
7
- const tasks = TaskParser.parse(markdown)
8
- expect(tasks).toHaveLength(1)
9
- expect(tasks[0]).toEqual({
10
- id: 'TASK-01',
11
- title: 'Initial task',
12
- priority: '🔴 Critical',
13
- complexity: 'S',
14
- status: 'TODO',
15
- })
16
- })
17
-
18
- it('should parse an IN_PROGRESS task correctly', () => {
19
- const markdown = '- [/] **[CLI-01]** Coding `Priority: 🟠 High` `Complexity: M`'
20
- const tasks = TaskParser.parse(markdown)
21
- expect(tasks).toHaveLength(1)
22
- expect(tasks[0]!.status).toBe('IN_PROGRESS')
23
- })
24
-
25
- it('should parse a DONE task correctly', () => {
26
- const markdown = '- [x] **[DOC-01]** Writing `Priority: 🔵 Medium` `Complexity: L`'
27
- const tasks = TaskParser.parse(markdown)
28
- expect(tasks).toHaveLength(1)
29
- expect(tasks[0]!.status).toBe('DONE')
30
- })
31
-
32
- it('should parse a BLOCKED task correctly', () => {
33
- const markdown = '- [!] **[CORE-01]** Waiting `Priority: ⚪ Low` `Complexity: XL`'
34
- const tasks = TaskParser.parse(markdown)
35
- expect(tasks).toHaveLength(1)
36
- expect(tasks[0]!.status).toBe('BLOCKED')
37
- })
38
-
39
- it('should parse multiple tasks across lines', () => {
40
- const markdown = `
41
- # Tasks
42
- - [ ] **[T1]** One \`Priority: 🔴 Critical\` \`Complexity: S\`
43
- - [x] **[T2]** Two \`Priority: 🟠 High\` \`Complexity: M\`
44
- `
45
- const tasks = TaskParser.parse(markdown)
46
- expect(tasks).toHaveLength(2)
47
- expect(tasks[0]!.id).toBe('T1')
48
- expect(tasks[1]!.id).toBe('T2')
49
- })
50
-
51
- it('should ignore non-task lines', () => {
52
- const markdown = `
53
- # Legend
54
- This is some text.
55
- - This is a list but not a task.
56
- `
57
- const tasks = TaskParser.parse(markdown)
58
- expect(tasks).toHaveLength(0)
59
- })
60
- })
@@ -1,40 +0,0 @@
1
- import type { Complexity, Priority, Task, TaskStatus } from '../types'
2
-
3
- export class TaskParser {
4
- static parse(markdown: string): Task[] {
5
- const tasks: Task[] = []
6
- const lines = markdown.split(/\r?\n/)
7
- const taskRegex = /- \[([ x/!])\] \*\*\[(.+)\]\*\* (.+) `Priority: (.+)` `Complexity: (.+)`/
8
-
9
- for (const line of lines) {
10
- const match = line.match(taskRegex)
11
- if (match) {
12
- const [, statusChar = ' ', id = '', title = '', priority = '', complexity = ''] =
13
- match
14
- tasks.push({
15
- id,
16
- title: title.trim(),
17
- priority: priority as Priority,
18
- complexity: complexity as Complexity,
19
- status: this.mapStatus(statusChar),
20
- })
21
- }
22
- }
23
- return tasks
24
- }
25
-
26
- private static mapStatus(char: string): TaskStatus {
27
- switch (char) {
28
- case ' ':
29
- return 'TODO'
30
- case '/':
31
- return 'IN_PROGRESS'
32
- case 'x':
33
- return 'DONE'
34
- case '!':
35
- return 'BLOCKED'
36
- default:
37
- return 'TODO'
38
- }
39
- }
40
- }
@@ -1,13 +0,0 @@
1
- import { z } from 'zod'
2
-
3
- /**
4
- * Manifest Schema for .autonomos/manifest.json
5
- */
6
- export const ManifestSchema = z.object({
7
- protocolVersion: z.string().describe('Version of the Agent Protocol specification'),
8
- cliVersion: z.string().describe('Version of the CLI that last updated this project'),
9
- initializedAt: z.string().datetime().describe('ISO timestamp of project initialization'),
10
- lastUpdated: z.string().datetime().describe('ISO timestamp of last protocol update'),
11
- })
12
-
13
- export type Manifest = z.infer<typeof ManifestSchema>
@@ -1,43 +0,0 @@
1
- /**
2
- * Template for AGENT.md - The context anchor at project root
3
- * @param projectName - Name of the project to personalize the template
4
- */
5
- export function generateAgentTemplate(projectName: string = 'Project'): string {
6
- return `---
7
- name: "${projectName}"
8
- type: "project"
9
- status: "active"
10
- ---
11
- # AGENT CONTEXT: ${projectName}
12
-
13
- ## 🧠 Context & Objectives
14
-
15
- *Describe what this project does and its main goals.*
16
-
17
- ## ⚙️ Workflow & Preferences
18
-
19
- - **Commits:** Conventional Commits
20
- - **Language:** English
21
-
22
- ## 🏗 Stack & Architecture
23
-
24
- - **Tech:** *(List frameworks, libraries)*
25
- - **Patterns:** *(Architecture patterns used)*
26
-
27
- ## 📁 Key Directories
28
-
29
- | Path | Description |
30
- |------|-------------|
31
- | \`src/\` | Source code |
32
- | \`.autonomos/\` | Agent Protocol files |
33
-
34
- ## ⚠️ Known Constraints
35
-
36
- *List any technical debts, missing features, or external limitations.*
37
- `
38
- }
39
-
40
- /**
41
- * Default AGENT.md template
42
- */
43
- export const AGENT_TEMPLATE = generateAgentTemplate()
@@ -1,26 +0,0 @@
1
- import { describe, expect, it } from 'vitest'
2
- import { createManifest, parseManifest } from './manifest'
3
-
4
- describe('Manifest Parser', () => {
5
- it('should validate a correct manifest correctly', () => {
6
- const manifest = createManifest('0.0.1')
7
- const json = JSON.stringify(manifest)
8
- const parsed = parseManifest(json)
9
- expect(parsed.cliVersion).toBe('0.0.1')
10
- })
11
-
12
- it('should throw error on invalid manifest', () => {
13
- const invalidJson = JSON.stringify({
14
- protocolVersion: '1.0',
15
- // Missing fields or invalid types
16
- })
17
- expect(() => parseManifest(invalidJson)).toThrow()
18
- })
19
-
20
- it('should throw error on invalid date format', () => {
21
- const manifest = createManifest('0.0.1')
22
- manifest.initializedAt = 'invalid-date'
23
- const json = JSON.stringify(manifest)
24
- expect(() => parseManifest(json)).toThrow()
25
- })
26
- })
@@ -1,30 +0,0 @@
1
- import { PROTOCOL_VERSION } from '../constants'
2
- import { ManifestSchema, type Manifest } from '../schemas/manifest'
3
-
4
- /**
5
- * Creates a new manifest object with current timestamps
6
- */
7
- export function createManifest(cliVersion: string): Manifest {
8
- const now = new Date().toISOString()
9
- return {
10
- protocolVersion: PROTOCOL_VERSION,
11
- cliVersion,
12
- initializedAt: now,
13
- lastUpdated: now,
14
- }
15
- }
16
-
17
- /**
18
- * Generates the manifest.json content as a formatted string
19
- */
20
- export function generateManifestContent(manifest: Manifest): string {
21
- return JSON.stringify(manifest, null, 4) + '\n'
22
- }
23
-
24
- /**
25
- * Parses manifest.json content into a Manifest object with validation
26
- */
27
- export function parseManifest(content: string): Manifest {
28
- const data = JSON.parse(content)
29
- return ManifestSchema.parse(data)
30
- }