@ainova-systems/intelligence 0.11.0-rc.8 → 0.11.0-rc.9
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/README.md +4 -0
- package/cli/internal/check.sh +7 -18
- package/cli/internal/migrate-v1.sh +3 -5
- package/cli/internal/package-add.sh +8 -13
- package/cli/internal/package-update.sh +30 -24
- package/cli/internal/restore.sh +4 -15
- package/cli/internal/upgrade-v2.sh +26 -1
- package/cli/lib/cli-common.sh +16 -12
- package/cli/lib/manifest.sh +23 -0
- package/engine/ENGINE_SHA +1 -1
- package/package.json +1 -1
- package/packages/sync/references/conventions.md +2 -2
package/README.md
CHANGED
|
@@ -42,4 +42,8 @@ intelligence sync
|
|
|
42
42
|
|
|
43
43
|
Any git repo with `rules/`, `agents/` or `skills/` at its root is already an Intelligence Package: install it from an explicit source — `intelligence package add github:your-org/your-repo` — with versions from its `x.y.z` git tags. Names (`@scope/name`) resolve only through registries this project explicitly trusts; a monorepo of packages needs one line in such an index.
|
|
44
44
|
|
|
45
|
+
Every package has the same compact manifest entry: requested `version` or
|
|
46
|
+
`ref` only. Repository URL/path, resolved tag/ref and commit SHA are recorded
|
|
47
|
+
in the committed `intelligence.lock`.
|
|
48
|
+
|
|
45
49
|
Requires `git` (and on Windows the bash it ships with — Git for Windows). Engine and docs: [ainova-systems/intelligence](https://github.com/ainova-systems/intelligence).
|
package/cli/internal/check.sh
CHANGED
|
@@ -57,9 +57,9 @@ if [ -d "$IP_ROOT/.intelligence/engine" ]; then
|
|
|
57
57
|
warn "stale .intelligence/engine directory (pre-package layout) — run 'intelligence init'"
|
|
58
58
|
fi
|
|
59
59
|
|
|
60
|
-
# Manifest packages: names valid,
|
|
61
|
-
#
|
|
62
|
-
#
|
|
60
|
+
# Manifest packages: names valid, requested intent only, locked and installed.
|
|
61
|
+
# The lock is authoritative for resolved source URL/path until an explicit
|
|
62
|
+
# package re-add changes that trust decision.
|
|
63
63
|
while IFS= read -r name; do
|
|
64
64
|
[ -n "$name" ] || continue
|
|
65
65
|
assert_valid_pkg_name "$name"
|
|
@@ -68,32 +68,21 @@ while IFS= read -r name; do
|
|
|
68
68
|
else
|
|
69
69
|
m_ver="$(qmap_field "$manifest" "packages" "$name" "version")"
|
|
70
70
|
m_ref="$(qmap_field "$manifest" "packages" "$name" "ref")"
|
|
71
|
-
m_url="$(qmap_field "$manifest" "packages" "$name" "url")"
|
|
72
|
-
m_path="$(qmap_field "$manifest" "packages" "$name" "path")"
|
|
73
71
|
l_req="$(qmap_field "$lock" "packages" "$name" "requested")"
|
|
74
72
|
l_res="$(qmap_field "$lock" "packages" "$name" "resolved")"
|
|
75
|
-
l_url="$(qmap_field "$lock" "packages" "$name" "url")"
|
|
76
|
-
l_path="$(qmap_field "$lock" "packages" "$name" "path")"
|
|
77
73
|
[ -z "$m_ver" ] || [ "$m_ver" = "$l_req" ] \
|
|
78
74
|
|| warn "$name requests '$m_ver' but the lock recorded '$l_req' — run 'intelligence update --preview'"
|
|
79
75
|
[ -z "$m_ref" ] || [ "$m_ref" = "$l_res" ] \
|
|
80
76
|
|| warn "$name pins ref '$m_ref' but the lock resolved '$l_res'"
|
|
81
|
-
[ -
|
|
82
|
-
||
|
|
83
|
-
|
|
84
|
-
|
|
77
|
+
if [ -n "$(qmap_field "$manifest" "packages" "$name" "url")" ] \
|
|
78
|
+
|| [ -n "$(qmap_field "$manifest" "packages" "$name" "path")" ]; then
|
|
79
|
+
warn "$name stores source details in the manifest — run 'intelligence init --apply' to move them to the lock-only model"
|
|
80
|
+
fi
|
|
85
81
|
if [ ! -d "$IP_ROOT/.intelligence/packages/$name" ]; then
|
|
86
82
|
warn "$name is locked but not installed — run 'intelligence sync'"
|
|
87
83
|
continue
|
|
88
84
|
fi
|
|
89
85
|
ok "$name @ $(qmap_field "$lock" "packages" "$name" "resolved")"
|
|
90
|
-
if [ -z "$(qmap_field "$manifest" "packages" "$name" "url")" ]; then
|
|
91
|
-
locked_url="$(qmap_field "$lock" "packages" "$name" "url")"
|
|
92
|
-
resolve_package_source "$manifest" "$name" 2>/dev/null || true
|
|
93
|
-
if [ -n "${RES_URL:-}" ] && [ -n "$locked_url" ] && [ "$RES_URL" != "$locked_url" ]; then
|
|
94
|
-
warn "$name now resolves to $RES_URL but the lock pins $locked_url — a registry re-pointed the name; verify with 'intelligence update --preview'"
|
|
95
|
-
fi
|
|
96
|
-
fi
|
|
97
86
|
fi
|
|
98
87
|
done < <(qmap_keys "$manifest" "packages")
|
|
99
88
|
|
|
@@ -194,6 +194,7 @@ while IFS="$LOCK_SEP" read -r pack name url ref mirror; do
|
|
|
194
194
|
if [ -z "$sha" ] || [ "$sha" = "unknown" ]; then
|
|
195
195
|
sha="$(GIT_TERMINAL_PROMPT=0 git ls-remote -- "$url" "$ref" 2>/dev/null | awk '{print $1; exit}')"
|
|
196
196
|
fi
|
|
197
|
+
[ -n "$ref" ] || ref="HEAD"
|
|
197
198
|
printf '%s\037%s\037%s\037%s\037%s\037%s\n' \
|
|
198
199
|
"$name" "" "$url" "" "$ref" "$sha" >> "$lock_rows"
|
|
199
200
|
done < "$pack_rows"
|
|
@@ -261,17 +262,14 @@ while IFS= read -r line || [ -n "$line" ]; do
|
|
|
261
262
|
done < "$config" > "$manifest_stage"
|
|
262
263
|
stamp_schema_version "$manifest_stage" "$eng"
|
|
263
264
|
|
|
264
|
-
# packages:
|
|
265
|
+
# packages: requested pins only; resolved source details live in the lock.
|
|
265
266
|
while IFS="$LOCK_SEP" read -r pack name url ref mirror; do
|
|
266
267
|
[ -n "$pack" ] || continue
|
|
267
|
-
qmap_set "$manifest_stage" "packages" "$name" "
|
|
268
|
-
[ -n "$ref" ] && qmap_set "$manifest_stage" "packages" "$name" "ref" "$ref"
|
|
268
|
+
qmap_set "$manifest_stage" "packages" "$name" "ref" "${ref:-HEAD}"
|
|
269
269
|
done < "$pack_rows"
|
|
270
270
|
|
|
271
271
|
# The engine's own content rides along as a package, pinned to the engine.
|
|
272
272
|
qmap_set "$manifest_stage" "packages" "$SYNC_PKG_NAME" "version" "$eng"
|
|
273
|
-
qmap_set "$manifest_stage" "packages" "$SYNC_PKG_NAME" "url" "$SYNC_PKG_URL"
|
|
274
|
-
qmap_set "$manifest_stage" "packages" "$SYNC_PKG_NAME" "path" "$SYNC_PKG_PATH"
|
|
275
273
|
printf '%s\037%s\037%s\037%s\037%s\037%s\n' \
|
|
276
274
|
"$SYNC_PKG_NAME" "$eng" "$SYNC_PKG_URL" "$SYNC_PKG_PATH" "v$eng" "$sync_pkg_sha" >> "$lock_rows"
|
|
277
275
|
|
|
@@ -117,6 +117,7 @@ if [ -z "$ref" ]; then
|
|
|
117
117
|
die "'$name' has no stable version tags at $url — a registry package must be versioned; use github:/git+ with @<ref> to pin a branch or commit"
|
|
118
118
|
fi
|
|
119
119
|
echo " NOTE: no version tags at $url — pinning the default branch head" >&2
|
|
120
|
+
ref="HEAD"
|
|
120
121
|
fi
|
|
121
122
|
fi
|
|
122
123
|
|
|
@@ -125,22 +126,16 @@ sha="$(fetch_package "$url" "${ref:-$resolved_tag}" "$path" "$IP_ROOT/$rel")"
|
|
|
125
126
|
|
|
126
127
|
wire_package_sources "$manifest" "$name" "$rel" "$IP_ROOT"
|
|
127
128
|
|
|
128
|
-
#
|
|
129
|
-
#
|
|
130
|
-
#
|
|
131
|
-
# fields behind (a stale ref: would freeze update, a stale url: would pin the
|
|
132
|
-
# old source).
|
|
129
|
+
# The manifest records requested intent only. The resolved source URL/path,
|
|
130
|
+
# tag/ref and SHA live in the required lock. Re-adding a package is the
|
|
131
|
+
# explicit operation for changing its trusted source.
|
|
133
132
|
qmap_delete_key "$manifest" "packages" "$name"
|
|
134
|
-
if [ "$
|
|
133
|
+
if [ -n "$ref" ]; then
|
|
134
|
+
qmap_set "$manifest" "packages" "$name" "ref" "$ref"
|
|
135
|
+
elif [ -n "$requested" ]; then
|
|
135
136
|
qmap_set "$manifest" "packages" "$name" "version" "$requested"
|
|
136
137
|
else
|
|
137
|
-
|
|
138
|
-
[ -n "$path" ] && qmap_set "$manifest" "packages" "$name" "path" "$path"
|
|
139
|
-
if [ -n "$ref" ]; then
|
|
140
|
-
qmap_set "$manifest" "packages" "$name" "ref" "$ref"
|
|
141
|
-
elif [ -n "$requested" ]; then
|
|
142
|
-
qmap_set "$manifest" "packages" "$name" "version" "$requested"
|
|
143
|
-
fi
|
|
138
|
+
die "internal: package '$name' has neither a requested version nor ref"
|
|
144
139
|
fi
|
|
145
140
|
|
|
146
141
|
lock_upsert "$lock" "$name" "$requested" "$url" "$path" "${ref:-$resolved_tag}" "$sha"
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
# Internal package range update operation.
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
#
|
|
4
|
+
# Resolve requested versions/refs against each package's locked source and
|
|
5
|
+
# rewrite the lock. `update <name>` limits the pass to one package; re-adding
|
|
6
|
+
# is the explicit operation for changing a source URL/path.
|
|
7
7
|
set -euo pipefail
|
|
8
8
|
source "$CLI_DIR/lib/cli-common.sh"
|
|
9
9
|
|
|
@@ -35,30 +35,36 @@ while IFS= read -r name; do
|
|
|
35
35
|
echo " $name: engine content follows the installed CLI — skipped"
|
|
36
36
|
continue
|
|
37
37
|
fi
|
|
38
|
+
current="$(qmap_field "$lock" "packages" "$name" "resolved")"
|
|
39
|
+
locked_requested="$(qmap_field "$lock" "packages" "$name" "requested")"
|
|
40
|
+
url="$(qmap_field "$lock" "packages" "$name" "url")"
|
|
41
|
+
path="$(qmap_field "$lock" "packages" "$name" "path")"
|
|
42
|
+
[ -n "$url" ] || die "$name has no source in intelligence.lock — restore the committed lock or re-add the package"
|
|
38
43
|
ref="$(qmap_field "$manifest" "packages" "$name" "ref")"
|
|
39
|
-
[ -n "$ref" ] && { echo " $name: pinned to ref '$ref' — skipped"; continue; }
|
|
40
44
|
range="$(qmap_field "$manifest" "packages" "$name" "version")"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
[ -n "$ref" ] || [ -n "$range" ] || die "$name has neither version nor ref in the manifest"
|
|
46
|
+
|
|
47
|
+
if [ -n "$ref" ]; then
|
|
48
|
+
tag="$ref"
|
|
49
|
+
requested=""
|
|
50
|
+
else
|
|
51
|
+
picked="$(list_remote_versions "$url" | semver_pick_highest "$range")"
|
|
52
|
+
[ -n "$picked" ] || { echo " $name: nothing satisfies '$range' at $url" >&2; continue; }
|
|
53
|
+
read -r tag _ <<< "$(remote_tag_for_version "$url" "$picked")"
|
|
54
|
+
requested="$range"
|
|
45
55
|
fi
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
if [ "$tag" = "$current" ] && [ "$requested" != "$locked_requested" ]; then
|
|
57
|
+
if [ "$preview" -eq 1 ]; then
|
|
58
|
+
echo " $name: request ${locked_requested:-<none>} -> ${requested:-<ref>} (keeps $current)"
|
|
59
|
+
else
|
|
60
|
+
locked_sha="$(qmap_field "$lock" "packages" "$name" "sha")"
|
|
61
|
+
lock_upsert "$lock" "$name" "$requested" "$url" "$path" "$current" "$locked_sha"
|
|
62
|
+
echo " $name: request ${locked_requested:-<none>} -> ${requested:-<ref>} (kept $current)"
|
|
63
|
+
fi
|
|
64
|
+
moved=$((moved + 1))
|
|
65
|
+
continue
|
|
51
66
|
fi
|
|
52
|
-
|
|
53
|
-
[ -n "$picked" ] || { echo " $name: nothing satisfies '${range:-*}' at $url" >&2; continue; }
|
|
54
|
-
read -r tag _ <<< "$(remote_tag_for_version "$url" "$picked")"
|
|
55
|
-
current="$(qmap_field "$lock" "packages" "$name" "resolved")"
|
|
56
|
-
cur_url="$(qmap_field "$lock" "packages" "$name" "url")"
|
|
57
|
-
cur_path="$(qmap_field "$lock" "packages" "$name" "path")"
|
|
58
|
-
# Same tag is not enough: a registry may re-point a name's source while
|
|
59
|
-
# keeping the version — the move doctor warns about must be actionable
|
|
60
|
-
# here, so url/path changes refetch too.
|
|
61
|
-
if [ "$tag" = "$current" ] && [ "$url" = "$cur_url" ] && [ "$path" = "$cur_path" ]; then
|
|
67
|
+
if [ "$tag" = "$current" ]; then
|
|
62
68
|
echo " $name: ${current:-<none>} (up to date)"
|
|
63
69
|
continue
|
|
64
70
|
fi
|
|
@@ -80,7 +86,7 @@ while IFS= read -r name; do
|
|
|
80
86
|
mkdir -p "$(dirname "$IP_ROOT/$rel")"
|
|
81
87
|
mv "$staging" "$IP_ROOT/$rel"
|
|
82
88
|
wire_package_sources "$manifest" "$name" "$rel" "$IP_ROOT"
|
|
83
|
-
lock_upsert "$lock" "$name" "$
|
|
89
|
+
lock_upsert "$lock" "$name" "$requested" "$url" "$path" "$tag" "$sha"
|
|
84
90
|
echo " $name: ${current:-<none>} -> $tag"
|
|
85
91
|
moved=$((moved + 1))
|
|
86
92
|
done < <(qmap_keys "$manifest" "packages")
|
package/cli/internal/restore.sh
CHANGED
|
@@ -23,7 +23,7 @@ manifest="$IP_ROOT/intelligence.yaml"
|
|
|
23
23
|
lock="$IP_ROOT/intelligence.lock"
|
|
24
24
|
|
|
25
25
|
# --frozen is the reproducibility contract: the lock must agree with the
|
|
26
|
-
# manifest on the package SET and on every requested-
|
|
26
|
+
# manifest on the package SET and on every requested-intent field before a
|
|
27
27
|
# single byte is restored. Anything less lets a manifest edit ride on a stale
|
|
28
28
|
# lock — the exact drift the flag exists to refuse.
|
|
29
29
|
if [ "$frozen" -eq 1 ]; then
|
|
@@ -33,20 +33,12 @@ if [ "$frozen" -eq 1 ]; then
|
|
|
33
33
|
|| die "locked restore: $name is in the manifest but not in intelligence.lock"
|
|
34
34
|
m_ver="$(qmap_field "$manifest" "packages" "$name" "version")"
|
|
35
35
|
m_ref="$(qmap_field "$manifest" "packages" "$name" "ref")"
|
|
36
|
-
m_url="$(qmap_field "$manifest" "packages" "$name" "url")"
|
|
37
|
-
m_path="$(qmap_field "$manifest" "packages" "$name" "path")"
|
|
38
36
|
l_req="$(qmap_field "$lock" "packages" "$name" "requested")"
|
|
39
37
|
l_res="$(qmap_field "$lock" "packages" "$name" "resolved")"
|
|
40
|
-
l_url="$(qmap_field "$lock" "packages" "$name" "url")"
|
|
41
|
-
l_path="$(qmap_field "$lock" "packages" "$name" "path")"
|
|
42
38
|
[ -z "$m_ver" ] || [ "$m_ver" = "$l_req" ] \
|
|
43
39
|
|| die "locked restore: $name requests '$m_ver' but the lock recorded '$l_req' — reconcile the manifest and lock"
|
|
44
40
|
[ -z "$m_ref" ] || [ "$m_ref" = "$l_res" ] \
|
|
45
41
|
|| die "--frozen: $name pins ref '$m_ref' but the lock resolved '$l_res'"
|
|
46
|
-
[ -z "$m_url" ] || [ "$m_url" = "$l_url" ] \
|
|
47
|
-
|| die "--frozen: $name declares url '$m_url' but the lock recorded '$l_url'"
|
|
48
|
-
[ -z "$m_path" ] || [ "$m_path" = "$l_path" ] \
|
|
49
|
-
|| die "--frozen: $name declares path '$m_path' but the lock recorded '$l_path'"
|
|
50
42
|
done < <(qmap_keys "$manifest" "packages")
|
|
51
43
|
while IFS= read -r name; do
|
|
52
44
|
[ -n "$name" ] || continue
|
|
@@ -76,14 +68,11 @@ if [ -n "$missing" ]; then
|
|
|
76
68
|
sync_pkg_install "$IP_ROOT"
|
|
77
69
|
continue
|
|
78
70
|
fi
|
|
79
|
-
url="$(qmap_field "$manifest" "packages" "$name" "url")"
|
|
80
|
-
path="$(qmap_field "$manifest" "packages" "$name" "path")"
|
|
81
71
|
ref="$(qmap_field "$manifest" "packages" "$name" "ref")"
|
|
82
72
|
range="$(qmap_field "$manifest" "packages" "$name" "version")"
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
fi
|
|
73
|
+
resolve_package_source "$manifest" "$name"
|
|
74
|
+
url="$RES_URL"; path="$RES_PATH"
|
|
75
|
+
[ -n "$url" ] || die "no trusted registry declares '$name' and it is absent from intelligence.lock"
|
|
87
76
|
resolved_tag=""
|
|
88
77
|
if [ -z "$ref" ]; then
|
|
89
78
|
picked="$(list_remote_versions "$url" | semver_pick_highest "$range")"
|
|
@@ -49,7 +49,32 @@ if [ -n "$legacy_stamp" ]; then
|
|
|
49
49
|
echo " migrating: sync_version -> schema_version"
|
|
50
50
|
fi
|
|
51
51
|
|
|
52
|
-
# v2 migration 1:
|
|
52
|
+
# v2 migration 1: package entries contain requested intent only. Early RCs
|
|
53
|
+
# also copied resolved url/path into the manifest. Preserve the existing lock
|
|
54
|
+
# as the trusted source and remove that duplicate representation. A direct
|
|
55
|
+
# unversioned package becomes an explicit HEAD pin so its manifest entry stays
|
|
56
|
+
# meaningful after the source fields are removed.
|
|
57
|
+
source_fields_migrated=0
|
|
58
|
+
while IFS= read -r name; do
|
|
59
|
+
[ -n "$name" ] || continue
|
|
60
|
+
m_url="$(qmap_field "$manifest" "packages" "$name" "url")"
|
|
61
|
+
m_path="$(qmap_field "$manifest" "packages" "$name" "path")"
|
|
62
|
+
[ -n "$m_url" ] || [ -n "$m_path" ] || continue
|
|
63
|
+
m_ver="$(qmap_field "$manifest" "packages" "$name" "version")"
|
|
64
|
+
m_ref="$(qmap_field "$manifest" "packages" "$name" "ref")"
|
|
65
|
+
if [ -z "$m_ver" ] && [ -z "$m_ref" ]; then
|
|
66
|
+
locked_ref="$(qmap_field "$IP_ROOT/intelligence.lock" "packages" "$name" "resolved")"
|
|
67
|
+
qmap_set "$manifest" "packages" "$name" "ref" "${locked_ref:-HEAD}"
|
|
68
|
+
fi
|
|
69
|
+
qmap_delete_field "$manifest" "packages" "$name" "url"
|
|
70
|
+
qmap_delete_field "$manifest" "packages" "$name" "path"
|
|
71
|
+
source_fields_migrated=1
|
|
72
|
+
done < <(qmap_keys "$manifest" "packages")
|
|
73
|
+
if [ "$source_fields_migrated" -eq 1 ]; then
|
|
74
|
+
echo " migrating: package url/path -> intelligence.lock"
|
|
75
|
+
fi
|
|
76
|
+
|
|
77
|
+
# v2 migration 2: staged engine content -> the @ainova-systems/sync package.
|
|
53
78
|
# Pre-package manifests listed `.intelligence/engine/{rules,agents,skills}`
|
|
54
79
|
# as sources fed by a CLI-staged copy; that copy is now an ordinary package
|
|
55
80
|
# entry seeded from the bundle. Post-condition: no `.intelligence/engine`
|
package/cli/lib/cli-common.sh
CHANGED
|
@@ -139,14 +139,12 @@ bundled_engine_version() {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
# --- The sync package's manifest/lock plumbing ---------------------------
|
|
142
|
-
# sync_pkg_entry <manifest> — write/refresh the
|
|
143
|
-
#
|
|
144
|
-
#
|
|
142
|
+
# sync_pkg_entry <manifest> — write/refresh only the requested exact pin.
|
|
143
|
+
# The built-in source lives in engine-package.yaml and resolved source state
|
|
144
|
+
# belongs exclusively to intelligence.lock.
|
|
145
145
|
sync_pkg_entry() {
|
|
146
146
|
local manifest="$1"
|
|
147
147
|
qmap_set "$manifest" "packages" "$SYNC_PKG_NAME" "version" "$(bundled_engine_version)"
|
|
148
|
-
qmap_set "$manifest" "packages" "$SYNC_PKG_NAME" "url" "$SYNC_PKG_URL"
|
|
149
|
-
qmap_set "$manifest" "packages" "$SYNC_PKG_NAME" "path" "$SYNC_PKG_PATH"
|
|
150
148
|
}
|
|
151
149
|
|
|
152
150
|
# sync_pkg_install <root> — materialize the package into the store and lock
|
|
@@ -227,13 +225,19 @@ project_needs_upgrade() {
|
|
|
227
225
|
[ -d "$root/.intelligence/engine" ] && return 0
|
|
228
226
|
|
|
229
227
|
while IFS= read -r name; do
|
|
230
|
-
[ "$name"
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
[ "$
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
228
|
+
[ -n "$name" ] || continue
|
|
229
|
+
# Early RC manifests mixed requested intent with resolved source
|
|
230
|
+
# details. Source URL/path now live only in the required lockfile.
|
|
231
|
+
[ -n "$(qmap_field "$manifest" "packages" "$name" "url")" ] && return 0
|
|
232
|
+
[ -n "$(qmap_field "$manifest" "packages" "$name" "path")" ] && return 0
|
|
233
|
+
if [ "$name" = "$SYNC_PKG_NAME" ]; then
|
|
234
|
+
pinned="$(qmap_field "$manifest" "packages" "$name" "version")"
|
|
235
|
+
locked="$(qmap_field "$root/intelligence.lock" "packages" "$name" "resolved")"
|
|
236
|
+
[ "$pinned" = "$eng" ] || return 0
|
|
237
|
+
if [ -f "$root/intelligence.lock" ]; then
|
|
238
|
+
[ -n "$locked" ] || return 0
|
|
239
|
+
[ "${locked#v}" = "$eng" ] || return 0
|
|
240
|
+
fi
|
|
237
241
|
fi
|
|
238
242
|
done < <(qmap_keys "$manifest" "packages")
|
|
239
243
|
return 1
|
package/cli/lib/manifest.sh
CHANGED
|
@@ -301,6 +301,29 @@ qmap_delete_key() {
|
|
|
301
301
|
'
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
# qmap_delete_field <file> <block> <key> <field> — drop one field from a
|
|
305
|
+
# quoted-key entry without disturbing its other fields or surrounding YAML.
|
|
306
|
+
qmap_delete_field() {
|
|
307
|
+
local file="$1" block="$2" key="$3" field="$4"
|
|
308
|
+
[ -f "$file" ] || return 0
|
|
309
|
+
_qmap_stage "$file" -v block="$block" -v key="$key" -v field="$field" '
|
|
310
|
+
{ sub(/\r$/, "") }
|
|
311
|
+
$0 ~ "^" block ":[ \t]*$" { inb = 1; print; next }
|
|
312
|
+
inb && /^[^ #]/ { inb = 0; ink = 0 }
|
|
313
|
+
inb && /^ "/ {
|
|
314
|
+
s = substr($0, 4); q = index(s, "\"")
|
|
315
|
+
ink = (q > 0 && substr(s, 1, q - 1) == key)
|
|
316
|
+
print; next
|
|
317
|
+
}
|
|
318
|
+
inb && ink && /^ [A-Za-z_]/ {
|
|
319
|
+
line = $0; sub(/^ /, "", line)
|
|
320
|
+
c = index(line, ":")
|
|
321
|
+
if (c > 0 && substr(line, 1, c - 1) == field) next
|
|
322
|
+
}
|
|
323
|
+
{ print }
|
|
324
|
+
'
|
|
325
|
+
}
|
|
326
|
+
|
|
304
327
|
# --- registries: a trust LIST, not a scope map -----------------------------
|
|
305
328
|
# The block holds registry repo URLs in trust order. Two shapes are read so
|
|
306
329
|
# early manifests keep working: the list form (`- "url"`) and the retired
|
package/engine/ENGINE_SHA
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
af238e67e8a9469edf6d2058e169de52cbeb93af
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ainova-systems/intelligence",
|
|
3
|
-
"version": "0.11.0-rc.
|
|
3
|
+
"version": "0.11.0-rc.9",
|
|
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"
|
|
@@ -92,11 +92,11 @@ intelligence package add github:acme/backend-intelligence
|
|
|
92
92
|
intelligence package add 'git+https://git.example.com/acme/backend.git@main#package'
|
|
93
93
|
```
|
|
94
94
|
|
|
95
|
-
Registries are an ordered trust list and the only resolver for a package name. There is no built-in catalog and no `@org/name` → GitHub guessing. An explicit `github:` or `git+` spec bypasses registry lookup
|
|
95
|
+
Registries are an ordered trust list and the only resolver for a package name. There is no built-in catalog and no `@org/name` → GitHub guessing. An explicit `github:` or `git+` spec bypasses registry lookup. In every case the manifest stores only requested `version` or `ref`; resolved URL/path and SHA live in the lock.
|
|
96
96
|
|
|
97
97
|
Stable Git tags provide package versions. Semver ranges select the highest matching stable tag; a `ref:` pin names a branch or commit and does not move during `intelligence update`. One package name has one version per project.
|
|
98
98
|
|
|
99
|
-
Commit `intelligence.lock`. It records requested versions, source URLs and paths, resolved refs and commit SHAs. After cloning, `intelligence sync` restores a missing store strictly from that lock before rendering; manifest/lock or SHA drift is refused.
|
|
99
|
+
Commit `intelligence.lock`. It records requested versions, source URLs and paths, resolved refs and commit SHAs. After cloning, `intelligence sync` restores a missing store strictly from that lock before rendering; manifest/lock or SHA drift is refused. Re-run `package add` when deliberately changing a source.
|
|
100
100
|
|
|
101
101
|
`@ainova-systems/sync` is ordinary package content exact-pinned to the bundled engine version. `intelligence init` installs it unless `--bare` is used. Lifecycle preflight keeps that pin and `schema_version` aligned with the installed CLI; package-range updates never move it independently.
|
|
102
102
|
|