@cairnkeep/cli 2.6.0 → 2.8.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.
Files changed (80) hide show
  1. package/CHANGELOG.md +35 -1
  2. package/README.md +45 -8
  3. package/bin/cairn +21 -3
  4. package/claude/commands/graphify.md +46 -55
  5. package/docs/design/meta-agent.md +39 -35
  6. package/docs/harness-compatibility.md +13 -5
  7. package/docs/learning/CURRICULUM-MAP.md +10 -3
  8. package/docs/learning/FEATURE-GUIDE.md +8 -5
  9. package/docs/learning/README.md +16 -14
  10. package/docs/learning/lessons/L00-why-cairnkeep.md +1 -5
  11. package/docs/learning/lessons/L01-safe-trial.md +3 -7
  12. package/docs/learning/lessons/L02-installation.md +6 -8
  13. package/docs/learning/lessons/L03-first-project.md +1 -5
  14. package/docs/learning/lessons/L04-memory-fundamentals.md +0 -6
  15. package/docs/learning/lessons/L05-daily-workflow.md +0 -5
  16. package/docs/learning/lessons/L06-repository-quality.md +0 -6
  17. package/docs/learning/lessons/L07-privacy-and-storage.md +0 -5
  18. package/docs/learning/lessons/L08-multiple-machines.md +0 -5
  19. package/docs/learning/lessons/L09-domain-knowledge.md +0 -5
  20. package/docs/learning/lessons/L10-context-exploration.md +0 -5
  21. package/docs/learning/lessons/L11-containers.md +0 -5
  22. package/docs/learning/lessons/L12-managed-overlays.md +0 -6
  23. package/docs/learning/lessons/L13-session-evidence.md +0 -6
  24. package/docs/learning/lessons/L14-typed-memory.md +0 -6
  25. package/docs/learning/lessons/L15-capability-governance.md +0 -6
  26. package/docs/learning/lessons/L16-evaluation.md +0 -7
  27. package/docs/learning/lessons/L17-agent-boundary.md +12 -14
  28. package/docs/learning/lessons/L18-local-code-graph.md +97 -0
  29. package/docs/learning/lessons/L19-validated-skill-improvement.md +87 -0
  30. package/docs/learning/templates/lesson-template.md +0 -4
  31. package/docs/learning/tracks/evidence-and-evaluation.md +5 -3
  32. package/docs/learning/tracks/practitioner.md +5 -4
  33. package/docs/operating.md +102 -9
  34. package/docs/privacy-and-data-flow.md +42 -0
  35. package/docs/skill-improvement.md +124 -0
  36. package/docs/storage.md +25 -0
  37. package/examples/eval/bundled-fake.json +1 -1
  38. package/kimi/skills/graphify/SKILL.md +33 -0
  39. package/mcp-memory-server/dist/capability-registry.js +2 -2
  40. package/mcp-memory-server/dist/eval-plan.js +22 -5
  41. package/mcp-memory-server/dist/eval-process.js +31 -0
  42. package/mcp-memory-server/dist/eval-runner.js +10 -4
  43. package/mcp-memory-server/dist/eval-schema.js +1 -1
  44. package/mcp-memory-server/dist/eval-workspace.js +50 -1
  45. package/mcp-memory-server/dist/graph-cli.js +386 -0
  46. package/mcp-memory-server/dist/skill-cli.js +236 -0
  47. package/mcp-memory-server/dist/skill-evaluation.js +244 -0
  48. package/mcp-memory-server/dist/skill-schema.js +164 -0
  49. package/mcp-memory-server/dist/skill-store.js +583 -0
  50. package/mcp-memory-server/package.json +3 -1
  51. package/opencode/command/graphify.md +48 -58
  52. package/package.json +2 -1
  53. package/pi/prompts/graphify.md +32 -0
  54. package/schemas/eval-report.schema.json +1 -1
  55. package/schemas/skill-adapter.schema.json +39 -0
  56. package/schemas/skill-proposal-protocol.schema.json +97 -0
  57. package/scripts/bootstrap.sh +2 -1
  58. package/scripts/completion.sh +55 -6
  59. package/scripts/smoke-bash32.sh +1 -0
  60. package/scripts/sync-kimi-assets.sh +77 -0
  61. package/scripts/sync-pi-assets.sh +52 -31
  62. package/scripts/test-bootstrap-untracked.sh +21 -0
  63. package/scripts/test-cli-dispatch.sh +4 -0
  64. package/scripts/test-completion.sh +16 -0
  65. package/scripts/test-graph-harness-adapters.sh +46 -0
  66. package/scripts/test-launcher-hooks.sh +4 -2
  67. package/scripts/test-learning-docs.sh +13 -11
  68. package/scripts/test-package-install.sh +24 -0
  69. package/scripts/test-skill-cli.sh +30 -0
  70. package/scripts/test-trajectory-hooks.sh +5 -1
  71. package/scripts/test-uninstall.sh +12 -2
  72. package/scripts/uninstall.sh +11 -4
  73. package/templates/graph-policy.md.template +26 -5
  74. package/docs/learning/PRODUCTION-PLAN.md +0 -153
  75. package/docs/learning/instructor-guide.md +0 -66
  76. package/docs/learning/templates/video-script-template.md +0 -50
  77. package/docs/learning/video-scripts/L00-why-cairnkeep.md +0 -80
  78. package/docs/learning/video-scripts/L01-safe-trial.md +0 -78
  79. package/docs/learning/video-scripts/L02-installation.md +0 -97
  80. package/docs/learning/video-scripts/L03-first-project.md +0 -99
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  description: "Build, rebuild, query, and inspect the project knowledge graph in .planning/graphs/"
3
- argument-hint: "[build [--force]|query <term>|status|diff]"
3
+ argument-hint: "[build [--force]|query <term>|explain <symbol>|path <from> <to>|status|diff]"
4
4
  tools:
