@ainova-systems/intelligence 0.11.0-rc.6 → 0.11.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +15 -16
  2. package/cli/commands/adapter.sh +153 -0
  3. package/cli/commands/init.sh +113 -22
  4. package/cli/commands/package.sh +30 -0
  5. package/cli/commands/registry.sh +5 -2
  6. package/cli/commands/status.sh +12 -4
  7. package/cli/commands/sync.sh +8 -21
  8. package/cli/commands/update.sh +76 -61
  9. package/cli/engine-package.yaml +4 -4
  10. package/cli/intelligence +37 -27
  11. package/cli/{commands/doctor.sh → internal/check.sh} +32 -14
  12. package/cli/{commands/migrate.sh → internal/migrate-v1.sh} +161 -42
  13. package/cli/{commands/add.sh → internal/package-add.sh} +11 -10
  14. package/cli/{commands/list.sh → internal/package-list.sh} +9 -4
  15. package/cli/{commands/remove.sh → internal/package-remove.sh} +3 -3
  16. package/cli/{commands/search.sh → internal/package-search.sh} +4 -4
  17. package/cli/internal/package-update.sh +97 -0
  18. package/cli/{commands/install.sh → internal/restore.sh} +11 -4
  19. package/cli/internal/target-state.sh +57 -0
  20. package/cli/{commands/upgrade.sh → internal/upgrade-v2.sh} +48 -8
  21. package/cli/lib/cli-common.sh +167 -14
  22. package/cli/lib/lockfile.sh +15 -9
  23. package/cli/lib/manifest.sh +106 -1
  24. package/cli/lib/registry.sh +29 -15
  25. package/cli/lib/semver.sh +4 -2
  26. package/engine/ENGINE_SHA +1 -0
  27. package/engine/{scripts/adapters → adapters}/_template.sh +10 -9
  28. package/engine/{scripts/adapters → adapters}/agents.sh +20 -25
  29. package/engine/{scripts/adapters → adapters}/opencode.sh +1 -1
  30. package/engine/{scripts/lib → lib}/common.sh +29 -541
  31. package/engine/lib/contract.sh +120 -0
  32. package/engine/sync.sh +238 -0
  33. package/package.json +6 -5
  34. package/{engine → packages/sync}/agents/intelligence-architect.md +5 -3
  35. package/{engine → packages/sync}/agents/intelligence-operator.md +10 -13
  36. package/packages/sync/references/adapters.md +252 -0
  37. package/packages/sync/references/conventions.md +385 -0
  38. package/{engine → packages/sync}/rules/intelligence-authoring.md +6 -6
  39. package/{engine → packages/sync}/skills/intelligence-add-agent/SKILL.md +5 -5
  40. package/{engine → packages/sync}/skills/intelligence-add-rule/SKILL.md +3 -3
  41. package/{engine → packages/sync}/skills/intelligence-add-skill/SKILL.md +3 -3
  42. package/{engine → packages/sync}/skills/intelligence-extract-skill/SKILL.md +2 -2
  43. package/packages/sync/skills/intelligence-install-adapter/SKILL.md +38 -0
  44. package/{engine → packages/sync}/skills/intelligence-learn-from-context/SKILL.md +3 -3
  45. package/packages/sync/skills/intelligence-learn-from-repository/SKILL.md +55 -0
  46. package/{engine → packages/sync}/skills/intelligence-review-skills/SKILL.md +6 -6
  47. package/packages/sync/skills/intelligence-sync/SKILL.md +20 -0
  48. package/packages/sync/skills/intelligence-uninstall-adapter/SKILL.md +24 -0
  49. package/packages/sync/skills/intelligence-update/SKILL.md +43 -0
  50. package/engine/INIT.md +0 -500
  51. package/engine/docs/ADAPTERS.md +0 -214
  52. package/engine/docs/CLI.md +0 -90
  53. package/engine/docs/CONVENTIONS.md +0 -456
  54. package/engine/scripts/ENGINE_SHA +0 -1
  55. package/engine/scripts/lib/layout.sh +0 -51
  56. package/engine/scripts/lib/migrations.sh +0 -708
  57. package/engine/scripts/sync.sh +0 -311
  58. package/engine/scripts/update.sh +0 -237
  59. package/engine/skills/intelligence-install-adapter/SKILL.md +0 -31
  60. package/engine/skills/intelligence-sync/SKILL.md +0 -16
  61. package/engine/skills/intelligence-uninstall-adapter/SKILL.md +0 -42
  62. package/engine/skills/intelligence-update/SKILL.md +0 -165
  63. /package/engine/{scripts/VERSION → VERSION} +0 -0
  64. /package/engine/{scripts/adapters → adapters}/claude.sh +0 -0
  65. /package/engine/{scripts/adapters → adapters}/codex.sh +0 -0
  66. /package/engine/{scripts/adapters → adapters}/copilot.sh +0 -0
  67. /package/engine/{scripts/adapters → adapters}/cursor.sh +0 -0
  68. /package/engine/{scripts/adapters → adapters}/pi.sh +0 -0
