@comfanion/workflow 4.1.3 → 4.5.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.
Files changed (58) hide show
  1. package/README.md +1 -2
  2. package/bin/cli.js +343 -5
  3. package/package.json +8 -3
  4. package/src/build-info.json +2 -1
  5. package/src/opencode/ARCHITECTURE.md +7 -6
  6. package/src/opencode/FLOW.yaml +157 -102
  7. package/src/opencode/agents/analyst.md +24 -20
  8. package/src/opencode/agents/architect.md +104 -39
  9. package/src/opencode/agents/change-manager.md +112 -250
  10. package/src/opencode/agents/coder.md +36 -19
  11. package/src/opencode/agents/crawler.md +180 -97
  12. package/src/opencode/agents/dev.md +117 -29
  13. package/src/opencode/agents/pm.md +25 -32
  14. package/src/opencode/agents/researcher.md +116 -241
  15. package/src/opencode/commands/architecture.md +1 -1
  16. package/src/opencode/commands/dev-story.md +1 -5
  17. package/src/opencode/commands/prd.md +1 -1
  18. package/src/opencode/commands/unit-docs.md +170 -0
  19. package/src/opencode/config.yaml +29 -0
  20. package/src/opencode/opencode.json +5 -0
  21. package/src/opencode/skills/adr-writing/SKILL.md +122 -159
  22. package/src/opencode/skills/adr-writing/template.md +130 -0
  23. package/src/opencode/skills/architecture-design/SKILL.md +113 -107
  24. package/src/opencode/skills/architecture-design/template.md +212 -0
  25. package/src/opencode/skills/architecture-validation/SKILL.md +1 -1
  26. package/src/opencode/skills/changelog/template.md +23 -0
  27. package/src/opencode/{workflows/dev-story/instructions.md → skills/dev-story/SKILL.md} +2 -2
  28. package/src/opencode/skills/epic-writing/SKILL.md +116 -264
  29. package/src/opencode/skills/epic-writing/template.md +119 -0
  30. package/src/opencode/skills/prd-validation/SKILL.md +1 -1
  31. package/src/opencode/skills/prd-writing/SKILL.md +79 -43
  32. package/src/opencode/skills/prd-writing/template.md +147 -0
  33. package/src/opencode/skills/requirements-gathering/SKILL.md +128 -78
  34. package/src/opencode/skills/requirements-gathering/template.md +156 -0
  35. package/src/opencode/skills/story-writing/SKILL.md +106 -464
  36. package/src/opencode/skills/story-writing/template.md +214 -0
  37. package/src/opencode/skills/unit-writing/SKILL.md +185 -0
  38. package/src/opencode/skills/unit-writing/template.md +136 -0
  39. package/src/opencode/tools/codeindex.ts +255 -0
  40. package/src/opencode/tools/codesearch.ts +134 -0
  41. package/src/repo-structure/docs/README.md +5 -5
  42. package/src/repo-structure/docs/requirements/README.md +1 -1
  43. package/src/opencode/templates/CHANGELOG.md +0 -82
  44. package/src/opencode/templates/adr-template.md +0 -115
  45. package/src/opencode/templates/architecture-template.md +0 -362
  46. package/src/opencode/templates/epic-template.md +0 -166
  47. package/src/opencode/templates/prd-template.md +0 -479
  48. package/src/opencode/templates/requirements-template.md +0 -132
  49. package/src/opencode/templates/story-template.md +0 -182
  50. /package/src/opencode/{templates/prd-acceptance-criteria-template.md → skills/acceptance-criteria/template.md} +0 -0
  51. /package/src/opencode/{templates/change-proposal-template.md → skills/archiving/template-change-proposal.md} +0 -0
  52. /package/src/opencode/{templates/git-workflow-template.md → skills/coding-standards/template-git.md} +0 -0
  53. /package/src/opencode/{templates/testing-standards-template.md → skills/coding-standards/template-testing.md} +0 -0
  54. /package/src/opencode/{templates/jira-cache-template.yaml → skills/jira-integration/template-cache.yaml} +0 -0
  55. /package/src/opencode/{templates/module-index-template.md → skills/module-documentation/template.md} +0 -0
  56. /package/src/opencode/{templates/sprint-status-template.yaml → skills/sprint-planning/template.yaml} +0 -0
  57. /package/src/opencode/{templates/integration-tests-template.md → skills/test-design/template-integration.md} +0 -0
  58. /package/src/opencode/{templates/module-test-cases-template.md → skills/test-design/template-module.md} +0 -0