5
5
  read: true
6
6
  bash: true
@@ -9,7 +9,9 @@ tools:
9
9
 
10
10
  **STOP -- DO NOT READ THIS FILE. You are already reading it. This prompt was injected into your context by OpenCode's command system. Using the Read tool on this file wastes tokens. Begin executing Step 1 immediately.**
11
11
 
12
- **graphify CLI:** the `graphify` subcommand is exposed by `gsd-tools` (on PATH). Invoke as `gsd-tools graphify …` as documented in this command and in `docs/CLI-TOOLS.md`. Other GSD queries use `gsd-tools <subcmd>` where a handler exists.
12
+ **graph workflow:** Cairnkeep owns this surface through `cairn graph`. The
13
+ operator installs only the isolated `graphify` executable; do not invoke
14
+ Graphify's harness installer.
13
15
 
14
16
  ## Output heading
15
17
 
@@ -17,32 +19,13 @@ Begin the final user-facing response with `GRAPHIFY`. Do not emit a standalone
17
19
  banner before owner I/O: in headless OpenCode, content-only output can end the
18
20
  turn before the command reaches its tools.
19
21
 
20
- ## Step 1 -- Config Gate
22
+ ## Step 1 -- Capability ownership
21
23
 
22
- **First action:** invoke the Read tool for `.planning/config.json`; do not emit
23
- text before this tool call.
24
-
25
- Check if graphify is enabled by reading `.planning/config.json` directly using the Read tool.
26
-
27
- **DO NOT use the gsd-tools config get-value command** -- it hard-exits on missing keys.
28
-
29
- 1. Read `.planning/config.json` using the Read tool
30
- 2. If the file does not exist: display the disabled message below and **STOP**
31
- 3. Parse the JSON content. Check if `config.graphify && config.graphify.enabled === true`
32
- 4. If `graphify.enabled` is NOT explicitly `true`: display the disabled message below and **STOP**
33
- 5. If `graphify.enabled` is `true`: proceed to Step 2
34
-
35
- **Disabled message:**
36
-
37
- ```
38
- GRAPHIFY
39
-
40
- Knowledge graph is disabled. To activate:
41
-
42
- gsd-tools config-set graphify.enabled true
43
-
44
- Then run /graphify build to create the initial graph.
45
- ```
24
+ Do not implement a separate configuration gate in the prompt. Every
25
+ `cairn graph` operation enforces the typed `graph` capability and its legacy
26
+ `graphify.enabled` compatibility default before Graphify or graph-file I/O.
27
+ Proceed directly to Step 2; if the owner reports a disabled capability, display
28
+ its fixed remediation message and **STOP**.
46
29
 