@@ -1,78 +1,93 @@
1
1
  #!/bin/bash
2
- # intelligence update [name] [--no-sync]
2
+ # intelligence update [@scope/name] [--preview|--apply]
3
3
  #
4
- # Re-resolve version ranges against the remotes and rewrite the lock. Pinned
5
- # packages (`ref:`) never move here — repin by editing the manifest or
6
- # re-adding. `update <name>` limits the pass to one package.
4
+ # One update surface: show the installed-CLI/project/package plan, then either
5
+ # stop, ask interactively, or apply without a prompt. Updating the global npm
6
+ # installation remains an explicit package-manager operation.
7
7
  set -euo pipefail
8
8
  source "$CLI_DIR/lib/cli-common.sh"
9
9
 
10
- only="" no_sync=0
10
+ only="" mode="ask" preview_seen=0 apply_seen=0
11
11
  while [ $# -gt 0 ]; do
12
12
  case "$1" in
13
- --no-sync) no_sync=1 ;;
14
- @*) only="$1" ;;
15
- *) die "unknown argument '$1'" ;;
13
+ --preview) preview_seen=1; mode="preview" ;;
14
+ --apply) apply_seen=1; mode="apply" ;;
15
+ @*) [ -z "$only" ] || die "only one package may be selected"; only="$1" ;;
16
+ *) die "usage: intelligence update [@scope/name] [--preview|--apply]" ;;
16
17
  esac
17
- shift || true
18
+ shift
18
19
  done
20
+ [ "$preview_seen" -eq 0 ] || [ "$apply_seen" -eq 0 ] || die "choose either --preview or --apply"
19
21
 
20
22
  require_v2
21
23
  manifest="$IP_ROOT/intelligence.yaml"
22
- lock="$IP_ROOT/intelligence.lock"
24
+ check_version_compat "$manifest"
25
+ eng="$(bundled_engine_version)"
26
+ stamp="$(read_schema_version "$manifest")"
27
+ project_change=0
23
28
 
24
- moved=0 found=0
25
- while IFS= read -r name; do
26
- [ -n "$name" ] || continue
27
- [ -n "$only" ] && [ "$name" != "$only" ] && continue
28
- # A named package that exists is "found" whatever happens next — a skip
29
- # message followed by "not in the manifest" would contradict itself.
30
- found=1
31
- if [ "$name" = "$SYNC_PKG_NAME" ]; then
32
- echo " $name: engine content moves with the engine — 'intelligence upgrade' owns it"
33
- continue
29
+ echo "Update plan"
30
+ echo ""
31
+ echo "CLI:"
32
+ if [ -n "${INTELLIGENCE_NPM_VERSION:-}" ] && [ "${IS_SKIP_NPM_CHECK:-0}" != "1" ] && command -v npm >/dev/null 2>&1; then
33
+ channel="latest"
34
+ case "$INTELLIGENCE_NPM_VERSION" in *-*) channel="next" ;; esac
35
+ available="$(npm view "@ainova-systems/intelligence" "dist-tags.$channel" 2>/dev/null || true)"
36
+ if [ -z "$available" ]; then
37
+ echo " installed: $INTELLIGENCE_NPM_VERSION; registry check unavailable"
38
+ elif [ "$available" = "$INTELLIGENCE_NPM_VERSION" ]; then
39
+ echo " $INTELLIGENCE_NPM_VERSION (up to date on npm $channel)"
40
+ else
41
+ echo " $INTELLIGENCE_NPM_VERSION -> $available (npm $channel)"
42
+ echo " run: npm install -g @ainova-systems/intelligence@$channel"
43
+ echo " then rerun: intelligence update --apply"
34
44
  fi
