Commit Graph

63 Commits

Author SHA1 Message Date
Affaan Mustafa
4d4ba25d11 feat: add orchestration workflows and harness skills 2026-03-12 14:49:05 -07:00
Affaan Mustafa
bfc73866c9 Revert "feat: add orchestration workflows and harness skills"
This reverts commit cb43402d7d.
2026-03-12 09:26:12 -07:00
Affaan Mustafa
cb43402d7d feat: add orchestration workflows and harness skills 2026-03-12 08:53:52 -07:00
Affaan Mustafa
5a5d647825 Merge origin/main into feat/insaits-security-hook 2026-03-10 20:48:59 -07:00
Affaan Mustafa
9c1e8dd1e4 fix: make insaits hook opt-in 2026-03-10 20:47:09 -07:00
Jonghyeok Park
67841042d6 refactor: deduplicate config lists and unify resolveFormatterBin branches
Extract BIOME_CONFIGS and PRETTIER_CONFIGS as shared constants to eliminate
duplication between PROJECT_ROOT_MARKERS and detectFormatter(). Unify the
biome/prettier branches in resolveFormatterBin() via a FORMATTER_PACKAGES
map. Remove redundant path.resolve() in quality-gate.js.
2026-03-11 10:45:28 +09:00
Jonghyeok Park
0a3afbe38f fix(hooks): add Windows .cmd support with shell injection guard
Handle Windows .cmd shim resolution via spawnSync with strict path
validation. Removes shell:true injection risk, uses strict equality,
and restores .cmd support with path injection guard.
2026-03-11 10:45:28 +09:00
Jonghyeok Park
66498ae9ac perf(hooks): use direct require() instead of spawning child process
Invoke hook scripts directly via require() when they export a
run(rawInput) function, eliminating one Node.js process spawn per
hook invocation (~50-100ms).

Includes path traversal guard, timeouts, error logging, PR review
feedback, legacy hooks guard, normalized filePath, and restored
findProjectRoot config detection with package manager support.
2026-03-11 10:45:27 +09:00
Nomadu27
9ea415c037 fix: extract BLOCKING_SEVERITIES constant, document broad catch
- Extract BLOCKING_SEVERITIES frozenset for extensible severity checks.
- Add inline comment on broad Exception catch explaining intentional
  SDK fault-tolerance pattern (BLE001 acknowledged).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 19:06:56 +01:00
Nomadu27
e30109829b fix: dict anomaly access, configurable fail mode, exception type logging
- Add get_anomaly_attr() helper that handles both dict and object
  anomalies. The SDK's send_message() returns dicts, so getattr()
  was silently returning defaults -- critical blocking never triggered.
- Fix field name: "detail" -> "details" (matches SDK schema).
- Make fail-open/fail-closed configurable via INSAITS_FAIL_MODE env var
  (defaults to "open" for backward compatibility).
- Include exception type name in fail-open log for diagnostics.
- Normalize severity comparison with .upper() for case-insensitive matching.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:53:21 +01:00
Nomadu27
68fc85ea49 fix: address cubic-dev-ai + coderabbit round 3 review
cubic-dev-ai P2: dev_mode now defaults to "false" (strict mode).
Users opt in to dev mode by setting INSAITS_DEV_MODE=true.

cubic-dev-ai P2: Move null-status check above stdout/stderr writes
in wrapper so partial/corrupt output is never leaked. Pass through
original raw input on signal kill, matching the result.error path.

coderabbit major: Wrap insAItsMonitor() and send_message() in
try/except so SDK errors don't crash the hook. Logs warning and
exits 0 (fail-open) on exception.

coderabbit nitpick: write_audit now creates a new dict (enriched)
instead of mutating the caller's event dict.

coderabbit nitpick: Extract magic numbers to named constants:
MIN_CONTENT_LENGTH=10, MAX_SCAN_LENGTH=4000, DEFAULT_MODEL.

Also: added env var documentation to module docstring.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:25:23 +01:00
Nomadu27
0405ade5f4 fix: make dev_mode configurable via INSAITS_DEV_MODE env var
Defaults to true (no API key needed) but can be disabled by setting
INSAITS_DEV_MODE=false for production deployments with an API key.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:09:02 +01:00
Nomadu27
6c56e541dd fix: address cubic-dev-ai review — 3 issues
P1: Log non-ENOENT spawn errors (timeout, signal kill) to stderr
instead of silently exiting 0. Separate handling for result.error
and null result.status so users know when the security monitor
failed to run.