47
30
  ---
48
31
 
@@ -62,6 +45,8 @@ empty or unknown argument. Apply the same exact matching rule to every row:
62
45
  |----------|--------|
63
46
  | `build` or `build --force` | Run inline build (Step 3) |
64
47
  | `query <term>` | Run inline query (Step 2a) |
48
+ | `explain <symbol>` | Explain one exact symbol (Step 2d) |
49
+ | `path <from> <to>` | Find the shortest path between two exact symbols (Step 2e) |
65
50
  | `status` | Run inline status check (Step 2b) |
66
51
  | `diff` | Run inline diff check (Step 2c) |
67
52
  | No argument or unknown | Show usage message |
@@ -76,6 +61,8 @@ Usage: /graphify <mode>
76
61
  Modes:
77
62
  build [--force] Build or rebuild the knowledge graph
78
63
  query <term> Search the graph for a term
64
+ explain <symbol> Explain one exact symbol and its relationships
65
+ path <from> <to> Find the shortest path between two exact symbols
79
66
  status Show graph freshness and statistics
80
67
  diff Show changes since last build
81
68
  ```
@@ -86,29 +73,42 @@ Modes:
86
73
  the result and do not continue until the tool returns:
87
74
 
88
75
  ```bash
89
- gsd-tools graphify query <term>
76
+ cairn graph query <term>
90
77
  ```
91
78
 
92
- Parse the JSON output and display results:
93
- - If the output contains `"disabled": true`, display the disabled message from Step 1 and **STOP**
94
- - If the output contains `"error"` field, display the error message and **STOP**
95
- - If no nodes found, display: `No graph matches for '<term>'. Try /graphify build to create or rebuild the graph.`
96
- - Otherwise, display matched nodes grouped by type, with edge relationships and confidence tiers (EXTRACTED/INFERRED/AMBIGUOUS)
79
+ Pass the parsed term as exactly one argument and display the result verbatim.
80
+ On failure, display the error without retrying or changing configuration.
97
81
 
98
82
  **STOP** after displaying results. Do not spawn an agent.
99
83
 
84
+ ### Step 2d -- Explain
85
+
86
+ **Invoke the shell tool** with `cairn graph explain <symbol>`, passing the
87
+ parsed symbol as exactly one argument. Display Graphify's explanation verbatim.
88
+ On failure, display the error and suggest `/graphify build` only when the
89
+ published graph is missing.
90
+
91
+ **STOP** after displaying the result. Do not spawn an agent.
92
+
93
+ ### Step 2e -- Path
94
+
95
+ **Invoke the shell tool** with `cairn graph path <from> <to>`, passing each
96
+ parsed symbol as exactly one argument. Display Graphify's path result verbatim.
97
+ On failure, display the error and suggest `/graphify build` only when the
98
+ published graph is missing.
99
+
100
+ **STOP** after displaying the result. Do not spawn an agent.
101
+
100
102
  ### Step 2b -- Status
101
103
 
102
104
  **Invoke the shell tool** with this exact command; do not print the command as
103
105
  the result and do not continue until the tool returns:
104
106
 
105
107
  ```bash
