mirror of
https://github.com/affaan-m/everything-claude-code.git
synced 2026-04-05 08:43:29 +08:00
fix: narrow unicode cleanup scope
This commit is contained in:
@@ -28,7 +28,7 @@ if (projectPath && projectPath !== cwd) {
|
||||
if (existsSync(projectPath)) {
|
||||
console.log(`→ cd ${projectPath}`);
|
||||
} else {
|
||||
console.log(`WARNING: Path not found: ${projectPath}`);
|
||||
console.log(`WARNING Path not found: ${projectPath}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ function main() {
|
||||
// Check if previous session ID exists in sessions array
|
||||
const alreadySaved = context.sessions?.some(s => s.id === prevSession.sessionId);
|
||||
if (!alreadySaved) {
|
||||
summaryLines.push(`WARNING: Last session wasn't saved — run /ck:save to capture it`);
|
||||
summaryLines.push(`WARNING Last session wasn't saved — run /ck:save to capture it`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,7 @@ function main() {
|
||||
const claudeMdGoal = extractClaudeMdGoal(cwd);
|
||||
if (claudeMdGoal && context.goal &&
|
||||
claudeMdGoal.toLowerCase().trim() !== context.goal.toLowerCase().trim()) {
|
||||
summaryLines.push(`WARNING: Goal mismatch — ck: "${context.goal.slice(0, 40)}" · CLAUDE.md: "${claudeMdGoal.slice(0, 40)}"`);
|
||||
summaryLines.push(`WARNING Goal mismatch — ck: "${context.goal.slice(0, 40)}" · CLAUDE.md: "${claudeMdGoal.slice(0, 40)}"`);
|
||||
summaryLines.push(` Run /ck:save with updated goal to sync`);
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ function main() {
|
||||
'```',
|
||||
``,
|
||||
`After the block, add one line: "Ready — what are we working on?"`,
|
||||
`If you see WARNING: warnings above, mention them briefly after the block.`,
|
||||
`If you see WARNING lines above, mention them briefly after the block.`,
|
||||
].join('\n'));
|
||||
|
||||
return parts;
|
||||
|
||||
@@ -4,16 +4,16 @@
|
||||
# Called by observer-loop.sh before spawning any Claude session.
|
||||
#
|
||||
# Config (env vars, all optional):
|
||||
# OBSERVER_INTERVAL_SECONDS default: 300 (per-project cooldown)
|
||||
# OBSERVER_LAST_RUN_LOG default: ~/.claude/observer-last-run.log
|
||||
# OBSERVER_ACTIVE_HOURS_START default: 800 (8:00 AM local, set to 0 to disable)
|
||||
# OBSERVER_ACTIVE_HOURS_END default: 2300 (11:00 PM local, set to 0 to disable)
|
||||
# OBSERVER_MAX_IDLE_SECONDS default: 1800 (30 min; set to 0 to disable)
|
||||
# OBSERVER_INTERVAL_SECONDS default: 300 (per-project cooldown)
|
||||
# OBSERVER_LAST_RUN_LOG default: ~/.claude/observer-last-run.log
|
||||
# OBSERVER_ACTIVE_HOURS_START default: 800 (8:00 AM local, set to 0 to disable)
|
||||
# OBSERVER_ACTIVE_HOURS_END default: 2300 (11:00 PM local, set to 0 to disable)
|
||||
# OBSERVER_MAX_IDLE_SECONDS default: 1800 (30 min; set to 0 to disable)
|
||||
#
|
||||
# Gate execution order (cheapest first):
|
||||
# Gate 1: Time window check (~0ms, string comparison)
|
||||
# Gate 2: Project cooldown log (~1ms, file read + mkdir lock)
|
||||
# Gate 3: Idle detection (~5-50ms, OS syscall; fail open)
|
||||
# Gate 1: Time window check (~0ms, string comparison)
|
||||
# Gate 2: Project cooldown log (~1ms, file read + mkdir lock)
|
||||
# Gate 3: Idle detection (~5-50ms, OS syscall; fail open)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
# and creates instincts. Uses Haiku model for cost efficiency.
|
||||
#
|
||||
# v2.1: Project-scoped — detects current project and analyzes
|
||||
# project-specific observations into project-scoped instincts.
|
||||
# project-specific observations into project-scoped instincts.
|
||||
#
|
||||
# Usage:
|
||||
# start-observer.sh # Start observer for current project (or global)
|
||||
# start-observer.sh --reset # Clear lock and restart observer for current project
|
||||
# start-observer.sh stop # Stop running observer
|
||||
# start-observer.sh status # Check if observer is running
|
||||
# start-observer.sh # Start observer for current project (or global)
|
||||
# start-observer.sh --reset # Clear lock and restart observer for current project
|
||||
# start-observer.sh stop # Stop running observer
|
||||
# start-observer.sh status # Check if observer is running
|
||||
|
||||
set -e
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
# Claude Code passes hook data via stdin as JSON.
|
||||
#
|
||||
# v2.1: Project-scoped observations — detects current project context
|
||||
# and writes observations to project-specific directory.
|
||||
# and writes observations to project-specific directory.
|
||||
#
|
||||
# Registered via plugin hooks/hooks.json (auto-loaded when plugin is enabled).
|
||||
# Can also be registered manually in ~/.claude/settings.json.
|
||||
@@ -92,9 +92,9 @@ if [ -n "${CLV2_CONFIG:-}" ] && [ -f "$(dirname "$CLV2_CONFIG")/disabled" ]; the
|
||||
fi
|
||||
|
||||
# Prevent observe.sh from firing on non-human sessions to avoid:
|
||||
# - ECC observing its own Haiku observer sessions (self-loop)
|
||||
# - ECC observing other tools' automated sessions
|
||||
# - automated sessions creating project-scoped homunculus metadata
|
||||
# - ECC observing its own Haiku observer sessions (self-loop)
|
||||
# - ECC observing other tools' automated sessions
|
||||
# - automated sessions creating project-scoped homunculus metadata
|
||||
|
||||
# Layer 1: entrypoint. Only interactive terminal sessions should continue.
|
||||
# sdk-ts: Agent SDK sessions can be human-interactive (e.g. via Happy).
|
||||
|
||||
@@ -5,19 +5,19 @@
|
||||
# Sourced by observe.sh and start-observer.sh.
|
||||
#
|
||||
# Exports:
|
||||
# _CLV2_PROJECT_ID - Short hash identifying the project (or "global")
|
||||
# _CLV2_PROJECT_NAME - Human-readable project name
|
||||
# _CLV2_PROJECT_ROOT - Absolute path to project root
|
||||
# _CLV2_PROJECT_DIR - Project-scoped storage directory under homunculus
|
||||
# _CLV2_PROJECT_ID - Short hash identifying the project (or "global")
|
||||
# _CLV2_PROJECT_NAME - Human-readable project name
|
||||
# _CLV2_PROJECT_ROOT - Absolute path to project root
|
||||
# _CLV2_PROJECT_DIR - Project-scoped storage directory under homunculus
|
||||
#
|
||||
# Also sets unprefixed convenience aliases:
|
||||
# PROJECT_ID, PROJECT_NAME, PROJECT_ROOT, PROJECT_DIR
|
||||
# PROJECT_ID, PROJECT_NAME, PROJECT_ROOT, PROJECT_DIR
|
||||
#
|
||||
# Detection priority:
|
||||
# 1. CLAUDE_PROJECT_DIR env var (if set)
|
||||
# 2. git remote URL (hashed for uniqueness across machines)
|
||||
# 3. git repo root path (fallback, machine-specific)
|
||||
# 4. "global" (no project context detected)
|
||||
# 1. CLAUDE_PROJECT_DIR env var (if set)
|
||||
# 2. git remote URL (hashed for uniqueness across machines)
|
||||
# 3. git repo root path (fallback, machine-specific)
|
||||
# 4. "global" (no project context detected)
|
||||
|
||||
_CLV2_HOMUNCULUS_DIR="${HOME}/.claude/homunculus"
|
||||
_CLV2_PROJECTS_DIR="${_CLV2_HOMUNCULUS_DIR}/projects"
|
||||
|
||||
@@ -8,15 +8,15 @@
|
||||
#
|
||||
# Hook config (in ~/.claude/settings.json):
|
||||
# {
|
||||
# "hooks": {
|
||||
# "Stop": [{
|
||||
# "matcher": "*",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/continuous-learning/evaluate-session.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# "hooks": {
|
||||
# "Stop": [{
|
||||
# "matcher": "*",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/continuous-learning/evaluate-session.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Patterns to detect: error_resolution, debugging_techniques, workarounds, project_specific
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
# Output: JSON to stdout
|
||||
#
|
||||
# Environment:
|
||||
# RULES_DISTILL_DIR Override ~/.claude/rules (for testing only)
|
||||
# RULES_DISTILL_DIR Override ~/.claude/rules (for testing only)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
# script always picks up project-level skills without relying on the caller.
|
||||
#
|
||||
# Environment:
|
||||
# RULES_DISTILL_GLOBAL_DIR Override ~/.claude/skills (for testing only;
|
||||
# do not set in production — intended for bats tests)
|
||||
# RULES_DISTILL_PROJECT_DIR Override project dir detection (for testing only)
|
||||
# RULES_DISTILL_GLOBAL_DIR Override ~/.claude/skills (for testing only;
|
||||
# do not set in production — intended for bats tests)
|
||||
# RULES_DISTILL_PROJECT_DIR Override project dir detection (for testing only)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
# script always picks up project-level skills without relying on the caller.
|
||||
#
|
||||
# Environment:
|
||||
# SKILL_STOCKTAKE_GLOBAL_DIR Override ~/.claude/skills (for testing only;
|
||||
# do not set in production — intended for bats tests)
|
||||
# SKILL_STOCKTAKE_PROJECT_DIR Override project dir detection (for testing only)
|
||||
# SKILL_STOCKTAKE_GLOBAL_DIR Override ~/.claude/skills (for testing only;
|
||||
# do not set in production — intended for bats tests)
|
||||
# SKILL_STOCKTAKE_PROJECT_DIR Override project dir detection (for testing only)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
# Usage: save-results.sh RESULTS_JSON <<< "$EVAL_JSON"
|
||||
#
|
||||
# stdin format:
|
||||
# { "skills": {...}, "mode"?: "full"|"quick", "batch_progress"?: {...} }
|
||||
# { "skills": {...}, "mode"?: "full"|"quick", "batch_progress"?: {...} }
|
||||
#
|
||||
# Always sets evaluated_at to current UTC time via `date -u`.
|
||||
# Merges stdin .skills into existing results.json (new entries override old).
|
||||
|
||||
@@ -7,9 +7,9 @@
|
||||
# script always picks up project-level skills without relying on the caller.
|
||||
#
|
||||
# Environment:
|
||||
# SKILL_STOCKTAKE_GLOBAL_DIR Override ~/.claude/skills (for testing only;
|
||||
# do not set in production — intended for bats tests)
|
||||
# SKILL_STOCKTAKE_PROJECT_DIR Override project dir detection (for testing only)
|
||||
# SKILL_STOCKTAKE_GLOBAL_DIR Override ~/.claude/skills (for testing only;
|
||||
# do not set in production — intended for bats tests)
|
||||
# SKILL_STOCKTAKE_PROJECT_DIR Override project dir detection (for testing only)
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
|
||||
@@ -10,15 +10,15 @@
|
||||
#
|
||||
# Hook config (in ~/.claude/settings.json):
|
||||
# {
|
||||
# "hooks": {
|
||||
# "PreToolUse": [{
|
||||
# "matcher": "Edit|Write",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/strategic-compact/suggest-compact.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# "hooks": {
|
||||
# "PreToolUse": [{
|
||||
# "matcher": "Edit|Write",
|
||||
# "hooks": [{
|
||||
# "type": "command",
|
||||
# "command": "~/.claude/skills/strategic-compact/suggest-compact.sh"
|
||||
# }]
|
||||
# }]
|
||||
# }
|
||||
# }
|
||||
#
|
||||
# Criteria for suggesting compact:
|
||||
|
||||
@@ -78,7 +78,7 @@ def ensure_private_dir(path: Path) -> Path:
|
||||
def parse_args() -> tuple[bool, Path]:
|
||||
clear = False
|
||||
output_dir: str | None = None
|
||||
|
||||
|
||||
args = sys.argv[1:]
|
||||
for arg in args:
|
||||
if arg == "--clear":
|
||||
@@ -87,7 +87,7 @@ def parse_args() -> tuple[bool, Path]:
|
||||
raise SystemExit(f"Unknown flag: {arg}")
|
||||
elif not arg.startswith("-"):
|
||||
output_dir = arg
|
||||
|
||||
|
||||
if output_dir is None:
|
||||
events_dir = os.environ.get("VIDEODB_EVENTS_DIR")
|
||||
if events_dir:
|
||||
@@ -147,10 +147,10 @@ def is_fatal_error(exc: Exception) -> bool:
|
||||
async def listen_with_retry():
|
||||
"""Main listen loop with auto-reconnect and exponential backoff."""
|
||||
global _first_connection
|
||||
|
||||
|
||||
retry_count = 0
|
||||
backoff = INITIAL_BACKOFF
|
||||
|
||||
|
||||
while retry_count < MAX_RETRIES:
|
||||
try:
|
||||
conn = videodb.connect()
|
||||
@@ -168,11 +168,11 @@ async def listen_with_retry():
|
||||
raise
|
||||
retry_count += 1
|
||||
log(f"Connection error: {e}")
|
||||
|
||||
|
||||
if retry_count >= MAX_RETRIES:
|
||||
log(f"Max retries ({MAX_RETRIES}) exceeded, exiting")
|
||||
break
|
||||
|
||||
|
||||
log(f"Reconnecting in {backoff}s (attempt {retry_count}/{MAX_RETRIES})...")
|
||||
await asyncio.sleep(backoff)
|
||||
backoff = min(backoff * 2, MAX_BACKOFF)
|
||||
@@ -233,20 +233,20 @@ async def main_async():
|
||||
"""Async main with signal handling."""
|
||||
loop = asyncio.get_running_loop()
|
||||
shutdown_event = asyncio.Event()
|
||||
|
||||
|
||||
def handle_signal():
|
||||
log("Received shutdown signal")
|
||||
shutdown_event.set()
|
||||
|
||||
|
||||
# Register signal handlers
|
||||
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||
with contextlib.suppress(NotImplementedError):
|
||||
loop.add_signal_handler(sig, handle_signal)
|
||||
|
||||
|
||||
# Run listener with cancellation support
|
||||
listen_task = asyncio.create_task(listen_with_retry())
|
||||
shutdown_task = asyncio.create_task(shutdown_event.wait())
|
||||
|
||||
|
||||
_done, pending = await asyncio.wait(
|
||||
[listen_task, shutdown_task],
|
||||
return_when=asyncio.FIRST_COMPLETED,
|
||||
@@ -254,7 +254,7 @@ async def main_async():
|
||||
|
||||
if listen_task.done():
|
||||
await listen_task
|
||||
|
||||
|
||||
# Cancel remaining tasks
|
||||
for task in pending:
|
||||
task.cancel()
|
||||
@@ -266,7 +266,7 @@ async def main_async():
|
||||
for sig in (signal.SIGINT, signal.SIGTERM):
|
||||
with contextlib.suppress(NotImplementedError):
|
||||
loop.remove_signal_handler(sig)
|
||||
|
||||
|
||||
log("Shutdown complete")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user