Commit Graph
2371 Commits
Author SHA1 Message Date
ae303fb6c1 fix(plan-canvas): deliver browser chat to the agent every time (#2739)
Feedback sent from the canvas only reached an agent through a live
/api/await long poll. When a turn ended with no await parked,
queueFeedback wrote the message to sessions.json and nothing ever
consumed it, so sending appeared to do nothing at all. The presence pill
made it worse: workingKeys had no expiry and the feedback handler never
broadcast presence, so it froze on "agent working" while nobody was
listening.

Delivery:
- Add the stop:plan-canvas-pending hook. It drains undelivered feedback
  and blocks the Stop, handing the messages to the agent, so a canvas
  message lands even when no await is running. Scoped to sessions under
  cwd so parallel agents cannot swallow each other's feedback; set
  ECC_PLAN_CANVAS_STOP_SCOPE=all to widen. Honors stop_hook_active and
  fails open on every error path.
- run-with-flags.js did not await a hook's run(), so any async hook
  silently degraded to pass-through. Fixed; plan-canvas-pending is the
  only async hook today.

Presence and indicators:
- Presence is now ended/typing/thinking/listening/queued/waiting.
  thinking and typing self-expire (90s/30s) and a 5s sweep pushes the
  decay to an idle browser, so the pill can no longer stick.
- Broadcast presence when feedback is queued, and clear the activity
  state when an agent reply lands.
- Add POST /api/session/:key/typing so agents can drive the indicator.
- Chat shows an animated dots bubble for thinking and typing, plus an
  explicit note when a message is queued with nobody listening.
  Respects prefers-reduced-motion.
- Send status reports what actually happened instead of always claiming
  the agent will pick it up.

CLI and skill:
- Add `ecc-plan-canvas pending` and `typing <file> --state ...`.
- SKILL.md documents background await as the primary pattern and makes
  replying in the canvas mandatory.

Tests: 6 new server cases covering queued presence, the typing endpoint,
state expiry and the sweep, plus a new hook suite covering delivery,
drain-once, stop_hook_active, cwd scoping and fail-open.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-09 18:15:25 -04:00
Affaan MustafaandGitHub 649def769b fix: complete Discord delivery receipts reliably (#2738)
* test: reproduce Actions receipt completion mismatch

* fix: complete Discord receipts with Actions identity
2026-08-09 16:44:18 -04:00
Affaan MustafaandGitHub cdbb25bf9d fix: deliver announcements through a scoped Discord webhook (#2737)
* test: reproduce Discord webhook announcement gap

* fix: deliver ECC announcements through channel webhook

* test: cover webhook replay and least privilege

* fix: make webhook delivery durable and least privilege

* test: cover trusted receipts and cross-workflow races

* fix: serialize and authenticate announcement receipts
2026-08-09 16:41:27 -04:00
Affaan MustafaandGitHub 2d46e80e09 fix: deliver ECC announcements to Discord (#2732) 2026-08-09 06:37:04 -04:00
Kumar PrateekandGitHub 51a6950bde fix(memory-vault): compare dev only when both stats report one (#2637)
ecc memory writes and --body-file reads fail on Windows. sameFileIdentity()
compares the dev field of a path-based stat against a handle-based fstat, and
libuv 1.49.0 through 1.50.x resolve path-based stat() and lstat() on Windows
through GetFileInformationByName, which leaves the volume serial unset while
fstat() reports it. The comparison never matches, so the TOCTOU guard rejects
every operation.

Keep the inode strict and compare dev only when both sides report one. POSIX
always reports a non-zero dev, so the original strict behaviour is preserved
there.

Request the guard's stats as BigInt. On the affected libuv versions dev is 0,
which leaves the inode as the only identity signal, and Windows file IDs run
past Number.MAX_SAFE_INTEGER where two distinct files can collapse to the same
number-valued inode.

Fixes #2626
2026-08-08 17:06:18 -04:00
59a99d669f fix(ci): restore green main for the Itô skill test suite (#2720)
main has been red since the Itô skill series landed. Two independent
problems, both in test files rather than shipped behavior:

- tests/ci/ito-inference-skill.test.js asserted a stale copy of the
  capability:ito-compute description. #2706 added device revocation to
  the lifecycle and updated manifests/install-components.json, but this
  expectation was not updated with it. The manifest is the shipped
  artifact, so the test expectation is what was wrong.
- three ito test files matched YAML frontmatter indentation with two
  literal spaces inside a regex literal, which trips no-regex-spaces.
  Replaced with an explicit ` {2}` quantifier, which matches identically.

The basket-compare occurrence was not visible in CI: npm run lint is
`eslint . && markdownlint ...`, so ESLint reported only the first file
and stopped. Fixing only what CI printed would have left main red on the
next run. The markdownlint half of that chain had therefore never
executed; it passes.

Verified on this branch: full suite 3707/3707, repo-wide ESLint clean,
and markdownlint clean under the exact CI glob.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-07 19:47:55 -04:00
Affaan MustafaandGitHub d451f5100a fix(skill): harden ito basket comparison lifecycle (#2712) 2026-08-07 15:08:52 -04:00
Affaan MustafaandGitHub a73deb211e docs: formalize Itô inference serving contract (#2708) 2026-08-07 14:55:22 -04:00
Affaan MustafaandGitHub b844a9edb8 Harden Itô market intelligence skill (#2711) 2026-08-07 14:54:37 -04:00
Affaan MustafaandGitHub d13a0706b9 fix ito trade planner safety contract (#2709) 2026-08-07 14:53:41 -04:00
Affaan MustafaandGitHub 9de131420b fix(ito-compute): complete device auth lifecycle (#2706) 2026-08-07 14:53:13 -04:00
Affaan MustafaandGitHub 4162cc1fc2 fix Data Atlas skill live read contract (#2707) 2026-08-07 14:51:06 -04:00
Affaan MustafaandGitHub f16a6ff2a6 fix: ship new Itô skills through install manifests (#2704)
* fix: ship new Ito skills through install manifests

* ci: audit shipped dependencies separately from tooling

* test(release): pass previous version to heading helper
2026-08-07 14:14:21 -04:00
fd27a0ec9f Add ito-inference and ito-training skills (delegate to canonical Itô backend) (#2700)
Two ECC skills chaining off an ito-compute booking, per the Full-Stack Harness
Engineering Plan (2026-08-06):

- ito-inference: serve a model on booked GPUs via ecc ito serve (Layer 0.2).
- ito-training: run a staged, eval-gated training pipeline via ecc ito train
  (Layer 0.3).

Both match the existing ito-compute skill: origin ECC, delegate to the canonical
CLI/backend, implement no parallel serving/training stack, chain off a completed
booking, and never book, reserve, or spend. They report the missing capability
while the desk serve-on-booking / training-run backends are scaffolds.

Co-authored-by: Affaan Mustafa <affaan@itomarkets.com>
2026-08-07 12:46:06 -04:00
9aac8585ab fix(skills): default GAN harness models to sonnet (#2442) (#2695)
Completes the model re-tiering from #2442: the gan-planner, gan-generator,
and gan-evaluator agents were already re-pinned to sonnet, but the
gan-style-harness script and docs still defaulted GAN_PLANNER_MODEL,
GAN_GENERATOR_MODEL, and GAN_EVALUATOR_MODEL to opus. Align the script
defaults, skill docs (en/ja/zh), and example commands with the landed
agent tiers. Opus remains available via the existing env overrides.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 17:42:22 -04:00
52a3babd5d feat(skills): add secure terminal opener (#2650)
* test(skills): define terminal opener contract

* feat(skills): add secure terminal opener

* fix(skills): report detached terminal errors

* docs: sync terminal opener skill count

* fix(security): require explicit terminal launch

* test(skills): cover terminal opener review findings

* fix(skills): bound terminal launch waits

* test(skills): cover terminal fallback output

* fix(skills): report terminal mux fallback

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 17:24:34 -04:00
b3c679684b test(release): add executable missing-heading regression (#2685)
release.test.js only greps release.sh for one of the five
update_latest_release_heading call sites, and plugin-manifest.test.js
only checks the headings committed today. Neither executes the rewrite,
so a helper that silently no-ops on a missing heading would ship green.

Extract the embedded node program from release.sh and run it against
fixtures to pin the fail-closed contract: bump stable and prerelease
headings, leave the rest of the file untouched, and exit non-zero
without writing when no heading matches. Also pin all five call sites so
the docs/zh-CN/README.md regression cannot recur.

Runs standalone via node tests/scripts/release-heading.test.js.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-06 16:53:59 -04:00
haelyraandGitHub d791457aca feat(docker): add hardened CLI test harness (#2625)
* feat(install): add hardened Docker test harness

* feat(docker): complete isolated CLI session lifecycle

* fix(docker): exercise packed public CLI offline

* fix(docker): close hardened harness review gaps

* test(docker): bound harness subprocesses
2026-08-06 16:52:39 -04:00
28e53a0bc1 feat(install): add guided multi-harness installer (#2649)
* feat(install): add guided Claude plugin setup

* fix: support Claude command shims on Windows

* feat: support safe Claude plugin scope migration

* fix(install): preserve interactive setup terminal

* fix(install): auto-migrate setup scope changes

* feat(install): add guided multi-harness installer

* fix(install): sync Yarn binary metadata

* fix(install): handle wizard EOF on Node 18

* ci: allow installer matrix tests to finish

* test(install): allow slower PowerShell delegation

* fix(install): harden guided provider reconciliation

* test(install): harden packaged and local compatibility

* chore: prepare guided installer release 2.2.0

* fix(install): report refreshed Codex marketplace state

* fix(install): verify managed content provenance

* test(install): allow empty Yarn smoke fixture

* test(install): invoke Windows package shims safely

* fix(install): close cross-platform release gaps

* fix(install): require trusted GitHub origins

* fix(install): preserve hook profile precedence

* refactor(install): centralize trusted GitHub origins

* ci: retrigger workflow run after merge of main

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-08-06 15:39:49 -04:00
Affaan MustafaandGitHub 623f2c020f Add bounded harness evaluation and rollback loop (#2686)
* feat(ecc2): add bounded harness evaluation loop

* fix(ecc2): preserve harness evidence and legacy IDs
2026-08-05 18:17:10 -04:00
haelyraandGitHub f1fec0e539 feat: add retention feedback loop and honest support matrix (#2681)
* feat: add retention feedback loop

* test: retire obsolete README parity row guard

* fix: harden public feedback guidance

* fix: let feedback CLI output flush

* test: keep feedback help coverage focused
2026-08-04 21:42:25 -04:00
7a5757e6c0 fix(hooks): never format installed plugin and marketplace clones (#2667)
The Stop hook formats every JS/TS file edited during a response, grouped by the project root each file happens to sit in. That includes trees under .claude/plugins, which are third-party checkouts we only read.

Formatting them writes to code the user does not own. It also does real damage when a repo's committed code has drifted from its own formatter config: the rewrite is not a no-op but a wholesale reformat, so an unrelated bugfix ends up carrying hundreds of untouched lines. I hit this contributing to this repo — a 162-line fix arrived as a 478-line diff, most of it reformatted code the change never went near.

Skips both the user-level install root and a project-local one, mirroring the lookup in scripts/harness-audit.js. Paths are resolved before the prefix comparison, and a sibling such as .claude/plugins-backup does not match. The user own .claude config outside plugins is still formatted.

Adds 7 tests for the predicate, plus an end-to-end check that a clone file listed in the accumulator is left byte-identical. Suite 16 to 23.

Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-08-04 17:14:37 -04:00
a8c6da485d fix(hooks): catch the bypass short flag anywhere in a cluster (#2668)
isCommitNoVerifyShortFlag anchored on the first character, so it only recognised the flag when it led the cluster. Git clusters short options, which means git commit -an is -a plus the bypass flag and skips the hooks. -sn and -vn slip through the same way, while -na and -nm are caught — the difference is position, not intent.

Scanning now walks the cluster and stops at a value-taking option, since that option swallows the rest as its inline value. The n in -mn stays message text, and the existing -tn case keeps working.

Adds 4 tests: the three clustered forms that were escaping, plus -mn to pin the inline-value boundary. Verified the three fail against current main. Suite 25 to 29.

Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-08-04 17:08:56 -04:00
f235549cb8 fix(install): exclude ECC skills from antigravity install target (#2680)
* fix: exclude ECC skills from antigravity install target

* test(install): cover antigravity skills exclusion

Two tests encoded the collision the parent commit fixes.

install-manifests used skills/example as its example of a supported
antigravity path; it now asserts skills are filtered and uses
commands/example for the positive case, so the test still proves
supported paths survive filtering.

install-apply asserted .agent/skills/tdd-workflow/SKILL.md exists. That
directory is antigravity's agent directory and already receives ECC
agents/, so the assertion was pinning ECC skills and ECC agents to the
same destination. Inverted, with the reason recorded inline.

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

---------

Co-authored-by: Calum Reeves <reevesc88@users.noreply.github.com>
Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
2026-08-04 16:57:27 -04:00
8a97868b5b fix(continuous-learning): /evolve never produces skill or agent candidates (#2664)
* fix(continuous-learning): cluster instincts by keyword overlap in /evolve

`cmd_evolve` grouped instincts by exact string equality of the whole
normalized trigger sentence. Triggers are free-form sentences, so every
instinct landed in its own bucket and `skill_candidates` was always empty.
`agent_candidates` is derived from `skill_candidates`, so agents never
generated either — `/evolve --generate` could only ever emit commands.

Measured on a 42-instinct project: 42 instincts produced 42 unique cluster
keys, largest cluster size 1.

Group on keyword overlap instead. Jaccard is the wrong metric here — trigger
keyword sets average ~7 words, so even clearly related pairs top out around
0.33 — so this uses the overlap coefficient (shared / smaller set) at 0.5,
plus a floor of 2 shared keywords so one incidental word cannot pull
unrelated instincts together. The same 42 instincts now yield 4 clusters.

Also unify the command/agent slug used by the preview and the writer. The
preview called `.replace('a ', '')`, which strips "a " anywhere in the
string, mangling "extracting data from Reddit" into
`/extracting-datfrom-R` while `--generate` wrote `extracting-data-from.md`.
Both paths now share `_evolved_command_name()` / `_evolved_agent_name()`.

Adds tests/scripts/instinct-cli-evolve.test.js, which fails on the previous
implementation (0 clusters instead of 1; preview name `extracting-datfrom-R`)
and covers the negative cases so unrelated triggers still stay apart.

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

* docs(continuous-learning): correct clustering metric name in docstring

The docstring said "Jaccard" while the implementation uses the overlap
coefficient, which is the point of the change.

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

* fix(continuous-learning): generate every evolve candidate and cut slugs on word boundaries

_generate_evolved() wrote only skill_candidates[:5], workflow_instincts[:5]
and agent_candidates[:3]. On a project with 36 command candidates that meant
5 files and no warning, so the output read as complete while 86% of the
candidates were dropped.

Generation is now unbounded by default and takes a --limit N flag for callers
that want a cap. A cap that truncates says so:

  Note: writing 3 of 36 command candidates (--limit 3); 33 skipped.

The analysis preview keeps showing five per kind but now names the remainder
("... and 31 more command candidates not shown") instead of presenting a
sample as the whole set.

Slugs were also cut with a hard slice, which split words mid-token and
produced /investigating-comple, /learning-about-compl and
/researching-mechanis. _truncate_slug() retreats to the last separator that
fits, and keeps the full head when the cut already lands on one, so
"analyzing large text files" stays /analyzing-large-text rather than losing
a word. A first word longer than the limit still falls back to a hard cut
because no boundary is available.

Shorter slugs collide more easily, and a collision used to mean one file
silently overwriting another. _assign_unique_slugs() suffixes duplicates
(-2, -3) and is called by both the preview and the writer over the same
ordered list, so advertised names and written names cannot drift apart.

Skill directory naming moved to _evolved_skill_name(); it previously used its
own inline slug expression, so it was the one truncation the shared helper
did not cover.

Adds tests/scripts/instinct-cli-evolve-generate.test.js: 7 cases covering
word-boundary cuts, the separator-aligned cut, unbounded generation, --limit
reporting, collision dedup, preview remainder and preview/writer agreement.
Six of the seven fail against the previous implementation.

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

---------

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-08-04 16:57:24 -04:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>haelyra
b2bc8dcd14 chore(deps): bump tar in the npm-security group across 1 directory (#2671)
Bumps the npm-security group with 1 update in the / directory: [tar](https://github.com/isaacs/node-tar).


Updates `tar` from 7.5.19 to 7.5.22
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v7.5.19...v7.5.22)

---
updated-dependencies:
- dependency-name: tar
  dependency-version: 7.5.22
  dependency-type: indirect
  dependency-group: npm-security
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-08-04 16:57:20 -04:00
Alexis D.andGitHub 2665d48ae6 fix(deps): bump fast-uri to 3.1.5 and brace-expansion to 5.0.9 (#2672)
npm audit --audit-level=high fails CI on two new high-severity
advisories:

- fast-uri GHSA-7p8r-x3mc-p8w7 (host confusion via backslash
  authority introducer) — pinned at 3.1.4 via overrides/resolutions;
  bump pins to the patched 3.1.5 (still within ajv's ^3.0.1 range)
- brace-expansion GHSA-rgw5-rvv9-x895 (DoS via unbounded intermediate
  arrays) — in-range lockfile bump 5.0.8 -> 5.0.9 under minimatch

npm audit now reports 0 vulnerabilities. yarn.lock regenerated with
Yarn 4.9.2 to keep resolutions in sync.
2026-08-04 12:36:54 -04:00
Alexis D.andGitHub ff15079b9f test(lib): extract shared mini test runner for coordination tests (#2663)
Address CodeRabbit review on #2311: dedupe the local test(name, fn)
harness and route all reporter output through a shared helper
(tests/lib/helpers/mini-test-runner.js) instead of direct console.log.
2026-08-04 00:29:31 -04:00
Karim FarahatandGitHub 203aac7710 fix(commands): probe for auto-update.js in auto-update ECC_ROOT resolver (#2462)
The auto-update command's inline ECC_ROOT resolver delegates to
resolveEccRoot() with the default probe (scripts/lib/utils.js). A
hooks-runtime-only install copies scripts/lib/ into ~/.claude, so the
partial install satisfies the probe and shadows the full plugin root
under ~/.claude/plugins/marketplaces/. The command then fails with
MODULE_NOT_FOUND because ~/.claude/scripts/auto-update.js does not
exist.

Pass {probe: scripts/auto-update.js} so the resolver only accepts a
root that actually contains the script the command runs. Applied to
the command doc and its ja-JP/zh-CN translations, with regression
tests for both the resolver behavior and the embedded snippets.
2026-08-04 00:28:59 -04:00
7b76082b13 fix(mcp): accept reserved _meta field in tools/call params (#2670)
* fix(mcp): accept reserved _meta field in tools/call params

The memory MCP server rejected any tools/call whose params contained a key
other than name/arguments, returning -32602 "Unknown or missing memory tool."

MCP clients (e.g. Claude Code) attach the spec-reserved `_meta` field
(such as progressToken) to request params, so every tool call from a
compliant client failed and the entire memory MCP surface was unreachable —
even though initialize/tools-list and the `ecc memory` CLI kept working.

Per the MCP base protocol, `_meta` is reserved for request metadata and
must be accepted. Add it to the params key allowlist.

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

* test(mcp): validate _meta shape and cover tools/call param allowlist

Address CodeRabbit review on #2670:
- Validate params._meta when present: accept metadata objects, reject null,
  arrays, and scalar values (reuses isRecord). Keeps _meta optional and
  preserves existing name/arguments/unexpected-key rejection.
- Add regression tests: accept _meta with progressToken, reject malformed
  _meta values, and continue rejecting unrelated top-level params.

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

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-08-04 00:28:09 -04:00
Bob.HouandGitHub ab373716e7 fix: add claude-opus-5 to KNOWN_MODEL_WINDOW_TOKENS (#2609)
* fix: add claude-opus-5 to KNOWN_MODEL_WINDOW_TOKENS

claude-opus-5 has a 1M context window (verified: 250k tokens at 25%
usage = ~1M), but was missing from the model table. This caused
resolveContextWindowTokens() to fall back to the 200k default when
tokens < 200k, incorrectly triggering compact warnings in the first
20% of a 1M session.

Same failure class as #2290 (Opus 4.x) and #2461 (fable-5/mythos-5).
The env override (ECC_CONTEXT_WINDOW_TOKENS) remains the escape hatch
for unlisted models.

Refs: #2290, #2461, #2468

* test: add regression test for claude-opus-5 context window

Verifies resolveContextWindowTokens returns LARGE_CONTEXT_WINDOW_TOKENS
for claude-opus-5 at 50k tokens, matching the behavior of fable-5 and
mythos-5 in the known-model table.
2026-08-04 00:27:33 -04:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
26f633462b chore(deps): bump toml in /ecc2 in the cargo-minor-and-patch group (#2661)
Bumps the cargo-minor-and-patch group in /ecc2 with 1 update: [toml](https://github.com/toml-rs/toml).


Updates `toml` from 1.1.3+spec-1.1.0 to 1.1.4+spec-1.1.0
- [Commits](https://github.com/toml-rs/toml/compare/toml-v1.1.3...toml-v1.1.4)

---
updated-dependencies:
- dependency-name: toml
  dependency-version: 1.1.4+spec-1.1.0
  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>
2026-08-04 00:26:10 -04:00
dependabot[bot]andGitHub 0c1d7be9a7 chore(deps-dev): require pytest-asyncio 1.4.0 (#2327)
Keep pytest-asyncio compatible with ECC's pytest 9 development floor.
2026-08-02 15:17:19 -04:00
haelyraandGitHub 85c7822c4a fix(commands): generate discoverable skills from learning workflows (#2653)
Carry #2246 forward on current main with native SKILL.md discovery, guarded writes, portable metadata, and fail-closed validation.
2026-08-02 14:39:29 -04:00
haelyraandGitHub f782bd616e fix(aura): reject history-free agents by default (#2652)
* fix(aura): reject history-free agents by default

* fix(aura): keep invalid responses fail-closed
2026-08-02 13:42:16 -04:00
haelyraandGitHub e4e4163101 fix(docs): restore main CI (#2623) 2026-07-29 14:11:01 -04:00
591ab5cbd3 fix(opencode): don't crash the whole session when plugins/lib is missing (#2538)
* fix(opencode): don't crash the whole session when plugins/lib is missing (#2530)

* fix: address review feedback (trailing newlines, symptom wording)

* fix(opencode): also lazy-load the store in ecc-hooks.ts plugin entrypoint

* test(opencode): add regression coverage for missing/present plugins/lib in ecc-hooks

* fix(opencode): guard diagnostic log() against unhandled rejection; tighten test assertion

* fix(opencode): only publish store after init succeeds; scrub loader errors from warning; catch sync log throws

* fix(opencode): scrub raw loader error from changed-files tool; add tool-level regression tests

* fix(ci): make OpenCode checks cross-platform

---------

Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-07-28 21:37:41 -04:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
afa34d1aca chore(deps): bump the cargo-minor-and-patch group (#2593)
Bumps the cargo-minor-and-patch group in /ecc2 with 4 updates: [tokio](https://github.com/tokio-rs/tokio), [serde_json](https://github.com/serde-rs/json), [clap](https://github.com/clap-rs/clap) and [libc](https://github.com/rust-lang/libc).


Updates `tokio` from 1.53.0 to 1.53.1
- [Release notes](https://github.com/tokio-rs/tokio/releases)
- [Commits](https://github.com/tokio-rs/tokio/compare/tokio-1.53.0...tokio-1.53.1)

Updates `serde_json` from 1.0.150 to 1.0.151
- [Release notes](https://github.com/serde-rs/json/releases)
- [Commits](https://github.com/serde-rs/json/compare/v1.0.150...v1.0.151)

Updates `clap` from 4.6.2 to 4.6.4
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.6.2...clap_complete-v4.6.4)

Updates `libc` from 0.2.186 to 0.2.189
- [Release notes](https://github.com/rust-lang/libc/releases)
- [Changelog](https://github.com/rust-lang/libc/blob/0.2.189/CHANGELOG.md)
- [Commits](https://github.com/rust-lang/libc/compare/0.2.186...0.2.189)

---
updated-dependencies:
- dependency-name: tokio
  dependency-version: 1.53.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: serde_json
  dependency-version: 1.0.151
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: clap
  dependency-version: 4.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: cargo-minor-and-patch
- dependency-name: libc
  dependency-version: 0.2.189
  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>
2026-07-28 21:33:18 -04:00
837acaf20b fix(hooks,lib): fix hook detection and parsing edge cases (#2405)
* fix(hooks,lib): fix hook detection and parsing edge cases

- auto-tmux-dev: dev\b -> dev(?![\w-]) so one-shot dev-build/dev-docs scripts
  are not detached into tmux; align command shapes (yarn run dev, bun dev) with
  pre-bash-dev-server-block.js DEV_PATTERN.
- pre-bash-commit-quality: skip obvious non-secret placeholders (env refs,
  ${...}, <...>, whitelisted tokens) in the api-key rule without suppressing
  real high-entropy secrets; make -m message extraction quote- and
  escaped-quote-aware so `-m "fix: \"x\""` / apostrophes are not truncated.
- pre-compact: annotate the CURRENT worktree's session (match **Worktree:** /
  legacy **Project:**) instead of the newest *-session.tmp across all projects,
  layered onto the LLM-summary flow from #2388; a present-but-blank Worktree
  header is treated as non-legacy (no foreign project fallback).
- shell-substitution: stop double-appending a trailing backslash in an
  unterminated backtick span.
- utils readStdinJson: on overflow, settle and resolve {} immediately (clear
  timer + listeners) instead of waiting for end/timeout and parsing a partial
  prefix; surface the overflow on stderr.

Regression tests added/extended (new tests/hooks/pre-compact.test.js).

Addresses review feedback on #2405. The earlier block-no-verify change was
dropped: its message-value skip on merge/cherry-pick/am/rebase would let
`git rebase -m --no-verify` bypass the hook (rebase's -m is the boolean
--merge), a false-negative worse than the contrived false-positive it fixed.

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

* fix(ci): align hook fixtures and drain oversized stdin

---------

Co-authored-by: djpjronline-netizen <276112803+djpjronline-netizen@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-07-28 21:32:42 -04:00
6be87a56ae fix: clean promoted instinct sources (#2587)
* fix: clean promoted instinct sources

* test(instincts): normalize retained-content line endings

---------

Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-07-28 21:31:12 -04:00
Affaan MustafaandClaude 4e973d3eaf docs: drop badges whose api.ecc.tools endpoints do not exist yet
claude-plugin, codex-plugin, and clones return 404 and would render as
broken shields on the repo homepage. Re-add when the endpoints ship.

Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0149VwNuynam6rvEfcMmiHHa
2026-07-27 16:45:17 -04:00
Affaan MustafaandClaude 19b05476fd docs: blend 2.1 README restructure with retained sections per Affaan x Haley thread
Co-Authored-By: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01H1b2jD5gWaPTnHWQ51V7oj
2026-07-27 16:41:57 -04:00
Affaan MustafaandGitHub b40f11919a fix old project name delimiter 2026-07-27 13:00:46 -07:00
haelyraandGitHub 86c786e8bb Update section title from 'Why It Feels Different' to 'Why Choose ECC?' 2026-07-27 15:25:33 -04:00
haelyra b6f461a363 docs: add README install jump link 2026-07-27 15:23:38 -04:00
haelyraandGitHub 55c343571b Revise TDD section title and format
Updated section title for clarity and corrected formatting.
2026-07-27 15:20:07 -04:00
haelyraandGitHub 41441427b9 docs: refresh README for ECC 2.1 (#2579)
Refresh the main README for ECC 2.1, including the Plan Canvas demo, install paths, harness guidance, security, sponsors, and community sections.
2026-07-27 15:17:36 -04:00
536221cf7a fix(hooks): dedupe transcript usage by message.id in cost-tracker (~2.5-3x inflation) (#2483)
Claude Code writes one transcript JSONL line per content block, so a
single API response (one message.id) spans multiple assistant lines that
each repeat the same message.usage. sumUsageFromTranscript summed every
line, inflating token totals and estimated_cost_usd roughly 2.5-3x.

Verified on a real session: 704 assistant lines but only 286 unique
message.ids (2.46 lines/response on average); line-summing reported
$866.52 while the deduped total is $332.62. Usage payloads are identical
across lines of the same id (0/286 varied), so counting once per id is
equivalent to taking the last line per id.

Fix: collect usage into a Map keyed by message.id (last line wins) and
sum unique entries. Lines without a message.id (older transcript shapes)
keep the previous per-line behavior via a synthetic key, so existing
tests and old transcripts are unaffected.

Adds a regression test: a response split into 3 content-block lines with
the same message.id is counted exactly once.

Note: rows already written to ~/.claude/metrics/costs.jsonl by the old
code carry inflated token counts and estimates (except rows whose cost
came from the harness-cost cache, where cost is authoritative but token
counts are still inflated). Downstream consumers may want to annotate
history; this change intentionally does not rewrite the raw log.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-27 11:14:47 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ecb45c1764 chore(deps-dev): update pyyaml requirement from >=6.0 to >=6.0.3 (#2455)
Updates the requirements on [pyyaml](https://github.com/yaml/pyyaml) to permit the latest version.
- [Release notes](https://github.com/yaml/pyyaml/releases)
- [Changelog](https://github.com/yaml/pyyaml/blob/6.0.3/CHANGES)
- [Commits](https://github.com/yaml/pyyaml/compare/6.0...6.0.3)

---
updated-dependencies:
- dependency-name: pyyaml
  dependency-version: 6.0.3
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-27 11:13:33 -07:00
dependabot[bot]GitHubdependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
ce11c63d86 chore(deps-dev): update pytest-mock requirement from >=3.12 to >=3.15.1 (#2454)
Updates the requirements on [pytest-mock](https://github.com/pytest-dev/pytest-mock) to permit the latest version.
- [Release notes](https://github.com/pytest-dev/pytest-mock/releases)
- [Changelog](https://github.com/pytest-dev/pytest-mock/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest-mock/compare/v3.12.0...v3.15.1)

---
updated-dependencies:
- dependency-name: pytest-mock
  dependency-version: 3.15.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>
2026-07-27 11:13:04 -07:00