@cairnkeep/cli 2.7.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 +44 -1
- package/README.md +51 -2
- package/bin/cairn +19 -1
- package/docs/context-packs.md +94 -0
- package/docs/design/meta-agent.md +39 -35
- package/docs/harness-compatibility.md +7 -1
- package/docs/learning/CURRICULUM-MAP.md +14 -4
- package/docs/learning/FEATURE-GUIDE.md +11 -4
- package/docs/learning/README.md +8 -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/L17-agent-boundary.md +12 -8
- package/docs/learning/lessons/L18-local-code-graph.md +97 -0
- package/docs/learning/lessons/L19-validated-skill-improvement.md +118 -0
- 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/evidence-and-evaluation.md +5 -3
- package/docs/learning/tracks/operator.md +4 -2
- package/docs/learning/tracks/practitioner.md +5 -4
- package/docs/mcp-tool-profiles.md +43 -0
- package/docs/operating.md +61 -0
- package/docs/privacy-and-data-flow.md +59 -1
- package/docs/skill-improvement.md +124 -0
- package/docs/storage.md +42 -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-plan.js +22 -5
- package/mcp-memory-server/dist/eval-process.js +31 -0
- package/mcp-memory-server/dist/eval-report.js +1 -0
- package/mcp-memory-server/dist/eval-runner.js +12 -4
- package/mcp-memory-server/dist/eval-schema.js +2 -1
- package/mcp-memory-server/dist/eval-workspace.js +50 -1
- 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/dist/skill-cli.js +236 -0
- package/mcp-memory-server/dist/skill-evaluation.js +244 -0
- package/mcp-memory-server/dist/skill-schema.js +164 -0
- package/mcp-memory-server/dist/skill-store.js +583 -0
- package/mcp-memory-server/package.json +4 -1
- package/package.json +1 -1
- package/schemas/context-pack.schema.json +33 -0
- package/schemas/eval-report.schema.json +2 -1
- package/schemas/skill-adapter.schema.json +39 -0
- package/schemas/skill-proposal-protocol.schema.json +97 -0
- package/scripts/completion.sh +62 -5
- package/scripts/doctor.sh +39 -0
- package/scripts/test-cli-dispatch.sh +6 -0
- package/scripts/test-completion.sh +16 -0
- package/scripts/test-learning-docs.sh +13 -3
- package/scripts/test-package-install.sh +35 -0
- package/scripts/test-skill-cli.sh +30 -0
- package/scripts/test-uninstall.sh +21 -0
- package/scripts/uninstall.sh +26 -1
- package/templates/env.example.template +11 -0
- package/templates/graph-policy.md.template +3 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/cairnkeep/cairnkeep/main/schemas/skill-adapter.schema.json",
|
|
4
|
+
"title": "Cairnkeep skill proposal adapter configuration v1",
|
|
5
|
+
"type": "object",
|
|
6
|
+
"additionalProperties": false,
|
|
7
|
+
"required": ["schema_version", "id", "command", "limits"],
|
|
8
|
+
"properties": {
|
|
9
|
+
"schema_version": { "const": 1 },
|
|
10
|
+
"id": { "$ref": "#/$defs/identifier" },
|
|
11
|
+
"command": {
|
|
12
|
+
"type": "object",
|
|
13
|
+
"additionalProperties": false,
|
|
14
|
+
"required": ["program", "args"],
|
|
15
|
+
"properties": {
|
|
16
|
+
"program": { "type": "string", "minLength": 1, "maxLength": 4096 },
|
|
17
|
+
"args": { "type": "array", "maxItems": 128, "items": { "type": "string", "maxLength": 16384 } }
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"environment_allowlist": {
|
|
21
|
+
"type": "array",
|
|
22
|
+
"maxItems": 64,
|
|
23
|
+
"default": [],
|
|
24
|
+
"items": { "type": "string", "pattern": "^[A-Z][A-Z0-9_]{0,127}$" }
|
|
25
|
+
},
|
|
26
|
+
"limits": {
|
|
27
|
+
"type": "object",
|
|
28
|
+
"additionalProperties": false,
|
|
29
|
+
"required": ["elapsed_ms", "stdout_bytes"],
|
|
30
|
+
"properties": {
|
|
31
|
+
"elapsed_ms": { "type": "integer", "minimum": 1, "maximum": 3600000 },
|
|
32
|
+
"stdout_bytes": { "type": "integer", "minimum": 1, "maximum": 4194304 }
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
"$defs": {
|
|
37
|
+
"identifier": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[a-z0-9][a-z0-9._-]*$" }
|
|
38
|
+
}
|
|
39
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
3
|
+
"$id": "https://raw.githubusercontent.com/cairnkeep/cairnkeep/main/schemas/skill-proposal-protocol.schema.json",
|
|
4
|
+
"title": "Cairnkeep skill proposal adapter protocol v1",
|
|
5
|
+
"oneOf": [{ "$ref": "#/$defs/request" }, { "$ref": "#/$defs/response" }],
|
|
6
|
+
"$defs": {
|
|
7
|
+
"identifier": { "type": "string", "minLength": 1, "maxLength": 128, "pattern": "^[a-z0-9][a-z0-9._-]*$" },
|
|
8
|
+
"digest": { "type": "string", "pattern": "^[a-f0-9]{64}$" },
|
|
9
|
+
"timestamp": { "type": "string", "format": "date-time" },
|
|
10
|
+
"relativePath": {
|
|
11
|
+
"type": "string",
|
|
12
|
+
"minLength": 1,
|
|
13
|
+
"maxLength": 1024,
|
|
14
|
+
"pattern": "^(?!/)(?!.*(?:^|/)(?:\\.|\\.\\.)(?:/|$))(?!.*\\\\)(?!.*//)(?!.*[\\u0000-\\u001f\\u007f])(?:.*\\/)?SKILL\\.md$"
|
|
15
|
+
},
|
|
16
|
+
"occurrence": {
|
|
17
|
+
"type": "object",
|
|
18
|
+
"additionalProperties": false,
|
|
19
|
+
"required": ["session_id", "session_digest", "ended_at", "outcome", "evidence"],
|
|
20
|
+
"properties": {
|
|
21
|
+
"session_id": { "type": "string", "minLength": 1, "maxLength": 256 },
|
|
22
|
+
"session_digest": { "$ref": "#/$defs/digest" },
|
|
23
|
+
"ended_at": { "$ref": "#/$defs/timestamp" },
|
|
24
|
+
"outcome": { "enum": ["failure", "resolution", "abandonment"] },
|
|
25
|
+
"tool_name": { "type": "string", "minLength": 1, "maxLength": 256 },
|
|
26
|
+
"evidence": { "type": "string", "maxLength": 4096 }
|
|
27
|
+
}
|
|
28
|
+
},
|
|
29
|
+
"candidate": {
|
|
30
|
+
"type": "object",
|
|
31
|
+
"additionalProperties": false,
|
|
32
|
+
"required": ["schema_version", "id", "project_id", "status", "note_id", "source_digest", "title", "description", "failure_family", "failure_count", "resolution_count", "occurrences", "lessons", "caveats", "created_at", "reviewed_at"],
|
|
33
|
+
"properties": {
|
|
34
|
+
"schema_version": { "const": 1 },
|
|
35
|
+
"id": { "$ref": "#/$defs/identifier" },
|
|
36
|
+
"project_id": { "$ref": "#/$defs/identifier" },
|
|
37
|
+
"status": { "const": "approved" },
|
|
38
|
+
"note_id": { "$ref": "#/$defs/identifier" },
|
|
39
|
+
"source_digest": { "$ref": "#/$defs/digest" },
|
|
40
|
+
"title": { "type": "string", "minLength": 1, "maxLength": 512 },
|
|
41
|
+
"description": { "type": "string", "maxLength": 4096 },
|
|
42
|
+
"failure_family": { "$ref": "#/$defs/identifier" },
|
|
43
|
+
"failure_count": { "type": "integer", "minimum": 2, "maximum": 1024 },
|
|
44
|
+
"resolution_count": { "type": "integer", "minimum": 1, "maximum": 1024 },
|
|
45
|
+
"occurrences": { "type": "array", "minItems": 2, "maxItems": 64, "items": { "$ref": "#/$defs/occurrence" } },
|
|
46
|
+
"lessons": { "type": "array", "maxItems": 16, "items": { "type": "string", "minLength": 1, "maxLength": 1024 } },
|
|
47
|
+
"caveats": { "type": "array", "maxItems": 16, "items": { "type": "string", "minLength": 1, "maxLength": 1024 } },
|
|
48
|
+
"created_at": { "$ref": "#/$defs/timestamp" },
|
|
49
|
+
"reviewed_at": { "$ref": "#/$defs/timestamp" }
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"edit": {
|
|
53
|
+
"type": "object",
|
|
54
|
+
"additionalProperties": false,
|
|
55
|
+
"required": ["operation", "anchor", "content", "rationale"],
|
|
56
|
+
"properties": {
|
|
57
|
+
"operation": { "enum": ["add", "replace", "delete"] },
|
|
58
|
+
"anchor": { "oneOf": [{ "type": "string", "minLength": 1, "maxLength": 16384 }, { "type": "null" }] },
|
|
59
|
+
"content": { "type": "string", "maxLength": 65536 },
|
|
60
|
+
"rationale": { "type": "string", "minLength": 1, "maxLength": 2048 }
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
"request": {
|
|
64
|
+
"type": "object",
|
|
65
|
+
"additionalProperties": false,
|
|
66
|
+
"required": ["schema_version", "operation", "candidate", "candidate_digest", "target", "edit_budget"],
|
|
67
|
+
"properties": {
|
|
68
|
+
"schema_version": { "const": 1 },
|
|
69
|
+
"operation": { "const": "propose" },
|
|
70
|
+
"candidate": { "$ref": "#/$defs/candidate" },
|
|
71
|
+
"candidate_digest": { "$ref": "#/$defs/digest" },
|
|
72
|
+
"target": {
|
|
73
|
+
"type": "object",
|
|
74
|
+
"additionalProperties": false,
|
|
75
|
+
"required": ["path", "baseline_digest", "content"],
|
|
76
|
+
"properties": {
|
|
77
|
+
"path": { "$ref": "#/$defs/relativePath" },
|
|
78
|
+
"baseline_digest": { "$ref": "#/$defs/digest" },
|
|
79
|
+
"content": { "type": "string", "maxLength": 262144 }
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"edit_budget": { "type": "integer", "minimum": 1, "maximum": 16 }
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
"response": {
|
|
86
|
+
"type": "object",
|
|
87
|
+
"additionalProperties": false,
|
|
88
|
+
"required": ["schema_version", "status"],
|
|
89
|
+
"properties": {
|
|
90
|
+
"schema_version": { "const": 1 },
|
|
91
|
+
"status": { "enum": ["completed", "adapter_error"] },
|
|
92
|
+
"error_code": { "$ref": "#/$defs/identifier" },
|
|
93
|
+
"edits": { "type": "array", "maxItems": 16, "default": [], "items": { "$ref": "#/$defs/edit" } }
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
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 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
|
|
@@ -63,10 +65,11 @@ _cairn_complete() {
|
|
|
63
65
|
*) COMPREPLY=( $(compgen -W "validate run ablate report prune delete" -- "$current") ) ;;
|
|
64
66
|
esac
|
|
65
67
|
;;
|
|
68
|
+
skill) COMPREPLY=( $(compgen -W "harvest list show review propose evaluate apply rollback --project --minimum-occurrences --kind --id --candidate --approve --target --adapter --edit-budget --proposal --exploration-task-set --confirmation-task-set --output --repetitions --seed --minimum-improvement --evaluation --application --confirm --yes --json" -- "$current") ) ;;
|
|
66
69
|
graph) COMPREPLY=( $(compgen -W "build query status diff explain path --force" -- "$current") ) ;;
|
|
67
70
|
memory) COMPREPLY=( $(compgen -W "path export import" -- "$current") ) ;;
|
|
68
71
|
audit-timer) COMPREPLY=( $(compgen -W "--on-calendar --para-root --render-only" -- "$current") ) ;;
|
|
69
|
-
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") ) ;;
|
|
70
73
|
completion) COMPREPLY=( $(compgen -W "bash zsh fish" -- "$current") ) ;;
|
|
71
74
|
esac
|
|
72
75
|
}
|
|
@@ -88,8 +91,11 @@ _cairn() {
|
|
|
88
91
|
'trajectory:inspect and prune local session trajectories'
|
|
89
92
|
'artifact:inspect, delete, and prune local artifacts'
|
|
90
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'
|
|
91
96
|
'notes:distill and search local hindsight notes'
|
|
92
97
|
'eval:run and inspect default-off local evaluations'
|
|
98
|
+
'skill:review and evaluate evidence-backed skill improvements'
|
|
93
99
|
'graph:inspect a published Graphify graph'
|
|
94
100
|
'memory:manage the durable memory store'
|
|
95
101
|
'audit-timer:install a memory and wiki audit timer'
|
|
@@ -118,6 +124,8 @@ _cairn() {
|
|
|
118
124
|
*) _values 'artifact command' list show delete prune ;;
|
|
119
125
|
esac
|
|
120
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]' ;;
|
|
121
129
|
capabilities)
|
|
122
130
|
case $words[3] in
|
|
123
131
|
list|status) _arguments '--json[emit JSON]' ;;
|
|
@@ -139,10 +147,23 @@ _cairn() {
|
|
|
139
147
|
*) _values 'eval command' validate run ablate report prune delete ;;
|
|
140
148
|
esac
|
|
141
149
|
;;
|
|
150
|
+
skill)
|
|
151
|
+
case $words[3] in
|
|
152
|
+
harvest) _arguments '--project[project root]:directory:_files -/' '--minimum-occurrences[minimum recurring failures]:count:' '--json[emit JSON]' ;;
|
|
153
|
+
list) _arguments '--project[project root]:directory:_files -/' '--kind[artifact kind]:kind:(candidate proposal evaluation application)' '--json[emit JSON]' ;;
|
|
154
|
+
show) _arguments '--project[project root]:directory:_files -/' '--kind[artifact kind]:kind:(candidate proposal evaluation application)' '--id[artifact ID]:artifact ID:' '--json[emit JSON]' ;;
|
|
155
|
+
review) _arguments '--project[project root]:directory:_files -/' '--candidate[candidate ID]:candidate ID:' '--approve[approve evidence]' '--json[emit JSON]' ;;
|
|
156
|
+
propose) _arguments '--project[project root]:directory:_files -/' '--candidate[candidate ID]:candidate ID:' '--target[existing SKILL.md]:file:_files' '--adapter[proposal adapter configuration]:file:_files' '--edit-budget[maximum edits]:count:' '--json[emit JSON]' ;;
|
|
157
|
+
evaluate) _arguments '--project[project root]:directory:_files -/' '--proposal[proposal ID]:proposal ID:' '--exploration-task-set[exploration task set]:file:_files' '--confirmation-task-set[confirmation task set]:file:_files' '--adapter[evaluation adapter configuration]:file:_files' '--output[report root]:directory:_files -/' '--repetitions[repetition count]:count:' '--seed[deterministic seed]:seed:' '--minimum-improvement[distinct improved tasks]:count:' '--yes[confirm execution]' '--json[emit JSON]' ;;
|
|
158
|
+
apply) _arguments '--project[project root]:directory:_files -/' '--proposal[proposal ID]:proposal ID:' '--evaluation[evaluation ID]:evaluation ID:' '--confirm[exact proposal digest]:digest:' '--json[emit JSON]' ;;
|
|
159
|
+
rollback) _arguments '--project[project root]:directory:_files -/' '--application[application ID]:application ID:' '--confirm[confirm rollback]' '--json[emit JSON]' ;;
|
|
160
|
+
*) _values 'skill command' harvest list show review propose evaluate apply rollback ;;
|
|
161
|
+
esac
|
|
162
|
+
;;
|
|
142
163
|
graph) _values 'graph command' build query status diff explain path '--force[allow a smaller graph after code deletion]' ;;
|
|
143
164
|
memory) _values 'memory command' path export import ;;
|
|
144
165
|
audit-timer) _arguments '--on-calendar[systemd calendar]:calendar:' '--para-root[PARA root]:directory:_files -/' '--render-only[render directory]:directory:_files -/' ;;
|
|
145
|
-
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 -/' ;;
|
|
146
167
|
completion) _values 'shell' bash zsh fish ;;
|
|
147
168
|
*) _arguments '*:argument:_files' ;;
|
|
148
169
|
esac
|
|
@@ -153,8 +174,8 @@ EOF
|
|
|
153
174
|
fish)
|
|
154
175
|
cat <<'EOF'
|
|
155
176
|
complete -c cairn -f
|
|
156
|
-
for command in bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval graph memory audit-timer uninstall completion version help
|
|
157
|
-
complete -c cairn -n "not __fish_seen_subcommand_from bootstrap memory-server sync sync-pi sync-kimi doctor trajectory artifact capabilities notes eval 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
|
|
158
179
|
end
|
|
159
180
|
complete -c cairn -n "__fish_seen_subcommand_from sync" -l apply
|
|
160
181
|
complete -c cairn -n "__fish_seen_subcommand_from sync" -l live-root -r
|
|
@@ -178,6 +199,17 @@ complete -c cairn -n "__fish_seen_subcommand_from capabilities; and __fish_seen_
|
|
|
178
199
|
complete -c cairn -n "__fish_seen_subcommand_from capabilities; and __fish_seen_subcommand_from reset" -l all
|
|
179
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"
|
|
180
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
|
|
181
213
|
complete -c cairn -n "__fish_seen_subcommand_from notes" -a "distill search-error promote doctor"
|
|
182
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"
|
|
183
215
|
complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from validate run ablate" -l task-set -r
|
|
@@ -191,11 +223,36 @@ complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcomma
|
|
|
191
223
|
complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from prune" -l older-than-days -r
|
|
192
224
|
complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from prune delete" -l dry-run
|
|
193
225
|
complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from validate run ablate report prune delete" -l json
|
|
226
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and not __fish_seen_subcommand_from harvest list show review propose evaluate apply rollback" -a "harvest list show review propose evaluate apply rollback"
|
|
227
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from harvest list show review propose evaluate apply rollback" -l project -r
|
|
228
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from harvest list show review propose evaluate apply rollback" -l json
|
|
229
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from harvest" -l minimum-occurrences -r
|
|
230
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from list show" -l kind -r -a "candidate proposal evaluation application"
|
|
231
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from show" -l id -r
|
|
232
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from review propose" -l candidate -r
|
|
233
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from review" -l approve
|
|
234
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from propose" -l target -r
|
|
235
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from propose evaluate" -l adapter -r
|
|
236
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from propose" -l edit-budget -r
|
|
237
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate apply" -l proposal -r
|
|
238
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l exploration-task-set -r
|
|
239
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l confirmation-task-set -r
|
|
240
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l output -r
|
|
241
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l repetitions -r
|
|
242
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l seed -r
|
|
243
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l minimum-improvement -r
|
|
244
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l yes
|
|
245
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from apply" -l evaluation -r
|
|
246
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from apply" -l confirm -r
|
|
247
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from rollback" -l application -r
|
|
248
|
+
complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from rollback" -l confirm
|
|
194
249
|
complete -c cairn -n "__fish_seen_subcommand_from graph" -a "build query status diff explain path"
|
|
195
250
|
complete -c cairn -n "__fish_seen_subcommand_from graph; and __fish_seen_subcommand_from build" -l force
|
|
196
251
|
complete -c cairn -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
|
|
197
252
|
complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l pi-live-root -r
|
|
198
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
|
|
199
256
|
EOF
|
|
200
257
|
;;
|
|
201
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"
|
|
@@ -14,6 +14,7 @@ done
|
|
|
14
14
|
capability_ids='memory.write memory.search notes.distill wiki graph security.audit route.check context.explore'
|
|
15
15
|
eval_commands='validate run ablate report prune delete'
|
|
16
16
|
eval_flags='--task-set --adapter --output --repetitions --seed --json --yes --disable --experiment --older-than-days --dry-run'
|
|
17
|
+
skill_commands='harvest list show review propose evaluate apply rollback'
|
|
17
18
|
for shell in bash zsh fish; do
|
|
18
19
|
grep -q 'capabilities' "$tmp/$shell"
|
|
19
20
|
grep -q 'list.*status.*enable.*disable.*reset.*logging\|list status enable disable reset logging' "$tmp/$shell"
|
|
@@ -37,6 +38,16 @@ for shell in bash zsh fish; do
|
|
|
37
38
|
echo "completion exposed a private eval lifecycle operation for $shell" >&2
|
|
38
39
|
exit 1
|
|
39
40
|
fi
|
|
41
|
+
grep -q 'skill' "$tmp/$shell"
|
|
42
|
+
grep -q 'harvest.*list.*show.*review.*propose.*evaluate.*apply.*rollback\|harvest list show review propose evaluate apply rollback' "$tmp/$shell"
|
|
43
|
+
for skill_flag in --candidate --exploration-task-set --confirmation-task-set --evaluation --application --confirm; do
|
|
44
|
+
grep -q -- "$skill_flag\|-l ${skill_flag#--}" "$tmp/$shell"
|
|
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"
|
|
40
51
|
done
|
|
41
52
|
|
|
42
53
|
"$ROOT/bin/cairn" help >"$tmp/root-help"
|
|
@@ -52,6 +63,11 @@ if grep -q 'doctor-diagnosis' "$tmp/eval-help"; then
|
|
|
52
63
|
echo 'eval help exposed a private lifecycle operation' >&2
|
|
53
64
|
exit 1
|
|
54
65
|
fi
|
|
66
|
+
grep -qF 'cairn skill <harvest|list|show|review|propose|evaluate|apply|rollback>' "$tmp/root-help"
|
|
67
|
+
node "$ROOT/mcp-memory-server/dist/skill-cli.js" --help >"$tmp/skill-help"
|
|
68
|
+
for command in $skill_commands; do
|
|
69
|
+
grep -q "cairn skill $command" "$tmp/skill-help"
|
|
70
|
+
done
|
|
55
71
|
|
|
56
72
|
node - "$ROOT/mcp-memory-server/src/capability-registry.ts" "$tmp/bash" "$tmp/zsh" "$tmp/fish" <<'NODE'
|
|
57
73
|
const fs = require("fs");
|
|
@@ -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
|
|
@@ -43,7 +44,16 @@ for number in $(seq -w 0 17); do
|
|
|
43
44
|
fi
|
|
44
45
|
done
|
|
45
46
|
|
|
46
|
-
|
|
47
|
+
graph_lesson=docs/learning/lessons/L18-local-code-graph.md
|
|
48
|
+
for mode in build query status diff explain path; do
|
|
49
|
+
grep -qF "cairn graph $mode" "$graph_lesson"
|
|
50
|
+
done
|
|
51
|
+
grep -qF 'Do not run `graphify install`' "$graph_lesson"
|
|
52
|
+
grep -qF '`cairn sync-kimi --apply`' "$graph_lesson"
|
|
53
|
+
grep -qF '`cairn sync-pi --apply`' "$graph_lesson"
|
|
54
|
+
grep -qF '`graphify-out/`' "$graph_lesson"
|
|
55
|
+
|
|
56
|
+
[[ $ready -eq 7 && $brief -eq 15 ]] || {
|
|
47
57
|
echo "unexpected learning status totals: ready=$ready brief=$brief" >&2
|
|
48
58
|
exit 1
|
|
49
59
|
}
|
|
@@ -19,6 +19,7 @@ server_dev_dependencies_before=$(manifest_field "$ROOT/mcp-memory-server/package
|
|
|
19
19
|
root_lock_before=$(sha256sum "$ROOT/package-lock.json" | cut -d' ' -f1)
|
|
20
20
|
server_lock_before=$(sha256sum "$ROOT/mcp-memory-server/package-lock.json" | cut -d' ' -f1)
|
|
21
21
|
node "$ROOT/mcp-memory-server/dist/eval-cli.js" --help >"$tmp/source-eval-help"
|
|
22
|
+
node "$ROOT/mcp-memory-server/dist/skill-cli.js" --help >"$tmp/source-skill-help"
|
|
22
23
|
env -u CAIRN_EVAL "$ROOT/bin/cairn" eval validate \
|
|
23
24
|
--task-set "$tmp/source-unread-task-set" \
|
|
24
25
|
--adapter "$tmp/source-unread-adapter" \
|
|
@@ -52,6 +53,11 @@ env -u CAIRN_NOTE_DISTILLATION cairn notes --help >/dev/null \
|
|
|
52
53
|
|| fail "installed package omitted the notes command"
|
|
53
54
|
|
|
54
55
|
installed_root="$tmp/prefix/lib/node_modules/@cairnkeep/cli"
|
|
56
|
+
cairn skill --help >"$tmp/installed-skill-help"
|
|
57
|
+
cmp -s "$tmp/source-skill-help" "$tmp/installed-skill-help" || \
|
|
58
|
+
fail "source and installed skill help differ"
|
|
59
|
+
cairn skill list --project "$tmp/project" --json >"$tmp/installed-skill-list.json" || \
|
|
60
|
+
fail "installed package skill list failed"
|
|
55
61
|
cairn eval --help >"$tmp/installed-eval-help"
|
|
56
62
|
cmp -s "$tmp/source-eval-help" "$tmp/installed-eval-help" || \
|
|
57
63
|
fail "source and installed eval help differ"
|
|
@@ -80,6 +86,35 @@ do
|
|
|
80
86
|
[[ -f "$installed_root/$required" ]] || fail "npm tarball omitted $required"
|
|
81
87
|
done
|
|
82
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
|
+
|
|
106
|
+
for required in \
|
|
107
|
+
schemas/skill-adapter.schema.json \
|
|
108
|
+
schemas/skill-proposal-protocol.schema.json \
|
|
109
|
+
mcp-memory-server/dist/skill-schema.js \
|
|
110
|
+
mcp-memory-server/dist/skill-store.js \
|
|
111
|
+
mcp-memory-server/dist/skill-evaluation.js \
|
|
112
|
+
mcp-memory-server/dist/skill-cli.js \
|
|
113
|
+
docs/skill-improvement.md
|
|
114
|
+
do
|
|
115
|
+
[[ -f "$installed_root/$required" ]] || fail "npm tarball omitted $required"
|
|
116
|
+
done
|
|
117
|
+
|
|
83
118
|
for required in \
|
|
84
119
|
schemas/eval-task-set.schema.json \
|
|
85
120
|
schemas/eval-adapter.schema.json \
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
|
|
5
|
+
tmp=$(mktemp -d)
|
|
6
|
+
trap 'rm -rf "$tmp"' EXIT
|
|
7
|
+
|
|
8
|
+
node "$ROOT/mcp-memory-server/dist/skill-cli.js" --help >"$tmp/help"
|
|
9
|
+
for operation in harvest list show review propose evaluate apply rollback; do
|
|
10
|
+
grep -q "$operation" "$tmp/help" || { echo "FAIL: skill help omitted $operation" >&2; exit 1; }
|
|
11
|
+
done
|
|
12
|
+
|
|
13
|
+
mkdir -p "$tmp/project"
|
|
14
|
+
node "$ROOT/mcp-memory-server/dist/skill-cli.js" list --project "$tmp/project" --json >"$tmp/list.json"
|
|
15
|
+
node -e '
|
|
16
|
+
const value = require(process.argv[1]);
|
|
17
|
+
for (const key of ["candidates", "proposals", "evaluations", "applications"]) {
|
|
18
|
+
if (!Array.isArray(value[key]) || value[key].length !== 0) process.exit(1);
|
|
19
|
+
}
|
|
20
|
+
' "$tmp/list.json"
|
|
21
|
+
|
|
22
|
+
if env -u CAIRN_EVAL node "$ROOT/mcp-memory-server/dist/skill-cli.js" evaluate \
|
|
23
|
+
--project "$tmp/project" --proposal missing --exploration-task-set missing \
|
|
24
|
+
--confirmation-task-set missing --adapter missing --yes >"$tmp/out" 2>"$tmp/err"; then
|
|
25
|
+
echo "FAIL: disabled skill evaluation succeeded" >&2
|
|
26
|
+
exit 1
|
|
27
|
+
fi
|
|
28
|
+
grep -q 'disabled' "$tmp/err" || { echo "FAIL: disabled skill evaluation did not fail closed" >&2; exit 1; }
|
|
29
|
+
|
|
30
|
+
echo "PASS: installed-style skill CLI discovery and default-off gate"
|
|
@@ -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.
|