Commit Graph

198 Commits

  • fix: CI fixes, security audit, remotion skill, lead-intelligence, npm audit (#1039)
    * fix(ci): resolve cross-platform test failures
    
    - Sanity check script (check-codex-global-state.sh) now falls back to
      grep -E when ripgrep is not available, fixing the codex-hooks sync
      test on all CI platforms. Patterns converted to POSIX ERE for
      portability.
    - Unicode safety test accepts both / and \ path separators so the
      executable-file assertion passes on Windows.
    - Gacha test sets PYTHONUTF8=1 so Python uses UTF-8 stdout encoding on
      Windows instead of cp1252, preventing UnicodeEncodeError on box-drawing
      characters.
    - Quoted-hook-path test skipped on Windows where NTFS disallows
      double-quote characters in filenames.
    
    * feat: port remotion-video-creation skill (29 rules), restore missing files
    
    New skill:
    - remotion-video-creation: 29 domain-specific Remotion rules covering 3D/Three.js,
      animations, audio, captions, charts, compositions, fonts, GIFs, Lottie,
      measuring, sequencing, tailwind, text animations, timing, transitions,
      trimming, and video embedding. Ported from personal skills.
    
    Restored:
    - autonomous-agent-harness/SKILL.md (was in commit but missing from worktree)
    - lead-intelligence/ (full directory restored from branch commit)
    
    Updated:
    - manifests/install-modules.json: added remotion-video-creation to media-generation
    - README.md + AGENTS.md: synced counts to 139 skills
    
    Catalog validates: 30 agents, 60 commands, 139 skills.
    
    * fix(security): pin MCP server versions, add dependabot, pin github-script SHA
    
    Critical:
    - Pin all npx -y MCP server packages to specific versions in .mcp.json
      to prevent supply chain attacks via version hijacking:
      - @modelcontextprotocol/server-github@2025.4.8
      - @modelcontextprotocol/server-memory@2026.1.26
      - @modelcontextprotocol/server-sequential-thinking@2025.12.18
      - @playwright/mcp@0.0.69 (was 0.0.68)
    
    Medium:
    - Add .github/dependabot.yml for weekly npm + github-actions updates
      with grouped minor/patch PRs
    - Pin actions/github-script to SHA (was @v7 tag, now pinned to commit)
    
    * feat: add social-graph-ranker skill — weighted network proximity scoring
    
    New skill: social-graph-ranker
    - Weighted social graph traversal with exponential decay across hops
    - Bridge Score: B(m) = Σ w(t) · λ^(d(m,t)-1) ranks mutuals by target proximity
    - Extended Score incorporates 2nd-order network (mutual-of-mutual connections)
    - Final ranking includes engagement bonus for responsive connections
    - Runs in parallel with lead-intelligence skill for combined warm+cold outreach
    - Supports X API + LinkedIn CSV for graph harvesting
    - Outputs tiered action list: warm intros, direct outreach, network gap analysis
    
    Added to business-content install module. Catalog validates: 30/60/140.
    
    * fix(security): npm audit fix — resolve all dependency vulnerabilities
    
    Applied npm audit fix --force to resolve:
    - minimatch ReDoS (3 vulnerabilities, HIGH)
    - smol-toml DoS (MODERATE)
    - brace-expansion memory exhaustion (MODERATE)
    - markdownlint-cli upgraded from 0.47.0 to 0.48.0
    
    npm audit now reports 0 vulnerabilities.
    
    * fix: resolve markdown lint and yarn lockfile sync
    
    - MD047: ensure single trailing newline on all remotion rule files
    - MD012: remove consecutive blank lines in lottie, measuring-dom-nodes, trimming
    - MD034: wrap bare URLs in angle brackets (tailwind, transcribe-captions)
    - yarn.lock: regenerated to sync with npm audit changes in package.json
    
    * fix: replace unicode arrows in lead-intelligence (CI unicode safety check)
  • feat(hooks): add WSL desktop notification support via PowerShell + BurntToast (#1019)
    * fix(hooks): add WSL desktop notification support via PowerShell + BurntToast
    
    Adds WSL (Windows Subsystem for Linux) desktop notification support to the
    existing desktop-notify hook. The hook now detects WSL, finds available
    PowerShell (7 or Windows PowerShell), checks for BurntToast module, and
    sends Windows toast notifications.
    
    New functions:
    - isWSL(): detects WSL environment
    - findPowerShell(): finds PowerShell 7 or Windows PowerShell on WSL
    - isBurntToastAvailable(): checks if BurntToast module is installed
    - notifyWindows(): sends Windows toast notification via BurntToast
    
    If BurntToast is not installed, logs helpful tip for installation.
    Falls back silently on non-WSL/non-macOS platforms.
    
    * docs(hooks): update desktop-notify description to include WSL
    
    Updates the hook description in hooks.json to reflect the newly
    added WSL notification support alongside macOS.
    
    * fix(hooks): capture stderr properly in notifyWindows
    
    Change stdio to ['ignore', 'pipe', 'pipe'] so stderr is captured
    and can be logged on errors. Without this, result.stderr is null
    and error logs show 'undefined' instead of the actual error.
    
    * fix(hooks): quote PowerShell path in install tip for shell safety
    
    The PowerShell path contains spaces and needs to be quoted
    when displayed as a copy-pasteable command.
    
    * fix(hooks): remove external repo URL from tip message
    
    BurntToast module is a well-known Microsoft module but per project
    policy avoiding unvetted external links in user-facing output.
    
    * fix(hooks): probe WSL interop PATH before hardcoded paths
    
    Adds 'pwsh.exe' and 'powershell.exe' as candidates to leverage
    WSL's Windows interop PATH resolution, making the hook work with
    non-default WSL mount prefixes or Windows drives.
    
    * perf(hooks): memoize isWSL detection at module load
    
    Avoids reading /proc/version twice (once in run(), once in findPowerShell())
    by computing the result once when the module loads.
    
    * perf(hooks): reduce PowerShell spawns from 3 to 1 per notification
    
    Merge findPowerShell version check and isBurntToastAvailable check
    into a single notifyWindows call. Now just tries to send directly;
    if it fails, tries next PowerShell path. Version field was unused.
    
    Net effect: up to 3 spawns reduced to 1 in the happy path.
    
    * fix(hooks): remove duplicate notifyWindows declaration
    
    There were two notifyWindows function declarations due to incomplete
    refactoring. Keeps only the version that returns true/false for the
    call site. Node.js would throw SyntaxError with 'use strict'.
    
    * fix(hooks): improve error handling and detection robustness
    
    - Increase PowerShell detection timeout from 1s to 3s to avoid false
      negatives on slower/cold WSL interop startup
    - Return error reason from notifyWindows to distinguish BurntToast
      module not found vs other PowerShell errors
    - Log actionable error details instead of always showing install tip
    
    ---------
    
    Co-authored-by: boss <boss@example.com>
  • fix: harden codex sync CI hermeticity (#1020)
    * test: isolate package-manager dependent hooks and formatter tests
    
    * fix: export codex sync env to child scripts
  • fix: audit consumer projects from cwd (#1014)
    * fix: audit consumer projects from cwd
    
    * fix: unblock unicode safety CI lint
    
    * fix: unblock shared CI regressions
    
    * test: isolate package-manager dependent hooks and formatter tests
  • fix: unblock unicode safety CI lint (#1017)
    * fix: unblock unicode safety CI lint
    
    * fix: unblock shared CI regressions
  • fix: skip pre-push checks on branch deletion
    The pre-push hook runs lint/typecheck/test/build checks on every push,
    including `git push origin --delete <branch>`. Branch deletion does not
    push any code, so verification checks are unnecessary and block the
    delete operation.
    
    Detect deletion pushes by reading stdin (local sha is all zeros for
    deletes) and exit early.
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
  • Merge pull request #926 from xingzihai/feature/pre-commit-quality-hook
    feat(hooks): add pre-commit quality check hook
  • fix(lint): prefix unused options parameter with underscore
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • refactor: address reviewer feedback
    - Add options={} parameter to run() to match run-with-flags.js contract
    - Remove case-insensitive flag from extension pre-filter for consistency
      with ADHOC_FILENAMES regex (both now case-sensitive)
    - Expand warning text to list more structured paths
    - Add test cases for uppercase extensions (TODO.MD, NOTES.TXT)
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(hooks): port doc-file-warning denylist policy to current hook runtime
    Replace the broad allowlist approach with a targeted denylist that only
    warns on known ad-hoc filenames (NOTES, TODO, SCRATCH, TEMP, DRAFT,
    BRAINSTORM, SPIKE, DEBUG, WIP) outside structured directories. This
    eliminates false positives for legitimate markdown-heavy workflows while
    still catching impulse documentation files.
    
    Closes #988
    
    Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • Merge pull request #892 from chris-yyau/fix/remove-redundant-skill-sync
    fix: remove redundant skill copy from sync-ecc-to-codex.sh
  • Merge pull request #964 from affaan-m/fix/claude-hooks-settings-merge-safe
    fix(installer): preserve existing Claude hook settings
  • Merge pull request #974 from Lidang-Jiang/fix/codex-sanity-check-persistent-instructions
    fix(codex): add persistent_instructions to baseline and relax sanity check
  • Merge pull request #971 from Lidang-Jiang/fix/codex-mcp-startup-timeout
    fix(codex): add startup_timeout_sec to MCP servers to prevent first-run timeouts
  • fix(installer): write error and help text to stderr for consistent stream output
    Extracted help text into getHelpText() and write both the error message
    and usage help to stderr via process.stderr.write(). This ensures that
    when output is redirected (e.g. 2>errors.txt), both the error and the
    guidance appear in the same stream.
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
  • fix(installer): show help text on error and document --profile full in README
    Running install.ps1/install.sh with no arguments gave a cryptic error
    with no guidance. Now the usage help is printed after the error so users
    know what arguments to pass.
    
    Also added --profile full as the recommended install option in the README
    quick-start section, which was previously undocumented.
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
  • fix(codex): align context7-mcp package specifier with config.toml
    Add @latest suffix to '@upstash/context7-mcp' in ECC_SERVERS so the
    generated merge spec matches .codex/config.toml exactly, preventing
    configDiffers from flagging false drift on --update-mcp runs.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(codex): allow leading whitespace in persistent_instructions regex
    The rg pattern anchored at line start (^persistent_instructions) would
    miss indented TOML entries. Use ^\s* prefix to match both top-level and
    indented configurations.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(scripts): add os.homedir() fallback for Windows compatibility
    On Windows (native cmd/PowerShell), process.env.HOME is undefined.
    Seven CLI entry points and two library files pass process.env.HOME
    directly as homeDir without a cross-platform fallback, causing all
    path resolutions to silently fail (resolving to "undefined/.claude/...").
    
    Node.js os.homedir() correctly handles all platforms (HOME on Unix,
    USERPROFILE on Windows, OS-level fallback). The project already uses
    this pattern in scripts/lib/state-store/index.js and has a getHomeDir()
    utility in scripts/lib/utils.js, but it was not applied consistently.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(codex): add persistent_instructions to baseline and relax sanity check
    The global sanity check (check-codex-global-state.sh) hard-fails when
    persistent_instructions is missing from ~/.codex/config.toml, but neither
    the baseline .codex/config.toml nor the sync script ever define this field.
    This causes a clean install to report a failing sanity check even though the
    sync otherwise succeeds (#967).
    
    - Add persistent_instructions to the baseline .codex/config.toml so that
      users who cp the config get a working default.
    - Downgrade the sanity check from fail to warn, since persistent_instructions
      is additive and optional — users who rely solely on AGENTS.md should not be
      blocked.
    
    Fixes #967 (persistent_instructions part; context7 naming addressed by #970)
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix(codex): sync startup_timeout_sec into merge-mcp-config.js ECC_SERVERS
    Reviewers identified that merge-mcp-config.js --update-mcp would
    silently strip the startup_timeout_sec from config.toml because the
    ECC_SERVERS spec did not include it. Add startup_timeout_sec = 30 to
    playwright, context7-mcp, github, memory, and sequential-thinking.
    
    Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
    
    Signed-off-by: Lidang-Jiang <lidangjiang@gmail.com>
  • fix: add execute permissions to codex sync shell scripts
    Three .sh files were committed without the execute bit, causing
    `install-global-git-hooks.sh` to fail with "Permission denied"
    when invoked by `sync-ecc-to-codex.sh`.
    
    Generated with [Claude Code](https://claude.ai/code)
    via [Happy](https://happy.engineering)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    Co-Authored-By: Happy <yesreply@happy.engineering>
  • feat(hooks): add pre-commit quality check hook
    - Add pre-bash-commit-quality.js hook script
    - Runs quality checks before git commit commands:
      - Lints staged files (ESLint, Pylint, golint)
      - Validates commit message format (conventional commits)
      - Detects console.log/debugger statements
      - Warns about TODO/FIXME without issue references
      - Detects potential hardcoded secrets
    - Updates hooks.json with new hook configuration
    - Updates README.md with hook documentation
    
    Cross-platform (Windows, macOS, Linux)
  • fix: remove redundant skill copy from sync-ecc-to-codex.sh
    Codex CLI reads skills natively from ~/.agents/skills/ (installed by
    ECC installer / npx skills). The sync script was redundantly copying
    the same skills from .agents/skills/ to ~/.codex/skills/.
    
    Changes:
    - Remove skill copy loop, variables, and path validation from sync script
    - Update sanity checker to validate ~/.agents/skills/ instead of
      ~/.codex/skills/, downgrade missing skills from FAIL to WARN
    - Update test assertions to verify skill sync removal
    
    Generated with [Claude Code](https://claude.ai/code)
    via [Happy](https://happy.engineering)
    
    Co-Authored-By: Claude <noreply@anthropic.com>
    Co-Authored-By: Happy <yesreply@happy.engineering>
  • Merge pull request #846 from pythonstrup/feat/desktop-notify-hook
    feat: add macOS desktop notification Stop hook
  • fix: add spawnSync error logging and restore 5s timeout
    - Check spawnSync result and log warning on failure via stderr
    - Restore osascript timeout to 5000ms, increase hook deadline to 10s
      for sufficient headroom
  • fix: use AppleScript-safe escaping and reduce spawnSync timeout
    - Replace JSON.stringify with curly quote substitution for AppleScript
      compatibility (AppleScript does not support \" backslash escapes)
    - Reduce spawnSync timeout from 5000ms to 3000ms to leave headroom
      within the 5s hook deadline
  • feat: add macOS desktop notification Stop hook
    Add a new Stop hook that sends a native macOS notification with the
    task summary (first line of last_assistant_message) when Claude finishes
    responding. Uses osascript via spawnSync for shell injection safety.
    Supports run-with-flags fast require() path. Only active on standard
    and strict profiles; silently skips on non-macOS platforms.
  • feat(hooks): add config protection hook to block linter config manipulation (#758)
    * feat(hooks): add config protection hook to block linter config manipulation
    
    Agents frequently modify linter/formatter configs (.eslintrc, biome.json,
    .prettierrc, .ruff.toml, etc.) to make checks pass instead of fixing
    the actual code.
    
    This PreToolUse hook intercepts Write/Edit/MultiEdit calls targeting
    known config files and blocks them with a steering message that directs
    the agent to fix the source code instead.
    
    Covers: ESLint, Prettier, Biome, Ruff, ShellCheck, Stylelint, and
    Markdownlint configs.
    
    Fixes #733
    
    * Address review: fix dead code, add missing configs, export run()
    
    - Removed pyproject.toml from PROTECTED_FILES (was dead code since
      it was also in PARTIAL_CONFIG_FILES). Added comment explaining why
      it's intentionally excluded.
    - Removed PARTIAL_CONFIG_FILES entirely (no longer needed).
    - Added missing ESLint v9 TypeScript flat configs: eslint.config.ts,
      eslint.config.mts, eslint.config.cts
    - Added missing Prettier ESM config: prettier.config.mjs
    - Exported run() function for in-process execution via run-with-flags,
      avoiding the spawnSync overhead (~50-100ms per call).
    
    * Handle stdin truncation gracefully, log warning instead of fail-open
    
    If stdin exceeds 1MB, the JSON would be malformed and the catch
    block would silently pass through. Now we detect truncation and
    log a warning. The in-process run() path is not affected.