@cairnkeep/cli 2.8.0 → 2.9.0
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/CHANGELOG.md +23 -1
- package/README.md +28 -2
- package/bin/cairn +13 -1
- package/docs/context-packs.md +94 -0
- package/docs/harness-compatibility.md +7 -1
- package/docs/learning/CURRICULUM-MAP.md +9 -4
- package/docs/learning/FEATURE-GUIDE.md +7 -2
- package/docs/learning/README.md +6 -2
- package/docs/learning/lessons/L00-why-cairnkeep.md +1 -1
- package/docs/learning/lessons/L01-safe-trial.md +3 -3
- package/docs/learning/lessons/L02-installation.md +2 -2
- package/docs/learning/lessons/L03-first-project.md +1 -1
- package/docs/learning/lessons/L19-validated-skill-improvement.md +52 -21
- package/docs/learning/lessons/L20-mcp-tool-profiles.md +67 -0
- package/docs/learning/lessons/L21-context-packs.md +79 -0
- package/docs/learning/tracks/operator.md +4 -2
- package/docs/mcp-tool-profiles.md +43 -0
- package/docs/operating.md +38 -0
- package/docs/privacy-and-data-flow.md +17 -0
- package/docs/storage.md +17 -0
- package/examples/eval/bundled-fake.json +1 -1
- package/mcp-memory-server/dist/context-pack-cli.js +185 -0
- package/mcp-memory-server/dist/context-pack.js +830 -0
- package/mcp-memory-server/dist/eval-report.js +1 -0
- package/mcp-memory-server/dist/eval-runner.js +2 -0
- package/mcp-memory-server/dist/eval-schema.js +1 -0
- package/mcp-memory-server/dist/index.js +68 -17
- package/mcp-memory-server/dist/mcp-tool-catalog.js +47 -0
- package/mcp-memory-server/dist/mcp-tool-cli.js +85 -0
- package/mcp-memory-server/dist/mcp-tool-profile.js +162 -0
- package/mcp-memory-server/package.json +3 -1
- package/package.json +1 -1
- package/schemas/context-pack.schema.json +33 -0
- package/schemas/eval-report.schema.json +1 -0
- package/scripts/completion.sh +24 -5
- package/scripts/doctor.sh +39 -0
- package/scripts/test-cli-dispatch.sh +6 -0
- package/scripts/test-completion.sh +5 -0
- package/scripts/test-learning-docs.sh +4 -3
- package/scripts/test-package-install.sh +17 -0
- package/scripts/test-uninstall.sh +21 -0
- package/scripts/uninstall.sh +26 -1
- package/templates/env.example.template +11 -0
package/scripts/completion.sh
CHANGED
|
@@ -11,7 +11,7 @@ _cairn_complete() {
|
|
|
11
11
|
COMPREPLY=()
|
|
12
12
|
current=${COMP_WORDS[COMP_CWORD]}
|
|
13
13
|
previous=${COMP_WORDS[COMP_CWORD-1]:-}
|
|
14
|
-
commands="bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval skill graph memory audit-timer uninstall completion version help"
|
|
14
|
+
commands="bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities mcp-tools pack notes eval skill graph memory audit-timer uninstall completion version help"
|
|
15
15
|
if (( COMP_CWORD == 1 )); then
|
|
16
16
|
COMPREPLY=( $(compgen -W "$commands" -- "$current") )
|
|
17
17
|
return
|
|
@@ -51,6 +51,8 @@ _cairn_complete() {
|
|
|
51
51
|
*) COMPREPLY=( $(compgen -W "list status enable disable reset logging" -- "$current") ) ;;
|
|
52
52
|
esac
|
|
53
53
|
;;
|
|
54
|
+
mcp-tools) COMPREPLY=( $(compgen -W "list status set reset full read-only custom --tool --project --json" -- "$current") ) ;;
|
|
55
|
+
pack) COMPREPLY=( $(compgen -W "init lock validate install list show remove enable disable update skills approve-skill revoke-skill --id --version --title --description --license --ref --project --project-id --check --apply --confirm --json" -- "$current") ) ;;
|
|
54
56
|
notes) COMPREPLY=( $(compgen -W "distill search-error promote doctor --project --session --all-projects --para-root --text --component --with --confirm --repair --json" -- "$current") ) ;;
|
|
55
57
|
eval)
|
|
56
58
|
case "${COMP_WORDS[2]:-}" in
|
|
@@ -67,7 +69,7 @@ _cairn_complete() {
|
|
|
67
69
|
graph) COMPREPLY=( $(compgen -W "build query status diff explain path --force" -- "$current") ) ;;
|
|
68
70
|
memory) COMPREPLY=( $(compgen -W "path export import" -- "$current") ) ;;
|
|
69
71
|
audit-timer) COMPREPLY=( $(compgen -W "--on-calendar --para-root --render-only" -- "$current") ) ;;
|
|
70
|
-
uninstall) COMPREPLY=( $(compgen -W "--dry-run --yes --purge-memory --live-root --pi-live-root --kimi-live-root" -- "$current") ) ;;
|
|
72
|
+
uninstall) COMPREPLY=( $(compgen -W "--dry-run --yes --purge-memory --purge-packs --live-root --pi-live-root --kimi-live-root" -- "$current") ) ;;
|
|
71
73
|
completion) COMPREPLY=( $(compgen -W "bash zsh fish" -- "$current") ) ;;
|
|
72
74
|
esac
|
|
73
75
|
}
|
|
@@ -89,6 +91,8 @@ _cairn() {
|
|
|
89
91
|
'trajectory:inspect and prune local session trajectories'
|
|
90
92
|
'artifact:inspect, delete, and prune local artifacts'
|
|
91
93
|
'capabilities:inspect and manage project capability state'
|
|
94
|
+
'mcp-tools:inspect and restrict MCP tool exposure'
|
|
95
|
+
'pack:manage immutable context packs and skill approvals'
|
|
92
96
|
'notes:distill and search local hindsight notes'
|
|
93
97
|
'eval:run and inspect default-off local evaluations'
|
|
94
98
|
'skill:review and evaluate evidence-backed skill improvements'
|
|
@@ -120,6 +124,8 @@ _cairn() {
|
|
|
120
124
|
*) _values 'artifact command' list show delete prune ;;
|
|
121
125
|
esac
|
|
122
126
|
;;
|
|
127
|
+
mcp-tools) _values 'MCP tool profile command' list status set reset full read-only custom '--tool[allow an exact tool]:tool:' '--project[project root]:directory:_files -/' '--json[emit JSON]' ;;
|
|
128
|
+
pack) _values 'context pack command' init lock validate install list show remove enable disable update skills approve-skill revoke-skill '--ref[pinned Git ref]:ref:' '--project[project root]:directory:_files -/' '--project-id[remote project ID]:project ID:' '--check[inspect update]' '--apply[apply update]' '--confirm[confirm digest]:digest:' '--json[emit JSON]' ;;
|
|
123
129
|
capabilities)
|
|
124
130
|
case $words[3] in
|
|
125
131
|
list|status) _arguments '--json[emit JSON]' ;;
|
|
@@ -157,7 +163,7 @@ _cairn() {
|
|
|
157
163
|
graph) _values 'graph command' build query status diff explain path '--force[allow a smaller graph after code deletion]' ;;
|
|
158
164
|
memory) _values 'memory command' path export import ;;
|
|
159
165
|
audit-timer) _arguments '--on-calendar[systemd calendar]:calendar:' '--para-root[PARA root]:directory:_files -/' '--render-only[render directory]:directory:_files -/' ;;
|
|
160
|
-
uninstall) _arguments '--dry-run[show changes]' '--yes[skip confirmation]' '--purge-memory[delete memory]' '--live-root[project Claude root]:directory:_files -/' '--pi-live-root[Pi agent root]:directory:_files -/' '--kimi-live-root[Kimi Code root]:directory:_files -/' '*:project directory:_files -/' ;;
|
|
166
|
+
uninstall) _arguments '--dry-run[show changes]' '--yes[skip confirmation]' '--purge-memory[delete memory]' '--purge-packs[delete context packs]' '--live-root[project Claude root]:directory:_files -/' '--pi-live-root[Pi agent root]:directory:_files -/' '--kimi-live-root[Kimi Code root]:directory:_files -/' '*:project directory:_files -/' ;;
|
|
161
167
|
completion) _values 'shell' bash zsh fish ;;
|
|
162
168
|
*) _arguments '*:argument:_files' ;;
|
|
163
169
|
esac
|
|
@@ -168,8 +174,8 @@ EOF
|
|
|
168
174
|
fish)
|
|
169
175
|
cat <<'EOF'
|
|
170
176
|
complete -c cairn -f
|
|
171
|
-
for command in bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval skill graph memory audit-timer uninstall completion version help
|
|
172
|
-
complete -c cairn -n "not __fish_seen_subcommand_from bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval skill graph memory audit-timer uninstall completion version help" -a $command
|
|
177
|
+
for command in bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities mcp-tools pack notes eval skill graph memory audit-timer uninstall completion version help
|
|
178
|
+
complete -c cairn -n "not __fish_seen_subcommand_from bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities mcp-tools pack notes eval skill graph memory audit-timer uninstall completion version help" -a $command
|
|
173
179
|
end
|
|
174
180
|
complete -c cairn -n "__fish_seen_subcommand_from sync" -l apply
|
|
175
181
|
complete -c cairn -n "__fish_seen_subcommand_from sync" -l live-root -r
|
|
@@ -193,6 +199,17 @@ complete -c cairn -n "__fish_seen_subcommand_from capabilities; and __fish_seen_
|
|
|
193
199
|
complete -c cairn -n "__fish_seen_subcommand_from capabilities; and __fish_seen_subcommand_from reset" -l all
|
|
194
200
|
complete -c cairn -n "__fish_seen_subcommand_from capabilities; and __fish_seen_subcommand_from logging; and not __fish_seen_subcommand_from enable disable reset" -a "enable disable reset"
|
|
195
201
|
complete -c cairn -n "__fish_seen_subcommand_from capabilities; and __fish_seen_subcommand_from list status enable disable reset logging" -l json
|
|
202
|
+
complete -c cairn -n "__fish_seen_subcommand_from mcp-tools" -a "list status set reset"
|
|
203
|
+
complete -c cairn -n "__fish_seen_subcommand_from mcp-tools; and __fish_seen_subcommand_from set" -a "full read-only custom"
|
|
204
|
+
complete -c cairn -n "__fish_seen_subcommand_from mcp-tools" -l project -r
|
|
205
|
+
complete -c cairn -n "__fish_seen_subcommand_from mcp-tools" -l tool -r
|
|
206
|
+
complete -c cairn -n "__fish_seen_subcommand_from mcp-tools" -l json
|
|
207
|
+
complete -c cairn -n "__fish_seen_subcommand_from pack" -a "init lock validate install list show remove enable disable update skills approve-skill revoke-skill"
|
|
208
|
+
complete -c cairn -n "__fish_seen_subcommand_from pack" -l project -r
|
|
209
|
+
complete -c cairn -n "__fish_seen_subcommand_from pack" -l project-id -r
|
|
210
|
+
complete -c cairn -n "__fish_seen_subcommand_from pack" -l ref -r
|
|
211
|
+
complete -c cairn -n "__fish_seen_subcommand_from pack" -l confirm -r
|
|
212
|
+
complete -c cairn -n "__fish_seen_subcommand_from pack" -l json
|
|
196
213
|
complete -c cairn -n "__fish_seen_subcommand_from notes" -a "distill search-error promote doctor"
|
|
197
214
|
complete -c cairn -n "__fish_seen_subcommand_from eval; and not __fish_seen_subcommand_from validate run ablate report prune delete" -a "validate run ablate report prune delete"
|
|
198
215
|
complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from validate run ablate" -l task-set -r
|
|
@@ -234,6 +251,8 @@ complete -c cairn -n "__fish_seen_subcommand_from graph; and __fish_seen_subcomm
|
|
|
234
251
|
complete -c cairn -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
|
|
235
252
|
complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l pi-live-root -r
|
|
236
253
|
complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l kimi-live-root -r
|
|
254
|
+
complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l purge-memory
|
|
255
|
+
complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l purge-packs
|
|
237
256
|
EOF
|
|
238
257
|
;;
|
|
239
258
|
*)
|
package/scripts/doctor.sh
CHANGED
|
@@ -400,6 +400,45 @@ case "$eval_state" in
|
|
|
400
400
|
unsafe) warn "evaluation report storage is unsafe" ;;
|
|
401
401
|
esac
|
|
402
402
|
|
|
403
|
+
# 12. MCP least-authority profile. Invalid or unknown custom tool names are a
|
|
404
|
+
# startup failure, so doctor treats them as an actionable configuration error.
|
|
405
|
+
mcp_profile_cli="$CAIRN_ROOT/mcp-memory-server/dist/mcp-tool-cli.js"
|
|
406
|
+
if [[ ! -f "$mcp_profile_cli" ]]; then
|
|
407
|
+
fail "MCP tool profile checker is missing from the installed package"
|
|
408
|
+
elif mcp_profile_json=$(node "$mcp_profile_cli" status --project "$PWD" --json 2>/dev/null); then
|
|
409
|
+
if mcp_profile_summary=$(node - "$mcp_profile_json" <<'NODE'
|
|
410
|
+
try {
|
|
411
|
+
const value = JSON.parse(process.argv[2]);
|
|
412
|
+
if (value.schema_version !== 1 || !["full", "read-only", "custom"].includes(value.mode)
|
|
413
|
+
|| !/^[a-f0-9]{64}$/.test(value.profile_digest) || !Array.isArray(value.allowed_tools)) process.exit(1);
|
|
414
|
+
process.stdout.write(`${value.mode}\t${value.profile_digest}`);
|
|
415
|
+
} catch { process.exit(1); }
|
|
416
|
+
NODE
|
|
417
|
+
); then
|
|
418
|
+
pass "MCP tool profile $(printf '%s' "$mcp_profile_summary" | cut -f1) ($(printf '%s' "$mcp_profile_summary" | cut -f2))"
|
|
419
|
+
else
|
|
420
|
+
fail "MCP tool profile status returned invalid data"
|
|
421
|
+
fi
|
|
422
|
+
else
|
|
423
|
+
fail "MCP tool profile is invalid (check .ai/mcp-tools.json and CAIRN_MCP_TOOL_PROFILE)"
|
|
424
|
+
fi
|
|
425
|
+
|
|
426
|
+
# 13. Context-pack objects and project pointers are verified even when MCP pack
|
|
427
|
+
# retrieval is disabled. The feature gate controls reads, not integrity checks.
|
|
428
|
+
pack_cli="$CAIRN_ROOT/mcp-memory-server/dist/context-pack-cli.js"
|
|
429
|
+
pack_base="${CAIRN_PACK_BASE_DIR:-$HOME/.cairnkeep/packs}"
|
|
430
|
+
pack_base="${pack_base/#\~/$HOME}"
|
|
431
|
+
if [[ ! -e "$pack_base" ]]; then
|
|
432
|
+
skip "context packs (not installed)"
|
|
433
|
+
elif [[ ! -f "$pack_cli" ]]; then
|
|
434
|
+
fail "context-pack checker is missing from the installed package"
|
|
435
|
+
elif pack_json=$(node "$pack_cli" doctor --json 2>/dev/null) && node -e 'const v=JSON.parse(process.argv[1]); if(v.ok!==true)process.exit(1)' "$pack_json"; then
|
|
436
|
+
pack_counts=$(node -e 'const v=JSON.parse(process.argv[1]); process.stdout.write(`${v.objects} object(s), ${v.projects} project pointer(s)`)' "$pack_json")
|
|
437
|
+
pass "context packs healthy ($pack_counts)"
|
|
438
|
+
else
|
|
439
|
+
fail "context-pack objects or project pointers failed integrity checks"
|
|
440
|
+
fi
|
|
441
|
+
|
|
403
442
|
echo
|
|
404
443
|
if [[ "$fails" -gt 0 ]]; then
|
|
405
444
|
echo "cairn doctor: $fails configured dependency check(s) failed."
|
|
@@ -16,6 +16,8 @@ tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
|
|
|
16
16
|
"$cairn" help | grep -q "cairn notes" || fail "help missing notes"
|
|
17
17
|
"$cairn" help | grep -q "cairn artifact <list|show|delete|prune>" || fail "help missing artifact"
|
|
18
18
|
"$cairn" help | grep -q "cairn capabilities <list|status|enable|disable|reset|logging>" || fail "help missing capabilities"
|
|
19
|
+
"$cairn" help | grep -q "cairn mcp-tools <list|status|set|reset>" || fail "help missing mcp-tools"
|
|
20
|
+
"$cairn" help | grep -q "cairn pack <init|lock|validate|install|list|show|remove|enable|disable|update|skills|approve-skill|revoke-skill>" || fail "help missing pack"
|
|
19
21
|
"$cairn" help | grep -q "cairn graph <build|query|status|diff|explain|path>" || fail "help missing graph"
|
|
20
22
|
"$cairn" sync --help >/dev/null 2>&1 || fail "cairn sync dispatch"
|
|
21
23
|
"$cairn" sync-pi --help >/dev/null 2>&1 || fail "cairn sync-pi dispatch"
|
|
@@ -23,6 +25,10 @@ tmp=$(mktemp -d); trap 'rm -rf "$tmp"' EXIT
|
|
|
23
25
|
env -u CAIRN_NOTE_DISTILLATION "$cairn" notes --help >/dev/null 2>&1 || fail "cairn notes dispatch"
|
|
24
26
|
"$cairn" artifact --help | grep -q "cairn artifact list" || fail "cairn artifact dispatch"
|
|
25
27
|
"$cairn" capabilities --help >"$tmp/capabilities-help" 2>/dev/null || fail "cairn capabilities dispatch"
|
|
28
|
+
"$cairn" mcp-tools list --json >"$tmp/mcp-tools.json" || fail "cairn mcp-tools dispatch"
|
|
29
|
+
CAIRN_PACK_BASE_DIR="$tmp/pack-store" "$cairn" pack list --json >"$tmp/packs.json" || fail "cairn pack dispatch"
|
|
30
|
+
node -e 'const v=require(process.argv[1]);if(v.schema_version!==1||!Array.isArray(v.tools))process.exit(1)' "$tmp/mcp-tools.json" || fail "mcp-tools JSON contract"
|
|
31
|
+
node -e 'const v=require(process.argv[1]);if(v.schema_version!==1||!Array.isArray(v.packs))process.exit(1)' "$tmp/packs.json" || fail "pack JSON contract"
|
|
26
32
|
"$cairn" graph --help | grep -q "cairn graph explain <symbol>" || fail "cairn graph dispatch"
|
|
27
33
|
grep -qxF 'MCP capability changes require a memory-server restart. Operating capability' "$tmp/capabilities-help" || fail "capability help missing exact restart wording"
|
|
28
34
|
grep -qxF 'changes apply on the next invocation.' "$tmp/capabilities-help" || fail "capability help missing exact invocation wording"
|
|
@@ -43,6 +43,11 @@ for shell in bash zsh fish; do
|
|
|
43
43
|
for skill_flag in --candidate --exploration-task-set --confirmation-task-set --evaluation --application --confirm; do
|
|
44
44
|
grep -q -- "$skill_flag\|-l ${skill_flag#--}" "$tmp/$shell"
|
|
45
45
|
done
|
|
46
|
+
grep -q 'mcp-tools' "$tmp/$shell"
|
|
47
|
+
grep -q 'full.*read-only.*custom\|full read-only custom' "$tmp/$shell"
|
|
48
|
+
grep -q 'pack' "$tmp/$shell"
|
|
49
|
+
grep -q 'init.*lock.*validate.*install.*list.*show.*remove.*enable.*disable.*update.*skills.*approve-skill.*revoke-skill\|init lock validate install list show remove enable disable update skills approve-skill revoke-skill' "$tmp/$shell"
|
|
50
|
+
grep -q -- '--purge-packs\|-l purge-packs' "$tmp/$shell"
|
|
46
51
|
done
|
|
47
52
|
|
|
48
53
|
"$ROOT/bin/cairn" help >"$tmp/root-help"
|
|
@@ -15,13 +15,14 @@ grep -qF "**Baseline:** Cairnkeep $version" "$coverage"
|
|
|
15
15
|
grep -qF "**Baseline:** Cairnkeep $version" "$feature_guide"
|
|
16
16
|
grep -qF 'https://github.com/cairnkeep/cairnkeep-course-labs' "$landing"
|
|
17
17
|
for checkpoint in course-00-app course-01-bootstrap course-02-memory course-03-quality \
|
|
18
|
-
course-04-operation course-05-evidence course-06-governance course-07-evaluation
|
|
18
|
+
course-04-operation course-05-evidence course-06-governance course-07-evaluation \
|
|
19
|
+
course-08-graph course-09-skill course-10-trust-context; do
|
|
19
20
|
grep -qF "\`$checkpoint\`" "$coverage"
|
|
20
21
|
done
|
|
21
22
|
|
|
22
23
|
ready=0
|
|
23
24
|
brief=0
|
|
24
|
-
for number in $(seq -w 0
|
|
25
|
+
for number in $(seq -w 0 21); do
|
|
25
26
|
matches=(docs/learning/lessons/L"$number"-*.md)
|
|
26
27
|
[[ ${#matches[@]} -eq 1 && -f ${matches[0]} ]] || {
|
|
27
28
|
echo "learning path must contain exactly one L$number lesson" >&2
|
|
@@ -52,7 +53,7 @@ grep -qF '`cairn sync-kimi --apply`' "$graph_lesson"
|
|
|
52
53
|
grep -qF '`cairn sync-pi --apply`' "$graph_lesson"
|
|
53
54
|
grep -qF '`graphify-out/`' "$graph_lesson"
|
|
54
55
|
|
|
55
|
-
[[ $ready -eq
|
|
56
|
+
[[ $ready -eq 7 && $brief -eq 15 ]] || {
|
|
56
57
|
echo "unexpected learning status totals: ready=$ready brief=$brief" >&2
|
|
57
58
|
exit 1
|
|
58
59
|
}
|
|
@@ -86,6 +86,23 @@ do
|
|
|
86
86
|
[[ -f "$installed_root/$required" ]] || fail "npm tarball omitted $required"
|
|
87
87
|
done
|
|
88
88
|
|
|
89
|
+
for required in \
|
|
90
|
+
schemas/context-pack.schema.json \
|
|
91
|
+
mcp-memory-server/dist/mcp-tool-catalog.js \
|
|
92
|
+
mcp-memory-server/dist/mcp-tool-profile.js \
|
|
93
|
+
mcp-memory-server/dist/mcp-tool-cli.js \
|
|
94
|
+
mcp-memory-server/dist/context-pack.js \
|
|
95
|
+
mcp-memory-server/dist/context-pack-cli.js \
|
|
96
|
+
docs/mcp-tool-profiles.md \
|
|
97
|
+
docs/context-packs.md
|
|
98
|
+
do
|
|
99
|
+
[[ -f "$installed_root/$required" ]] || fail "npm tarball omitted $required"
|
|
100
|
+
done
|
|
101
|
+
CAIRN_PACK_BASE_DIR="$tmp/installed-packs" cairn pack list --json >"$tmp/installed-pack-list.json" || \
|
|
102
|
+
fail "installed package pack CLI failed"
|
|
103
|
+
cairn mcp-tools list --json >"$tmp/installed-mcp-tools.json" || \
|
|
104
|
+
fail "installed package mcp-tools CLI failed"
|
|
105
|
+
|
|
89
106
|
for required in \
|
|
90
107
|
schemas/skill-adapter.schema.json \
|
|
91
108
|
schemas/skill-proposal-protocol.schema.json \
|
|
@@ -303,6 +303,27 @@ check "memory store restored" "$(cat "$SB/home/.cairnkeep/db" 2>/dev/null)"
|
|
|
303
303
|
check "note store restored exactly" "$(sha256sum "$SB/home/.cairnkeep/notes/projects/example/hindsight/failure.md" | cut -d' ' -f1)" "$purge_note_before"
|
|
304
304
|
check "typed and journal state restored exactly" "$(tree_hash "$SB/home/.cairnkeep")" "$purge_store_before"
|
|
305
305
|
|
|
306
|
+
# --- context-pack data requires its own explicit purge consent ---------------
|
|
307
|
+
PACK_HOME="$SB/pack-home"
|
|
308
|
+
PACK_STORE="$PACK_HOME/.cairnkeep/packs"
|
|
309
|
+
mkdir -p "$PACK_STORE/objects/example" "$PACK_HOME/.cairnkeep/memory"
|
|
310
|
+
printf 'immutable pack\n' >"$PACK_STORE/objects/example/marker"
|
|
311
|
+
printf 'memory\n' >"$PACK_HOME/.cairnkeep/memory/marker"
|
|
312
|
+
pack_output=$(HOME="$PACK_HOME" XDG_CONFIG_HOME="$PACK_HOME/.config" \
|
|
313
|
+
CAIRN_AGENTFS_BASE_DIR="$PACK_HOME/.cairnkeep" CAIRN_PACK_BASE_DIR="$PACK_STORE" \
|
|
314
|
+
"$ROOT_DIR/scripts/uninstall.sh" --yes --live-root "$SB/pack-live" --pi-live-root "$SB/pack-pi" --kimi-live-root "$SB/pack-kimi" 2>&1)
|
|
315
|
+
check "ordinary uninstall reports retained context packs" "$(grep -q 'kept context packs' <<<"$pack_output" && echo yes || echo no)" "yes"
|
|
316
|
+
check "ordinary uninstall retains context packs" "$([[ -f "$PACK_STORE/objects/example/marker" ]] && echo yes || echo no)" "yes"
|
|
317
|
+
HOME="$PACK_HOME" XDG_CONFIG_HOME="$PACK_HOME/.config" \
|
|
318
|
+
CAIRN_AGENTFS_BASE_DIR="$PACK_HOME/.cairnkeep" CAIRN_PACK_BASE_DIR="$PACK_STORE" \
|
|
319
|
+
"$ROOT_DIR/scripts/uninstall.sh" --yes --purge-memory --live-root "$SB/pack-live" --pi-live-root "$SB/pack-pi" --kimi-live-root "$SB/pack-kimi" >/dev/null 2>&1
|
|
320
|
+
check "memory purge retains context packs" "$([[ -f "$PACK_STORE/objects/example/marker" ]] && echo yes || echo no)" "yes"
|
|
321
|
+
check "memory purge removes non-pack memory" "$([[ -e "$PACK_HOME/.cairnkeep/memory" ]] && echo no || echo yes)" "yes"
|
|
322
|
+
HOME="$PACK_HOME" XDG_CONFIG_HOME="$PACK_HOME/.config" \
|
|
323
|
+
CAIRN_AGENTFS_BASE_DIR="$PACK_HOME/.cairnkeep" CAIRN_PACK_BASE_DIR="$PACK_STORE" \
|
|
324
|
+
"$ROOT_DIR/scripts/uninstall.sh" --yes --purge-packs --live-root "$SB/pack-live" --pi-live-root "$SB/pack-pi" --kimi-live-root "$SB/pack-kimi" >/dev/null 2>&1
|
|
325
|
+
check "explicit pack purge removes context packs" "$([[ -e "$PACK_STORE" ]] && echo no || echo yes)" "yes"
|
|
326
|
+
|
|
306
327
|
echo
|
|
307
328
|
if [[ "$fails" -gt 0 ]]; then echo "test-uninstall: $fails check(s) failed."; exit 1; fi
|
|
308
329
|
echo "test-uninstall: OK"
|
package/scripts/uninstall.sh
CHANGED
|
@@ -25,9 +25,12 @@ PI_LIVE_ROOT="${PI_CODING_AGENT_DIR:-$HOME/.pi/agent}"
|
|
|
25
25
|
KIMI_LIVE_ROOT="${KIMI_CODE_HOME:-$HOME/.kimi-code}"
|
|
26
26
|
STORE_DIR="${CAIRN_AGENTFS_BASE_DIR:-$HOME/.cairnkeep}"
|
|
27
27
|
STORE_DIR="${STORE_DIR/#\~/$HOME}"
|
|
28
|
+
PACK_DIR="${CAIRN_PACK_BASE_DIR:-$HOME/.cairnkeep/packs}"
|
|
29
|
+
PACK_DIR="${PACK_DIR/#\~/$HOME}"
|
|
28
30
|
DRY_RUN=0
|
|
29
31
|
ASSUME_YES=0
|
|
30
32
|
PURGE_MEMORY=0
|
|
33
|
+
PURGE_PACKS=0
|
|
31
34
|
PROJECTS=()
|
|
32
35
|
|
|
33
36
|
# The hooks cairnkeep registers (basename is the settings.json match token).
|
|
@@ -49,7 +52,7 @@ PROJECT_AI_FILES=(
|
|
|
49
52
|
|
|
50
53
|
usage() {
|
|
51
54
|
cat <<'EOF'
|
|
52
|
-
Usage: uninstall.sh [--dry-run] [--yes] [--purge-memory] [--live-root PATH]
|
|
55
|
+
Usage: uninstall.sh [--dry-run] [--yes] [--purge-memory] [--purge-packs] [--live-root PATH]
|
|
53
56
|
[--pi-live-root PATH] [--kimi-live-root PATH] [PROJECT ...]
|
|
54
57
|
|
|
55
58
|
Reverse cairnkeep's install. Everything removed/edited is backed up into
|
|
@@ -59,6 +62,8 @@ $HOME/.cairnkeep-uninstall-<ts>/ with a revert.sh before any change.
|
|
|
59
62
|
--yes Do not prompt for confirmation.
|
|
60
63
|
--purge-memory Also remove the global memory store and .agentfs/ memory and
|
|
61
64
|
trajectories in each PROJECT. Backed up first; off by default.
|
|
65
|
+
--purge-packs Also remove immutable context-pack objects and project
|
|
66
|
+
pointers. Backed up first; off by default.
|
|
62
67
|
--live-root PATH Claude root to clean (default: $CLAUDE_CONFIG_DIR or ~/.claude).
|
|
63
68
|
--pi-live-root PATH Pi agent root to clean (default: $PI_CODING_AGENT_DIR or ~/.pi/agent).
|
|
64
69
|
--kimi-live-root PATH Kimi Code root to clean (default: $KIMI_CODE_HOME or ~/.kimi-code).
|
|
@@ -73,6 +78,7 @@ while [[ $# -gt 0 ]]; do
|
|
|
73
78
|
--dry-run) DRY_RUN=1; shift ;;
|
|
74
79
|
--yes) ASSUME_YES=1; shift ;;
|
|
75
80
|
--purge-memory) PURGE_MEMORY=1; shift ;;
|
|
81
|
+
--purge-packs) PURGE_PACKS=1; shift ;;
|
|
76
82
|
--live-root) LIVE_ROOT="$2"; shift 2 ;;
|
|
77
83
|
--pi-live-root) PI_LIVE_ROOT="$2"; shift 2 ;;
|
|
78
84
|
--kimi-live-root) KIMI_LIVE_ROOT="$2"; shift 2 ;;
|
|
@@ -142,6 +148,7 @@ echo " live root: $LIVE_ROOT"
|
|
|
142
148
|
echo " Pi live root: $PI_LIVE_ROOT"
|
|
143
149
|
echo " Kimi root: $KIMI_LIVE_ROOT"
|
|
144
150
|
echo " memory store: $STORE_DIR ($([[ $PURGE_MEMORY -eq 1 ]] && echo 'WILL be purged' || echo 'kept'))"
|
|
151
|
+
echo " context packs: $PACK_DIR ($([[ $PURGE_PACKS -eq 1 ]] && echo 'WILL be purged' || echo 'kept'))"
|
|
145
152
|
[[ ${#PROJECTS[@]} -gt 0 ]] && echo " projects: ${PROJECTS[*]}"
|
|
146
153
|
|
|
147
154
|
if [[ $DRY_RUN -eq 0 && $ASSUME_YES -eq 0 ]]; then
|
|
@@ -231,6 +238,24 @@ fi
|
|
|
231
238
|
if [[ $PURGE_MEMORY -eq 1 ]]; then
|
|
232
239
|
echo "Memory store:"
|
|
233
240
|
remove_path "$STORE_DIR"
|
|
241
|
+
if [[ $PURGE_PACKS -eq 0 && "$PACK_DIR" == "$STORE_DIR"/* && $DRY_RUN -eq 0 ]]; then
|
|
242
|
+
pack_backup="$BACKUP_DIR/files/${PACK_DIR#/}"
|
|
243
|
+
if [[ -d "$pack_backup" ]]; then
|
|
244
|
+
mkdir -p "$(dirname "$PACK_DIR")"
|
|
245
|
+
cp -a "$pack_backup" "$PACK_DIR"
|
|
246
|
+
echo " retained context packs: $PACK_DIR"
|
|
247
|
+
fi
|
|
248
|
+
fi
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
if [[ $PURGE_MEMORY -eq 0 && $PURGE_PACKS -eq 0 && -d "$PACK_DIR" ]]; then
|
|
252
|
+
echo "Context packs:"
|
|
253
|
+
echo " kept context packs: $PACK_DIR (use --purge-packs to remove)"
|
|
254
|
+
fi
|
|
255
|
+
|
|
256
|
+
if [[ $PURGE_PACKS -eq 1 && ! ( $PURGE_MEMORY -eq 1 && "$PACK_DIR" == "$STORE_DIR"/* ) ]]; then
|
|
257
|
+
echo "Context packs:"
|
|
258
|
+
remove_path "$PACK_DIR"
|
|
234
259
|
fi
|
|
235
260
|
|
|
236
261
|
# 6. Per-project bootstrap scaffold.
|
|
@@ -17,6 +17,17 @@
|
|
|
17
17
|
# scopes default to ~/.cairnkeep; project scope uses <server-cwd>/.agentfs/.
|
|
18
18
|
# CAIRN_AGENTFS_BASE_DIR=~/.cairnkeep
|
|
19
19
|
#
|
|
20
|
+
# Least-authority MCP profiles only restrict currently available tools. Project
|
|
21
|
+
# state is managed with `cairn mcp-tools`; these are process overrides.
|
|
22
|
+
# CAIRN_MCP_TOOL_PROFILE=read-only
|
|
23
|
+
# CAIRN_MCP_ALLOWED_TOOLS=memory_read,memory_search
|
|
24
|
+
#
|
|
25
|
+
# Immutable context packs are local and OFF by default. HTTP access requires
|
|
26
|
+
# the separate pack HTTP flag plus the existing authenticated HTTP settings.
|
|
27
|
+
# CAIRN_CONTEXT_PACKS=1
|
|
28
|
+
# CAIRN_CONTEXT_PACK_HTTP=1
|
|
29
|
+
# CAIRN_PACK_BASE_DIR=~/.cairnkeep/packs
|
|
30
|
+
#
|
|
20
31
|
# Typed metadata, filters, logical note address spaces, and memory_import are
|
|
21
32
|
# OFF by default. Restart the memory server after changing this construction-
|
|
22
33
|
# time tool-schema flag. No model, API key, or network endpoint is required.
|