@comfanion/workflow 4.36.24 → 4.36.25

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 CHANGED
@@ -12,6 +12,37 @@ AI-assisted development workflow with **semantic code search**, agents, and stru
12
12
  - 🔄 **Auto-indexing** - Background indexing on startup with fun toast notifications
13
13
  - 🎯 **Jira Integration** - Bidirectional sync with your project
14
14
 
15
+ ## Agents & Workflow
16
+
17
+ The workflow uses specialized AI agents, each with a unique persona and skills:
18
+
19
+ | Agent | Name | Role | Phase |
20
+ |-------|------|------|-------|
21
+ | 📊 **Analyst** | Sara | Requirements gathering, stakeholder interviews | Planning |
22
+ | 📋 **PM** | Dima | PRD, epics, stories, sprint planning, Jira | Planning → Sprint |
23
+ | 🏗️ **Architect** | Winston | System design, ADRs, coding standards | Planning |
24
+ | 💻 **Dev** | Rick | TDD implementation, code review | Implementation |
25
+ | ⚡ **Coder** | Morty | Quick implementation, bug fixes | Implementation |
26
+ | 🔍 **Researcher** | Kristina | Technical/market/domain research | Any |
27
+ | 🔄 **Change Manager** | Bruce | Documentation changes, impact analysis | Any |
28
+
29
+ ### Workflow Pipeline
30
+
31
+ ```
32
+ Planning: /requirements → /prd → /coding-standards → /architecture
33
+ Sprint: /epics → /stories → /sprint-plan → /jira-sync
34
+ Development: /dev-story ↔ /code-review (loop until done)
35
+ ```
36
+
37
+ ### Key Skills
38
+
39
+ - **requirements-gathering** - Extract FR/NFR through interviews
40
+ - **prd-writing** - Product requirements documents
41
+ - **architecture-design** - Hexagonal/DDD patterns
42
+ - **story-writing** - User stories with Given/When/Then AC
43
+ - **dev-story** - Red-green-refactor implementation cycle
44
+ - **jira-integration** - Bidirectional sync with Jira
45
+
15
46
  ## Quick Start
16
47
 