@@ -0,0 +1,255 @@
1
+ /**
2
+ * Code Index Status & Management Tool
3
+ *
4
+ * Check indexing status and trigger re-indexing.
5
+ * Supports multiple indexes: code, docs, config.
6
+ *
7
+ * Usage by model:
8
+ * codeindex({ action: "status" })
9
+ * codeindex({ action: "status", index: "docs" })
10
+ * codeindex({ action: "reindex", index: "code" })
11
+ * codeindex({ action: "list" })
12
+ */
13
+
14
+ import { tool } from "@opencode-ai/plugin"
15
+ import path from "path"
16
+ import fs from "fs/promises"
17
+ import { glob } from "glob"
18
+ import ignore from "ignore"
19
+
20
+ // Index presets (duplicated from vectorizer for independence)
21
+ const INDEX_PRESETS: Record<string, { pattern: string; description: string }> = {
22
+ code: {
23
+ pattern: '**/*.{js,ts,jsx,tsx,mjs,cjs,py,go,rs,java,kt,swift,c,cpp,h,hpp,cs,rb,php,scala,clj}',
24
+ description: 'Source code files'
25
+ },
26
+ docs: {
27
+ pattern: '**/*.{md,mdx,txt,rst,adoc}',
28
+ description: 'Documentation files'
29
+ },
30
+ config: {
31
+ pattern: '**/*.{yaml,yml,json,toml,ini,env,xml}',
32
+ description: 'Configuration files'
33
+ },
34
+ all: {
35
+ pattern: '**/*.{js,ts,jsx,tsx,mjs,cjs,py,go,rs,java,kt,swift,c,cpp,h,hpp,cs,rb,php,scala,clj,md,mdx,txt,rst,adoc,yaml,yml,json,toml}',
36
+ description: 'All supported files'
37
+ }
38
+ }
39
+
40
+ export default tool({
41
+ description: `Check codebase index status or trigger re-indexing for semantic search.
42
+
43
+ Actions:
44
+ - "status" → Show index statistics (specify index or see all)
45
+ - "list" → List all available indexes with stats
46
+ - "reindex" → Re-index files (specify which index)
47
+
48
+ Available indexes:
49
+ - "code" - Source code files
50
+ - "docs" - Documentation files
51
+ - "config" - Configuration files
52
+
53
+ Note: Initial indexing takes ~30s to load the embedding model.`,
54
+
55
+ args: {
56
+ action: tool.schema.enum(["status", "list", "reindex"]).describe("Action to perform"),
57
+ index: tool.schema.string().optional().default("code").describe("Index name for status/reindex: code, docs, config"),
58
+ },
59
+
60
+ async execute(args, context) {
61
+ const projectRoot = process.cwd()
62
+ const vectorizerDir = path.join(projectRoot, ".opencode", "vectorizer")
63
+ const vectorsDir = path.join(projectRoot, ".opencode", "vectors")
64
+
65
+ // Check if vectorizer is installed
66
+ const isInstalled = await fs.access(path.join(vectorizerDir, "node_modules"))
67
+ .then(() => true)
68
+ .catch(() => false)
69
+
70
+ if (!isInstalled) {
71
+ return `❌ Vectorizer not installed.
72
+
73
+ To install:
74
+ \`\`\`bash
75
+ npx opencode-workflow vectorizer install
76
+ \`\`\`
77
+
78
+ This will download the embedding model (~100MB) and set up the vector database.`
79
+ }
80
+
81
+ try {
82
+ const vectorizerModule = path.join(vectorizerDir, "index.js")
83
+ const { CodebaseIndexer, INDEX_PRESETS: PRESETS } = await import(`file://${vectorizerModule}`)
84
+
85
+ // LIST: Show all indexes
86
+ if (args.action === "list") {
87
+ const tempIndexer = await new CodebaseIndexer(projectRoot, "code").init()
88
+ const allStats = await tempIndexer.getAllStats()
89
+
90
+ let output = `## Codebase Index Overview\n\n`
91
+ output += `✅ **Vectorizer installed**\n\n`
92
+
93
+ if (allStats.length === 0) {
94
+ output += `⚠️ **No indexes created yet**\n\n`
95
+ output += `Create indexes with:\n`
96
+ output += `\`\`\`bash\n`
97
+ output += `npx opencode-workflow index --index code # Source code\n`
98
+ output += `npx opencode-workflow index --index docs # Documentation\n`
99
+ output += `npx opencode-workflow index --index config # Config files\n`
100
+ output += `\`\`\`\n\n`
101
+ } else {
102
+ output += `### Active Indexes\n\n`
103
+ for (const stat of allStats) {
104
+ output += `**📁 ${stat.indexName}** - ${stat.description}\n`
105
+ output += ` Files: ${stat.fileCount}, Chunks: ${stat.chunkCount}\n\n`
106
+ }
107
+ }
108
+
109
+ output += `### Available Presets\n\n`
110
+ for (const [name, preset] of Object.entries(PRESETS || INDEX_PRESETS) as [string, any][]) {
111
+ const exists = allStats.find((s: any) => s.indexName === name)
112
+ const status = exists ? "✅" : "⬜"
113
+ output += `${status} **${name}**: ${preset.description}\n`
114
+ }
115
+
116
+ output += `\n### Usage\n`
117
+ output += `\`\`\`\n`
118
+ output += `codesearch({ query: "your query", index: "code" })\n`
119
+ output += `codesearch({ query: "deployment guide", index: "docs" })\n`
120
+ output += `codesearch({ query: "api keys", searchAll: true })\n`
121
+ output += `\`\`\``
122
+
123
+ return output
124
+ }
125
+
126
+ // STATUS: Show specific index status
127
+ if (args.action === "status") {
128
+ const indexName = args.index || "code"
129
+ const hashesFile = path.join(vectorsDir, indexName, "hashes.json")
130
+
131
+ try {
132
+ const indexer = await new CodebaseIndexer(projectRoot, indexName).init()
133
+ const stats = await indexer.getStats()
134
+
135
+ // Get sample files
136
+ const hashesContent = await fs.readFile(hashesFile, "utf8")
137
+ const hashes = JSON.parse(hashesContent)
138
+ const sampleFiles = Object.keys(hashes).slice(0, 5)
139
+
140
+ return `## Index Status: "${indexName}"
141
+
142
+ ✅ **Vectorizer installed**
143
+ ✅ **Index active**
144
+
145
+ **Description:** ${stats.description}
146
+ **Files indexed:** ${stats.fileCount}
147
+ **Chunks:** ${stats.chunkCount}
148
+
149
+ **Sample indexed files:**
150
+ ${sampleFiles.map(f => `- ${f}`).join("\n")}
151
+ ${stats.fileCount > 5 ? `- ... and ${stats.fileCount - 5} more` : ""}
152
+
153
+ **Usage:**
154
+ \`\`\`
155
+ codesearch({ query: "your search query", index: "${indexName}" })
156
+ \`\`\`
157
+
158
+ To re-index:
159
+ \`\`\`
160
+ codeindex({ action: "reindex", index: "${indexName}" })
161
+ \`\`\``
162
+
163
+ } catch {
164
+ return `## Index Status: "${indexName}"
165
+
166
+ ✅ **Vectorizer installed**
167
+ ⚠️ **Index "${indexName}" not created yet**
168
+
169
+ To create this index:
170
+ \`\`\`bash
171
+ npx opencode-workflow index --index ${indexName}
172
+ \`\`\`
173
+
174
+ Or use:
175
+ \`\`\`
176
+ codeindex({ action: "reindex", index: "${indexName}" })
177
+ \`\`\``
178
+ }
179
+ }
180
+
181
+ // REINDEX: Re-index specific index (do it directly, no shell)
182
+ if (args.action === "reindex") {
183
+ const indexName = args.index || "code"
184
+
185
+ try {
186
+ const indexer = await new CodebaseIndexer(projectRoot, indexName).init()
187
+
188
+ // Get pattern from preset
189
+ const preset = (PRESETS || INDEX_PRESETS)[indexName]
190
+ const pattern = preset?.pattern || '**/*.{js,ts,py,go,md,yaml,json}'
191
+
192
+ // Load .gitignore
193
+ let ig = ignore()
194
+ try {
195
+ const gitignore = await fs.readFile(path.join(projectRoot, '.gitignore'), 'utf8')
196
+ ig = ig.add(gitignore)
197
+ } catch {}
198
+ ig.add(['node_modules', '.git', 'dist', 'build', '.opencode/vectors', '.opencode/vectorizer'])
199
+
200
+ // Find files
201
+ const files = await glob(pattern, { cwd: projectRoot, nodir: true })
202
+ const filtered = files.filter((f: string) => !ig.ignores(f))
203
+
204
+ let indexed = 0
205
+ let skipped = 0
206
+
207
+ for (const file of filtered) {
208
+ const filePath = path.join(projectRoot, file)
209
+ try {
210
+ const wasIndexed = await indexer.indexFile(filePath)
211
+ if (wasIndexed) {
212
+ indexed++
213
+ } else {
214
+ skipped++
215
+ }
216
+ } catch {
217
+ // Skip files that can't be read
218
+ }
219
+ }
220
+
221
+ // Unload model to free memory
222
+ await indexer.unloadModel()
223
+
224
+ const stats = await indexer.getStats()
225
+
226
+ return `## Re-indexing Complete ✅
227
+
228
+ **Index:** ${indexName}
229
+ **Description:** ${stats.description}
230
+ **Files found:** ${filtered.length}
231
+ **Files indexed:** ${indexed}
232
+ **Files unchanged:** ${skipped}
233
+ **Total chunks:** ${stats.chunkCount}
234
+
235
+ You can now use semantic search:
236
+ \`\`\`
237
+ codesearch({ query: "your search query", index: "${indexName}" })
238
+ \`\`\``
239
+
240
+ } catch (error: any) {
241
+ return `❌ Re-indexing failed: ${error.message}
242
+
243
+ Try:
244
+ 1. Check if vectorizer is installed: \`npx opencode-workflow vectorizer status\`
245
+ 2. Re-install vectorizer: \`npx opencode-workflow vectorizer install\``
246
+ }
247
+ }
248
+
249
+ return `Unknown action: ${args.action}. Use: status, list, or reindex`
250
+
251
+ } catch (error: any) {
252
+ return `❌ Error: ${error.message}`
253
+ }
254
+ },
255
+ })
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Semantic Code Search Tool
3
+ *
4
+ * Allows the AI model to search the codebase using semantic similarity.
5
+ * Uses local embeddings (all-MiniLM-L6-v2) and LanceDB vector store.
6
+ * Supports multiple indexes: code, docs, config, or search all.
7
+ *
8
+ * Usage by model:
9
+ * codesearch({ query: "authentication middleware", limit: 5 })
10
+ * codesearch({ query: "how to deploy", index: "docs" })
11
+ * codesearch({ query: "database config", index: "config" })
12
+ * codesearch({ query: "error handling", searchAll: true })
13
+ *
14
+ * Prerequisites:
15
+ * npx opencode-workflow vectorizer install
16
+ * npx opencode-workflow index --index code
17
+ * npx opencode-workflow index --index docs
18
+ */
19
+
20
+ import { tool } from "@opencode-ai/plugin"
21
+ import path from "path"
22
+ import fs from "fs/promises"
23
+
24
+ export default tool({
25
+ description: `Search the codebase semantically. Use this to find relevant code snippets, functions, or files based on meaning, not just text matching.
26
+
27
+ Available indexes:
28
+ - "code" (default) - Source code files (*.js, *.ts, *.py, *.go, etc.)
29
+ - "docs" - Documentation files (*.md, *.txt, etc.)
30
+ - "config" - Configuration files (*.yaml, *.json, etc.)
31
+ - searchAll: true - Search across all indexes
32
+
33
+ Examples:
34
+ - "authentication logic" → finds auth-related code
35
+ - "database connection handling" → finds DB setup code
36
+ - "how to deploy" with index: "docs" → finds deployment docs
37
+ - "API keys" with index: "config" → finds config with API settings
38
+
39
+ Prerequisites: Run 'npx opencode-workflow index --index <name>' first.`,
40
+
41
+ args: {
42
+ query: tool.schema.string().describe("Semantic search query describing what you're looking for"),
43
+ index: tool.schema.string().optional().default("code").describe("Index to search: code, docs, config, or custom name"),
44
+ limit: tool.schema.number().optional().default(5).describe("Number of results to return (default: 5)"),
45
+ searchAll: tool.schema.boolean().optional().default(false).describe("Search all indexes instead of just one"),
46
+ },
47
+
48
+ async execute(args, context) {
49
+ const projectRoot = process.cwd()
50
+ const vectorizerDir = path.join(projectRoot, ".opencode", "vectorizer")
51
+ const vectorizerModule = path.join(vectorizerDir, "index.js")
52
+
53
+ // Check if vectorizer is installed
54
+ try {
55
+ await fs.access(path.join(vectorizerDir, "node_modules"))
56
+ } catch {
57
+ return `❌ Vectorizer not installed. Run: npx opencode-workflow vectorizer install`
58
+ }
59
+
60
+ try {
61
+ // Dynamic import of the vectorizer
62
+ const { CodebaseIndexer } = await import(`file://${vectorizerModule}`)
63
+
64
+ let allResults: any[] = []
65
+ const limit = args.limit || 5
66
+ const indexName = args.index || "code"
67
+
68
+ if (args.searchAll) {
69
+ // Search all indexes
70
+ const tempIndexer = await new CodebaseIndexer(projectRoot, "code").init()
71
+ const indexes = await tempIndexer.listIndexes()
72
+
73
+ if (indexes.length === 0) {
74
+ return `❌ No indexes found. Run: npx opencode-workflow index --index code`
75
+ }
76
+
77
+ for (const idx of indexes) {
78
+ const indexer = await new CodebaseIndexer(projectRoot, idx).init()
79
+ const results = await indexer.search(args.query, limit)
80
+ allResults.push(...results.map((r: any) => ({ ...r, _index: idx })))
81
+ }
82
+
83
+ // Sort by distance and take top N
84
+ allResults.sort((a, b) => (a._distance || 0) - (b._distance || 0))
85
+ allResults = allResults.slice(0, limit)
86
+
87
+ } else {
88
+ // Search specific index
89
+ const hashesFile = path.join(projectRoot, ".opencode", "vectors", indexName, "hashes.json")
90
+ try {
91
+ await fs.access(hashesFile)
92
+ } catch {
93
+ return `❌ Index "${indexName}" not found. Run: npx opencode-workflow index --index ${indexName}`
94
+ }
95
+
96
+ const indexer = await new CodebaseIndexer(projectRoot, indexName).init()
97
+ const results = await indexer.search(args.query, limit)
98
+ allResults = results.map((r: any) => ({ ...r, _index: indexName }))
99
+ }
100
+
101
+ if (allResults.length === 0) {
102
+ const scope = args.searchAll ? "any index" : `index "${indexName}"`
103
+ return `No results found in ${scope} for: "${args.query}"\n\nTry:\n- Different keywords\n- Re-index with: npx opencode-workflow index --index ${indexName} --force`
104
+ }
105
+
106
+ // Format results for the model
107
+ const scope = args.searchAll ? "all indexes" : `index "${indexName}"`
108
+ let output = `## Search Results for: "${args.query}" (${scope})\n\n`
109
+
110
+ for (let i = 0; i < allResults.length; i++) {
111
+ const r = allResults[i]
112
+ const score = r._distance ? (1 - r._distance).toFixed(3) : "N/A"
113
+ const indexLabel = args.searchAll ? ` [${r._index}]` : ""
114
+
115
+ output += `### ${i + 1}. ${r.file}${indexLabel}\n`
116
+ output += `**Relevance:** ${score}\n\n`
117
+ output += "```\n"
118
+ // Truncate long content
119
+ const content = r.content.length > 500
120
+ ? r.content.substring(0, 500) + "\n... (truncated)"
121
+ : r.content
122
+ output += content
123
+ output += "\n```\n\n"
124
+ }
125
+
126
+ output += `---\n*Found ${allResults.length} results. Use Read tool to see full files.*`
127
+
128
+ return output
129
+
130
+ } catch (error: any) {
131
+ return `❌ Search failed: ${error.message}\n\nTry re-indexing: npx opencode-workflow index --index ${args.index || "code"} --force`
132
+ }
133
+ },
134
+ })
@@ -47,11 +47,11 @@ docs/
47
47
 
