@ainova-systems/intelligence 0.11.0-rc.9 → 0.11.1
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/cli/commands/adapter.sh +46 -6
- package/cli/commands/init.sh +182 -33
- package/cli/commands/package.sh +2 -2
- package/cli/commands/registry.sh +3 -3
- package/cli/commands/status.sh +4 -4
- package/cli/commands/sync.sh +76 -23
- package/cli/commands/update.sh +1 -1
- package/cli/intelligence +18 -3
- package/cli/internal/{upgrade-v2.sh → align-project.sh} +9 -8
- package/cli/internal/check.sh +51 -2
- package/cli/internal/{migrate-v1.sh → convert-legacy.sh} +33 -29
- package/cli/internal/package-add.sh +1 -1
- package/cli/internal/package-list.sh +1 -1
- package/cli/internal/package-remove.sh +1 -1
- package/cli/internal/package-search.sh +1 -1
- package/cli/internal/package-update.sh +1 -1
- package/cli/internal/restore.sh +1 -1
- package/cli/internal/target-state.sh +26 -18
- package/cli/lib/adapter-lifecycle.sh +43 -0
- package/cli/lib/cli-common.sh +12 -8
- package/cli/lib/gitignore.sh +215 -0
- package/cli/lib/manifest.sh +35 -1
- package/cli/lib/onboarding.sh +137 -0
- package/engine/ENGINE_SHA +1 -1
- package/engine/VERSION +1 -1
- package/engine/adapters/_template.sh +19 -2
- package/engine/adapters/agents.sh +14 -3
- package/engine/adapters/claude.sh +15 -0
- package/engine/adapters/codex.sh +11 -1
- package/engine/adapters/copilot.sh +11 -0
- package/engine/adapters/cursor.sh +15 -0
- package/engine/adapters/opencode.sh +13 -2
- package/engine/adapters/pi.sh +18 -5
- package/engine/lib/adapter-contract.sh +100 -0
- package/engine/lib/common.sh +5 -0
- package/engine/lib/contract.sh +2 -2
- package/engine/sync.sh +87 -25
- package/package.json +1 -1
- package/packages/sync/agents/intelligence-architect.md +2 -2
- package/packages/sync/references/adapters.md +51 -7
- package/packages/sync/references/conventions.md +60 -21
- package/packages/sync/references/onboarding-migration.md +87 -0
- package/packages/sync/skills/intelligence-install-adapter/SKILL.md +12 -5
- package/packages/sync/skills/intelligence-learn-from-context/SKILL.md +23 -4
- package/packages/sync/skills/intelligence-learn-from-repository/SKILL.md +94 -38
- package/packages/sync/skills/intelligence-review-skills/SKILL.md +1 -1
- package/packages/sync/skills/intelligence-sync/SKILL.md +9 -1
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Declarative adapter ownership contract shared by the engine and CLI.
|
|
3
|
+
#
|
|
4
|
+
# Every adapter exposes adapter_contract_<name> <configured-output>. The
|
|
5
|
+
# function emits tab-separated records through the helpers below. Keeping the
|
|
6
|
+
# declaration beside sync_to_<name>() makes backup, rollback, git policy and
|
|
7
|
+
# lifecycle checks consume the same ownership model as the writer itself.
|
|
8
|
+
|
|
9
|
+
adapter_contract_version() { printf 'version\t%s\n' "$1"; }
|
|
10
|
+
adapter_contract_requires() { printf 'requires\t%s\n' "$1"; }
|
|
11
|
+
adapter_contract_owned() { printf 'owned\t%s\n' "$1"; }
|
|
12
|
+
adapter_contract_managed() { printf 'managed\t%s\n' "$1"; }
|
|
13
|
+
adapter_contract_legacy() { printf 'legacy\t%s\n' "$1"; }
|
|
14
|
+
adapter_contract_preserve() { printf 'preserve\t%s\n' "$1"; }
|
|
15
|
+
adapter_contract_ignore() { printf 'ignore\t%s\n' "$1"; }
|
|
16
|
+
adapter_contract_include() { printf 'include\t%s\n' "$1"; }
|
|
17
|
+
|
|
18
|
+
adapter_contract_function() {
|
|
19
|
+
printf 'adapter_contract_%s' "$1"
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
# Reject records that could address anything outside the repository. Contract
|
|
23
|
+
# paths are always repo-relative; ignore/include records may contain globs.
|
|
24
|
+
adapter_contract_safe_path() {
|
|
25
|
+
local path="$1"
|
|
26
|
+
case "$path" in
|
|
27
|
+
""|/*|*\\*|[A-Za-z]:*|..|../*|*/../*|*/..|*$'\t'*|*$'\n'*) return 1 ;;
|
|
28
|
+
*) return 0 ;;
|
|
29
|
+
esac
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
adapter_contract_safe_concrete_path() {
|
|
33
|
+
adapter_contract_safe_path "$1" || return 1
|
|
34
|
+
case "$1" in
|
|
35
|
+
*'*'*|*'?'*|*'['*) return 1 ;;
|
|
36
|
+
*) return 0 ;;
|
|
37
|
+
esac
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# adapter_contract_records <adapter-name> <adapter-file> <configured-output>
|
|
41
|
+
# Source and query in a subshell so a project adapter cannot leak shell state
|
|
42
|
+
# into the caller. Project adapters are trusted executable code during sync;
|
|
43
|
+
# the isolation here is for correctness, not a security boundary.
|
|
44
|
+
adapter_contract_records() (
|
|
45
|
+
local name="$1" file="$2" output="$3" fn line kind value saw_version=0
|
|
46
|
+
# shellcheck source=/dev/null
|
|
47
|
+
source "$file"
|
|
48
|
+
fn="$(adapter_contract_function "$name")"
|
|
49
|
+
declare -F "$fn" >/dev/null 2>&1 || {
|
|
50
|
+
echo "ERROR: adapter '$name' has no $fn contract" >&2
|
|
51
|
+
return 1
|
|
52
|
+
}
|
|
53
|
+
while IFS= read -r line; do
|
|
54
|
+
[ -n "$line" ] || continue
|
|
55
|
+
kind="${line%%$'\t'*}"
|
|
56
|
+
if [ "$kind" = "$line" ]; then
|
|
57
|
+
echo "ERROR: adapter '$name' emitted a malformed contract record" >&2
|
|
58
|
+
return 1
|
|
59
|
+
fi
|
|
60
|
+
value="${line#*$'\t'}"
|
|
61
|
+
case "$kind" in
|
|
62
|
+
version)
|
|
63
|
+
[ "$value" = "1" ] || {
|
|
64
|
+
echo "ERROR: adapter '$name' uses unsupported contract version '$value'" >&2
|
|
65
|
+
return 1
|
|
66
|
+
}
|
|
67
|
+
saw_version=1
|
|
68
|
+
;;
|
|
69
|
+
requires)
|
|
70
|
+
case "$value" in
|
|
71
|
+
""|[!abcdefghijklmnopqrstuvwxyz]*|*[!abcdefghijklmnopqrstuvwxyz0123456789_]*)
|
|
72
|
+
echo "ERROR: adapter '$name' declares invalid requirement '$value'" >&2
|
|
73
|
+
return 1
|
|
74
|
+
;;
|
|
75
|
+
esac
|
|
76
|
+
;;
|
|
77
|
+
owned|managed|legacy|preserve)
|
|
78
|
+
adapter_contract_safe_concrete_path "$value" || {
|
|
79
|
+
echo "ERROR: adapter '$name' declares unsafe $kind path '$value'" >&2
|
|
80
|
+
return 1
|
|
81
|
+
}
|
|
82
|
+
;;
|
|
83
|
+
ignore|include)
|
|
84
|
+
adapter_contract_safe_path "$value" || {
|
|
85
|
+
echo "ERROR: adapter '$name' declares unsafe $kind path '$value'" >&2
|
|
86
|
+
return 1
|
|
87
|
+
}
|
|
88
|
+
;;
|
|
89
|
+
*)
|
|
90
|
+
echo "ERROR: adapter '$name' emitted unknown contract record '$kind'" >&2
|
|
91
|
+
return 1
|
|
92
|
+
;;
|
|
93
|
+
esac
|
|
94
|
+
printf '%s\n' "$line"
|
|
95
|
+
done < <("$fn" "$output")
|
|
96
|
+
[ "$saw_version" -eq 1 ] || {
|
|
97
|
+
echo "ERROR: adapter '$name' contract did not declare version 1" >&2
|
|
98
|
+
return 1
|
|
99
|
+
}
|
|
100
|
+
)
|
package/engine/lib/common.sh
CHANGED
|
@@ -806,6 +806,11 @@ warn_unsynced() {
|
|
|
806
806
|
case "$rel_dir" in
|
|
807
807
|
.claude/*|.cursor/*|.github/*|.codex/*|.agents/*|.intelligence/*|*/node_modules/*|*/vendor/*|*/dist/*) continue ;;
|
|
808
808
|
esac
|
|
809
|
+
# Initial onboarding backups are immutable migration evidence, never
|
|
810
|
+
# source directories. Suggesting one would reintroduce legacy content.
|
|
811
|
+
case "/$rel_dir/" in
|
|
812
|
+
*"/$intel_basename/_backup/"*) continue ;;
|
|
813
|
+
esac
|
|
809
814
|
|
|
810
815
|
# Skip ignore/submodule patterns.
|
|
811
816
|
local skip=false
|
package/engine/lib/contract.sh
CHANGED
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
# * the IS_STATUS / IS_RC_* codes every engine flow reports.
|
|
10
10
|
#
|
|
11
11
|
# Schema migrations themselves are NOT here: the CLI owns them behind
|
|
12
|
-
# `intelligence init`, and a
|
|
13
|
-
# engine before `intelligence init` converts it.
|
|
12
|
+
# `intelligence init`, and a legacy Intelligence Sync project is brought forward
|
|
13
|
+
# by its archived engine before `intelligence init` converts it.
|
|
14
14
|
|
|
15
15
|
# The applied-schema version is a managed key in the manifest.
|
|
16
16
|
#
|
package/engine/sync.sh
CHANGED
|
@@ -19,6 +19,7 @@ SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
|
19
19
|
|
|
20
20
|
source "$SCRIPT_DIR/lib/common.sh"
|
|
21
21
|
source "$SCRIPT_DIR/lib/contract.sh"
|
|
22
|
+
source "$SCRIPT_DIR/lib/adapter-contract.sh"
|
|
22
23
|
|
|
23
24
|
if [ -z "${CONFIG_FILE:-}" ] || [ ! -f "${CONFIG_FILE:-}" ]; then
|
|
24
25
|
is_status config-missing "CONFIG_FILE=${CONFIG_FILE:-}"
|
|
@@ -85,31 +86,6 @@ echo " Config: $CONFIG_FILE"
|
|
|
85
86
|
echo " Root: $REPO_ROOT"
|
|
86
87
|
echo ""
|
|
87
88
|
|
|
88
|
-
# Invariant: AGENTS.md is the canonical carrier of always-on rules for
|
|
89
|
-
# Cursor / Copilot / Codex / Pi / opencode (their adapters skip always-on
|
|
90
|
-
# rules to avoid duplication, since each tool reads AGENTS.md natively for
|
|
91
|
-
# baseline project context). If those targets are enabled, `agents` must
|
|
92
|
-
# also be enabled — otherwise always-on rules go nowhere for those tools.
|
|
93
|
-
# Skip the check when the user requested a single target via $TARGET_FILTER:
|
|
94
|
-
# they may be syncing only one IDE intentionally.
|
|
95
|
-
if [ -z "$TARGET_FILTER" ]; then
|
|
96
|
-
agents_enabled=$(is_target_enabled "$CONFIG_FILE" "agents")
|
|
97
|
-
if [ "$agents_enabled" != "1" ]; then
|
|
98
|
-
# AGENTS.md-dependent adapters: any tool whose adapter skips always-on
|
|
99
|
-
# rule emission (because the tool reads AGENTS.md natively) must be
|
|
100
|
-
# listed here. Add new adapters to this list when they ship.
|
|
101
|
-
for tool in cursor copilot codex pi opencode; do
|
|
102
|
-
if [ "$(is_target_enabled "$CONFIG_FILE" "$tool")" = "1" ]; then
|
|
103
|
-
echo "ERROR: targets.$tool is enabled but targets.agents is not." >&2
|
|
104
|
-
echo " $tool relies on AGENTS.md to deliver always-on rules — without it," >&2
|
|
105
|
-
echo " always-on rules would be invisible to $tool." >&2
|
|
106
|
-
echo " Either enable targets.agents in $CONFIG_FILE, or disable targets.$tool." >&2
|
|
107
|
-
exit 1
|
|
108
|
-
fi
|
|
109
|
-
done
|
|
110
|
-
fi
|
|
111
|
-
fi
|
|
112
|
-
|
|
113
89
|
# Lint frontmatter across all source files (rules, agents, skills).
|
|
114
90
|
# Catches issues like unquoted colons that strict YAML consumers reject.
|
|
115
91
|
for section in rules agents skills; do
|
|
@@ -167,6 +143,88 @@ for adapters_dir in "$SCRIPT_DIR/adapters" "$INTELLIGENCE_DIR/adapters"; do
|
|
|
167
143
|
done
|
|
168
144
|
done
|
|
169
145
|
|
|
146
|
+
# Validate every selected adapter contract before any output is touched, then
|
|
147
|
+
# snapshot the declared write-set. If a later adapter fails, the EXIT handler
|
|
148
|
+
# restores all earlier adapter outputs so sync is atomic from the repository's
|
|
149
|
+
# point of view.
|
|
150
|
+
SYNC_TX_DIR="$(mktemp -d -t intelligence-sync-XXXXXX)"
|
|
151
|
+
SYNC_TX_INDEX="$SYNC_TX_DIR/paths.tsv"
|
|
152
|
+
SYNC_TX_SEEN="$SYNC_TX_DIR/seen"
|
|
153
|
+
mkdir -p "$SYNC_TX_DIR/data"
|
|
154
|
+
: > "$SYNC_TX_INDEX"
|
|
155
|
+
: > "$SYNC_TX_SEEN"
|
|
156
|
+
SYNC_TX_ACTIVE=0
|
|
157
|
+
|
|
158
|
+
snapshot_sync_path() {
|
|
159
|
+
local adapter_name="$1" rel="$2" src index present=0
|
|
160
|
+
grep -Fqx -- "$rel" "$SYNC_TX_SEEN" && return 0
|
|
161
|
+
printf '%s\n' "$rel" >> "$SYNC_TX_SEEN"
|
|
162
|
+
validate_output_path "$REPO_ROOT" "$CONFIG_FILE" "$adapter_name" "$REPO_ROOT/$rel"
|
|
163
|
+
index="$(wc -l < "$SYNC_TX_INDEX" | tr -d ' ')"
|
|
164
|
+
src="$REPO_ROOT/$rel"
|
|
165
|
+
if [ -e "$src" ] || [ -L "$src" ]; then
|
|
166
|
+
cp -a "$src" "$SYNC_TX_DIR/data/$index"
|
|
167
|
+
present=1
|
|
168
|
+
fi
|
|
169
|
+
printf '%s\t%s\t%s\n' "$index" "$rel" "$present" >> "$SYNC_TX_INDEX"
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
restore_sync_snapshot() {
|
|
173
|
+
local index rel present dst
|
|
174
|
+
while IFS=$'\t' read -r index rel present; do
|
|
175
|
+
[ -n "$rel" ] || continue
|
|
176
|
+
dst="$REPO_ROOT/$rel"
|
|
177
|
+
rm -rf "$dst"
|
|
178
|
+
if [ "$present" = "1" ]; then
|
|
179
|
+
mkdir -p "$(dirname "$dst")"
|
|
180
|
+
cp -a "$SYNC_TX_DIR/data/$index" "$dst"
|
|
181
|
+
fi
|
|
182
|
+
done < "$SYNC_TX_INDEX"
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
finish_sync_transaction() {
|
|
186
|
+
local rc=$?
|
|
187
|
+
trap - EXIT INT TERM
|
|
188
|
+
set +e
|
|
189
|
+
if [ "${SYNC_TX_ACTIVE:-0}" = "1" ] && [ "$rc" -ne 0 ]; then
|
|
190
|
+
restore_sync_snapshot
|
|
191
|
+
echo "ERROR: sync failed; all adapter-owned paths were restored to their pre-sync state." >&2
|
|
192
|
+
fi
|
|
193
|
+
rm -rf "$SYNC_TX_DIR"
|
|
194
|
+
exit "$rc"
|
|
195
|
+
}
|
|
196
|
+
trap finish_sync_transaction EXIT
|
|
197
|
+
trap 'exit 130' INT TERM
|
|
198
|
+
|
|
199
|
+
preflight_idx=0
|
|
200
|
+
while [ "$preflight_idx" -lt "${#ADAPTERS[@]}" ]; do
|
|
201
|
+
adapter="${ADAPTERS[$preflight_idx]}"
|
|
202
|
+
adapter_file="${ADAPTER_FILES[$preflight_idx]}"
|
|
203
|
+
preflight_idx=$((preflight_idx + 1))
|
|
204
|
+
if [ -n "$TARGET_FILTER" ] && [ "$adapter" != "$TARGET_FILTER" ]; then
|
|
205
|
+
continue
|
|
206
|
+
fi
|
|
207
|
+
[ "$(is_target_enabled "$CONFIG_FILE" "$adapter")" = "1" ] || continue
|
|
208
|
+
output="$(get_target_output "$CONFIG_FILE" "$adapter")"
|
|
209
|
+
[ -n "$output" ] || output=".$adapter"
|
|
210
|
+
validate_output_path "$REPO_ROOT" "$CONFIG_FILE" "$adapter" "$REPO_ROOT/$output"
|
|
211
|
+
records="$(adapter_contract_records "$adapter" "$adapter_file" "$output")" || exit 1
|
|
212
|
+
while IFS=$'\t' read -r kind value; do
|
|
213
|
+
[ "$kind" = "requires" ] || continue
|
|
214
|
+
if [ "$(is_target_enabled "$CONFIG_FILE" "$value")" != "1" ]; then
|
|
215
|
+
echo "ERROR: targets.$adapter requires enabled target '$value'." >&2
|
|
216
|
+
echo " Enable it first: intelligence adapter enable $value" >&2
|
|
217
|
+
exit 1
|
|
218
|
+
fi
|
|
219
|
+
done <<< "$records"
|
|
220
|
+
while IFS=$'\t' read -r kind value; do
|
|
221
|
+
case "$kind" in
|
|
222
|
+
owned|managed) snapshot_sync_path "$adapter" "$value" ;;
|
|
223
|
+
esac
|
|
224
|
+
done <<< "$records"
|
|
225
|
+
done
|
|
226
|
+
SYNC_TX_ACTIVE=1
|
|
227
|
+
|
|
170
228
|
synced=0
|
|
171
229
|
adapter_count=${#ADAPTERS[@]}
|
|
172
230
|
adapter_idx=0
|
|
@@ -224,6 +282,10 @@ if [ $synced -eq 0 ]; then
|
|
|
224
282
|
exit 1
|
|
225
283
|
fi
|
|
226
284
|
|
|
285
|
+
SYNC_TX_ACTIVE=0
|
|
286
|
+
rm -rf "$SYNC_TX_DIR"
|
|
287
|
+
trap - EXIT INT TERM
|
|
288
|
+
|
|
227
289
|
# Warn about unsynced directories
|
|
228
290
|
warn_unsynced "$REPO_ROOT" "$CONFIG_FILE"
|
|
229
291
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainova-systems/intelligence",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.1",
|
|
4
4
|
"description": "Build, version and distribute AI agent intelligence across your organization — one CLI, versioned Intelligence Packages, and a sync engine for Claude Code, Cursor, Copilot, Codex, Pi and OpenCode.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"intelligence": "bin/intelligence.js"
|
|
@@ -46,8 +46,8 @@ The per-artifact checks are procedure, so they live in the meta-skills rather th
|
|
|
46
46
|
| `intelligence-add-rule` / `intelligence-add-agent` / `intelligence-add-skill` | author one artifact |
|
|
47
47
|
| `intelligence-extract-skill` | turn an observed workflow into a skill |
|
|
48
48
|
| `intelligence-review-skills` | audit the layer for duplication, drift, size, hardcoded paths |
|
|
49
|
-
| `intelligence-learn-from-repository` |
|
|
50
|
-
| `intelligence-learn-from-context` | fold
|
|
49
|
+
| `intelligence-learn-from-repository` | recover and complete first-time repository onboarding |
|
|
50
|
+
| `intelligence-learn-from-context` | fold one later session lesson into an established layer |
|
|
51
51
|
| `intelligence-sync` | project the source to every tool channel |
|
|
52
52
|
| `intelligence-update` | interpret and apply the CLI's unified update plan |
|
|
53
53
|
| `intelligence-install-adapter` / `intelligence-uninstall-adapter` | research and manage a tool adapter |
|
|
@@ -42,14 +42,25 @@ To stop syncing a target:
|
|
|
42
42
|
intelligence adapter disable mytool
|
|
43
43
|
```
|
|
44
44
|
|
|
45
|
-
Disabling changes only target state. Generated output is deliberately kept
|
|
45
|
+
Disabling changes only target state. Generated output is deliberately kept so disabling is reversible; the adapter contract identifies its paths for review. A disabled project adapter can be deleted with `intelligence adapter remove mytool`; removal prompts by default, accepts `--apply` for explicit non-interactive use, and also keeps generated output. Built-in adapter source cannot be removed. Use `intelligence adapter list` to inspect source, state and output.
|
|
46
46
|
|
|
47
|
-
## Required
|
|
47
|
+
## Required interface
|
|
48
48
|
|
|
49
|
-
The file name and function
|
|
49
|
+
The file name, contract function and sync function form the adapter's identity:
|
|
50
50
|
|
|
51
51
|
```bash
|
|
52
52
|
# <content-dir>/adapters/mytool.sh
|
|
53
|
+
adapter_contract_mytool() {
|
|
54
|
+
local output="${1%/}"
|
|
55
|
+
adapter_contract_version 1
|
|
56
|
+
adapter_contract_owned "$output/rules"
|
|
57
|
+
adapter_contract_owned "$output/agents"
|
|
58
|
+
adapter_contract_owned "$output/skills"
|
|
59
|
+
adapter_contract_ignore "$output/rules/"
|
|
60
|
+
adapter_contract_ignore "$output/agents/"
|
|
61
|
+
adapter_contract_ignore "$output/skills/"
|
|
62
|
+
}
|
|
63
|
+
|
|
53
64
|
sync_to_mytool() {
|
|
54
65
|
local repo_root="$1"
|
|
55
66
|
local config_file="$2"
|
|
@@ -59,6 +70,30 @@ sync_to_mytool() {
|
|
|
59
70
|
}
|
|
60
71
|
```
|
|
61
72
|
|
|
73
|
+
The contract accepts the configured repo-relative output path and emits only
|
|
74
|
+
records through these helpers:
|
|
75
|
+
|
|
76
|
+
| Record | Meaning |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `adapter_contract_version 1` | Required interface version |
|
|
79
|
+
| `adapter_contract_requires <name>` | Another target that must be enabled for a full sync |
|
|
80
|
+
| `adapter_contract_owned <path>` | Path exclusively regenerated by this adapter |
|
|
81
|
+
| `adapter_contract_managed <path>` | Shared or marker-managed path modified by this adapter |
|
|
82
|
+
| `adapter_contract_legacy <path>` | Pre-Intelligence input backed up, then quarantined for the first transactional render |
|
|
83
|
+
| `adapter_contract_preserve <path>` | Settings or state preserved in place and included in the initial backup |
|
|
84
|
+
| `adapter_contract_ignore <pattern>` | Exact `.gitignore` pattern managed on enable/init |
|
|
85
|
+
| `adapter_contract_include <pattern>` | Exact negated `.gitignore` pattern managed on enable/init |
|
|
86
|
+
|
|
87
|
+
All paths are repository-relative. The CLI refuses missing, malformed, unsafe,
|
|
88
|
+
or unsupported contracts before enabling or syncing an adapter. `owned` and
|
|
89
|
+
`managed` paths form the transactional write-set: if any adapter fails, the
|
|
90
|
+
engine restores every selected adapter path to its pre-sync state.
|
|
91
|
+
|
|
92
|
+
For an existing `.vscodeignore`, `.npmignore`, or `.dockerignore`, enable/init
|
|
93
|
+
also excludes the configured adapter output plus its `owned`, `managed`, and
|
|
94
|
+
`legacy` paths from published or build artifacts. This packaging policy is
|
|
95
|
+
separate from the narrower Git policy expressed by `ignore` and `include`.
|
|
96
|
+
|
|
62
97
|
The engine calls:
|
|
63
98
|
|
|
64
99
|
```text
|
|
@@ -162,7 +197,7 @@ Built-ins currently emit Claude and Cursor Markdown, Copilot `.agent.md`, Codex
|
|
|
162
197
|
|
|
163
198
|
Content shipped in `@ainova-systems/sync` cannot assume the project's content-directory name or package-store location. It uses these tokens:
|
|
164
199
|
|
|
165
|
-
| Token |
|
|
200
|
+
| Token | Expansion |
|
|
166
201
|
|---|---|
|
|
167
202
|
| `<content-dir>` | Project content directory, usually `intelligence` |
|
|
168
203
|
| `<module>` | Installed sync package, usually `.intelligence/packages/@ainova-systems/sync` |
|
|
@@ -177,8 +212,8 @@ Call `finalize_output_file` on every text file after transformation. It expands
|
|
|
177
212
|
|
|
178
213
|
Adapters regenerate output, so cleanup is part of their public contract.
|
|
179
214
|
|
|
180
|
-
1. Delete only paths
|
|
181
|
-
2.
|
|
215
|
+
1. Delete only paths declared `owned`. Preserve sibling settings, commands, extensions, workflows and hand-authored files.
|
|
216
|
+
2. Keep `adapter_contract_<name>()` exactly aligned with every path `sync_to_<name>()` writes or deletes.
|
|
182
217
|
3. Use marker-based cleanup when generated and hand-authored files share a directory. The OpenCode adapter is the reference implementation.
|
|
183
218
|
4. Use `sync_open_skill_dirs` for `.agents/skills/`; multiple adapters share it.
|
|
184
219
|
5. Write only beneath the supplied `output_dir`, except for an explicitly shared standard path handled by a shared helper.
|
|
@@ -211,6 +246,13 @@ sync_mytool_rules() {
|
|
|
211
246
|
done < <(read_yaml_list "$config_file" "rules")
|
|
212
247
|
}
|
|
213
248
|
|
|
249
|
+
adapter_contract_mytool() {
|
|
250
|
+
local output="${1%/}"
|
|
251
|
+
adapter_contract_version 1
|
|
252
|
+
adapter_contract_owned "$output/rules"
|
|
253
|
+
adapter_contract_ignore "$output/rules/"
|
|
254
|
+
}
|
|
255
|
+
|
|
214
256
|
sync_to_mytool() {
|
|
215
257
|
local repo_root="$1" config_file="$2" output_dir="$3"
|
|
216
258
|
|
|
@@ -221,7 +263,7 @@ sync_to_mytool() {
|
|
|
221
263
|
|
|
222
264
|
## Testing
|
|
223
265
|
|
|
224
|
-
Use a disposable Git repository with
|
|
266
|
+
Use a disposable Git repository with an Intelligence manifest and representative always-on/scoped rules, agents, skills and bundled skill resources.
|
|
225
267
|
|
|
226
268
|
```bash
|
|
227
269
|
intelligence sync mytool
|
|
@@ -234,6 +276,8 @@ Verify:
|
|
|
234
276
|
- skill resources are present;
|
|
235
277
|
- no literal layout tokens remain;
|
|
236
278
|
- hand-authored siblings under the tool root survive;
|
|
279
|
+
- a deliberately failing later adapter restores all earlier output byte-for-byte;
|
|
280
|
+
- `intelligence status --check` accepts the contract and its Git policy;
|
|
237
281
|
- output paths cannot overlap sources or escape the repository;
|
|
238
282
|
- a second sync produces no Git diff.
|
|
239
283
|
|
|
@@ -18,7 +18,7 @@ Use these tests:
|
|
|
18
18
|
|
|
19
19
|
Do not bury conventions in agents, workflows in rules or reusable expertise in skills. Each misplaced concern either fails to load when needed or consumes context when it is not needed.
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Intelligence project structure
|
|
22
22
|
|
|
23
23
|
```text
|
|
24
24
|
project/
|
|
@@ -57,7 +57,7 @@ project:
|
|
|
57
57
|
name: payments
|
|
58
58
|
intelligence_dir: "intelligence" # optional; this is the default
|
|
59
59
|
|
|
60
|
-
schema_version: "0.11.
|
|
60
|
+
schema_version: "0.11.1"
|
|
61
61
|
|
|
62
62
|
sources:
|
|
63
63
|
rules:
|
|
@@ -104,7 +104,7 @@ Commit `intelligence.lock`. It records requested versions, source URLs and paths
|
|
|
104
104
|
|
|
105
105
|
Package-owned artifacts cannot assume the project's content-directory name or their installed package path. They use tokens expanded by every adapter through `finalize_output_file`:
|
|
106
106
|
|
|
107
|
-
| Token |
|
|
107
|
+
| Token | Expansion |
|
|
108
108
|
|---|---|
|
|
109
109
|
| `<content-dir>` | Repo-relative content directory, usually `intelligence` |
|
|
110
110
|
| `<module>` | Installed sync package, usually `.intelligence/packages/@ainova-systems/sync` |
|
|
@@ -283,7 +283,7 @@ Size limits are backstops, not quotas:
|
|
|
283
283
|
|
|
284
284
|
Every line enters a finite context budget. Prefer subtraction, consolidation and precise scope over exhaustive prose.
|
|
285
285
|
|
|
286
|
-
## Generated output
|
|
286
|
+
## Generated output and version control
|
|
287
287
|
|
|
288
288
|
| Target | Rules | Skills | Agents |
|
|
289
289
|
|---|---|---|---|
|
|
@@ -297,22 +297,26 @@ Every line enters a finite context budget. Prefer subtraction, consolidation and
|
|
|
297
297
|
|
|
298
298
|
`AGENTS.md` is regenerated by the `agents` adapter. Its optional static header is `targets.agents.header` in `intelligence.yaml`; generated rule, agent and skill sections follow it. Commit `AGENTS.md` when it is the project's shared canonical context.
|
|
299
299
|
|
|
300
|
-
|
|
300
|
+
By default, commit the manifest, lock, project-owned content, `AGENTS.md`, and shared `.github/` output. Ignore the restorable package store and tool output owned by enabled adapters. `intelligence init` and `intelligence adapter enable` add these patterns without ignoring shared tool roots or settings:
|
|
301
301
|
|
|
302
302
|
```gitignore
|
|
303
303
|
# CLI-managed package store
|
|
304
304
|
.intelligence/
|
|
305
305
|
|
|
306
|
-
#
|
|
307
|
-
.
|
|
308
|
-
.
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
.
|
|
312
|
-
|
|
306
|
+
# Local root instructions migrate into project rules; local preferences stay ignored
|
|
307
|
+
CLAUDE.md
|
|
308
|
+
.cursorrules
|
|
309
|
+
|
|
310
|
+
# Generated Claude and Cursor content; shared settings remain trackable
|
|
311
|
+
.claude/*
|
|
312
|
+
!.claude/
|
|
313
|
+
!.claude/settings.json
|
|
314
|
+
.cursor/*
|
|
315
|
+
!.cursor/
|
|
316
|
+
!.cursor/settings.json
|
|
313
317
|
|
|
314
318
|
# Generated open-standard and Codex content
|
|
315
|
-
.agents/
|
|
319
|
+
.agents/skills/
|
|
316
320
|
.codex/agents/
|
|
317
321
|
|
|
318
322
|
# Generated Pi content
|
|
@@ -320,12 +324,47 @@ Generated IDE output may be gitignored when every collaborator can reproduce it
|
|
|
320
324
|
.pi/extensions/intelligence-sync-rules.ts
|
|
321
325
|
.pi/prompts/intelligence-agent-*.md
|
|
322
326
|
|
|
323
|
-
# Generated OpenCode agents.
|
|
324
|
-
#
|
|
327
|
+
# Generated OpenCode agents. Commands share a directory with hand-authored
|
|
328
|
+
# files, so they remain tracked unless the project chooses exact file ignores.
|
|
325
329
|
.opencode/agents/
|
|
326
330
|
```
|
|
327
331
|
|
|
328
|
-
Copilot output lives under `.github
|
|
332
|
+
Copilot output lives under `.github/` and is committed with other repository-level GitHub configuration. Do not ignore `.github/` wholesale. `AGENTS.md` is also committed so every clone has the shared tool-neutral entry point before sync.
|
|
333
|
+
|
|
334
|
+
Git tracking and release packaging are separate policies. When a project
|
|
335
|
+
already has `.vscodeignore`, `.npmignore`, or `.dockerignore`, the CLI appends a
|
|
336
|
+
small idempotent block excluding the package store, `intelligence.yaml`,
|
|
337
|
+
`intelligence.lock`, the complete project content directory, and enabled
|
|
338
|
+
adapter output. Existing entries remain untouched and absent secondary ignore
|
|
339
|
+
files are not created.
|
|
340
|
+
|
|
341
|
+
An ignore rule does not untrack a file already in Git. After init or adapter
|
|
342
|
+
enable, the CLI reports each affected tracked path that remains in the
|
|
343
|
+
worktree with an exact `git rm --cached -- '<path>'` command; this preserves
|
|
344
|
+
the local file while removing it from the index. Legacy root entry points
|
|
345
|
+
quarantined into the initial backup are ordinary worktree deletions to review
|
|
346
|
+
and stage, not candidates for `git rm --cached`.
|
|
347
|
+
|
|
348
|
+
Before release, inspect the packager's actual file list. An npm `files`
|
|
349
|
+
allowlist can force inclusion despite `.npmignore`, and a Dockerfile-specific
|
|
350
|
+
`<name>.Dockerfile.dockerignore` takes precedence over the root
|
|
351
|
+
`.dockerignore`. Use the relevant pack/list command as the final proof rather
|
|
352
|
+
than inferring contents from Git status.
|
|
353
|
+
|
|
354
|
+
`AGENTS.md` is the only shared root instruction entry point. During onboarding,
|
|
355
|
+
move useful repository guidance from legacy root files such as `.cursorrules`
|
|
356
|
+
and instruction-bearing `CLAUDE.md` out of their quarantined backup copies and
|
|
357
|
+
into project-owned rules, then verify the generated tool output. Do not restore
|
|
358
|
+
the original root monolith. Create a new root tool-specific file only when it
|
|
359
|
+
contains genuinely local configuration that an adapter cannot represent; keep
|
|
360
|
+
that exception gitignored rather than maintaining a second committed source.
|
|
361
|
+
|
|
362
|
+
Before the first render, `intelligence init` preserves existing AI prompt paths
|
|
363
|
+
under `<content-dir>/_backup/`. Its `manifest.tsv` labels the snapshot
|
|
364
|
+
`initial-onboarding`, lists exact original paths, and marks legacy entry points.
|
|
365
|
+
Those legacy paths are quarantined only for the transactional first render; a
|
|
366
|
+
failed render restores them, while a successful render leaves them inactive for
|
|
367
|
+
repository learning. The backup remains until the user approves removal.
|
|
329
368
|
|
|
330
369
|
## Project-owned adapters
|
|
331
370
|
|
|
@@ -337,7 +376,7 @@ intelligence adapter create mytool
|
|
|
337
376
|
intelligence adapter enable mytool
|
|
338
377
|
```
|
|
339
378
|
|
|
340
|
-
Project adapters survive CLI upgrades and may override a built-in by name. `intelligence adapter enable mytool` runs a full sync so shared context stays current. `intelligence adapter disable mytool` keeps generated output for explicit
|
|
379
|
+
Project adapters survive CLI upgrades and may override a built-in by name. Each adapter declares a versioned ownership contract beside its sync function; backup, rollback, dependencies and Git policy all consume it. `intelligence adapter enable mytool` runs a full transactional sync so shared context stays current. `intelligence adapter disable mytool` keeps generated output for explicit cleanup; a disabled project adapter can then be deleted with `intelligence adapter remove mytool`. See `adapters.md` for the interface and safety contract.
|
|
341
380
|
|
|
342
381
|
## Schema and command boundaries
|
|
343
382
|
|
|
@@ -345,14 +384,14 @@ The permanent applied-schema key is the top-level scalar `schema_version` in `in
|
|
|
345
384
|
|
|
346
385
|
The public lifecycle is deliberately compact:
|
|
347
386
|
|
|
348
|
-
- `intelligence init [--preview|--apply]` is universal: it creates a new setup, aligns an existing
|
|
349
|
-
- `intelligence sync [adapter]` first aligns an existing
|
|
387
|
+
- `intelligence init [--preview|--apply]` is universal: it creates a new setup, aligns an existing Intelligence project, or plans/applies conversion of an eligible legacy Intelligence Sync project.
|
|
388
|
+
- `intelligence sync [adapter] [--compact]` first aligns an existing Intelligence project with the installed CLI, restores a missing store strictly from `intelligence.lock`, then renders. Compact mode shows only final status on success and all diagnostics on failure. In CI it refuses an alignment that would change tracked files and points to a local `intelligence init --apply` plus review/commit.
|
|
350
389
|
- `intelligence update [@scope/name] [--preview|--apply]` is the only update surface. It prints the CLI/project/package plan; default mode prompts, `--preview` never writes, and `--apply` does not prompt. It never moves `ref:` pins.
|
|
351
390
|
- `intelligence package add|remove|list|search` owns package inventory.
|
|
352
391
|
- `intelligence adapter list|create|enable|disable|remove` owns adapter inventory and target state.
|
|
353
392
|
- `intelligence status [--check]` reports state; `--check` runs deep consistency checks.
|
|
354
393
|
|
|
355
|
-
Implement
|
|
394
|
+
Implement Intelligence schema changes as idempotent structural checks. Stage and verify replacement state before deleting or replacing prior state. A stale engine refuses a manifest whose `schema_version` is newer; normal project entry points close a behind-project gap through lifecycle preflight.
|
|
356
395
|
|
|
357
396
|
Breaking changelog entries use a `### Breaking` checklist of verifiable post-conditions. The update skill reads every release across the version gap, chooses the package/CLI/project command sequence and verifies those conditions after the deterministic command completes.
|
|
358
397
|
|
|
@@ -382,4 +421,4 @@ Callers capture the real code with `command || rc=$?`. Do not use `if ! command;
|
|
|
382
421
|
| `<content-dir>/{rules,agents,skills,adapters}/` | Project source of truth | Tracked |
|
|
383
422
|
| `.intelligence/` | Restorable package store | Ignored |
|
|
384
423
|
| `AGENTS.md` | Generated canonical project context | Normally tracked |
|
|
385
|
-
| Tool output directories | Generated native content |
|
|
424
|
+
| Tool output directories | Generated native content | Built-in adapter-owned paths ignored; shared settings tracked |
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# Migrating Existing AI Instructions
|
|
2
|
+
|
|
3
|
+
Read this reference only when repository onboarding finds pre-existing AI
|
|
4
|
+
instructions, an `<content-dir>/_backup/` created by `intelligence init`, or a
|
|
5
|
+
Git diff showing that the first sync replaced tracked tool output.
|
|
6
|
+
|
|
7
|
+
## Inventory and recovery
|
|
8
|
+
|
|
9
|
+
When `<content-dir>/_backup/manifest.tsv` contains
|
|
10
|
+
`state<TAB>initial-onboarding`, it is the authoritative inventory from before
|
|
11
|
+
the first generated write. Read each `target`, `path`, and `legacy` record
|
|
12
|
+
before looking at current adapter output. A `legacy` record means the CLI
|
|
13
|
+
quarantined that active entry point before the first successful render. If
|
|
14
|
+
`path<TAB>AGENTS.md` is present, the backed-up
|
|
15
|
+
file is the original custom project contract; keep following it while deciding
|
|
16
|
+
how to migrate its durable guidance.
|
|
17
|
+
|
|
18
|
+
Treat these as migration inputs, not as current generated output:
|
|
19
|
+
|
|
20
|
+
- root `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, and
|
|
21
|
+
`.github/copilot-instructions.md`;
|
|
22
|
+
- Claude and Cursor rules, agents, skills, and commands;
|
|
23
|
+
- Copilot instructions, prompts, agents, and skills;
|
|
24
|
+
- Codex/Open Agent Skills, Pi rules/prompts, and OpenCode agents/commands;
|
|
25
|
+
- scripts or documentation that describe an older sync path.
|
|
26
|
+
|
|
27
|
+
Prefer the copy under `<content-dir>/_backup/`; do not restore quarantined root
|
|
28
|
+
monoliths as active instructions. If the backup is absent and the first
|
|
29
|
+
sync changed tracked files, inspect their pre-sync content read-only through
|
|
30
|
+
Git (`git diff` and `git show HEAD:<path>`). Never restore old content directly
|
|
31
|
+
into an adapter output directory.
|
|
32
|
+
|
|
33
|
+
Build one conflict report before proposing changes:
|
|
34
|
+
|
|
35
|
+
- `MIGRATE`: instruction-bearing files whose useful content needs a
|
|
36
|
+
project-owned destination;
|
|
37
|
+
- `PRESERVE`: settings and unrelated shared files the adapters do not own;
|
|
38
|
+
- `REPLACE`: adapter-owned paths that sync regenerates;
|
|
39
|
+
- `STALE`: references to removed paths or commands requiring a decision.
|
|
40
|
+
|
|
41
|
+
Always preserve `.claude/settings.json`, `.claude/settings.local.json`,
|
|
42
|
+
`.cursor/settings.json`, Git metadata, workflows, and non-AI repository files.
|
|
43
|
+
|
|
44
|
+
## Reverse mappings
|
|
45
|
+
|
|
46
|
+
Migrate meaning, not tool syntax:
|
|
47
|
+
|
|
48
|
+
| Existing format | Project-owned destination |
|
|
49
|
+
|---|---|
|
|
50
|
+
| Root `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, Copilot root instructions | Split verified guidance by topic into rules; keep local machine preferences in a gitignored root file only when no adapter representation exists |
|
|
51
|
+
| `.claude/rules/*.md` | Rule; preserve valid `paths:` |
|
|
52
|
+
| `.cursor/rules/*.mdc` | Rule; rename `globs:` to `paths:` and remove `alwaysApply:` |
|
|
53
|
+
| Claude/Cursor/Copilot agents | Agent; map native model/readonly/tool fields back to `tier:` and `access:` |
|
|
54
|
+
| Claude/Cursor/Copilot skills or commands | Skill when the procedure is repeated, multi-step, stable, and verifiable; otherwise a rule or no artifact |
|
|
55
|
+
| Pi/OpenCode/Codex prompt artifacts | Rule, agent, or skill according to responsibility, after removing tool-specific wrappers |
|
|
56
|
+
|
|
57
|
+
Verify every retained claim against repository code or executable
|
|
58
|
+
configuration. Do not preserve stale instructions merely because they existed.
|
|
59
|
+
Prefer updating an existing project-owned artifact to creating a sibling.
|
|
60
|
+
|
|
61
|
+
## Apply and cleanup
|
|
62
|
+
|
|
63
|
+
Obtain approval per `CREATE`, `UPDATE`, `REMOVE`, or `KEEP` proposal. Apply
|
|
64
|
+
project-owned source changes first, then run `intelligence sync` and
|
|
65
|
+
`intelligence status --check`. Inspect the enabled targets to prove the
|
|
66
|
+
migrated guidance arrived and verify quarantined old root instructions remain
|
|
67
|
+
absent. Create a new root tool file only from a separately approved, genuinely
|
|
68
|
+
machine-local subset that has no adapter representation; never restore the
|
|
69
|
+
original instruction monolith.
|
|
70
|
+
|
|
71
|
+
For every removed or renamed path, search all tracked files with `git ls-files`
|
|
72
|
+
and report remaining references with file and line number. Apply an unambiguous
|
|
73
|
+
replacement directly; ask about narrative or otherwise ambiguous references.
|
|
74
|
+
|
|
75
|
+
The CLI owns generated-output `.gitignore` entries and its blocks in existing
|
|
76
|
+
`.vscodeignore`, `.npmignore`, and `.dockerignore` files. Verify them against
|
|
77
|
+
the enabled adapters. Treat CLI-reported tracked ignored paths that still exist
|
|
78
|
+
locally as unresolved until the user approves the exact `git rm --cached`
|
|
79
|
+
commands. A quarantined tracked legacy path is already a worktree deletion;
|
|
80
|
+
review and stage that deletion normally instead of using `git rm --cached`. Preserve
|
|
81
|
+
`AGENTS.md`, `.github/`, shared settings, and unrelated files under shared tool
|
|
82
|
+
roots in Git, while excluding development-only Intelligence content from
|
|
83
|
+
published artifacts. Inspect the packager's actual file list before release;
|
|
84
|
+
do not infer package or Docker context contents from Git status.
|
|
85
|
+
|
|
86
|
+
Keep `<content-dir>/_backup/` until the user separately approves its removal
|
|
87
|
+
after migration and reference checks pass. The backup remains gitignored.
|