P1: Remove "async": true from hooks.json — async hooks run in the
background and cannot block tool execution. The security hook needs
to be synchronous so exit(2) actually prevents credential exposure
and other critical findings from proceeding.

P2: Remove dead tool_response/tool_result code from extract_content.
In a PreToolUse hook the tool hasn't executed yet, so tool_response
is never populated. Removed the variable and the unreachable branch
that appended its content.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 18:08:19 +01:00
Nomadu27
44dc96d2c6 fix: address CodeRabbit review — convert to PreToolUse, add type annotations, logging
Critical fixes:
- Convert hook from PostToolUse to PreToolUse so exit(2) blocking works
- Change all python references to python3 for cross-platform compat
- Add insaits-security-wrapper.js to bridge run-with-flags.js to Python

Standard fixes:
- Wrap hook with run-with-flags.js so users can disable via
  ECC_DISABLED_HOOKS="pre:insaits-security"
- Add "async": true to hooks.json entry
- Add type annotations to all function signatures (Dict, List, Tuple, Any)
- Replace all print() statements with logging module (stderr)
- Fix silent OSError swallow in write_audit — now logs warning
- Remove os.environ.setdefault('INSAITS_DEV_MODE') — pass dev_mode=True
  through monitor constructor instead
- Update hooks/README.md: moved to PreToolUse table, "detects" not
  "catches", clarify blocking vs non-blocking behavior

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 17:52:44 +01:00
Jonghyeok Park
e5d02000c3 perf(hooks): eliminate npx overhead and merge biome invocations
- Use local node_modules/.bin/biome binary instead of npx (~200-500ms savings)
- Change post-edit-format from `biome format --write` to `biome check --write`
  (format + lint in one pass)
- Skip redundant biome check in quality-gate for JS/TS files already
  handled by post-edit-format
- Fix quality-gate to use findProjectRoot instead of process.cwd()
- Export run() function from both hooks for direct invocation
- Update tests to match shared resolve-formatter module usage
2026-03-10 22:19:31 +09:00
Affaan Mustafa
af51fcacb7 fix: resolve PR 371 portability regressions 2026-03-09 22:49:43 -07:00
Affaan Mustafa
440178d697 fix: harden hook portability and plugin docs 2026-03-09 22:49:43 -07:00
Nomadu27
540f738cc7 feat: add InsAIts PostToolUse security monitoring hook
- Add insaits-security-monitor.py: real-time AI security monitoring
  hook that catches credential exposure, prompt injection,
  hallucinations, and 20+ other anomaly types
- Update hooks.json with InsAIts PostToolUse entry
- Update hooks/README.md with InsAIts in PostToolUse table
- Add InsAIts MCP server entry to mcp-configs/mcp-servers.json