35
- ref="$(qmap_field "$manifest" "packages" "$name" "ref")"
36
- [ -n "$ref" ] && { echo " $name: pinned to ref '$ref' — skipped"; continue; }
37
- range="$(qmap_field "$manifest" "packages" "$name" "version")"
38
- # An exact version is a pin, same as ref: — update never moves pins.
39
- if [ -n "$range" ] && semver_is_stable "$range"; then
40
- echo " $name: pinned to $range — edit the manifest to move it"
41
- continue
42
- fi
43
- url="$(qmap_field "$manifest" "packages" "$name" "url")"
44
- path="$(qmap_field "$manifest" "packages" "$name" "path")"
45
- if [ -z "$url" ]; then
46
- resolve_package_source "$manifest" "$name"
47
- url="$RES_URL"; path="$RES_PATH"
48
- fi
49
- picked="$(list_remote_versions "$url" | semver_pick_highest "$range")"
50
- [ -n "$picked" ] || { echo " $name: nothing satisfies '${range:-*}' at $url" >&2; continue; }
51
- read -r tag _ <<< "$(remote_tag_for_version "$url" "$picked")"
52
- current="$(qmap_field "$lock" "packages" "$name" "resolved")"
53
- cur_url="$(qmap_field "$lock" "packages" "$name" "url")"
54
- cur_path="$(qmap_field "$lock" "packages" "$name" "path")"
55
- # Same tag is not enough: a registry may re-point a name's source while
56
- # keeping the version — the move doctor warns about must be actionable
57
- # here, so url/path changes refetch too.
58
- if [ "$tag" = "$current" ] && [ "$url" = "$cur_url" ] && [ "$path" = "$cur_path" ]; then
59
- echo " $name: ${current:-<none>} (up to date)"
60
- continue
61
- fi
62
- rel=".intelligence/packages/$name"
63
- # The new version may have dropped a top-level section dir: unwire the old
64
- # shape first, or a dangling store-backed source bricks the next sync.
65
- unwire_package_sources "$manifest" "$rel"
66
- sha="$(fetch_package "$url" "$tag" "$path" "$IP_ROOT/$rel")"
67
- wire_package_sources "$manifest" "$name" "$rel" "$IP_ROOT"
68
- lock_upsert "$lock" "$name" "$range" "$url" "$path" "$tag" "$sha"
69
- echo " $name: ${current:-<none>} -> $tag"
70
- moved=$((moved + 1))
71
- done < <(qmap_keys "$manifest" "packages")
45
+ else
46
+ echo " source checkout/registry check skipped; engine $eng"
47
+ fi
48
+
49
+ echo ""
50
+ echo "Project:"
51
+ if project_needs_upgrade "$IP_ROOT"; then
52
+ echo " lifecycle alignment required (stamp ${stamp:-unstamped}, engine $eng)"
53
+ project_change=1
54
+ else
55
+ echo " schema/content $eng (up to date)"
56
+ fi
72
57
 
