mirror of
https://github.com/affaan-m/ECC.git
synced 2026-08-17 21:15:40 +02:00
a3130f9ebfaeed075df5d5b52538acb0ee4bcdf8
2278
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
a3130f9ebf |
feat(codex): add ECC navigation guide (#2525)
* feat(codex): add ECC navigation guide * fix(codex): ship navigation guide references --------- Co-authored-by: Haley Chen <2022hachen@gmail.com> |
||
|
|
b6fe5a71e1 | fix: harden plan canvas code scanning alerts | ||
|
|
b6652335d3 |
fix(hooks): bound plugin shell probe timeouts (#2547)
Co-authored-by: Haley Chen <2022hachen@gmail.com> |
||
|
|
8348fb5387 |
fix: detect Anthropic API keys (sk-ant-...) in pre-commit secret scan (#2529)
The existing OpenAI pattern sk-[a-zA-Z0-9]{20,} never matches real
Anthropic keys: their sk-ant-api03-... format contains hyphens, which
break the character class before reaching the 20-char threshold. Keys
from the fastest-growing Claude Code user base slipped through the scan.
Adds a dedicated sk-ant-[a-zA-Z0-9_-]{20,} pattern (checked before the
OpenAI one) and extends the staged-secrets test with a realistic
Anthropic key fixture.
|
||
|
|
a1bf029cbf |
fix(observer): repair daemon boot (stale resolver name) and close analysis stdin (#2452) (#2464)
Two continuous-learning-v2 observer regressions reported in #2452: - start-observer.sh still called _ecc_resolve_homunculus_dir, but the shared lib was renamed to _clv2_resolve_homunculus_dir (with observe.sh and detect-project.sh updated, start-observer.sh missed). Under set -e every launch dies with exit 127 at line 40 - daemon boot is broken on all platforms, not just Windows. - observer-loop.sh backgrounds the analysis claude call with stdin left open; on Git Bash/MSYS2 the child inherits it, waits, warns 'no stdin data received', and exits 1 before reading the analysis file. Close stdin with </dev/null while keeping the -p prompt flag, preserving the Windows-compat decision from #842 instead of reverting to a stdin redirect. Adds two source invariant guards to tests/hooks/hooks.test.js: every *_resolve_homunculus_dir call site must match a function the shared lib defines, and the backgrounded claude call must close stdin. Fixes #2452 |
||
|
|
cd39df154c |
fix(suggest-compact): recognize large-window model families without a [1m] marker (#2468)
* fix(suggest-compact): recognize large-window model families without a [1m] marker resolveContextWindowTokens() only detected a 1M window via the env override, the [1m] model-id marker, or observed tokens already above 200k. Large-window models whose ids carry none of these (e.g. claude-fable-5) were misclassified as 200k windows, overstating context usage ~5x in the compact suggestion. Add a known-model-family substring table (claude-fable-5, claude-mythos-5) checked after the env override and [1m] marker and before the token-count heuristic. Env overrides still win, and unknown model ids still fall back to the 200k default. Closes #2461 * fix(suggest-compact): anchor known-model-family match at a token boundary Unanchored substring matching would misclassify a hypothetical smaller tier sharing a known family prefix (e.g. claude-fable-5-mini) as a 1M window. Require the family id to end at a token boundary: end of id, a delimiter, or a dated/versioned suffix (-20260115). Alphanumeric continuations and letter suffixes no longer match. Addresses CodeRabbit/Greptile review on #2468 |
||
|
|
e7b3ba07bb |
fix(config-protection): match protected filenames case-insensitively (#2543)
On a case-insensitive filesystem (macOS APFS/HFS+, Windows NTFS) a write to `.ESLINTRC.JS` lands on the exact same inode as `.eslintrc.js`, but the guard looked the basename up in PROTECTED_FILES with a case-sensitive `Set.has`. Every entry in that Set is lowercase, so any case-variant path missed the branch entirely and returned exit 0 — a single Write silently overwrote a live config while the hook reported success. Reproduced on macOS APFS: `.eslintrc.js` and `.ESLINTRC.JS` share one inode, yet the hook returned exit 2 for the former and exit 0 for the latter, and the uppercase write replaced the real config's contents. This is a one-step bypass of the whole guard and needs no shell access, unlike the known delete-then-recreate route. Fix: also test `basename.toLowerCase()`. All 32 PROTECTED_FILES entries are already lowercase, so the fallback is exact. On a genuinely case-sensitive filesystem this costs at most a false positive on a distinct file whose name differs from a protected one by case alone. Behaviour deliberately unchanged: first-time creation is still allowed (the bootstrap affordance), non-config paths still pass through, and the existing lstat/ENOENT fail-closed semantics are untouched. Test: adds a case-variant case that asserts exit 2. It guards itself with an inode comparison and skips on case-sensitive filesystems rather than asserting something untrue there. Verified in both directions — it FAILS against the unpatched hook (`Got 0; 0 !== 2`) and passes with the fix. Suite: 9/9. |
||
|
|
96789caaf9 |
feat: add Itô compute sponsor routing and Phase 2 plan (#2546)
* feat: add Ito compute sponsor routing * fix: harden Ito integration CI and framing |
||
|
|
5deee34c93 |
fix(hooks): remove stray '?' that made every 'yarn <anything>' fire tmux reminder (#2517)
* fix(hooks): remove stray '?' that made every 'yarn <anything>' trigger tmux reminder
The tmux-reminder matcher uses one alternation per package manager. Each
branch requires a subcommand (install|test) — except yarn, whose subcommand
group carried a trailing `?`:
yarn (install|test)?
That made the subcommand optional, so the branch degraded to "yarn " plus
anything: `yarn add foo`, `yarn build`, `yarn dev`, even `yarn --version`
all matched and spammed the "Consider running in tmux" hint into the
additional-context channel.
Drop the `?` so yarn matches parity with npm/pnpm/bun. Verified locally
against 14 cases (yarn install/test still fire; yarn add/build/dev/… no
longer do; npm/pnpm/bun/pytest behavior unchanged).
Fixes #2514
* test(hooks): add pre-bash-tmux-reminder regression tests
Add coverage for the tmux-reminder matcher following the auto-tmux-dev.test.js
structure — the regex-first hook now has direct regression tests for the yarn
branch fix in this PR (and for the sibling package managers, other matched
tools, TMUX bypass, and malformed input).
16 assertions total:
- fires for: yarn install, yarn test, npm install, pnpm test, bun install,
pytest tests/, cargo build
- does NOT fire for: yarn add react, yarn build, yarn dev, yarn --version,
bare `yarn`, npm run dev
- respects TMUX env var
- tolerates invalid JSON and missing command field
Verified the tests actually catch the bug: reintroducing the buggy
`yarn (install|test)?` fails 4 of the 5 yarn non-match cases (the fifth,
bare `yarn`, stays passing because even the buggy branch requires a trailing
space after yarn).
Addresses CodeRabbit review on #2517.
* test(hooks): fail loudly on spawn errors, use destructuring, split runTests
Address three CodeRabbit review notes on tests/hooks/pre-bash-tmux-reminder.test.js:
- Fail loudly on spawnSync errors: raise instead of coercing
`result.status || 0`, which would mask spawn errors, timeouts, or signal
termination as a successful exit 0 (masks legitimate test failures).
- Use destructuring (`const { TMUX, ...env } = process.env`) instead of
copy-then-`delete` so the base env is built immutably.
- Split `runTests` (was 66 lines) into small per-group helpers
(runYarnTests, runSiblingPackageManagerTests, runOtherToolTests,
runTmuxBypassTests, runEdgeCaseTests). `runTests` is now 18 lines and
purely orchestrates.
16 assertions still pass; no coverage changes.
The 4th CodeRabbit note (avoid console.log in test files) is intentionally
not adopted here — every sibling hook test in this repo
(auto-tmux-dev.test.js, bash-hook-dispatcher.test.js, block-no-verify.test.js,
etc.) writes to console.log because the project's own test runner
(tests/run-all.js) is console-log based and there is no Jest/Mocha
dependency. Diverging from the established convention in a bugfix PR is
out of scope.
* test(hooks): trim tmux reminder regression coverage
---------
Co-authored-by: Haley Chen <2022hachen@gmail.com>
|
||
|
|
ee7dded8e9 |
fix(observer): use _clv2_resolve_homunculus_dir (matches lib export) (#2511)
Commit
|
||
|
|
faff56015f |
docs(strategic-compact): document context-window override env vars (#2487)
* docs(strategic-compact): document context-window override env vars * docs(strategic-compact): mirror context-window override env vars for Codex |
||
|
|
4a4fa907f5 |
docs(rules): add Delegation Completion Contract to agent orchestration rules (#2471)
The 'Parallel Task Execution' rule encourages agents to spawn subagents, but defines no completion contract. Observed failure mode: subagents followed the rule, spawned their own children, and returned 'waiting for background agents' as their final answer. All children completed successfully, but their results were orphaned because a parent whose turn has ended cannot receive completion notifications - leaving zombie 'running' tasks and lost work. Adds three rules that apply at every delegation depth: 1. Your final message IS the deliverable (never end with 'waiting') 2. If you delegate, you own collection (no fire-and-forget) 3. Decompose only when work cannot fit in one context |
||
|
|
56d2913f38 | docs(skills): fix typo in remotion charts rule (#2460) | ||
|
|
0071fa5c3c |
refactor(hooks): consolidate PostToolUse hooks into sync/async dispatchers (#2494)
* refactor(hooks): consolidate PostToolUse hooks into sync/async dispatchers Replace 10 individual PostToolUse entries in hooks.json with two consolidated dispatcher entries (post:dispatcher:sync / post:dispatcher:async). The dispatcher's internal registry preserves every hook ID, matcher, and profile, so ECC_DISABLED_HOOKS and ECC_HOOK_PROFILE gating behave exactly as before. Performance (Edit event, actual hooks.json commands spawned in parallel like the harness does, median of 7 runs): - Blocking hook latency: 81ms -> 49ms (~40% faster; 7 blocking processes -> 1 sync dispatcher) - Node processes per tool call: 10 -> 2 (7 blocking + 3 async -> 1 sync + 1 async) - observe-runner now runs in-process (~370ms) inside the async dispatcher, which stays backgrounded (async: true, timeout 45s), so it adds no user-facing latency. Also: - dashboard-web lists dispatcher-managed child hooks so the hook inventory stays complete - post-edit-console-warn refactored to export run() for in-process dispatch while keeping standalone stdin behavior - dispatcher stdin reading is multi-byte safe (StringDecoder) and child hook exit codes propagate to the dispatcher exit code * test(hooks): replace emoji literal with unicode escape for CI unicode safety check * fix(hooks): adopt explicit cli() entrypoint and merge multi-hook stdout Address Greptile review on #2494: - Replace the non-standard 'require.main === undefined' guard with an explicit exported cli(). The hooks.json bootstraps now call require(s).cli(), so merely requiring the module (dashboard-web, test runners, Jest, worker threads) can never trigger dispatch, attach stdin listeners, or set process.exitCode. - Replace last-writer-wins stdout with mergeHookStdout(): when several hooks emit additionalContext envelopes they merge into a single PostToolUse envelope; non-mergeable raw stdout keeps the last hook's output and emits a stderr warning naming the dropped hook IDs, so nothing is lost silently. Also includes local formatter reformatting of the dispatcher and its test file (no behavioral changes beyond the above). * fix(hooks): keep post:bash:dispatcher phase reachable in minimal profile The Greptile P1 premise was partially incorrect: sub-hooks without explicit profiles default to standard,strict via parseProfiles() (scripts/lib/hook-flags.js), so audit/cost logs never ran under the minimal profile on main either — there is no user-visible regression. However, main did spawn the bash dispatcher phase unconditionally and let each sub-hook gate itself. Restore that semantic by opening the outer registry gate to minimal,standard,strict so a future sub-hook that opts into minimal is not silently blocked at the phase level. Adds the previously missing minimal-profile async dry-run test. * test(hooks): assert failing hook exit code propagates to real process status Spawns the actual dispatcher subprocess with an injected failing hook and asserts the OS-level exit status, stderr diagnostic, and suppressed pass-through — closing the E2E gap CodeRabbit flagged on #2494. * chore: retrigger CI (flaky windows powershell bootstrap test) |
||
|
|
754b8dd76c |
fix: make the installer runtime pass strict supply-chain vetting (#2503)
* fix: make the installer runtime pass strict supply-chain vetting
Remediate the four enterprise supply-chain vetting blockers from
affaan-m/ECC#2502 so the installer runtime (package.json + manifests +
scripts/lib/**) passes strict exact-pin evidence policy:
1. Remove the package.json `postinstall` lifecycle script (it only echoed a
post-install banner) and move that banner to an explicit opt-in
`npm run welcome` command. No install-time lifecycle script remains.
2. Exact-pin every dependency in package.json (dependencies + devDependencies)
to the versions already resolved in package-lock.json; no ^/~ ranges.
3. Replace non-ASCII characters on the installer runtime script/config surface:
em-dashes (U+2014) in scripts/lib/{path-safety,install-executor,
install/link-rewrite}.js comments and the two "Itô" (U+00F4) occurrences in
manifests/{install-components,install-modules}.json descriptions become
ASCII, so strict-surface Unicode scanners are clean.
4. Drop the bare `require("ajv")` from scripts/lib/install-state.js; the file
already carries a complete hand-rolled validator enforcing the same
schemas/install-state.schema.json (ecc.install.v1) constraints, so the
installer closure is dependency-free (zero non-builtin bare requires).
Refs affaan-m/ECC#2502
* fix: avoid unpinned welcome invocations
Signed-off-by: Samar Tomar <samar_tomar@hotmail.com>
* fix: validate translated skill frontmatter
Signed-off-by: Samar Tomar <samar_tomar@hotmail.com>
* fix: repair skill frontmatter YAML
Signed-off-by: Samar Tomar <samar_tomar@hotmail.com>
* fix: add MIT license to core skill manifests; pin verification-loop tsc invocation
* fix: preserve tsc/pyright exit status in verification-loop type-check (set -o pipefail)
* chore(deps): sync lockfiles with exact-pinned package.json
Regenerate package-lock.json and yarn.lock so the pinned dependency
specs are reflected in both lockfiles. npm ci and Yarn's --immutable
install now pass the sync check. The resolution tree is unchanged
(231 yarn resolutions, byte-identical set; zero npm transitive drift);
only the root descriptor strings move from ranges to the versions
already resolved in the committed lockfiles.
Addresses the Codex P1 on #2503.
---------
Signed-off-by: Samar Tomar <samar_tomar@hotmail.com>
Co-authored-by: Samarjeet Singh Tomar <samartomar@gmail.com>
|
||
|
|
5da21c2b66 |
fix(project-detect): parse Python deps pinned with ~ and @ (was losing framework detection on compatible-release pins) (#2498)
* fix(project-detect): parse Python deps pinned with ~= and @ direct references * test(project-detect): cover ~= compatible-release and @ direct-reference parsing * test(project-detect): cover direct references * fix(project-detect): skip bare VCS/URL requirement lines in getPythonDeps A requirements.txt line like git+https://host/repo.git#egg=pkg carries no leading package name, so the delimiter split recorded the whole URL fragment as a dependency. Skip names that start with git+ or contain a URL scheme, and tighten the test assertions so any leaked URL, scheme, or @ delimiter fails loudly. |
||
|
|
5d68ef3617 |
fix(plan-canvas): stop dropping list items when a block's first item is over-indented (#2501)
* fix(plan-canvas): stop dropping list items when a block's first item is over-indented * fix: address greptile findings for PR #2501 - list-type detection and outdent nesting - plan-canvas markdown: fix nested list rendering where outdented runs (indent 6→4) create duplicate sibling UL blocks instead of sharing parent (#2501) - transcript-context: add LARGE_WINDOW_NATIVE_MODEL_IDS array for models whose default context window is 1M but do NOT carry the [1m] marker (fixes #2497) - Add test coverage for transcript-context and shell-substitution modules - Add test coverage for project-detect module (#2498) * fix(plan-canvas): handle outdented list runs * fix(plan-canvas): start a new list when marker type changes at the same indent CommonMark treats a marker-type change (bullet to ordered or back) at the same indentation as the start of a new list. buildList previously absorbed the run into the current list, so mixed runs rendered under a single wrong tag. Stop the run on a tag change and let buildListBlock render the next run as a sibling list with its own tag. |
||
|
|
fb98726d0a |
fix(llm/providers/claude): attach cache_control to system block, not top-level (#2515)
* fix(llm/providers/claude): attach cache_control to system block, not top-level
The Anthropic Messages API does not accept `cache_control` as a top-level
request parameter — it is a per-content-block field. Passing it at the top
level raises `TypeError` in the Python SDK (which validates kwargs against
`messages.create()`'s signature) or a `400 unknown_parameter` from the API,
so every ClaudeProvider.generate() call fails.
Move `cache_control: {"type": "ephemeral"}` onto the last system-prompt
block so ephemeral prompt caching still works when a system prompt is
present, and drop it when there isn't one (nothing to cache).
Existing tests didn't catch this because `FakeMessages.create(**_params)`
accepted anything and ignored the kwargs. FakeMessages now records
`last_params`, and two regression tests assert that:
- `cache_control` never appears as a top-level param, and
- when a system prompt is set, `cache_control` rides on the last block.
Fixes #2512
* test(claude_provider): split composite isinstance+truthiness assertion (PT018)
Ruff PT018 flagged the combined `isinstance(system, list) and system` check
in `test_generate_does_not_pass_cache_control_as_top_level_param`. Split
it into two focused asserts (`isinstance(system, list)` then `assert system`)
so a failure points at the exact violation instead of a compound condition.
Behavior unchanged; 6/6 tests still pass.
Addresses CodeRabbit review on #2515.
|
||
|
|
ed38744605 |
fix(hooks): require successful shell probe in observe runner (#2403)
Require observe-runner shell detection to accept only candidates whose probe exits successfully, avoiding Windows WSL launcher false positives. |
||
|
|
40927950c4 |
fix: community-reported issues — pyproject URLs, dashboard Tkinter error, 1.x→2.0 migration guide, cyber-safeguards docs (#2481)
* fix: repo URLs in pyproject, graceful dashboard tkinter error, 1.x->2.0 migration guide, cyber-safeguards troubleshooting Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: catch ImportError for broken tkinter installs and update About panel repo URL Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
f6e18e0835 |
fix(agents): read-only reviewer contract + model re-tiering (#2442) + soften data-scraper prose (#2428) (#2480)
* fix(agents): retier reviewer frontmatter (#2442) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * docs(skills): soften data scraper prose (#2428) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
38a7ebbe32 |
fix(install): reference all curated skills in modules + reverse-coverage guard (#2431) (#2440)
* fix(install): reference all curated skills in modules + add reverse-coverage guard (#2431) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(install): normalize path separators in delivery-gate dry-run assertion (#2431) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
67537ea480 |
fix(repair): build opencode payload so repair clears doctor's opencode-plugin-not-built warning (#2414) (#2438)
* fix(repair): build opencode plugin payload so repair clears doctor's opencode-plugin-not-built warning (#2414) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor(repair): narrow validation bypass to specific codes; fix test-artifact cleanup (#2414 review) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
a511395613 |
feat: Plan Canvas, a browser review canvas for plans (#2467)
* feat: add Plan Canvas - browser annotate-and-approve review for plan artifacts - scripts/plan-canvas.js CLI (open/await/end/stop/server; bin ecc-plan-canvas) - loopback server + ECC-styled chrome + annotation SDK + zero-dep markdown renderer - Approve/Request-changes verdicts wired to the /plan confirmation gate - plan-canvas skill, /plan-canvas command, SessionStart hook surfacing open reviews - shared scripts/lib/loopback-guard.js extracted from control-pane (API re-exported) - 121 new tests incl. full-workflow E2E; registered in manifests, catalog, registry Inspired by lavish-axi (https://github.com/kunchenguid/lavish-axi) by @kunchenguid; original ECC-native implementation, not a port. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * refactor(plan-canvas): invoke via ecc-plan-canvas bin so the skill works from any project Skill/command referenced a cwd-relative `node scripts/plan-canvas.js`, unusable outside the ECC root. Switch to the ecc-plan-canvas bin (and $CLAUDE_PLUGIN_ROOT fallback) and align CLI next_step hints so an agent can run it as a skill in any repo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * feat(plan-canvas): render Mermaid diagrams + ship Codex cross-harness surface - markdown renderer emits <pre class="mermaid"> for ```mermaid blocks (source entity-escaped so the browser decodes it for the renderer while blocking injection) - artifact template loads a pinned Mermaid build only when a diagram is present, themed to ECC dark, securityLevel strict, graceful offline fallback to source (ECC_PLAN_CANVAS_MERMAID_URL overrides for a local mirror) - skill teaches Mermaid-for-diagrams and states the CLI+JSON loop is harness-agnostic - add .agents/skills/plan-canvas (Codex) with agents/openai.yaml interface manifest - register in install-modules workflow-quality paths; docs updated Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * docs(plan-canvas): add demo screenshot Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * fix(ci): sync yarn.lock with new bin; add contributor checklist - yarn.lock records the ecc-plan-canvas bin so Yarn hardened-mode install no longer wants to modify the lockfile on public PRs - PR template + CONTRIBUTING gain a pre-push checklist covering the lockfile trap and the full skill/command/CLI registration surfaces Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Haley Chen <2022hachen@gmail.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com> |
||
|
|
4130457d67 |
fix(tests): use mkdtempSync for test scratch dirs (CodeQL js/insecure-temporary-file) (#2443)
Replaces 54 predictable os.tmpdir()+Date.now() test-home paths in tests/hooks/hooks.test.js and the pid-based transcript files in tests/lib/llm-summary.test.js with fs.mkdtempSync. The 22 claude-tool-count-* sites are left as-is: they intentionally mirror the path the production hook computes. Clears all 16 open code-scanning alerts (#256-#271). |
||
|
|
49128b5763 |
feat(install): add Kimi Code CLI install target (kimi-project adapter) (#2441)
Rebuild of #2154 on current main, following the hermes/openclaw (#2433) adapter recipe: 10-line kimi-project adapter (project kind, ./.kimi root), registry + helpers ownership, SUPPORTED_INSTALL_TARGETS + legacy-compat modules, kimi target on the 5 shared modules + .kimi in platform-configs paths, both schema enums, npm files allowlist, help text, README stub. Credit to @MoYiC6 for the original adapter design in #2154. |
||
|
|
c837139e6c |
feat: add Hermes and OpenClaw harness install targets (#2433)
* feat: add Hermes and OpenClaw harness install targets - Add scripts/lib/install-targets/hermes-home.js and openclaw-home.js - Register new adapters in registry.js and helpers.js - Add hermes/openclaw to SUPPORTED_INSTALL_TARGETS, schema enum, and install help text - Add .hermes/ and .openclaw/ platform source directories with READMEs - Update install-modules.json so rules/agents/commands/platform-configs cover the new targets Verification: - npx ecc doctor reports all 13 targets OK (including hermes-home and openclaw-home) - install-targets regression guard passes for new targets - Catalog check passes * fix(install): register hermes/openclaw in install-modules schema enum + npm files allowlist --------- Co-authored-by: Lxcardoza993 <265670745+Lxcardoza993@users.noreply.github.com> Co-authored-by: Affaan Mustafa <me@affaanmustafa.com> |
||
|
|
2d40baacbd |
fix: resolve open-issue cluster (#2295, #2298, #2303–#2306, #2340) + createdTime fallback bug (#2408)
* fix: resolve issue cluster (#2295,#2298,#2303,#2304,#2305,#2306,#2340) + createdTime fallback bug - session-manager: fix createdTime birthtime||ctime fallback that never fired (a Date is always truthy); use birthtimeMs>0 check via resolveCreatedTime() - installer: rewrite source-relative rules/skills links for the injected ecc/ namespace so installed skills resolve correctly (#2340) - continuous-learning-v2: drop unused mock import (#2305); standardize bash shebangs (#2303); poll for PID file instead of fixed sleep (#2295); rename _ecc_* -> _clv2_* (#2304); align promotion confidence docs (#2298); de-brittle Scope Decision Guide cross-reference (#2306) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): resync lockfiles with package.json (eslint 10) + migrate yarn.lock to Yarn 4 format package.json requires eslint@^10.6.0 but the committed locks pinned 9.39.2, so npm ci aborted and Yarn 4 hardened mode rejected the stale v1-classic yarn.lock (YN0028). Regenerate package-lock.json and rewrite yarn.lock in Yarn 4 (berry) format so npm ci and immutable yarn installs both pass. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): require clean probe exit for Windows shell/bash detection; add pyyaml dev dep Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(observer): portable mktemp template on BSD/macOS (#2417); correct false attribution-disabled claim in git-workflow docs (#2426) (#2430) Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: remove duplicate resolveCreatedTime introduced by merge (no-redeclare) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: restore heading-based Scope Decision Guide ref (line numbers drift) + keep behavioral #2340 install test --------- Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Affaan Mustafa <me@affaanmustafa.com> |
||
|
|
3167852753 |
fix(gateguard): drop \x00 placeholder in glob-to-regex (eslint no-control-regex) (#2439)
Replace the NUL-byte '**' placeholder trick with split('**')/join('.*'),
which is semantically identical and lint-clean under eslint 10.
|
||
|
|
0a35a0216b |
feat(gateguard): add GATEGUARD_EXEMPT_GLOBS path exemptions (#2432)
The fact-forcing gate fires once per first-touched file per session. In
build-heavy sessions this costs a deny->retry round-trip on every new file,
including trees where the gate's questions ("who imports this? what schema?")
carry no signal: test files, generated artifacts, scratch dirs.
Add an opt-in, comma-separated glob allowlist read from GATEGUARD_EXEMPT_GLOBS.
A matching Edit/Write/MultiEdit target skips the first-touch gate; destructive-
Bash and routine-Bash gates are untouched. Default-off (unset => identical prior
behavior), fail-open (a malformed glob is dropped, never throws), and memoized on
the env value, matching the existing getExtraDestructiveRegex idiom.
"env": { "GATEGUARD_EXEMPT_GLOBS": "**/tests/**,**/scratchpad/**" }
Adds 4 tests; all 144 gateguard tests pass.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
||
|
|
8b6543929e |
chore(continuous-learning-v2): standardize shell shebangs to env bash (#2401)
* chore(continuous-learning-v2): standardize shell shebangs to env bash Three scripts under skills/continuous-learning-v2/ used the hardcoded `#!/bin/bash` shebang while the other four already used the portable `#!/usr/bin/env bash`: - hooks/observe.sh (runs on every hook invocation) - scripts/detect-project.sh - agents/start-observer.sh The hardcoded interpreter path fails to execute on systems where bash is not installed at /bin/bash (NixOS, some Homebrew layouts, FreeBSD). Standardize all three to `#!/usr/bin/env bash`, matching the repo-wide majority convention, and add a regression test that asserts shebang uniformity for every shell script in this skill so the inconsistency cannot reappear. Fixes #2303 * test(continuous-learning-v2): harden shebang test runner Address review feedback on the shebang-consistency regression test: - firstLine() now splits on /\r?\n/ so a script checked out with CRLF line endings does not leave a trailing carriage return that would break the shebang comparison on Windows. - The test() helper now surfaces the full error (stack trace, not just the message) on failure and writes pass/fail lines via process.stdout/stderr so diagnostics are preserved. * test(continuous-learning-v2): skip hidden dirs in shebang scan The recursive shell-script scan now skips hidden directories (e.g. the observer's runtime `.observer-tmp`). This keeps the shebang-consistency check deterministic: only committed skill scripts are examined, and an untracked local artifact left over from an observer run can no longer cause a false failure. |
||
|
|
ff4a06dd91 |
feat(session-start): make instinct injection count and confidence threshold configurable (#2413)
* feat(session-start): make instinct injection count and confidence threshold configurable Expose ECC_MAX_INJECTED_INSTINCTS and ECC_INSTINCT_CONFIDENCE_THRESHOLD so operators can tune SessionStart instinct injection without editing source. Defaults are unchanged (6 instincts, 0.7 confidence floor). The two previously hardcoded constants become DEFAULT_-prefixed fallbacks, resolved through getMaxInjectedInstincts() and getInstinctConfidenceThreshold(), mirroring the existing getSessionRetentionDays() / getSessionStartMaxContextChars() env-override pattern already in this file. Invalid or out-of-range values fall back to the defaults. Adds subprocess coverage in tests/hooks/hooks.test.js and documents both variables in the README Hook Runtime Controls section. Implements part (a) of #2371. * fix(session-start): reject partial env values for instinct injection knobs Parse ECC_MAX_INJECTED_INSTINCTS and ECC_INSTINCT_CONFIDENCE_THRESHOLD with Number() (after trim) instead of parseInt/parseFloat, so malformed values like "3.9", "6abc", or "0.7x" fall back to the default rather than silently accepting the numeric prefix (parseInt("3.9")=3, parseFloat("0.7x")=0.7). Adds a regression assertion that a non-integer count falls back to 6. * fix(session-start): validate decimal grammar for instinct injection env vars Number() still accepts non-decimal numeric syntax, so ECC_INSTINCT_CONFIDENCE_THRESHOLD=0x1 resolved to 1 and ECC_MAX_INJECTED_INSTINCTS=1e2 to 100. Gate each value on a strict format (/^\d+(\.\d+)?$/ for the 0-1 threshold, /^\d+$/ for the positive-integer count) before converting, so hex/exponent/partial values fall back to the default. Adds regression assertions for 1e2 and 0x1. |
||
|
|
41599069c3 |
fix(steering): add missing name attribute to auto-inclusion steering files (#2416)
* fix(steering): add missing name attribute to auto-inclusion steering files * docs: include name attribute on steering file example --------- Co-authored-by: Jucelio Brandao Goncalves Junior <jbgjunior@simpress.com.br> |
||
|
|
0a926b45ba |
fix(install): rewrite relative skill links for injected ecc namespace (#2399)
* fix(install): rewrite relative skill links for injected ecc namespace Skill and rule markdown is byte-copied during a claude install, but the home/project adapters inject an `ecc/` namespace segment (skills/<id> -> skills/ecc/<id>, rules/<x> -> rules/ecc/<x>). Source-relative links such as `../../rules/react/hooks.md` therefore broke after install: the extra level changed what `../..` resolved to, and the link target itself moved under rules/ecc/. Rewrite relative links in namespaced markdown so they resolve to the file's actual installed location, derived from the plan's own file placements (no hardcoded namespace literal, so the links cannot drift from where files land). Non-namespacing adapters and links to non-installed targets are left untouched; URLs, anchors, absolute paths, and fenced code blocks are never rewritten. Fixes #2340 * fix(install): keep non-namespaced markdown on the byte-for-byte copy path Address review feedback: the markdown branch in applyInstallPlan diverted every copy-file markdown operation through read+rewrite+write, so identity-mapped markdown (source path == install path, no namespace injected) lost byte-for-byte content and source mode bits even though no link rewrite was needed. Gate the rewrite on isNamespacedSource() so only files whose install path actually changed (e.g. skills/x -> skills/ecc/x) leave the copyFileSync path; everything else is copied verbatim as before. * test(install): emit failure stack in the link-rewrite test runner Address review feedback: the local test() harness logged only error.message, so a failing assertion lost its source line and diff. Print error.stack on stderr on failure so broken rewrite cases stay diagnosable. |
||
|
|
90f82d360b |
fix(observer): replace hardcoded sleep 2 with PID file poll in start-observer.sh (#2356)
* fix(observer): replace hardcoded sleep 2 with PID file poll in start-observer.sh Fixes #2295 The previous `sleep 2` after launching the observer loop has two problems: on slow filesystems or loaded systems 2 seconds may not be enough, producing a false-negative on the subsequent PID file check; on healthy systems it adds unnecessary latency. Replace with a poll loop that exits as soon as the PID file appears: for _i in $(seq 1 50); do [ -f "$PID_FILE" ] && break; sleep 0.2; done 50 × 0.2s = 10s max wait (vs the previous fixed 2s), but typical startup returns within the first iteration. No behavior change in the success path — only the wait strategy changes. Tests: `node tests/run-all.js` 2891 passed / 0 failed; `npm run lint`, `catalog:check`, `command-registry:check` all clean. * test(observer): add regression guard for sleep-2 → PID-file poll (#2295) Asserts start-observer.sh never reverts to the fixed `sleep 2` wait and keeps the 50 × 0.2s `$PID_FILE` poll in place. Sits next to the existing observer-loop invariant block in tests/hooks/hooks.test.js, matching the repo's pattern of guarding shell-script invariants via source-content assertions. Without this, any future "cleanup" that reintroduces a fixed sleep would silently regress the slow-filesystem fix from the previous commit. * fix(observer): loosen poll-regression assertions and document failure-path latency (#2356 review) Addresses CodeRabbit + Greptile feedback on PR #2356: - tests/hooks/hooks.test.js: split the over-specific positive assertion (which pinned the exact `for _i in $(seq 1 50); … sleep 0.2; done` line) into three intent-based assertions — bounded iteration count, early-exit on $PID_FILE, sub-second interval. Valid refactors (rename loop var, switch to `while`, retune to 100 × 0.1s) no longer false-fail while the `sleep 2` regression remains guarded. - start-observer.sh: extend the inline comment to record the trade-off Greptile flagged — a loop that crashes before writing $PID_FILE is now detected in ~10s instead of ~2s. Healthy startups still return in iteration 1. Tests: node tests/run-all.js (Node v22.18.0) → 2892 passed / 0 failed. |
||
|
|
c8c83ef428 |
fix(install): dedupe copy-file operations sharing a destination (#2429)
OpenCode ships override command files under .opencode/commands/ that shadow the generic commands/*.md sources. The manifest install plan recorded both writes against the same destination, so `ecc doctor` reported perpetual drift for the 29 shadowed command files and `ecc repair` "fixed" that phantom drift by copying the generic source over the correct override, corrupting the installed command while never clearing the warning. Dedupe copy-file operations by destination in createManifestInstallPlan, keeping the last writer to match the sequential apply order. install, repair, and doctor all consume this one builder, so a fresh install is clean and a single repair rewrites drifted state green. Fixes #2414 |
||
|
|
52f7e82a61 |
docs(continuous-learning-v2): observer.md promotion uses avg confidence, not per-instance (#2411)
SKILL.md and _promote_auto already use avg_conf >= 0.8; observer.md (EN + zh-CN) was missed and still says per-instance. Same drift as #2274. Refs #2298. |
||
|
|
8c3a3040ae |
fix(skills): document plugin vs manual hook setup for strategic-compact (#2420)
The Hook Setup section told all users to wire
`node ~/.claude/scripts/hooks/suggest-compact.js` into settings.json.
That path only exists on manual `./install.sh` installs; for plugin
installs the hook is already registered by the plugin's hooks/hooks.json
(id `pre:edit-write:suggest-compact`, standard/strict profiles), so the
snippet fails silently and would double-register the hook.
- Add a plugin-install note (mirrors continuous-learning-v2 wording)
and scope the snippet to manual installs — applied to the canonical
skill, the .kiro mirror, and ja-JP/zh-CN/zh-TW/ko-KR translations
- ko-KR: also replace the settings.json snippet that used
`${CLAUDE_PLUGIN_ROOT}`, which does not resolve in user settings.json
|
||
|
|
e05a201258 |
fix(rules): add paths frontmatter to web rule pack (#2425)
Every other language pack (typescript, react, python, golang, vue, ...) scopes its rules with a paths: YAML frontmatter block, so Claude Code only loads them when matching files are in context. The 7 files in rules/web/ ship without frontmatter, and per the official rules-loading docs (https://code.claude.com/docs/en/memory) rules without a paths field load unconditionally into every session - ~15.5KB of always-on context even in projects with no frontend code. Add the same frontmatter convention used by the react pack, scoped to web-facing file types (css/scss/sass/less/html/tsx/jsx/vue/svelte). |
||
|
|
fb37c23c84 |
fix(golang-patterns): replace removed govet check-shadowing with enable: [shadow] (#2423)
golangci-lint deprecated the govet `check-shadowing` setting in v1.57.0 and later removed it; a config using it now errors. The current v1-format way to enable the shadow analyzer is `govet.enable: [shadow]`. Applies to the source skill and the ja-JP, zh-CN, zh-TW, ko-KR, tr translated copies. Refs: https://golangci-lint.run/docs/product/migration-guide/ |
||
|
|
ee2663d5b2 |
fix(clickhouse-io): use official @clickhouse/client instead of unmaintained clickhouse package (#2422)
* fix(clickhouse-io): use official @clickhouse/client instead of unmaintained clickhouse package
The example imported the third-party `clickhouse` (TimonKK) package and used
its API (new ClickHouse, .query().toPromise(), .insert().stream()). Migrate to
the official @clickhouse/client: createClient() and structured
clickhouse.insert({ table, values, format }). The structured values array also
removes the previous SQL string-interpolation anti-pattern.
Applies to the source skill and the ja-JP, zh-CN, zh-TW, ko-KR translated
copies (translated code comments preserved).
Refs: https://clickhouse.com/docs/integrations/javascript
* fix(clickhouse-io): migrate remaining insert calls to @clickhouse/client
Address review feedback: the earlier commit missed two spots that still used
the legacy clickhouse API.
- CDC example: clickhouse.insert('market_updates', [...]) ->
clickhouse.insert({ table, values, format: 'JSONEachRow' })
- Single-row insertTrade: map the row to the column shape (same as the bulk
path) instead of passing the raw trade object.
Applies to the source skill and the ja-JP, zh-CN, zh-TW, ko-KR copies.
|
||
|
+28 |
7a46a7b8fc |
docs: MRR-biased ECC Pro + AgentShield security roadmap (#2321)
* docs: add MRR-biased ECC Pro + AgentShield security roadmap Output of a multi-agent survey + research pass: capability map of AgentShield and ECC Pro, triage of every open PR/issue on both repos, and web research on competitors, unbuilt ideas, and dev-tool demand. 17 items across 4 themes (now/next/later) scored for free-to-paid conversion, each linked to the real PRs/issues that implement it. Includes the reusable workflow script that generated it. Headline: ecc-agentshield is ~30K downloads/month with near-zero monetization bridge, and the agent-proximity moat is computed but never rendered. Roadmap removes trust blockers (FP cluster), makes the moat visible (PR #2320), then productizes local CLI primitives into hosted Pro surfaces. * docs(design): add hosted Pro fleet dashboard design (Sentry for agent security) Implementation-ready architecture for the flagship 'next' roadmap item: a hosted, multi-repo agent-security posture dashboard built on the existing ecc-agentshield primitives (evidence-pack bundleDigest + operatorReadback, watch/drift DriftResult, runtime NDJSON, baseline diff, policy promotion). Covers free-vs-Pro scope, ingestion/query API grounded in real field names, data model + time-series rollups, auth/RBAC + redaction guarantees, MVP build order, and pricing hooks. Companion to ECC-PRO-SECURITY-ROADMAP.md. * feat(control-pane): serve 3D agent-airspace viz + /api/proximity feed (#2320) Adds the Layer 4 observability view to the control pane: a self-contained, dependency-free 3D point-cloud of the agent airspace (positions from the proximity embedding, sized by working set, colored by collision risk, links for converging pairs) plus an XSS-safe advisory panel that polls every 5s. - proximity-viz.js: renderProximityVizHtml() (canvas projection, no external JS) - server.js: GET /proximity (page) + GET /api/proximity (snapshot.proximity feed) - test: asserts both routes serve and the feed carries positions/links/advisories * fix(clv2): escape $HOME before pgrep -f in migrate-homunculus.sh (#2339) * fix(clv2): escape $HOME before pgrep -f in migrate-homunculus.sh pgrep -f treats its argument as an extended regular expression, but the running-observer guard interpolated $HOME unescaped. Paths containing regex metacharacters (e.g. /home/user.name, /home/c++dev, /home/user (work)) made the match over-broad or invalid, causing either a false negative (live observer missed, migration proceeds and risks registry corruption) or a false positive (migration blocked unnecessarily). Escape the ERE metacharacters in $HOME via sed before building the pattern so the home prefix is matched literally while the trailing .*observer-loop\.sh regex is preserved. Portable across BSD and GNU sed. Fixes #2301 * test(clv2): add regression test for migrate-homunculus.sh $HOME escaping Guards the #2301 fix: extracts the script's sed escaping command and asserts the resulting pgrep -f pattern matches the literal home path while no longer over-matching a regex-expanded decoy (HOME=/home/user.name must not match /home/userXname). Also pins that the guard uses escaped_home rather than $HOME directly. Follows the existing clv2 shell-test convention in tests/hooks/observe-entrypoint-allowlist.test.js. Refs #2301 * test(clv2): skip migrate-homunculus escaping test on Windows The test relies on POSIX bash/sed/grep -E semantics, which differ on the Windows CI runners. Guard with the same process.platform === 'win32' early exit used by tests/hooks/observe-subdirectory-detection.test.js so the bash-dependent assertions only run on POSIX platforms. Refs #2301 * fix(clv2): harden registry writes and project deletion (#2294, #2297) (#2323) Two security-priority fixes in continuous-learning-v2/scripts/instinct-cli.py: - #2294: _write_registry wrote projects.json without the advisory lock that _update_registry holds, so concurrent 'projects delete/gc/merge' could race an observe-time update and corrupt the registry. Extract the lock into a shared _registry_lock() context manager and use it in both writers. - #2297: _remove_project_storage called shutil.rmtree on PROJECTS_DIR/project_id with no containment check. Add defense-in-depth: resolve the path and refuse to delete anything that is not strictly inside PROJECTS_DIR (or is the root itself), so a relaxed validator or future caller can never cause an arbitrary-directory delete. Adds 5 pytest regression tests (atomic write under lock, contained delete, missing-dir no-op, traversal refused, root refused). Node integration suite (tests/scripts/instinct-cli-projects.test.js) green 9/9. * feat(workflows): add orch-review native Workflow pilot (#2363) * feat(workflows): add orch-review native Workflow pilot Port orch-pipeline Phase 5 (Review) to a native Claude Code Workflow script. The gated outer loop stays in the main conversation; this script owns only the autonomous review+verify segment between the two human gates: 1. Review — reviewers fan out in parallel: ecc:code-reviewer always, ecc:<language>-reviewer when args.language maps, ecc:security-reviewer when the orch-pipeline security trigger matches the diff/paths. 2. Dedup — merge findings across dimensions keyed on the normalized evidence snippet, since independent reviewers flag the same line. 3. Verify — each unique CRITICAL/HIGH finding goes to an independent adversarial verifier; MEDIUM/LOW pass through as advisory. The Review->Verify barrier is deliberate: deduping before verification stops the verifier running N times on the same bug (local testing: 11 raw findings collapsed to 4 unique, ~halving verifier cost). Existing ECC reviewer subagents are reused via agentType; reviewer output is validated by JSON schema. args is accepted as an object or a JSON-encoded string. - workflows/orch-review.workflow.js — the workflow script - workflows/README.md — invocation contract, returns shape, follow-ups CI lint is scoped to scripts/ and tests/, so the script (validated with node --check) and the README (passes markdownlint) are untouched. * fix(workflows): fail closed on invalid args and lost review dimensions Addresses the two safety findings from the PR bot review: 1. Lost review dimension (Greptile P1 / CodeRabbit Major): a reviewer agent that returns null or rejects was silently dropped by filter(Boolean), so an unreviewed security dimension could still return APPROVE. Each dimension's outcome is now captured; failures land in failedDimensions and force CHANGES_REQUESTED (incomplete). 2. Invalid args (CodeRabbit Major): an empty diff returned APPROVE and bad JSON / non-array changedFiles threw inconsistently. Input is now validated up front and rejected with a clear error — the gate fails closed instead of approving an unreviewed payload. Docs (header contract + README) updated for the new return fields (incomplete, failedDimensions, stats.failed). Remaining bot nits (evidence minLength, verify-label collision, verified->confirmed rename, contract drift) deferred as follow-ups. * fix(workflows): address remaining orch-review review nits Follow-up to the bot review (deferred items from the safety pass): - evidence: require minLength 1 in the schema, and fall back to a title+line dedup key when evidence is empty, so empty-evidence findings in one file no longer collapse onto a single key and drop (CodeRabbit). - verify label: include a slice of the normalized evidence so two CRITICAL/HIGH findings from the same file get distinct labels and do not alias under resumability (Greptile). - stats.verified -> stats.confirmed to match the "confirmed" wording used in the log and avoid ambiguity vs the refuted count (Greptile); header contract and README updated to match. Verified by running the workflow on a synthetic vulnerable diff: dedup 12 raw -> 5 unique, stats.confirmed populated, fail-closed fields (incomplete/failedDimensions) intact. * fix(workflows): harden verify stage and diff-only verification Addresses the second-round bot review: - Verify stage now has the same failure guard as the review stage: a rejected verifier no longer nulls out its slot (which crashed the later filter). A null return is treated as unconfirmed; a rejection keeps the finding as blocking (fail closed) so an unverifiable CRITICAL is never silently demoted to advisory (CodeRabbit @221). - verifyPrompt now instructs the skeptic to judge solely from the provided diff text and not to refute merely because the referenced file is absent from the working tree (the diff may be an unapplied PR). Fixes the false-refute seen when testing on a synthetic diff. CodeRabbit @81 (evidence minLength) was already addressed in the prior commit; this is a stale re-post on the unresolved thread. * fix(workflows): keep unverifiable blockers blocking; stop leaking error text Second-round bot review (CodeRabbit): - @218 Treat a null/failed verifier as `unverified`, not refuted. A terminal verifier failure or skip no longer demotes a CRITICAL/HIGH to advisory; it stays in `blocking` tagged "could not be verified" (fail closed). Only a genuine isReal=false verdict is refuted. Adds stats.unverified. - @189 Do not return raw subagent error text. Review/verify failures now log the raw message for operators and return only a bounded label (failedDimensions[].error = "review agent failed"). Stale re-posts this round (@81 evidence minLength, @224 verify guard) were already fixed in prior commits. * docs(workflows): enumerate bounded failedDimensions.error labels CodeRabbit (trivial): the public contract implied callers get human-readable error text, but the implementation returns only bounded labels. Enumerate them in the README returns block. * Update yarn.lock (#2342) * Add memxus configuration to mcp-servers.json (#2355) * Add memxus configuration to mcp-servers.json Added configuration for Memxus service with API key placeholder and description. * Revise description in mcp-servers.json Updated the description to include a note about reviewing stored memories to prevent prompt-injection. * Update description in mcp-servers.json Update description in mcp-servers.json * Fix for docs: Scope Decision Guide table duplicated in SKILL.md and observer.md with minor drift (#2366) #2306 Co-authored-by: angadsingh7666 <angdsingh7666@gmail.com> * fix(llm): align Claude provider with current Anthropic API (#2133) Replace invalid default model IDs (e.g. claude-sonnet-4-7) with current claude-sonnet-4-6, claude-opus-4-8, and claude-haiku-4-5. Route system messages to the API system field, enable ephemeral prompt caching, omit temperature for Opus 4.7/4.8, and surface cache usage metrics. Update the CLI model picker to match. Co-authored-by: Vladimir Đuranović <vlada@MacBook-Pro.local> Co-authored-by: Cursor <cursoragent@cursor.com> * fix(release): derive approval gate paths from version (#2383) Co-authored-by: jan <jan@w-saxs001.local> * fix(release): derive video suite paths from version (#2384) Co-authored-by: jan <jan@w-saxs001.local> * ci: isolate OMP workflow verification (#2382) Co-authored-by: jan <jan@w-saxs001.local> * fix(tests): resolve 10 failing tests on Windows (#2307) - resolve-formatter: stop findProjectRoot walk before os.homedir() to avoid mistaking global dotfiles (e.g. ~/.prettierrc) for a project root - instinct-cli-projects: detect python3/python binary at runtime; skip gracefully when Python 3 is unavailable instead of crashing with null status - command-registry: regenerate COMMAND-REGISTRY.json (was stale) Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * fix(hooks): quote args when probing Windows .cmd MCP servers via shell (#2343) On Windows, when a bare-name MCP server command (e.g. codesys-mcp-sp21-plus) falls back to the .cmd candidate, the probe sets shell:true to work around Node 18.20+ CVE-2024-27980. However, passing an args array alongside shell:true causes Node to concatenate the tokens without quoting (DEP0190), so an arg containing a space (e.g. --codesys-path "C:\Program Files\...") is re-split by cmd.exe at every space boundary. The child process receives a truncated path, fails to launch, and the probe declares the server unavailable, falsely blocking every MCP tool call to that server. Fix: add a quoteWin() helper that double-quotes any token containing whitespace or cmd metacharacters. In the useShell branch, build a single properly-quoted command line string and pass it as the sole argument to spawn() with no separate args array. The else branch (shell:false, all non-.cmd commands) is unchanged. Regression test added: on Windows, creates a .cmd shim that echoes its first positional argument to stderr, probes it with a space-containing path arg, and asserts the probe succeeds and the arg was not split at the space boundary. Co-authored-by: Karstein Phobic Nyvold Kvistad <karstein.kvistad@maritimerobotics.com> * fix(hooks): guard doc-file-warning stdin listeners behind require.main (#2358) * fix(hooks): guard doc-file-warning stdin listeners behind require.main doc-file-warning.js registered process.stdin data/end listeners at module scope while also exporting run(). run-with-flags.js require()s any hook that exports run() for its in-process fast path, so importing this hook attached stray stdin listeners to the dispatcher process, corrupting the PreToolUse stdout JSON contract. This is the exact failure run-with-flags' own SAFETY comment warns about, and 24 sibling hooks already guard against it. - Move the stdin entrypoint into main() and gate it behind require.main === module - pre-write-doc-warn.js now calls main() explicitly instead of relying on the import side effect - Add regression tests: require() attaches no stdin listeners, run()/main() stay exported, and the pre-write-doc-warn shim still warns * docs(hooks): add JSDoc for doc-file-warning main() entrypoint Satisfies the docstring-coverage pre-merge check; documents the stdin entrypoint and why it must not run on require(). * fix(windows): prefer PowerShell over bash to prevent zombie process accumulation (#2346) * fix(windows): prefer PowerShell over bash to prevent zombie process accumulation On Windows, ECC hook scripts were spawning bash.exe (MSYS2/Git Bash) on every tool use via findShellBinary(). These processes were not reaped by Windows, causing 40+ zombie bash.exe/conhost.exe processes per session with noticeable system lag. Changes to scripts/hooks/plugin-hook-bootstrap.js: - Add isPowerShellBin(bin) helper: basename-based detection so full paths like C:\Windows\...\powershell.exe are handled correctly - findShellBinary(): check BASH env var first (preserves escape hatch), then on win32 probe pwsh.exe -> powershell.exe -> bash.exe -> bash; use correct probe args per shell type; cache result in _cachedShell - findBashBinary(): separate cached bash-only finder used by spawnShell .sh fallback; skips PowerShell binaries even if BASH points to one - spawnShell(): use isPowerShellBin() to select -NoProfile -NonInteractive -File args for PowerShell; .sh scripts fall back to findBashBinary() with a skip-warning if no bash found on Windows observe-runner.js is intentionally unchanged: it always invokes observe.sh which is bash-only; routing it through PowerShell would silently break it. The observe.sh -> observe.js migration is tracked separately. Fixes #2345 * fix(windows): address CodeRabbit and Greptile review comments - Add timeout: 30000 to all spawnSync probe calls in findShellBinary and findBashBinary to prevent hangs on broken/stalled shell candidates - Add -ExecutionPolicy Bypass to PowerShell -File invocation to fix execution on machines with the default Restricted policy (Win10/11) - Add PowerShell availability skip guard to PS selection test (mirrors existing bash skip guard) - Fix no-bash test to keep PowerShell on PATH so the .sh fallback branch is actually exercised rather than hitting shell-unavailable early exit * test: add timeout to spawnSync probes in Windows test skip guards --------- Co-authored-by: Christopher J Diamond <diamondcj@leidos.com> * feat(session): LLM-powered session summary via claude -p (#2388) Replace mechanical text extraction in session-end.js and pre-compact.js with LLM-generated summaries using `claude -p`. Summaries now capture design decisions, resolved bugs, changed files, and carry-over context rather than just truncated user message snippets. - Add scripts/lib/llm-summary.js: generateSessionSummary, extractConversationText, getContextRemainingPct, getContextThreshold, getLLMModel - Update scripts/hooks/session-end.js: trigger LLM when context < 20% or every 50 messages (env-configurable via ECC_LLM_SUMMARY_*) - Update scripts/hooks/pre-compact.js: generate LLM summary right before compaction and write it to the active session .tmp file - Add tests/lib/llm-summary.test.js: 18 unit tests - Update tests/hooks/hooks.test.js: 3 integration tests for new behaviour Recursion guard: sets ECC_SKIP_LLM_SUMMARY=1 in subprocess env so Stop hooks fired by the claude -p subprocess do not re-enter summarisation. Requires no ANTHROPIC_API_KEY — reuses Claude Code's own authentication. Co-authored-by: Hiroshi Tanaka <hiroshi_tanaka@MBAM3.local> Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(deps): update anthropic requirement from >=0.25.0 to >=0.111.0 (#2329) Updates the requirements on [anthropic](https://github.com/anthropics/anthropic-sdk-python) to permit the latest version. - [Release notes](https://github.com/anthropics/anthropic-sdk-python/releases) - [Changelog](https://github.com/anthropics/anthropic-sdk-python/blob/main/CHANGELOG.md) - [Commits](https://github.com/anthropics/anthropic-sdk-python/compare/v0.25.0...v0.111.0) --- updated-dependencies: - dependency-name: anthropic dependency-version: 0.111.0 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump actions/checkout from 6.0.3 to 7.0.0 (#2328) Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.3 to 7.0.0. - [Release notes](https://github.com/actions/checkout/releases) - [Commits](https://github.com/actions/checkout/compare/v6.0.3...v7) --- updated-dependencies: - dependency-name: actions/checkout dependency-version: 7.0.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml (#2330) Bumps [slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml](https://github.com/slsa-framework/slsa-github-generator) from 1.4.0 to 2.1.0. - [Release notes](https://github.com/slsa-framework/slsa-github-generator/releases) - [Changelog](https://github.com/slsa-framework/slsa-github-generator/blob/main/CHANGELOG.md) - [Commits](https://github.com/slsa-framework/slsa-github-generator/compare/68bad40844440577b33778c9f29077a3388838e9...f7dd8c54c2067bafc12ca7a55595d5ee9b75204a) --- updated-dependencies: - dependency-name: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml dependency-version: 2.1.0 dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump cron from 0.16.0 to 0.17.0 in /ecc2 (#2333) Bumps [cron](https://github.com/zslayton/cron) from 0.16.0 to 0.17.0. - [Release notes](https://github.com/zslayton/cron/releases) - [Commits](https://github.com/zslayton/cron/commits) --- updated-dependencies: - dependency-name: cron dependency-version: 0.17.0 dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): update pytest requirement from >=8.0 to >=9.1.1 (#2324) Updates the requirements on [pytest](https://github.com/pytest-dev/pytest) to permit the latest version. - [Release notes](https://github.com/pytest-dev/pytest/releases) - [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest/compare/8.0.0...9.1.1) --- updated-dependencies: - dependency-name: pytest dependency-version: 9.1.1 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): update mypy requirement from >=1.10 to >=2.1.0 (#2326) Updates the requirements on [mypy](https://github.com/python/mypy) to permit the latest version. - [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md) - [Commits](https://github.com/python/mypy/compare/v1.10.0...v2.1.0) --- updated-dependencies: - dependency-name: mypy dependency-version: 2.1.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): update pytest-cov requirement from >=4.1 to >=7.1.0 (#2332) Updates the requirements on [pytest-cov](https://github.com/pytest-dev/pytest-cov) to permit the latest version. - [Changelog](https://github.com/pytest-dev/pytest-cov/blob/master/CHANGELOG.rst) - [Commits](https://github.com/pytest-dev/pytest-cov/compare/v4.1.0...v7.1.0) --- updated-dependencies: - dependency-name: pytest-cov dependency-version: 7.1.0 dependency-type: direct:development ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the actions-minor-and-patch group across 1 directory with 3 updates (#2325) Bumps the actions-minor-and-patch group with 3 updates in the / directory: [actions/setup-node](https://github.com/actions/setup-node), [pnpm/action-setup](https://github.com/pnpm/action-setup) and [softprops/action-gh-release](https://github.com/softprops/action-gh-release). Updates `actions/setup-node` from 6.3.0 to 6.4.0 - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](https://github.com/actions/setup-node/compare/v6.3.0...48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e) Updates `pnpm/action-setup` from 6.0.8 to 6.0.9 - [Release notes](https://github.com/pnpm/action-setup/releases) - [Commits](https://github.com/pnpm/action-setup/compare/0e279bb959325dab635dd2c09392533439d90093...0ebf47130e4866e96fce0953f49152a61190b271) Updates `softprops/action-gh-release` from 3.0.0 to 3.0.1 - [Release notes](https://github.com/softprops/action-gh-release/releases) - [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md) - [Commits](https://github.com/softprops/action-gh-release/compare/b4309332981a82ec1c5618f44dd2e27cc8bfbfda...718ea10b132b3b2eba29c1007bb80653f286566b) --- updated-dependencies: - dependency-name: actions/setup-node dependency-version: 6.4.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions-minor-and-patch - dependency-name: pnpm/action-setup dependency-version: 6.0.9 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-minor-and-patch - dependency-name: softprops/action-gh-release dependency-version: 3.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions-minor-and-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps): bump the cargo-minor-and-patch group across 1 directory with 3 updates (#2387) Bumps the cargo-minor-and-patch group with 3 updates in the /ecc2 directory: [ratatui](https://github.com/ratatui/ratatui), [anyhow](https://github.com/dtolnay/anyhow) and [uuid](https://github.com/uuid-rs/uuid). Updates `ratatui` from 0.30.1 to 0.30.2 - [Release notes](https://github.com/ratatui/ratatui/releases) - [Changelog](https://github.com/ratatui/ratatui/blob/main/CHANGELOG.md) - [Commits](https://github.com/ratatui/ratatui/compare/ratatui-v0.30.1...ratatui-v0.30.2) Updates `anyhow` from 1.0.102 to 1.0.103 - [Release notes](https://github.com/dtolnay/anyhow/releases) - [Commits](https://github.com/dtolnay/anyhow/compare/1.0.102...1.0.103) Updates `uuid` from 1.23.3 to 1.23.4 - [Release notes](https://github.com/uuid-rs/uuid/releases) - [Commits](https://github.com/uuid-rs/uuid/compare/v1.23.3...v1.23.4) --- updated-dependencies: - dependency-name: ratatui dependency-version: 0.30.2 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: anyhow dependency-version: 1.0.103 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch - dependency-name: uuid dependency-version: 1.23.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: cargo-minor-and-patch ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * chore(deps-dev): bump eslint from 9.39.2 to 10.6.0 (#2260) Bumps [eslint](https://github.com/eslint/eslint) from 9.39.2 to 10.6.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Commits](https://github.com/eslint/eslint/compare/v9.39.2...v10.6.0) --- updated-dependencies: - dependency-name: eslint dependency-version: 10.5.0 dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix(ci): unbreak main after dependabot batch (checkout SHA + lint) (#2393) * fix(ci): track actions/checkout v7 SHA in supply-chain workflow test Dependabot #2328 bumped actions/checkout v6->v7, changing the pinned SHA in supply-chain-watch.yml; update the test's expected SHA to match. * Revert "feat(workflows): add orch-review native Workflow pilot (#2363)" This reverts commit |
||
|
|
914a58a716 |
feat(workflows): re-land orch-review workflow + add /orch-review command (#2400)
* feat(workflows): re-land orch-review workflow + add /orch-review command Re-lands #2363 (reverted by #2393 to unbreak main's lint) and fixes the root cause so it stays green: - Restore workflows/orch-review.workflow.js + workflows/README.md. - eslint.config.js: ignore 'workflows/**/*.workflow.*' and '.claude/workflows/**' per the maintainer's note in #2393. Workflow DSL scripts use both top-level export (ESM) and top-level return (the runtime wraps them in an async fn), which no single eslint sourceType can parse — they must be excluded, not lint-fixed. 'npx eslint .' is green with this ignore. - Add commands/orch-review.md (the /orch-review surface) + regenerate docs/COMMAND-REGISTRY.json. Supersedes #2397 (command-only), which referenced the reverted workflow. * fix(workflows): address orch-review bot review findings - Verifier uncertainty no longer demotes blockers (Greptile P1 + CodeRabbit): isReal=false only refutes when confidence >= 0.8; low-confidence 'false' is treated as uncertain and kept blocking (fail closed). - Treat the diff (and finding text) as untrusted input in both review and verify prompts; ignore embedded directives (prompt-injection hardening). - Validate changedFiles entries are strings, not just that it is an array. - Enforce proof for HIGH/CRITICAL in FINDINGS_SCHEMA, not only in the prompt. - Remove in-place mutation in dimension build + dedup merge (immutable). - /orch-review: extract & validate a numeric PR id before shelling out to gh. - Docs: complete the stats example, soften wording, refresh follow-up list. * style(workflows): apply formatter to orch-review assembly * fix(plan-orchestrate): detect ecc@ecc marketplace + emit ecc: agent prefix (#2316) (#2409) * fix(plan-orchestrate): detect ecc@ecc marketplace + emit ecc: agent prefix (#2316) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): resync lockfiles with package.json (eslint 10) + migrate yarn.lock to Yarn 4 format package.json requires eslint@^10.6.0 but the committed locks pinned 9.39.2, so npm ci aborted and Yarn 4 hardened mode rejected the stale v1-classic yarn.lock (YN0028). Regenerate package-lock.json and rewrite yarn.lock in Yarn 4 (berry) format so npm ci and immutable yarn installs both pass. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): require clean probe exit for Windows shell/bash detection; add pyyaml dev dep Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor: consolidate duplicated hook-root resolver into shared resolveEccRoot() (#2368) (#2410) * fix(ci): resync lockfiles with package.json (eslint 10) + migrate yarn.lock to Yarn 4 format package.json requires eslint@^10.6.0 but the committed locks pinned 9.39.2, so npm ci aborted and Yarn 4 hardened mode rejected the stale v1-classic yarn.lock (YN0028). Regenerate package-lock.json and rewrite yarn.lock in Yarn 4 (berry) format so npm ci and immutable yarn installs both pass. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): require clean probe exit for Windows shell/bash detection; add pyyaml dev dep Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor: consolidate duplicated hook-root resolver into shared resolveEccRoot() (#2368) The inline node -e resolver blob was duplicated ~60x across hooks.json, command docs, and translations. Each copy inlined the full ~700-char plugin-root search using a spread over nested array literals (p.join(d,'plugins',...s) over [['ecc'],...]), which breaks Windows hook execution due to shell quoting (#2368). Collapse every copy to a 250-char locator that loads the committed resolve-ecc-root module and delegates to resolveEccRoot() — no spread, no nested array literals, no escaped double quotes. The real search logic now lives in one tested module. Also route session-start-bootstrap.js through resolveEccRoot() instead of its own duplicated reimplementation, and fix the auto-update.md 'marketplace' (singular) typo along the way. Guard tests updated: discovery behavior is asserted against resolveEccRoot(); the inline is asserted to delegate and to contain no Windows-fragile constructs. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(resolve-ecc-root): restore full env-unset discovery in inline resolver Address Greptile review on #2410: when CLAUDE_PLUGIN_ROOT is unset the delegating inline could only load the resolver module from ~/.claude, returning ~/.claude without ever reaching the plugin/cache search. Restore the old inline's discovery breadth (exact plugin roots + versioned cache) Windows-safely (no spread, nested arrays, or escaped quotes), then delegate the authoritative decision to resolveEccRoot(). Add regression tests for plugin-subdir and versioned-cache bootstrap with env unset. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: docs/COMMAND-REGISTRY.json check fails on fresh Windows clone (missing .gitattributes) (#2437) * fix: add .gitattributes to force LF line endings for text files npm run command-registry:check (part of npm test) fails on a fresh clone on Windows with the common core.autocrlf=true setting: git checks out docs/COMMAND-REGISTRY.json with CRLF, but generate-command-registry.js always writes LF, so the strict string comparison in checkRegistry() never matches. Forcing LF via .gitattributes makes checkouts consistent across platforms regardless of a contributor's local autocrlf setting. * fix: normalize CRLF line endings to LF per .gitattributes pyproject.toml, src/llm/__init__.py, src/llm/prompt/builder.py, src/llm/providers/claude.py, and tests/test_builder.py had CRLF line endings committed to the repo, inconsistent with the rest of the codebase. Renormalized via 'git add --renormalize .' now that .gitattributes enforces eol=lf. --------- Co-authored-by: Affaan Mustafa <me@affaanmustafa.com> * chore(catalog): sync command counts (92->93) + register orch-review in agent.yaml surface --------- Co-authored-by: devin-ai-integration[bot] <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Boube <109886533+Cb2i@users.noreply.github.com> Co-authored-by: Affaan Mustafa <me@affaanmustafa.com> |
||
|
|
1a747097f2 |
fix: docs/COMMAND-REGISTRY.json check fails on fresh Windows clone (missing .gitattributes) (#2437)
* fix: add .gitattributes to force LF line endings for text files npm run command-registry:check (part of npm test) fails on a fresh clone on Windows with the common core.autocrlf=true setting: git checks out docs/COMMAND-REGISTRY.json with CRLF, but generate-command-registry.js always writes LF, so the strict string comparison in checkRegistry() never matches. Forcing LF via .gitattributes makes checkouts consistent across platforms regardless of a contributor's local autocrlf setting. * fix: normalize CRLF line endings to LF per .gitattributes pyproject.toml, src/llm/__init__.py, src/llm/prompt/builder.py, src/llm/providers/claude.py, and tests/test_builder.py had CRLF line endings committed to the repo, inconsistent with the rest of the codebase. Renormalized via 'git add --renormalize .' now that .gitattributes enforces eol=lf. --------- Co-authored-by: Affaan Mustafa <me@affaanmustafa.com> |
||
|
|
3af4676e99 |
refactor: consolidate duplicated hook-root resolver into shared resolveEccRoot() (#2368) (#2410)
* fix(ci): resync lockfiles with package.json (eslint 10) + migrate yarn.lock to Yarn 4 format package.json requires eslint@^10.6.0 but the committed locks pinned 9.39.2, so npm ci aborted and Yarn 4 hardened mode rejected the stale v1-classic yarn.lock (YN0028). Regenerate package-lock.json and rewrite yarn.lock in Yarn 4 (berry) format so npm ci and immutable yarn installs both pass. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): require clean probe exit for Windows shell/bash detection; add pyyaml dev dep Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * refactor: consolidate duplicated hook-root resolver into shared resolveEccRoot() (#2368) The inline node -e resolver blob was duplicated ~60x across hooks.json, command docs, and translations. Each copy inlined the full ~700-char plugin-root search using a spread over nested array literals (p.join(d,'plugins',...s) over [['ecc'],...]), which breaks Windows hook execution due to shell quoting (#2368). Collapse every copy to a 250-char locator that loads the committed resolve-ecc-root module and delegates to resolveEccRoot() — no spread, no nested array literals, no escaped double quotes. The real search logic now lives in one tested module. Also route session-start-bootstrap.js through resolveEccRoot() instead of its own duplicated reimplementation, and fix the auto-update.md 'marketplace' (singular) typo along the way. Guard tests updated: discovery behavior is asserted against resolveEccRoot(); the inline is asserted to delegate and to contain no Windows-fragile constructs. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(resolve-ecc-root): restore full env-unset discovery in inline resolver Address Greptile review on #2410: when CLAUDE_PLUGIN_ROOT is unset the delegating inline could only load the resolver module from ~/.claude, returning ~/.claude without ever reaching the plugin/cache search. Restore the old inline's discovery breadth (exact plugin roots + versioned cache) Windows-safely (no spread, nested arrays, or escaped quotes), then delegate the authoritative decision to resolveEccRoot(). Add regression tests for plugin-subdir and versioned-cache bootstrap with env unset. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
6fac227f7a |
fix(plan-orchestrate): detect ecc@ecc marketplace + emit ecc: agent prefix (#2316) (#2409)
* fix(plan-orchestrate): detect ecc@ecc marketplace + emit ecc: agent prefix (#2316) Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): resync lockfiles with package.json (eslint 10) + migrate yarn.lock to Yarn 4 format package.json requires eslint@^10.6.0 but the committed locks pinned 9.39.2, so npm ci aborted and Yarn 4 hardened mode rejected the stale v1-classic yarn.lock (YN0028). Regenerate package-lock.json and rewrite yarn.lock in Yarn 4 (berry) format so npm ci and immutable yarn installs both pass. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): require clean probe exit for Windows shell/bash detection; add pyyaml dev dep Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: affaan <affaan@itomarkets.com> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> |
||
|
|
81af407619 |
chore(catalog): sync manifests + fix skill emoji (wave 2) (#2395)
* chore(catalog): sync manifests after skill batch (#2275 #2377 #2378 #2381) Update skill counts (273 -> 277) across catalog docs after the verified skill batch. * fix(skills): replace emoji with ASCII in growth-log + loop-design-check check-unicode-safety (pre-push gate) bans emoji in SKILL.md; the merged #2377 and #2381 slipped through run-all.js. Swap U+274C/U+2705 for 'Avoid:'/'Bad:'/'Good:'. |
||
|
|
0bd2b2cdfb | feat: add loop-design-check skill (design + review goal-oriented agent loops) (#2381) | ||
|
|
51bced9a1f |
Stop hook: verify thinking quality at session end — task completeness, assumptions, stale logs, disk space (delivery-gate) (#2378)
* Restore delivery-gate: Stop hook with learning capture enforcement (auto-closed by fork sync, now on clean branch)
* Fix bot findings: log level→INFO (DISK_REMIND dead code), count_edits full transcript (not truncated), memory-dir-absent warning (not silent pass), SKILL.md description accuracy
* Fix CodeRabbit feedback: treat missing memory-dir as all-stale on complex tasks (fail-close instead of fail-open)
* Trigger bot re-review (no logic changes)
* Fix: handle both stdin formats — raw transcript AND JSON with transcript_path (Greptile feedback)
* Add debug log for memory-dir lookup path
* Fix path encoding: replace colon with dash (not strip), matching Claude Code actual encoding on Windows
* Fix SKILL.md: update How It Works for JSON+transcript_path, add English translation to CLAUDE.md block (Greptile feedback)
* Fix: memory-dir absent → warn but don't block (prevents deadlock for new users per Greptile feedback)
* fix: restore daltino-approved voice (thinking quality/收尾铁律) with technical patches
Reverts 'session hygiene' rebranding. Preserves original approved framing
while keeping technical improvements:
- JSON transcript_path parsing documentation
- filesystem mtime staleness check
- 'skip tests for now' rationalization pattern
- disk critically low explicit block condition
* fix: remove stdout JSON echo — Stop hooks write feedback to stderr, not stdout
Previously sys.stdout.write(raw) echoed the raw hook JSON payload to stdout,
which Claude Code displays as the hook's response message. When the hook
blocked (exit 2), Claude saw {"transcript_path":"...","session_id":"..."}
instead of the actual blocking reason from stderr.
This made the gate functionally silent from Claude's perspective — it could
not guide Claude to the corrective action (update growth-log / free disk).
Fix per Greptile feedback: stop echo, let stderr messages reach Claude.
* fix: remove duplicate disk-critical log line
* docs(delivery-gate): v1.1.0 — accurate scope (deterministic checks, not reasoning), warning vs block table, CI/CD analogy, limitations section, self-audit pairing
* fix(delivery-gate): expand rationalization regex coverage (R3/R4) — match "we can fix" and "integration tests" variants
* chore: bump version to 1.1.1 to re-trigger CI checks
|
||
|
|
b5806b3d1c |
Add growth-log skill: methodology for effective learning capture (#2377)
* Add growth-log skill: methodology for writing effective, transferable growth log entries * Add metadata.origin: ECC frontmatter per repo convention (Greptile feedback) * Re-sign: apply GPG-verified commit to growth-log branch (rebase artifact, content unchanged) * docs(growth-log): v1.1.0 — remove personal library structure, generic storage, delivery-gate optional companion |