@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.
- package/README.md +15 -16
- package/cli/commands/adapter.sh +153 -0
- package/cli/commands/init.sh +113 -22
- package/cli/commands/package.sh +30 -0
- package/cli/commands/registry.sh +5 -2
- package/cli/commands/status.sh +12 -4
- package/cli/commands/sync.sh +8 -21
- package/cli/commands/update.sh +76 -61
- package/cli/engine-package.yaml +4 -4
- package/cli/intelligence +37 -27
- package/cli/{commands/doctor.sh → internal/check.sh} +32 -14
- package/cli/{commands/migrate.sh → internal/migrate-v1.sh} +161 -42
- package/cli/{commands/add.sh → internal/package-add.sh} +11 -10
- package/cli/{commands/list.sh → internal/package-list.sh} +9 -4
- package/cli/{commands/remove.sh → internal/package-remove.sh} +3 -3
- package/cli/{commands/search.sh → internal/package-search.sh} +4 -4
- package/cli/internal/package-update.sh +97 -0
- package/cli/{commands/install.sh → internal/restore.sh} +11 -4
- package/cli/internal/target-state.sh +57 -0
- package/cli/{commands/upgrade.sh → internal/upgrade-v2.sh} +48 -8
- package/cli/lib/cli-common.sh +167 -14
- package/cli/lib/lockfile.sh +15 -9
- package/cli/lib/manifest.sh +106 -1
- package/cli/lib/registry.sh +29 -15
- package/cli/lib/semver.sh +4 -2
- package/engine/ENGINE_SHA +1 -0
- package/engine/{scripts/adapters → adapters}/_template.sh +10 -9
- package/engine/{scripts/adapters → adapters}/agents.sh +20 -25
- package/engine/{scripts/adapters → adapters}/opencode.sh +1 -1
- package/engine/{scripts/lib → lib}/common.sh +29 -541
- package/engine/lib/contract.sh +120 -0
- package/engine/sync.sh +238 -0
- package/package.json +6 -5
- package/{engine → packages/sync}/agents/intelligence-architect.md +5 -3
- package/{engine → packages/sync}/agents/intelligence-operator.md +10 -13
- package/packages/sync/references/adapters.md +252 -0
- package/packages/sync/references/conventions.md +385 -0
- package/{engine → packages/sync}/rules/intelligence-authoring.md +6 -6
- package/{engine → packages/sync}/skills/intelligence-add-agent/SKILL.md +5 -5
- package/{engine → packages/sync}/skills/intelligence-add-rule/SKILL.md +3 -3
- package/{engine → packages/sync}/skills/intelligence-add-skill/SKILL.md +3 -3
- package/{engine → packages/sync}/skills/intelligence-extract-skill/SKILL.md +2 -2
- package/packages/sync/skills/intelligence-install-adapter/SKILL.md +38 -0
- package/{engine → packages/sync}/skills/intelligence-learn-from-context/SKILL.md +3 -3
- package/packages/sync/skills/intelligence-learn-from-repository/SKILL.md +55 -0
- package/{engine → packages/sync}/skills/intelligence-review-skills/SKILL.md +6 -6
- package/packages/sync/skills/intelligence-sync/SKILL.md +20 -0
- package/packages/sync/skills/intelligence-uninstall-adapter/SKILL.md +24 -0
- package/packages/sync/skills/intelligence-update/SKILL.md +43 -0
- package/engine/INIT.md +0 -500
- package/engine/docs/ADAPTERS.md +0 -214
- package/engine/docs/CLI.md +0 -90
- package/engine/docs/CONVENTIONS.md +0 -456
- package/engine/scripts/ENGINE_SHA +0 -1
- package/engine/scripts/lib/layout.sh +0 -51
- package/engine/scripts/lib/migrations.sh +0 -708
- package/engine/scripts/sync.sh +0 -311
- package/engine/scripts/update.sh +0 -237
- package/engine/skills/intelligence-install-adapter/SKILL.md +0 -31
- package/engine/skills/intelligence-sync/SKILL.md +0 -16
- package/engine/skills/intelligence-uninstall-adapter/SKILL.md +0 -42
- package/engine/skills/intelligence-update/SKILL.md +0 -165
- /package/engine/{scripts/VERSION → VERSION} +0 -0
- /package/engine/{scripts/adapters → adapters}/claude.sh +0 -0
- /package/engine/{scripts/adapters → adapters}/codex.sh +0 -0
- /package/engine/{scripts/adapters → adapters}/copilot.sh +0 -0
- /package/engine/{scripts/adapters → adapters}/cursor.sh +0 -0
- /package/engine/{scripts/adapters → adapters}/pi.sh +0 -0
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# shellcheck disable=SC2034 # IS_RC_*/IS_SCHEMA_VERSION_KEY are the public bash<->CLI contract, consumed by the scripts that source this lib
|
|
3
|
+
# intelligence-sync: the version and status contract.
|
|
4
|
+
# Source this file — never execute directly.
|
|
5
|
+
#
|
|
6
|
+
# Two things live here, and both are contracts other programs depend on:
|
|
7
|
+
# * the applied-schema stamp (`schema_version` in the manifest) with its
|
|
8
|
+
# read / write / compare helpers, and
|
|
9
|
+
# * the IS_STATUS / IS_RC_* codes every engine flow reports.
|
|
10
|
+
#
|
|
11
|
+
# Schema migrations themselves are NOT here: the CLI owns them behind
|
|
12
|
+
# `intelligence init`, and a v1 project is brought forward by the archived v1
|
|
13
|
+
# engine before `intelligence init` converts it.
|
|
14
|
+
|
|
15
|
+
# The applied-schema version is a managed key in the manifest.
|
|
16
|
+
#
|
|
17
|
+
# INVARIANT: this key is a PERMANENT, format-stable, top-level scalar contract.
|
|
18
|
+
# Anything else in the manifest may be reshaped; the name, location and shape of
|
|
19
|
+
# this key never are - so any engine, however old or new, can always read "what
|
|
20
|
+
# schema is this?" before parsing the rest.
|
|
21
|
+
IS_SCHEMA_VERSION_KEY="schema_version"
|
|
22
|
+
|
|
23
|
+
# read_schema_version <config_file> → applied version, or "" if absent.
|
|
24
|
+
read_schema_version() {
|
|
25
|
+
local cf="$1"
|
|
26
|
+
[ -f "$cf" ] || return 0
|
|
27
|
+
awk -v k="$IS_SCHEMA_VERSION_KEY" '
|
|
28
|
+
{ sub(/\r$/, "") }
|
|
29
|
+
$0 ~ "^" k ":" {
|
|
30
|
+
v = $0; sub(/^[^:]*:[[:space:]]*/, "", v)
|
|
31
|
+
gsub(/^["\047]|["\047][[:space:]]*$/, "", v)
|
|
32
|
+
sub(/[[:space:]]+$/, "", v)
|
|
33
|
+
print v; exit
|
|
34
|
+
}
|
|
35
|
+
' "$cf"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
# stamp_schema_version <config_file> <version> — idempotent, transactional upsert of
|
|
39
|
+
# the contract key (replace in place if present, else append at top level).
|
|
40
|
+
# No-op if config.yaml does not exist yet (pre-bootstrap).
|
|
41
|
+
stamp_schema_version() {
|
|
42
|
+
local cf="$1" ver="$2"
|
|
43
|
+
[ -f "$cf" ] || return 0
|
|
44
|
+
local tmp="$cf.ver.tmp"
|
|
45
|
+
awk -v k="$IS_SCHEMA_VERSION_KEY" -v val="$ver" '
|
|
46
|
+
{ sub(/\r$/, "") }
|
|
47
|
+
$0 ~ "^" k ":" { print k ": \"" val "\""; found=1; next }
|
|
48
|
+
{ print }
|
|
49
|
+
END { if (!found) print k ": \"" val "\"" }
|
|
50
|
+
' "$cf" > "$tmp" && mv "$tmp" "$cf"
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
# --- bash ↔ skill status contract -------------------------------------------
|
|
54
|
+
# Bash is the deterministic, fail-closed core: it never guesses. Any state it
|
|
55
|
+
# cannot resolve safely is reported as a machine-readable status line on
|
|
56
|
+
# stdout plus a stable exit code, and the intelligence-update SKILL (the
|
|
57
|
+
# intelligent layer) decides what to do. Codes are part of the public
|
|
58
|
+
# contract — do not renumber.
|
|
59
|
+
IS_RC_OK=0 # success (synced / migrated / nothing to do)
|
|
60
|
+
IS_RC_ERROR=1 # generic error
|
|
61
|
+
IS_RC_CONFIG_MISSING=2 # no manifest found
|
|
62
|
+
IS_RC_AMBIGUOUS=3 # conflicting state; agent/human-only — bash never emits this itself
|
|
63
|
+
IS_RC_AHEAD=4 # project stamped newer than this engine understands
|
|
64
|
+
IS_RC_ABORTED_INCOMPLETE=5 # staged state incomplete; the project was left untouched
|
|
65
|
+
IS_RC_NEEDS_UPDATE=6 # pending schema changes (stamp < engine) — run `intelligence init --apply`
|
|
66
|
+
|
|
67
|
+
# is_status <code-name> [detail] — emit one parseable line for the skill.
|
|
68
|
+
is_status() {
|
|
69
|
+
local code="$1" detail="${2:-}"
|
|
70
|
+
if [ -n "$detail" ]; then
|
|
71
|
+
echo "IS_STATUS=$code IS_DETAIL=$detail"
|
|
72
|
+
else
|
|
73
|
+
echo "IS_STATUS=$code"
|
|
74
|
+
fi
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
# Engine version = scripts/VERSION next to this lib (BASH_SOURCE works when
|
|
78
|
+
# sourced). Empty if unreadable — callers treat empty as "no guard".
|
|
79
|
+
engine_version() {
|
|
80
|
+
local vf
|
|
81
|
+
vf="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." 2>/dev/null && pwd)/VERSION"
|
|
82
|
+
[ -f "$vf" ] && tr -d ' \t\r\n' < "$vf"
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
# _ver_gt A B → true if semver A is strictly greater than B (numeric x.y.z;
|
|
86
|
+
# any non-numeric suffix on a field is ignored). Missing fields = 0.
|
|
87
|
+
# Pre-release/build metadata ordering is intentionally NOT handled — the
|
|
88
|
+
# stamp only ever stores plain x.y.z, so this is sufficient.
|
|
89
|
+
_ver_gt() {
|
|
90
|
+
local a="$1" b="$2" i ai bi
|
|
91
|
+
local -a A B
|
|
92
|
+
IFS=. read -r -a A <<< "$a"
|
|
93
|
+
IFS=. read -r -a B <<< "$b"
|
|
94
|
+
for i in 0 1 2; do
|
|
95
|
+
ai=$(printf '%s' "${A[$i]:-0}" | tr -cd '0-9'); ai=${ai:-0}
|
|
96
|
+
bi=$(printf '%s' "${B[$i]:-0}" | tr -cd '0-9'); bi=${bi:-0}
|
|
97
|
+
if [ "$((10#$ai))" -gt "$((10#$bi))" ]; then return 0; fi
|
|
98
|
+
if [ "$((10#$ai))" -lt "$((10#$bi))" ]; then return 1; fi
|
|
99
|
+
done
|
|
100
|
+
return 1
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
# check_version_compat <config_file> — refuse to operate on a project whose
|
|
104
|
+
# config schema is stamped newer than this engine knows (a stale engine must
|
|
105
|
+
# never rewrite/sync a newer schema). Emits status + returns IS_RC_AHEAD on
|
|
106
|
+
# conflict, else 0.
|
|
107
|
+
check_version_compat() {
|
|
108
|
+
local cf="$1" stamp eng
|
|
109
|
+
stamp="$(read_schema_version "$cf")"
|
|
110
|
+
[ -n "$stamp" ] || return 0
|
|
111
|
+
eng="$(engine_version)"
|
|
112
|
+
[ -n "$eng" ] || return 0
|
|
113
|
+
if _ver_gt "$stamp" "$eng"; then
|
|
114
|
+
is_status ahead-of-engine "stamp=$stamp engine=$eng"
|
|
115
|
+
echo " ERROR: project stamped $stamp but this engine is $eng — refusing." >&2
|
|
116
|
+
echo " Update the CLI first: npm i -g @ainova-systems/intelligence@latest" >&2
|
|
117
|
+
return "$IS_RC_AHEAD"
|
|
118
|
+
fi
|
|
119
|
+
return 0
|
|
120
|
+
}
|
package/engine/sync.sh
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# intelligence-sync: the sync engine's entry point.
|
|
3
|
+
#
|
|
4
|
+
# The engine runs from outside the project (the CLI's install dir), so it never
|
|
5
|
+
# searches the filesystem for one: the project arrives through the environment,
|
|
6
|
+
# exported by `intelligence sync`.
|
|
7
|
+
#
|
|
8
|
+
# CONFIG_FILE the project's manifest (intelligence.yaml at the root)
|
|
9
|
+
# REPO_ROOT the project root
|
|
10
|
+
# IS_CONTENT_REL the project's content dir, repo-relative
|
|
11
|
+
# IS_MODULE_REL the installed sync package, repo-relative
|
|
12
|
+
# IS_PROTECTED_DIRS dirs an adapter output may never overlap
|
|
13
|
+
#
|
|
14
|
+
# Usage: intelligence sync [target]
|
|
15
|
+
|
|
16
|
+
set -euo pipefail
|
|
17
|
+
|
|
18
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
19
|
+
|
|
20
|
+
source "$SCRIPT_DIR/lib/common.sh"
|
|
21
|
+
source "$SCRIPT_DIR/lib/contract.sh"
|
|
22
|
+
|
|
23
|
+
if [ -z "${CONFIG_FILE:-}" ] || [ ! -f "${CONFIG_FILE:-}" ]; then
|
|
24
|
+
is_status config-missing "CONFIG_FILE=${CONFIG_FILE:-}"
|
|
25
|
+
echo "ERROR: the engine needs CONFIG_FILE to point at an existing manifest." >&2
|
|
26
|
+
echo " Run it through the CLI: intelligence sync" >&2
|
|
27
|
+
exit "$IS_RC_CONFIG_MISSING"
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Schema version lives in the manifest (the frozen contract key).
|
|
31
|
+
_cf="$CONFIG_FILE"
|
|
32
|
+
|
|
33
|
+
# Stale engine vs project schema stamped NEWER (ahead-of-engine) → refuse.
|
|
34
|
+
_vc_rc=0
|
|
35
|
+
check_version_compat "$_cf" || _vc_rc=$?
|
|
36
|
+
if [ "$_vc_rc" -ne 0 ]; then exit "$_vc_rc"; fi
|
|
37
|
+
|
|
38
|
+
# Schema gap → refuse. sync is a PURE synchronizer: it never changes schemas,
|
|
39
|
+
# so the CLI lifecycle preflight must align the project first. An ABSENT stamp
|
|
40
|
+
# means the same thing — a manifest with no
|
|
41
|
+
# `schema_version` must not silently sync past a schema change.
|
|
42
|
+
_stamp="$(read_schema_version "$_cf")"
|
|
43
|
+
_eng="$(engine_version)"
|
|
44
|
+
if [ -z "$_stamp" ]; then
|
|
45
|
+
is_status needs-update "stamped= engine=$_eng (no schema_version)"
|
|
46
|
+
echo "ERROR: the manifest has no schema_version — schema un-applied." >&2
|
|
47
|
+
echo " Run: intelligence init --apply" >&2
|
|
48
|
+
exit "$IS_RC_NEEDS_UPDATE"
|
|
49
|
+
elif [ -n "$_eng" ] && _ver_gt "$_eng" "$_stamp"; then
|
|
50
|
+
is_status needs-update "stamped=$_stamp engine=$_eng"
|
|
51
|
+
echo "ERROR: project at $_stamp but engine is $_eng — pending schema changes." >&2
|
|
52
|
+
echo " Run: intelligence init --apply" >&2
|
|
53
|
+
exit "$IS_RC_NEEDS_UPDATE"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Normalize REPO_ROOT and CONFIG_FILE to one `cd && pwd` spelling so
|
|
57
|
+
# prefix-stripping in path comparisons works: Git Bash on Windows reaches the
|
|
58
|
+
# same location through `D:/...` and `/d/...`, and the CLI (or the Node shim
|
|
59
|
+
# behind it) may hand us either.
|
|
60
|
+
REPO_ROOT_RAW="${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || dirname "$CONFIG_FILE")}"
|
|
61
|
+
REPO_ROOT="$(cd "$REPO_ROOT_RAW" && pwd)"
|
|
62
|
+
unset REPO_ROOT_RAW
|
|
63
|
+
CONFIG_FILE="$(cd "$(dirname "$CONFIG_FILE")" && pwd)/$(basename "$CONFIG_FILE")"
|
|
64
|
+
|
|
65
|
+
# Layout tokens for generated output (see finalize_output_file in common.sh).
|
|
66
|
+
# Package-shipped rules/agents cannot hardcode the content dir's name — the
|
|
67
|
+
# project chooses it — so they write `<content-dir>` / `<module>` and every adapter
|
|
68
|
+
# expands them on the way out.
|
|
69
|
+
IS_CONTENT_REL="${IS_CONTENT_REL:-intelligence}"
|
|
70
|
+
# No vendor default: the CLI always exports the package path (derived from its
|
|
71
|
+
# distribution data), so a bare invocation must say so rather than guess.
|
|
72
|
+
if [ -z "${IS_MODULE_REL:-}" ]; then
|
|
73
|
+
echo "ERROR: the engine needs IS_MODULE_REL (exported by the intelligence CLI)." >&2
|
|
74
|
+
exit 1
|
|
75
|
+
fi
|
|
76
|
+
export IS_CONTENT_REL IS_MODULE_REL
|
|
77
|
+
|
|
78
|
+
# Project-owned adapters live in the content dir: <content-dir>/adapters/.
|
|
79
|
+
INTELLIGENCE_DIR="$REPO_ROOT/$IS_CONTENT_REL"
|
|
80
|
+
|
|
81
|
+
TARGET_FILTER="${1:-}"
|
|
82
|
+
|
|
83
|
+
echo "=== intelligence-sync ==="
|
|
84
|
+
echo " Config: $CONFIG_FILE"
|
|
85
|
+
echo " Root: $REPO_ROOT"
|
|
86
|
+
echo ""
|
|
87
|
+
|
|
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
|
+
# Lint frontmatter across all source files (rules, agents, skills).
|
|
114
|
+
# Catches issues like unquoted colons that strict YAML consumers reject.
|
|
115
|
+
for section in rules agents skills; do
|
|
116
|
+
while IFS= read -r src; do
|
|
117
|
+
[ -z "$src" ] && continue
|
|
118
|
+
src_dir="$(resolve_source_dir "$REPO_ROOT" "$src")"
|
|
119
|
+
[ -d "$src_dir" ] || continue
|
|
120
|
+
if [ "$section" = "skills" ]; then
|
|
121
|
+
while IFS= read -r f; do
|
|
122
|
+
[ -n "$f" ] && lint_frontmatter "$f"
|
|
123
|
+
done < <(find "$src_dir" -mindepth 2 -maxdepth 2 -name 'SKILL.md' 2>/dev/null)
|
|
124
|
+
else
|
|
125
|
+
for f in "$src_dir"/*.md; do
|
|
126
|
+
[ -f "$f" ] && lint_frontmatter "$f"
|
|
127
|
+
done
|
|
128
|
+
fi
|
|
129
|
+
done < <(read_yaml_list "$CONFIG_FILE" "$section")
|
|
130
|
+
done
|
|
131
|
+
|
|
132
|
+
# Adapters come from two places, discovered by filename (minus `.sh`,
|
|
133
|
+
# `_template` excluded):
|
|
134
|
+
#
|
|
135
|
+
# 1. Built-in — shipped inside the CLI, replaced with each CLI installation
|
|
136
|
+
# 2. Project — <content-dir>/adapters/, owned by the project and never touched
|
|
137
|
+
#
|
|
138
|
+
# A custom adapter therefore belongs in the content dir's `adapters/`; the
|
|
139
|
+
# built-in directory lives inside the installed CLI and is not the project's to
|
|
140
|
+
# edit. A project adapter whose name matches a built-in overrides it (an escape
|
|
141
|
+
# hatch for patching a built-in without forking — announced, never silent).
|
|
142
|
+
ADAPTERS=()
|
|
143
|
+
ADAPTER_FILES=()
|
|
144
|
+
|
|
145
|
+
register_adapter() {
|
|
146
|
+
local name="$1" file="$2"
|
|
147
|
+
local n=${#ADAPTERS[@]} i=0
|
|
148
|
+
while [ "$i" -lt "$n" ]; do
|
|
149
|
+
if [ "${ADAPTERS[$i]}" = "$name" ]; then
|
|
150
|
+
ADAPTER_FILES[$i]="$file"
|
|
151
|
+
echo " NOTE: project adapter '$name' overrides the built-in one ($(basename "$INTELLIGENCE_DIR")/adapters/$(basename "$file"))"
|
|
152
|
+
return 0
|
|
153
|
+
fi
|
|
154
|
+
i=$((i + 1))
|
|
155
|
+
done
|
|
156
|
+
ADAPTERS+=("$name")
|
|
157
|
+
ADAPTER_FILES+=("$file")
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
for adapters_dir in "$SCRIPT_DIR/adapters" "$INTELLIGENCE_DIR/adapters"; do
|
|
161
|
+
[ -d "$adapters_dir" ] || continue
|
|
162
|
+
for adapter_file in "$adapters_dir"/*.sh; do
|
|
163
|
+
[ -f "$adapter_file" ] || continue
|
|
164
|
+
adapter_name="$(basename "$adapter_file" .sh)"
|
|
165
|
+
[ "$adapter_name" = "_template" ] && continue
|
|
166
|
+
register_adapter "$adapter_name" "$adapter_file"
|
|
167
|
+
done
|
|
168
|
+
done
|
|
169
|
+
|
|
170
|
+
synced=0
|
|
171
|
+
adapter_count=${#ADAPTERS[@]}
|
|
172
|
+
adapter_idx=0
|
|
173
|
+
|
|
174
|
+
while [ "$adapter_idx" -lt "$adapter_count" ]; do
|
|
175
|
+
adapter="${ADAPTERS[$adapter_idx]}"
|
|
176
|
+
adapter_file="${ADAPTER_FILES[$adapter_idx]}"
|
|
177
|
+
adapter_idx=$((adapter_idx + 1))
|
|
178
|
+
|
|
179
|
+
# Skip if user requested specific target and this isn't it
|
|
180
|
+
if [ -n "$TARGET_FILTER" ] && [ "$adapter" != "$TARGET_FILTER" ]; then
|
|
181
|
+
continue
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
# Check if target is enabled in config
|
|
185
|
+
enabled=$(is_target_enabled "$CONFIG_FILE" "$adapter")
|
|
186
|
+
if [ "$enabled" != "1" ]; then
|
|
187
|
+
if [ -n "$TARGET_FILTER" ]; then
|
|
188
|
+
echo "ERROR: Adapter '$TARGET_FILTER' is disabled in $CONFIG_FILE." >&2
|
|
189
|
+
echo " Enable it first: intelligence adapter enable $TARGET_FILTER" >&2
|
|
190
|
+
exit 1
|
|
191
|
+
fi
|
|
192
|
+
continue
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
# Get output directory
|
|
196
|
+
output=$(get_target_output "$CONFIG_FILE" "$adapter")
|
|
197
|
+
if [ -z "$output" ]; then
|
|
198
|
+
output=".$adapter"
|
|
199
|
+
fi
|
|
200
|
+
output_dir="$REPO_ROOT/$output"
|
|
201
|
+
|
|
202
|
+
# Refuse to run if the output would clobber content — `output: "."`,
|
|
203
|
+
# `output: "intelligence"`, or a `../` path that escapes the repo. Applies
|
|
204
|
+
# to EVERY adapter, `agents` included: dir-writing adapters `rm -rf` their
|
|
205
|
+
# output, and `agents` overwrites whatever single file it is handed. Both
|
|
206
|
+
# turn a bad config line into a destructive write.
|
|
207
|
+
validate_output_path "$REPO_ROOT" "$CONFIG_FILE" "$adapter" "$output_dir"
|
|
208
|
+
|
|
209
|
+
# Source adapter and run.
|
|
210
|
+
# shellcheck source=/dev/null
|
|
211
|
+
source "$adapter_file"
|
|
212
|
+
"sync_to_$adapter" "$REPO_ROOT" "$CONFIG_FILE" "$output_dir"
|
|
213
|
+
echo ""
|
|
214
|
+
synced=$((synced + 1))
|
|
215
|
+
done
|
|
216
|
+
|
|
217
|
+
if [ $synced -eq 0 ]; then
|
|
218
|
+
if [ -n "$TARGET_FILTER" ]; then
|
|
219
|
+
echo "ERROR: Adapter '$TARGET_FILTER' not found."
|
|
220
|
+
echo "Available: ${ADAPTERS[*]}"
|
|
221
|
+
else
|
|
222
|
+
echo "WARNING: No targets enabled in $CONFIG_FILE"
|
|
223
|
+
fi
|
|
224
|
+
exit 1
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
# Warn about unsynced directories
|
|
228
|
+
warn_unsynced "$REPO_ROOT" "$CONFIG_FILE"
|
|
229
|
+
|
|
230
|
+
# Report model overrides that drift from intelligence-sync defaults
|
|
231
|
+
# (helpful when defaults move forward — e.g., gpt-5.5 -> gpt-5.6).
|
|
232
|
+
report_model_drift "$CONFIG_FILE"
|
|
233
|
+
|
|
234
|
+
echo ""
|
|
235
|
+
# sync.sh never changes project schemas (the CLI preflight owns that), so
|
|
236
|
+
# success is always ok.
|
|
237
|
+
is_status ok "synced=$synced"
|
|
238
|
+
echo "=== Done: $synced target(s) synced ==="
|
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.8",
|
|
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"
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
"files": [
|
|
9
9
|
"bin",
|
|
10
10
|
"cli",
|
|
11
|
-
"engine"
|
|
11
|
+
"engine",
|
|
12
|
+
"packages"
|
|
12
13
|
],
|
|
13
14
|
"engines": {
|
|
14
15
|
"node": ">=18"
|
|
@@ -16,11 +17,11 @@
|
|
|
16
17
|
"license": "MIT",
|
|
17
18
|
"repository": {
|
|
18
19
|
"type": "git",
|
|
19
|
-
"url": "git+https://github.com/ainova-systems/intelligence
|
|
20
|
+
"url": "git+https://github.com/ainova-systems/intelligence.git"
|
|
20
21
|
},
|
|
21
|
-
"homepage": "https://github.com/ainova-systems/intelligence
|
|
22
|
+
"homepage": "https://github.com/ainova-systems/intelligence#readme",
|
|
22
23
|
"bugs": {
|
|
23
|
-
"url": "https://github.com/ainova-systems/intelligence
|
|
24
|
+
"url": "https://github.com/ainova-systems/intelligence/issues"
|
|
24
25
|
},
|
|
25
26
|
"keywords": [
|
|
26
27
|
"ai",
|
|
@@ -9,12 +9,13 @@ skills:
|
|
|
9
9
|
- intelligence-add-skill
|
|
10
10
|
- intelligence-extract-skill
|
|
11
11
|
- intelligence-review-skills
|
|
12
|
+
- intelligence-learn-from-repository
|
|
12
13
|
- intelligence-learn-from-context
|
|
13
14
|
---
|
|
14
15
|
|
|
15
16
|
# Intelligence architect
|
|
16
17
|
|
|
17
|
-
Owns `<
|
|
18
|
+
Owns `<content-dir>/` itself: what the layer is made of, and what it is allowed to grow into. Not the project's code — the instructions that shape how everyone else writes it.
|
|
18
19
|
|
|
19
20
|
## Expertise
|
|
20
21
|
|
|
@@ -45,9 +46,10 @@ The per-artifact checks are procedure, so they live in the meta-skills rather th
|
|
|
45
46
|
| `intelligence-add-rule` / `intelligence-add-agent` / `intelligence-add-skill` | author one artifact |
|
|
46
47
|
| `intelligence-extract-skill` | turn an observed workflow into a skill |
|
|
47
48
|
| `intelligence-review-skills` | audit the layer for duplication, drift, size, hardcoded paths |
|
|
49
|
+
| `intelligence-learn-from-repository` | propose the initial project-owned layer from repository evidence |
|
|
48
50
|
| `intelligence-learn-from-context` | fold a session's lessons back into the layer |
|
|
49
51
|
| `intelligence-sync` | project the source to every tool channel |
|
|
50
|
-
| `intelligence-update` |
|
|
51
|
-
| `intelligence-install-adapter` / `intelligence-uninstall-adapter` |
|
|
52
|
+
| `intelligence-update` | interpret and apply the CLI's unified update plan |
|
|
53
|
+
| `intelligence-install-adapter` / `intelligence-uninstall-adapter` | research and manage a tool adapter |
|
|
52
54
|
|
|
53
55
|
A change is done when the sync is green and the skill you invoked reports clean. Size is a separate judgement: the caps are ceilings, not quotas, and a short artifact is not a defect.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: intelligence-operator
|
|
3
|
-
description: "
|
|
3
|
+
description: "Interpret CLI plans and operate sync, update, and adapter flows"
|
|
4
4
|
tier: standard
|
|
5
5
|
access: full
|
|
6
6
|
skills:
|
|
@@ -12,20 +12,17 @@ skills:
|
|
|
12
12
|
|
|
13
13
|
# Intelligence operator
|
|
14
14
|
|
|
15
|
-
Operates the
|
|
16
|
-
|
|
15
|
+
Operates the CLI: projects the source tree to every enabled tool channel, interprets and applies update
|
|
16
|
+
plans, and manages adapters. What the layer contains - which rules, agents and skills
|
|
17
17
|
exist and what they say - is `intelligence-architect`'s judgement; this agent runs the machinery
|
|
18
18
|
that ships it.
|
|
19
19
|
|
|
20
20
|
## Expertise
|
|
21
21
|
|
|
22
|
-
The status contract
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
what that code says - including stopping. The guards carry the decisions, which is why this agent
|
|
27
|
-
runs on the standard tier: the failure mode is a loud refusal and a retry, not a plausible wrong
|
|
28
|
-
answer.
|
|
22
|
+
The CLI and engine status contract. Mechanical flows are deterministic and
|
|
23
|
+
fail-closed; the agent reads their result, selects the next supported command,
|
|
24
|
+
checks changelog post-conditions, and stops on a refusal instead of recreating
|
|
25
|
+
the operation in prose.
|
|
29
26
|
|
|
30
27
|
## Boundaries
|
|
31
28
|
|
|
@@ -35,7 +32,7 @@ answer.
|
|
|
35
32
|
- **Operating is not authoring.** A change to what an artifact says - a rule body, an agent persona,
|
|
36
33
|
a skill's steps - belongs to `intelligence-architect` and the authoring meta-skills. This agent
|
|
37
34
|
ships what exists and never decides what should exist.
|
|
38
|
-
- **A state the
|
|
35
|
+
- **A state the CLI refuses to resolve goes to a human.** `ambiguous` and every other non-ok
|
|
39
36
|
status exists so that nobody guesses past a refusal; report the code and its detail, do the one
|
|
40
37
|
thing the contract names for it, and stop rather than force a way through.
|
|
41
38
|
|
|
@@ -45,5 +42,5 @@ answer.
|
|
|
45
42
|
<sync-cmd> # expect IS_STATUS=ok
|
|
46
43
|
```
|
|
47
44
|
|
|
48
|
-
Done is the invoked skill reporting its own success criteria met: `IS_STATUS=ok
|
|
49
|
-
|
|
45
|
+
Done is the invoked skill reporting its own success criteria met: `IS_STATUS=ok`,
|
|
46
|
+
per-target counts matching the sources, and no warning left unhandled.
|