73
- [ -n "$only" ] && [ "$found" -eq 0 ] && die "package '$only' is not in the manifest"
74
- echo "updated: $moved package(s)"
58
+ if project_has_packages "$IP_ROOT" && [ ! -f "$IP_ROOT/intelligence.lock" ]; then
59
+ die "manifest declares packages but intelligence.lock is absent — restore the committed lock before planning or applying updates"
60
+ fi
61
+
62
+ pkg_args=(--preview)
63
+ [ -z "$only" ] || pkg_args+=("$only")
64
+ pkg_plan="$(bash "$CLI_DIR/internal/package-update.sh" "${pkg_args[@]}")"
65
+ echo ""
66
+ echo "Packages:"
67
+ printf '%s\n' "$pkg_plan"
68
+ package_changes="$(printf '%s\n' "$pkg_plan" | awk '/^updates available:/ {print $3; exit}')"
69
+ package_changes="${package_changes:-0}"
75
70
 
76
- if [ "$moved" -gt 0 ] && [ "$no_sync" -eq 0 ]; then
77
- exec bash "$CLI_DIR/commands/sync.sh"
71
+ if [ "$mode" = "preview" ]; then
72
+ exit 0
73
+ fi
74
+ if [ "$project_change" -eq 0 ] && [ "$package_changes" -eq 0 ]; then
75
+ echo ""
76
+ echo "Nothing to apply with the currently installed CLI."
77
+ exit 0
78
78
  fi
79
+ if [ "$mode" = "ask" ]; then
80
+ [ -t 0 ] || die "update requires confirmation — rerun with --preview or --apply"
81
+ printf '\nApply this plan? [Y/n] '
82
+ read -r answer
83
+ case "$answer" in
84
+ ""|y|Y|yes|YES) ;;
85
+ *) echo "update cancelled"; exit 0 ;;
86
+ esac
87
+ fi
88
+
89
+ ensure_project_current "$IP_ROOT"
90
+ apply_args=(--no-sync)
91
+ [ -z "$only" ] || apply_args+=("$only")
92
+ bash "$CLI_DIR/internal/package-update.sh" "${apply_args[@]}"
93
+ exec bash "$CLI_DIR/commands/sync.sh"
@@ -6,9 +6,9 @@
6
6
  # The engine-content package is the one package whose content documents the
7
7
  # engine scripts bundled with the CLI: init writes this entry into the
8
8
  # manifest (visible, removable), its pin always equals the engine VERSION,
9
- # `upgrade` moves it, and at the matching version it materializes from the
10
- # bundle without network.
9
+ # lifecycle preflight aligns it with the installed CLI, and at the matching
10
+ # version it materializes from the bundle without network.
11
11
  name: "@ainova-systems/sync"
12
- url: "https://github.com/ainova-systems/intelligence-sync.git"
13
- path: "intelligence/sync"
12
+ url: "https://github.com/ainova-systems/intelligence.git"
13
+ path: "packages/sync"
14
14
  default_registry: "https://github.com/ainova-systems/intelligence-registry.git"
package/cli/intelligence CHANGED
@@ -3,25 +3,20 @@
3
3
  #
4
4
  # Dispatcher only: each command lives in commands/<name>.sh so commands can be
5
5
  # ported to Node one at a time without touching the others. The engine is the
6
- # vendored bash engine bundled next to the CLI (npm package) or, when running
7
- # from the intelligence-sync repo itself, the repo's own module.
6
+ # bash engine shipped next to the CLI.
8
7
 
9
8
  set -euo pipefail
10
9
 
11
10
  CLI_DIR="$(cd "$(dirname "$0")" && pwd)"
12
11
  export CLI_DIR
13
12
 
14
- # Engine discovery, by role (scripts/sync.sh + scripts/VERSION), never by
15
- # guessing names beyond the two shipped layouts:
16
- # 1. npm package: <pkg>/cli/intelligence + <pkg>/engine/scripts/
17
- # 2. this repo: <repo>/cli/intelligence + <repo>/intelligence/sync/scripts/
13
+ # Engine discovery, by role (sync.sh + VERSION). The repo and the npm package
14
+ # ship one layout — <root>/{cli,engine,packages/sync} — so there is a single
15
+ # candidate rather than a per-distribution list.
18
16
  IS_ENGINE_DIR=""