17
48
  ```bash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@comfanion/workflow",
3
- "version": "4.36.24",
3
+ "version": "4.36.25",
4
4
  "description": "Initialize OpenCode Workflow system for AI-assisted development with semantic code search",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "4.36.24",
3
- "buildDate": "2026-01-24T19:02:10.302Z",
2
+ "version": "4.36.25",
3
+ "buildDate": "2026-01-24T20:24:17.710Z",
4
4
  "files": [
5
5
  "config.yaml",
6
6
  "FLOW.yaml",
@@ -302,7 +302,7 @@ pipeline:
302
302
  #
303
303
  agents:
304
304
  analyst:
305
- name: Mary
305
+ name: Sara
306
306
  title: Business Analyst
307
307
  icon: "📊"
308
308
  description: Requirements Analyst - extracts FR/NFR through stakeholder interviews
@@ -323,7 +323,7 @@ agents:
323
323
  - methodologies
324
324
 
325
325
  pm:
326
- name: John
326
+ name: Dima
327
327
  title: Product Manager
328
328
  icon: "📋"
329
329
  description: Product Manager - creates PRDs, epics, stories, sprint planning, Jira sync
@@ -371,7 +371,7 @@ agents:
371
371
  - methodologies
372
372
 
373
373
  dev:
374
- name: Amelia
374
+ name: Rick
375
375
  title: Senior Developer
376
376
  icon: "💻"
377
377
  description: Developer - implements stories following red-green-refactor cycle
@@ -389,9 +389,25 @@ agents:
389
389
  - code-review
390
390
  - test-design
391
391
 
392
+ coder:
393
+ name: Morty
394
+ title: Fast Coder
395
+ icon: "⚡"
396
+ description: Fast Coder - quick implementation, bug fixes, code following patterns
397
+ mode: subagent
398
+ hidden: true # Internal subagent, invoked by @dev
399
+ model: anthropic/claude-sonnet-4-20250514
400
+ temperature: 0.1
401
+ file: agents/coder.md
402
+ expertise:
403
+ - Quick implementation
404
+ - Bug fixes
405
+ - Following existing patterns
406
+ personality: Fast, no questions, executes or fails
407
+
392
408
  # Supporting Agents (not in main pipeline)
393
409
  researcher:
394
- name: Alex
410
+ name: Kristina
395
411
  title: Researcher
396
412
  icon: "🔍"
397
413
  description: Researcher - conducts technical, market, and domain research
@@ -412,7 +428,7 @@ agents:
412
428
  - methodologies
413
429
 
414
430
  change-manager:
415
- name: Charles
431
+ name: Bruce
416
432
  title: Change Manager
417
433
  icon: "🔄"
418
434
  description: Change Manager - manages documentation change proposals
@@ -26,7 +26,7 @@ permission:
26
26
  bash: deny # No bash access
27
27
  ---
28
28
 
29
- <agent id="analyst" name="Mary" title="Business Analyst" icon="📊">
29
+ <agent id="analyst" name="Sara" title="Business Analyst" icon="📊">
30
30
 
31
31
  <activation critical="MANDATORY">
32
32
  <step n="1">Load persona from this agent file</step>
@@ -33,7 +33,7 @@ permission:
33
33
  "cp *": ask # Copies need confirmation
34
34
  ---
35
35
 
36
- <agent id="change-manager" name="Charles" title="Change Manager" icon="🔄">
36
+ <agent id="change-manager" name="Bruce" title="Change Manager" icon="🔄">
37
37
 
38
38
  <activation critical="MANDATORY">
39
39
  <step n="1">Load persona from this agent file</step>
@@ -30,7 +30,7 @@ permission:
30
30
  bash: allow # Full bash for speed
31
31
  ---
32
32
 
33
- <agent id="coder" name="Swift" title="Fast Coder" icon="⚡">
33
+ <agent id="coder" name="Morty" title="Fast Coder" icon="⚡">
34
34
 
35
35
  <activation critical="MANDATORY">
36
36
  <step n="1">Receive task from parent agent or user</step>
@@ -29,7 +29,7 @@ permission:
29
29
  webfetch: allow
30
30
  ---
31
31
 
32
- <agent id="dev" name="Amelia" title="Senior Developer" icon="💻">
32
+ <agent id="dev" name="Rick" title="Senior Developer" icon="💻">
33
33
 
34
34
  <activation critical="MANDATORY">
35
35
  <step n="1">Load persona from this agent file</step>
@@ -34,7 +34,7 @@ permission:
34
34
  "git log*": allow
35
35
  ---
36
36
 
37
- <agent id="pm" name="John" title="Product Manager" icon="📋">
37
+ <agent id="pm" name="Dima" title="Product Manager" icon="📋">
38
38
 
39
39
  <activation critical="MANDATORY">
40
40
  <step n="1">Load persona from this agent file</step>
@@ -38,7 +38,7 @@ permission:
38
38
  "curl *": ask # HTTP requests need approval
39
39
  ---
40
40
 
41
- <agent id="researcher" name="Alex" title="Research Specialist" icon="🔍">
41
+ <agent id="researcher" name="Kristina" title="Research Specialist" icon="🔍">
42
42
 
43
43
  <activation critical="MANDATORY">
44
44
  <step n="1">Load persona from this agent file</step>
@@ -281,11 +281,15 @@ vectorizer:
281
281
  - "**/yarn.lock"
282
282
 
283
283
  # Global exclude patterns (applied to ALL indexes, in addition to per-index ignore)
284
+ # Patterns without * are wrapped in **/{pattern}/**
285
+ # NOTE: Dot-folders (.git, .claude, .idea, etc.) are already ignored by default (glob dot:false)
284
286
  exclude:
285
287
  - node_modules
286
- - .git
287
- - .opencode/vectors
288
- - .opencode/vectorizer
288
+ - vendor
289
+ - dist
290
+ - build
291
+ - out
292
+ - __pycache__
289
293
 
290
294
  # =============================================================================
291
295
  # LSP (Language Server Protocol) - Code Intelligence
@@ -51,7 +51,10 @@ const DEFAULT_CONFIG = {
51
51
  docs: { enabled: true, extensions: ['.md', '.mdx', '.txt', '.rst', '.adoc'] },
52
52
  config: { enabled: false, extensions: ['.yaml', '.yml', '.json', '.toml', '.ini', '.xml'] },
53
53
  },
54
- exclude: ['node_modules', '.git', 'dist', 'build', '.opencode/vectors', '.opencode/vectorizer', 'vendor', '__pycache__'],
54
+ exclude: [
55
+ // Build & deps (dot-folders like .git, .claude, .idea are already ignored by glob default)
56
+ 'node_modules', 'vendor', 'dist', 'build', 'out', '__pycache__',
57
+ ],
55
58
  }
56
59
 
57
60
  interface VectorizerConfig {
@@ -44,6 +44,7 @@ Prerequisites: Run 'npx @comfanion/workflow index --index <name>' first.`,
44
44
  limit: tool.schema.number().optional().default(5).describe("Number of results to return (default: 5)"),
