kodelyth-ecc 2.1.1 → 2.1.2

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/CHANGELOG.md CHANGED
@@ -2,6 +2,37 @@
2
2
 
3
3
  All notable changes to Kodelyth ECC are documented here.
4
4
 
5
+ ## v2.1.2 — Install-flow fixes caught by live user testing (July 2026)
6
+
7
+ Ran the actual `npx kodelyth-ecc --target claude-code` flow as a user would, end-to-end. Three real bugs surfaced and got fixed.
8
+
9
+ ### Fixed
10
+
11
+ - **`--target claude-code` was rejected** with "Unknown target." install.sh only knew `claude-home`, but every doc, README, and CHANGELOG example uses `claude-code`. install.sh now accepts both (`claude-home|claude-code)` case)
12
+ - **Post-install RTK block silently skipped** on the (correct) `--target claude-code` because `TARGET_MAP` was keyed on `claude-home`. Added `normalizeTarget()` and both the RTK and terse post-install blocks now normalise the target before lookup. `gemini-cli` → `gemini-home`, `cursor` → `cursor-project` also normalised
13
+ - **install.sh `/dev/tty` read failed on piped/CI shells** even though the guard tested `-e /dev/tty`. Guard now also tests `-r /dev/tty` and honours `KODELYTH_NONINTERACTIVE=1` env (Windows PowerShell path already set this)
14
+ - **install.sh footer showed stale `v1.8.1`** from a leftover VERSION file. Bumped to current
15
+
16
+ ### Verified end-to-end on this Mac
17
+
18
+ ```
19
+ $ npm i -g kodelyth-ecc && kodelyth-ecc --target claude-code
20
+ ...
21
+ ━ RTK token savings ─────────────────────────────
22
+ ✓ RTK 0.42.4 — wired for claude-home
23
+ ✓ Restart your AI tool to activate. 60-90% token savings on shell commands.
24
+
25
+ ━ Terse mode ────────────────────────────────────
26
+ ✓ /terse and /terse-compress installed for claude-home
27
+ · Activate any time: type /terse in your AI tool (dormant until you do)
28
+ ```
29
+
30
+ Files land at `~/.claude/skills/terse-mode/SKILL.md` and `~/.claude/commands/terse.md`. Discoverable by the AI on next session.
31
+
32
+ ### Added
33
+
34
+ - `scripts/rtk/index.js` — `normalizeTarget(target)` exported. Accepts `claude-code`, `gemini-cli`, `cursor` and returns the canonical install.sh target names. `roocode` and `kimi` also added to `TARGET_MAP`
35
+
5
36
  ## v2.0.0 — Terse mode: output-token compressor + memory compressor (July 2026)
6
37
 
7
38
  RTK saves input tokens. Terse mode now saves output tokens. Together — on a typical coding session — ECC cuts ~55-65% of total token cost while keeping code, commands, and errors byte-exact.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 1.8.1
1
+ 2.1.2
@@ -351,30 +351,39 @@ if (args[0] === 'terse') {
351
351
  }
352
352
  }
353
353
 
