@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,311 +0,0 @@
1
- #!/bin/bash
2
- # intelligence-sync: Unified sync entry point
3
- # Reads config.yaml from the umbrella folder and syncs to all enabled targets.
4
- #
5
- # Usage:
6
- # bash <umbrella>/sync/scripts/sync.sh # Sync all enabled targets
7
- # bash <umbrella>/sync/scripts/sync.sh claude # Sync only Claude
8
- # bash <umbrella>/sync/scripts/sync.sh cursor # Sync only Cursor
9
- #
10
- # Layout-agnostic: detect_layout finds the umbrella (the dir holding
11
- # config.yaml; name not hardcoded) and migrates a pre-0.3.1 flat layout into
12
- # the <umbrella>/sync/ module. REPO_ROOT: auto-detected from git, or via env.
13
-
14
- set -euo pipefail
15
-
16
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
17
-
18
- source "$SCRIPT_DIR/lib/common.sh"
19
- source "$SCRIPT_DIR/lib/layout.sh"
20
- source "$SCRIPT_DIR/lib/migrations.sh"
21
-
22
- # Umbrella = whatever folder holds config.yaml (name not hardcoded). The
23
- # module is wherever this script lives — sync.sh self-locates and does NOT
24
- # assume a folder name.
25
- detect_layout "$SCRIPT_DIR"
26
- INTELLIGENCE_DIR="$LS_UMBRELLA_DIR"
27
-
28
- # sync.sh is a PURE synchronizer — it is not a migrator. Migration across a
29
- # breaking-change gap is owned solely by the intelligence-update flow
30
- # (update.sh + skill). sync refuses to run across an un-applied gap so a
31
- # stale/mismatched engine can never generate against a newer layout.
32
- if [ "${IS_CLI:-0}" != "1" ] && [ "$LS_LAYOUT" != "modular" ]; then
33
- is_status needs-update "layout=$LS_LAYOUT"
34
- echo "ERROR: engine is not in the modular layout (layout=$LS_LAYOUT)." >&2
35
- echo " Run the update flow: tell your agent \"Update intelligence-sync\"." >&2
36
- exit "$IS_RC_NEEDS_UPDATE"
37
- fi
38
-
39
- # CLI mode (IS_CLI=1): the engine runs from outside the repo (the npm install
40
- # dir), so detect_layout cannot see the project — the project arrives through
41
- # the environment instead: CONFIG_FILE names the root manifest, REPO_ROOT the
42
- # project. The layout gate above is bypassed and the manifest is required up
43
- # front, before the version gates read it.
44
- if [ "${IS_CLI:-0}" = "1" ] && { [ -z "${CONFIG_FILE:-}" ] || [ ! -f "$CONFIG_FILE" ]; }; then
45
- is_status config-missing "cli-mode"
46
- echo "ERROR: CLI mode requires CONFIG_FILE to point at an existing manifest." >&2
47
- exit "$IS_RC_CONFIG_MISSING"
48
- fi
49
-
50
- # Schema version lives in config.yaml (the frozen contract key).
51
- _cf="${CONFIG_FILE:-$INTELLIGENCE_DIR/config.yaml}"
52
-
53
- # Stale engine vs project schema stamped NEWER (ahead-of-engine) → refuse.
54
- _vc_rc=0
55
- check_version_compat "$_cf" || _vc_rc=$?
56
- if [ "$_vc_rc" -ne 0 ]; then exit "$_vc_rc"; fi
57
-
58
- # Schema gap → refuse; the update flow must apply the migration chain first.
59
- # Per the contract, an ABSENT stamp means pre-0.3.1 / un-applied schema — a
60
- # modular tree with no `sync_version` must NOT silently sync
61
- # (that would bypass migrations). A correctly bootstrapped project always has
62
- # the key (INIT emits it; update.sh stamps it).
63
- _stamp="$(read_engine_stamp "$_cf")"
64
- _eng="$(engine_version)"
65
- if [ -z "$_stamp" ]; then
66
- is_status needs-update "stamped= engine=$_eng (no sync_version)"
67
- echo "ERROR: config.yaml has no sync_version — schema un-applied." >&2
68
- echo " Run the update flow first: tell your agent \"Update intelligence-sync\"." >&2
69
- exit "$IS_RC_NEEDS_UPDATE"
70
- elif [ -n "$_eng" ] && _ver_gt "$_eng" "$_stamp"; then
71
- is_status needs-update "stamped=$_stamp engine=$_eng"
72
- echo "ERROR: project at $_stamp but engine is $_eng — pending breaking changes." >&2
73
- echo " Run the update flow first: tell your agent \"Update intelligence-sync\"." >&2
74
- exit "$IS_RC_NEEDS_UPDATE"
75
- fi
76
-
77
- # Normalize REPO_ROOT to the same `cd && pwd` style as INTELLIGENCE_DIR so
78
- # prefix-stripping in path comparisons works (Git Bash on Windows: git
79
- # rev-parse returns `D:/...` while cd && pwd returns `/d/...`; the styles
80
- # do not match without normalization).
81
- REPO_ROOT_RAW="${REPO_ROOT:-$(git rev-parse --show-toplevel 2>/dev/null || (cd "$INTELLIGENCE_DIR/.." && pwd))}"
82
- REPO_ROOT="$(cd "$REPO_ROOT_RAW" && pwd)"
83
- unset REPO_ROOT_RAW
84
-
85
- # Layout tokens for generated output (see finalize_output_file in common.sh).
86
- # Engine-shipped rules/agents cannot hardcode the umbrella's name — the project
87
- # chooses it — so they write `<umbrella>` / `<module>` and every adapter expands
88
- # them to these repo-relative paths on the way out. In CLI mode both values are
89
- # part of the env contract: the umbrella is the project's content dir and the
90
- # module is the staged engine content inside the package store.
91
- if [ "${IS_CLI:-0}" = "1" ]; then
92
- # Re-normalize CONFIG_FILE the same way REPO_ROOT is above — the CLI (or
93
- # the Node shim behind it) may hand us `D:/...` while `cd && pwd` yields
94
- # `/d/...`, and prefix comparisons downstream need one spelling.
95
- CONFIG_FILE="$(cd "$(dirname "$CONFIG_FILE")" && pwd)/$(basename "$CONFIG_FILE")"
96
- IS_UMBRELLA_REL="${IS_UMBRELLA_REL:-intelligence}"
97
- IS_MODULE_REL="${IS_MODULE_REL:-.intelligence/packages/@ainova-systems/sync}"
98
- # Project-owned adapters keep their v1 home: <umbrella>/adapters/.
99
- INTELLIGENCE_DIR="$REPO_ROOT/$IS_UMBRELLA_REL"
100
- else
101
- IS_UMBRELLA_REL="$(repo_rel_dir "$REPO_ROOT" "$LS_UMBRELLA_DIR")"
102
- IS_MODULE_REL="$(repo_rel_dir "$REPO_ROOT" "$LS_MODULE_DIR")"
103
- IS_UMBRELLA_REL="${IS_UMBRELLA_REL:-intelligence}"
104
- IS_MODULE_REL="${IS_MODULE_REL:-intelligence/sync}"
105
- fi
106
- export IS_UMBRELLA_REL IS_MODULE_REL
107
-
108
- # Config: explicit env > config.yaml in the umbrella folder
109
- if [ -n "${CONFIG_FILE:-}" ]; then
110
- CONFIG_FILE="$CONFIG_FILE"
111
- elif [ -f "$INTELLIGENCE_DIR/config.yaml" ]; then
112
- CONFIG_FILE="$INTELLIGENCE_DIR/config.yaml"
113
- else
114
- CONFIG_FILE=""
115
- fi
116
-
117
- if [ -z "$CONFIG_FILE" ] || [ ! -f "$CONFIG_FILE" ]; then
118
- is_status config-missing "umbrella=$INTELLIGENCE_DIR"
119
- echo "ERROR: Config file not found."
120
- echo "Looked for: config.yaml (in $INTELLIGENCE_DIR)"
121
- echo "Run INIT.md bootstrap or create config.yaml manually."
122
- exit "$IS_RC_CONFIG_MISSING"
123
- fi
124
-
125
- TARGET_FILTER="${1:-}"
126
-
127
- echo "=== intelligence-sync ==="
128
- echo " Config: $CONFIG_FILE"
129
- echo " Root: $REPO_ROOT"
130
- echo ""
131
-
132
- # Invariant: AGENTS.md is the canonical carrier of always-on rules for
133
- # Cursor / Copilot / Codex / Pi / opencode (their adapters skip always-on
134
- # rules to avoid duplication, since each tool reads AGENTS.md natively for
135
- # baseline project context). If those targets are enabled, `agents` must
136
- # also be enabled — otherwise always-on rules go nowhere for those tools.
137
- # Skip the check when the user requested a single target via $TARGET_FILTER:
138
- # they may be syncing only one IDE intentionally.
139
- if [ -z "$TARGET_FILTER" ]; then
140
- agents_enabled=$(is_target_enabled "$CONFIG_FILE" "agents")
141
- if [ "$agents_enabled" != "1" ]; then
142
- # AGENTS.md-dependent adapters: any tool whose adapter skips always-on
143
- # rule emission (because the tool reads AGENTS.md natively) must be
144
- # listed here. Add new adapters to this list when they ship.
145
- for tool in cursor copilot codex pi opencode; do
146
- if [ "$(is_target_enabled "$CONFIG_FILE" "$tool")" = "1" ]; then
147
- echo "ERROR: targets.$tool is enabled but targets.agents is not." >&2
148
- echo " $tool relies on AGENTS.md to deliver always-on rules — without it," >&2
149
- echo " always-on rules would be invisible to $tool." >&2
150
- echo " Either enable targets.agents in $CONFIG_FILE, or disable targets.$tool." >&2
151
- exit 1
152
- fi
153
- done
154
- fi
155
- fi
156
-
157
- # Remote sources (declared `packs:` reached via `@<pack>`, and inline `git+`
158
- # specs in sources.*) are shallow-cloned on demand by resolve_source_dir. Give
159
- # it a run-scoped cache dir so each spec is fetched at most once per sync and is
160
- # removed on exit. Honors $TMPDIR (never hardcodes /tmp), mirroring update.sh.
161
- IS_REMOTE_CACHE="$(mktemp -d -t intelligence-sync-remotes-XXXXXX 2>/dev/null || mktemp -d)"
162
- export IS_REMOTE_CACHE
163
- trap 'rm -rf "$IS_REMOTE_CACHE"' EXIT INT TERM
164
-
165
- # A `@<pack>` token carries only the reference; its url / ref / mirror live in
166
- # config.yaml. resolve_source_dir keeps its published two-argument contract so
167
- # project-owned adapters written against it keep working, so the config path
168
- # reaches it the same way the clone cache does — through the environment.
169
- IS_CONFIG_FILE="$CONFIG_FILE"
170
- export IS_CONFIG_FILE
171
-
172
- # Fail closed on an undeclared pack reference or an unsafe mirror, before any
173
- # adapter runs — see validate_pack_refs for why this cannot live in the resolver.
174
- validate_pack_refs "$REPO_ROOT" "$CONFIG_FILE"
175
-
176
- # A pack that declares `mirror:` is additionally materialized into a tracked
177
- # directory in the repo, so an upstream bump is visible in `git diff` rather
178
- # than only in the generated output. Without it, the pack stays transient.
179
- while IFS= read -r mirror_rel; do
180
- [ -n "$mirror_rel" ] && echo " Pack mirror: $mirror_rel"
181
- done < <(list_pack_mirrors "$REPO_ROOT" "$CONFIG_FILE")
182
-
183
- # Lint frontmatter across all source files (rules, agents, skills).
184
- # Catches issues like unquoted colons that strict YAML consumers reject.
185
- for section in rules agents skills; do
186
- while IFS= read -r src; do
187
- [ -z "$src" ] && continue
188
- src_dir="$(resolve_source_dir "$REPO_ROOT" "$src")"
189
- [ -d "$src_dir" ] || continue
190
- if [ "$section" = "skills" ]; then
191
- while IFS= read -r f; do
192
- [ -n "$f" ] && lint_frontmatter "$f"
193
- done < <(find "$src_dir" -mindepth 2 -maxdepth 2 -name 'SKILL.md' 2>/dev/null)
194
- else
195
- for f in "$src_dir"/*.md; do
196
- [ -f "$f" ] && lint_frontmatter "$f"
197
- done
198
- fi
199
- done < <(read_yaml_list "$CONFIG_FILE" "$section")
200
- done
201
-
202
- # Adapters come from two places, discovered by filename (minus `.sh`,
203
- # `_template` excluded):
204
- #
205
- # 1. Built-in — <module>/scripts/adapters/ (upstream-owned; update.sh
206
- # replaces this directory wholesale on every engine update)
207
- # 2. Project — <umbrella>/adapters/ (project-owned; update.sh
208
- # never touches it)
209
- #
210
- # A custom adapter therefore belongs in the umbrella's `adapters/` — put one in
211
- # the engine's own adapters/ and the next update deletes it. A project adapter
212
- # whose name matches a built-in overrides it (an escape hatch for patching a
213
- # built-in without forking the engine — announced, never silent).
214
- ADAPTERS=()
215
- ADAPTER_FILES=()
216
-
217
- register_adapter() {
218
- local name="$1" file="$2"
219
- local n=${#ADAPTERS[@]} i=0
220
- while [ "$i" -lt "$n" ]; do
221
- if [ "${ADAPTERS[$i]}" = "$name" ]; then
222
- ADAPTER_FILES[$i]="$file"
223
- echo " NOTE: project adapter '$name' overrides the built-in one ($(basename "$INTELLIGENCE_DIR")/adapters/$(basename "$file"))"
224
- return 0
225
- fi
226
- i=$((i + 1))
227
- done
228
- ADAPTERS+=("$name")
229
- ADAPTER_FILES+=("$file")
230
- }
231
-
232
- for adapters_dir in "$SCRIPT_DIR/adapters" "$INTELLIGENCE_DIR/adapters"; do
233
- [ -d "$adapters_dir" ] || continue
234
- for adapter_file in "$adapters_dir"/*.sh; do
235
- [ -f "$adapter_file" ] || continue
236
- adapter_name="$(basename "$adapter_file" .sh)"
237
- [ "$adapter_name" = "_template" ] && continue
238
- register_adapter "$adapter_name" "$adapter_file"
239
- done
240
- done
241
-
242
- synced=0
243
- adapter_count=${#ADAPTERS[@]}
244
- adapter_idx=0
245
-
246
- while [ "$adapter_idx" -lt "$adapter_count" ]; do
247
- adapter="${ADAPTERS[$adapter_idx]}"
248
- adapter_file="${ADAPTER_FILES[$adapter_idx]}"
249
- adapter_idx=$((adapter_idx + 1))
250
-
251
- # Skip if user requested specific target and this isn't it
252
- if [ -n "$TARGET_FILTER" ] && [ "$adapter" != "$TARGET_FILTER" ]; then
253
- continue
254
- fi
255
-
256
- # Check if target is enabled in config
257
- enabled=$(is_target_enabled "$CONFIG_FILE" "$adapter")
258
- if [ "$enabled" != "1" ] && [ -z "$TARGET_FILTER" ]; then
259
- continue
260
- fi
261
-
262
- # Get output directory
263
- output=$(get_target_output "$CONFIG_FILE" "$adapter")
264
- if [ -z "$output" ]; then
265
- output=".$adapter"
266
- fi
267
- output_dir="$REPO_ROOT/$output"
268
-
269
- # Refuse to run if the output would clobber content — `output: "."`,
270
- # `output: "intelligence"`, or a `../` path that escapes the repo. Applies
271
- # to EVERY adapter, `agents` included: dir-writing adapters `rm -rf` their
272
- # output, and `agents` overwrites whatever single file it is handed. Both
273
- # turn a bad config line into a destructive write.
274
- validate_output_path "$REPO_ROOT" "$CONFIG_FILE" "$adapter" "$output_dir"
275
-
276
- # Source adapter and run.
277
- # shellcheck source=/dev/null
278
- source "$adapter_file"
279
- "sync_to_$adapter" "$REPO_ROOT" "$CONFIG_FILE" "$output_dir"
280
- echo ""
281
- synced=$((synced + 1))
282
- done
283
-
284
- if [ $synced -eq 0 ]; then
285
- if [ -n "$TARGET_FILTER" ]; then
286
- echo "ERROR: Adapter '$TARGET_FILTER' not found."
287
- echo "Available: ${ADAPTERS[*]}"
288
- else
289
- echo "WARNING: No targets enabled in $CONFIG_FILE"
290
- fi
291
- exit 1
292
- fi
293
-
294
- # Warn about unsynced directories
295
- warn_unsynced "$REPO_ROOT" "$CONFIG_FILE"
296
-
297
- # Report model overrides that drift from intelligence-sync defaults
298
- # (helpful when defaults move forward — e.g., gpt-5.5 -> gpt-5.6).
299
- report_model_drift "$CONFIG_FILE"
300
-
301
- # The intelligence CLI is the recommended setup for new projects. Recommend it
302
- # to vendored setups — stderr only, so IS_STATUS stdout parsing (skills, CI)
303
- # is untouched, and suppressible for pipelines.
304
- if [ "${IS_CLI:-0}" != "1" ] && [ -z "${IS_SUPPRESS_CLI_NOTE:-}" ]; then
305
- echo "NOTE: the intelligence CLI is now the recommended setup — 'npm i -g @ainova-systems/intelligence', then 'intelligence migrate'. This vendored flow keeps working." >&2
306
- fi
307
-
308
- echo ""
309
- # sync.sh never migrates (the update flow owns that), so success is always ok.
310
- is_status ok "synced=$synced"
311
- echo "=== Done: $synced target(s) synced ==="
@@ -1,237 +0,0 @@
1
- #!/bin/bash
2
- # intelligence-sync: self-update
3
- # Pulls the latest upstream-owned content into the local vendored module:
4
- # <umbrella>/sync/scripts/ sync engine + adapters
5
- # <umbrella>/sync/INIT.md bootstrap prompt
6
- # <umbrella>/sync/skills/intelligence-* meta-skills (by reserved prefix)
7
- # <umbrella>/sync/docs/ vendored docs
8
- # Project content (config.yaml, rules/, agents/, non-meta skills/) is never
9
- # touched — except an idempotent additive line in config.yaml sources.skills
10
- # when migrating a pre-0.3.1 flat project.
11
- #
12
- # The umbrella folder name is not hardcoded (intelligence/, Intelligence/, …).
13
- # Pre-0.3.1 projects laid the engine out flat under the umbrella; this script
14
- # transparently migrates them into the <umbrella>/sync/ module.
15
- #
16
- # Usage:
17
- # bash <umbrella>/sync/scripts/update.sh # interactive
18
- # bash <umbrella>/sync/scripts/update.sh --yes # apply without prompt
19
- # REPO_URL=<url> bash .../update.sh # custom upstream
20
- #
21
- # Cross-platform: uses `mktemp -d` (Linux/macOS/Windows Git Bash).
22
- # Honors $TMPDIR / $TMP / $TEMP — never hardcodes /tmp.
23
-
24
- set -euo pipefail
25
-
26
- REPO_URL="${REPO_URL:-https://github.com/ainova-systems/intelligence-sync.git}"
27
- SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
28
- AUTO_YES=0
29
- [ "${1:-}" = "--yes" ] && AUTO_YES=1
30
-
31
- source "$SCRIPT_DIR/lib/layout.sh"
32
- source "$SCRIPT_DIR/lib/migrations.sh"
33
-
34
- detect_layout "$SCRIPT_DIR"
35
- UMBRELLA="$LS_UMBRELLA_DIR"
36
- CONFIG_FILE_PATH="$UMBRELLA/config.yaml"
37
-
38
- # Local module dir = wherever this engine lives (self-located, any name) when
39
- # already modular; for a pre-0.3.1 flat project the module does not exist yet,
40
- # so it is created under the conventional name `sync`. MODULE_NAME is only the
41
- # creation convention — not a rename feature, not used to find the upstream.
42
- if [ "$LS_LAYOUT" = "modular" ]; then
43
- MODULE_DIR="$LS_MODULE_DIR"
44
- MODULE_NAME="$LS_MODULE_NAME"
45
- else
46
- MODULE_NAME="sync"
47
- MODULE_DIR="$UMBRELLA/$MODULE_NAME"
48
- fi
49
- # The upstream repo's module is always `sync/` by convention, independent of
50
- # whatever the local module is named.
51
- UPSTREAM_MODULE="sync"
52
-
53
- WORK_DIR=$(mktemp -d -t intelligence-sync-update-XXXXXX 2>/dev/null || mktemp -d)
54
- trap 'rm -rf "$WORK_DIR"' EXIT INT TERM
55
-
56
- echo "=== intelligence-sync: self-update ==="
57
- echo " Upstream: $REPO_URL"
58
- echo " Umbrella: $UMBRELLA (layout: $LS_LAYOUT)"
59
- echo " Module: $MODULE_DIR"
60
- echo " Work dir: $WORK_DIR"
61
- echo ""
62
-
63
- if ! command -v git >/dev/null 2>&1; then
64
- echo "ERROR: git is required."
65
- exit 1
66
- fi
67
-
68
- echo " Cloning latest..."
69
- # LF regardless of the host's core.autocrlf: this checkout is copied verbatim
70
- # into the project, so a CRLF one on Windows would install CRLF shell scripts.
71
- git -c core.autocrlf=false -c core.eol=lf clone --depth=1 --quiet "$REPO_URL" "$WORK_DIR"
72
-
73
- # Normalize the upstream into a single module-shaped staging dir so the rest
74
- # of this script is layout-agnostic. Accept either upstream shape:
75
- # modular: $WORK_DIR/intelligence/sync/{scripts,INIT.md,docs,skills}
76
- # legacy : $WORK_DIR/intelligence/{scripts,INIT.md,skills} + $WORK_DIR/docs
77
- UPMOD="$WORK_DIR/_module"
78
- mkdir -p "$UPMOD/skills"
79
- if [ -d "$WORK_DIR/intelligence/$UPSTREAM_MODULE/scripts" ]; then
80
- _SRC="$WORK_DIR/intelligence/$UPSTREAM_MODULE"
81
- cp -r "$_SRC/scripts" "$UPMOD/scripts"
82
- [ -f "$_SRC/INIT.md" ] && cp "$_SRC/INIT.md" "$UPMOD/INIT.md"
83
- [ -d "$_SRC/docs" ] && cp -r "$_SRC/docs" "$UPMOD/docs"
84
- # Engine-owned rule + agent (0.7.0+). Absent in older upstreams — optional.
85
- [ -d "$_SRC/rules" ] && cp -r "$_SRC/rules" "$UPMOD/rules"
86
- [ -d "$_SRC/agents" ] && cp -r "$_SRC/agents" "$UPMOD/agents"
87
- for s in "$_SRC"/skills/intelligence-*; do
88
- [ -d "$s" ] && cp -r "$s" "$UPMOD/skills/"
89
- done
90
- elif [ -d "$WORK_DIR/intelligence/scripts" ]; then
91
- cp -r "$WORK_DIR/intelligence/scripts" "$UPMOD/scripts"
92
- [ -f "$WORK_DIR/intelligence/INIT.md" ] && cp "$WORK_DIR/intelligence/INIT.md" "$UPMOD/INIT.md"
93
- [ -d "$WORK_DIR/docs" ] && cp -r "$WORK_DIR/docs" "$UPMOD/docs"
94
- for s in "$WORK_DIR/intelligence"/skills/intelligence-*; do
95
- [ -d "$s" ] && cp -r "$s" "$UPMOD/skills/"
96
- done
97
- else
98
- is_status error "upstream-layout-unrecognized"
99
- echo "ERROR: upstream layout unrecognized — no intelligence/$UPSTREAM_MODULE/scripts/ or intelligence/scripts/."
100
- exit "$IS_RC_ERROR"
101
- fi
102
-
103
- # Local module dir to diff against: the existing module, or (pre-migration)
104
- # the flat legacy locations.
105
- if [ -d "$MODULE_DIR/scripts" ]; then
106
- _LOCAL="$MODULE_DIR"
107
- else
108
- _LOCAL="$UMBRELLA" # legacy flat
109
- fi
110
-
111
- echo ""
112
- echo " Diff (scripts/):"
113
- diff -ruN "$_LOCAL/scripts" "$UPMOD/scripts" || true
114
- echo ""
115
- echo " Diff (INIT.md):"
116
- diff -uN "$_LOCAL/INIT.md" "$UPMOD/INIT.md" 2>/dev/null || true
117
- echo ""
118
- echo " Diff (meta-skills intelligence-*):"
119
- for up in "$UPMOD"/skills/intelligence-*; do
120
- [ -d "$up" ] || continue
121
- name=$(basename "$up")
122
- diff -ruN "$_LOCAL/skills/$name" "$up" 2>/dev/null || true
123
- done
124
- if [ -d "$UPMOD/docs" ]; then
125
- echo ""
126
- echo " Diff (docs/):"
127
- diff -ruN "$_LOCAL/docs" "$UPMOD/docs" 2>/dev/null || true
128
- fi
129
- # Engine-owned rule + agent (0.7.0+): upstream-owned like the meta-skills, and
130
- # distinct from the project's own <umbrella>/rules and <umbrella>/agents.
131
- for _d in rules agents; do
132
- [ -d "$UPMOD/$_d" ] || continue
133
- echo ""
134
- echo " Diff (engine $_d/):"
135
- diff -ruN "$_LOCAL/$_d" "$UPMOD/$_d" 2>/dev/null || true
136
- done
137
-
138
- if [ $AUTO_YES -ne 1 ]; then
139
- echo ""
140
- if [ "$LS_LAYOUT" = "legacy" ]; then
141
- echo " NOTE: pre-0.3.1 flat layout — the engine will be MIGRATED into '$MODULE_NAME/'."
142
- echo " Legacy scripts/, INIT.md, docs/, and intelligence-* skills move there;"
143
- echo " a single additive line is added to config.yaml sources.skills."
144
- fi
145
- read -r -p "Apply update? Engine/INIT/meta-skills/docs + engine rule/agent overwritten; YOUR rules/agents/skills NOT touched. [y/N] " confirm
146
- case "$confirm" in
147
- y|Y|yes|YES) ;;
148
- *) echo " Cancelled."; exit 0 ;;
149
- esac
150
- fi
151
-
152
- # CRITICAL: run the DESTINATION engine's migration chain, not the stale local
153
- # one. A breaking migration shipped in the new version is defined only in the
154
- # upstream migrations.sh; re-source it so MIGRATIONS / migrate_to_* /
155
- # run_migrations / engine_version all reflect the version we are applying.
156
- # Otherwise a new breaking change would be silently skipped while the version
157
- # still advances — the exact corruption this architecture exists to prevent.
158
- if [ -f "$UPMOD/scripts/lib/migrations.sh" ]; then
159
- # shellcheck source=/dev/null
160
- source "$UPMOD/scripts/lib/migrations.sh"
161
- fi
162
-
163
- # Migrate via the upstream chain (authoritative content from UPMOD).
164
- # Idempotent: a no-op on already-current projects. Fail-closed: on a state
165
- # bash will not resolve it emits IS_STATUS + a stable code and we stop so the
166
- # intelligence-update skill can take over (never partially destroys).
167
- _mig_rc=0
168
- run_migrations "$UMBRELLA" "$MODULE_NAME" "$UPMOD" || _mig_rc=$?
169
- if [ "$_mig_rc" -ne 0 ]; then exit "$_mig_rc"; fi
170
-
171
- # In-place refresh of the module (covers already-modular projects, and
172
- # re-asserts content post-migration). Idempotent.
173
- mkdir -p "$MODULE_DIR/skills"
174
- if command -v rsync >/dev/null 2>&1; then
175
- rsync -a --delete "$UPMOD/scripts/" "$MODULE_DIR/scripts/"
176
- else
177
- rm -rf "$MODULE_DIR/scripts"; cp -r "$UPMOD/scripts" "$MODULE_DIR/scripts"
178
- fi
179
- [ -f "$UPMOD/INIT.md" ] && cp "$UPMOD/INIT.md" "$MODULE_DIR/INIT.md"
180
- for _d in rules agents; do
181
- [ -d "$UPMOD/$_d" ] || continue
182
- if command -v rsync >/dev/null 2>&1; then
183
- mkdir -p "$MODULE_DIR/$_d"
184
- rsync -a --delete "$UPMOD/$_d/" "$MODULE_DIR/$_d/"
185
- else
186
- # `:?` so an empty MODULE_DIR/_d can never expand this into `rm -rf /`.
187
- rm -rf "${MODULE_DIR:?}/${_d:?}"; cp -r "$UPMOD/$_d" "$MODULE_DIR/$_d"
188
- fi
189
- done
190
- if [ -d "$UPMOD/docs" ]; then
191
- if command -v rsync >/dev/null 2>&1; then
192
- rsync -a --delete "$UPMOD/docs/" "$MODULE_DIR/docs/"
193
- else
194
- rm -rf "$MODULE_DIR/docs"; cp -r "$UPMOD/docs" "$MODULE_DIR/docs"
195
- fi
196
- fi
197
- for up in "$UPMOD"/skills/intelligence-*; do
198
- [ -d "$up" ] || continue
199
- name=$(basename "$up")
200
- if command -v rsync >/dev/null 2>&1; then
201
- rsync -a --delete "$up/" "$MODULE_DIR/skills/$name/"
202
- else
203
- rm -rf "$MODULE_DIR/skills/$name"; cp -r "$up" "$MODULE_DIR/skills/$name"
204
- fi
205
- done
206
- # Prune local meta-skills no longer upstream (deprecated ones disappear; no
207
- # duplicates, project skills untouched).
208
- for local_skill in "$MODULE_DIR"/skills/intelligence-*; do
209
- [ -d "$local_skill" ] || continue
210
- name=$(basename "$local_skill")
211
- [ -d "$UPMOD/skills/$name" ] || { echo " Removing meta-skill no longer upstream: $name"; rm -rf "$local_skill"; }
212
- done
213
-
214
- # Stamp the applied schema version into config.yaml (the frozen contract
215
- # key). Covers the already-modular in-place path where no migration ran.
216
- _ver="0.3.1"
217
- [ -f "$UPMOD/scripts/VERSION" ] && _ver="$(tr -d ' \r\n' < "$UPMOD/scripts/VERSION")"
218
- stamp_version "$CONFIG_FILE_PATH" "$_ver"
219
-
220
- find "$MODULE_DIR/scripts" -name '*.sh' -exec chmod +x {} \; 2>/dev/null || true
221
-
222
- echo ""
223
- if [ "${IS_MIGRATED:-0}" -eq 1 ]; then
224
- is_status migrated "version=$_ver"
225
- else
226
- is_status ok "version=$_ver"
227
- fi
228
- echo " Updated: $MODULE_NAME/{scripts,INIT.md,docs}, $MODULE_NAME/skills/intelligence-*, $MODULE_NAME/{rules,agents} (version $_ver)"
229
- echo " Untouched: your <umbrella>/rules, <umbrella>/agents, project skills, <umbrella>/adapters."
230
- echo " config.yaml only gains the engine's managed keys (sync_version, module sources)."
231
- echo " Next: bash $MODULE_NAME/scripts/sync.sh"
232
-
233
- # The intelligence CLI is the recommended setup for new projects. stderr only,
234
- # so IS_STATUS stdout parsing (skills, CI) is untouched; suppressible for CI.
235
- if [ -z "${IS_SUPPRESS_CLI_NOTE:-}" ]; then
236
- echo "NOTE: the intelligence CLI is now the recommended setup — 'npm i -g @ainova-systems/intelligence', then 'intelligence migrate'. This vendored flow keeps working." >&2
237
- fi
@@ -1,31 +0,0 @@
1
- ---
2
- name: intelligence-install-adapter
3
- description: "Enable IDE adapter for intelligence-sync"
4
- argument-hint: <target-name>
5
- agent: intelligence-operator
6
- ---
7
-
8
- # Install Adapter
9
-
10
- The project's config is `<manifest>`; the content dir is `<umbrella>/` (never assume the name or casing); the engine's own files live under `<module>/` — these paths are localized to this project at sync time.
11
-
12
- ## Steps
13
-
14
- 1. Check whether target `$ARGUMENTS` is already enabled in `<manifest>` — if yes, report and stop.
15
-
16
- 2. **Locate the adapter.** The sync discovers adapters in two places:
17
- - **Built-in**: `<module>/scripts/adapters/$ARGUMENTS.sh` — upstream-owned. Every engine update replaces that whole directory.
18
- - **Project-owned**: `<umbrella>/adapters/$ARGUMENTS.sh` — updates never touch it. A project adapter of the same name overrides the built-in.
19
-
20
- If neither exists, research the tool's prompt format (web search for its rules / agents / skills file layout), then copy `<module>/scripts/adapters/_template.sh` to **`<umbrella>/adapters/$ARGUMENTS.sh`** and implement `sync_to_$ARGUMENTS()`. Author it there, never inside the engine's `scripts/adapters/` — a file written there is deleted by the next engine update. Adapter contract: `<module>/docs/ADAPTERS.md`. An adapter that would serve every project is worth contributing upstream.
21
-
22
- 3. Update `<manifest>`:
23
- - Target exists with `enabled: false` → flip to `enabled: true`.
24
- - Target missing → add it under `targets:` with its `output:` path.
25
- - If the target reads always-on rules from `AGENTS.md` (`cursor`, `copilot`, `codex`, `pi`, `opencode`), `targets.agents` must be enabled too — sync fails closed otherwise.
26
-
27
- 4. Add the adapter's generated paths to `.gitignore` (the paths it writes, not the whole output root — a shared root like `.github/` or `.claude/` also holds tracked, hand-authored files).
28
-
29
- 5. Run `/intelligence-sync` to generate the output.
30
-
31
- 6. Report: adapter enabled, files generated, output location.
@@ -1,16 +0,0 @@
1
- ---
2
- name: intelligence-sync
3
- description: "Sync intelligence to enabled IDE targets"
4
- agent: intelligence-operator
5
- context: fork
6
- ---
7
-
8
- Run the sync engine to transform rules, agents, and skills from the intelligence sources to each enabled IDE's native format.
9
-
10
- > **The sync never migrates.** It is a pure synchronizer: across an un-applied schema it **fails closed** with `IS_STATUS=needs-update` (exit 6) and changes nothing. Bringing the project up to the engine is the update flow's job — in a vendored setup tell your agent *"Update intelligence-sync"* (the `intelligence-update` skill); in a CLI setup (root `intelligence.yaml`) run `npm i -g @ainova-systems/intelligence@latest` and `intelligence upgrade` — then re-run sync.
11
-
12
- ## Steps
13
-
14
- 1. Run `<sync-cmd>`.
15
- 2. Review the output — verify rule, agent, and skill counts per target, and that it ends with `IS_STATUS=ok`.
16
- 3. If warnings about unsynced directories appear, add the missing paths under `sources:` in `<manifest>`.
@@ -1,42 +0,0 @@
1
- ---
2
- name: intelligence-uninstall-adapter
3
- description: "Disable IDE adapter and clean up output"
4
- argument-hint: <target-name>
5
- agent: intelligence-operator
6
- ---
7
-
8
- # Uninstall Adapter
9
-
10
- The project's config is `<manifest>`; the content dir is `<umbrella>/` (never assume the name or casing); the engine's own files live under `<module>/` — these paths are localized to this project at sync time.
11
-
12
- ## Steps
13
-
14
- 1. Set `enabled: false` for the target in `<manifest>`.
15
-
16
- 2. **Remove only the paths the adapter owns — never the output root.** Several adapters write into a shared root that also holds files nobody generated: `.github/` holds `workflows/`, `.claude/` holds `settings.json`, `.opencode/` holds `opencode.json`. Deleting the root destroys hand-authored work, and no adapter ever does that on re-sync.
17
-
18
- | Target | Remove | Keep (never adapter-owned) |
19
- |---|---|---|
20
- | `claude` | `.claude/rules/`, `.claude/agents/`, skill subdirs in `.claude/skills/` | `.claude/` itself, `settings.json`, `settings.local.json`, `commands/` |
21
- | `cursor` | `.cursor/rules/`, `.cursor/agents/`, `.cursor/skills/` | `.cursor/` itself, `settings.json` |
22
- | `copilot` | `.github/instructions/`, `.github/prompts/`, `.github/agents/`, skill subdirs in `.github/skills/` | `.github/` itself, `workflows/`, `ISSUE_TEMPLATE/`, a hand-authored `copilot-instructions.md` |
23
- | `codex` | `.codex/agents/` | `.codex/` itself |
24
- | `pi` | `.pi/intelligence-sync/`, `.pi/extensions/intelligence-sync-rules.ts`, `.pi/prompts/intelligence-agent-*.md` | `.pi/settings.json`, any other extension or prompt |
25
- | `opencode` | `.opencode/agents/`, and only the files in `.opencode/commands/` carrying the `<!-- Generated by intelligence-sync. Do not edit manually. -->` marker | `.opencode/opencode.json`, hand-authored commands |
26
- | `agents` | `AGENTS.md` — only if the user confirms; it is a committed project doc | — |
27
-
28
- `.agents/skills/` is **shared** by `codex`, `pi` and `opencode`. Remove it only when none of those three remains enabled.
29
-
30
- For an adapter not in this table (a project adapter under `<umbrella>/adapters/`), read its `sync_to_<name>()` cleanup block: whatever it deletes on every re-sync is exactly what it owns.
31
-
32
- 3. Remove the adapter's paths from `.gitignore` if nothing else needs them.
33
-
34
- 4. Run `/intelligence-sync` to regenerate the remaining targets.
35
-
36
- 5. **Verify** — an uninstall that removed the wrong thing must not pass quietly:
37
- - sync reports `IS_STATUS=ok`;
38
- - every path listed under *Remove* for this target is gone;
39
- - every path listed under *Keep* still exists, with its content intact (`.github/workflows/`, `.claude/settings.json`, `.opencode/opencode.json`, hand-authored commands);
40
- - the other enabled targets still produce their output.
41
-
42
- 6. Report: adapter disabled, which paths were removed, which were deliberately kept, and the verification result.