19
- for _cand in "$CLI_DIR/../engine" "$CLI_DIR/../intelligence/sync"; do
20
- if [ -f "$_cand/scripts/sync.sh" ] && [ -f "$_cand/scripts/VERSION" ]; then
21
- IS_ENGINE_DIR="$(cd "$_cand" && pwd)"
22
- break
23
- fi
24
- done
17
+ if [ -f "$CLI_DIR/../engine/sync.sh" ] && [ -f "$CLI_DIR/../engine/VERSION" ]; then
18
+ IS_ENGINE_DIR="$(cd "$CLI_DIR/../engine" && pwd)"
19
+ fi
25
20
  if [ -z "$IS_ENGINE_DIR" ]; then
26
21
  echo "ERROR: bundled sync engine not found next to the CLI ($CLI_DIR)." >&2
27
22
  echo " Reinstall: npm i -g @ainova-systems/intelligence" >&2
@@ -29,41 +24,56 @@ if [ -z "$IS_ENGINE_DIR" ]; then
29
24
  fi
30
25
  export IS_ENGINE_DIR
31
26
 
27
+ # The engine's own content, shipped beside the engine as the seed for the
28
+ # @ainova-systems/sync package at exactly this CLI's version. Separate from the
29
+ # engine dir: the store must receive rules/agents/skills, never engine scripts.
30
+ IS_BUNDLED_PKG_DIR=""
31
+ if [ -d "$CLI_DIR/../packages/sync" ]; then
32
+ IS_BUNDLED_PKG_DIR="$(cd "$CLI_DIR/../packages/sync" && pwd)"
33
+ fi
34
+ export IS_BUNDLED_PKG_DIR
35
+
32
36
  cmd="${1:-}"
33
37
  case "$cmd" in
34
38
  ""|help|-h|--help)
35
- engine_ver="$(tr -d ' \t\r\n' < "$IS_ENGINE_DIR/scripts/VERSION")"
39
+ engine_ver="$(tr -d ' \t\r\n' < "$IS_ENGINE_DIR/VERSION")"
36
40
  cat <<EOF
37
41
  intelligence — build, version and distribute AI agent intelligence
38
42
  (engine $engine_ver${INTELLIGENCE_NPM_VERSION:+, package $INTELLIGENCE_NPM_VERSION})
39
43
 
40
44
  Usage: intelligence <command> [args]
41
45
 
42
- init Set up this project (manifest, content skeleton, targets)
43
- add <spec> Add a package: @scope/name[@range] | github:org/repo[#path] | git+<url>[@ref][#path]
44
- remove <name> Remove a package
45
- install [--frozen] Restore .intelligence/ exactly from intelligence.lock
46
- update [name] Re-resolve version ranges and rewrite the lockfile
47
- upgrade Upgrade the project to this CLI's engine (restage + restamp)
48
- list Installed packages with requested/locked versions
49
- search [term] What the registries offer, and what this project has
50
- sync [target] Render intelligence to every enabled tool (.claude, AGENTS.md, ...)
51
- registry <list|add|remove> Bind a scope to a registry index
52
- migrate [--dry-run] Convert a vendored (v1) setup to the CLI setup
53
- doctor Check manifest, lockfile, store and engine consistency
54
- status Project state at a glance
46
+ init [--preview|--apply] Initialize, migrate, restore or align this project
47
+ --targets a,b --dir name --bare --no-sync New-project options
48
+ --force Accept a dirty worktree during v1 conversion
49
+ sync [adapter] Restore locked content if needed, then render enabled adapters
50
+ update [@scope/name] Show an update plan; ask before applying it
51
+ --preview Show the plan without asking or writing
52
+ --apply Apply the plan without asking
53
+ package <command> add | remove | list | search
54
+ adapter <command> list | create | enable | disable | remove
55
+ status [--check] Project state; --check runs deep consistency checks
56
+ registry <list|add|remove> Manage the trusted registry list (add <repo-url>)
55
57
  version Print CLI and engine versions
56
58
  EOF
57
59
  exit 0
58
60
  ;;
59
61
  version|-v|--version)