48
48
  ## Templates
49
49
 
50
- Templates are in `.opencode/templates/`:
51
- - `prd-template.md`
52
- - `architecture-template.md`
53
- - `epic-template.md`
54
- - `story-template.md`
50
+ Templates are co-located with skills in `.opencode/skills/`:
51
+ - `skills/prd-writing/template.md`
52
+ - `skills/architecture-design/template.md`
53
+ - `skills/epic-writing/template.md`
54
+ - `skills/story-writing/template.md`
55
55
 
56
56
  ## Writing Guidelines
57
57
 
@@ -19,7 +19,7 @@ This folder contains requirements gathered from stakeholders.
19
19
 
20
20
  ## Template
21
21
 
22
- See `.opencode/templates/requirements-template.md`
22
+ See `.opencode/skills/requirements-gathering/template.md`
23
23
 
24
24
  ## Next Steps
25
25
 
@@ -1,82 +0,0 @@
1
- # Changelog
2
-
3
- All notable changes to this project will be documented in this file.
4
-
5
- The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
- and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
-
8
- ## [Unreleased]
9
-
10
- ### Added
11
- -
12
-
13
- ### Changed
14
- -
15
-
16
- ### Deprecated
17
- -
18
-
19
- ### Removed
20
- -
21
-
22
- ### Fixed
23
- -
24
-
25
- ### Security
26
- -
27
-
28
- ---
29
-
30
- ## [1.0.0] - YYYY-MM-DD
31
-
32
- ### Added
33
- - Initial release
34
- - Feature X
35
- - Feature Y
36
-
37
- ### Changed
38
- -
39
-
40
- ### Fixed
41
- -
42
-
43
- ---
44
-
45
- ## [0.1.0] - YYYY-MM-DD
46
-
47
- ### Added
48
- - Project skeleton
49
- - Basic documentation
50
-
51
- ---
52
-
53
- <!--
54
- CHANGELOG GUIDELINES:
55
-
56
- ## Entry Format
57
- - Start with verb: Add, Change, Fix, Remove, Deprecate
58
- - Be specific: "Add user registration API" not "Add feature"
59
- - Reference issues/PRs: "Fix login bug (#123)"
60
- - Group related changes
61
-
62
- ## Categories
63
- - Added: New features
64
- - Changed: Changes in existing functionality
65
- - Deprecated: Soon-to-be removed features
66
- - Removed: Removed features
67
- - Fixed: Bug fixes
68
- - Security: Vulnerability fixes
69
-
70
- ## Versioning (SemVer)
71
- - MAJOR: Breaking changes
72
- - MINOR: New features (backward compatible)
73
- - PATCH: Bug fixes (backward compatible)
74
-
75
- ## Example Entries
76
- - Add product catalog API with CRUD operations
77
- - Add user authentication via JWT tokens
78
- - Change order status from string to enum
79
- - Fix race condition in inventory reservation (#234)
80
- - Remove deprecated v1 API endpoints
81
- - Security: Fix SQL injection in search query
82
- -->
@@ -1,115 +0,0 @@
1
- # ADR-NNN: [Title]
2
-
3
- **Status:** Proposed | Accepted | Deprecated | Superseded
4
- **Date:** YYYY-MM-DD
5
- **Deciders:** [List of people involved]
6
- **Supersedes:** [ADR-XXX if applicable]
7
- **Superseded by:** [ADR-XXX if applicable]
8
-
9
- ---
10
-
11
- ## Context
12
-
13
- [What is the issue that we're seeing that is motivating this decision or change?]
14
-
15
- [Describe the forces at play (technical, political, social, project). These forces are probably in tension.]
16
-
17
- ---
18
-
19
- ## Decision
20
-
21
- [What is the change that we're proposing and/or doing?]
22
-
23
- **We will [decision].**
24
-
25
- ---
26
-
27
- ## Consequences
28
-
29
- ### Positive
30
-
31
- - [Benefit 1]
32
- - [Benefit 2]
33
- - [Benefit 3]
34
-
35
- ### Negative
36
-
37
- - [Drawback 1]
38
- - [Drawback 2]
39
-
40
- ### Neutral
41
-
42
- - [Trade-off 1]
43
- - [Trade-off 2]
44
-
45
- ---
46
-
47
- ## Options Considered
48
-
49
- ### Option 1: [Name]
50
-
51
- **Description:** [What this option entails]
52
-
53
- **Pros:**
54
- - [Pro 1]
55
- - [Pro 2]
56
-
57
- **Cons:**
58
- - [Con 1]
59
- - [Con 2]
60
-
61
- ### Option 2: [Name]
62
-
63
- **Description:** [What this option entails]
64
-
65
- **Pros:**
66
- - [Pro 1]
67
-
68
- **Cons:**
69
- - [Con 1]
70
-
71
- ### Option 3: [Name] (Chosen)
72
-
73
- **Description:** [What this option entails]
74
-
75
- **Pros:**
76
- - [Pro 1]
77
- - [Pro 2]
78
-
79
- **Cons:**
80
- - [Con 1]
81
-
82
- **Why chosen:** [Why this option was selected over others]
83
-
84
- ---
85
-
86
- ## Implementation
87
-
88
- [If applicable, describe how this decision will be implemented]
89
-
90
- ### Action Items
91
-
92
- - [ ] [Action 1]
93
- - [ ] [Action 2]
94
- - [ ] [Action 3]
95
-
96
- ### Timeline
97
-
98
- | Phase | Description | Target Date |
99
- |-------|-------------|-------------|
100
- | Phase 1 | [Description] | YYYY-MM-DD |
101
- | Phase 2 | [Description] | YYYY-MM-DD |
102
-
103
- ---
104
-
105
- ## Related
106
-
107
- - [Link to related ADR]
108
- - [Link to related documentation]
109
- - [Link to relevant code/PR]
110
-
111
- ---
112
-
113
- ## Notes
114
-
115
- [Any additional notes, context, or information]