45
45
  searchAll: tool.schema.boolean().optional().default(false).describe("Search all indexes instead of just one"),
46
46
  freshen: tool.schema.boolean().optional().default(true).describe("Auto-update stale files before searching (default: true)"),
47
+ includeArchived: tool.schema.boolean().optional().default(false).describe("Include archived files in results (default: false). Files are archived if in /archive/ folder or have 'archived: true' in frontmatter."),
47
48
  },
48
49
 
49
50
  async execute(args, context) {
@@ -88,7 +89,7 @@ Prerequisites: Run 'npx @comfanion/workflow index --index <name>' first.`,
88
89
  if (args.freshen !== false) {
89
90
  await indexer.freshen()
90
91
  }
91
- const results = await indexer.search(args.query, limit)
92
+ const results = await indexer.search(args.query, limit, args.includeArchived)
92
93
  allResults.push(...results.map((r: any) => ({ ...r, _index: idx })))
93
94
  await indexer.unloadModel() // Free memory after each index search
94
95
  }
@@ -181,6 +181,30 @@ class CodebaseIndexer {
181
181
  return crypto.createHash('md5').update(content).digest('hex');
182
182
  }
183
183
 
184
+ /**
185
+ * Check if file is archived (should be excluded from default search)
186
+ * Archived if:
187
+ * - Path contains /archive/ folder
188
+ * - File has frontmatter with archived: true
189
+ */
190
+ isArchived(relPath, content) {
191
+ // Check path
192
+ if (relPath.includes('/archive/') || relPath.startsWith('archive/')) {
193
+ return true;
194
+ }
195
+
196
+ // Check frontmatter (YAML between --- markers at start of file)
197
+ const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
198
+ if (frontmatterMatch) {
199
+ const frontmatter = frontmatterMatch[1];
200
+ if (/^archived:\s*true/m.test(frontmatter)) {
201
+ return true;
202
+ }
203
+ }
204
+
205
+ return false;
206
+ }
207
+
184
208
  async embed(text) {
185
209
  const model = await this.loadModel();
186
210
  const result = await model(text, { pooling: 'mean', normalize: true });
@@ -246,6 +270,7 @@ class CodebaseIndexer {
246
270
  }
247
271
 
248
272
  const chunks = this.chunkCode(content);
273
+ const archived = this.isArchived(relPath, content);
249
274
  const data = [];
250
275
 
251
276
  for (let i = 0; i < chunks.length; i++) {
@@ -254,7 +279,8 @@ class CodebaseIndexer {
254
279
  file: relPath,
255
280
  chunk_index: i,
256
281
  content: chunks[i],
257
- vector: embedding
282
+ vector: embedding,
283
+ archived: archived
258
284
  });
259
285
  }
260
286
 
@@ -279,8 +305,11 @@ class CodebaseIndexer {
279
305
 
280
306
  /**
281
307
  * Semantic search across indexed codebase
308
+ * @param {string} query - Search query
309
+ * @param {number} limit - Max results (default 5)
310
+ * @param {boolean} includeArchived - Include archived files (default false)
282
311
  */
283
- async search(query, limit = 5) {
312
+ async search(query, limit = 5, includeArchived = false) {
284
313
  const tableName = 'chunks';
285
314
  const tables = await this.db.tableNames();
286
315
  if (!tables.includes(tableName)) {
@@ -289,9 +318,18 @@ class CodebaseIndexer {
289
318
 
290
319
  const queryEmbedding = await this.embed(query);
291
320
  const table = await this.db.openTable(tableName);
292
- const results = await table.search(queryEmbedding).limit(limit).execute();
293
321
 
294
- return results;
322
+ // Fetch more results if we need to filter archived
323
+ const fetchLimit = includeArchived ? limit : limit * 3;
324
+ let results = await table.search(queryEmbedding).limit(fetchLimit).execute();
325
+
326
+ // Filter out archived files unless explicitly requested
327
+ if (!includeArchived) {
328
+ results = results.filter(r => !r.archived);
329
+ }
330
+
331
+ // Trim to requested limit
332
+ return results.slice(0, limit);
295
333
  }
296
334
 
297
335
  /**