60
- engine_ver="$(tr -d ' \t\r\n' < "$IS_ENGINE_DIR/scripts/VERSION")"
62
+ engine_ver="$(tr -d ' \t\r\n' < "$IS_ENGINE_DIR/VERSION")"
61
63
  echo "${INTELLIGENCE_NPM_VERSION:-$engine_ver} (engine $engine_ver)"
62
64
  exit 0
63
65
  ;;
64
66
  esac
65
67
  shift
66
68
 
69
+ # The command word builds a path — allow exactly lowercase words, so
70
+ # `intelligence ../x` can never exec a neighbouring script.
71
+ case "$cmd" in
72
+ *[!a-z-]*|-*)
73
+ echo "ERROR: unknown command '$cmd'. Run 'intelligence help'." >&2
74
+ exit 1
75
+ ;;
76
+ esac
67
77
  cmd_file="$CLI_DIR/commands/$cmd.sh"
68
78
  if [ ! -f "$cmd_file" ]; then
69
79
  echo "ERROR: unknown command '$cmd'. Run 'intelligence help'." >&2
@@ -1,5 +1,5 @@
1
1
  #!/bin/bash
2
- # intelligence doctor — consistency checks, no writes. Exit 1 on problems.
2
+ # Internal deep consistency check. No writes; exits 1 on problems.
3
3
  set -euo pipefail
4
4
  source "$CLI_DIR/lib/cli-common.sh"
5
5
 
@@ -22,7 +22,7 @@ case "$IP_MODE" in
22
22
  legacy)
23
23
  echo "project: vendored (v1) at $IP_ROOT"
24
24
  ok "vendored engine $(tr -d ' \t\r\n' < "$IP_MODULE_DIR/scripts/VERSION")"
25
- echo " → 'intelligence migrate' converts it to the CLI setup"
25
+ echo " → 'intelligence init' converts it to the CLI setup"
26
26
  exit 0
27
27
  ;;
28
28
  esac
@@ -31,16 +31,16 @@ echo "project: $IP_ROOT"
31
31
  manifest="$IP_ROOT/intelligence.yaml"
32
32
  lock="$IP_ROOT/intelligence.lock"
33
33
 
34
- stamp="$(read_engine_stamp "$manifest")"
34
+ stamp="$(read_schema_version "$manifest")"
35
35
  eng="$(bundled_engine_version)"
36
36
  if [ -z "$stamp" ]; then
37
- warn "manifest has no sync_version — run 'intelligence upgrade'"
37
+ warn "manifest has no schema_version — run 'intelligence init'"
38
38
  elif _ver_gt "$stamp" "$eng"; then
39
39
  warn "manifest schema $stamp is newer than this CLI's engine $eng — update the CLI: npm i -g @ainova-systems/intelligence@latest"
40
40
  elif _ver_gt "$eng" "$stamp"; then
41
- warn "manifest schema $stamp behind engine $eng — run 'intelligence upgrade'"
41
+ warn "manifest schema $stamp behind engine $eng — run 'intelligence init'"
42
42
  else
43
- ok "sync_version $stamp matches the engine"
43
+ ok "schema_version $stamp matches the engine"
44
44
  fi
45
45
 
46
46
  # The engine-content package must sit at the bundled engine version — the
@@ -50,11 +50,11 @@ if [ -n "$sync_locked" ]; then
50
50
  if [ "${sync_locked#v}" = "$eng" ]; then
51
51
  ok "$SYNC_PKG_NAME at $sync_locked (matches the engine)"
52
52
  else
53
- warn "$SYNC_PKG_NAME locked at $sync_locked but the engine is $eng — run 'intelligence upgrade'"
53
+ warn "$SYNC_PKG_NAME locked at $sync_locked but the engine is $eng — run 'intelligence init'"
54
54
  fi
55
55
  fi
56
56
  if [ -d "$IP_ROOT/.intelligence/engine" ]; then
