agent-knowledge-cli 0.1.2__py3-none-any.whl

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.
Files changed (88) hide show
  1. agent_knowledge/__init__.py +3 -0
  2. agent_knowledge/__main__.py +3 -0
  3. agent_knowledge/assets/__init__.py +0 -0
  4. agent_knowledge/assets/claude/global.md +44 -0
  5. agent_knowledge/assets/claude/project-template.md +46 -0
  6. agent_knowledge/assets/claude/scripts/install.sh +85 -0
  7. agent_knowledge/assets/commands/doctor.md +21 -0
  8. agent_knowledge/assets/commands/global-knowledge-sync.md +27 -0
  9. agent_knowledge/assets/commands/graphify-sync.md +26 -0
  10. agent_knowledge/assets/commands/knowledge-sync.md +26 -0
  11. agent_knowledge/assets/commands/ship.md +29 -0
  12. agent_knowledge/assets/rules/generate-architecture-doc.mdc +87 -0
  13. agent_knowledge/assets/rules/history-backfill.mdc +67 -0
  14. agent_knowledge/assets/rules/memory-bootstrap.mdc +53 -0
  15. agent_knowledge/assets/rules/memory-writeback.mdc +90 -0
  16. agent_knowledge/assets/rules/shared-memory.mdc +102 -0
  17. agent_knowledge/assets/rules/workflow-orchestration.mdc +93 -0
  18. agent_knowledge/assets/rules-global/action-first.mdc +26 -0
  19. agent_knowledge/assets/rules-global/no-icons-emojis.mdc +16 -0
  20. agent_knowledge/assets/rules-global/no-unsolicited-docs.mdc +20 -0
  21. agent_knowledge/assets/scripts/bootstrap-memory-tree.sh +389 -0
  22. agent_knowledge/assets/scripts/compact-memory.sh +191 -0
  23. agent_knowledge/assets/scripts/doctor.sh +137 -0
  24. agent_knowledge/assets/scripts/global-knowledge-sync.sh +372 -0
  25. agent_knowledge/assets/scripts/graphify-sync.sh +397 -0
  26. agent_knowledge/assets/scripts/import-agent-history.sh +706 -0
  27. agent_knowledge/assets/scripts/install-project-links.sh +258 -0
  28. agent_knowledge/assets/scripts/lib/knowledge-common.sh +875 -0
  29. agent_knowledge/assets/scripts/measure-token-savings.py +540 -0
  30. agent_knowledge/assets/scripts/ship.sh +256 -0
  31. agent_knowledge/assets/scripts/update-knowledge.sh +341 -0
  32. agent_knowledge/assets/scripts/validate-knowledge.sh +265 -0
  33. agent_knowledge/assets/skills/decision-recording/SKILL.md +124 -0
  34. agent_knowledge/assets/skills/history-backfill/SKILL.md +115 -0
  35. agent_knowledge/assets/skills/memory-compaction/SKILL.md +115 -0
  36. agent_knowledge/assets/skills/memory-management/SKILL.md +134 -0
  37. agent_knowledge/assets/skills/project-ontology-bootstrap/SKILL.md +173 -0
  38. agent_knowledge/assets/skills/session-management/SKILL.md +116 -0
  39. agent_knowledge/assets/skills-cursor/create-rule/SKILL.md +164 -0
  40. agent_knowledge/assets/skills-cursor/create-skill/SKILL.md +498 -0
  41. agent_knowledge/assets/skills-cursor/create-subagent/SKILL.md +225 -0
  42. agent_knowledge/assets/skills-cursor/migrate-to-skills/SKILL.md +134 -0
  43. agent_knowledge/assets/skills-cursor/shell/SKILL.md +24 -0
  44. agent_knowledge/assets/skills-cursor/update-cursor-settings/SKILL.md +122 -0
  45. agent_knowledge/assets/templates/dashboards/project-overview.template.md +24 -0
  46. agent_knowledge/assets/templates/dashboards/session-rollup.template.md +23 -0
  47. agent_knowledge/assets/templates/hooks/hooks.json.template +11 -0
  48. agent_knowledge/assets/templates/integrations/claude/CLAUDE.md +7 -0
  49. agent_knowledge/assets/templates/integrations/codex/AGENTS.md +7 -0
  50. agent_knowledge/assets/templates/integrations/cursor/agent-knowledge.mdc +11 -0
  51. agent_knowledge/assets/templates/integrations/cursor/hooks.json +11 -0
  52. agent_knowledge/assets/templates/memory/MEMORY.root.template.md +36 -0
  53. agent_knowledge/assets/templates/memory/branch.template.md +33 -0
  54. agent_knowledge/assets/templates/memory/decision.template.md +33 -0
  55. agent_knowledge/assets/templates/memory/profile.hybrid.yaml +16 -0
  56. agent_knowledge/assets/templates/memory/profile.ml-platform.yaml +18 -0
  57. agent_knowledge/assets/templates/memory/profile.robotics.yaml +19 -0
  58. agent_knowledge/assets/templates/memory/profile.web-app.yaml +16 -0
  59. agent_knowledge/assets/templates/portfolio/.obsidian/README.md +21 -0
  60. agent_knowledge/assets/templates/portfolio/.obsidian/app.json +5 -0
  61. agent_knowledge/assets/templates/portfolio/.obsidian/core-plugins.json +7 -0
  62. agent_knowledge/assets/templates/project/.agent-project.yaml +36 -0
  63. agent_knowledge/assets/templates/project/.agentknowledgeignore +10 -0
  64. agent_knowledge/assets/templates/project/AGENTS.md +87 -0
  65. agent_knowledge/assets/templates/project/agent-knowledge/.obsidian/README.md +23 -0
  66. agent_knowledge/assets/templates/project/agent-knowledge/.obsidian/app.json +5 -0
  67. agent_knowledge/assets/templates/project/agent-knowledge/.obsidian/core-plugins.json +7 -0
  68. agent_knowledge/assets/templates/project/agent-knowledge/Evidence/README.md +34 -0
  69. agent_knowledge/assets/templates/project/agent-knowledge/Evidence/imports/README.md +29 -0
  70. agent_knowledge/assets/templates/project/agent-knowledge/Evidence/raw/README.md +25 -0
  71. agent_knowledge/assets/templates/project/agent-knowledge/Memory/MEMORY.md +37 -0
  72. agent_knowledge/assets/templates/project/agent-knowledge/Memory/decisions/decisions.md +31 -0
  73. agent_knowledge/assets/templates/project/agent-knowledge/Outputs/README.md +24 -0
  74. agent_knowledge/assets/templates/project/agent-knowledge/STATUS.md +43 -0
  75. agent_knowledge/assets/templates/project/agent-knowledge/Sessions/README.md +21 -0
  76. agent_knowledge/assets/templates/project/agent-knowledge/Templates/README.md +19 -0
  77. agent_knowledge/assets/templates/project/gitignore.agent-knowledge +13 -0
  78. agent_knowledge/cli.py +457 -0
  79. agent_knowledge/runtime/__init__.py +0 -0
  80. agent_knowledge/runtime/integrations.py +154 -0
  81. agent_knowledge/runtime/paths.py +46 -0
  82. agent_knowledge/runtime/shell.py +22 -0
  83. agent_knowledge/runtime/sync.py +255 -0
  84. agent_knowledge_cli-0.1.2.dist-info/METADATA +155 -0
  85. agent_knowledge_cli-0.1.2.dist-info/RECORD +88 -0
  86. agent_knowledge_cli-0.1.2.dist-info/WHEEL +4 -0
  87. agent_knowledge_cli-0.1.2.dist-info/entry_points.txt +2 -0
  88. agent_knowledge_cli-0.1.2.dist-info/licenses/LICENSE +21 -0
