@autonomos/core 0.0.1

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,61 @@
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
+ })
@@ -0,0 +1,80 @@
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
+ }
@@ -0,0 +1,60 @@
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
+ })
@@ -0,0 +1,40 @@
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
+ }
@@ -0,0 +1,13 @@
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>
@@ -0,0 +1,43 @@
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()
@@ -0,0 +1,26 @@
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
+ })
@@ -0,0 +1,30 @@
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
+ }
@@ -0,0 +1,157 @@
1
+ import { PROTOCOL_VERSION } from '../constants'
2
+
3
+ /**
4
+ * The immutable Protocol kernel template
5
+ * This is the core specification that defines how AI agents interact with the project
6
+ */
7
+ export const PROTOCOL_TEMPLATE = `# AI AGENT PROTOCOL (v${PROTOCOL_VERSION})
8
+
9
+ > **SYSTEM INTEGRITY WARNING:** This file is the IMMUTABLE KERNEL of the project's AI workflow. Do not modify this file. Your instructions are to execute tasks and manage the project state based strictly on the definitions below.
10
+
11
+ ## 0. ⚡ QUICK REFERENCE
12
+ | Action | File / Command |
13
+ |--------|----------------|
14
+ | **Get Context** | Read \`AGENT.md\` (Root + Local) |
15
+ | **Pick Task** | Check \`.autonomos/TASKS.md\` (Highest Priority) |
16
+ | **Track Progress** | Update \`.autonomos/TASKS.md\` to \`[/]\` |
17
+ | **Log Session** | Create \`.autonomos/worklogs/YYYY-MM-DD-[TASK_ID].md\` |
18
+ | **Finalize Task** | Update \`.autonomos/TASKS.md\` to \`[x]\` + Link Worklog |
19
+
20
+ ---
21
+
22
+ ## 1. BOOTSTRAPPING & INITIALIZATION
23
+ **IF** this is your first time seeing this project, or if key system files are missing, you **MUST** initialize them immediately before doing any work.
24
+
25
+ ### Check for existence:
26
+ 1. \`.autonomos/TASKS.md\` (task registry)
27
+ 2. \`.autonomos/worklogs/\` (directory)
28
+ 3. \`AGENT.md\` (at project root)
29
+
30
+ **IF MISSING**, create them using the **TEMPLATES** defined in Section 2.
31
+
32
+ ---
33
+
34
+ ## 2. STRICT FILE STRUCTURES & TEMPLATES
35
+ You must adhere to these schemas. Do not invent new formats.
36
+
37
+ ### A. The Task Registry (\`.autonomos/TASKS.md\`)
38
+ **Role:** The single source of truth for project state.
39
+ **Location:** \`.autonomos/TASKS.md\`
40
+ **Structure:**
41
+ * Must use the specific Header and Legend.
42
+ * Tasks must follow the format: \`- [Status] **[ID]** Title of task \`Priority\` \`Complexity\`\`
43
+ * Valid Priorities: \`🔴 Critical\`, \`🟠 High\`, \`🔵 Medium\`, \`⚪ Low\`
44
+ * Valid Complexities: \`S\`, \`M\`, \`L\`, \`XL\`
45
+ * Valid Statuses: \` [ ] \` (Todo), \`[/]\` (In Progress), \` [x] \` (Done), \` [!] \` (Blocked)
46
+
47
+ **TEMPLATE FOR NEW TASKS.md:**
48
+ \`\`\`markdown
49
+ # PROJECT TASKS & ROADMAP
50
+
51
+ > **LEGEND**
52
+ > **Priority:** [🔴 Critical] [🟠 High] [🔵 Medium] [⚪ Low]
53
+ > **Complexity:** [S] Small (1h), [M] Medium (4h), [L] Large (1-2 days), [XL] Huge (Planning req.)
54
+ > **Status:** [ ] Todo, [/] In Progress, [x] Done, [!] Blocked
55
+
56
+ ## 🚀 Active Sprint
57
+ - [ ] **[INIT-01]** Verify project structure and context \`Priority: 🔴\` \`Complexity: S\`
58
+
59
+ ## 🔮 Backlog
60
+ *(Empty initially)*
61
+
62
+ \`\`\`
63
+
64
+ ### B. The Worklog (\`.autonomos/worklogs/\`)
65
+ **Role:** Detailed history of complex tasks to save context tokens for future sessions.
66
+ **Location:** \`.autonomos/worklogs/YYYY-MM-DD-[TASK_ID]-[slug].md\`
67
+ **Trigger:** Create a log when a task is finished, blocked, or if the session ends mid-task.
68
+
69
+ **TEMPLATE FOR WORKLOG:**
70
+ \`\`\`markdown
71
+ # WORKLOG: [TASK ID] [Task Name]
72
+ **Date:** YYYY-MM-DD
73
+ **Agent Status:** [Complete / Partial / Blocked]
74
+
75
+ ## 📝 Description
76
+ Brief summary of what was attempted/achieved.
77
+
78
+ ## 🛠 Technical Details
79
+ - **Files Modified:** List of files.
80
+ - **Key Decisions:** Why did you choose this library/pattern?
81
+ - **Challenges:** Any errors encountered and how they were solved.
82
+
83
+ ## ⏭ Next Steps / Context for Successor
84
+ Clear instructions for the next agent picking this up.
85
+ \`\`\`
86
+
87
+ ### C. The Context Anchor (\`AGENT.md\`)
88
+ **Role:** Fractal knowledge base. Contains facts, stack details, and user preferences.
89
+ **Location:** Root (\`/AGENT.md\`) and any subdirectory requiring specific context (e.g., \`/packages/core/AGENT.md\`).
90
+
91
+ **TEMPLATE FOR AGENT.md:**
92
+ \`\`\`markdown
93
+ ---
94
+ name: "[Name of directory or project]"
95
+ type: "[project / package / module / script]"
96
+ status: "[active / maintenance / poc]"
97
+ ---
98
+ # AGENT CONTEXT: [Directory Name or Root]
99
+
100
+ ## 🧠 Context & Objectives
101
+ What does this specific folder/module do?
102
+
103
+ ## ⚙️ Workflow & Preferences
104
+ - **Commits:** [e.g. Conventional Commits]
105
+ - **Language:** [English (default)]
106
+
107
+ ## 🏗 Stack & Architecture
108
+ - **Tech:** [Frameworks, Libs specific to this module]
109
+ - **Patterns:** [Architecture patterns used]
110
+
111
+ ## 📁 Key Directories
112
+ | Path | Description |
113
+ |------|-------------|
114
+ | \`src/\` | Source code |
115
+ | \`scripts/\` | Build or utility scripts |
116
+
117
+ ## ⚠️ Known Constraints
118
+ *List any technical debts, missing features, or external limitations.*
119
+ \`\`\`
120
+
121
+ ## 3. CORE WORKFLOW (The Loop)
122
+
123
+ ### Phase 1: Context Loading (Read-Only)
124
+ 1. **Read Root AGENT.md:** Absorb global preferences (Commit style, package manager, strict rules).
125
+ 2. **Read .autonomos/TASKS.md:** Identify the highest priority task (🔴 or 🟠) that is not [x] or [!].
126
+ 3. **Read Target AGENT.md:** If the task is in a subdirectory, check for a local \`AGENT.md\`.
127
+ * *Note:* If the local \`AGENT.md\` contradicts the root, the local one wins for that specific scope.
128
+
129
+ ### Phase 2: Execution
130
+ 1. **Mark the task as [/] (In Progress)** in \`.autonomos/TASKS.md\`.
131
+ 2. **Perform the task.**
132
+ 3. **Constraint Check:** Constantly refer to "Workflow & Preferences" in \`AGENT.md\`.
133
+
134
+ ### Phase 3: Crystallization (Write-Only)
135
+ Before ending the session, you **MUST**:
136
+
137
+ 1. **Update AGENT.md:**
138
+ * Did you learn a new command? Add it to ⚙️ Workflow.
139
+ * Did you create a new complex module (>5 files)? Create a new \`AGENT.md\` inside it using the template above.
140
+
141
+ 2. **Create Worklog:**
142
+ * Write a file in \`.autonomos/worklogs/\` summarizing your work.
143
+
144
+ 3. **Update TASKS.md:**
145
+ * Mark task as [x] (Done) or [!] (Blocked).
146
+ * Add a link to your worklog: \`- [x] **[ID]** Title... *See: .autonomos/worklogs/...*\`
147
+
148
+ ## 4. METADATA RULES
149
+ * **Language:** Documentation (\`AGENT.md\`, \`TASKS.md\`) must be written in **English** unless specified otherwise in User Preferences.
150
+ * **Tone:** Technical, concise, "Fact-based". No fluff.
151
+ * **Anonymity:** You are a continuous entity. Refer to previous work as "we" or "the project", not "the previous AI".
152
+ `
153
+
154
+ /**
155
+ * @deprecated Use PROTOCOL_TEMPLATE instead
156
+ */
157
+ export const PROTOCOL_TEMPLATE_V2026_1 = PROTOCOL_TEMPLATE
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Template for TASKS.md - The task registry
3
+ */
4
+ export const TASKS_TEMPLATE = `# PROJECT TASKS & ROADMAP
5
+
6
+ > **LEGEND**
7
+ > **Priority:** [🔴 Critical] [🟠 High] [🔵 Medium] [⚪ Low]
8
+ > **Complexity:** [S] Small (1h), [M] Medium (4h), [L] Large (1-2 days), [XL] Huge (Planning req.)
9
+ > **Status:** [ ] Todo, [/] In Progress, [x] Done, [!] Blocked
10
+
11
+ ## 🚀 Active Sprint
12
+
13
+ - [ ] **[INIT-01]** Review project context and structure \`Priority: 🔵\` \`Complexity: S\`
14
+
15
+ ## 🔮 Backlog
16
+
17
+ *(Add future tasks here)*
18
+ `
@@ -0,0 +1,37 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { generateWorklogContent } from './worklog'
3
+
4
+ describe('Worklog Template', () => {
5
+ it('should generate a valid worklog content', () => {
6
+ const content = generateWorklogContent({
7
+ taskId: 'TASK-01',
8
+ taskName: 'Fixing Bug',
9
+ status: 'Complete',
10
+ description: 'Fixed the line splitting issue.',
11
+ filesModified: ['src/parsers/task-parser.ts'],
12
+ decisions: ['Used regex for splitting'],
13
+ challenges: ['Template literal escaping'],
14
+ nextSteps: ['Add more tests'],
15
+ })
16
+
17
+ expect(content).toContain('# WORKLOG: [TASK-01] Fixing Bug')
18
+ expect(content).toContain('**Agent Status:** [Complete]')
19
+ expect(content).toContain('- src/parsers/task-parser.ts')
20
+ expect(content).toContain('- Used regex for splitting')
21
+ })
22
+
23
+ it('should use current date if not provided', () => {
24
+ const content = generateWorklogContent({
25
+ taskId: 'T',
26
+ taskName: 'N',
27
+ status: 'Partial',
28
+ description: 'D',
29
+ filesModified: [],
30
+ decisions: [],
31
+ challenges: [],
32
+ nextSteps: [],
33
+ })
34
+ const today = new Date().toISOString().split('T')[0]
35
+ expect(content).toContain(`**Date:** ${today}`)
36
+ })
37
+ })
@@ -0,0 +1,55 @@
1
+ import type { TaskStatus } from '../types'
2
+
3
+ interface WorklogOptions {
4
+ taskId: string
5
+ taskName: string
6
+ date?: string
7
+ status: 'Complete' | 'Partial' | 'Blocked'
8
+ description: string
9
+ filesModified: string[]
10
+ decisions: string[]
11
+ challenges: string[]
12
+ nextSteps: string[]
13
+ }
14
+
15
+ /**
16
+ * Generate a Worklog markdown content
17
+ */
18
+ export function generateWorklogContent(options: WorklogOptions): string {
19
+ const date = options.date ?? new Date().toISOString().split('T')[0]
20
+
21
+ return `# WORKLOG: [${options.taskId}] ${options.taskName}
22
+ **Date:** ${date}
23
+ **Agent Status:** [${options.status}]
24
+
25
+ ## 📝 Description
26
+ ${options.description}
27
+
28
+ ## 🛠 Technical Details
29
+ - **Files Modified:**
30
+ ${options.filesModified.map(f => ` - ${f}`).join('\n')}
31
+ - **Key Decisions:**
32
+ ${options.decisions.map(d => ` - ${d}`).join('\n')}
33
+ - **Challenges:**
34
+ ${options.challenges.map(c => ` - ${c}`).join('\n')}
35
+
36
+ ## ⏭ Next Steps / Context for Successor
37
+ ${options.nextSteps.map(s => `- ${s}`).join('\n')}
38
+ `
39
+ }
40
+
41
+ /**
42
+ * Common status mapping for worklogs
43
+ */
44
+ export function mapTaskStatusToWorklogStatus(
45
+ status: TaskStatus
46
+ ): 'Complete' | 'Partial' | 'Blocked' {
47
+ switch (status) {
48
+ case 'DONE':
49
+ return 'Complete'
50
+ case 'BLOCKED':
51
+ return 'Blocked'
52
+ default:
53
+ return 'Partial'
54
+ }
55
+ }
package/src/types.ts ADDED
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Priority levels for tasks
3
+ */
4
+ export type Priority = '🔴 Critical' | '🟠 High' | '🔵 Medium' | '⚪ Low'
5
+
6
+ /**
7
+ * Complexity estimates for tasks
8
+ */
9
+ export type Complexity = 'S' | 'M' | 'L' | 'XL'
10
+
11
+ /**
12
+ * Task status markers
13
+ */
14
+ export type TaskStatus = 'TODO' | 'IN_PROGRESS' | 'DONE' | 'BLOCKED'
15
+
16
+ /**
17
+ * Task entity parsed from TASKS.md
18
+ */
19
+ export interface Task {
20
+ id: string
21
+ title: string
22
+ priority: Priority
23
+ complexity: Complexity
24
+ status: TaskStatus
25
+ worklogPath?: string
26
+ }
27
+
28
+ /**
29
+ * Agent configuration parsed from AGENT.md
30
+ */
31
+ export interface AgentConfig {
32
+ name: string
33
+ description?: string
34
+ stack: string[]
35
+ preferences?: Record<string, any>
36
+ }
37
+
38
+ export interface AgentSection {
39
+ title: string
40
+ content: string
41
+ }
42
+
43
+ export interface AgentContext {
44
+ title: string
45
+ description?: string
46
+ sections: AgentSection[]
47
+ metadata?: Record<string, any>
48
+ }
49
+
50
+ export const PRIORITIES: Priority[] = ['🔴 Critical', '🟠 High', '🔵 Medium', '⚪ Low']
51
+ export const COMPLEXITIES: Complexity[] = ['S', 'M', 'L', 'XL']