57
- warn "stale .intelligence/engine directory (pre-package layout) — run 'intelligence upgrade'"
57
+ warn "stale .intelligence/engine directory (pre-package layout) — run 'intelligence init'"
58
58
  fi
59
59
 
60
60
  # Manifest packages: names valid, locked, installed — and the lock's source
@@ -64,16 +64,34 @@ while IFS= read -r name; do
64
64
  [ -n "$name" ] || continue
65
65
  assert_valid_pkg_name "$name"
66
66
  if [ -z "$(qmap_field "$lock" "packages" "$name" "url")" ]; then
67
- warn "$name is in the manifest but not in intelligence.lock — run 'intelligence install'"
68
- elif [ ! -d "$IP_ROOT/.intelligence/packages/$name" ]; then
69
- warn "$name is locked but not installed — run 'intelligence install'"
67
+ warn "$name is in the manifest but not in intelligence.lock — run 'intelligence init'"
70
68
  else
69
+ m_ver="$(qmap_field "$manifest" "packages" "$name" "version")"
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
+ l_req="$(qmap_field "$lock" "packages" "$name" "requested")"
74
+ 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
+ [ -z "$m_ver" ] || [ "$m_ver" = "$l_req" ] \
78
+ || warn "$name requests '$m_ver' but the lock recorded '$l_req' — run 'intelligence update --preview'"
79
+ [ -z "$m_ref" ] || [ "$m_ref" = "$l_res" ] \
80
+ || warn "$name pins ref '$m_ref' but the lock resolved '$l_res'"
81
+ [ -z "$m_url" ] || [ "$m_url" = "$l_url" ] \
82
+ || warn "$name declares url '$m_url' but the lock recorded '$l_url'"
83
+ [ -z "$m_path" ] || [ "$m_path" = "$l_path" ] \
84
+ || warn "$name declares path '$m_path' but the lock recorded '$l_path'"
85
+ if [ ! -d "$IP_ROOT/.intelligence/packages/$name" ]; then
86
+ warn "$name is locked but not installed — run 'intelligence sync'"
87
+ continue
88
+ fi
71
89
  ok "$name @ $(qmap_field "$lock" "packages" "$name" "resolved")"
72
90
  if [ -z "$(qmap_field "$manifest" "packages" "$name" "url")" ]; then
73
91
  locked_url="$(qmap_field "$lock" "packages" "$name" "url")"
74
92
  resolve_package_source "$manifest" "$name" 2>/dev/null || true
75
93
  if [ -n "${RES_URL:-}" ] && [ -n "$locked_url" ] && [ "$RES_URL" != "$locked_url" ]; then
76
- warn "$name now resolves to $RES_URL but the lock pins $locked_url — a registry re-pointed the name; verify before 'intelligence update'"
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'"
77
95
  fi
78
96
  fi
79
97
  fi
@@ -87,7 +105,7 @@ if [ -f "$lock" ]; then
87
105
  while IFS= read -r m; do
88
106
  [ "$m" = "$name" ] && found=1
89
107
  done < <(qmap_keys "$manifest" "packages")
90
- [ "$found" -eq 1 ] || warn "$name is locked but absent from the manifest — 'intelligence remove $name' cleans it up"
108
+ [ "$found" -eq 1 ] || warn "$name is locked but absent from the manifest — 'intelligence package remove $name' cleans it up"
91
109
  done < <(qmap_keys "$lock" "packages")
92
110
  fi
93
111
 
@@ -102,7 +120,7 @@ for section in rules agents skills; do
102
120
  if [ ! -d "$IP_ROOT/$src" ]; then
103
121
  case "$src" in
104
122
  # Store content is restorable state: absent means un-installed.
105
- .intelligence/*) warn "sources.$section '$src' missing — run 'intelligence install'" ;;
123
+ .intelligence/*) warn "sources.$section '$src' missing — run 'intelligence sync'" ;;
106
124
  # A project-owned dir that does not exist yet is a legitimate
107
125
  # state — a project consuming only packages authors nothing of
108
126
  # its own — and the engine simply skips it. Declared up front so