Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .kyzn/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# kyzn — gitignored local data
history/
reports/
35 changes: 35 additions & 0 deletions .kyzn/config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# kyzn configuration — commit this file
# Generated by: kyzn init
# Date: 2026-03-18T00:24:58Z

project:
name: bloxcue
type: generic

preferences:
mode:
How aggressive should improvements be?
Comment on lines +10 to +11
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Commit a parseable .kyzn/config.yaml

The new config file is not valid YAML: the prompt transcript was written literally after mode: here, and ruby -e 'require "yaml"; YAML.load_file(".kyzn/config.yaml")' fails with could not find expected ':' at line 11. Any future kyzn run in this repo that tries to load .kyzn/config.yaml will fail before it can read the project preferences.

Useful? React with 👍 / 👎.

1) Deep — real improvements only (no cosmetic changes)
2) Clean — dead weight cleanup (remove unused code, fix naming)
3) Full — everything (maximum value per run)

Choice [1]: 1
budget: Budget per run (USD) [2.50]: 2.50
max_turns: 30
diff_limit: 2000
trust:
Trust level for auto-merging?
1) Guardian — always create PR, always wait for approval (recommended)
2) Autopilot — auto-merge if build passes + tests pass + diff < threshold

Choice [1]: 1
on_build_fail:
If the build breaks after improvements, what should kyzn do?
1) Write a report explaining what happened (recommended)
2) Silently discard the branch
3) Create a draft PR so you can see what was attempted

Choice [1]: 1

focus:
priorities: []
27 changes: 17 additions & 10 deletions scripts/indexer.py
Original file line number Diff line number Diff line change
Expand Up @@ -822,8 +822,10 @@ def load_index() -> Dict:
_index_cache = json.loads(INDEX_FILE.read_text())
_index_mtime = current_mtime
return _index_cache
except Exception:
pass
except (OSError, json.JSONDecodeError) as e:
print(f"[bloxcue] Warning: failed to load index cache ({e}), rebuilding", file=sys.stderr)
except Exception as e:
print(f"[bloxcue] Warning: unexpected error loading index ({e}), rebuilding", file=sys.stderr)

return build_index()

Expand Down Expand Up @@ -955,12 +957,15 @@ def search(query: str, limit: int = 5) -> List[Dict]:

# Bigram bonus (phrase matching)
entry_bigrams = entry.get("bigrams", [])
entry_bigrams_set = set(entry_bigrams)
for qbigram in query_bigrams:
for ebigram in entry_bigrams:
if qbigram == ebigram:
score += 5.0
elif qbigram in ebigram or ebigram in qbigram:
score += 2.5
if qbigram in entry_bigrams_set:
score += 5.0
else:
for ebigram in entry_bigrams:
if qbigram in ebigram or ebigram in qbigram:
score += 2.5
break

# Fuzzy fallback: catch matches that BM25 missed (typos, partial matches)
if score == 0:
Expand Down Expand Up @@ -1027,6 +1032,7 @@ def search(query: str, limit: int = 5) -> List[Dict]:
# MMR diversity: reduce redundancy in top results
if len(results) > 1:
selected = [results[0]]
selected_term_sets = [set(results[0]["entry"].get("keywords", []))]
remaining = results[1:]

while remaining and len(selected) < limit:
Expand All @@ -1036,8 +1042,7 @@ def search(query: str, limit: int = 5) -> List[Dict]:
for i, candidate in enumerate(remaining):
cand_terms = set(candidate["entry"].get("keywords", []))
max_overlap = 0.0
for sel in selected:
sel_terms = set(sel["entry"].get("keywords", []))
for sel_terms in selected_term_sets:
if cand_terms and sel_terms:
union = len(cand_terms | sel_terms)
if union > 0:
Expand All @@ -1051,7 +1056,9 @@ def search(query: str, limit: int = 5) -> List[Dict]:
best_mmr = mmr
best_idx = i

selected.append(remaining.pop(best_idx))
chosen = remaining.pop(best_idx)
selected.append(chosen)
selected_term_sets.append(set(chosen["entry"].get("keywords", [])))

results = selected

Expand Down
Loading