106
- gsd-tools graphify status
108
+ cairn graph status
107
109
  ```
108
110
 
109
- Parse the JSON output and display:
110
- - If `exists: false`, display the message field
111
- - Otherwise show last build time, node/edge/hyperedge counts, and STALE or FRESH indicator
111
+ Display the local node/edge counts and freshness result verbatim.
112
112
 
113
113
  **STOP** after displaying status. Do not spawn an agent.
114
114
 
@@ -118,14 +118,11 @@ Parse the JSON output and display:
118
118
  the result and do not continue until the tool returns:
119
119
 
120
120
  ```bash
121
- gsd-tools graphify diff
121
+ cairn graph diff
122
122
  ```
123
123
 
124
- Parse the JSON output and display:
125
- - If `no_baseline: true`, display the message field
126
- - Otherwise show node and edge change counts (added/removed/changed)
127
-
128
- If no snapshot exists, suggest running `build` twice (first to create, second to generate a diff baseline).
124
+ Display the node and edge change counts verbatim. If no snapshot exists,
125
+ suggest rebuilding after the next code change.
129
126
 
130
127
  **STOP** after displaying diff. Do not spawn an agent.
131
128
 
@@ -137,20 +134,14 @@ If no snapshot exists, suggest running `build` twice (first to create, second to
137
134
  the result and do not continue until the tool returns:
138
135
 
139
136
  ```bash