@@ -0,0 +1,706 @@
1
+ #!/bin/bash
2
+ #
3
+ # Collect project evidence into agent-knowledge/Evidence/raw/ and imports/.
4
+ #
5
+
6
+ set -euo pipefail
7
+
8
+ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
9
+ # shellcheck source=/dev/null
10
+ . "$SCRIPT_DIR/lib/knowledge-common.sh"
11
+
12
+ usage() {
13
+ cat <<'EOF'
14
+ Usage:
15
+ scripts/import-agent-history.sh [project-dir]
16
+ scripts/import-agent-history.sh --project <dir> [--dry-run] [--json] [--summary-file <file>]
17
+ EOF
18
+ }
19
+
20
+ TARGET_PROJECT_ARG="."
21
+ POSITIONAL=()
22
+ GENERATED=()
23
+ RAW_GENERATED=()
24
+ IMPORT_GENERATED=()
25
+ OUTPUT_GENERATED=()
26
+ CACHED=()
27
+ WARNINGS=()
28
+ SKIPPED=()
29
+ DATE="$(kc_today)"
30
+ GENERATED_AT="$(kc_now_utc)"
31
+
32
+ while [ "$#" -gt 0 ]; do
33
+ if kc_parse_common_flag "$@" ; then
34
+ shift
35
+ continue
36
+ fi
37
+ flag_status=$?
38
+ if [ "$flag_status" -eq 2 ]; then
39
+ shift 2
40
+ continue
41
+ fi
42
+
43
+ case "$1" in
44
+ --project)
45
+ TARGET_PROJECT_ARG="${2:-.}"
46
+ shift 2
47
+ ;;
48
+ *)
49
+ POSITIONAL+=("$1")
50
+ shift
51
+ ;;
52
+ esac
53
+ done
54
+
55
+ if [ "$SHOW_HELP" -eq 1 ]; then
56
+ usage
57
+ exit 0
58
+ fi
59
+
60
+ if [ ${#POSITIONAL[@]} -ge 1 ]; then
61
+ TARGET_PROJECT_ARG="${POSITIONAL[0]}"
62
+ fi
63
+
64
+ kc_load_project_context "$TARGET_PROJECT_ARG"
65
+ kc_require_knowledge_pointer
66
+ kc_ensure_dir "$EVIDENCE_RAW_DIR" "agent-knowledge/Evidence/raw"
67
+ kc_ensure_dir "$EVIDENCE_IMPORTS_DIR" "agent-knowledge/Evidence/imports"
68
+ kc_ensure_dir "$OUTPUTS_DIR" "agent-knowledge/Outputs"
69
+ kc_ensure_dir "$EVIDENCE_CACHE_DIR" "agent-knowledge/Evidence/.cache"
70
+
71
+ PROJECT_LABEL="$(basename "$TARGET_PROJECT")"
72
+
73
+ relative_path() {
74
+ sed "s|$TARGET_PROJECT/||" | sed "s|^$TARGET_PROJECT$|.|"
75
+ }
76
+
77
+ header() {
78
+ local title="$1"
79
+ local source="$2"
80
+ local kind="$3"
81
+ local confidence="$4"
82
+ printf '# Evidence: %s\n' "$title"
83
+ printf '# Source: %s\n' "$source"
84
+ printf '# Kind: %s\n' "$kind"
85
+ printf '# Confidence: %s\n' "$confidence"
86
+ printf '# Generated: %s\n' "$GENERATED_AT"
87
+ printf '# Project: %s\n\n' "$PROJECT_LABEL"
88
+ }
89
+
90
+ list_existing_paths() {
91
+ local base="$1"
92
+ shift
93
+ local path=""
94
+ local rel=""
95
+
96
+ for path in "$@"; do
97
+ rel="$(kc_normalize_relative_path "$path")"
98
+ [ -e "$base/$rel" ] || continue
99
+ if kc_path_is_ignored "$rel"; then
100
+ SKIPPED+=("$rel")
101
+ continue
102
+ fi
103
+ printf '%s\n' "$rel"
104
+ done
105
+ }
106
+
107
+ list_top_level_dirs() {
108
+ find "$TARGET_PROJECT" -mindepth 1 -maxdepth 1 -type d 2>/dev/null \
109
+ | relative_path \
110
+ | grep -Ev '^(agent-knowledge|node_modules|vendor|\.git|\.cursor|dist|build|\.next|__pycache__|\.venv)$' \
111
+ | kc_filter_relative_lines \
112
+ | sort
113
+ }
114
+
115
+ find_relative() {
116
+ local maxdepth="$1"
117
+ shift
118
+ find "$TARGET_PROJECT" "$@" -maxdepth "$maxdepth" 2>/dev/null \
119
+ | relative_path \
120
+ | kc_filter_relative_lines \
121
+ | sort
122
+ }
123
+
124
+ find_any_relative() {
125
+ find "$TARGET_PROJECT" "$@" 2>/dev/null \
126
+ | relative_path \
127
+ | kc_filter_relative_lines \
128
+ | sort
129
+ }
130
+
131
+ project_profile_guess() {
132
+ local manifest_total=0
133
+
134
+ manifest_total="$(printf '%s\n' "$MANIFEST_PATHS" | awk 'NF { count++ } END { print count + 0 }')"
135
+
136
+ if printf '%s\n' "$MANIFEST_PATHS" "$TEST_PATHS" "$TOP_LEVEL_DIRS" | grep -Eq '(^|/)(package\.xml|launch|urdf|simulation|gazebo|worlds)$' || \
137
+ printf '%s\n' "$MANIFEST_PATHS" | grep -q '^CMakeLists.txt$'; then
138
+ printf 'robotics\n'
139
+ return
140
+ fi
141
+
142
+ if printf '%s\n' "$MANIFEST_PATHS" "$TOP_LEVEL_DIRS" | grep -Eq '(^|/)(pyproject\.toml|requirements\.txt|notebooks|models|data)$'; then
143
+ printf 'ml-platform\n'
144
+ return
145
+ fi
146
+
147
+ if printf '%s\n' "$MANIFEST_PATHS" "$TOP_LEVEL_DIRS" | grep -Eq '(^|/)(pnpm-workspace\.yaml|nx\.json|turbo\.json|packages|services|apps)$' || [ "$manifest_total" -ge 3 ]; then
148
+ printf 'hybrid\n'
149
+ return
150
+ fi
151
+
152
+ if printf '%s\n' "$MANIFEST_PATHS" | grep -q '^package.json$'; then
153
+ printf 'web-app\n'
154
+ return
155
+ fi
156
+
157
+ printf '%s\n' "${PROJECT_PROFILE:-unknown}"
158
+ }
159
+
160
+ render_manifest_contents() {
161
+ local rel=""
162
+
163
+ while IFS= read -r rel; do
164
+ [ -n "$rel" ] || continue
165
+ printf '=== %s ===\n' "$rel"
166
+ if [ "$(wc -l < "$TARGET_PROJECT/$rel")" -gt 200 ]; then
167
+ head -60 "$TARGET_PROJECT/$rel"
168
+ printf '... (truncated at 60 lines)\n'
169
+ else
170
+ cat "$TARGET_PROJECT/$rel"
171
+ fi
172
+ printf '\n'
173
+ done <<EOF
174
+ $MANIFEST_PATHS
175
+ EOF
176
+ }
177
+
178
+ render_doc_contents() {
179
+ local rel=""
180
+
181
+ while IFS= read -r rel; do
182
+ [ -n "$rel" ] || continue
183
+ printf '=== %s ===\n' "$rel"
184
+ if [ "$(wc -l < "$TARGET_PROJECT/$rel")" -gt 300 ]; then
185
+ head -100 "$TARGET_PROJECT/$rel"
186
+ printf '... (truncated at 100 lines)\n'
187
+ else
188
+ cat "$TARGET_PROJECT/$rel"
189
+ fi
190
+ printf '\n'
191
+ done <<EOF
192
+ $DOC_IMPORT_PATHS
193
+ EOF
194
+ }
195
+
196
+ capture_text_artifact() {
197
+ local namespace="$1"
198
+ local key="$2"
199
+ local dst="$3"
200
+ local label="$4"
201
+ local bucket="$5"
202
+ local source="$6"
203
+ local kind="$7"
204
+ local confidence="$8"
205
+ local related_paths="$9"
206
+ local notes="${10:-}"
207
+ local signature="${11:-}"
208
+ local meta_dst="$dst.meta.json"
209
+ local tmp_file=""
210
+ local changed=0
211
+
212
+ if kc_cache_is_current "$namespace" "$key" "$signature" "$dst" "$meta_dst"; then
213
+ CACHED+=("$label")
214
+ return 0
215
+ fi
216
+
217
+ tmp_file="$(mktemp)"
218
+ cat > "$tmp_file"
219
+ kc_apply_temp_file "$tmp_file" "$dst" "$label"
220
+ case "$KC_LAST_ACTION" in
221
+ created|updated|would-create|would-update)
222
+ changed=1
223
+ ;;
224
+ esac
225
+
226
+ kc_write_metadata_json "$meta_dst" "$label.meta.json" "$source" "$kind" "$confidence" "$GENERATED_AT" "$related_paths" "$notes"
227
+ case "$KC_LAST_ACTION" in
228
+ created|updated|would-create|would-update)
229
+ changed=1
230
+ ;;
231
+ esac
232
+
233
+ kc_cache_store "$namespace" "$key" "$signature"
234
+
235
+ if [ "$changed" -eq 1 ]; then
236
+ GENERATED+=("$label")
237
+ case "$bucket" in
238
+ raw)
239
+ RAW_GENERATED+=("$label")
240
+ ;;
241
+ imports)
242
+ IMPORT_GENERATED+=("$label")
243
+ ;;
244
+ outputs)
245
+ OUTPUT_GENERATED+=("$label")
246
+ ;;
247
+ esac
248
+ fi
249
+ }
250
+
251
+ capture_markdown_note() {
252
+ local namespace="$1"
253
+ local key="$2"
254
+ local dst="$3"
255
+ local label="$4"
256
+ local bucket="$5"
257
+ local source="$6"
258
+ local kind="$7"
259
+ local confidence="$8"
260
+ local related_paths="$9"
261
+ local notes="${10}"
262
+ local signature="${11}"
263
+ local tmp_file=""
264
+ local changed=0
265
+
266
+ if kc_cache_is_current "$namespace" "$key" "$signature" "$dst"; then
267
+ CACHED+=("$label")
268
+ return 0
269
+ fi
270
+
271
+ tmp_file="$(mktemp)"
272
+ cat > "$tmp_file"
273
+ kc_apply_temp_file "$tmp_file" "$dst" "$label"
274
+ case "$KC_LAST_ACTION" in
275
+ created|updated|would-create|would-update)
276
+ changed=1
277
+ ;;
278
+ esac
279
+
280
+ kc_cache_store "$namespace" "$key" "$signature"
281
+
282
+ if [ "$changed" -eq 1 ]; then
283
+ GENERATED+=("$label")
284
+ case "$bucket" in
285
+ imports)
286
+ IMPORT_GENERATED+=("$label")
287
+ ;;
288
+ outputs)
289
+ OUTPUT_GENERATED+=("$label")
290
+ ;;
291
+ esac
292
+ fi
293
+ }
294
+
295
+ MANIFEST_PATHS="$(list_existing_paths "$TARGET_PROJECT" \
296
+ package.json package-lock.json pnpm-lock.yaml yarn.lock pnpm-workspace.yaml nx.json turbo.json \
297
+ pyproject.toml requirements.txt setup.py setup.cfg Pipfile poetry.lock \
298
+ Cargo.toml Cargo.lock go.mod go.sum CMakeLists.txt Makefile package.xml)"
299
+ DOC_IMPORT_PATHS="$(list_existing_paths "$TARGET_PROJECT" \
300
+ README.md README.rst CLAUDE.md AGENTS.md .agent-project.yaml .cursorrules \
301
+ agent-knowledge/INDEX.md agent-knowledge/Memory/MEMORY.md docs/README.md)"
302
+ CONFIG_PATHS="$(find "$TARGET_PROJECT" -maxdepth 2 \( \
303
+ -name ".editorconfig" -o \
304
+ -name ".clang-format" -o \
305
+ -name ".clang-tidy" -o \
306
+ -name ".eslintrc" -o \
307
+ -name ".eslintrc.js" -o \
308
+ -name ".eslintrc.cjs" -o \
309
+ -name "eslint.config.js" -o \
310
+ -name "eslint.config.mjs" -o \
311
+ -name "eslint.config.cjs" -o \
312
+ -name ".prettierrc" -o \
313
+ -name ".prettierrc.json" -o \
314
+ -name ".prettierrc.yaml" -o \
315
+ -name ".pre-commit-config.yaml" -o \
316
+ -name "pytest.ini" -o \
317
+ -name "mypy.ini" -o \
318
+ -name "ruff.toml" -o \
319
+ -name "tsconfig.json" -o \
320
+ -name "tsconfig.base.json" \) 2>/dev/null | relative_path | kc_filter_relative_lines | sort)"
321
+ TEST_PATHS="$(find "$TARGET_PROJECT" -maxdepth 3 -type d \( \
322
+ -name "test" -o \
323
+ -name "tests" -o \
324
+ -name "__tests__" -o \
325
+ -name "spec" -o \
326
+ -name "specs" -o \
327
+ -name "integration-tests" -o \
328
+ -name "launch" -o \
329
+ -name "simulation" -o \
330
+ -name "notebooks" -o \
331
+ -name "models" -o \
332
+ -name "data" \) 2>/dev/null | relative_path | kc_filter_relative_lines | sort)"
333
+ WORKFLOW_PATHS="$(if [ -d "$TARGET_PROJECT/.github/workflows" ]; then
334
+ find "$TARGET_PROJECT/.github/workflows" -mindepth 1 -maxdepth 1 -type f 2>/dev/null | relative_path | kc_filter_relative_lines | sort
335
+ fi)"
336
+ STRUCTURE_PATHS="$(find "$TARGET_PROJECT" \
337
+ -maxdepth 4 \
338
+ -not -path "*/.git/*" \
339
+ -not -path "*/node_modules/*" \
340
+ -not -path "*/vendor/*" \
341
+ -not -path "*/__pycache__/*" \
342
+ -not -path "*/.venv/*" \
343
+ -not -path "*/dist/*" \
344
+ -not -path "*/.next/*" \
345
+ -not -path "*/build/*" \
346
+ | sort | relative_path | grep -Ev '^agent-knowledge($|/)' | kc_filter_relative_lines)"
347
+ TOP_LEVEL_DIRS="$(list_top_level_dirs)"
348
+ DOC_INDEX_PATHS="$(find_any_relative \
349
+ -name "*.md" \
350
+ -not -path "*/node_modules/*" \
351
+ -not -path "*/.git/*" \
352
+ -not -path "*/vendor/*")"
353
+ TASK_PATHS="$(find "$TARGET_PROJECT/tasks" -mindepth 1 -maxdepth 2 -type f 2>/dev/null | relative_path | kc_filter_relative_lines | sort)"
354
+ SESSION_FILE_PATHS="$(find "$SESSIONS_DIR" -mindepth 1 -maxdepth 1 -type f 2>/dev/null | relative_path | kc_filter_relative_lines | sort)"
355
+ TRACE_PATHS="$(for d in agent-traces traces logs/agent agent-knowledge/Outputs/traces; do
356
+ if [ -d "$TARGET_PROJECT/$d" ] && ! kc_path_is_ignored "$d"; then
357
+ find "$TARGET_PROJECT/$d" -type f 2>/dev/null | relative_path | kc_filter_relative_lines
358
+ fi
359
+ done | sort)"
360
+
361
+ LIKELY_PROFILE="$(project_profile_guess)"
362
+ ARCH_SUMMARY_RELATED="$(printf '%s\n%s\n%s\n%s\n' "$MANIFEST_PATHS" "$DOC_IMPORT_PATHS" "$TOP_LEVEL_DIRS" "$WORKFLOW_PATHS" | awk 'NF && !seen[$0]++ { print $0 }')"
363
+
364
+ kc_log "Collecting evidence: $PROJECT_LABEL"
365
+ kc_log ""
366
+ if [ -f "$IGNORE_FILE" ]; then
367
+ WARNINGS+=("history import is honoring .agentknowledgeignore")
368
+ fi
369
+
370
+ if kc_git_available; then
371
+ if kc_git_has_commits; then
372
+ GIT_SIGNATURE="$(printf '%s\n%s\n' "$(git -C "$TARGET_PROJECT" rev-parse HEAD)" "$(git -C "$TARGET_PROJECT" rev-list --count HEAD 2>/dev/null || echo 0)" | kc_hash_text)"
373
+ capture_text_artifact "history-import" "git-log" "$EVIDENCE_RAW_DIR/git-log.txt" "agent-knowledge/Evidence/raw/git-log.txt" "raw" "git" "git-log" "EXTRACTED" ".git" "Last 300 commits in oneline form. Review as evidence, not canonical truth." "$GIT_SIGNATURE" <<EOF
374
+ $(header "git-log (oneline, last 300)" "git" "git-log" "EXTRACTED")
375
+ $(git -C "$TARGET_PROJECT" log --oneline -300)
376
+ EOF
377
+
378
+ capture_text_artifact "history-import" "git-log-detail" "$EVIDENCE_RAW_DIR/git-log-detail.txt" "agent-knowledge/Evidence/raw/git-log-detail.txt" "raw" "git" "git-log-detail" "EXTRACTED" ".git" "Detailed commit evidence with subject and body for the most recent history slice." "$GIT_SIGNATURE" <<EOF
379
+ $(header "git-log-detail (last 50, with body)" "git" "git-log-detail" "EXTRACTED")
380
+ $(git -C "$TARGET_PROJECT" log -50 --pretty=format:"----%ncommit %h%nDate: %ai%nAuthor: %an%n%n%s%n%b")
381
+ EOF
382
+
383
+ capture_text_artifact "history-import" "git-authors" "$EVIDENCE_RAW_DIR/git-authors.txt" "agent-knowledge/Evidence/raw/git-authors.txt" "raw" "git" "git-authors" "EXTRACTED" ".git" "Unique git authors extracted from repository history." "$GIT_SIGNATURE" <<EOF
384
+ $(header "git-authors" "git" "git-authors" "EXTRACTED")
385
+ $(git -C "$TARGET_PROJECT" log --pretty=format:"%an <%ae>" | sort -u)
386
+ EOF
387
+ else
388
+ WARNINGS+=("git evidence skipped because the repository has no commits yet")
389
+ kc_log " note: git evidence skipped (repository has no commits yet)"
390
+ fi
391
+ else
392
+ WARNINGS+=("git evidence skipped because the target is not a git repo")
393
+ kc_log " note: git evidence skipped (not a git repo)"
394
+ fi
395
+
396
+ STRUCTURE_SIGNATURE="$(kc_signature_from_project_relative_lines "$STRUCTURE_PATHS")"
397
+ capture_text_artifact "history-import" "structure" "$EVIDENCE_RAW_DIR/structure.txt" "agent-knowledge/Evidence/raw/structure.txt" "raw" "repo-scan" "directory-structure" "EXTRACTED" "$TOP_LEVEL_DIRS" "Top-level directories and immediate structural signals from the current repo." "$STRUCTURE_SIGNATURE" <<EOF
398
+ $(header "structure (top-level and depth 4 overview)" "repo-scan" "directory-structure" "EXTRACTED")
399
+ ## Top-level Directories
400
+ $(if [ -n "$TOP_LEVEL_DIRS" ]; then printf '%s\n' "$TOP_LEVEL_DIRS"; else printf '(none)\n'; fi)
401
+
402
+ ## Depth-4 Structure
403
+ $(printf '%s\n' "$STRUCTURE_PATHS")
404
+ EOF
405
+
406
+ MANIFEST_SIGNATURE="$(kc_signature_from_project_relative_lines "$MANIFEST_PATHS")"
407
+ capture_text_artifact "history-import" "manifests" "$EVIDENCE_RAW_DIR/manifests.txt" "agent-knowledge/Evidence/raw/manifests.txt" "raw" "repo-scan" "manifests" "EXTRACTED" "$MANIFEST_PATHS" "Dependency and manifest files copied with truncation for very large files." "$MANIFEST_SIGNATURE" <<EOF
408
+ $(header "manifests" "repo-scan" "manifests" "EXTRACTED")
409
+ $(if [ -n "$MANIFEST_PATHS" ]; then render_manifest_contents; else echo "(no manifests found)"; fi)
410
+ EOF
411
+
412
+ CONFIG_SIGNATURE="$(kc_signature_from_project_relative_lines "$CONFIG_PATHS")"
413
+ capture_text_artifact "history-import" "config-files" "$EVIDENCE_RAW_DIR/config-files.txt" "agent-knowledge/Evidence/raw/config-files.txt" "raw" "repo-scan" "config-files" "EXTRACTED" "$CONFIG_PATHS" "Config files that usually define linting, formatting, typing, or build conventions." "$CONFIG_SIGNATURE" <<EOF
414
+ $(header "config-files" "repo-scan" "config-files" "EXTRACTED")
415
+ $(if [ -n "$CONFIG_PATHS" ]; then printf '%s\n' "$CONFIG_PATHS"; else echo "(no matching config files found)"; fi)
416
+ EOF
417
+
418
+ TEST_SIGNATURE="$(kc_signature_from_project_relative_lines "$TEST_PATHS")"
419
+ capture_text_artifact "history-import" "tests" "$EVIDENCE_RAW_DIR/tests.txt" "agent-knowledge/Evidence/raw/tests.txt" "raw" "repo-scan" "test-surfaces" "EXTRACTED" "$TEST_PATHS" "Directories that suggest tests, launches, simulations, datasets, or model assets." "$TEST_SIGNATURE" <<EOF
420
+ $(header "tests" "repo-scan" "test-surfaces" "EXTRACTED")
421
+ $(if [ -n "$TEST_PATHS" ]; then printf '%s\n' "$TEST_PATHS"; else echo "(no matching test or validation directories found)"; fi)
422
+ EOF
423
+
424
+ WORKFLOW_SIGNATURE="$(kc_signature_from_project_relative_lines "$WORKFLOW_PATHS")"
425
+ capture_text_artifact "history-import" "ci-workflows" "$EVIDENCE_RAW_DIR/ci-workflows.txt" "agent-knowledge/Evidence/raw/ci-workflows.txt" "raw" "repo-scan" "ci-workflows" "EXTRACTED" "$WORKFLOW_PATHS" "Workflow definitions that shape validation and deployment behavior." "$WORKFLOW_SIGNATURE" <<EOF
426
+ $(header "ci-workflows" "repo-scan" "ci-workflows" "EXTRACTED")
427
+ $(if [ -n "$WORKFLOW_PATHS" ]; then
428
+ while IFS= read -r rel; do
429
+ [ -n "$rel" ] || continue
430
+ echo "=== $rel ==="
431
+ if [ "$(wc -l < "$TARGET_PROJECT/$rel")" -gt 150 ]; then
432
+ head -60 "$TARGET_PROJECT/$rel"
433
+ echo "... (truncated)"
434
+ else
435
+ cat "$TARGET_PROJECT/$rel"
436
+ fi
437
+ echo ""
438
+ done <<EOF_INNER
439
+ $WORKFLOW_PATHS
440
+ EOF_INNER
441
+ else
442
+ echo "(no .github/workflows found)"
443
+ fi)
444
+ EOF
445
+
446
+ DOC_SIGNATURE="$(kc_signature_from_project_relative_lines "$DOC_IMPORT_PATHS")"
447
+ capture_text_artifact "history-import" "existing-docs" "$EVIDENCE_IMPORTS_DIR/existing-docs.txt" "agent-knowledge/Evidence/imports/existing-docs.txt" "imports" "repo-scan" "existing-docs" "EXTRACTED" "$DOC_IMPORT_PATHS" "High-signal docs and local project metadata copied for backfill review." "$DOC_SIGNATURE" <<EOF
448
+ $(header "existing-docs" "repo-scan" "existing-docs" "EXTRACTED")
449
+ $(if [ -n "$DOC_IMPORT_PATHS" ]; then render_doc_contents; else echo "(no key doc files found)"; fi)
450
+ EOF
451
+
452
+ DOC_INDEX_SIGNATURE="$(kc_signature_from_project_relative_lines "$DOC_INDEX_PATHS")"
453
+ capture_text_artifact "history-import" "doc-index" "$EVIDENCE_IMPORTS_DIR/doc-index.txt" "agent-knowledge/Evidence/imports/doc-index.txt" "imports" "repo-scan" "doc-index" "EXTRACTED" "$DOC_INDEX_PATHS" "Markdown path index only. Use this to decide which docs to inspect next." "$DOC_INDEX_SIGNATURE" <<EOF
454
+ $(header "doc-index (paths)" "repo-scan" "doc-index" "EXTRACTED")
455
+ $(if [ -n "$DOC_INDEX_PATHS" ]; then printf '%s\n' "$DOC_INDEX_PATHS"; else echo "(no markdown files found)"; fi)
456
+ EOF
457
+
458
+ TASK_SIGNATURE="$(kc_signature_from_project_relative_lines "$TASK_PATHS")"
459
+ capture_text_artifact "history-import" "tasks" "$EVIDENCE_IMPORTS_DIR/tasks.txt" "agent-knowledge/Evidence/imports/tasks.txt" "imports" "repo-scan" "tasks" "EXTRACTED" "$TASK_PATHS" "Task files can be useful but may lag behind the true project state." "$TASK_SIGNATURE" <<EOF
460
+ $(header "tasks" "repo-scan" "tasks" "EXTRACTED")
461
+ $(if [ -n "$TASK_PATHS" ]; then
462
+ while IFS= read -r rel; do
463
+ [ -n "$rel" ] || continue
464
+ echo "=== $rel ==="
465
+ cat "$TARGET_PROJECT/$rel"
466
+ echo ""
467
+ done <<EOF_INNER
468
+ $TASK_PATHS
469
+ EOF_INNER
470
+ if [ -d "$TARGET_PROJECT/tasks" ] && ! kc_path_is_ignored "tasks"; then
471
+ echo "=== tasks/ contents ==="
472
+ ls "$TARGET_PROJECT/tasks/"
473
+ fi
474
+ else
475
+ echo "(no tasks/ directory found)"
476
+ fi)
477
+ EOF
478
+
479
+ SESSION_SIGNATURE="$(kc_signature_from_project_relative_lines "$SESSION_FILE_PATHS")"
480
+ capture_text_artifact "history-import" "session-files" "$EVIDENCE_IMPORTS_DIR/session-files.txt" "agent-knowledge/Evidence/imports/session-files.txt" "imports" "local-knowledge" "session-files" "AMBIGUOUS" "$SESSION_FILE_PATHS" "Session notes are temporary and may contain unresolved or outdated assumptions." "$SESSION_SIGNATURE" <<EOF
481
+ $(header "session-files" "local-knowledge" "session-files" "AMBIGUOUS")
482
+ $(if [ -n "$SESSION_FILE_PATHS" ]; then
483
+ while IFS= read -r rel; do
484
+ [ -n "$rel" ] || continue
485
+ echo "=== $rel ==="
486
+ if [ "$(wc -l < "$TARGET_PROJECT/$rel")" -gt 120 ]; then
487
+ head -60 "$TARGET_PROJECT/$rel"
488
+ echo "... (truncated at 60 lines)"
489
+ else
490
+ cat "$TARGET_PROJECT/$rel"
491
+ fi
492
+ echo ""
493
+ done <<EOF_INNER
494
+ $SESSION_FILE_PATHS
495
+ EOF_INNER
496
+ else
497
+ echo "(no local Sessions/ files found)"
498
+ fi)
499
+ EOF
500
+
501
+ CURSOR_SESSION_LIST="$(
502
+ found=""
503
+ for d in "$HOME"/.cursor/projects/*/sessions; do
504
+ if [ -d "$d" ] && printf '%s' "$d" | grep -qi "$PROJECT_LABEL" 2>/dev/null; then
505
+ echo "$d"
506
+ found="yes"
507
+ fi
508
+ done
509
+ [ -n "$found" ] || true
510
+ )"
511
+ CURSOR_SESSION_SIGNATURE="$(kc_signature_from_paths $CURSOR_SESSION_LIST)"
512
+ capture_text_artifact "history-import" "cursor-sessions" "$EVIDENCE_IMPORTS_DIR/cursor-sessions.txt" "agent-knowledge/Evidence/imports/cursor-sessions.txt" "imports" "cursor" "cursor-session-index" "AMBIGUOUS" "$CURSOR_SESSION_LIST" "Cursor session listings help locate prior work, but session output is not canonical truth." "$CURSOR_SESSION_SIGNATURE" <<EOF
513
+ $(header "cursor-sessions" "cursor" "cursor-session-index" "AMBIGUOUS")
514
+ $(found=""
515
+ for d in "$HOME"/.cursor/projects/*/sessions; do
516
+ if [ -d "$d" ] && printf '%s' "$d" | grep -qi "$PROJECT_LABEL" 2>/dev/null; then
517
+ echo "=== $d ==="
518
+ ls -lt "$d" 2>/dev/null | head -10
519
+ echo ""
520
+ found="yes"
521
+ fi
522
+ done
523
+ [ -z "$found" ] && echo "(no matching Cursor session dirs found)")
524
+ EOF
525
+
526
+ TRACE_SIGNATURE="$(kc_signature_from_project_relative_lines "$TRACE_PATHS")"
527
+ capture_text_artifact "history-import" "trace-index" "$EVIDENCE_IMPORTS_DIR/trace-index.txt" "agent-knowledge/Evidence/imports/trace-index.txt" "imports" "project-traces" "trace-index" "AMBIGUOUS" "$TRACE_PATHS" "Imported traces and generated outputs are evidence only and must be curated before promotion to Memory." "$TRACE_SIGNATURE" <<EOF
528
+ $(header "trace-index" "project-traces" "trace-index" "AMBIGUOUS")
529
+ $(if [ -n "$TRACE_PATHS" ]; then printf '%s\n' "$TRACE_PATHS"; else echo "(no imported trace directories found)"; fi)
530
+ EOF
531
+
532
+ STRUCTURAL_SUMMARY_SIGNATURE="$(kc_signature_from_lines "$(printf '%s\n---\n%s\n---\n%s\n---\n%s\n---\n%s\n' "$TOP_LEVEL_DIRS" "$MANIFEST_PATHS" "$DOC_IMPORT_PATHS" "$CONFIG_PATHS" "$WORKFLOW_PATHS")")"
533
+ capture_markdown_note "history-import" "structural-summary-note" "$EVIDENCE_IMPORTS_DIR/structural-summary.md" "agent-knowledge/Evidence/imports/structural-summary.md" "imports" "import-agent-history.sh" "structural-summary" "EXTRACTED" "$ARCH_SUMMARY_RELATED" "Compact structural evidence note derived from repo surfaces. Evidence only." "$STRUCTURAL_SUMMARY_SIGNATURE" <<EOF
534
+ ---
535
+ note_type: structural-evidence
536
+ project: $PROJECT_NAME
537
+ profile: ${LIKELY_PROFILE:-unknown}
538
+ source: import-agent-history.sh
539
+ kind: structural-summary
540
+ confidence: EXTRACTED
541
+ generated_at: $GENERATED_AT
542
+ related_paths:
543
+ $(kc_yaml_list "$ARCH_SUMMARY_RELATED" 2)
544
+ notes:
545
+ - Generated from manifests, docs, config files, and top-level structure.
546
+ - Treat this as evidence first, not durable memory.
547
+ tags:
548
+ - agent-knowledge
549
+ - evidence
550
+ - structural
551
+ ---
552
+
553
+ # Structural Evidence Summary
554
+
555
+ ## Purpose
556
+
557
+ - Quick orientation note derived from direct repository scans.
558
+
559
+ ## Current Signal
560
+
561
+ - Likely project profile: \`$LIKELY_PROFILE\`
562
+ - Top-level directories: $(if [ -n "$TOP_LEVEL_DIRS" ]; then printf '%s' "$TOP_LEVEL_DIRS" | awk 'NF { items[++count]=$0 } END { for (i=1;i<=count;i++) { printf "`%s`", items[i]; if (i < count) printf ", " } }'; else printf 'none detected'; fi)
563
+ - Key manifests: $(if [ -n "$MANIFEST_PATHS" ]; then printf '%s' "$MANIFEST_PATHS" | awk 'NF { items[++count]=$0 } END { for (i=1;i<=count;i++) { printf "`%s`", items[i]; if (i < count) printf ", " } }'; else printf 'none detected'; fi)
564
+ - Key docs: $(if [ -n "$DOC_IMPORT_PATHS" ]; then printf '%s' "$DOC_IMPORT_PATHS" | awk 'NF { items[++count]=$0 } END { for (i=1;i<=count;i++) { printf "`%s`", items[i]; if (i < count) printf ", " } }'; else printf 'none detected'; fi)
565
+
566
+ ## Related Evidence
567
+
568
+ - [../raw/structure.txt](../raw/structure.txt)
569
+ - [../raw/manifests.txt](../raw/manifests.txt)
570
+ - [../raw/config-files.txt](../raw/config-files.txt)
571
+ - [existing-docs.txt](existing-docs.txt)
572
+ - [doc-index.txt](doc-index.txt)
573
+
574
+ ## Open Questions
575
+
576
+ - Which structural signals should be promoted into curated memory after review?
577
+ - Are there ignored or external paths that materially change the architecture picture?
578
+ EOF
579
+
580
+ OUTPUT_SUMMARY_SIGNATURE="$(kc_signature_from_lines "$(printf '%s\n---\n%s\n---\n%s\n' "$STRUCTURAL_SUMMARY_SIGNATURE" "$LIKELY_PROFILE" "$ARCH_SUMMARY_RELATED")")"
581
+ capture_markdown_note "history-import" "architecture-summary-output" "$OUTPUTS_DIR/architecture-summary.md" "agent-knowledge/Outputs/architecture-summary.md" "outputs" "Evidence/imports/structural-summary.md" "architecture-summary" "INFERRED" "$ARCH_SUMMARY_RELATED" "Generated discovery output derived from evidence. Promote to Memory intentionally if it proves durable." "$OUTPUT_SUMMARY_SIGNATURE" <<EOF
582
+ ---
583
+ note_type: generated-output
584
+ project: $PROJECT_NAME
585
+ profile: ${LIKELY_PROFILE:-unknown}
586
+ source: Evidence/imports/structural-summary.md
587
+ kind: architecture-summary
588
+ confidence: INFERRED
589
+ generated_at: $GENERATED_AT
590
+ related_paths:
591
+ $(kc_yaml_list "$ARCH_SUMMARY_RELATED" 2)
592
+ notes:
593
+ - Derived from structural evidence for quick orientation.
594
+ - Not durable project memory unless promoted intentionally.
595
+ tags:
596
+ - agent-knowledge
597
+ - outputs
598
+ - structural
599
+ ---
600
+
601
+ # Architecture Summary
602
+
603
+ ## Purpose
604
+
605
+ - Concise orientation note for discovery before deeper grep or file reads.
606
+
607
+ ## Likely Shape
608
+
609
+ - Inferred profile: \`$LIKELY_PROFILE\`
610
+ - Major top-level branches: $(if [ -n "$TOP_LEVEL_DIRS" ]; then printf '%s' "$TOP_LEVEL_DIRS" | awk 'NF { items[++count]=$0 } END { for (i=1;i<=count;i++) { printf "`%s`", items[i]; if (i < count) printf ", " } }'; else printf 'none detected'; fi)
611
+ - Validation and delivery surfaces: $(if [ -n "$WORKFLOW_PATHS" ] || [ -n "$TEST_PATHS" ]; then printf '%s\n%s\n' "$WORKFLOW_PATHS" "$TEST_PATHS" | awk 'NF && !seen[$0]++ { items[++count]=$0 } END { for (i=1;i<=count;i++) { printf "`%s`", items[i]; if (i < count) printf ", " } }'; else printf 'none detected'; fi)
612
+
613
+ ## Evidence Sources
614
+
615
+ - [../Evidence/imports/structural-summary.md](../Evidence/imports/structural-summary.md)
616
+ - [../Evidence/raw/structure.txt](../Evidence/raw/structure.txt)
617
+ - [../Evidence/raw/manifests.txt](../Evidence/raw/manifests.txt)
618
+ - [../Evidence/raw/ci-workflows.txt](../Evidence/raw/ci-workflows.txt)
619
+
620
+ ## Promotion Rule
621
+
622
+ - Use this note for orientation only.
623
+ - Promote a point into \`Memory/\` only after agent review confirms it is durable and useful.
624
+ EOF
625
+
626
+ STRUCTURAL_MAP_SIGNATURE="$(kc_signature_from_lines "$(printf '%s\n---\n%s\n---\n%s\n---\n%s\n' "$TOP_LEVEL_DIRS" "$MANIFEST_PATHS" "$DOC_IMPORT_PATHS" "$TEST_PATHS")")"
627
+ capture_markdown_note "history-import" "structural-map-output" "$OUTPUTS_DIR/structural-map.md" "agent-knowledge/Outputs/structural-map.md" "outputs" "Evidence/raw/structure.txt" "structural-map" "EXTRACTED" "$ARCH_SUMMARY_RELATED" "Generated structure map for fast navigation. Evidence/output first, not memory." "$STRUCTURAL_MAP_SIGNATURE" <<EOF
628
+ ---
629
+ note_type: generated-output
630
+ project: $PROJECT_NAME
631
+ profile: ${LIKELY_PROFILE:-unknown}
632
+ source: Evidence/raw/structure.txt
633
+ kind: structural-map
634
+ confidence: EXTRACTED
635
+ generated_at: $GENERATED_AT
636
+ related_paths:
637
+ $(kc_yaml_list "$ARCH_SUMMARY_RELATED" 2)
638
+ notes:
639
+ - Generated from direct path listings and manifest/doc surfaces.
640
+ - Intended for orientation and navigation, not canonical memory.
641
+ tags:
642
+ - agent-knowledge
643
+ - outputs
644
+ - structure
645
+ ---
646
+
647
+ # Structural Map
648
+
649
+ ## Top-Level Directories
650
+
651
+ $(if [ -n "$TOP_LEVEL_DIRS" ]; then printf '%s\n' "$TOP_LEVEL_DIRS" | awk 'NF { printf "- `%s`\n", $0 }'; else echo "- None detected."; fi)
652
+
653
+ ## Key Manifests
654
+
655
+ $(if [ -n "$MANIFEST_PATHS" ]; then printf '%s\n' "$MANIFEST_PATHS" | awk 'NF { printf "- `%s`\n", $0 }'; else echo "- None detected."; fi)
656
+
657
+ ## Key Docs
658
+
659
+ $(if [ -n "$DOC_IMPORT_PATHS" ]; then printf '%s\n' "$DOC_IMPORT_PATHS" | awk 'NF { printf "- `%s`\n", $0 }'; else echo "- None detected."; fi)
660
+
661
+ ## Test And Workflow Surfaces
662
+
663
+ $(if [ -n "$TEST_PATHS" ] || [ -n "$WORKFLOW_PATHS" ]; then printf '%s\n%s\n' "$TEST_PATHS" "$WORKFLOW_PATHS" | awk 'NF && !seen[$0]++ { printf "- `%s`\n", $0 }'; else echo "- None detected."; fi)
664
+
665
+ ## See Also
666
+
667
+ - [../Evidence/raw/structure.txt](../Evidence/raw/structure.txt)
668
+ - [../Evidence/imports/structural-summary.md](../Evidence/imports/structural-summary.md)
669
+ EOF
670
+
671
+ kc_status_load
672
+ if [ "${DRY_RUN:-0}" -eq 0 ] && [ ${#GENERATED[@]} -gt 0 ]; then
673
+ STATUS_LAST_IMPORT="$(kc_now_utc)"
674
+ fi
675
+ STATUS_WARNING_LINES="$(printf '%s\n' "${WARNINGS[@]+"${WARNINGS[@]}"}")"
676
+ kc_status_write
677
+
678
+ json_summary="{"
679
+ json_summary="$json_summary\"script\":\"import-agent-history\","
680
+ json_summary="$json_summary\"project_root\":\"$(kc_json_escape "$TARGET_PROJECT")\","
681
+ json_summary="$json_summary\"dry_run\":$(kc_json_bool "$DRY_RUN"),"
682
+ json_summary="$json_summary\"raw_files\":$(kc_json_array "${RAW_GENERATED[@]+"${RAW_GENERATED[@]}"}"),"
683
+ json_summary="$json_summary\"import_files\":$(kc_json_array "${IMPORT_GENERATED[@]+"${IMPORT_GENERATED[@]}"}"),"
684
+ json_summary="$json_summary\"output_files\":$(kc_json_array "${OUTPUT_GENERATED[@]+"${OUTPUT_GENERATED[@]}"}"),"
685
+ json_summary="$json_summary\"cached\":$(kc_json_array "${CACHED[@]+"${CACHED[@]}"}"),"
686
+ json_summary="$json_summary\"skipped\":$(kc_json_array "${SKIPPED[@]+"${SKIPPED[@]}"}"),"
687
+ json_summary="$json_summary\"warnings\":$(kc_json_array "${WARNINGS[@]+"${WARNINGS[@]}"}")"
688
+ json_summary="$json_summary}"
689
+ kc_write_json_output "$json_summary"
690
+
691
+ if [ "$JSON_MODE" -ne 1 ]; then
692
+ kc_log ""
693
+ kc_log "Evidence collected in:"
694
+ kc_log " agent-knowledge/Evidence/raw/"
695
+ kc_log " agent-knowledge/Evidence/imports/"
696
+ kc_log "Generated discovery outputs:"
697
+ kc_log " agent-knowledge/Outputs/architecture-summary.md"
698
+ kc_log " agent-knowledge/Outputs/structural-map.md"
699
+ if [ ${#CACHED[@]} -gt 0 ]; then
700
+ kc_log ""
701
+ kc_log "Cached:"
702
+ printf ' %s\n' "${CACHED[@]+"${CACHED[@]}"}"
703
+ fi
704
+ kc_log ""
705
+ kc_log "Curated memory remains separate. Review evidence before writing durable notes."
706
+ fi