Commit Graph

2035 Commits

Author SHA1 Message Date
AHNINE Amine
4197ea545f fix(hooks): stop false loop warnings and repeated identical context warnings (#2121)
* fix(hooks): stop false loop warnings and repeated identical context warnings

Two PostToolUse monitor defects surfaced during a long single-turn session:

1. ecc-metrics-bridge hashToolCall fingerprinted Edit/Write/MultiEdit on
   file_path ONLY, so several distinct edits to the same file produced the
   same hash and tripped the loop detector ("stuck loop") even though every
   edit was different. Now the hash includes the edit content
   (old_string/new_string/content/edits) so distinct edits to one file hash
   differently; identical edits still collide as intended.

2. ecc-context-monitor re-emitted the SAME warning every DEBOUNCE_CALLS (5)
   tool calls even when nothing changed. Because the cost figure only refreshes
   at Stop (turn) boundaries, a single stale value printed the identical
   warning ~20 times within one turn. Dedupe on message content instead: a
   warning surfaces only when its text changes (cost moved, new file count, new
   loop) or on first escalation to critical, and is otherwise suppressed.

Adds regression tests for the same-file/different-content hash case.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* fix(hooks): address CodeRabbit review (#2121)

- ecc-context-monitor: clear dedupe state when warnings resolve, so the same
  warning text recurring in a later turn (context dips/recovers/dips, a loop
  that stops then restarts) is surfaced again instead of suppressed as a
  duplicate. Guarded so the no-warning hot path stays write-free.
- ecc-metrics-bridge: hash the FULL serialized edit payload and truncate the
  digest, not the input. Slicing the serialized string to HASH_INPUT_LIMIT
  first could collapse large edits sharing their first 2048 chars, reviving the
  false-loop collision for big Write/edit payloads.
- Add regression test for >2048-char edit divergence.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:26:30 +08:00
lynuxis2026-pixel
5df520658a Add NEXUS to mcp-configs/mcp-servers.json (local cost/privacy proxy) (#2125)
* Add NEXUS to mcp-configs/mcp-servers.json

NEXUS (github.com/lynuxis2026-pixel/nexus-proxy) is a local, single-binary
cost/privacy proxy that sits under the harness. Adding it as an MCP server lets
an ECC agent query its own usage/savings mid-session (nexus_stats, nexus_savings,
nexus_recent, nexus_providers, nexus_cost_breakdown).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* Tighten nexus MCP description to ECC's concise house style

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: ludicolijn1985-blip <ludicolijn1985@gmail.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:26:27 +08:00
0xJayHK
54578415cd fix(trae): strip trailing slash so skill manifest entries are single-slash (#2126)
The Trae installer recorded nested skill files with a doubled slash
(e.g. `skills/skill-comply//pyproject.toml`). The skills loop used the
glob variable `$d`, which carries a trailing slash, both as the `find`
root and as the prefix removed from each file path. Under bash, BSD
`find` with a trailing-slash argument emits `.../skill-comply//file`, so
`${source_file#$d}` left a leading slash, producing double-slash manifest
entries that did not match the single-slash paths uninstall.sh expects.

Strip the trailing slash from `$d` and remove the `$d/` prefix so `find`
emits clean paths and manifest entries are single-slash. Fixes the
previously failing test in tests/scripts/trae-install.test.js
("records nested skill files and the full rules tree in the manifest").

Co-authored-by: affaan-m <tamiraw808@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:26:25 +08:00
xiaoxi
e4dfc1679b fix: surface legacy data warning in instinct-cli status (#2127)
* fix: surface legacy data warning in instinct-cli status (#2036)

When the data directory moved from ~/.claude/homunculus/ to the
XDG-compliant ~/.local/share/ecc-homunculus/, legacy installs with data
still in the old path saw "No instincts found" with no explanation.

Add _warn_legacy_data() to cmd_status so users get a clear, actionable
warning pointing them to the migration script or the CLV2_HOMUNCULUS_DIR
override. Wrap the directory scan in try/except to handle permission
errors gracefully.

Closes #2036

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: address review feedback — drop unused f-strings, resolve absolute migrate path

Remove extraneous f-prefix from strings without interpolation (ruff F541).
Resolve migrate-homunculus.sh path relative to instinct-cli.py instead of
hard-coding a repo-relative path that only works from the repo root.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

* fix: quote migrate script path to handle spaces

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: kky <lingmu141592@gmail.com>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 13:26:22 +08:00
nyxst4ck
3248ac69f0 docs: quote pip extras install example (#2130)
Co-authored-by: nyxst4ck <289980115+nyxst4ck@users.noreply.github.com>
2026-06-07 13:26:20 +08:00
Matt Van Horn
9adaa88999 fix: normalize POSIX CLAUDE_PLUGIN_ROOT to Windows path in hook bootstrap (#2139)
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-07 13:26:17 +08:00
Matt Van Horn
80233f1b72 fix: shrink default OpenCode install surface and gate hooks-runtime (#2140)
Co-authored-by: Matt Van Horn <455140+mvanhorn@users.noreply.github.com>
2026-06-07 13:26:14 +08:00
Adilan Akhramovich
53d4b7d664 Fix claude-project target for legacy language installs (#2147) 2026-06-07 13:26:11 +08:00
bymle
0cb8907e14 fix(gateguard): gate force/path git checkout as destructive (#2158)
* fix(gateguard): gate force/path git checkout as destructive

The destructive-command gate's `checkout` handler only flagged
`git checkout -- <path>`. It missed `git checkout --force` / `-f <branch>`
and `git checkout .`, all of which discard uncommitted working-tree changes,
so they bypassed the gate (once the once-per-session routine-Bash gate is
satisfied, they ran with no challenge). The sibling `switch` handler already
covers these force forms; mirror it for `checkout`.

* test(gateguard): document Test 7b force-checkout case

---------

Co-authored-by: bymle <229636660+bymle@users.noreply.github.com>
2026-06-07 13:26:08 +08:00
Kumario
680cc7153b docs(claude): install manual skills at top level (#2160)
* docs(claude): install manual skills at top level

* test(docs): guard Claude manual skill install path

* test(docs): detect PowerShell/$HOME nested skill-install paths

Address CodeRabbit on #2160: the nested-path regression guard only matched
Unix `mkdir`/`cp` with `~`, so a reintroduced PowerShell `Copy-Item ...
$HOME/.claude/skills/ecc` (or backslash-separated) form would have slipped
through. Extend the pattern to also cover `Copy-Item`/`New-Item` (and the
`md`/`copy`/`cpi` aliases), accept `$HOME` as an alternative to `~`, allow both
`/` and `\` separators, and match case-insensitively.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:26:06 +08:00
konstapukarifastnetfi
be536c1a3e fix: truncate corrupted legacy command shims (#2167)
tdd.md, e2e.md, and orchestrate.md in legacy-command-shims/commands/ still
carried their full pre-shim command bodies concatenated below the shim
headers: a stray '})' and orphaned code fence in tdd.md, leftover Playwright
test bodies plus a foreign project-specific 'PMX-Specific Critical Flows'
section in e2e.md, and orphaned report-template fragments in orchestrate.md.
The trailing bodies also contradicted the shim headers by claiming the
commands invoke agents directly.

Truncate each file at the end of its Delegation section. The other nine
legacy shims are clean 20-23 line shims and are untouched.
2026-06-07 13:26:03 +08:00
konstapukarifastnetfi
8b24f63ede fix: refresh stale technical content in agents, rules, and skills (#2168)
Several published examples contained APIs that no longer exist, code that
does not run, or model versions that drifted from reality:

- agents/performance-optimizer.md used the web-vitals v3 API
  (getCLS/getFID/getLCP/getFCP/getTTFB) and reported FID. web-vitals v4
  renamed the imports to onCLS/onINP/onLCP/onFCP/onTTFB and FID was
  replaced by INP (target < 200ms)
- rules/common/performance.md pinned stale model versions in the
  model-selection guidance; refresh to the versions the repo itself uses
  (agent.yaml pins claude-opus-4-6) and add the PowerShell variant for
  MAX_THINKING_TOKENS next to the bash export
- skills/python-patterns/SKILL.md: both get_value examples referenced
  default_value without declaring the parameter (NameError); add
  default_value: Any = None to the EAFP and LBYL signatures
- skills/frontend-patterns/SKILL.md: the custom useQuery example rebuilt
  refetch whenever callers passed inline fetchers/options, re-triggering
  the effect after every state update (infinite fetch loop). Keep the
  latest fetcher/options in refs so refetch stays referentially stable.
  The PASS-labelled useMemo example mutated its input with in-place sort;
  copy before sorting
- skills/coding-standards/SKILL.md repeated the same PASS-labelled
  in-place-sort-in-useMemo example; same fix
- rules/typescript/security.md used a vendor-specific OPENAI_API_KEY in
  generic guidance; switch to a neutral API_KEY

Every hand-maintained copy of the affected content is synced in the same
change: locale mirrors (ja-JP, ko-KR, pt-BR, tr, zh-CN, zh-TW - each only
where it carries the affected file) and the .agents/.kiro/.cursor harness
mirrors. Two structural divergences are left alone and noted here:
.kiro/steering/performance.md has no extended-thinking control list to
carry the PowerShell variant, and docs/zh-TW/rules/performance.md keeps an
older condensed thinking section without the budget-cap line.
rules/zh/performance.md is intentionally untouched - the rules/zh tree is
being retired in a separate change
2026-06-07 13:26:01 +08:00
konstapukarifastnetfi
36bec90d45 docs: align command docs with shipped behavior (#2169)
- multi-{plan,execute,backend,frontend,workflow}.md: add an in-file
  prerequisite note for the external ccg-workflow runtime. README.md already
  warns these commands need codeagent-wrapper and the .ccg prompt tree, but
  users meeting them via the installed slash commands never see the README;
  the commands-core module still installs all five by default
- quality-gate.md: describe what scripts/hooks/quality-gate.js actually does.
  The doc advertised '/quality-gate [path] [--fix] [--strict]' with lint/type
  checks, but the script reads the file path from hook stdin JSON, toggles
  behavior via ECC_QUALITY_GATE_FIX / ECC_QUALITY_GATE_STRICT env vars, and
  runs formatters only (Biome/Prettier, gofmt, ruff format)
- claude-devfleet SKILL.md: add a Setup section pointing at the DevFleet
  server repository (github.com/LEC-AI/claude-devfleet, already disclosed in
  mcp-configs/mcp-servers.json) plus the SECURITY.md port-verification note;
  the skill previously assumed a running instance with no way to obtain one
- regenerate docs/COMMAND-REGISTRY.json for the quality-gate description
2026-06-07 13:25:58 +08:00
konstapukarifastnetfi
5dc60a5243 fix: retire rules/zh from the always-loaded default rules install (#2170)
rules/zh shipped ~17KB of Chinese rule text into the auto-loaded rules tree
of every default install (rules-core installs the bare 'rules' path with
defaultInstall: true), with no paths: frontmatter gating. The content had
also drifted behind both rules/common and the maintained translations in
docs/zh-CN/rules/common (e.g. zh/coding-style.md 48 lines vs the 52-line
docs/zh-CN copy), and 'zh' was already dropped from the installer's language
help in favor of the gated docs-zh-cn locale module (--locale zh-CN).

- move rules/zh/code-review.md to docs/zh-CN/rules/common/code-review.md:
  the only file with no counterpart in the maintained locale tree (fills a
  zh-CN parity gap with rules/common/code-review.md)
- delete the remaining 10 rules/zh files, all older duplicates of
  docs/zh-CN/rules/common content
- update trae-install test to assert the rules tree via rules/web instead

Not addressed here: rules/README.md (~5.5KB of installer docs) still ships
into the auto-loaded tree via the bare 'rules' module path; filtering README
files from rule-tree expansion is a separate decision
2026-06-07 13:25:56 +08:00
konstapukarifastnetfi
6614f79fe3 test: skip chmod-based permission tests when running as root (#2171)
Two tests provoke EACCES via chmod (saveAliases backup double failure,
appendSessionContent on a read-only file) and already skip on win32, but
root ignores file modes so both fail when the suite runs as root (for
example in a default Docker container). Every other chmod-based test in
the repo already guards with process.getuid?.() === 0; these two were the
only ones missing the guard. Apply the same skip condition and message.
2026-06-07 13:25:53 +08:00
konstapukarifastnetfi
b189e8ec9f fix: close install manifest packaging gaps (#2172)
- commands-core now ships scripts/harness-audit.js and scripts/skills-health.js:
  the module installs the whole commands/ dir, so /harness-audit and
  /skill-health were installed without their backing engines on
  manifest-driven installs (the original 1.10.0 failure mode)
- agentic-patterns now ships scripts/claw.js: the module installs the
  nanoclaw-repl skill, whose workflow operates scripts/claw.js
- package.json files array gains scripts/skills-health.js so the npm publish
  surface stays aligned with the module graph (claw.js and harness-audit.js
  were already listed)
- orchestration drops commands/multi-workflow.md and commands/sessions.md
  from its explicit paths: both are already shipped by commands-core, which
  is a declared dependency of the module, so the duplicate ownership produced
  two copy operations per destination in install-state. The two scripts/lib
  entries are kept because hooks-runtime is NOT a declared dependency and a
  standalone orchestration install still needs them
2026-06-07 13:25:51 +08:00
skausage-ops
3e671ff848 fix: send claude prompt via stdin so Windows shell mode does not mangle it (#2174)
askClaude() passed the full multi-line prompt as a claude

Fix: keep only the short, safe flags (--model, -p) as args and send the prompt over stdin via spawnSync input. The prompt never touches the shell command line, so multi-line/special-char prompts arrive intact. claude -p reads stdin on macOS/Linux too, so behavior is unchanged there.

Verified on Windows 11 (Node 24, claude CLI via npm): real turns now return correct responses, and node tests/scripts/claw.test.js passes 19/19.

Co-authored-by: skausage-ops <268783127+skausage-ops@users.noreply.github.com>
2026-06-07 13:25:48 +08:00
Kumario
70fde3c14f fix(skills): keep curl credentials out of argv (#2175)
* fix(skills): avoid curl credential argv leaks

* test(ci): guard secret curl examples
2026-06-07 13:25:45 +08:00
Johnson K C
40673a89fa test: guard broken-symlink tests so the suite passes on Windows (#2176)
* test: guard broken-symlink tests so the suite passes on Windows

Four test cases create a dangling symlink with fs.symlinkSync() to exercise
statSync catch branches, but did not guard for platforms where symlink
creation is not permitted. On Windows without Developer Mode / admin rights,
fs.symlinkSync throws EPERM, so these tests fail and `npm test` is red:

  - tests/ci/validators.test.js (Round 73, validate-commands skill entry)
  - tests/lib/session-manager.test.js (Round 83, getAllSessions)
  - tests/lib/session-manager.test.js (Round 84, getSessionById)
  - tests/lib/utils.test.js (Round 84, findFiles)

Wrap each symlinkSync in try/catch and skip cleanly on failure, mirroring the
existing convention already used in this repo (validators.test.js Round 57 and
hooks/config-protection.test.js). On Linux/macOS and admin Windows the symlink
still succeeds and the tests run unchanged; only the unsupported-symlink path
now skips instead of failing.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* test: only skip symlink tests on EPERM/EACCES, rethrow other errors

Address CodeRabbit review: the catch blocks swallowed every error, which could
mask a real test/setup failure as a false skip. Inspect err.code and only take
the skip path for EPERM/EACCES (symlink creation blocked, e.g. Windows without
Developer Mode); rethrow anything else so genuine failures still surface.

Per the repo coding guideline: never silently swallow errors.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-07 13:25:43 +08:00
Sahil Aghara
e116d69c65 feat(skills): add kubernetes-patterns skill (#2178)
* feat(skills): add kubernetes-patterns skill

* fix(skills): address CodeRabbit review on kubernetes-patterns

- Add When to Use alias section (repo skill-format requirement)
- Add How It Works overview section (required schema)
- Add Examples quick-reference table (required schema)
- Fix RBAC: split into Pattern A (no API, token disabled) and
  Pattern B (needs API, token enabled) to resolve contradiction
  between automountServiceAccountToken: false and Role/RoleBinding
- Fix missing -n my-namespace flag on OOMKilled kubectl describe command
2026-06-07 13:25:41 +08:00
bymle
7883da658b fix(dev-server-block): stop blocking dev-<suffix> scripts (#2179)
`DEV_PATTERN`'s trailing `\b` treats a hyphen as a word boundary, so
`dev\b` matched the `dev` prefix of distinct npm scripts like
`dev-setup` / `dev-docs` / `dev-build` and blocked them with exit 2.
Replace the trailing `\b` with `(?![\w-])` so the dev server still
matches (`dev`, `dev;`, `dev:ssr`) but `dev-<suffix>` scripts pass.

Adds regression tests for dev-setup/dev-docs/dev-build (allowed) and
dev:ssr (still blocked).

Co-authored-by: bymle <229636660+bymle@users.noreply.github.com>
2026-06-07 13:25:39 +08:00
bymle
e7e38cd508 fix(session-end): preserve $-sequences in user messages when rewriting summary (#2180)
The regenerated summary block embeds raw user-message text and was passed
as the *replacement* argument to String.prototype.replace, where $-sequences
($&, $$, $`, $') are special. A user message containing $& re-injected the
entire matched block (duplicating the summary markers) and $$ collapsed to $,
silently corrupting the persisted session summary. buildSummarySection only
escapes newlines and backticks, not $.

Fix: use function replacers (() => summaryBlock) at both rewrite sites so the
replacement text is treated literally. Adds an end-to-end regression test.

Co-authored-by: bymle <229636660+bymle@users.noreply.github.com>
2026-06-07 13:25:36 +08:00
bymle
9c35aef60f fix(project-detect): match packageKeys on boundaries, not substrings (#2181)
Framework detection matched a dependency against a framework's packageKeys
with unbounded substring containment (dep.includes(key)), so any dependency
whose name merely contained a key was misclassified: `preact` and even
`reactive` were both detected as `react`.

Match only when the dependency equals the key, or the key is a prefix
immediately followed by a delimiter (/ . _ -). This still matches every real
case (react-dom, @remix-run/node, spring-boot-starter, org.springframework.boot,
github.com/labstack/echo/v4, phoenix_live_view) while excluding preact/reactive
(and incidentally nextra). Adds regression tests.

Co-authored-by: bymle <229636660+bymle@users.noreply.github.com>
2026-06-07 13:25:34 +08:00
dependabot[bot]
09e2bc58d3 chore(deps): bump actions/checkout from 6.0.2 to 6.0.3 (#2183)
Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.2 to 6.0.3.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](de0fac2e45...df4cb1c069)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 6.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-06-07 13:25:31 +08:00
zucchini
a3d8d8ab92 fix(observer): auto-scale max_turns by analysis batch size (#2062)
* fix(observer): auto-scale max_turns by analysis batch size (#2035)

The hardcoded default of MAX_TURNS=20 is insufficient when
MAX_ANALYSIS_LINES=500 (also the default). Claude exhausts its turn
budget before it can write all discovered instinct files, producing:

  Error: Reached max turns (20)

Fix: when ECC_OBSERVER_MAX_TURNS is not explicitly set, compute
max_turns proportionally to the actual analysis batch size:
  max_turns = clamp(analysis_count / 10, 20, 100)

This gives:
  - 20–199 lines → 20 turns  (existing floor, unchanged)
  - 500 lines    → 50 turns  (resolves the reported failure)
  - 1000 lines   → 100 turns (cap)

Explicitly setting ECC_OBSERVER_MAX_TURNS still overrides the
auto-scaled value, preserving the existing escape hatch.

* test(observer): update max_turns test for auto-scaling; document validation

The max-turns budget test in tests/hooks/hooks.test.js still asserted the removed literal max_turns="${ECC_OBSERVER_MAX_TURNS:-20}", which would fail against the new auto-scaling logic. Assert the auto-scale formula and the 20/100 clamp bounds instead.

Also add the explanatory comment CodeRabbit requested above the max_turns sanitization block, clarifying it guards the explicit ECC_OBSERVER_MAX_TURNS override path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 13:25:29 +08:00
Gaurav Dubey
d8a84b5f7b fix(.cursor/hooks): route block-no-verify through local hook to fix message-body false positives (#2107) (#2177)
Cursor hooks still called `npx block-no-verify@1.1.2`, the broken external
package whose matcher over-matches: it blocks legitimate `git commit`
whenever `--no-verify` (or `no-verify`) appears anywhere in the command
string, including inside the commit message body. The Claude Code surface
already routes through the in-repo `scripts/hooks/block-no-verify.js`,
which performs flag-position-aware tokenisation and passes 25 regression
tests covering every false-positive case from #2107.

Add a thin Cursor wrapper (`before-shell-execution-block-no-verify.js`)
that reads Cursor stdin, transforms to the Claude Code `tool_input.command`
shape, delegates to the local hook's exported `run()`, and forwards exit
code and stderr. Update `.cursor/hooks.json` to call the wrapper instead
of the npx package. New 14-case test file pins the false-positive cases
from the issue plus the still-blocked real bypass attempts.

Fixes #2107
2026-06-07 13:01:36 +08:00
Gaurav Dubey
8dc43e5f60 fix(session-start): support ECC_SESSION_RETENTION_DAYS opt-out + document env var (#2151) (#2163)
* fix(session-start): support ECC_SESSION_RETENTION_DAYS opt-out + document env var

The retention pass for *-session.tmp files (issue #2151) landed previously,
but the env var that controls it was undocumented in the README and rejected
falsy values (0, off, disabled), silently falling back to the 30-day default.
Users who want to keep all sessions for forensic or research workflows had no
way to opt out.

This patch:

- Extends getSessionRetentionDays() so 0|off|false|disabled|never|none disables
  pruning entirely (returns null sentinel; default behavior unchanged).
- Updates the call site in main() to skip pruneExpiredSessions when retention
  is null and emits a clear "[SessionStart] Pruning disabled via
  ECC_SESSION_RETENTION_DAYS" log line so the operator can tell pruning is off.
- Documents ECC_SESSION_RETENTION_DAYS in the README "Hook Runtime Controls"
  section alongside the other ECC_SESSION_* knobs.
- Adds three regression tests in tests/hooks/hooks.test.js covering opt-out
  via 0, opt-out via off, and garbage-value fallback to default 30.

Verification:
- node tests/hooks/hooks.test.js  — 240/240 green (incl. 3 new retention tests)
- node tests/run-all.js           — 2622/2622 green
- npx eslint scripts/hooks/session-start.js tests/hooks/hooks.test.js — clean
- node scripts/ci/validate-no-personal-paths.js — clean
- node scripts/ci/check-unicode-safety.js       — clean
- node scripts/ci/validate-hooks.js — 28 matchers validated
- node scripts/ci/validate-rules.js — 115 files validated

Fixes #2151

* docs(readme): list all ECC_SESSION_RETENTION_DAYS opt-out values + add Windows example

Address reviewer feedback on PR #2163:
- CodeRabbit and cubic both flagged that the README docs only listed 3 of 6
  opt-out values accepted by getSessionRetentionDays() (0, off, disabled),
  while the implementation also accepts false, never, none.
- cubic also flagged the missing Windows PowerShell example for the new
  variable, breaking the parallel structure of the existing
  ECC_CONTEXT_MONITOR_COST_WARNINGS example block.

Updated the README to:
- Spell out all six opt-out values (0, off, false, disabled, never, none)
  and clarify they "keep all sessions (disable pruning)".
- Add an ECC_SESSION_RETENTION_DAYS line to the Windows PowerShell example.

No behavior change. README only.

Verification:
- npx markdownlint README.md — clean
- npx eslint scripts/hooks/session-start.js tests/hooks/hooks.test.js — clean
2026-06-07 13:01:33 +08:00
Gaurav Dubey
4afdb90800 feat(gateguard): add env knobs for routine bash gate + extra destructive patterns (#2161)
* feat(gateguard): add env knobs for routine bash gate + extra destructive patterns

The JS port of gateguard-fact-force has two bash gates: a destructive
gate (rm -rf, drop table, git push --force, etc.) that operators want
to keep, and a once-per-session routine gate that fires on the very
first bash invocation regardless of intent. Operators on hosts where
the routine gate is friction without signal (Cursor, OpenCode, etc.)
have been maintaining local patches that get clobbered on every plugin
update; the Python upstream gateguard-ai already exposes equivalent
config via .gateguard.yml.

Adds two env vars, both off-by-default so existing behavior is
preserved:

- GATEGUARD_BASH_ROUTINE_DISABLED — truthy values (1, true, on, yes,
  enabled) skip the routine bash gate. Destructive gate is unaffected.
- GATEGUARD_BASH_EXTRA_DESTRUCTIVE — regex source string for additional
  destructive patterns. Matches against the same quote-stripped,
  subshell-flattened command the built-in DESTRUCTIVE_SQL_DD regex sees,
  so a custom phrase inside $(...) or backticks is also caught. A
  malformed regex is logged once to stderr and treated as not configured
  rather than crashing the hook (hooks must never block tool execution
  unexpectedly).

Twelve new tests pin both env vars (truthy aliases, falsy values, unset
baseline, destructive-gate-still-fires, alternation members, malformed
regex degrades safely, custom phrase inside command substitution).
Existing 2619/2619 tests still pass; eslint clean.

Fixes #2078

* fix(gateguard): reset extra-destructive warn-once gate when env value changes

Both reviewers (CodeRabbit + cubic) flagged that
extraDestructiveWarnLogged was never reset when GATEGUARD_BASH_EXTRA_DESTRUCTIVE
flipped from one invalid regex to a different invalid regex. The
sticky boolean meant a long-running process saw bad-pattern-a's
warning then silently swallowed bad-pattern-b's parse failure.

Fix: clear extraDestructiveWarnLogged whenever the cache key changes
(i.e. before the regex compile attempt). The warn-once-per-distinct-
pattern invariant now matches the per-key cache invariant.

Adds a same-process regression test via loadDirectHook() that spies on
process.stderr.write and asserts: same bad pattern warns once across
multiple invocations; switching to a different bad pattern emits a
second warning; switching to a valid regex emits zero warnings.
2026-06-07 13:01:30 +08:00
Gaurav Dubey
a08445ad78 fix(suggest-compact): clean up old counter temp files (#2159)
* fix(suggest-compact): clean up old counter temp files

claude-tool-count-<sessionId> files were written into the OS temp dir
on every hook run and never removed, accumulating one orphan per
session indefinitely.

Sweep stale counter files at the top of main() before opening the
active counter. Retention is env-tunable via COMPACT_STATE_TTL_DAYS
(default 14 days); invalid values fall back to the default. The
active session's counter file is preserved unconditionally even if
its mtime is past the cutoff. Failures during the sweep are swallowed
to preserve the always-exit-0 hook contract.

Adds 7 regression tests covering the sweep, env-var validation, and
the always-exit-0 invariant under a populated temp dir.

Fixes #2156

* fix(suggest-compact): preserve counter files at the TTL cutoff boundary

The cleanup sweep used `mtimeMs > cutoffMs` to short-circuit, which
matched files whose mtime sits exactly on the cutoff boundary and
deleted them. The cleanupOldCounters docstring promises only files
*older than* retentionDays are removed; a file at age == retentionDays
is not older than retentionDays, so it must survive.

Switch the comparison to `>=` so only strictly older files fall
through to deletion. Add a regression test that pins boundary-aged
files (mtimeMs sitting just past the projected cutoff) are preserved.

Refs #2156
2026-06-07 13:01:27 +08:00
Gaurav Dubey
30ef079e7e fix(continuous-learning-v2): accept claude-vscode as valid entrypoint (#2134)
The observe.sh Layer 1 entrypoint guard short-circuits with exit 0 when
CLAUDE_CODE_ENTRYPOINT is not in {cli, sdk-ts, claude-desktop}. Claude
Code's VS Code extension sets CLAUDE_CODE_ENTRYPOINT=claude-vscode, so
VS Code users see no observations recorded — observations.jsonl never
gets created and the instinct pipeline stays empty.

Add claude-vscode to the allowlist, mirroring the precedent in #1522
which added claude-desktop the same way.

Add a regression test that spawns observe.sh under bash -x for each
allowed entrypoint (cli, sdk-ts, claude-desktop, claude-vscode) and
each denied entrypoint (unknown-host, claude-cody, mcp), asserting
that allowed entrypoints reach Layer 2's ECC_HOOK_PROFILE check while
denied entrypoints stop at Layer 1.

Fixes #2102
2026-06-07 13:01:24 +08:00
Chris Yau
898fd231ce fix: guard two script edge cases (tolerant package.json parse, set -u empty array) (#2088)
* fix: guard two script edge cases

- scripts/harness-audit.js: getRepoChecks() parsed package.json with raw
  JSON.parse(readText(...)), while the rest of the file (lines 218, 822)
  uses the tolerant safeParseJson(safeRead(...)). In repo target mode a
  project lacking package.json — or with malformed JSON — threw an uncaught
  exception and crashed the audit instead of degrading. Match the existing
  convention so the audit tolerates a missing/invalid package.json.

- skills/frontend-slides/scripts/export-pdf.sh: `set -- "${POSITIONAL[@]}"`
  expands an empty array under `set -u` on bash 3.2 (the macOS system bash),
  aborting with "POSITIONAL[@]: unbound variable" instead of printing the
  usage message when invoked with no positional args. Guard the expansion
  with ${POSITIONAL[@]+"${POSITIONAL[@]}"} (no-op safe under bash 3.2 set -u).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

* fix: null-safe package.json access in getRepoChecks

Review follow-up (CodeRabbit + cubic): switching to safeParseJson at line
389 means packageJson can be null on a missing/malformed package.json, but
the quality-ci-validations check dereferenced packageJson.scripts before the
optional chaining could help — throwing TypeError instead of degrading.
Guard the base object with packageJson?.scripts?.test at the access site,
matching the file's existing convention (e.g. line 220 uses packageJson?.name).

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>

---------

Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
2026-06-07 13:01:21 +08:00
Affaan Mustafa
c8caf193c4 feat: worktree-lifecycle service (deterministic conflict prediction + safe GC) (#2164)
* feat: add worktree-lifecycle service (ecc.worktree-lifecycle.v1)

The "unowned moat" from the orchestrator landscape research: no existing
tool ships deterministic merge-conflict prediction or a safe worktree GC.

- scripts/lib/worktree-lifecycle/git.js: injectable, hermetic git layer.
  Predicts merge conflicts WITHOUT touching the working tree via
  `git merge-tree`. Strips inherited GIT_* env so it is safe inside hooks.
- scripts/lib/worktree-lifecycle/lifecycle.js: deterministic state machine
  (main/dirty/conflict/merge-ready/merged/stale/idle) + planCleanup that
  buckets worktrees into remove / salvage / keep. Only fully-merged trees
  are auto-removable; stale (unmerged+inactive) => salvage, never deleted.
- scripts/worktree-lifecycle.js: CLI (--json/--conflicts/--stale/
  --cleanup-plan/--base/--stale-days/--repo).
- tests/lib/worktree-lifecycle.test.js: 11 tests (fake-git + real-git).

Safety model mirrors the reference-arch salvage rule, validated by the
2026-06-05 MacBook->Mac Mini consolidation. Tests: 11/0.

* fix: hermetic git env in session adapters + mcp-inventory lint

- session adapters (codex-worktree, opencode): resolveGitBranch stripped
  no git env, so the "outside a repo" path returned the host branch when
  run inside a git hook (GIT_DIR set). Strip GIT_* before rev-parse.
- mcp-inventory: fix eslint no-unused-vars (signatures) and a stale
  eslint-disable directive in the merged code.

* test: run each test with inherited git env stripped (hermetic runner)

When the suite runs inside a git hook (pre-push), git sets GIT_DIR/
GIT_WORK_TREE, which hijack 'git -C <dir>' calls in tests that exercise
real git, making them operate on the host repo. Strip GIT_* before
spawning each test so the suite is isolated from ambient git state.

---------

Co-authored-by: ECC Test <ecc@example.test>
2026-06-07 13:00:08 +08:00
Affaan Mustafa
7113b5bf63 feat: MCP inventory (ecc.mcp.v1) — unified cross-harness MCP config view (#2146)
* feat: add MCP inventory (ecc.mcp.v1) across harnesses

Read-only MCP-gateway groundwork: discover MCP server configs across
every installed harness, normalize to a canonical ecc.mcp.v1 inventory,
redact secrets, and report which servers are configured in 2+ harnesses
(the configure-N-times pain). The read+dedup side of a unified gateway,
mirroring how the session-adapter layer started read-only.

Readers (per-harness config formats):
- claude-code: ~/.claude.json mcpServers + project .mcp.json
- codex: ~/.codex/config.toml [mcp_servers.*] TOML via @iarna/toml
- opencode: ~/.config/opencode/opencode.json mcp block (command ARRAY)

canonical-mcp.js:
- normalize transport labels (local=>stdio, remote=>http) to stdio/http/sse
- merge servers by name across harnesses; flag DRIFT when signatures differ
- fragmentation report + aggregates
- SECRET REDACTION: env values stripped to key names; secrets in args
  (--modelApiKey sk-ant-...), inline --flag=secret, and URL userinfo/token
  query params all redacted before storage AND before the dedup signature.

scripts/mcp-inventory.js: CLI (--json, --fragmented, --help).
tests/lib/mcp-inventory.test.js: 12 tests incl. a regression for the
real arg-carried-secret leak found while smoke-testing on live configs.

Tests: 12/0. Real-data smoke: 33 servers across 3 harnesses, 21
configured in 2+ harnesses (7 drift); secret-leak audit clean.

* test: cover reader error paths, collect skip-logic, and CLI main() for mcp-inventory

Lift global branch coverage past the 80% gate (was 79.86%). Adds 6
tests exercising: missing-file/malformed-JSON/missing-block reader
fallbacks, codex no-parser path, collect skipping non-function readers
and swallowing reader errors, CLI usage()/main() help+json+human paths,
and formatHumanReport no-fragmentation + fragmented-only branches.

Also scrub a real API-key fragment that had leaked into a test fixture;
all secret-like fixtures are now obviously-fake FAKE... tokens.

mcp-inventory.js branch 30%->93%, collect.js ->100%. Global branch 80.33%.
2026-06-06 03:55:17 +08:00
Affaan Mustafa
ab5e17fea9 feat: extend session-adapter layer with codex-worktree + opencode adapters (#2145)
* feat: add codex-worktree session adapter

Adds the third session adapter (after dmux-tmux and claude-history),
normalizing Codex rollout sessions into the harness-neutral
ecc.session.v1 snapshot. Reads ~/.codex/sessions rollout JSONL,
derives objective (skipping the AGENTS.md preamble + leading message
UUID), model, originator, worktree cwd, and best-effort git branch.

This is step 1 of ECC-2.0-SESSION-ADAPTER-DISCOVERY (move the
abstraction beyond tmux + Claude-history) and supports the
wrap/adapt control-pane strategy: ECC reads sessions from any
harness rather than owning one UX.

- scripts/lib/session-adapters/codex-worktree.js: adapter + rollout parser
- canonical-session.js: normalizeCodexWorktreeSession
- registry.js: register adapter, codex/codex-worktree target types
- tests/lib/session-adapters-codex.test.js: 4 tests (unit + registry routing)

* feat: add opencode session adapter + allow empty intent objective

Adds the fourth session adapter (after dmux-tmux, claude-history,
codex-worktree), normalizing OpenCode sessions into ecc.session.v1.

Reads ~/.local/share/opencode/storage: session/<project>/ses_*.json
for metadata (id, directory, title, version, projectID, time) and
message/<session>/msg_*.json to extract the model (modelID/providerID
from the first assistant message). Derives objective from the session
title, treating the auto-generated "New session - <date>" title as no
objective. Recency-based active/recorded state.

Schema: relax intent.objective from non-empty to allow empty string
(ensureStringAllowEmpty). Sessions legitimately have no objective yet
(fresh/auto-titled), and claude-history already emitted "" via
metadata.title fallback. This fixes a latent over-strict validation.

- scripts/lib/session-adapters/opencode.js: adapter + storage parser
- canonical-session.js: normalizeOpencodeSession + ensureStringAllowEmpty
- registry.js: register adapter + opencode target type
- tests/lib/session-adapters-opencode.test.js: 5 tests

Tests: opencode 5/0, codex 4/0, session-adapters 14/0,
control-pane-state 10/0, session-inspect 8/0, control-pane 12/0.
Smoke-tested on a real OpenCode session (140 messages, gpt-5.3-codex).

* test: cover error/fallback branches for codex-worktree + opencode adapters

Lift global branch coverage past the 80% gate (was 79.53%). Adds error
and fallback path tests: missing-session/unknown-id throws, findRolloutById/
findSessionInfoById, direct file targets, objective truncation, model
fallbacks, corrupt-line skip, mtime activity fallback, and the real
resolveGitBranch path outside a repo.

codex-worktree.js branch 52.8%->78.3%; global branch 80.04%.
2026-06-06 03:55:00 +08:00
Affaan Mustafa
bc8e12bb80 feat: add dynamic workflow team orchestration surface
Adds dynamic workflow/team orchestration skills, the content pack, and control-pane work-item/Kanban state DB support. Includes reviewer hardening for state-db CLI validation, optional state DB failure handling, and mergeStateStatus projection.
2026-06-04 21:45:13 +08:00
Affaan Mustafa
0f84c0e279 feat: add ECC2 local control pane (#2131)
* feat: add ECC2 local control pane

* fix: refresh control pane package locks

* test: harden control pane coverage

* test: allow portable control pane shutdown

* test: retry local control pane fetches

* fix: harden control pane error handling

* fix: wrap control pane metadata
2026-06-03 21:54:30 +08:00
Affaan Mustafa
99baa82500 docs: define ECC platform value loop (#2119) 2026-06-02 19:51:02 +08:00
Affaan Mustafa
d86fadad0d docs: record rc1 live package readbacks (#2117) 2026-06-02 19:32:59 +08:00
Affaan Mustafa
64cd1ba248 fix: surface warn-only PreToolUse hooks (#2084) 2026-05-28 07:45:46 -04:00
Alexis Le Dain
04c68e483a Add React language track with agents, skills, rules, and commands (#2024)
* feat(rules): add rules/react/ track

Five rule files mirroring per-language convention (coding-style,
hooks, patterns, security, testing). Each has `paths:` glob
frontmatter for auto-activation when editing matching files.

- coding-style.md: file extensions, naming, JSX, RSC boundary
- hooks.md: React hooks (NOT Claude Code hooks) — rules-of-hooks,
  dep arrays, cleanup, memoization, React 19 additions
- patterns.md: container/presentational split, state location
  decision tree, Suspense + error boundaries, forms, data fetching
- security.md: dangerouslySetInnerHTML, unsafe URL schemes,
  server-action validation, env-var leaks, CSP
- testing.md: RTL queries, userEvent, async, MSW, axe, anti-patterns

Each file extends typescript/* and common/* rules.

* feat(skills): add react-patterns, react-testing, react-performance

Three new skills under skills/ following the SKILL.md convention.

- react-patterns: React 18/19 idioms — hooks discipline, state
  location decision tree, server/client component boundary,
  Suspense + error boundaries, form actions (React 19), data
  fetching matrix, composition recipes, accessibility-first.
- react-testing: React Testing Library + Vitest/Jest, query
  priority order, userEvent, MSW network mocking, axe a11y
  assertions, RTL vs Playwright CT boundary, TDD workflow.
- react-performance: 70-rule performance ruleset adapted from
  Vercel Labs react-best-practices (MIT) across 8 priority
  categories — waterfalls, bundle size, server-side, client
  fetch, re-render, rendering, JS micro, advanced patterns.
  Includes Lighthouse / Web Vitals mapping and attribution to
  upstream.

Cross-links between the three skills and out to frontend-patterns,
accessibility, e2e-testing, tdd-workflow.

* feat(agents): add react-reviewer and react-build-resolver

Two new agents covering React-specific code review and build error
resolution, plus matching .kiro/ mirrors and a routing pointer
edit on typescript-reviewer.

- react-reviewer: slim React-only lanes (hooks rules,
  dangerouslySetInnerHTML, unsafe URL schemes, key prop, state
  mutation, derived-state-in-effect, server/client component
  boundary, accessibility, render performance, Server Action
  validation, env-var leaks). Explicitly delegates generic
  TypeScript/async/Node concerns to typescript-reviewer. Both
  agents should be invoked together on .tsx/.jsx PRs.
- react-build-resolver: React build/bundler/runtime hydration
  failures across Vite, webpack, Next.js, CRA, Parcel, esbuild,
  Bun, Rsbuild. Handles JSX/TSX compile errors, tsconfig fixes,
  Next.js App Router server/client boundary errors, hydration
  mismatches, duplicated React copies, Tailwind/PostCSS pipeline.
- .kiro/agents/react-reviewer.json + react-build-resolver.json:
  Kiro IDE format mirrors following the per-language precedent.
- typescript-reviewer: routing pointer added to its MEDIUM React
  block — defers to /react-review for React-specific concerns
  while keeping its block as fallback for repos that only invoke
  typescript-reviewer.

All agents carry the standard Prompt Defense Baseline stanza.

* feat(commands): add /react-review /react-build /react-test

Three new slash commands invoking the React agents.

- /react-review: invokes react-reviewer. Documents the routing
  rule with typescript-reviewer — both should run together on
  TSX/JSX PRs. Lists CRITICAL/HIGH/MEDIUM rule categories and
  the automated checks (eslint with react-hooks + jsx-a11y,
  tsc --noEmit, npm audit).
- /react-build: invokes react-build-resolver. Documents bundler
  detection, common failure patterns, fix strategy, and stop
  conditions.
- /react-test: enforces TDD with React Testing Library + Vitest
  or Jest, behavior-focused queries, userEvent + MSW patterns,
  axe accessibility assertions, coverage targets.

Each command file has the required description: frontmatter and
follows the per-language command convention (cpp-test, go-test,
kotlin-test, etc.).

* chore: wire react track into manifests and stack mappings

- agent.yaml: add react-patterns, react-performance, react-testing
  to the skills array; add react-build, react-review, react-test to
  the commands array (alphabetically inserted to satisfy the
  ci/agent-yaml-surface sync test).
- config/project-stack-mappings.json: extend the `react` stack
  entry — add "react" to rules array (was ["common","typescript",
  "web"]); add react-patterns, react-performance, react-testing,
  accessibility to the skills array.
- docs/COMMAND-REGISTRY.json: bump totalCommands 75 -> 78; add
  three new entries (react-build, react-review, react-test) with
  primaryAgents / allAgents / skills wiring. react-review's
  allAgents includes typescript-reviewer to reflect the dual-agent
  routing convention.
- CLAUDE.md: add Skills-table row mapping *.tsx / *.jsx /
  components/** to react-patterns + react-testing skills and
  the /react-review, /react-build, /react-test commands.

* chore(catalog): sync counts to 62 agents / 78 commands / 235 skills

Auto-generated via `node scripts/ci/catalog.js --write --text`
after the react track additions:

- 2 new agents: react-reviewer, react-build-resolver (60 -> 62)
- 3 new commands: react-build, react-review, react-test (75 -> 78)
- 3 new skills: react-patterns, react-performance, react-testing
  (232 -> 235)

Files updated by the catalog sync:
- .claude-plugin/plugin.json description string
- .claude-plugin/marketplace.json plugin description
- README.md quick-start summary, project tree, feature parity tables
- README.zh-CN.md quick-start summary
- AGENTS.md project structure summary
- docs/zh-CN/README.md parity table
- docs/zh-CN/AGENTS.md project structure summary

All counts now match the filesystem catalog (verified by
ci/catalog.test.js).

* feat(kiro): add react agent markdown companions to JSON entries

* feat(kiro): add react skills into manifests

* fix(ci): sync catalog counts, registry, and package files for react track

- .claude-plugin/{plugin,marketplace}.json: bump description counts to 62/235/78
- docs/COMMAND-REGISTRY.json: regenerate to include quality-gate and react commands
- package.json: add skills/react-{patterns,performance,testing}/ to files allowlist so npm-publish-surface aligns with install-modules manifest

* fix(react): address PR #2024 review feedback

Critical:
- Remove undefined/.claude/session-aliases.json containing __proto__ prototype-pollution
  fixture committed by accident in a7333c14

High:
- agents/react-build-resolver.md: replace brittle `test -o $(grep -l ...)` and
  `test -a -n $(grep ...)` detection with explicit `{ ... || grep -q ...; }` so
  bundler detection no longer breaks when grep returns empty
- agents/react-build-resolver.md: drop hardcoded `npm i react@^19 react-dom@^19`
  remediation; replace with version-agnostic pair-upgrade note that honors the
  project's installed major (17/18/19) — surgical fix principle
- commands/react-review.md: guard `tsc --noEmit -p tsconfig.json` with
  `[ -f tsconfig.json ] &&` so the review skips cleanly on JS-only projects

Medium:
- rules/react/security.md: correct the React-18-blocks-javascript-URL claim
  (React only warns in dev; production navigation is not blocked)
- rules/react/security.md: correct CRA env-var exposure row (CRA exposes
  REACT_APP_*, NODE_ENV, PUBLIC_URL — not 'all' variables)
- skills/react-testing/SKILL.md: instantiate QueryClient once outside the
  wrapper closure so React Query cache survives re-renders (flaky-test fix)
- skills/react-testing/SKILL.md: restore console.error spy with mockRestore()
  in a try/finally so the mock does not leak across tests
- commands/react-test.md: switch outer example-session fence to 4 backticks
  so the inner ```tsx/```bash blocks don't prematurely terminate it

* fix(kiro): mirror react-build-resolver react 19 conditional remediation

Discussion r3272907106 flagged the kiro json variant still carrying the hardcoded
'npm i react@^19 react-dom@^19' line that the .md companion already dropped.
Replace with the same conditional, version-agnostic guidance so both variants
stay in sync.

* fix(react): bump react-build example session fence to 4 backticks

Discussion r3272907144 flagged the same nested-fence issue in
commands/react-build.md that we fixed earlier in commands/react-test.md.
The outer triple-backtick text block was being prematurely terminated by
the inner bash/tsx fences inside the Example Session.

* fix(react): bump react-review example usage fence to 4 backticks

Discussion r3272907201 flagged the same nested-fence issue in
commands/react-review.md. The outer triple-backtick text block was
being prematurely terminated by the inner tsx/ts fences inside the
Example Usage transcript.

* fix(docs): clarify commands row as legacy shims in feature parity table

Discussion r3272912003: README comparison table said 'PASS: 78 commands'
while the install-section and quick-start prose use 'legacy command shims'.
Aligned the comparison-table cell to 'PASS: 78 commands (legacy shims)' so
the count word survives the catalog-validator regex while making the legacy
nature explicit.

Widened the catalog comparison-table commands regex to tolerate an optional
parenthetical after the count word, so both the existing 'X commands' and
the new 'X commands (legacy shims)' phrasings validate without breaking
older READMEs/translations.

* Update rules/react/security.md

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* fix(react): guard tsc in react-build-resolver diagnostic commands

Discussion r3288910205: the agent prompt instructed an unconditional
'tsc --noEmit -p tsconfig.json', which adds noise (or hard-fails) on
JavaScript-only projects with no tsconfig.json or no installed TypeScript.

Replaced with 'test -f tsconfig.json && npx --yes tsc --noEmit -p tsconfig.json'
in both variants:
- agents/react-build-resolver.md
- .kiro/agents/react-build-resolver.json (prompt string mirrored)

Mirrors the same guard already applied to commands/react-review.md in de135f61.

* fix(react): pin tsc resolution to local install in build resolver

Discussion r3289054157: previous fix used 'npx --yes tsc' which auto-installs
the latest TypeScript from npm when none is local, producing version drift
and non-reproducible typecheck results across machines.

Switched to 'npx --no-install tsc' in both variants so the diagnostic uses
only the project's pinned TypeScript and fails fast if it isn't installed:
- agents/react-build-resolver.md
- .kiro/agents/react-build-resolver.json (prompt string mirrored)

* feat(counts): resolve counts for agents, skills...

* fix(ci): regen command registry for golang-testing entry

Removes stale kotlin-patterns entry to satisfy command-registry:check.

* fix: keep local Claude settings out of React track PR

---------

Co-authored-by: AlexisLeDain <a.ledain@docoon.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Affaan Mustafa <affaan@dcube.ai>
2026-05-28 07:32:52 -04:00
Affaan Mustafa
7d6ca9612d docs: neutralize public ECC metadata (#2083) 2026-05-28 07:30:06 -04:00
Affaan Mustafa
928076cc08 chore: export marketing campaign command v2.0.0-rc.1 2026-05-25 14:19:03 -04:00
Affaan Mustafa
d7813494cb chore: sync catalog counts after PR triage 2026-05-25 14:14:42 -04:00
Affaan Mustafa
3add394cca fix(docs): remove unicode verdict markers 2026-05-25 14:13:36 -04:00
Martin Klein
7fef1ddbeb docs(i18n): add German localization scout (#2029)
Adds de-DE docs, installer wiring, and locale tests. Pre-validated on current main with install manifest checks, markdownlint, locale-install tests, and ECC 2.0 release-surface tests.
2026-05-25 14:12:01 -04:00
Affaan Mustafa
5b4c4bda97 fix(docs): wrap integration reference links 2026-05-25 14:11:05 -04:00
luisllaver
1d72dfb2d5 feat(integrations): add opt-in AURA trust adapter (#2026)
Adds a read-only opt-in AURA trust-check adapter. Synthetic merge passed validators and 22 AURA offline tests via uvx pytest.
2026-05-25 14:10:42 -04:00
michieh.eth
c2b3899685 feat(mcp): add Squish Memory server catalog entry (#2039)
Adds Squish Memory to the MCP server catalog. Pre-validated in a synthetic current-main merge.
2026-05-25 14:10:39 -04:00
Chet
d29dad1688 feat: add marketing campaign agent skill and command (#2031)
Adds marketing-agent, marketing-campaign skill, and marketing-campaign command. Pre-validated in a synthetic current-main merge.
2026-05-25 14:10:35 -04:00
ndesv21
61dd56901b feat(skills): add social publisher skill (#2052)
Adds a SocialClaw-backed social-publisher skill. Pre-validated in a synthetic current-main merge.
2026-05-25 14:10:32 -04:00