354
+ // Normalise alias → canonical target (matches scripts/rtk/index.js).
355
+ function _canon(target) {
356
+ if (target === 'claude-code') return 'claude-home';
357
+ if (target === 'gemini-cli') return 'gemini-home';
358
+ if (target === 'cursor') return 'cursor-project';
359
+ return target;
360
+ }
354
361
  function getTargetSkillsDir(target) {
355
362
  const home = os.homedir();
356
- switch (target) {
357
- case 'claude-code': return path.join(home, '.claude', 'skills');
358
- case 'cursor':
363
+ switch (_canon(target)) {
364
+ case 'claude-home': return path.join(home, '.claude', 'skills');
359
365
  case 'cursor-project': return path.join(home, '.cursor', 'skills');
360
- case 'windsurf-home': return path.join(home, '.codeium', 'windsurf', 'skills');
366
+ case 'windsurf-home':
367
+ case 'windsurf-project': return path.join(home, '.codeium', 'windsurf', 'skills');
361
368
  case 'antigravity': return path.join(home, '.antigravity', 'skills');
362
369
  case 'codex-home': return path.join(home, '.codex', 'skills');
363
- case 'gemini-cli': return path.join(home, '.gemini', 'skills');
370
+ case 'gemini-home': return path.join(home, '.gemini', 'skills');
371
+ case 'gemini-project': return path.join(process.cwd(), '.gemini', 'skills');
364
372
  case 'opencode': return path.join(home, '.config', 'opencode', 'skills');
365
373
  default: return null;
366
374
  }
367
375
  }
368
376
  function getTargetCommandsDir(target) {
369
377
  const home = os.homedir();
370
- switch (target) {
371
- case 'claude-code': return path.join(home, '.claude', 'commands');
372
- case 'cursor':
378
+ switch (_canon(target)) {
379
+ case 'claude-home': return path.join(home, '.claude', 'commands');
373
380
  case 'cursor-project': return path.join(home, '.cursor', 'commands');
374
- case 'windsurf-home': return path.join(home, '.codeium', 'windsurf', 'commands');
381
+ case 'windsurf-home':
382
+ case 'windsurf-project': return path.join(home, '.codeium', 'windsurf', 'commands');
375
383
  case 'antigravity': return path.join(home, '.antigravity', 'commands');
376
384
  case 'codex-home': return path.join(home, '.codex', 'commands');
377
- case 'gemini-cli': return path.join(home, '.gemini', 'commands');
385
+ case 'gemini-home': return path.join(home, '.gemini', 'commands');
386
+ case 'gemini-project': return path.join(process.cwd(), '.gemini', 'commands');
378
387
  case 'opencode': return path.join(home, '.config', 'opencode', 'commands');
379
388
  default: return null;
380
389
  }
@@ -1232,7 +1241,8 @@ if (isWin) {
1232
1241
  try {
1233
1242
  const rtk = require(path.join(ROOT, 'scripts', 'rtk', 'index.js'));
1234
1243
  const targetIdx = args.indexOf('--target');
1235
- const target = targetIdx >= 0 && args[targetIdx + 1] ? args[targetIdx + 1] : 'claude-code';
1244
+ const rawTarget = targetIdx >= 0 && args[targetIdx + 1] ? args[targetIdx + 1] : 'claude-code';
1245
+ const target = rtk.normalizeTarget(rawTarget);
1236
1246
  if (rtk.TARGET_MAP[target]) {
1237
1247
  const w = (m) => process.stdout.write(m + '\n');
1238
1248
  w('');
@@ -1261,7 +1271,8 @@ if (isWin) {
1261
1271
  try {
1262
1272
  const rtk2 = require(path.join(ROOT, 'scripts', 'rtk', 'index.js'));
1263
1273
  const targetIdx = args.indexOf('--target');
1264
- const target = targetIdx >= 0 && args[targetIdx + 1] ? args[targetIdx + 1] : 'claude-code';
1274
+ const rawTarget = targetIdx >= 0 && args[targetIdx + 1] ? args[targetIdx + 1] : 'claude-code';
1275
+ const target = rtk2.normalizeTarget(rawTarget);
1265
1276
  const skillsDir = getTargetSkillsDir(target);
1266
1277
  const cmdsDir = getTargetCommandsDir(target);
1267
1278
  if (skillsDir && cmdsDir) {
package/install.sh CHANGED
@@ -233,7 +233,7 @@ HOME_DIR="$HOME"
233
233
  WINDSURFRULES_DEST="" # only set for windsurf targets
234
234
 
235
235
  case "$TARGET" in
236
- claude-home)
236
+ claude-home|claude-code)
237
237
  DEST="$HOME_DIR/.claude"
238
238
  AGENTS_DEST="$DEST/agents"
239
239
  SKILLS_DEST="$DEST/skills"
@@ -361,7 +361,7 @@ case "$TARGET" in
361
361
  ;;
362
362
  *)
363
363
  echo -e "${RED}Unknown target: $TARGET${RESET}"
364
- echo "Valid targets: claude-home, antigravity, cursor-project, windsurf-project, windsurf-home, codex-home, opencode, cline, roocode, aider, kimi, gemini-project, gemini-home"
364
+ echo "Valid targets: claude-home (aka claude-code), antigravity, cursor-project, windsurf-project, windsurf-home, codex-home, opencode, cline, roocode, aider, kimi, gemini-project, gemini-home"
365
365
  exit 1
366
366
  ;;
367
367
  esac
@@ -375,8 +375,12 @@ fi
375
375
  echo ""
376
376
 
377
377
  # ── Confirm ───────────────────────────────────────────────────────────────────
378
- if [[ -e /dev/tty ]]; then
379
- read -r -p "$(echo -e "${YELLOW}Proceed with install? [Y/n] ${RESET}")" CONFIRM </dev/tty
378
+ # Honour KODELYTH_NONINTERACTIVE=1 for CI, npx pipes, and Windows powershell path.
379
+ if [[ "${KODELYTH_NONINTERACTIVE:-}" == "1" ]]; then
380
+ CONFIRM="Y"
381
+ echo -e "${CYAN} Non-interactive mode (KODELYTH_NONINTERACTIVE=1) — proceeding.${RESET}"
382
+ elif [[ -e /dev/tty ]] && [[ -r /dev/tty ]]; then
383
+ read -r -p "$(echo -e "${YELLOW}Proceed with install? [Y/n] ${RESET}")" CONFIRM </dev/tty || CONFIRM="Y"
380
384
  CONFIRM="${CONFIRM:-Y}"
381
385
  else
382
386
  CONFIRM="Y"
@@ -476,7 +480,7 @@ echo -e "${BOLD}Installing components...${RESET}"
476
480
  echo ""
477
481
 
478
482
  case "$TARGET" in
479
- claude-home)
483
+ claude-home|claude-code)
480
484
  install_dir "$SCRIPT_DIR/agents" "$AGENTS_DEST" "Agents ($AGENT_COUNT)"
481
485
  install_dir "$SCRIPT_DIR/skills" "$SKILLS_DEST" "Skills ($SKILL_COUNT)"
482
486
  install_dir "$SCRIPT_DIR/commands" "$COMMANDS_DEST" "Commands ($CMD_COUNT)"
@@ -685,7 +689,7 @@ echo -e "${GREEN}${BOLD} ARMED AND OPERATIONAL.${RESET}"
685
689
  echo ""
686
690
 
687
691
  case "$TARGET" in
688
- claude-home)
692
+ claude-home|claude-code)
689
693
  echo -e "${BOLD} Claude Code — what to do now:${RESET}"
690
694
  echo ""
691
695
  echo " Open any project in Claude Code, then:"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kodelyth-ecc",
3
- "version": "2.1.1",
3
+ "version": "2.1.2",
4
4
  "description": "Production-grade AI coding toolkit — 70 agents (incl. devil-mode adversarial crew), 194 skills, 97 commands, parallel multi-agent commands, semantic intent routing, self-learning memory, and a built-in MCP server (16 tools / 6 prompts / 377 resources) that bridges to Claude Desktop, LangGraph, AutoGen, CrewAI, and OpenAI Agents SDK. Works with Claude Code, Windsurf, Cursor, Codex, Antigravity, OpenCode, Cline, RooCode, Aider, Kimi, and Gemini CLI.",
5
5
  "author": "Kodelyth <github.com/sifxprime>",
6
6
  "license": "MIT",
@@ -18,9 +18,10 @@ const fs = require('fs');
18
18
 
19
19
  // ── ECC install target → RTK agent flag ──────────────────────────────────────
20
20
  // Reference: `rtk init --help` and RTK README "Supported AI Tools" table.
21
+ // Keyed by canonical install.sh target names (claude-home, gemini-home, ...).
22
+ // Common aliases (claude-code, gemini-cli) are normalised in normalizeTarget().
21
23
  const TARGET_MAP = {
22
- 'claude-code': ['init', '-g'],
23
- 'cursor': ['init', '-g', '--agent', 'cursor'],
24
+ 'claude-home': ['init', '-g'],
24
25
  'cursor-project': ['init', '--agent', 'cursor'],
25
26
  'windsurf-home': ['init', '-g', '--agent', 'windsurf'],
26
27
  'windsurf-project': ['init', '--agent', 'windsurf'],
@@ -28,22 +29,32 @@ const TARGET_MAP = {
28
29
  'codex-home': ['init', '-g', '--codex'],
29
30
  'opencode': ['init', '-g', '--opencode'],
30
31
  'cline': ['init', '--agent', 'cline'],
31
- 'gemini-cli': ['init', '-g', '--gemini'],
32
+ 'gemini-home': ['init', '-g', '--gemini'],
33
+ 'roocode': ['init', '--agent', 'cline'], // roocode is cline-compatible per RTK
34
+ 'kimi': ['init', '-g'], // treat like claude-code hook
32
35
  };
33
36
 
37
+ // Normalise well-known aliases → canonical target names used by install.sh.
38
+ function normalizeTarget(t) {
39
+ if (t === 'claude-code') return 'claude-home';
40
+ if (t === 'gemini-cli') return 'gemini-home';
41
+ if (t === 'cursor') return 'cursor-project';
42
+ return t;
43
+ }
44
+
34
45
  // ── Detect which IDEs ECC has already been installed for on this machine ─────
35
46
  // Returns list of ECC install-target strings that have visible ECC artifacts.
36
47
  function detectInstalledTargets() {
37
48
  const home = os.homedir();
38
49
  const targets = [];
39
50
  const checks = [
40
- { target: 'claude-code', dir: path.join(home, '.claude', 'agents') },
41
- { target: 'cursor', dir: path.join(home, '.cursor', 'rules') },
51
+ { target: 'claude-home', dir: path.join(home, '.claude', 'agents') },
52
+ { target: 'cursor-project', dir: path.join(home, '.cursor', 'rules') },
42
53
  { target: 'windsurf-home', dir: path.join(home, '.codeium', 'windsurf', 'memories') },
43
54
  { target: 'antigravity', dir: path.join(home, '.antigravity') },
44
55
  { target: 'codex-home', dir: path.join(home, '.codex') },
45
56
  { target: 'opencode', dir: path.join(home, '.config', 'opencode') },
46
- { target: 'gemini-cli', dir: path.join(home, '.gemini') },
57
+ { target: 'gemini-home', dir: path.join(home, '.gemini') },
47
58
  ];
48
59
  for (const { target, dir } of checks) {
49
60
  try {
@@ -116,15 +127,16 @@ function enableFor(target, { log = () => {} } = {}) {
116
127
  if (!isInstalled()) {
117
128
  return { enabled: false, skipped: true, reason: 'rtk binary not on PATH' };
118
129
  }
119
- const rtkArgs = TARGET_MAP[target];
130
+ const canonical = normalizeTarget(target);
131
+ const rtkArgs = TARGET_MAP[canonical];
120
132
  if (!rtkArgs) {
121
133
  return { enabled: false, skipped: true, reason: `no RTK mapping for target "${target}"` };
122
134
  }
123
135
 
124
- log(`[rtk] wiring RTK into ${target} …`);
136
+ log(`[rtk] wiring RTK into ${canonical} …`);
125
137
  // --auto-patch is only accepted by the default Claude Code hook flow.
126
138
  // Other agent flags (--codex, --gemini, --opencode, --agent X) reject it.
127
- const finalArgs = target === 'claude-code' ? [...rtkArgs, '--auto-patch'] : rtkArgs;
139
+ const finalArgs = canonical === 'claude-home' ? [...rtkArgs, '--auto-patch'] : rtkArgs;
128
140
  const r = spawnSync('rtk', finalArgs, { encoding: 'utf8' });
129
141
  const output = (r.stdout || '') + (r.stderr || '');
130
142
  if (r.status !== 0) {
@@ -175,6 +187,7 @@ function savings({ days = 30 } = {}) {
175
187
 
176
188
  module.exports = {
177
189
  TARGET_MAP,
190
+ normalizeTarget,
178
191
  detectInstalledTargets,
179
192
  isInstalled,
180
193
  getVersion,