@neikyun/ciel 6.9.2 → 6.10.1
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.
|
@@ -33,6 +33,11 @@ declare -a SOURCES=(
|
|
|
33
33
|
# .claude/rules/*.md detected separately (variable count)
|
|
34
34
|
RULES_DIR="$PROJECT_DIR/.claude/rules"
|
|
35
35
|
|
|
36
|
+
# Claude Code's per-project auto-memory dir. Lives OUTSIDE the repo, derived
|
|
37
|
+
# from cwd with `/` replaced by `-`. Tests override via CIEL_AUTO_MEMORY_DIR.
|
|
38
|
+
# Pattern: ~/.claude/projects/-Users-foo-Projects-Bar/memory/
|
|
39
|
+
AUTO_MEMORY_DIR="${CIEL_AUTO_MEMORY_DIR:-$HOME/.claude/projects/$(echo "$PROJECT_DIR" | sed 's|/|-|g')/memory}"
|
|
40
|
+
|
|
36
41
|
# ─── Helpers ─────────────────────────────────────────────────────────────────
|
|
37
42
|
|
|
38
43
|
scan_sources() {
|
|
@@ -58,6 +63,17 @@ scan_sources() {
|
|
|
58
63
|
fi
|
|
59
64
|
fi
|
|
60
65
|
|
|
66
|
+
# Claude Code auto-memory — excludes the MEMORY.md index file (just a TOC,
|
|
67
|
+
# not memory content). Each *.md sibling is a discrete entry to migrate.
|
|
68
|
+
if [[ -d "$AUTO_MEMORY_DIR" ]]; then
|
|
69
|
+
local auto_count
|
|
70
|
+
auto_count=$(find "$AUTO_MEMORY_DIR" -maxdepth 1 -name "*.md" -type f -not -name "MEMORY.md" 2>/dev/null | wc -l | tr -d ' ')
|
|
71
|
+
if [[ "$auto_count" -gt 0 ]]; then
|
|
72
|
+
echo " ✓ $AUTO_MEMORY_DIR/ ($auto_count Claude Code auto-memory entries — to migrate to .ciel/memory/)"
|
|
73
|
+
found=$((found + auto_count))
|
|
74
|
+
fi
|
|
75
|
+
fi
|
|
76
|
+
|
|
61
77
|
echo ""
|
|
62
78
|
if [[ "$found" -eq 0 ]]; then
|
|
63
79
|
echo "No ingestable sources found. The cued-recall memory will populate"
|
|
@@ -233,8 +233,16 @@ def match_path_pattern(pattern: str, paths) -> bool:
|
|
|
233
233
|
return False
|
|
234
234
|
|
|
235
235
|
|
|
236
|
-
def score_memory(mem, paths, symbols, intents, langs) -> int:
|
|
237
|
-
"""Score a memory's relevance. 0 = exclude. Positive = include, higher first.
|
|
236
|
+
def score_memory(mem, paths, symbols, intents, langs, prompt_lower="") -> int:
|
|
237
|
+
"""Score a memory's relevance. 0 = exclude. Positive = include, higher first.
|
|
238
|
+
|
|
239
|
+
Symbol and intent matching are case-insensitive and fall back to a
|
|
240
|
+
word-boundary search against the raw prompt. This lets a memory tagged
|
|
241
|
+
`symbols: [OkHttp]` fire on a prompt that mentions "okhttp" in prose,
|
|
242
|
+
and lets free-form intent tags (e.g. `intents: [okhttp, diagnostics]`)
|
|
243
|
+
match without being members of the fixed INTENT_KEYWORDS vocabulary.
|
|
244
|
+
Word boundaries prevent "test" intent from firing on "contest".
|
|
245
|
+
"""
|
|
238
246
|
# Hard language gate: if memory is language-specific AND prompt has language
|
|
239
247
|
# cues AND no overlap → exclude. Avoids Kotlin memories firing on TS edits.
|
|
240
248
|
mem_langs = mem.get('languages') or []
|
|
@@ -245,11 +253,23 @@ def score_memory(mem, paths, symbols, intents, langs) -> int:
|
|
|
245
253
|
for pattern in mem.get('path_patterns') or []:
|
|
246
254
|
if match_path_pattern(pattern, paths):
|
|
247
255
|
score += 10
|
|
256
|
+
|
|
257
|
+
# Case-insensitive comparison sets — built once per memory call.
|
|
258
|
+
symbols_lower = {s.lower() for s in symbols}
|
|
259
|
+
intents_lower = {i.lower() for i in intents}
|
|
260
|
+
|
|
248
261
|
for sym in mem.get('symbols') or []:
|
|
249
|
-
|
|
262
|
+
sym_lower = sym.lower()
|
|
263
|
+
if sym_lower in symbols_lower or (
|
|
264
|
+
prompt_lower and re.search(r'\b' + re.escape(sym_lower) + r'\b', prompt_lower)
|
|
265
|
+
):
|
|
250
266
|
score += 8
|
|
267
|
+
|
|
251
268
|
for intent in mem.get('intents') or []:
|
|
252
|
-
|
|
269
|
+
intent_lower = intent.lower()
|
|
270
|
+
if intent_lower in intents_lower or (
|
|
271
|
+
prompt_lower and re.search(r'\b' + re.escape(intent_lower) + r'\b', prompt_lower)
|
|
272
|
+
):
|
|
253
273
|
score += 5
|
|
254
274
|
|
|
255
275
|
# No cue match at all → don't include (cued recall, not free recall)
|
|
@@ -399,6 +419,7 @@ def cmd_query(args):
|
|
|
399
419
|
symbols = extract_symbol_cues(prompt)
|
|
400
420
|
intents = extract_intent_cues(prompt)
|
|
401
421
|
langs = extract_language_cues(prompt)
|
|
422
|
+
prompt_lower = prompt.lower()
|
|
402
423
|
now = datetime.now(timezone.utc)
|
|
403
424
|
iso_now = now.isoformat().replace('+00:00', 'Z')
|
|
404
425
|
|
|
@@ -418,7 +439,7 @@ def cmd_query(args):
|
|
|
418
439
|
for mid, m in mems.items():
|
|
419
440
|
if m.get('stale'):
|
|
420
441
|
continue
|
|
421
|
-
s = score_memory(m, paths, symbols, intents, langs)
|
|
442
|
+
s = score_memory(m, paths, symbols, intents, langs, prompt_lower=prompt_lower)
|
|
422
443
|
if s > 0:
|
|
423
444
|
scored.append((s, mid, m))
|
|
424
445
|
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Scan project for ingestable tribal docs (lessons.md, ciel-overlay.md, .claude/rules/, etc.) and propose ingestion into the cued-recall memory under .ciel/memory/. Reports findings if no sources found. Always confirms each candidate with the user before writing.
|
|
2
|
+
description: Scan project for ingestable tribal docs (lessons.md, ciel-overlay.md, .claude/rules/, Claude Code auto-memory at ~/.claude/projects/<slug>/memory/, etc.) and propose ingestion into the cued-recall memory under .ciel/memory/. Reports findings if no sources found. Always confirms each candidate with the user before writing.
|
|
3
3
|
---
|
|
4
4
|
|
|
5
5
|
# /ciel-memory-bootstrap — Initialize Cued-Recall Memory
|
|
6
6
|
|
|
7
|
-
**Purpose:** First-run scan of an existing project to convert tribal knowledge already documented in `lessons.md`, `ciel-overlay.md`, `.claude/rules/`, and similar files into the structured cued-recall memory at `.ciel/memory/`.
|
|
7
|
+
**Purpose:** First-run scan of an existing project to convert tribal knowledge already documented in `lessons.md`, `ciel-overlay.md`, `.claude/rules/`, Claude Code's per-project auto-memory (`~/.claude/projects/<slug>/memory/`), and similar files into the structured cued-recall memory at `.ciel/memory/`.
|
|
8
8
|
|
|
9
9
|
**Usage:** `/ciel-memory-bootstrap` (no args)
|
|
10
10
|
|
|
@@ -60,6 +60,39 @@ For each source found in Step 1, `Read` the file fully. Identify candidate memor
|
|
|
60
60
|
| `## Heading\n\n- rule\n- rule` (rules.md style) | One memory per rule. |
|
|
61
61
|
| Numbered lessons in `ciel-overlay.md` "Key Lessons" | One memory per lesson. |
|
|
62
62
|
| `## section` in CLAUDE.md/AGENTS.md describing a non-obvious convention | One memory per section. |
|
|
63
|
+
| **Claude Code auto-memory** entries (`~/.claude/projects/<slug>/memory/*.md`, excluding `MEMORY.md`) | One memory per file. Title = frontmatter `description`. Cues derived per "Auto-memory mapping" below. |
|
|
64
|
+
|
|
65
|
+
#### Auto-memory mapping (special parser)
|
|
66
|
+
|
|
67
|
+
Claude Code auto-memory uses a different frontmatter than Ciel's cued-recall. Each source file looks like:
|
|
68
|
+
|
|
69
|
+
```yaml
|
|
70
|
+
---
|
|
71
|
+
name: feedback-okhttp-cookiejar-override
|
|
72
|
+
description: Neiyomi shared PersistentCookieJar overrides manual Cookie headers via OkHttp BridgeInterceptor
|
|
73
|
+
metadata:
|
|
74
|
+
type: feedback
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
(body markdown — Context / Why / How to apply sections)
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
When you encounter a file under `$AUTO_MEMORY_DIR`, map it to a Ciel episode as follows:
|
|
81
|
+
|
|
82
|
+
| Auto-memory field | Ciel frontmatter field | Notes |
|
|
83
|
+
|---|---|---|
|
|
84
|
+
| `description:` | `title:` | one-line summary |
|
|
85
|
+
| `name:` | base of slug for filename | already kebab-case |
|
|
86
|
+
| `metadata.type:` (`user`/`feedback`/`project`/`reference`) | `intents:` `[<type>]` plus topic-specific intents inferred from body | e.g. `feedback` + `okhttp` + `cookie` |
|
|
87
|
+
| body markdown | Ciel episode body, verbatim | preserve Context/Why/How to apply structure |
|
|
88
|
+
| paths cited in body (e.g. `src/`, `*.kt`, `Caddyfile`) | `path_patterns:` | infer from grep — narrow patterns preferred |
|
|
89
|
+
| symbols cited in body (class/function/table names) | `symbols:` | infer from grep |
|
|
90
|
+
| language hint (file extensions in body) | `languages:` | `kotlin`/`typescript`/`python`/`sql`/etc. |
|
|
91
|
+
| `captured_from:` (NEW) | `auto-memory-migration` | distinguishes from user-intervention captures |
|
|
92
|
+
|
|
93
|
+
**Skip `MEMORY.md`** — it's a table-of-contents index, not memory content. The scan already excludes it.
|
|
94
|
+
|
|
95
|
+
**Backup before delete.** After successfully writing an episode file for an auto-memory entry, MOVE (not delete) the source to `$AUTO_MEMORY_DIR/.migrated-to-ciel/<filename>` so the user can audit migration. The MEMORY.md index file itself stays in place — Claude Code may regenerate it on next session.
|
|
63
96
|
|
|
64
97
|
Skip:
|
|
65
98
|
- The pipeline / workflow descriptions (those belong in CLAUDE.md, not memory)
|
|
@@ -152,6 +185,8 @@ Report:
|
|
|
152
185
|
| Nothing scanned | No tribal docs in this project | Working as intended; report and end |
|
|
153
186
|
| Memories all tagged with broad paths | Source content didn't include path hints | Ask user to refine tags after listing |
|
|
154
187
|
| index.json malformed after rebuild | python3 parse error | Recreate empty index, re-run rebuild step |
|
|
188
|
+
| Auto-memory not detected | Slug derivation mismatch (cwd has unexpected characters) | Override via `CIEL_AUTO_MEMORY_DIR=<absolute-path> bash hooks/memory-bootstrap.sh scan` |
|
|
189
|
+
| Auto-memory file has `name:` but no `description:` | Older auto-memory format | Use first heading or filename as title; ask user to confirm before writing |
|
|
155
190
|
|
|
156
191
|
## See also
|
|
157
192
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neikyun/ciel",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.10.1",
|
|
4
4
|
"description": "Ciel — Deep-reasoning pipeline for LLM-assisted development. OpenCode plugin + multi-platform CLI (OpenCode, Claude Code, more).",
|
|
5
5
|
"main": "./dist/plugin/index.js",
|
|
6
6
|
"types": "./dist/plugin/index.d.ts",
|