@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.
- package/README.md +1 -2
- package/bin/cli.js +343 -5
- package/package.json +8 -3
- package/src/build-info.json +2 -1
- package/src/opencode/ARCHITECTURE.md +7 -6
- package/src/opencode/FLOW.yaml +157 -102
- package/src/opencode/agents/analyst.md +24 -20
- package/src/opencode/agents/architect.md +104 -39
- package/src/opencode/agents/change-manager.md +112 -250
- package/src/opencode/agents/coder.md +36 -19
- package/src/opencode/agents/crawler.md +180 -97
- package/src/opencode/agents/dev.md +117 -29
- package/src/opencode/agents/pm.md +25 -32
- package/src/opencode/agents/researcher.md +116 -241
- package/src/opencode/commands/architecture.md +1 -1
- package/src/opencode/commands/dev-story.md +1 -5
- package/src/opencode/commands/prd.md +1 -1
- package/src/opencode/commands/unit-docs.md +170 -0
- package/src/opencode/config.yaml +29 -0
- package/src/opencode/opencode.json +5 -0
- package/src/opencode/skills/adr-writing/SKILL.md +122 -159
- package/src/opencode/skills/adr-writing/template.md +130 -0
- package/src/opencode/skills/architecture-design/SKILL.md +113 -107
- package/src/opencode/skills/architecture-design/template.md +212 -0
- package/src/opencode/skills/architecture-validation/SKILL.md +1 -1
- package/src/opencode/skills/changelog/template.md +23 -0
- package/src/opencode/{workflows/dev-story/instructions.md → skills/dev-story/SKILL.md} +2 -2
- package/src/opencode/skills/epic-writing/SKILL.md +116 -264
- package/src/opencode/skills/epic-writing/template.md +119 -0
- package/src/opencode/skills/prd-validation/SKILL.md +1 -1
- package/src/opencode/skills/prd-writing/SKILL.md +79 -43
- package/src/opencode/skills/prd-writing/template.md +147 -0
- package/src/opencode/skills/requirements-gathering/SKILL.md +128 -78
- package/src/opencode/skills/requirements-gathering/template.md +156 -0
- package/src/opencode/skills/story-writing/SKILL.md +106 -464
- package/src/opencode/skills/story-writing/template.md +214 -0
- package/src/opencode/skills/unit-writing/SKILL.md +185 -0
- package/src/opencode/skills/unit-writing/template.md +136 -0
- package/src/opencode/tools/codeindex.ts +255 -0
- package/src/opencode/tools/codesearch.ts +134 -0
- package/src/repo-structure/docs/README.md +5 -5
- package/src/repo-structure/docs/requirements/README.md +1 -1
- package/src/opencode/templates/CHANGELOG.md +0 -82
- package/src/opencode/templates/adr-template.md +0 -115
- package/src/opencode/templates/architecture-template.md +0 -362
- package/src/opencode/templates/epic-template.md +0 -166
- package/src/opencode/templates/prd-template.md +0 -479
- package/src/opencode/templates/requirements-template.md +0 -132
- package/src/opencode/templates/story-template.md +0 -182
- /package/src/opencode/{templates/prd-acceptance-criteria-template.md → skills/acceptance-criteria/template.md} +0 -0
- /package/src/opencode/{templates/change-proposal-template.md → skills/archiving/template-change-proposal.md} +0 -0
- /package/src/opencode/{templates/git-workflow-template.md → skills/coding-standards/template-git.md} +0 -0
- /package/src/opencode/{templates/testing-standards-template.md → skills/coding-standards/template-testing.md} +0 -0
- /package/src/opencode/{templates/jira-cache-template.yaml → skills/jira-integration/template-cache.yaml} +0 -0
- /package/src/opencode/{templates/module-index-template.md → skills/module-documentation/template.md} +0 -0
- /package/src/opencode/{templates/sprint-status-template.yaml → skills/sprint-planning/template.yaml} +0 -0
- /package/src/opencode/{templates/integration-tests-template.md → skills/test-design/template-integration.md} +0 -0
- /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/
|
|
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
|
|
|
@@ -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]
|