InsAIts (https://github.com/Nomadu27/InsAIts) is an open-source
runtime security layer for multi-agent AI. It runs 100% locally
and writes tamper-evident audit logs to .insaits_audit_session.jsonl.

Install: pip install insa-its

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-10 01:02:58 +01:00
zzzhizhi
177dd36e23 fix(hooks): allow tmux-wrapped dev server commands (#321)
* fix(hooks): fix shell splitter redirection/escape bugs, extract shared module

- Fix single & incorrectly splitting redirection operators (&>, >&, 2>&1)
- Fix escaped quotes (\", \') not being handled inside quoted strings
- Extract splitShellSegments into shared scripts/lib/shell-split.js
  to eliminate duplication between hooks.json, before-shell-execution.js,
  and pre-bash-dev-server-block.js
- Add comprehensive tests for shell splitting edge cases

* fix(hooks): handle backslash escapes outside quotes in shell splitter

Escaped operators like \&& and \; outside quotes were still being
treated as separators. Add escape handling for unquoted context.
2026-03-07 14:47:49 -08:00
Helbetica
7bed751db0 fix: auto-start dev servers in tmux instead of blocking (#344)
* fix: auto-start development servers in tmux instead of blocking

Replace blocking PreToolUse hook that used process.exit(2) with an auto-transform hook that:
- Detects development server commands
- Wraps them in tmux with directory-based session names
- Runs server detached so Claude Code is not blocked
- Provides confirmation message with log viewing instructions

Benefits:
- Development servers no longer block Claude Code execution
- Each project gets its own tmux session (allows multiple projects)
- Logs remain accessible via 'tmux capture-pane -t <session>'
- Non-blocking: if tmux unavailable, command still runs (graceful fallback)

Implementation:
- Created scripts/hooks/auto-tmux-dev.js with transform logic
- Updated hooks.json to reference the script instead of inline node command
- Applied same fix to cached plugin version (1.4.1) for immediate effect

* fix: resolve PR #344 code review issues in auto-tmux-dev.js

Critical fixes:
- Fix variable scope: declare 'input' before try block, not inside
- Fix shell injection: sanitize sessionName and escape cmd for shell
- Replace unused execFileSync import with spawnSync

Improvements:
- Add real Windows support using cmd /k window launcher
- Add tmux availability check with graceful fallback
- Update header comment to accurately describe platform support

Test coverage:
- Valid JSON input: transforms command for respective platform
- Invalid JSON: passes through raw data unchanged
- Unsupported tools: gracefully falls back to original command
- Shell metacharacters: sanitized in sessionName, escaped in cmd

* fix: correct cmd.exe escape sequence for double quotes on Windows

Use double-quote doubling ('""') instead of backslash-escape ('\\\") for cmd.exe syntax.
Backslash escaping is Unix convention and not recognized by cmd.exe. This fixes quoted
arguments in dev server commands on Windows (e.g., 'npm run dev --filter="my-app"').
2026-03-07 14:47:46 -08:00
jtzingsheim1
9661a6f042 fix(hooks): scrub secrets and harden hook security (#348)
* fix(hooks): scrub secrets and harden hook security

- Scrub common secret patterns (api_key, token, password, etc.) from
  observation logs before persisting to JSONL (observe.sh)
- Auto-purge observation files older than 30 days (observe.sh)
- Strip embedded credentials from git remote URLs before saving to
  projects.json (detect-project.sh)
- Add command prefix allowlist to runCommand — only git, node, npx,
  which, where are permitted (utils.js)
- Sanitize CLAUDE_SESSION_ID in temp file paths to prevent path
  traversal (suggest-compact.js)

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

* fix(hooks): address review feedback from CodeRabbit and Cubic

- Reject shell command-chaining operators (;|&`) in runCommand, strip
  quoted sections before checking to avoid false positives (utils.js)
- Remove command string from blocked error message to avoid leaking
  secrets (utils.js)
- Fix Python regex quoting: switch outer shell string from double to
  single quotes so regex compiles correctly (observe.sh)
- Add optional auth scheme match (Bearer, Basic) to secret scrubber
  regex (observe.sh)
- Scope auto-purge to current project dir and match only archived
  files (observations-*.jsonl), not live queue (observe.sh)
- Add second fallback after session ID sanitization to prevent empty
  string (suggest-compact.js)
- Preserve backward compatibility when credential stripping changes
  project hash — detect and migrate legacy directories
  (detect-project.sh)

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

* fix(hooks): block $() substitution, fix Bearer redaction, add security tests

- Add $ and \n to blocked shell metacharacters in runCommand to prevent
  command substitution via $(cmd) and newline injection (utils.js)
- Make auth scheme group capturing so Bearer/Basic is preserved in
  redacted output instead of being silently dropped (observe.sh)
- Add 10 unit tests covering runCommand allowlist blocking (rm, curl,
  bash prefixes) and metacharacter rejection (;|&`$ chaining), plus
  error message leak prevention (utils.test.js)

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

* fix(hooks): scrub parse-error fallback, strengthen security tests

Address remaining reviewer feedback from CodeRabbit and Cubic:

- Scrub secrets in observe.sh parse-error fallback path (was writing
  raw unsanitized input to observations file)
- Remove redundant re.IGNORECASE flag ((?i) inline flag already set)
- Add inline comment documenting quote-stripping limitation trade-off
- Fix misleading test name for error-output test
- Add 5 new security tests: single-quote passthrough, mixed
  quoted+unquoted metacharacters, prefix boundary (no trailing space),
  npx acceptance, and newline injection
- Improve existing quoted-metacharacter test to actually exercise
  quote-stripping logic

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

* fix(security): block $() and backtick inside quotes in runCommand

Shell evaluates $() and backticks inside double quotes, so checking
only the unquoted portion was insufficient. Now $ and ` are rejected
anywhere in the command string, while ; | & remain quote-aware.

Addresses CodeRabbit and Cubic review feedback on PR #348.

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

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-07 14:47:31 -08:00
Affaan Mustafa
48b883d741 feat: deliver v1.8.0 harness reliability and parity updates 2026-03-04 14:48:06 -08:00
Jonghyeok Park
3260c7449e fix(lint): remove unnecessary escape characters in regex patterns
- doc-file-warning.js: \/ → / inside character classes (4 occurrences)
- project-detect.js: \[ → [ inside character classes (2 occurrences)

These are pre-existing no-useless-escape errors on upstream main.
2026-03-03 22:11:51 +09:00
Affaan Mustafa
3bfd29bb46 fix(hooks): exclude .history/ directory from doc file warning
Incorporates the fix from #316 into the standalone script.
2026-03-02 22:16:58 -08:00
Affaan Mustafa
1df0a53f22 fix: resolve CI failures on main — lint, hooks validator, and test alignment
- Fix MD012 trailing blank lines in commands/projects.md and commands/promote.md
- Fix MD050 strong-style in continuous-learning-v2 (escape __tests__ as inline code)
- Extract doc-file-warning hook to standalone script to fix hooks validator regex parsing
- Update session-end test to match #317 behavior (always update summary content)
- Allow shell script hooks in integration test format validation

All 992 tests passing.
2026-03-02 22:15:46 -08:00
justtrance-web
912df24f4a feat: automatic project type and framework detection (#293)
Add SessionStart hook integration that auto-detects project languages
and frameworks by inspecting marker files and dependency manifests.

Supports 12 languages (Python, TypeScript, Go, Rust, Ruby, Java, C#,
Swift, Kotlin, Elixir, PHP, JavaScript) and 25+ frameworks (Next.js,
React, Django, FastAPI, Rails, Laravel, Spring, etc.).

Detection output is injected into Claude's context as JSON, enabling
context-aware recommendations without loading irrelevant rules.

- New: scripts/lib/project-detect.js (cross-platform detection library)
- Modified: scripts/hooks/session-start.js (integration)
- New: tests/lib/project-detect.test.js (28 tests, all passing)

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-02 22:07:10 -08:00
will
e000bbe5e4 fix(session-end): always update session summary content (#317)
* fix(session-end): always update session summary content

Previously, session-end.js would only write content to session files
on first creation. Subsequent sessions would only update the timestamp,
causing stale content (e.g., old tasks, resolved issues) to persist
indefinitely.

This fix ensures that every session end updates the summary section
with fresh content from the current transcript, keeping cross-session
context accurate and relevant.

Fixes: #187 (partially - addresses stale content issue)

Changes:
- Remove the blank-template-only check
- Replace entire Session Summary section on every session end
- Keep timestamp update separate from content update

* fix(session-end): match both summary headers and prevent duplicate stats

Fixes two issues identified in PR #317 code review:

1. CodeRabbit: Updated regex to match both `## Session Summary` and
   `## Current State` headers, ensuring files created from blank template
   can be updated with fresh summaries.

2. Cubic: Changed regex lookahead `(?=### Stats|$)` to end-of-string `$`
   to prevent duplicate `### Stats` sections. The old pattern stopped before
   `### Stats` without consuming it, but buildSummarySection() also emits
   a `### Stats` block, causing duplication on each session update.

Changes:
- Regex now: `/## (?:Session Summary|Current State)[\s\S]*?$/`
- Matches both header variants used in blank template and populated sessions
- Matches to end-of-string to cleanly replace entire summary section

---------

Co-authored-by: will <will@192.168.5.31>
2026-03-02 22:00:33 -08:00
Affaan Mustafa
3b2448dbb4 fix(hooks): extract doc-warning hook to external script to fix CI
The inline JS in the Write PreToolUse hook had a multi-layer escaping
bug: the regex [\\/\\] collapsed to [\/\] after the validator's
unescape chain, producing an invalid regex (Unmatched ')').

Fix: move the doc-file-warning hook to scripts/hooks/pre-write-doc-warn.js,
eliminating the inline escaping problem entirely. All 992 tests now pass.

Closes the 991/992 CI failure on main.
2026-02-26 18:46:06 -08:00
Affaan Mustafa
f730fae78e Merge pull request #252 from pythonstrup/feat/auto-detect-formatter
LGTM — Auto-detect formatter hook. Safe, well-structured.
2026-02-24 09:24:15 -08:00
Jonghyeok Park
4eb6fbdd3f feat: auto-detect formatter in post-edit hook (Biome/Prettier)
The post-edit-format hook was hardcoded to use Prettier. Projects using
Biome had their code reformatted with Prettier defaults (e.g. double
quotes overwriting single quotes).

Now the hook walks up from the edited file to find the project root,
then checks for config files:
- biome.json / biome.jsonc → runs Biome
- .prettierrc / prettier.config.* → runs Prettier
- Neither found → skips formatting silently
2026-02-20 14:30:01 +09:00
Pangerkumzuk Longkumer
e1fca6e84d Merge branch 'affaan-m:main' into main 2026-02-18 18:33:04 +05:30
copilot-swe-agent[bot]
1eca3c9130 Fix stdin overflow bug in hook scripts - truncate chunks to stay within MAX_STDIN limit
Co-authored-by: pangerlkr <73515951+pangerlkr@users.noreply.github.com>
2026-02-18 07:40:12 +00:00
Affaan Mustafa
2c26d2d67c fix: add missing process.exit(0) to early return in post-edit-console-warn hook 2026-02-16 20:03:12 -08:00
Affaan Mustafa
b678c2f1b0 fix: collapse newlines in user messages to prevent markdown list breaks in session-end
User messages containing newline characters were being added as-is to
markdown list items in buildSummarySection(), breaking the list format.
Now newlines are replaced with spaces before backtick escaping.
2026-02-13 04:28:50 -08:00
Affaan Mustafa
e2040b46b3 fix: remove unreachable return after process.exit in post-edit-typecheck hook 2026-02-13 04:15:13 -08:00
Affaan Mustafa
992688a674 fix: add cwd to prettier hook, consistent process.exit(0), and stdout pass-through
- post-edit-format.js: add cwd based on file directory so npx resolves
  correct local prettier binary
- post-edit-typecheck.js, post-edit-format.js: replace console.log(data)
  with process.stdout.write(data) to avoid trailing newline corruption
- Add process.exit(0) to 4 hooks for consistent termination
  (check-console-log, post-edit-console-warn, post-edit-format,
  post-edit-typecheck)
- run-all.js: switch from execSync to spawnSync so stderr is visible
  on the success path (hook warnings were silently discarded)
- Add 21 tests: cwd verification, process.exit(0) checks, exact
  stdout pass-through, extension edge cases, exclusion pattern
  matching, threshold boundary values (630 → 651)
2026-02-13 03:20:41 -08:00
Affaan Mustafa
6bbcbec23d fix: exact byte pass-through in post-edit-console-warn, add 7 tests
Replace console.log(data) with process.stdout.write(data) in both
pass-through paths to prevent appending a trailing newline that
corrupts the hook output. Add 7 tests covering exact byte fidelity,
malformed JSON, missing file_path, non-existent files, exclusion
patterns in check-console-log, non-git repo handling, and empty stdin.
2026-02-13 02:49:33 -08:00
Affaan Mustafa
f4758ff8f0 fix: consistent periodic interval spacing in suggest-compact, add 10 tests
- suggest-compact.js: count % 25 → (count - threshold) % 25 for consistent
  spacing regardless of threshold value
- Update existing periodic interval test to match corrected behavior
- 10 new tests: interval fix regression (non-25-divisible threshold, false
  suggestion prevention), corrupted counter file, 1M boundary, malformed
  JSON pass-through, non-TS extension pass-through, empty sessions dir,
  blank template skip
2026-02-13 02:45:08 -08:00
Affaan Mustafa
4ff4872bf3 fix: nullish coalescing in evaluate-session config, narrow pre-compact glob, add 11 tests
- evaluate-session.js: || 10 → ?? 10 for min_session_length (0 is valid)
- pre-compact.js: *.tmp → *-session.tmp to match only session files
- 11 new tests: config loading (min=0, null, custom path, invalid JSON),
  session-end update path (timestamp, template replace, preserve content),
  pre-compact glob specificity, extractSessionSummary edge cases
2026-02-13 02:42:01 -08:00
Affaan Mustafa
d9331cb17f fix: eliminate command injection in hooks, fix pass-through newline corruption, add 8 tests
Replace shell: true with npx.cmd on Windows in post-edit-format.js and
post-edit-typecheck.js to prevent command injection via crafted file paths.
Replace console.log(data) with process.stdout.write(data) in
check-console-log.js to avoid appending extra newlines to pass-through data.
2026-02-13 02:22:55 -08:00
Affaan Mustafa
0e0319a1c2 fix: clamp suggest-compact counter overflow, add 9 boundary tests
Counter file could contain huge values (e.g. 999999999999) that pass
Number.isFinite() but cause unbounded growth. Added range clamp to
reject values outside [1, 1000000].

New tests cover:
- Counter overflow reset (huge number, negative number)
- COMPACT_THRESHOLD zero fallback
- session-end empty sections (no tools/files omits headers)
- session-end slice boundaries (10 messages, 20 tools, 30 files)
- post-edit-console-warn 5-match limit
- post-edit-console-warn ignores console.warn/error/debug
2026-02-13 01:59:25 -08:00
Affaan Mustafa
3f651b7c3c fix: typecheck hook false positives, add 11 session-manager tests
- Fix post-edit-typecheck.js error filtering: use relative/absolute path
  matching instead of basename, preventing false positives when multiple
  files share the same name (e.g., src/utils.ts vs tests/utils.ts)
- Add writeSessionContent tests (create, overwrite, invalid path)
- Add appendSessionContent test (append to existing file)
- Add deleteSession tests (delete existing, non-existent)
- Add sessionExists tests (file, non-existent, directory)
- Add getSessionStats empty content edge case
- Add post-edit-typecheck stdout passthrough test
- Total: 391 → 402 tests, all passing
2026-02-13 01:28:59 -08:00
dungan
4843a06b3a fix: Windows compatibility for hook scripts (execFileSync + tmux) (#215)
* fix: Windows compatibility for hook scripts

- post-edit-format.js: add `shell: process.platform === 'win32'` to
  execFileSync options so npx.cmd is resolved via cmd.exe on Windows
- post-edit-typecheck.js: same fix for tsc invocation via npx
- hooks.json: skip tmux-dependent hooks on Windows where tmux is
  unavailable (dev-server blocker and long-running command reminder)

On Windows, execFileSync('npx', ...) without shell:true fails with
ENOENT because Node.js cannot directly execute .cmd files. These
hooks silently fail on all Windows installations.

The tmux hooks unconditionally block dev server commands (exit 2) or
warn about tmux on Windows where tmux is not available.

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

* fix: parse Claude Code JSONL transcript format correctly

The session-end hook expected user messages at entry.content, but
Claude Code's actual JSONL format nests them at entry.message.content.
This caused all session files to be blank templates (0 user messages
despite 136+ actual entries).

- Check entry.message?.content in addition to entry.content
- Extract tool_use blocks from assistant message.content arrays

Verified with Claude Code v2.1.41 JSONL transcripts.

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

---------

Co-authored-by: ddungan <sckim@mococo.co.kr>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-13 01:04:27 -08:00
Affaan Mustafa
b1b28f2f92 fix: capture stderr in typecheck hook, add 13 tests for session-end and utils
- post-edit-typecheck.js: capture both stdout and stderr from tsc
- hooks.test.js: 7 extractSessionSummary tests (JSONL parsing, array content,
  malformed lines, empty transcript, long message truncation, env var fallback)
- utils.test.js: 6 tests (replaceInFile g-flag behavior, string replace,
  capture groups, writeFile overwrite, unicode content)

Total test count: 294 → 307
2026-02-12 16:31:07 -08:00
Affaan Mustafa
bc0520c6c1 fix: broken cross-references, version sync, and enhanced command validator
- Fix /build-and-fix → /build-fix in tdd.md, plan.md (+ cursor, zh-CN)
- Fix non-existent explorer agent → planner in orchestrate.md (+ cursor, zh-CN, zh-TW)
- Fix /python-test → /tdd in python-review.md (+ cursor, zh-CN)
- Sync package.json version from 1.0.0 to 1.4.1 to match plugin.json
- Enhance validate-commands.js with cross-reference checking:
  command refs, agent path refs, skill dir refs, workflow diagrams
- Strip fenced code blocks before scanning to avoid false positives
- Skip hypothetical "Creates:" lines in evolve.md examples
- Add 46 new tests (suggest-compact, session-manager, utils, hooks)
2026-02-12 16:19:04 -08:00
Affaan Mustafa
492c99ac24 fix: 3 bugs fixed, stdin encoding hardened, 37 CI validator tests added
Bug fixes:
- utils.js: glob-to-regex conversion now escapes all regex special chars
  (+, ^, $, |, (), {}, [], \) before converting * and ? wildcards
- validate-hooks.js: escape sequence processing order corrected —
  \\\\ now processed before \\n and \\t to prevent double-processing
- 6 hooks: added process.stdin.setEncoding('utf8') to prevent
  multi-byte UTF-8 character corruption at chunk boundaries
  (check-console-log, post-edit-format, post-edit-typecheck,
  post-edit-console-warn, session-end, evaluate-session)

New tests (37):
- CI validator test suite (tests/ci/validators.test.js):
  - validate-agents: 9 tests (real project, frontmatter parsing,
    BOM/CRLF, colons in values, missing fields, non-md skip)
  - validate-hooks: 13 tests (real project, invalid JSON, invalid
    event types, missing fields, async/timeout validation, inline JS
    syntax, array commands, legacy format)
  - validate-skills: 6 tests (real project, missing SKILL.md, empty
    files, non-directory entries)
  - validate-commands: 5 tests (real project, empty files, non-md skip)
  - validate-rules: 4 tests (real project, empty files)

Total test count: 228 (up from 191)
2026-02-12 16:08:49 -08:00
Affaan Mustafa
90ea2f327c fix: 2 bugs fixed, 17 tests added for hook scripts
Bug fixes:
- evaluate-session.js: whitespace-tolerant regex for counting user
  messages in JSONL transcripts (/"type":"user"/ → /"type"\s*:\s*"user"/)
- session-end.js: guard against null elements in content arrays
  (c.text → (c && c.text) to prevent TypeError)

New tests (17):
- evaluate-session: whitespace JSON regression test
- session-end: null content array elements regression test
- post-edit-console-warn: 5 tests (warn, skip non-JS, clean files,
  missing file, stdout passthrough)
- post-edit-format: 3 tests (empty stdin, non-JS skip, invalid JSON)
- post-edit-typecheck: 4 tests (empty stdin, non-TS skip, missing file,
  no tsconfig)

Total test count: 191 (up from 164)
2026-02-12 16:02:31 -08:00
Affaan Mustafa
ed7ec29ead fix: migrate hooks to stdin JSON input, fix duplicate main() calls, add threshold validation
- Migrate session-end.js and evaluate-session.js from CLAUDE_TRANSCRIPT_PATH
  env var to stdin JSON transcript_path (correct hook input mechanism)
- Remove duplicate main() calls that ran before stdin was read, causing
  session files to be created with empty data
- Add range validation (1-10000) on COMPACT_THRESHOLD in suggest-compact.js
  to prevent negative or absurdly large thresholds
- Add integration/hooks.test.js to tests/run-all.js so CI runs all 97 tests
- Update evaluate-session.sh to parse transcript_path from stdin JSON
- Update hooks.test.js to pass transcript_path via stdin instead of env var
- Sync .cursor/ copies
2026-02-12 15:33:55 -08:00
Affaan Mustafa
3546abc6ea fix: remove unused fs imports in 3 hook scripts
readFile utility replaced direct fs usage but the imports weren't
removed, causing ESLint no-unused-vars failures in CI.
2026-02-12 15:33:51 -08:00
Affaan Mustafa
e7b5c62eb7 fix: use readFile utility in hooks and add pattern type safety
- Replace raw fs.readFileSync with readFile() from utils in
  check-console-log.js and post-edit-console-warn.js to eliminate
  TOCTOU race conditions (file deleted between existsSync and read)
- Remove redundant existsSync in post-edit-format.js (exec already
  handles missing files via its catch block)
- Resolve path upfront in post-edit-typecheck.js before tsconfig walk
- Add type guard in getGitModifiedFiles() to skip non-string and
  empty patterns before regex compilation
2026-02-12 15:28:30 -08:00