@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.
- package/CHANGELOG.md +35 -1
- package/README.md +45 -8
- package/bin/cairn +21 -3
- package/claude/commands/graphify.md +46 -55
- package/docs/design/meta-agent.md +39 -35
- package/docs/harness-compatibility.md +13 -5
- package/docs/learning/CURRICULUM-MAP.md +10 -3
- package/docs/learning/FEATURE-GUIDE.md +8 -5
- package/docs/learning/README.md +16 -14
- package/docs/learning/lessons/L00-why-cairnkeep.md +1 -5
- package/docs/learning/lessons/L01-safe-trial.md +3 -7
- package/docs/learning/lessons/L02-installation.md +6 -8
- package/docs/learning/lessons/L03-first-project.md +1 -5
- package/docs/learning/lessons/L04-memory-fundamentals.md +0 -6
- package/docs/learning/lessons/L05-daily-workflow.md +0 -5
- package/docs/learning/lessons/L06-repository-quality.md +0 -6
- package/docs/learning/lessons/L07-privacy-and-storage.md +0 -5
- package/docs/learning/lessons/L08-multiple-machines.md +0 -5
- package/docs/learning/lessons/L09-domain-knowledge.md +0 -5
- package/docs/learning/lessons/L10-context-exploration.md +0 -5
- package/docs/learning/lessons/L11-containers.md +0 -5
- package/docs/learning/lessons/L12-managed-overlays.md +0 -6
- package/docs/learning/lessons/L13-session-evidence.md +0 -6
- package/docs/learning/lessons/L14-typed-memory.md +0 -6
- package/docs/learning/lessons/L15-capability-governance.md +0 -6
- package/docs/learning/lessons/L16-evaluation.md +0 -7
- package/docs/learning/lessons/L17-agent-boundary.md +12 -14
- package/docs/learning/lessons/L18-local-code-graph.md +97 -0
- package/docs/learning/lessons/L19-validated-skill-improvement.md +87 -0
- package/docs/learning/templates/lesson-template.md +0 -4
- package/docs/learning/tracks/evidence-and-evaluation.md +5 -3
- package/docs/learning/tracks/practitioner.md +5 -4
- package/docs/operating.md +102 -9
- package/docs/privacy-and-data-flow.md +42 -0
- package/docs/skill-improvement.md +124 -0
- package/docs/storage.md +25 -0
- package/examples/eval/bundled-fake.json +1 -1
- package/kimi/skills/graphify/SKILL.md +33 -0
- package/mcp-memory-server/dist/capability-registry.js +2 -2
- 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-runner.js +10 -4
- package/mcp-memory-server/dist/eval-schema.js +1 -1
- package/mcp-memory-server/dist/eval-workspace.js +50 -1
- package/mcp-memory-server/dist/graph-cli.js +386 -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 +3 -1
- package/opencode/command/graphify.md +48 -58
- package/package.json +2 -1
- package/pi/prompts/graphify.md +32 -0
- package/schemas/eval-report.schema.json +1 -1
- package/schemas/skill-adapter.schema.json +39 -0
- package/schemas/skill-proposal-protocol.schema.json +97 -0
- package/scripts/bootstrap.sh +2 -1
- package/scripts/completion.sh +55 -6
- package/scripts/smoke-bash32.sh +1 -0
- package/scripts/sync-kimi-assets.sh +77 -0
- package/scripts/sync-pi-assets.sh +52 -31
- package/scripts/test-bootstrap-untracked.sh +21 -0
- package/scripts/test-cli-dispatch.sh +4 -0
- package/scripts/test-completion.sh +16 -0
- package/scripts/test-graph-harness-adapters.sh +46 -0
- package/scripts/test-launcher-hooks.sh +4 -2
- package/scripts/test-learning-docs.sh +13 -11
- package/scripts/test-package-install.sh +24 -0
- package/scripts/test-skill-cli.sh +30 -0
- package/scripts/test-trajectory-hooks.sh +5 -1
- package/scripts/test-uninstall.sh +12 -2
- package/scripts/uninstall.sh +11 -4
- package/templates/graph-policy.md.template +26 -5
- package/docs/learning/PRODUCTION-PLAN.md +0 -153
- package/docs/learning/instructor-guide.md +0 -66
- package/docs/learning/templates/video-script-template.md +0 -50
- package/docs/learning/video-scripts/L00-why-cairnkeep.md +0 -80
- package/docs/learning/video-scripts/L01-safe-trial.md +0 -78
- package/docs/learning/video-scripts/L02-installation.md +0 -97
- 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
|
-
**
|
|
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 --
|
|
22
|
+
## Step 1 -- Capability ownership
|
|
21
23
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
76
|
+
cairn graph query <term>
|
|
90
77
|
```
|
|
91
78
|
|
|
92
|
-
|
|
93
|
-
|
|
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
|
-
|
|
108
|
+
cairn graph status
|
|
107
109
|
```
|
|
108
110
|
|
|
109
|
-
|
|
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
|
-
|
|
121
|
+
cairn graph diff
|
|
122
122
|
```
|
|
123
123
|
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
137
|
+
cairn graph build [--force]
|
|
141
138
|
```
|
|
142
139
|
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
|
|
146
|
-
|
|
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
|
|
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.
|
|
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
|
+
}
|
package/scripts/bootstrap.sh
CHANGED
|
@@ -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
|
|
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"
|
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 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
|
*)
|
package/scripts/smoke-bash32.sh
CHANGED
|
@@ -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"
|