140
- gsd-tools graphify build [--force]
137
+ cairn graph build [--force]
141
138
  ```
142
139
 
143
- Parse the JSON output and display:
144
- - If the output contains `"disabled": true`, display the disabled message from Step 1 and **STOP**
145
- - If the output contains an `"error"` field, display the error and the `stage` field when present, then **STOP**
146
- - Otherwise display the build summary using `status.last_build`, `status.node_count`, `status.edge_count`, `status.hyperedge_count`, whether the snapshot was saved, and whether a forced clean rebuild was used
147
-
148
- This command now performs the full pipeline directly:
149
- - runs `graphify update .` with legacy fallback to `graphify . --update`
150
- - when `--force` is present, clears `graphify-out/`, published graph artifacts, and `.planning/graphs/.last-build-snapshot.json` first
151
- - validates `graphify-out/graph.json`
152
- - copies `graph.json`, `graph.html`, and `GRAPH_REPORT.md` into `.planning/graphs/`
153
- - writes `.planning/graphs/.last-build-snapshot.json`
140
+ Display the build summary verbatim. This managed path runs Graphify's local
141
+ code-only `update`, strips provider credentials from its subprocess
142
+ environment, validates the resulting graph, atomically publishes available
143
+ artifacts into `.planning/graphs/`, and snapshots the previous graph for diff.
144
+ `--force` permits a rebuilt graph with fewer nodes after code deletion.
154
145
 
155
146
  **STOP** after displaying the build result. Do not spawn an agent.
156
147
 
@@ -158,7 +149,6 @@ This command now performs the full pipeline directly:
158
149
 
159
150
  ## Anti-Patterns
160
151
 
161
- 1. DO NOT spawn an agent for graphify operations -- build/query/status/diff are handled directly
152
+ 1. DO NOT spawn an agent for graphify operations -- build/query/explain/path/status/diff are handled directly
162
153
  2. DO NOT modify graph files directly outside the graphify CLI path
163
- 3. DO NOT skip the config gate check
164
- 4. DO NOT use gsd-tools config get-value for the config gate -- it exits on missing keys
154
+ 3. DO NOT duplicate capability parsing in the prompt -- `cairn graph` owns it
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cairnkeep/cli",
3
- "version": "2.6.0",
3
+ "version": "2.8.0",
4
4
  "description": "A durable, harness-agnostic memory + context layer for coding agents and MCP clients.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -18,6 +18,7 @@
18
18
  "claude/",
19
19
  "opencode/",
20
20
  "pi/",
21
+ "kimi/",
21
22
  "examples/anythingllm/",
22
23
  "examples/overlay-distribution/",
23
24
  "examples/eval/",
@@ -0,0 +1,32 @@
1
+ ---
2
+ description: Build, query, and inspect the local project graph through Cairnkeep
3
+ argument-hint: "[build [--force]|query <term>|status|diff|explain <symbol>|path <from> <to>]"
4
+ ---
5
+
6
+ <!-- managed-by:cairnkeep -->
7
+ # Cairnkeep graph
8
+
9
+ Handle this request through Cairnkeep's public graph owner. The invocation
10
+ arguments are:
11
+
12
+ ```text
13
+ $ARGUMENTS
14
+ ```
15
+
16
+ Accept exactly one of these forms:
17
+
18
+ - `build`
19
+ - `build --force`
20
+ - `query <term>`
21
+ - `status`
22
+ - `diff`
23
+ - `explain <symbol>`
24
+ - `path <from> <to>`
25
+
26
+ Invoke the shell tool exactly once with the corresponding `cairn graph ...`
27
+ command. Pass each term or symbol as one safely quoted argument. Return the
28
+ command output verbatim and stop.
29
+
30
+ If the arguments do not match a supported form, show the supported forms and
31
+ stop without invoking a tool. Do not call the Graphify executable, edit graph
32
+ artifacts, spawn another agent, or implement graph logic in this prompt.
@@ -9,7 +9,7 @@
9
9
  "schema_version": { "const": 1 },
10
10
  "experiment_id": { "$ref": "#/$defs/identifier" },
11
11
  "status": { "enum": ["partial", "final"] },
12
- "experiment_kind": { "enum": ["two_pass", "ablation"] },
12
+ "experiment_kind": { "enum": ["two_pass", "ablation", "skill_candidate"] },
13
13
  "task_set_digest": { "$ref": "#/$defs/digest" },
14
14
  "adapter_config_digest": { "$ref": "#/$defs/digest" },
15
15
  "source_revision": { "$ref": "#/$defs/commit" },
@@ -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
+ }
@@ -104,7 +104,8 @@ echo "Next steps (full guide: docs/operating.md):"
104
104
  echo " 1. cp .ai/env.example .ai/.env and edit"
105
105
  echo " 2. Register the memory server: claude mcp add cairn-memory -s user -- cairn memory-server"
106
106
  echo " 3. Install the operating layer (commands/agents/hooks): cairn sync --apply"
107
- echo " For Pi trajectory capture, also run: cairn sync-pi --apply"
107
+ echo " For Pi trajectory + /graphify, also run: cairn sync-pi --apply"
108
+ echo " For Kimi /graphify, also run: cairn sync-kimi --apply"
108
109
  echo " From a source clone, use bin/cairn in place of cairn."
109
110
  echo " 4. Launch: $target/.ai/start-claude.sh"
110
111
  echo " Kimi memory-client launch: $target/.ai/start-kimi.sh"
@@ -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 doctor trajectory artifact capabilities notes eval memory audit-timer uninstall completion version help"
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"
15
15
  if (( COMP_CWORD == 1 )); then
16
16
  COMPREPLY=( $(compgen -W "$commands" -- "$current") )
17
17
  return
@@ -20,6 +20,7 @@ _cairn_complete() {
20
20
  bootstrap) COMPREPLY=( $(compgen -W "--untracked" -- "$current") ) ;;
21
21
  sync) COMPREPLY=( $(compgen -W "--apply --live-root" -- "$current") ) ;;
22
22
  sync-pi) COMPREPLY=( $(compgen -W "--apply --live-root" -- "$current") ) ;;
23
+ sync-kimi) COMPREPLY=( $(compgen -W "--apply --live-root" -- "$current") ) ;;
23
24
  doctor) COMPREPLY=( $(compgen -W "--repair" -- "$current") ) ;;
24
25
  trajectory) COMPREPLY=( $(compgen -W "list show prune --json --dry-run" -- "$current") ) ;;
25
26
  artifact) COMPREPLY=( $(compgen -W "list show delete prune --kind --session --json --dry-run --include-protected" -- "$current") ) ;;
@@ -62,9 +63,11 @@ _cairn_complete() {
62
63
  *) COMPREPLY=( $(compgen -W "validate run ablate report prune delete" -- "$current") ) ;;
63
64
  esac
64
65
  ;;
66
+ 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") ) ;;
67
+ graph) COMPREPLY=( $(compgen -W "build query status diff explain path --force" -- "$current") ) ;;
65
68
  memory) COMPREPLY=( $(compgen -W "path export import" -- "$current") ) ;;
66
69
  audit-timer) COMPREPLY=( $(compgen -W "--on-calendar --para-root --render-only" -- "$current") ) ;;
67
- uninstall) COMPREPLY=( $(compgen -W "--dry-run --yes --purge-memory --live-root --pi-live-root" -- "$current") ) ;;
70
+ uninstall) COMPREPLY=( $(compgen -W "--dry-run --yes --purge-memory --live-root --pi-live-root --kimi-live-root" -- "$current") ) ;;
68
71
  completion) COMPREPLY=( $(compgen -W "bash zsh fish" -- "$current") ) ;;
69
72
  esac
70
73
  }
@@ -80,13 +83,16 @@ _cairn() {
80
83
  'bootstrap:scaffold a project'
81
84
  'memory-server:run the memory MCP server'
82
85
  'sync:install the Claude operating layer'
83
- 'sync-pi:install the Pi trajectory extension'
86
+ 'sync-pi:install the Pi trajectory extension and graph prompt'
87
+ 'sync-kimi:install the Kimi graph Skill'
84
88
  'doctor:check runtime dependencies and endpoints'
85
89
  'trajectory:inspect and prune local session trajectories'
86
90
  'artifact:inspect, delete, and prune local artifacts'
87
91
  'capabilities:inspect and manage project capability state'
88
92
  'notes:distill and search local hindsight notes'
89
93
  'eval:run and inspect default-off local evaluations'
94
+ 'skill:review and evaluate evidence-backed skill improvements'
95
+ 'graph:inspect a published Graphify graph'
90
96
  'memory:manage the durable memory store'
91
97
  'audit-timer:install a memory and wiki audit timer'
92
98
  'uninstall:remove installed Cairnkeep components safely'
@@ -102,6 +108,7 @@ _cairn() {
102
108
  bootstrap) _arguments '--untracked[keep scaffold out of Git]' '*:project directory:_files -/' ;;
103
109
  sync) _arguments '--apply[apply changes]' '--live-root[project Claude root]:directory:_files -/' ;;
104
110
  sync-pi) _arguments '--apply[apply changes]' '--live-root[Pi agent root]:directory:_files -/' ;;
111
+ sync-kimi) _arguments '--apply[apply changes]' '--live-root[Kimi Code root]:directory:_files -/' ;;
105
112
  doctor) _arguments '--repair[repair trajectory metadata and indexes]' ;;
106
113
  trajectory) _values 'trajectory command' list show prune ;;
107
114
  artifact)
@@ -134,9 +141,23 @@ _cairn() {
134
141
  *) _values 'eval command' validate run ablate report prune delete ;;
135
142
  esac
136
143
  ;;
144
+ skill)
145
+ case $words[3] in
146
+ harvest) _arguments '--project[project root]:directory:_files -/' '--minimum-occurrences[minimum recurring failures]:count:' '--json[emit JSON]' ;;
147
+ list) _arguments '--project[project root]:directory:_files -/' '--kind[artifact kind]:kind:(candidate proposal evaluation application)' '--json[emit JSON]' ;;
148
+ show) _arguments '--project[project root]:directory:_files -/' '--kind[artifact kind]:kind:(candidate proposal evaluation application)' '--id[artifact ID]:artifact ID:' '--json[emit JSON]' ;;
149
+ review) _arguments '--project[project root]:directory:_files -/' '--candidate[candidate ID]:candidate ID:' '--approve[approve evidence]' '--json[emit JSON]' ;;
150
+ 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]' ;;
151
+ 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]' ;;
152
+ 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]' ;;
153
+ rollback) _arguments '--project[project root]:directory:_files -/' '--application[application ID]:application ID:' '--confirm[confirm rollback]' '--json[emit JSON]' ;;
154
+ *) _values 'skill command' harvest list show review propose evaluate apply rollback ;;
155
+ esac
156
+ ;;
157
+ graph) _values 'graph command' build query status diff explain path '--force[allow a smaller graph after code deletion]' ;;
137
158
  memory) _values 'memory command' path export import ;;
138
159
  audit-timer) _arguments '--on-calendar[systemd calendar]:calendar:' '--para-root[PARA root]:directory:_files -/' '--render-only[render directory]:directory:_files -/' ;;
139
- 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 -/' '*:project 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 -/' ;;
140
161
  completion) _values 'shell' bash zsh fish ;;
141
162
  *) _arguments '*:argument:_files' ;;
142
163
  esac
@@ -147,13 +168,15 @@ EOF
147
168
  fish)
148
169
  cat <<'EOF'
149
170
  complete -c cairn -f
150
- for command in bootstrap memory-server sync sync-pi doctor trajectory artifact capabilities notes eval memory audit-timer uninstall completion version help
151
- complete -c cairn -n "not __fish_seen_subcommand_from bootstrap memory-server sync sync-pi doctor trajectory artifact capabilities notes eval memory audit-timer uninstall completion version help" -a $command
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
152
173
  end
153
174
  complete -c cairn -n "__fish_seen_subcommand_from sync" -l apply
154
175
  complete -c cairn -n "__fish_seen_subcommand_from sync" -l live-root -r
155
176
  complete -c cairn -n "__fish_seen_subcommand_from sync-pi" -l apply
156
177
  complete -c cairn -n "__fish_seen_subcommand_from sync-pi" -l live-root -r
178
+ complete -c cairn -n "__fish_seen_subcommand_from sync-kimi" -l apply
179
+ complete -c cairn -n "__fish_seen_subcommand_from sync-kimi" -l live-root -r
157
180
  complete -c cairn -n "__fish_seen_subcommand_from bootstrap" -l untracked
158
181
  complete -c cairn -n "__fish_seen_subcommand_from memory" -a "path export import"
159
182
  complete -c cairn -n "__fish_seen_subcommand_from doctor" -l repair
@@ -183,8 +206,34 @@ complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcomma
183
206
  complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from prune" -l older-than-days -r
184
207
  complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from prune delete" -l dry-run
185
208
  complete -c cairn -n "__fish_seen_subcommand_from eval; and __fish_seen_subcommand_from validate run ablate report prune delete" -l json
209
+ 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"
210
+ 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
211
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from harvest list show review propose evaluate apply rollback" -l json
212
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from harvest" -l minimum-occurrences -r
213
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from list show" -l kind -r -a "candidate proposal evaluation application"
214
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from show" -l id -r
215
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from review propose" -l candidate -r
216
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from review" -l approve
217
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from propose" -l target -r
218
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from propose evaluate" -l adapter -r
219
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from propose" -l edit-budget -r
220
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate apply" -l proposal -r
221
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l exploration-task-set -r
222
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l confirmation-task-set -r
223
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l output -r
224
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l repetitions -r
225
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l seed -r
226
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l minimum-improvement -r
227
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from evaluate" -l yes
228
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from apply" -l evaluation -r
229
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from apply" -l confirm -r
230
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from rollback" -l application -r
231
+ complete -c cairn -n "__fish_seen_subcommand_from skill; and __fish_seen_subcommand_from rollback" -l confirm
232
+ complete -c cairn -n "__fish_seen_subcommand_from graph" -a "build query status diff explain path"
233
+ complete -c cairn -n "__fish_seen_subcommand_from graph; and __fish_seen_subcommand_from build" -l force
186
234
  complete -c cairn -n "__fish_seen_subcommand_from completion" -a "bash zsh fish"
187
235
  complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l pi-live-root -r
236
+ complete -c cairn -n "__fish_seen_subcommand_from uninstall" -l kimi-live-root -r
188
237
  EOF
189
238
  ;;
190
239
  *)
@@ -31,6 +31,7 @@ SCRIPTS=(
31
31
  scripts/sync-opencode-explore-assets.sh
32
32
  scripts/sync-opencode-wiki-assets.sh
33
33
  scripts/sync-pi-assets.sh
34
+ scripts/sync-kimi-assets.sh
34
35
  )
35
36
 
36
37
  fails=0
@@ -0,0 +1,77 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+
4
+ usage() {
5
+ cat <<'EOF'
6
+ Usage: sync-kimi-assets.sh [--check|--apply] [--live-root PATH]
7
+
8
+ Compare or sync Cairnkeep's thin graph Skill against the live Kimi Code tree.
9
+
10
+ Options:
11
+ --check Verify managed live assets match the repo copies (default)
12
+ --apply Install managed assets, then verify
13
+ --live-root PATH Override the Kimi Code root (default: $KIMI_CODE_HOME or ~/.kimi-code)
14
+ -h, --help Show this help text
15
+ EOF
16
+ }
17
+
18
+ ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)
19
+ SOURCE_ROOT="$ROOT_DIR/kimi"
20
+ LIVE_ROOT="${KIMI_CODE_HOME:-$HOME/.kimi-code}"
21
+ MODE="check"
22
+ ASSETS=("skills/graphify/SKILL.md")
23
+
24
+ while [[ $# -gt 0 ]]; do
25
+ case "$1" in
26
+ --check) MODE="check"; shift ;;
27
+ --apply) MODE="apply"; shift ;;
28
+ --live-root) LIVE_ROOT="$2"; shift 2 ;;
29
+ -h|--help) usage; exit 0 ;;
30
+ *) echo "Unknown argument: $1" >&2; usage >&2; exit 2 ;;
31
+ esac
32
+ done
33
+
34
+ ensure_sources() {
35
+ local rel
36
+ for rel in "${ASSETS[@]}"; do
37
+ [[ -f "$SOURCE_ROOT/$rel" ]] || {
38
+ echo "Missing repo-managed source asset: $SOURCE_ROOT/$rel" >&2
39
+ return 2
40
+ }
41
+ done
42
+ }
43
+
44
+ check_assets() {
45
+ local rel
46
+ local failed=0
47
+ for rel in "${ASSETS[@]}"; do
48
+ if [[ ! -f "$LIVE_ROOT/$rel" ]]; then
49
+ echo "Missing live Kimi asset under $LIVE_ROOT: $rel" >&2
50
+ failed=1
51
+ elif ! cmp -s "$SOURCE_ROOT/$rel" "$LIVE_ROOT/$rel"; then
52
+ echo "Out-of-sync live Kimi asset under $LIVE_ROOT: $rel" >&2
53
+ failed=1
54
+ fi
55
+ done
56
+ return "$failed"
57
+ }
58
+
59
+ ensure_sources
60
+
61
+ if [[ "$MODE" == "apply" ]]; then
62
+ updated=0
63
+ unchanged=0
64
+ for rel in "${ASSETS[@]}"; do
65
+ mkdir -p "$(dirname "$LIVE_ROOT/$rel")"
66
+ if [[ -f "$LIVE_ROOT/$rel" ]] && cmp -s "$SOURCE_ROOT/$rel" "$LIVE_ROOT/$rel"; then
67
+ unchanged=$((unchanged + 1))
68
+ else
69
+ install -m 0644 "$SOURCE_ROOT/$rel" "$LIVE_ROOT/$rel"
70
+ updated=$((updated + 1))
71
+ fi
72
+ done
73
+ printf 'Applied %s Kimi asset(s); %s already matched.\n' "$updated" "$unchanged"
74
+ fi
75
+
76
+ check_assets
77
+ printf 'Kimi graph Skill is in sync under %s\n' "$LIVE_ROOT"