cclaw-cli 0.46.5 → 0.46.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -15,7 +15,6 @@ export interface WorkflowGuardOptions {
15
15
  tddTestGlobs?: string[];
16
16
  }
17
17
  export declare function workflowGuardScript(options?: WorkflowGuardOptions): string;
18
- export declare function observeScript(): string;
19
18
  export declare function contextMonitorScript(): string;
20
19
  export declare function summarizeObservationsRuntimeModule(): string;
21
20
  export declare function summarizeObservationsScript(): string;
@@ -693,260 +693,6 @@ if [ -n "$REASONS" ]; then
693
693
  printf '[cclaw] %s\n' "$NOTE" >&2
694
694
  fi
695
695
 
696
- exit 0
697
- `;
698
- }
699
- export function observeScript() {
700
- return `#!/usr/bin/env bash
701
- # cclaw observe hook — generated by cclaw sync
702
- # Captures PreToolUse/PostToolUse events to ${RUNTIME_ROOT}/observations.jsonl
703
- # Reads hook JSON from stdin, extracts tool + truncated I/O, appends JSONL.
704
- # Always exits 0 to never block the agent.
705
- set -uo pipefail
706
-
707
- # Phase: "pre" or "post" passed as $1 by the hook runner
708
- PHASE="\${1:-post}"
709
-
710
- ${RUNTIME_SHELL_DETECT_ROOT}
711
-
712
- OBS_FILE="$ROOT/${RUNTIME_ROOT}/observations.jsonl"
713
- STATE_FILE="$ROOT/${RUNTIME_ROOT}/state/flow-state.json"
714
- ACTIVITY_FILE="$ROOT/${RUNTIME_ROOT}/state/stage-activity.jsonl"
715
- LOCK_DIR="$ROOT/${RUNTIME_ROOT}/state/.observe.lock"
716
- MAX_LEN=2000
717
-
718
- # Guard: skip if disabled or observations dir missing
719
- [ -f "$ROOT/${RUNTIME_ROOT}/.observe-disabled" ] && exit 0
720
- [ -d "$ROOT/${RUNTIME_ROOT}" ] || exit 0
721
- mkdir -p "$ROOT/${RUNTIME_ROOT}/state" 2>/dev/null || true
722
-
723
- escape_json() {
724
- local str="$1"
725
- str=\${str//\\\\/\\\\\\\\}
726
- str=\${str//\\"/\\\\\\"}
727
- str=\${str//$'\\t'/\\\\t}
728
- str=\${str//$'\\n'/\\\\n}
729
- printf '%s' "$str"
730
- }
731
-
732
- acquire_lock() {
733
- local attempt=0
734
- while ! mkdir "$LOCK_DIR" 2>/dev/null; do
735
- attempt=$((attempt + 1))
736
- if [ "$attempt" -ge 200 ]; then
737
- return 1
738
- fi
739
- sleep 0.02
740
- done
741
- return 0
742
- }
743
-
744
- release_lock() {
745
- rmdir "$LOCK_DIR" 2>/dev/null || true
746
- }
747
-
748
- rotate_file() {
749
- local file_path="$1"
750
- local keep_lines="$2"
751
- if [ ! -f "$file_path" ]; then
752
- return
753
- fi
754
- local line_count
755
- line_count=$(wc -l < "$file_path" 2>/dev/null | tr -d ' ')
756
- if [ -z "$line_count" ]; then
757
- return
758
- fi
759
- if [ "$line_count" -gt $((keep_lines * 2)) ]; then
760
- local tmp_path="\${file_path}.tmp.$$"
761
- if tail -n "$keep_lines" "$file_path" > "$tmp_path" 2>/dev/null; then
762
- mv "$tmp_path" "$file_path" 2>/dev/null || rm -f "$tmp_path" 2>/dev/null || true
763
- fi
764
- fi
765
- }
766
-
767
- sync_run_artifacts() {
768
- if [ "$PHASE" != "post" ]; then
769
- return
770
- fi
771
- [ -n "$ACTIVE_RUN" ] || return
772
- if [ "$ACTIVE_RUN" = "none" ]; then
773
- return
774
- fi
775
-
776
- local tool_lower
777
- tool_lower=$(printf '%s' "$TOOL" | tr '[:upper:]' '[:lower:]')
778
- case "$tool_lower" in
779
- write|edit|multiedit|multi_edit|delete|applypatch|runcommand|shell|terminal|execcommand) ;;
780
- *) return ;;
781
- esac
782
-
783
- local active_dir="$ROOT/${RUNTIME_ROOT}/artifacts"
784
- local run_dir="$ROOT/${RUNTIME_ROOT}/runs/$ACTIVE_RUN/artifacts"
785
- [ -d "$active_dir" ] || return
786
- mkdir -p "$run_dir" 2>/dev/null || return
787
-
788
- for run_file in "$run_dir"/*; do
789
- [ -e "$run_file" ] || continue
790
- [ -f "$run_file" ] || continue
791
- local base_name
792
- base_name=$(basename "$run_file")
793
- local active_file="$active_dir/$base_name"
794
- if [ ! -f "$active_file" ]; then
795
- rm -f "$run_file" 2>/dev/null || true
796
- continue
797
- fi
798
- if command -v cmp >/dev/null 2>&1 && cmp -s "$active_file" "$run_file" 2>/dev/null; then
799
- continue
800
- fi
801
- cp "$active_file" "$run_file" 2>/dev/null || true
802
- done
803
-
804
- for active_file in "$active_dir"/*; do
805
- [ -e "$active_file" ] || continue
806
- [ -f "$active_file" ] || continue
807
- local base_name
808
- base_name=$(basename "$active_file")
809
- local run_file="$run_dir/$base_name"
810
- if [ -f "$run_file" ] && command -v cmp >/dev/null 2>&1 && cmp -s "$active_file" "$run_file" 2>/dev/null; then
811
- continue
812
- fi
813
- cp "$active_file" "$run_file" 2>/dev/null || true
814
- done
815
- }
816
-
817
- # Read stdin (hook JSON)
818
- INPUT=$(cat 2>/dev/null || echo '{}')
819
- [ -z "$INPUT" ] && exit 0
820
-
821
- # Extract fields from hook payload.
822
- TOOL="unknown"
823
- PAYLOAD=""
824
- if command -v jq >/dev/null 2>&1; then
825
- TOOL=$(echo "$INPUT" | jq -r '.tool_name // .tool // .toolName // .name // .id // .command // .tool.name // .tool.id // .input.tool_name // .input.tool // .input.toolName // .input.name // .input.id // .input.command // .input.tool.name // .input.tool.id // "unknown"' 2>/dev/null || echo "unknown")
826
- if [ "$PHASE" = "pre" ]; then
827
- PAYLOAD=$(echo "$INPUT" | jq -r --arg max "$MAX_LEN" '.tool_input // .input // {} | tostring | .[0:($max|tonumber)]' 2>/dev/null || echo "")
828
- else
829
- PAYLOAD=$(echo "$INPUT" | jq -r --arg max "$MAX_LEN" '.tool_response // .tool_output // .output // .result_json // "" | tostring | .[0:($max|tonumber)]' 2>/dev/null || echo "")
830
- fi
831
- else
832
- TOOL=$(printf '%s' "$INPUT" | sed -n -E 's/.*"tool_name"[[:space:]]*:[[:space:]]*"([^"]+)".*/\\1/p' | head -1)
833
- if [ -z "$TOOL" ]; then
834
- TOOL=$(printf '%s' "$INPUT" | sed -n -E 's/.*"tool"[[:space:]]*:[[:space:]]*"([^"]+)".*/\\1/p' | head -1)
835
- fi
836
- [ -n "$TOOL" ] || TOOL="unknown"
837
- PAYLOAD=$(printf '%s' "$INPUT" | cut -c1-"$MAX_LEN")
838
- fi
839
-
840
- TS=$(date -u +"%Y-%m-%dT%H:%M:%SZ" 2>/dev/null || echo "")
841
- STAGE="none"
842
- ACTIVE_RUN="none"
843
- if [ -f "$STATE_FILE" ]; then
844
- if command -v jq >/dev/null 2>&1; then
845
- STAGE=$(jq -r '.currentStage // "none"' "$STATE_FILE" 2>/dev/null || echo "none")
846
- ACTIVE_RUN=$(jq -r '.activeRunId // "none"' "$STATE_FILE" 2>/dev/null || echo "none")
847
- elif command -v python3 >/dev/null 2>&1; then
848
- STAGE=$(python3 - "$STATE_FILE" <<'PY'
849
- import json
850
- import sys
851
-
852
- stage = "none"
853
- try:
854
- with open(sys.argv[1], "r", encoding="utf-8") as fh:
855
- data = json.load(fh)
856
- value = data.get("currentStage")
857
- if isinstance(value, str) and value:
858
- stage = value
859
- except Exception:
860
- pass
861
- print(stage)
862
- PY
863
- )
864
- ACTIVE_RUN=$(python3 - "$STATE_FILE" <<'PY'
865
- import json
866
- import sys
867
-
868
- run_id = "none"
869
- try:
870
- with open(sys.argv[1], "r", encoding="utf-8") as fh:
871
- data = json.load(fh)
872
- value = data.get("activeRunId")
873
- if isinstance(value, str) and value:
874
- run_id = value
875
- except Exception:
876
- pass
877
- print(run_id)
878
- PY
879
- )
880
- else
881
- STAGE=$(grep -o '"currentStage"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE_FILE" 2>/dev/null | head -1 | sed 's/.*"\\([^"]*\\)"$/\\1/' || echo "none")
882
- ACTIVE_RUN=$(grep -o '"activeRunId"[[:space:]]*:[[:space:]]*"[^"]*"' "$STATE_FILE" 2>/dev/null | head -1 | sed 's/.*"\\([^"]*\\)"$/\\1/' || echo "none")
883
- fi
884
- fi
885
-
886
- # Skip observation of cclaw hooks to avoid recursion
887
- case "$TOOL" in
888
- cclaw*|*cclaw-hook*|observe) exit 0 ;;
889
- esac
890
-
891
- if [ "$PHASE" = "pre" ]; then
892
- EVENT="tool_start"
893
- else
894
- EVENT="tool_complete"
895
- fi
896
-
897
- # Scrub potential secrets (env vars, tokens, keys) — BSD/macOS sed compatible
898
- PAYLOAD=$(echo "$PAYLOAD" | sed -E 's/[A-Za-z0-9_]*([Kk][Ee][Yy]|[Tt][Oo][Kk][Ee][Nn]|[Ss][Ee][Cc][Rr][Ee][Tt]|[Pp][Aa][Ss][Ss][Ww][Oo][Rr][Dd]|[Cc][Rr][Ee][Dd][Ee][Nn][Tt][Ii][Aa][Ll])[A-Za-z0-9_]*[=:][^ ",}]+/[REDACTED]/g' 2>/dev/null || echo "$PAYLOAD")
899
-
900
- # Build JSONL lines.
901
- if command -v jq >/dev/null 2>&1; then
902
- EVENT_JSON=$(jq -n -c \\
903
- --arg ts "$TS" \\
904
- --arg event "$EVENT" \\
905
- --arg tool "$TOOL" \\
906
- --arg phase "$PHASE" \\
907
- --arg stage "$STAGE" \\
908
- --arg runId "$ACTIVE_RUN" \\
909
- --arg payload "$PAYLOAD" \\
910
- '{ts:$ts,event:$event,tool:$tool,phase:$phase,stage:$stage,runId:$runId,data:$payload}' 2>/dev/null || echo "")
911
- ACTIVITY_JSON=$(jq -n -c \\
912
- --arg ts "$TS" \\
913
- --arg event "$EVENT" \\
914
- --arg tool "$TOOL" \\
915
- --arg phase "$PHASE" \\
916
- --arg stage "$STAGE" \\
917
- --arg runId "$ACTIVE_RUN" \\
918
- --arg schemaVersion "1" \\
919
- '{ts:$ts,event:$event,tool:$tool,phase:$phase,stage:$stage,runId:$runId,schemaVersion:($schemaVersion|tonumber)}' 2>/dev/null || echo "")
920
- else
921
- EVENT_JSON=$(printf '{"ts":"%s","event":"%s","tool":"%s","phase":"%s","stage":"%s","runId":"%s","data":"%s"}' \\
922
- "$(escape_json "$TS")" \\
923
- "$(escape_json "$EVENT")" \\
924
- "$(escape_json "$TOOL")" \\
925
- "$(escape_json "$PHASE")" \\
926
- "$(escape_json "$STAGE")" \\
927
- "$(escape_json "$ACTIVE_RUN")" \\
928
- "$(escape_json "$PAYLOAD")")
929
- ACTIVITY_JSON=$(printf '{"ts":"%s","event":"%s","tool":"%s","phase":"%s","stage":"%s","runId":"%s","schemaVersion":1}' \\
930
- "$(escape_json "$TS")" \\
931
- "$(escape_json "$EVENT")" \\
932
- "$(escape_json "$TOOL")" \\
933
- "$(escape_json "$PHASE")" \\
934
- "$(escape_json "$STAGE")" \\
935
- "$(escape_json "$ACTIVE_RUN")")
936
- fi
937
-
938
- if acquire_lock; then
939
- trap release_lock EXIT INT TERM
940
- [ -n "$EVENT_JSON" ] && printf '%s\\n' "$EVENT_JSON" >> "$OBS_FILE" 2>/dev/null
941
- [ -n "$ACTIVITY_JSON" ] && printf '%s\\n' "$ACTIVITY_JSON" >> "$ACTIVITY_FILE" 2>/dev/null
942
- rotate_file "$OBS_FILE" 4000
943
- rotate_file "$ACTIVITY_FILE" 3000
944
- release_lock
945
- trap - EXIT INT TERM
946
- fi
947
-
948
- sync_run_artifacts
949
-
950
696
  exit 0
951
697
  `;
952
698
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cclaw-cli",
3
- "version": "0.46.5",
3
+ "version": "0.46.6",
4
4
  "description": "Installer-first flow toolkit for coding agents",
5
5
  "type": "module",
6
6
  "bin": {