@comfanion/workflow 4.36.13 → 4.36.15
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 +144 -39
- package/package.json +1 -1
- package/src/build-info.json +1 -1
- package/src/opencode/config.yaml +32 -10
- package/src/vectorizer/index.js +98 -8
package/README.md
CHANGED
|
@@ -1,15 +1,61 @@
|
|
|
1
1
|
# @comfanion/workflow
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
AI-assisted development workflow with **semantic code search**, agents, and structured documentation.
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/@comfanion/workflow)
|
|
6
6
|
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- 🔍 **Semantic Code Search** - Find code by meaning, not just text (`"authentication logic"` → finds auth handlers)
|
|
10
|
+
- 🤖 **AI Agents** - Specialized personas (Analyst, PM, Architect, Developer) with skills
|
|
11
|
+
- 📝 **Structured Workflow** - PRD → Architecture → Epics → Stories → Implementation
|
|
12
|
+
- 🔄 **Auto-indexing** - Background indexing on startup with fun toast notifications
|
|
13
|
+
- 🎯 **Jira Integration** - Bidirectional sync with your project
|
|
14
|
+
|
|
7
15
|
## Quick Start
|
|
8
16
|
|
|
9
17
|
```bash
|
|
10
18
|
npx @comfanion/workflow init
|
|
11
19
|
```
|
|
12
20
|
|
|
21
|
+
## Semantic Code Search
|
|
22
|
+
|
|
23
|
+
Search your codebase by **meaning**, not just text matching:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# In Claude Code / AI assistant:
|
|
27
|
+
/search "user authentication middleware" # Finds auth-related code
|
|
28
|
+
/search "database connection handling" # Finds DB setup
|
|
29
|
+
/search "error handling patterns" # Finds error handlers
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### How It Works
|
|
33
|
+
|
|
34
|
+
1. **Vectorizer** converts code into embeddings using local AI model
|
|
35
|
+
2. **Indexes** are stored in `.opencode/vectors/` (code, docs, config)
|
|
36
|
+
3. **Search** finds semantically similar code chunks
|
|
37
|
+
4. **Auto-indexer** keeps indexes fresh on startup
|
|
38
|
+
|
|
39
|
+
### Available Indexes
|
|
40
|
+
|
|
41
|
+
| Index | Files | Use Case |
|
|
42
|
+
|-------|-------|----------|
|
|
43
|
+
| `code` | `*.js, *.ts, *.py, *.go...` | Find functions, classes, logic |
|
|
44
|
+
| `docs` | `*.md, *.txt` | Find documentation, guides |
|
|
45
|
+
| `config` | `*.yaml, *.json` | Find configuration, settings |
|
|
46
|
+
|
|
47
|
+
### Commands
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
# Manual indexing
|
|
51
|
+
npx @comfanion/workflow index # Index all
|
|
52
|
+
npx @comfanion/workflow index --code # Index code only
|
|
53
|
+
npx @comfanion/workflow index --docs # Index docs only
|
|
54
|
+
|
|
55
|
+
# Check index status
|
|
56
|
+
npx @comfanion/workflow index --status
|
|
57
|
+
```
|
|
58
|
+
|
|
13
59
|
## Installation
|
|
14
60
|
|
|
15
61
|
### NPX (recommended)
|
|
@@ -22,11 +68,15 @@ npx @comfanion/workflow init
|
|
|
22
68
|
|
|
23
69
|
```bash
|
|
24
70
|
npm install -g @comfanion/workflow
|
|
25
|
-
comfanion-workflow init
|
|
26
|
-
# or
|
|
27
71
|
opencode-workflow init
|
|
28
72
|
```
|
|
29
73
|
|
|
74
|
+
### Alternative Package Name
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
npx create-opencode-workflow init
|
|
78
|
+
```
|
|
79
|
+
|
|
30
80
|
## Commands
|
|
31
81
|
|
|
32
82
|
### `init`
|
|
@@ -40,21 +90,13 @@ npx @comfanion/workflow init
|
|
|
40
90
|
**Interactive prompts:**
|
|
41
91
|
|
|
42
92
|
1. **Your name** - For personalized agent communication
|
|
43
|
-
2. **Communication language** - Ukrainian
|
|
93
|
+
2. **Communication language** - Ukrainian, English, Russian
|
|
44
94
|
3. **Development methodology** - TDD or STUB
|
|
45
|
-
4. **
|
|
46
|
-
5. **
|
|
95
|
+
4. **Vectorizer** - Enable semantic search
|
|
96
|
+
5. **Jira integration** - Enable/disable
|
|
47
97
|
|
|
48
98
|
**Flags:**
|
|
49
99
|
|
|
50
|
-
```bash
|
|
51
|
-
# Skip prompts, use defaults
|
|
52
|
-
npx @comfanion/workflow init -y
|
|
53
|
-
|
|
54
|
-
# With specific options
|
|
55
|
-
npx @comfanion/workflow init --tdd --jira --full
|
|
56
|
-
```
|
|
57
|
-
|
|
58
100
|
| Flag | Description |
|
|
59
101
|
|------|-------------|
|
|
60
102
|
| `-y, --yes` | Skip prompts, use defaults |
|
|
@@ -65,12 +107,17 @@ npx @comfanion/workflow init --tdd --jira --full
|
|
|
65
107
|
|
|
66
108
|
### `update`
|
|
67
109
|
|
|
68
|
-
Update `.opencode/` to latest version
|
|
110
|
+
Update `.opencode/` to latest version.
|
|
69
111
|
|
|
70
112
|
```bash
|
|
71
113
|
npx @comfanion/workflow update
|
|
72
114
|
```
|
|
73
115
|
|
|
116
|
+
**Preserves:**
|
|
117
|
+
- ✅ Your `config.yaml` (with comments!)
|
|
118
|
+
- ✅ Vector indexes (`.opencode/vectors/`)
|
|
119
|
+
- ✅ Custom settings
|
|
120
|
+
|
|
74
121
|
### `doctor`
|
|
75
122
|
|
|
76
123
|
Check installation health.
|
|
@@ -79,49 +126,102 @@ Check installation health.
|
|
|
79
126
|
npx @comfanion/workflow doctor
|
|
80
127
|
```
|
|
81
128
|
|
|
82
|
-
### `
|
|
129
|
+
### `vectorizer`
|
|
83
130
|
|
|
84
|
-
|
|
131
|
+
Manage semantic search vectorizer.
|
|
85
132
|
|
|
86
133
|
```bash
|
|
87
|
-
npx @comfanion/workflow
|
|
134
|
+
npx @comfanion/workflow vectorizer install # Install dependencies
|
|
135
|
+
npx @comfanion/workflow vectorizer status # Check status
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Configuration
|
|
139
|
+
|
|
140
|
+
### `config.yaml`
|
|
141
|
+
|
|
142
|
+
```yaml
|
|
143
|
+
# User settings
|
|
144
|
+
user_name: "Developer"
|
|
145
|
+
communication_language: "en" # en, uk, ru
|
|
146
|
+
|
|
147
|
+
# Development
|
|
148
|
+
development:
|
|
149
|
+
methodology: tdd # tdd or stub
|
|
150
|
+
|
|
151
|
+
# Semantic Search
|
|
152
|
+
vectorizer:
|
|
153
|
+
enabled: true
|
|
154
|
+
auto_index: true # Auto-index on startup
|
|
155
|
+
debounce_ms: 5000
|
|
156
|
+
indexes:
|
|
157
|
+
code: { enabled: true }
|
|
158
|
+
docs: { enabled: true }
|
|
159
|
+
config: { enabled: false }
|
|
160
|
+
exclude:
|
|
161
|
+
- "node_modules/**"
|
|
162
|
+
- "dist/**"
|
|
163
|
+
- "*.min.js"
|
|
164
|
+
|
|
165
|
+
# Jira Integration
|
|
166
|
+
jira:
|
|
167
|
+
enabled: false
|
|
168
|
+
url: "https://your-domain.atlassian.net"
|
|
169
|
+
project_key: "PROJ"
|
|
88
170
|
```
|
|
89
171
|
|
|
90
172
|
## What Gets Created
|
|
91
173
|
|
|
92
|
-
### `.opencode/`
|
|
174
|
+
### `.opencode/`
|
|
93
175
|
|
|
94
176
|
```
|
|
95
177
|
.opencode/
|
|
96
178
|
├── config.yaml # Your configuration
|
|
97
|
-
├── FLOW.yaml # Workflow definition
|
|
98
|
-
├── agents/ #
|
|
99
|
-
├──
|
|
100
|
-
├──
|
|
101
|
-
├──
|
|
179
|
+
├── FLOW.yaml # Workflow definition
|
|
180
|
+
├── agents/ # AI agent personas
|
|
181
|
+
│ ├── analyst.md # Business Analyst
|
|
182
|
+
│ ├── pm.md # Product Manager
|
|
183
|
+
│ ├── architect.md # Solution Architect
|
|
184
|
+
│ └── dev.md # Senior Developer
|
|
185
|
+
├── skills/ # Knowledge modules (25+)
|
|
186
|
+
├── plugins/ # Auto-indexer plugin
|
|
187
|
+
├── vectorizer/ # Semantic search engine
|
|
188
|
+
│ ├── index.js
|
|
189
|
+
│ └── package.json
|
|
190
|
+
├── vectors/ # Vector indexes (auto-created)
|
|
191
|
+
│ ├── code/
|
|
192
|
+
│ ├── docs/
|
|
193
|
+
│ └── config/
|
|
194
|
+
├── tools/ # MCP tools
|
|
195
|
+
│ ├── search.ts # Semantic search tool
|
|
196
|
+
│ └── codeindex.ts # Index management tool
|
|
102
197
|
└── commands/ # Slash commands
|
|
103
198
|
```
|
|
104
199
|
|
|
105
|
-
### `docs/`
|
|
200
|
+
### `docs/`
|
|
106
201
|
|
|
107
202
|
```
|
|
108
203
|
docs/
|
|
109
204
|
├── sprint-artifacts/ # Epics, stories, sprints
|
|
110
205
|
├── requirements/ # Requirements documents
|
|
111
206
|
├── architecture/ # Architecture + ADRs
|
|
112
|
-
|
|
113
|
-
├── coding-standards/ # Coding standards
|
|
114
|
-
└── confluence/ # Translations (Ukrainian)
|
|
207
|
+
└── coding-standards/ # Coding patterns
|
|
115
208
|
```
|
|
116
209
|
|
|
117
|
-
|
|
210
|
+
## Auto-Indexer Plugin
|
|
118
211
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
212
|
+
The auto-indexer runs on Claude Code / AI assistant startup:
|
|
213
|
+
|
|
214
|
+
- 🔍 Checks if indexes need updating
|
|
215
|
+
- 📊 Shows toast notification with file count
|
|
216
|
+
- ☕ Shows fun message while indexing ("Grab a coffee!")
|
|
217
|
+
- 📝 Logs to `.opencode/indexer.log`
|
|
218
|
+
|
|
219
|
+
**Disable auto-indexing:**
|
|
220
|
+
|
|
221
|
+
```yaml
|
|
222
|
+
# config.yaml
|
|
223
|
+
vectorizer:
|
|
224
|
+
auto_index: false
|
|
125
225
|
```
|
|
126
226
|
|
|
127
227
|
## Methodologies
|
|
@@ -129,9 +229,9 @@ CHANGELOG.md # Change history
|
|
|
129
229
|
### TDD (Test-Driven Development)
|
|
130
230
|
|
|
131
231
|
```
|
|
132
|
-
1. Write failing test
|
|
133
|
-
2. Write minimal code to pass
|
|
134
|
-
3. Refactor
|
|
232
|
+
1. Write failing test (RED)
|
|
233
|
+
2. Write minimal code to pass (GREEN)
|
|
234
|
+
3. Refactor (BLUE)
|
|
135
235
|
4. Repeat
|
|
136
236
|
```
|
|
137
237
|
|
|
@@ -146,13 +246,18 @@ CHANGELOG.md # Change history
|
|
|
146
246
|
|
|
147
247
|
## Jira Integration
|
|
148
248
|
|
|
149
|
-
|
|
249
|
+
Set credentials:
|
|
150
250
|
|
|
151
251
|
```bash
|
|
152
252
|
export JIRA_EMAIL="your-email@company.com"
|
|
153
253
|
export JIRA_API_TOKEN="your-api-token"
|
|
154
254
|
```
|
|
155
255
|
|
|
256
|
+
## Requirements
|
|
257
|
+
|
|
258
|
+
- **Node.js** >= 18
|
|
259
|
+
- **~100MB disk** for vectorizer dependencies
|
|
260
|
+
|
|
156
261
|
## Links
|
|
157
262
|
|
|
158
263
|
- **npm:** https://www.npmjs.com/package/@comfanion/workflow
|
package/package.json
CHANGED
package/src/build-info.json
CHANGED
package/src/opencode/config.yaml
CHANGED
|
@@ -235,28 +235,50 @@ vectorizer:
|
|
|
235
235
|
# Debounce time in ms (wait before indexing after file change)
|
|
236
236
|
debounce_ms: 1000
|
|
237
237
|
|
|
238
|
-
# Indexes to maintain
|
|
238
|
+
# Indexes to maintain - each has pattern (what to include) and ignore (what to skip)
|
|
239
239
|
indexes:
|
|
240
|
+
# Code index - source code files
|
|
240
241
|
code:
|
|
241
242
|
enabled: true
|
|
242
|
-
|
|
243
|
+
# Glob pattern for files to index
|
|
244
|
+
pattern: "**/*.{js,ts,jsx,tsx,mjs,cjs,py,go,rs,java,kt,swift,c,cpp,h,hpp,cs,rb,php,scala,clj}"
|
|
245
|
+
# Glob patterns to ignore
|
|
246
|
+
ignore:
|
|
247
|
+
- "**/node_modules/**"
|
|
248
|
+
- "**/.git/**"
|
|
249
|
+
- "**/dist/**"
|
|
250
|
+
- "**/build/**"
|
|
251
|
+
- "**/.opencode/**"
|
|
252
|
+
- "**/docs/**"
|
|
253
|
+
- "**/vendor/**"
|
|
254
|
+
- "**/__pycache__/**"
|
|
255
|
+
- "**/*.min.js"
|
|
256
|
+
- "**/*.bundle.js"
|
|
257
|
+
|
|
258
|
+
# Documentation index - markdown, text files
|
|
243
259
|
docs:
|
|
244
260
|
enabled: true
|
|
245
|
-
|
|
261
|
+
# Only docs folder by default (change to "**/*.md" for all markdown)
|
|
262
|
+
pattern: "docs/**/*.{md,mdx,txt,rst,adoc}"
|
|
263
|
+
ignore: []
|
|
264
|
+
|
|
265
|
+
# Configuration index - yaml, json, toml
|
|
246
266
|
config:
|
|
247
|
-
enabled: false
|
|
248
|
-
|
|
267
|
+
enabled: false # Disabled by default
|
|
268
|
+
pattern: "**/*.{yaml,yml,json,toml,ini}"
|
|
269
|
+
ignore:
|
|
270
|
+
- "**/node_modules/**"
|
|
271
|
+
- "**/.git/**"
|
|
272
|
+
- "**/.opencode/**"
|
|
273
|
+
- "**/package-lock.json"
|
|
274
|
+
- "**/yarn.lock"
|
|
249
275
|
|
|
250
|
-
#
|
|
276
|
+
# Global exclude patterns (applied to ALL indexes, in addition to per-index ignore)
|
|
251
277
|
exclude:
|
|
252
278
|
- node_modules
|
|
253
279
|
- .git
|
|
254
|
-
- dist
|
|
255
|
-
- build
|
|
256
280
|
- .opencode/vectors
|
|
257
281
|
- .opencode/vectorizer
|
|
258
|
-
- vendor
|
|
259
|
-
- __pycache__
|
|
260
282
|
|
|
261
283
|
# =============================================================================
|
|
262
284
|
# LSP (Language Server Protocol) - Code Intelligence
|
package/src/vectorizer/index.js
CHANGED
|
@@ -17,9 +17,9 @@ if (!DEBUG) {
|
|
|
17
17
|
}
|
|
18
18
|
|
|
19
19
|
/**
|
|
20
|
-
*
|
|
20
|
+
* Default index presets (can be overridden by config.yaml)
|
|
21
21
|
*/
|
|
22
|
-
const
|
|
22
|
+
const DEFAULT_PRESETS = {
|
|
23
23
|
code: {
|
|
24
24
|
pattern: '**/*.{js,ts,jsx,tsx,mjs,cjs,py,go,rs,java,kt,swift,c,cpp,h,hpp,cs,rb,php,scala,clj}',
|
|
25
25
|
ignore: ['**/node_modules/**', '**/.git/**', '**/dist/**', '**/build/**', '**/.opencode/**', '**/docs/**', '**/vendor/**', '**/__pycache__/**'],
|
|
@@ -42,6 +42,82 @@ const INDEX_PRESETS = {
|
|
|
42
42
|
}
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
+
// Will be populated from config.yaml if available
|
|
46
|
+
let INDEX_PRESETS = { ...DEFAULT_PRESETS };
|
|
47
|
+
let GLOBAL_IGNORE = [];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Load index configuration from config.yaml
|
|
51
|
+
* @param {string} projectRoot - Project root directory
|
|
52
|
+
*/
|
|
53
|
+
async function loadConfig(projectRoot) {
|
|
54
|
+
try {
|
|
55
|
+
const configPath = path.join(projectRoot, '.opencode', 'config.yaml');
|
|
56
|
+
const content = await fs.readFile(configPath, 'utf8');
|
|
57
|
+
|
|
58
|
+
// Parse vectorizer section from YAML
|
|
59
|
+
const vectorizerMatch = content.match(/^vectorizer:([\s\S]*?)(?=^[a-z]|\Z)/m);
|
|
60
|
+
if (!vectorizerMatch) return;
|
|
61
|
+
|
|
62
|
+
const section = vectorizerMatch[1];
|
|
63
|
+
|
|
64
|
+
// Parse global exclude
|
|
65
|
+
const excludeMatch = section.match(/^\s{2}exclude:\s*\n((?:\s{4}-\s+.+\n?)*)/m);
|
|
66
|
+
if (excludeMatch) {
|
|
67
|
+
GLOBAL_IGNORE = excludeMatch[1]
|
|
68
|
+
.split('\n')
|
|
69
|
+
.map(line => line.replace(/^\s*-\s*/, '').trim())
|
|
70
|
+
.filter(Boolean)
|
|
71
|
+
.map(p => p.includes('*') ? p : `**/${p}/**`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Parse indexes section
|
|
75
|
+
const indexesMatch = section.match(/^\s{2}indexes:\s*\n([\s\S]*?)(?=^\s{2}[a-z]|\s{2}exclude:|\Z)/m);
|
|
76
|
+
if (!indexesMatch) return;
|
|
77
|
+
|
|
78
|
+
const indexesSection = indexesMatch[1];
|
|
79
|
+
|
|
80
|
+
// Parse each index (code, docs, config)
|
|
81
|
+
for (const indexName of ['code', 'docs', 'config']) {
|
|
82
|
+
const indexRegex = new RegExp(`^\\s{4}${indexName}:\\s*\\n([\\s\\S]*?)(?=^\\s{4}[a-z]|\\Z)`, 'm');
|
|
83
|
+
const indexMatch = indexesSection.match(indexRegex);
|
|
84
|
+
if (!indexMatch) continue;
|
|
85
|
+
|
|
86
|
+
const indexSection = indexMatch[1];
|
|
87
|
+
|
|
88
|
+
// Parse enabled
|
|
89
|
+
const enabledMatch = indexSection.match(/^\s+enabled:\s*(true|false)/m);
|
|
90
|
+
const enabled = enabledMatch ? enabledMatch[1] === 'true' : true;
|
|
91
|
+
|
|
92
|
+
// Parse pattern
|
|
93
|
+
const patternMatch = indexSection.match(/^\s+pattern:\s*["']?([^"'\n]+)["']?/m);
|
|
94
|
+
const pattern = patternMatch ? patternMatch[1].trim() : DEFAULT_PRESETS[indexName]?.pattern;
|
|
95
|
+
|
|
96
|
+
// Parse ignore array
|
|
97
|
+
const ignoreMatch = indexSection.match(/^\s+ignore:\s*\n((?:\s+-\s+.+\n?)*)/m);
|
|
98
|
+
let ignore = [];
|
|
99
|
+
if (ignoreMatch) {
|
|
100
|
+
ignore = ignoreMatch[1]
|
|
101
|
+
.split('\n')
|
|
102
|
+
.map(line => line.replace(/^\s*-\s*/, '').replace(/["']/g, '').trim())
|
|
103
|
+
.filter(Boolean);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (enabled && pattern) {
|
|
107
|
+
INDEX_PRESETS[indexName] = {
|
|
108
|
+
pattern,
|
|
109
|
+
ignore,
|
|
110
|
+
description: `${indexName} files from config.yaml`
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
if (DEBUG) console.log('[vectorizer] Loaded config:', { INDEX_PRESETS, GLOBAL_IGNORE });
|
|
116
|
+
} catch (e) {
|
|
117
|
+
if (DEBUG) console.log('[vectorizer] Using default presets (no config.yaml)');
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
45
121
|
class CodebaseIndexer {
|
|
46
122
|
/**
|
|
47
123
|
* @param {string} projectRoot - Project root directory
|
|
@@ -55,9 +131,15 @@ class CodebaseIndexer {
|
|
|
55
131
|
this.model = null;
|
|
56
132
|
this.db = null;
|
|
57
133
|
this.hashes = {};
|
|
134
|
+
this.configLoaded = false;
|
|
58
135
|
}
|
|
59
136
|
|
|
60
137
|
async init() {
|
|
138
|
+
// Load config on first init
|
|
139
|
+
if (!this.configLoaded) {
|
|
140
|
+
await loadConfig(this.root);
|
|
141
|
+
this.configLoaded = true;
|
|
142
|
+
}
|
|
61
143
|
await fs.mkdir(this.cacheDir, { recursive: true });
|
|
62
144
|
this.db = await lancedb.connect(path.join(this.cacheDir, 'lancedb'));
|
|
63
145
|
await this.loadHashes();
|
|
@@ -219,10 +301,14 @@ class CodebaseIndexer {
|
|
|
219
301
|
*/
|
|
220
302
|
async checkHealth(extraIgnore = []) {
|
|
221
303
|
const { glob } = await import('glob');
|
|
222
|
-
const preset = INDEX_PRESETS[this.indexName] ||
|
|
304
|
+
const preset = INDEX_PRESETS[this.indexName] || DEFAULT_PRESETS.code;
|
|
223
305
|
|
|
224
|
-
// Combine preset ignore
|
|
225
|
-
const ignore = [
|
|
306
|
+
// Combine: preset ignore + global ignore + extra ignore
|
|
307
|
+
const ignore = [
|
|
308
|
+
...(preset.ignore || []),
|
|
309
|
+
...GLOBAL_IGNORE,
|
|
310
|
+
...extraIgnore.map(p => p.includes('*') ? p : `**/${p}/**`)
|
|
311
|
+
];
|
|
226
312
|
|
|
227
313
|
const expectedFiles = await glob(preset.pattern, {
|
|
228
314
|
cwd: this.root,
|
|
@@ -295,10 +381,14 @@ class CodebaseIndexer {
|
|
|
295
381
|
*/
|
|
296
382
|
async indexAll(onProgress = null, extraIgnore = []) {
|
|
297
383
|
const { glob } = await import('glob');
|
|
298
|
-
const preset = INDEX_PRESETS[this.indexName] ||
|
|
384
|
+
const preset = INDEX_PRESETS[this.indexName] || DEFAULT_PRESETS.code;
|
|
299
385
|
|
|
300
|
-
// Combine preset ignore
|
|
301
|
-
const ignore = [
|
|
386
|
+
// Combine: preset ignore + global ignore + extra ignore
|
|
387
|
+
const ignore = [
|
|
388
|
+
...(preset.ignore || []),
|
|
389
|
+
...GLOBAL_IGNORE,
|
|
390
|
+
...extraIgnore.map(p => p.includes('*') ? p : `**/${p}/**`)
|
|
391
|
+
];
|
|
302
392
|
|
|
303
393
|
const files = await glob(preset.pattern, {
|
|
304
394
|
cwd: this.root,
|