claude-flow-novice 2.18.12 → 2.18.13
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/.claude/agents/custom/claude-code-expert.md +56 -0
- package/.claude/skills/cfn-agent-lifecycle/SKILL.md +1 -1
- package/.claude/skills/cfn-agent-tooling/SKILL.md +1 -1
- package/.claude/skills/cfn-compilation-error-fixer/SKILL.md +1 -1
- package/.claude/skills/cfn-compilation-error-fixer/lib/fixer/cerebras-gated-fixer-v2.ts +1 -1
- package/.claude/skills/cfn-config/SKILL.md +1 -1
- package/.claude/skills/cfn-dependency-management/SKILL.md +1 -1
- package/.claude/skills/cfn-deployment-lifecycle/SKILL.md +1 -1
- package/.claude/skills/cfn-docker-runtime/SKILL.md +1 -1
- package/.claude/skills/cfn-edit-safety/SKILL.md +1 -1
- package/.claude/skills/cfn-epic-parser/SKILL.md +8 -0
- package/.claude/skills/cfn-error-management/SKILL.md +1 -1
- package/.claude/skills/cfn-intervention-system/SKILL.md +1 -1
- package/.claude/skills/cfn-knowledge-base/SKILL.md +1 -1
- package/.claude/skills/cfn-local-ruvector-accelerator/SKILL.md +8 -0
- package/.claude/skills/cfn-local-ruvector-accelerator/src/cli/index.rs +29 -4
- package/.claude/skills/cfn-local-ruvector-accelerator/src/cli/query.rs +2 -2
- package/.claude/skills/cfn-local-ruvector-accelerator/src/search_engine.rs +150 -29
- package/.claude/skills/cfn-local-ruvector-accelerator/src/sqlite_store.rs +1 -1
- package/.claude/skills/cfn-loop-orchestration-v2/SKILL.md +1 -1
- package/.claude/skills/cfn-loop-orchestration-v2/lib/decision/SKILL.md +8 -0
- package/.claude/skills/cfn-loop-orchestration-v2/lib/orchestrator/SKILL.md +1 -1
- package/.claude/skills/cfn-loop-orchestration-v2/lib/output/SKILL.md +8 -0
- package/.claude/skills/cfn-loop-orchestration-v2/lib/validation/SKILL.md +11 -2
- package/.claude/skills/cfn-memory-persistence/lib/auto/SKILL.md +7 -0
- package/.claude/skills/cfn-memory-persistence/lib/management/SKILL.md +7 -0
- package/.claude/skills/cfn-parameterized-queries/SKILL.md +8 -0
- package/.claude/skills/cfn-planning/SKILL.md +1 -1
- package/.claude/skills/cfn-skill-management/SKILL.md +1 -1
- package/.claude/skills/cfn-transparency-middleware/SKILL.md +1 -1
- package/.claude/skills/cfn-utilities/SKILL.md +1 -1
- package/.claude/skills/cfn-vision-analysis/SKILL.md +1 -1
- package/index/index.bin +0 -0
- package/index/metadata.json +1 -0
- package/package.json +1 -1
- package/.claude/skills/cfn-compilation-error-fixer/HANDOFF.md +0 -29
- package/.ruvector/index.db-journal +0 -0
|
@@ -237,6 +237,61 @@ Claude Code auto-discovers MCP servers from:
|
|
|
237
237
|
|
|
238
238
|
To prevent auto-discovered servers from connecting, add them to `disabledMcpServers`.
|
|
239
239
|
|
|
240
|
+
## SKILL.md Best Practices
|
|
241
|
+
|
|
242
|
+
### Description Field is Primary Discovery
|
|
243
|
+
- Claude reads **only the `description` field** at startup to decide when to invoke skills
|
|
244
|
+
- Full SKILL.md content is loaded **only after** Claude decides the skill is relevant
|
|
245
|
+
- Description must answer: **What does it do?** + **When should it be used?**
|
|
246
|
+
|
|
247
|
+
### Effective Description Formula
|
|
248
|
+
```yaml
|
|
249
|
+
description: "<Capability>. Use when <condition 1>, <condition 2>, or <condition 3>."
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Good example:**
|
|
253
|
+
```yaml
|
|
254
|
+
description: "Extract text and tables from PDF files, fill forms, merge documents. Use when working with PDF files or when the user mentions PDFs, forms, or document extraction."
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
**Bad examples:**
|
|
258
|
+
- `"Helps with documents"` - too vague
|
|
259
|
+
- `"Processes data"` - too generic
|
|
260
|
+
- Missing trigger conditions
|
|
261
|
+
|
|
262
|
+
### Required Frontmatter
|
|
263
|
+
```yaml
|
|
264
|
+
---
|
|
265
|
+
name: lowercase-skill-name # Max 64 chars, hyphens/lowercase only
|
|
266
|
+
description: What + when # Max 1024 chars
|
|
267
|
+
version: 1.0.0 # Optional but recommended
|
|
268
|
+
tags: [category, type] # For organization (not indexed by Claude)
|
|
269
|
+
---
|
|
270
|
+
```
|
|
271
|
+
|
|
272
|
+
### Content Best Practices
|
|
273
|
+
- **Under 500 lines** in SKILL.md body
|
|
274
|
+
- Use **progressive disclosure** - detailed docs in separate files
|
|
275
|
+
- Include concrete **Quick Start** examples
|
|
276
|
+
- One level deep for reference files (no deep nesting)
|
|
277
|
+
|
|
278
|
+
### Anti-Patterns to Avoid
|
|
279
|
+
- Missing trigger conditions in description
|
|
280
|
+
- Verbose prose instead of blueprints
|
|
281
|
+
- Time-sensitive information
|
|
282
|
+
- Offering too many options without clear recommendation
|
|
283
|
+
- Inconsistent terminology
|
|
284
|
+
|
|
285
|
+
### Skill Analysis Checklist
|
|
286
|
+
When reviewing SKILL.md files, verify:
|
|
287
|
+
- [ ] Description includes both capability AND trigger conditions
|
|
288
|
+
- [ ] Uses "Use when..." pattern for discovery
|
|
289
|
+
- [ ] Under 500 lines in body
|
|
290
|
+
- [ ] Has YAML frontmatter with name, description
|
|
291
|
+
- [ ] Includes concrete Quick Start example
|
|
292
|
+
- [ ] No deep nesting of reference files
|
|
293
|
+
- [ ] Consistent terminology throughout
|
|
294
|
+
|
|
240
295
|
## Documentation URLs to Reference
|
|
241
296
|
|
|
242
297
|
Primary resources:
|
|
@@ -244,6 +299,7 @@ Primary resources:
|
|
|
244
299
|
- https://docs.claudecode.com/workflows
|
|
245
300
|
- https://docs.claudecode.com/tools
|
|
246
301
|
- https://docs.claudecode.com/best-practices
|
|
302
|
+
- https://docs.claudecode.com/skills (skill creation guide)
|
|
247
303
|
|
|
248
304
|
## Output Format
|
|
249
305
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-agent-lifecycle
|
|
3
|
-
description: Unified agent management from selection through completion - spawning, execution, output processing
|
|
3
|
+
description: "Unified agent management from selection through completion - spawning, execution, output processing. Use when selecting agents for tasks, spawning agents with dependency validation, processing agent outputs, or tracking agent lifecycle events with audit trails."
|
|
4
4
|
version: 2.0.0
|
|
5
5
|
tags: [mega-skill, agent-management, lifecycle, spawning]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-agent-tooling
|
|
3
|
-
description: Agent development tools - generation and validation
|
|
3
|
+
description: "Agent development tools - generation and validation. Use when creating new agent templates from scaffolding, or validating and linting existing agent profiles for correctness and completeness."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, agents, templates, validation, development]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-compilation-error-fixer
|
|
3
|
-
description: Two-phase compilation error fixer for Rust and TypeScript using Cerebras LLM bulk processing + dedicated agent cleanup
|
|
3
|
+
description: "Two-phase compilation error fixer for Rust and TypeScript using Cerebras LLM bulk processing + dedicated agent cleanup. Use when you have 20+ compilation errors that need fast bulk reduction, or when errors are mostly mechanical (type mismatches, missing imports, syntax issues)."
|
|
4
4
|
version: 2.0.0
|
|
5
5
|
tags: [rust, typescript, compilation, cerebras, error-fixer, cfn]
|
|
6
6
|
status: production
|
|
@@ -25,7 +25,7 @@ const CONFIG = {
|
|
|
25
25
|
maxLayer1Retries: 3, // Max retries when Layer 1 gates reject
|
|
26
26
|
maxTokens: 4000,
|
|
27
27
|
model: 'zai-glm-4.6',
|
|
28
|
-
projectPath: '/mnt/c/Users/masha/Documents/ourstories-v2/services/rust-services',
|
|
28
|
+
projectPath: process.env.RUST_PROJECT_PATH || '/mnt/c/Users/masha/Documents/ourstories-v2/services/rust-services',
|
|
29
29
|
parallelLLMCalls: 10,
|
|
30
30
|
enableLayer3: !process.argv.includes('--no-layer3'),
|
|
31
31
|
enableClippy: !process.argv.includes('--no-clippy'),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-config
|
|
3
|
-
description: Configuration management and environment sanitization
|
|
3
|
+
description: "Configuration management and environment sanitization. Use when you need to manage configuration files, validate environment variables, sanitize sensitive data, or update system settings across CFN Loop components."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, config, environment, sanitization]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-dependency-management
|
|
3
|
-
description: Task dependency extraction and context ingestion
|
|
3
|
+
description: "Task dependency extraction and context ingestion. Use when you need to parse task criteria, identify dependencies, generate execution order, or inject context for complex multi-step tasks."
|
|
4
4
|
version: 1.1.0
|
|
5
5
|
tags: [mega-skill, dependencies, extraction, ingestion, orchestration]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-deployment-lifecycle
|
|
3
|
-
description: Skill deployment and promotion lifecycle management
|
|
3
|
+
description: "Skill deployment and promotion lifecycle management. Use when transitioning skills from APPROVED to DEPLOYED status, or promoting skills from staging to production with SLA enforcement."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, deployment, promotion, lifecycle]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-docker-runtime
|
|
3
|
-
description: Docker container orchestration for CFN Loop - spawning, coordination, logging, wave execution
|
|
3
|
+
description: "Docker container orchestration for CFN Loop - spawning, coordination, logging, wave execution. Use when running CFN Loop agents in Docker containers, executing waves of parallel agents, coordinating containerized agents via Redis, or managing Docker-based agent lifecycle."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, docker, containers, orchestration]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-edit-safety
|
|
3
|
-
description: Pre-edit backup and post-edit validation for safe file modifications
|
|
3
|
+
description: "Pre-edit backup and post-edit validation for safe file modifications. Use when you need to capture file state before edits, validate changes after modifications, revert files to previous state, or ensure edit safety with automatic backup and validation hooks."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, backup, hooks, validation, safety]
|
|
6
6
|
status: production
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-epic-parser
|
|
3
|
+
description: "Converts natural language epic documents from markdown into structured JSON configurations for MDAP or CFN Loop execution. Use when you need to parse epic documents, validate epic structure, or generate execution configurations from planning documents."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [epic, parser, mdap, cfn-loop, planning]
|
|
6
|
+
status: production
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
# CFN Epic Parser
|
|
2
10
|
|
|
3
11
|
## Overview
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-error-management
|
|
3
|
-
description: Unified error handling, batching, and logging for CFN Loop
|
|
3
|
+
description: "Unified error handling, batching, and logging for CFN Loop. Use when you need to capture agent errors, batch multiple errors for processing, log structured error data, or categorize and recover from agent failures."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, errors, logging, batch-processing]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-intervention-system
|
|
3
|
-
description: Human intervention detection and orchestration for CFN Loop
|
|
3
|
+
description: "Human intervention detection and orchestration for CFN Loop. Use when automated processes need human oversight, when escalation is required, or when managing intervention workflows and approval gates."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, intervention, human-in-the-loop, escalation]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-knowledge-base
|
|
3
|
-
description: Organizational learning from CFN Loop execution - workflow codification and playbooks
|
|
3
|
+
description: "Organizational learning from CFN Loop execution - workflow codification and playbooks. Use when you need to store successful patterns, query past learnings, track edge cases and failures, or retrieve agent configurations and iteration strategies from previous tasks."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, learning, workflow, playbook]
|
|
6
6
|
status: production
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-local-ruvector-accelerator
|
|
3
|
+
description: "Lightning-fast local RuVector storage optimized for solo development with pure local file storage and vector search. Use when you need instant pattern lookup without PostgreSQL or Docker overhead, or when working offline with local semantic code search."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [ruvector, local, vector-search, patterns, offline]
|
|
6
|
+
status: production
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
# Local RuVector Accelerator
|
|
2
10
|
|
|
3
11
|
## Description
|
|
@@ -31,6 +31,7 @@ impl Default for IndexStats {
|
|
|
31
31
|
|
|
32
32
|
pub struct IndexCommand {
|
|
33
33
|
project_dir: PathBuf,
|
|
34
|
+
source_path: PathBuf, // Path to walk for files (can differ from project_dir)
|
|
34
35
|
index_path: PathBuf,
|
|
35
36
|
file_types: Vec<String>,
|
|
36
37
|
patterns: Option<Vec<String>>,
|
|
@@ -53,8 +54,16 @@ impl IndexCommand {
|
|
|
53
54
|
let search_engine = SearchEngine::new(project_dir).unwrap();
|
|
54
55
|
let store = SqliteStore::new(&index_path.join("index.db")).unwrap();
|
|
55
56
|
|
|
57
|
+
// Use path argument for file collection, defaulting to project_dir if path is empty
|
|
58
|
+
let source_path = if path.as_os_str().is_empty() || path == Path::new(".") {
|
|
59
|
+
project_dir.to_path_buf()
|
|
60
|
+
} else {
|
|
61
|
+
path.to_path_buf()
|
|
62
|
+
};
|
|
63
|
+
|
|
56
64
|
Self {
|
|
57
65
|
project_dir: project_dir.to_path_buf(),
|
|
66
|
+
source_path,
|
|
58
67
|
index_path,
|
|
59
68
|
file_types,
|
|
60
69
|
patterns,
|
|
@@ -95,7 +104,7 @@ impl IndexCommand {
|
|
|
95
104
|
.context("Failed to create index directory")?;
|
|
96
105
|
|
|
97
106
|
// Initialize search engine
|
|
98
|
-
let mut search_engine = self.search_engine.
|
|
107
|
+
let mut search_engine = self.search_engine.duplicate()?;
|
|
99
108
|
search_engine.load_or_create()?;
|
|
100
109
|
|
|
101
110
|
// Initialize database
|
|
@@ -106,11 +115,11 @@ impl IndexCommand {
|
|
|
106
115
|
}
|
|
107
116
|
|
|
108
117
|
fn collect_files(&self) -> Result<Vec<PathBuf>> {
|
|
109
|
-
info!("Collecting files to index");
|
|
118
|
+
info!("Collecting files to index from: {}", self.source_path.display());
|
|
110
119
|
|
|
111
120
|
let mut files = Vec::new();
|
|
112
121
|
|
|
113
|
-
let walker = WalkDir::new(&self.
|
|
122
|
+
let walker = WalkDir::new(&self.source_path)
|
|
114
123
|
.into_iter()
|
|
115
124
|
.filter_entry(|e| !Self::is_hidden(e))
|
|
116
125
|
.filter_map(|e| e.ok())
|
|
@@ -125,6 +134,15 @@ impl IndexCommand {
|
|
|
125
134
|
return false;
|
|
126
135
|
}
|
|
127
136
|
|
|
137
|
+
// Skip node_modules, target, dist, build directories
|
|
138
|
+
let path_str = e.path().to_string_lossy();
|
|
139
|
+
if path_str.contains("/node_modules/") ||
|
|
140
|
+
path_str.contains("/target/") ||
|
|
141
|
+
path_str.contains("/dist/") ||
|
|
142
|
+
path_str.contains("/build/") {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
|
|
128
146
|
// Check file extension
|
|
129
147
|
if let Some(ext) = e.path().extension() {
|
|
130
148
|
self.file_types.contains(&ext.to_string_lossy().to_string())
|
|
@@ -144,7 +162,14 @@ impl IndexCommand {
|
|
|
144
162
|
fn is_hidden(entry: &DirEntry) -> bool {
|
|
145
163
|
entry.file_name()
|
|
146
164
|
.to_str()
|
|
147
|
-
.map(|s|
|
|
165
|
+
.map(|s| {
|
|
166
|
+
// Allow .claude directory (contains agents, skills, commands, hooks)
|
|
167
|
+
if s == ".claude" {
|
|
168
|
+
return false;
|
|
169
|
+
}
|
|
170
|
+
// Skip other hidden directories (like .git, .ruvector, etc.)
|
|
171
|
+
s.starts_with('.')
|
|
172
|
+
})
|
|
148
173
|
.unwrap_or(false)
|
|
149
174
|
}
|
|
150
175
|
|
|
@@ -62,7 +62,7 @@ impl QueryCommand {
|
|
|
62
62
|
info!("Executing query: {}", self.config.query);
|
|
63
63
|
|
|
64
64
|
// Load the search engine
|
|
65
|
-
let mut search_engine = self.search_engine.
|
|
65
|
+
let mut search_engine = self.search_engine.duplicate()?;
|
|
66
66
|
search_engine.load_or_create()?;
|
|
67
67
|
|
|
68
68
|
// Perform search
|
|
@@ -170,7 +170,7 @@ impl BatchQueryCommand {
|
|
|
170
170
|
info!("Executing batch queries from: {}", self.batch_file.display());
|
|
171
171
|
|
|
172
172
|
// Load the search engine
|
|
173
|
-
let mut search_engine = self.search_engine.
|
|
173
|
+
let mut search_engine = self.search_engine.duplicate()?;
|
|
174
174
|
search_engine.load_or_create()?;
|
|
175
175
|
|
|
176
176
|
// Read batch queries
|
|
@@ -1,14 +1,157 @@
|
|
|
1
|
+
use anyhow::{Result, Context, anyhow};
|
|
2
|
+
use ndarray::{Array1, Array2};
|
|
3
|
+
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
|
4
|
+
use std::path::{Path, PathBuf};
|
|
5
|
+
use std::fs::{File, OpenOptions};
|
|
6
|
+
use std::io::{Read, Write, BufReader, BufWriter};
|
|
7
|
+
use std::collections::HashMap;
|
|
8
|
+
use serde::{Serialize, Deserialize};
|
|
9
|
+
use tracing::info;
|
|
10
|
+
use memmap2::MmapOptions;
|
|
11
|
+
use crate::embeddings::EmbeddingsManager;
|
|
12
|
+
use crate::sqlite_store::SqliteStore;
|
|
13
|
+
|
|
14
|
+
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
15
|
+
pub struct SearchConfig {
|
|
16
|
+
pub dimension: usize,
|
|
17
|
+
pub batch_size: usize,
|
|
18
|
+
pub max_results: usize,
|
|
19
|
+
pub index_path: PathBuf,
|
|
20
|
+
pub use_mmap: bool,
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
impl Default for SearchConfig {
|
|
24
|
+
fn default() -> Self {
|
|
25
|
+
Self {
|
|
26
|
+
dimension: 1536,
|
|
27
|
+
batch_size: 100,
|
|
28
|
+
max_results: 10,
|
|
29
|
+
index_path: PathBuf::from("index"),
|
|
30
|
+
use_mmap: true,
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
#[derive(Debug, Clone)]
|
|
36
|
+
pub struct VectorIndex {
|
|
37
|
+
pub vectors: Array2<f32>,
|
|
38
|
+
pub ids: Vec<String>,
|
|
39
|
+
pub metadata: HashMap<String, IndexMetadata>,
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
impl VectorIndex {
|
|
43
|
+
pub fn new(dimension: usize) -> Self {
|
|
44
|
+
Self {
|
|
45
|
+
vectors: Array2::zeros((0, dimension)),
|
|
46
|
+
ids: Vec::new(),
|
|
47
|
+
metadata: HashMap::new(),
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
pub fn add_vector(&mut self, id: String, vector: Array1<f32>, metadata: IndexMetadata) -> Result<()> {
|
|
52
|
+
if vector.len() != self.vectors.ncols() {
|
|
53
|
+
return Err(anyhow!("Vector dimension mismatch"));
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
let new_row = self.vectors.nrows();
|
|
57
|
+
self.vectors.push_row(vector.view())?;
|
|
58
|
+
self.ids.push(id.clone());
|
|
59
|
+
self.metadata.insert(id, metadata);
|
|
60
|
+
|
|
61
|
+
Ok(())
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
pub fn add_vectors(&mut self, vectors: Vec<Array1<f32>>, ids: Vec<String>, metadata: HashMap<String, IndexMetadata>) -> Result<()> {
|
|
65
|
+
if vectors.len() != ids.len() {
|
|
66
|
+
return Err(anyhow!("Vectors and IDs length mismatch"));
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
for (vector, id) in vectors.into_iter().zip(ids.into_iter()) {
|
|
70
|
+
let meta = metadata.get(&id).cloned().unwrap_or_else(|| IndexMetadata::default());
|
|
71
|
+
self.add_vector(id, vector, meta)?;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
Ok(())
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
|
|
79
|
+
pub struct IndexMetadata {
|
|
80
|
+
pub path: String,
|
|
81
|
+
pub pattern: String,
|
|
82
|
+
pub context: Option<String>,
|
|
83
|
+
pub line_number: Option<usize>,
|
|
84
|
+
pub snippet: Option<String>,
|
|
85
|
+
pub file_hash: String,
|
|
86
|
+
pub indexed_at: u64,
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
#[derive(Debug, Clone)]
|
|
90
|
+
pub struct SearchResult {
|
|
91
|
+
pub id: String,
|
|
92
|
+
pub path: String,
|
|
93
|
+
pub pattern: String,
|
|
94
|
+
pub score: f32,
|
|
95
|
+
pub context: Option<String>,
|
|
96
|
+
pub line_number: Option<usize>,
|
|
97
|
+
pub snippet: Option<String>,
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#[derive(Debug, Clone)]
|
|
101
|
+
pub struct IndexStats {
|
|
102
|
+
pub num_vectors: usize,
|
|
103
|
+
pub dimension: usize,
|
|
104
|
+
pub index_size_bytes: u64,
|
|
105
|
+
pub metadata_count: usize,
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
pub struct SearchEngine {
|
|
109
|
+
pub index: VectorIndex,
|
|
110
|
+
pub config: SearchConfig,
|
|
111
|
+
pub embedding_manager: EmbeddingsManager,
|
|
112
|
+
pub store: SqliteStore,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
impl std::fmt::Debug for SearchEngine {
|
|
116
|
+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
117
|
+
f.debug_struct("SearchEngine")
|
|
118
|
+
.field("index", &self.index)
|
|
119
|
+
.field("config", &self.config)
|
|
120
|
+
.finish_non_exhaustive()
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
impl SearchEngine {
|
|
125
|
+
/// Create a copy of the search engine by recreating connections
|
|
126
|
+
pub fn duplicate(&self) -> Result<Self> {
|
|
127
|
+
let index_path = &self.config.index_path;
|
|
128
|
+
let embedding_manager = EmbeddingsManager::new(index_path)?;
|
|
129
|
+
let store = SqliteStore::new(&index_path.join("index.db"))?;
|
|
130
|
+
|
|
131
|
+
Ok(Self {
|
|
132
|
+
index: self.index.clone(),
|
|
133
|
+
config: self.config.clone(),
|
|
134
|
+
embedding_manager,
|
|
135
|
+
store,
|
|
136
|
+
})
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
1
140
|
impl SearchEngine {
|
|
2
141
|
pub fn new(project_dir: &Path) -> Result<Self> {
|
|
3
|
-
let config = SearchConfig::default();
|
|
142
|
+
let mut config = SearchConfig::default();
|
|
4
143
|
let index_path = project_dir.join(&config.index_path);
|
|
144
|
+
// Update config with absolute path for consistent usage
|
|
145
|
+
config.index_path = index_path.clone();
|
|
5
146
|
|
|
6
147
|
let embedding_manager = EmbeddingsManager::new(&index_path)?;
|
|
148
|
+
let store = SqliteStore::new(&index_path.join("index.db"))?;
|
|
7
149
|
|
|
8
150
|
Ok(Self {
|
|
9
151
|
index: VectorIndex::new(config.dimension),
|
|
10
152
|
config,
|
|
11
153
|
embedding_manager,
|
|
154
|
+
store,
|
|
12
155
|
})
|
|
13
156
|
}
|
|
14
157
|
|
|
@@ -36,14 +179,12 @@ impl SearchEngine {
|
|
|
36
179
|
pub fn search(&self, query: &str, max_results: Option<usize>) -> Result<Vec<SearchResult>> {
|
|
37
180
|
let max_results = max_results.unwrap_or(self.config.max_results);
|
|
38
181
|
|
|
39
|
-
|
|
40
|
-
let pattern_results = self.embedding_manager.store.search_patterns(query, max_results)?;
|
|
182
|
+
let pattern_results = self.store.search_patterns(query, max_results)?;
|
|
41
183
|
|
|
42
184
|
let mut results = Vec::new();
|
|
43
185
|
|
|
44
186
|
for (pattern, score) in pattern_results {
|
|
45
|
-
|
|
46
|
-
if let Some((_, metadata)) = self.embedding_manager.store.get_embedding(&pattern)? {
|
|
187
|
+
if let Some((_, metadata)) = self.store.get_embedding(&pattern)? {
|
|
47
188
|
results.push(SearchResult {
|
|
48
189
|
id: pattern.clone(),
|
|
49
190
|
path: metadata.path.clone(),
|
|
@@ -56,7 +197,6 @@ impl SearchEngine {
|
|
|
56
197
|
}
|
|
57
198
|
}
|
|
58
199
|
|
|
59
|
-
// Sort and limit results
|
|
60
200
|
results.sort_by(|a, b| b.score.partial_cmp(&a.score).unwrap());
|
|
61
201
|
results.truncate(max_results);
|
|
62
202
|
|
|
@@ -94,10 +234,8 @@ impl SearchEngine {
|
|
|
94
234
|
let index_file = self.config.index_path.join("index.bin");
|
|
95
235
|
let metadata_file = self.config.index_path.join("metadata.json");
|
|
96
236
|
|
|
97
|
-
// Save vectors and IDs
|
|
98
237
|
self.save_vectors(&index_file)?;
|
|
99
238
|
|
|
100
|
-
// Save metadata
|
|
101
239
|
let metadata_json = serde_json::to_string_pretty(&self.index.metadata)?;
|
|
102
240
|
std::fs::write(&metadata_file, metadata_json)?;
|
|
103
241
|
|
|
@@ -114,22 +252,18 @@ impl SearchEngine {
|
|
|
114
252
|
|
|
115
253
|
let mut writer = BufWriter::new(file);
|
|
116
254
|
|
|
117
|
-
|
|
118
|
-
writer.write_u32::<LittleEndian>(
|
|
119
|
-
writer.write_u32::<LittleEndian>(1)?; // Version
|
|
255
|
+
writer.write_u32::<LittleEndian>(0x52554345)?;
|
|
256
|
+
writer.write_u32::<LittleEndian>(1)?;
|
|
120
257
|
|
|
121
|
-
// Write dimensions and count
|
|
122
258
|
writer.write_u32::<LittleEndian>(self.config.dimension as u32)?;
|
|
123
259
|
writer.write_u32::<LittleEndian>(self.index.vectors.nrows() as u32)?;
|
|
124
260
|
|
|
125
|
-
// Write vectors
|
|
126
261
|
for vector in self.index.vectors.rows() {
|
|
127
262
|
for &value in vector.iter() {
|
|
128
263
|
writer.write_f32::<LittleEndian>(value)?;
|
|
129
264
|
}
|
|
130
265
|
}
|
|
131
266
|
|
|
132
|
-
// Write IDs (length-prefixed strings)
|
|
133
267
|
for id in &self.index.ids {
|
|
134
268
|
writer.write_u32::<LittleEndian>(id.len() as u32)?;
|
|
135
269
|
writer.write_all(id.as_bytes())?;
|
|
@@ -143,10 +277,8 @@ impl SearchEngine {
|
|
|
143
277
|
let index_file = self.config.index_path.join("index.bin");
|
|
144
278
|
let metadata_file = self.config.index_path.join("metadata.json");
|
|
145
279
|
|
|
146
|
-
// Load vectors and IDs
|
|
147
280
|
self.load_vectors(&index_file)?;
|
|
148
281
|
|
|
149
|
-
// Load metadata
|
|
150
282
|
let metadata_json = std::fs::read_to_string(&metadata_file)
|
|
151
283
|
.context("Failed to read metadata file")?;
|
|
152
284
|
self.index.metadata = serde_json::from_str(&metadata_json)
|
|
@@ -159,11 +291,9 @@ impl SearchEngine {
|
|
|
159
291
|
let file = File::open(path)?;
|
|
160
292
|
|
|
161
293
|
if self.config.use_mmap {
|
|
162
|
-
// Use memory mapping for large files
|
|
163
294
|
let mmap = unsafe { MmapOptions::new().map(&file)? };
|
|
164
295
|
self.load_vectors_from_slice(&mmap)?;
|
|
165
296
|
} else {
|
|
166
|
-
// Read normally for smaller files
|
|
167
297
|
let mut reader = BufReader::new(file);
|
|
168
298
|
self.load_vectors_from_reader(&mut reader)?;
|
|
169
299
|
}
|
|
@@ -179,19 +309,16 @@ impl SearchEngine {
|
|
|
179
309
|
}
|
|
180
310
|
|
|
181
311
|
fn load_vectors_from_reader<R: Read>(&mut self, reader: &mut R) -> Result<()> {
|
|
182
|
-
// Read and verify magic number
|
|
183
312
|
let magic = reader.read_u32::<LittleEndian>()?;
|
|
184
313
|
if magic != 0x52554345 {
|
|
185
314
|
return Err(anyhow!("Invalid file format"));
|
|
186
315
|
}
|
|
187
316
|
|
|
188
|
-
// Read version
|
|
189
317
|
let version = reader.read_u32::<LittleEndian>()?;
|
|
190
318
|
if version != 1 {
|
|
191
319
|
return Err(anyhow!("Unsupported version: {}", version));
|
|
192
320
|
}
|
|
193
321
|
|
|
194
|
-
// Read dimensions and count
|
|
195
322
|
let dimension = reader.read_u32::<LittleEndian>()? as usize;
|
|
196
323
|
let count = reader.read_u32::<LittleEndian>()? as usize;
|
|
197
324
|
|
|
@@ -203,7 +330,6 @@ impl SearchEngine {
|
|
|
203
330
|
));
|
|
204
331
|
}
|
|
205
332
|
|
|
206
|
-
// Read vectors
|
|
207
333
|
let mut vectors = Vec::with_capacity(count * dimension);
|
|
208
334
|
for _ in 0..count * dimension {
|
|
209
335
|
vectors.push(reader.read_f32::<LittleEndian>()?);
|
|
@@ -211,7 +337,6 @@ impl SearchEngine {
|
|
|
211
337
|
|
|
212
338
|
let vectors_array = Array2::from_shape_vec((count, dimension), vectors)?;
|
|
213
339
|
|
|
214
|
-
// Read IDs
|
|
215
340
|
let mut ids = Vec::with_capacity(count);
|
|
216
341
|
for _ in 0..count {
|
|
217
342
|
let len = reader.read_u32::<LittleEndian>()? as usize;
|
|
@@ -236,7 +361,7 @@ impl SearchEngine {
|
|
|
236
361
|
}
|
|
237
362
|
|
|
238
363
|
fn estimate_index_size(&self) -> u64 {
|
|
239
|
-
let vectors_size = self.index.vectors.nrows() * self.index.vectors.ncols() * 4;
|
|
364
|
+
let vectors_size = self.index.vectors.nrows() * self.index.vectors.ncols() * 4;
|
|
240
365
|
let ids_size: usize = self.index.ids.iter().map(|id| id.len()).sum();
|
|
241
366
|
(vectors_size + ids_size) as u64
|
|
242
367
|
}
|
|
@@ -244,7 +369,6 @@ impl SearchEngine {
|
|
|
244
369
|
pub fn optimize_index(&mut self) -> Result<()> {
|
|
245
370
|
info!("Optimizing index...");
|
|
246
371
|
|
|
247
|
-
// Normalize all vectors
|
|
248
372
|
for mut vector in self.index.vectors.rows_mut() {
|
|
249
373
|
let norm = vector.iter().map(|x| x * x).sum::<f32>().sqrt();
|
|
250
374
|
if norm > 0.0 {
|
|
@@ -254,15 +378,13 @@ impl SearchEngine {
|
|
|
254
378
|
}
|
|
255
379
|
}
|
|
256
380
|
|
|
257
|
-
|
|
258
|
-
self.rebuild_metadata_indexlettes()?;
|
|
381
|
+
self.rebuild_metadata_index()?;
|
|
259
382
|
|
|
260
383
|
info!("Index optimized successfully");
|
|
261
384
|
Ok(())
|
|
262
385
|
}
|
|
263
386
|
|
|
264
387
|
fn rebuild_metadata_index(&mut self) -> Result<()> {
|
|
265
|
-
// Create path-based index for faster filtering
|
|
266
388
|
let mut path_index: HashMap<String, Vec<String>> = HashMap::new();
|
|
267
389
|
|
|
268
390
|
for (id, metadata) in &self.index.metadata {
|
|
@@ -271,7 +393,6 @@ impl SearchEngine {
|
|
|
271
393
|
.push(id.clone());
|
|
272
394
|
}
|
|
273
395
|
|
|
274
|
-
// Store path index as metadata
|
|
275
396
|
let path_index_json = serde_json::to_string(&path_index)?;
|
|
276
397
|
let path_index_file = self.config.index_path.join("path_index.json");
|
|
277
398
|
std::fs::write(path_index_file, path_index_json)?;
|
|
@@ -122,7 +122,7 @@ impl SqliteStore {
|
|
|
122
122
|
"SELECT pattern FROM embeddings WHERE pattern LIKE ? LIMIT ?"
|
|
123
123
|
)?;
|
|
124
124
|
|
|
125
|
-
let mut rows = stmt.query([
|
|
125
|
+
let mut rows = stmt.query(params![format!("%{}%", query), limit as i64])?;
|
|
126
126
|
|
|
127
127
|
let mut results = Vec::new();
|
|
128
128
|
while let Some(row) = rows.next()? {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-loop-orchestration-v2
|
|
3
|
-
description: CFN Loop coordination and orchestration - gate checks, validation, consensus, coordination patterns
|
|
3
|
+
description: "CFN Loop coordination and orchestration - gate checks, validation, consensus, coordination patterns. Use when orchestrating multi-agent workflows, managing iteration cycles, or coordinating Loop 2/Loop 3 dependencies."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, cfn-loop, orchestration, coordination]
|
|
6
6
|
status: production
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-product-owner-decision
|
|
3
|
+
description: "Strategic decision-making for CFN Loop progression with robust parsing. Use when evaluating validator consensus and determining PROCEED/ITERATE/ABORT outcomes."
|
|
4
|
+
version: 2.0.0
|
|
5
|
+
tags: [cfn-loop, decision-making, product-owner, typescript, consensus]
|
|
6
|
+
status: production
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
# Product Owner Decision Skill
|
|
2
10
|
|
|
3
11
|
**Version:** 2.0.0 (TypeScript)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-loop-orchestration
|
|
3
|
-
description: CFN Loop workflow orchestration - three-loop structure management with gate checks and consensus
|
|
3
|
+
description: "CFN Loop workflow orchestration - three-loop structure management with gate checks and consensus. Use when coordinating Loop 3 implementers and Loop 2 validators, managing iteration cycles, or enforcing quality gates."
|
|
4
4
|
version: 3.1.0
|
|
5
5
|
tags: [orchestration, cfn-loop, workflow, consensus]
|
|
6
6
|
status: production
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-loop-output-processing
|
|
3
|
+
description: "Type-safe output processing for Loop 2 validators and Loop 3 implementers. Use when parsing agent confidence scores, feedback, or calculating consensus from multiple validators."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [cfn-loop, output-processing, typescript, validation, consensus]
|
|
6
|
+
status: production
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
# CFN Loop Output Processing - Unified TypeScript Module
|
|
2
10
|
|
|
3
11
|
**Version:** 1.0.0
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-loop-validation
|
|
3
|
+
description: "Multi-layer validation and quality gates for CFN Loop workflows. Use when implementing gate checks, consensus validation, or enforcing clean agent exit patterns."
|
|
4
|
+
version: 2.3.0
|
|
5
|
+
tags: [cfn-loop, validation, quality-gates, consensus, typescript]
|
|
6
|
+
status: production
|
|
7
|
+
confidence: 0.98
|
|
8
|
+
---
|
|
9
|
+
|
|
1
10
|
# CFN Loop Validation Skill
|
|
2
11
|
|
|
3
12
|
**Purpose:** Implement multi-layer validation and quality gates for CFN Loop workflows with clean agent exit patterns.
|
|
4
13
|
|
|
5
|
-
**Version:** 2.3.0
|
|
6
|
-
**Confidence:** 0.98
|
|
14
|
+
**Version:** 2.3.0
|
|
15
|
+
**Confidence:** 0.98
|
|
7
16
|
**Status:** Production Ready (Robustness Enhanced)
|
|
8
17
|
|
|
9
18
|
---
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-automatic-memory-persistence
|
|
3
|
+
description: "Automatic, structured persistence of agent outputs to SQLite database. Use when tracking agent outputs across CFN Loop workflows, persisting confidence scores, or querying agent execution history."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [memory, persistence, sqlite, auto, agent-tracking]
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# Automatic Memory Persistence Skill
|
|
2
9
|
|
|
3
10
|
## Overview
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-memory-management
|
|
3
|
+
description: "Prevent and detect memory leaks in Claude CLI operations through proactive monitoring, limits, and profiling. Use when managing memory limits for long-running agents, detecting memory leaks, profiling heap usage, or implementing recovery procedures."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [memory, monitoring, profiling, leak-detection, performance]
|
|
6
|
+
---
|
|
7
|
+
|
|
1
8
|
# CFN Memory Management Skill
|
|
2
9
|
|
|
3
10
|
**Purpose:** Prevent and detect memory leaks in Claude CLI operations through proactive monitoring, limits, and profiling.
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cfn-parameterized-queries
|
|
3
|
+
description: "Secure SQL query execution with parameterized queries to prevent SQL injection attacks. Use when executing database queries, inserting/updating records, or performing any SQL operations that require security hardening."
|
|
4
|
+
version: 1.0.0
|
|
5
|
+
tags: [security, sql, database, parameterized-queries, injection-prevention]
|
|
6
|
+
status: production
|
|
7
|
+
---
|
|
8
|
+
|
|
1
9
|
#!/bin/bash
|
|
2
10
|
|
|
3
11
|
# CFN Parameterized Queries - Secure SQL Query Execution
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-planning
|
|
3
|
-
description: Epic decomposition, coordinator planning, and scope management
|
|
3
|
+
description: "Epic decomposition, coordinator planning, and scope management. Use when breaking down epics into sprints and tasks, coordinating multi-coordinator workflows, or simplifying and managing project scope boundaries."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, epic, planning, scope, decomposition]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-skill-management
|
|
3
|
-
description: Skill loading, propagation, and building for CFN
|
|
3
|
+
description: "Skill loading, propagation, and building for CFN. Use when dynamically discovering and loading skills, deploying skills across environments, or creating new skill scaffolding."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [mega-skill, skills, loader, builder, deployment]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-transparency-middleware
|
|
3
|
-
description: Agent interaction capture, logging, and analysis with memory tracking and security (Rust implementation)
|
|
3
|
+
description: "Agent interaction capture, logging, and analysis with memory tracking and security (Rust implementation). Use when you need to capture and analyze agent interactions, track tool usage and performance metrics, query execution history, or export audit trails for compliance."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [middleware, logging, security, transparency, memory, rust]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-utilities
|
|
3
|
-
description: Reusable bash utility functions for CFN Loop - logging, error handling, retry, file operations
|
|
3
|
+
description: "Reusable bash utility functions for CFN Loop - logging, error handling, retry, file operations. Use when you need structured logging, atomic file operations, retry logic with exponential backoff, or standardized error handling in bash scripts."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [bash, logging, error-handling, retry, file-operations, utilities]
|
|
6
6
|
status: production
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: cfn-vision-analysis
|
|
3
|
-
description: Image and vision analysis capabilities for screenshot and mockup validation
|
|
3
|
+
description: "Image and vision analysis capabilities for screenshot and mockup validation. Use when validating screenshots against mockups, checking UI consistency, detecting visual regressions, or verifying brand guideline compliance."
|
|
4
4
|
version: 1.0.0
|
|
5
5
|
tags: [vision, image, analysis, screenshots]
|
|
6
6
|
status: production
|
package/index/index.bin
ADDED
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow-novice",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.13",
|
|
4
4
|
"description": "Claude Flow Novice - Advanced orchestration platform for multi-agent AI workflows with CFN Loop architecture\n\nIncludes Local RuVector Accelerator and all CFN skills for complete functionality.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
┌─────────────────┐
|
|
2
|
-
│ cargo check │ → Parse Rust errors
|
|
3
|
-
└────────┬────────┘
|
|
4
|
-
▼
|
|
5
|
-
┌─────────────────┐
|
|
6
|
-
│ Cerebras LLM │ → Generate fix
|
|
7
|
-
└────────┬────────┘
|
|
8
|
-
▼
|
|
9
|
-
┌─────────────────────────────────────────┐
|
|
10
|
-
│ LAYER 1: Structural Gates │
|
|
11
|
-
│ A: Line Count Delta G: Import Path │
|
|
12
|
-
│ B: Function Signature H: Pattern Dup │
|
|
13
|
-
│ C: Import Duplicates I: Impl Loc │
|
|
14
|
-
│ D: Brace Balance J: Type Cast │
|
|
15
|
-
│ E: Semantic Diff K: Match Arm │
|
|
16
|
-
│ F: Orphaned Code L: Regression │
|
|
17
|
-
└────────┬────────────────────────────────┘
|
|
18
|
-
▼
|
|
19
|
-
┌─────────────────┐
|
|
20
|
-
│ LAYER 2: Clippy│
|
|
21
|
-
└────────┬────────┘
|
|
22
|
-
▼
|
|
23
|
-
┌─────────────────┐
|
|
24
|
-
│ LAYER 3: Review │
|
|
25
|
-
└────────┬────────┘
|
|
26
|
-
▼
|
|
27
|
-
┌─────────────────┐
|
|
28
|
-
│ Write to file │
|
|
29
|
-
└─────────────────┘
|
|
Binary file
|