@paths.design/caws-cli 11.1.5 → 11.1.7
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.
- package/README.md +1 -1
- package/dist/init/hook-packs/manifest-claude-code.d.ts +1 -1
- package/dist/init/hook-packs/manifest-claude-code.d.ts.map +1 -1
- package/dist/init/hook-packs/manifest-claude-code.js +59 -6
- package/dist/init/hook-packs/manifest-claude-code.js.map +1 -1
- package/dist/init/hook-packs/types.js +1 -1
- package/dist/init/hook-packs/types.js.map +1 -1
- package/dist/shell/commands/agents.d.ts +49 -0
- package/dist/shell/commands/agents.d.ts.map +1 -0
- package/dist/shell/commands/agents.js +577 -0
- package/dist/shell/commands/agents.js.map +1 -0
- package/dist/shell/commands/claim.d.ts.map +1 -1
- package/dist/shell/commands/claim.js +3 -4
- package/dist/shell/commands/claim.js.map +1 -1
- package/dist/shell/commands/status.d.ts +12 -0
- package/dist/shell/commands/status.d.ts.map +1 -1
- package/dist/shell/commands/status.js +236 -21
- package/dist/shell/commands/status.js.map +1 -1
- package/dist/shell/commands/worktree.d.ts +9 -0
- package/dist/shell/commands/worktree.d.ts.map +1 -1
- package/dist/shell/commands/worktree.js +302 -0
- package/dist/shell/commands/worktree.js.map +1 -1
- package/dist/shell/index.d.ts +4 -2
- package/dist/shell/index.d.ts.map +1 -1
- package/dist/shell/index.js +12 -1
- package/dist/shell/index.js.map +1 -1
- package/dist/shell/register.d.ts.map +1 -1
- package/dist/shell/register.js +150 -0
- package/dist/shell/register.js.map +1 -1
- package/dist/shell/render/status.d.ts +7 -1
- package/dist/shell/render/status.d.ts.map +1 -1
- package/dist/shell/render/status.js +72 -0
- package/dist/shell/render/status.js.map +1 -1
- package/dist/store/agents-store.d.ts.map +1 -1
- package/dist/store/agents-store.js +9 -0
- package/dist/store/agents-store.js.map +1 -1
- package/dist/store/apply-patch.d.ts.map +1 -1
- package/dist/store/apply-patch.js +15 -0
- package/dist/store/apply-patch.js.map +1 -1
- package/dist/store/doctor-snapshot.d.ts.map +1 -1
- package/dist/store/doctor-snapshot.js +143 -3
- package/dist/store/doctor-snapshot.js.map +1 -1
- package/dist/store/git-sparse-checkout.d.ts +25 -0
- package/dist/store/git-sparse-checkout.d.ts.map +1 -0
- package/dist/store/git-sparse-checkout.js +101 -0
- package/dist/store/git-sparse-checkout.js.map +1 -0
- package/dist/store/index.d.ts +2 -0
- package/dist/store/index.d.ts.map +1 -1
- package/dist/store/index.js +10 -1
- package/dist/store/index.js.map +1 -1
- package/dist/store/leases-store.d.ts +89 -0
- package/dist/store/leases-store.d.ts.map +1 -0
- package/dist/store/leases-store.js +369 -0
- package/dist/store/leases-store.js.map +1 -0
- package/dist/store/lifecycle-transaction.d.ts.map +1 -1
- package/dist/store/lifecycle-transaction.js +34 -1
- package/dist/store/lifecycle-transaction.js.map +1 -1
- package/dist/store/rules.d.ts +21 -1
- package/dist/store/rules.d.ts.map +1 -1
- package/dist/store/rules.js +22 -0
- package/dist/store/rules.js.map +1 -1
- package/dist/store/types.d.ts +25 -1
- package/dist/store/types.d.ts.map +1 -1
- package/dist/store/worktrees-migration.d.ts +141 -0
- package/dist/store/worktrees-migration.d.ts.map +1 -0
- package/dist/store/worktrees-migration.js +356 -0
- package/dist/store/worktrees-migration.js.map +1 -0
- package/dist/store/worktrees-writer.d.ts.map +1 -1
- package/dist/store/worktrees-writer.js +37 -1
- package/dist/store/worktrees-writer.js.map +1 -1
- package/package.json +2 -2
- package/templates/hook-packs/claude-code/CLAUDE.md +5 -5
- package/templates/hook-packs/claude-code/agent-heartbeat.sh +131 -0
- package/templates/hook-packs/claude-code/agent-register.sh +62 -0
- package/templates/hook-packs/claude-code/agent-stop.sh +51 -0
- package/templates/hook-packs/claude-code/audit.sh +1 -1
- package/templates/hook-packs/claude-code/block-dangerous.sh +1 -1
- package/templates/hook-packs/claude-code/classify_command.py +454 -12
- package/templates/hook-packs/claude-code/dispatch/post_tool_use.sh +1 -1
- package/templates/hook-packs/claude-code/dispatch/pre_tool_use.sh +11 -2
- package/templates/hook-packs/claude-code/dispatch/session_start.sh +6 -2
- package/templates/hook-packs/claude-code/dispatch/stop.sh +7 -2
- package/templates/hook-packs/claude-code/guard-strikes.sh +1 -1
- package/templates/hook-packs/claude-code/lib/parse-input.sh +1 -1
- package/templates/hook-packs/claude-code/lib/run-handlers.sh +1 -1
- package/templates/hook-packs/claude-code/reset-danger-latch.sh +1 -1
- package/templates/hook-packs/claude-code/reset-strikes.sh +1 -1
- package/templates/hook-packs/claude-code/runtime-paths.sh +1 -1
- package/templates/hook-packs/claude-code/scope-guard.sh +1 -1
- package/templates/hook-packs/claude-code/session-caws-status.sh +7 -1
- package/templates/hook-packs/claude-code/session-log.sh +1 -1
- package/templates/hook-packs/claude-code/worktree-guard.sh +130 -4
- package/templates/hook-packs/claude-code/worktree-write-guard.sh +133 -18
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# CAWS-MANAGED-HOOK
|
|
3
|
+
# hook_pack: claude-code
|
|
4
|
+
# hook_pack_version: 5
|
|
5
|
+
# caws_min_major: 11
|
|
6
|
+
# lineage_refs: 19
|
|
7
|
+
# do_not_edit_directly: update via `caws init --agent-surface claude-code`
|
|
8
|
+
#
|
|
9
|
+
# PreToolUse handler — heartbeats the current session's lease and surfaces
|
|
10
|
+
# parallel-agent presence to the calling agent
|
|
11
|
+
# (MULTI-AGENT-ACTIVITY-REGISTRY-001).
|
|
12
|
+
#
|
|
13
|
+
# Sourcing: invoked by dispatch/pre_tool_use.sh (FIRST in the handler
|
|
14
|
+
# list) after parse-input.sh has populated HOOK_SESSION_ID. The dispatcher
|
|
15
|
+
# runs with --short-circuit-on-block; this handler must never block.
|
|
16
|
+
#
|
|
17
|
+
# Behavior:
|
|
18
|
+
# - Refuses on empty/unknown HOOK_SESSION_ID.
|
|
19
|
+
# - Invokes `caws agents heartbeat --session-id <id> --platform claude-code
|
|
20
|
+
# --throttle 30000 --reason pre_tool_use --json --include-active-summary`.
|
|
21
|
+
# - Parses CAWS-native JSON. When active_agent_count > 1, wraps the
|
|
22
|
+
# active_agents list into Claude Code's hookSpecificOutput.
|
|
23
|
+
# additionalContext envelope and emits it on stdout. When the count
|
|
24
|
+
# is 1 (self only), emits nothing — silent in the common case.
|
|
25
|
+
# - Throttled invocations still return an active_agents summary, so
|
|
26
|
+
# parallel-presence surfacing fires every tool call even when the
|
|
27
|
+
# write was skipped.
|
|
28
|
+
#
|
|
29
|
+
# IO BOUNDARY: this script is the ONLY surface that emits Claude Code's
|
|
30
|
+
# hookSpecificOutput.additionalContext envelope for lease state. The CLI
|
|
31
|
+
# emits CAWS-native JSON only. A Cursor or terminal integration would
|
|
32
|
+
# rewrite this script to emit its own protocol-specific output while
|
|
33
|
+
# reusing the same `caws agents heartbeat --json --include-active-summary`
|
|
34
|
+
# command verbatim.
|
|
35
|
+
#
|
|
36
|
+
# RUNTIME DEPENDENCIES: bash + node. node is already required by the CAWS
|
|
37
|
+
# CLI itself (which is a Node binary), so depending on it here adds no new
|
|
38
|
+
# runtime surface area. We do NOT depend on jq — jq is not guaranteed
|
|
39
|
+
# present on every install target (it is absent from many container base
|
|
40
|
+
# images and minimal CI runners), and a missing jq would silently drop
|
|
41
|
+
# every parallel-agent notice. The product goal is "agents see each
|
|
42
|
+
# other": that visibility cannot depend on a shell utility outside the
|
|
43
|
+
# CAWS toolchain.
|
|
44
|
+
#
|
|
45
|
+
# FAIL-CLOSED-NON-BLOCKING: if the CLI is absent, fails, or returns
|
|
46
|
+
# malformed JSON, this hook exits 0 silently. Heartbeat is observability
|
|
47
|
+
# and parallel-agent surfacing; a failure must never block the tool call.
|
|
48
|
+
|
|
49
|
+
set -uo pipefail
|
|
50
|
+
|
|
51
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
52
|
+
|
|
53
|
+
# shellcheck source=lib/parse-input.sh
|
|
54
|
+
source "$SCRIPT_DIR/lib/parse-input.sh" 2>/dev/null || exit 0
|
|
55
|
+
parse_hook_input || exit 0
|
|
56
|
+
|
|
57
|
+
if [[ -z "${HOOK_SESSION_ID:-}" || "$HOOK_SESSION_ID" == "unknown" ]]; then
|
|
58
|
+
exit 0
|
|
59
|
+
fi
|
|
60
|
+
|
|
61
|
+
CAWS_BIN="${CAWS_BIN:-caws}"
|
|
62
|
+
if ! command -v "$CAWS_BIN" >/dev/null 2>&1; then
|
|
63
|
+
exit 0
|
|
64
|
+
fi
|
|
65
|
+
|
|
66
|
+
# Capture both stdout (JSON) and stderr (diagnostics). On any CLI error,
|
|
67
|
+
# fall through to silent exit.
|
|
68
|
+
CLI_OUT="$(
|
|
69
|
+
"$CAWS_BIN" agents heartbeat \
|
|
70
|
+
--session-id "$HOOK_SESSION_ID" \
|
|
71
|
+
--platform claude-code \
|
|
72
|
+
--throttle 30000 \
|
|
73
|
+
--reason pre_tool_use \
|
|
74
|
+
--json \
|
|
75
|
+
--include-active-summary \
|
|
76
|
+
2>/dev/null
|
|
77
|
+
)" || exit 0
|
|
78
|
+
|
|
79
|
+
if [[ -z "$CLI_OUT" ]]; then
|
|
80
|
+
exit 0
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
# Parse the CAWS-native JSON and, when active_agent_count > 1, compose
|
|
84
|
+
# Claude Code's hookSpecificOutput.additionalContext envelope. A single
|
|
85
|
+
# node invocation does the whole pipeline: parse → filter peers → format
|
|
86
|
+
# bullet list → wrap envelope → emit. Malformed input, parse errors, or
|
|
87
|
+
# any thrown exception fall through to silent exit (fail-closed-non-
|
|
88
|
+
# blocking). Node is already a hard CAWS dependency — the CLI binary
|
|
89
|
+
# IS node — so this adds no new runtime surface vs. jq.
|
|
90
|
+
printf '%s' "$CLI_OUT" | node -e '
|
|
91
|
+
let raw = "";
|
|
92
|
+
process.stdin.setEncoding("utf8");
|
|
93
|
+
process.stdin.on("data", (chunk) => { raw += chunk; });
|
|
94
|
+
process.stdin.on("end", () => {
|
|
95
|
+
let parsed;
|
|
96
|
+
try { parsed = JSON.parse(raw); } catch { process.exit(0); }
|
|
97
|
+
const count = Number(parsed && parsed.active_agent_count);
|
|
98
|
+
if (!Number.isFinite(count) || count <= 1) process.exit(0);
|
|
99
|
+
const agents = Array.isArray(parsed.active_agents) ? parsed.active_agents : [];
|
|
100
|
+
const peers = agents.filter((a) => a && a.is_self !== true);
|
|
101
|
+
if (peers.length === 0) process.exit(0);
|
|
102
|
+
const bullets = peers.map((a) => {
|
|
103
|
+
const worktree = a.bound_worktree || "no worktree";
|
|
104
|
+
const spec = a.bound_spec_id ? " — spec " + a.bound_spec_id : "";
|
|
105
|
+
const kind = a.git_dir_kind || "unknown";
|
|
106
|
+
const branch = a.branch || "-";
|
|
107
|
+
const ageMs = Number(a.last_active_age_ms);
|
|
108
|
+
const ageSec = Number.isFinite(ageMs) ? Math.floor(ageMs / 1000) : 0;
|
|
109
|
+
return "• " + (a.session_id || "<unknown>") +
|
|
110
|
+
" (" + worktree + ")" + spec +
|
|
111
|
+
" — git_dir_kind=" + kind +
|
|
112
|
+
" — branch=" + branch +
|
|
113
|
+
" — last active " + ageSec + "s ago";
|
|
114
|
+
}).join("\n");
|
|
115
|
+
const ctx = "MULTI-AGENT NOTICE: " + count +
|
|
116
|
+
" agents active in this repo (including this session). Other active sessions:\n" +
|
|
117
|
+
bullets + "\n\n" +
|
|
118
|
+
"Coordinate via '\''caws agents list'\'' and '\''caws status'\'' before " +
|
|
119
|
+
"mutating shared state. Authority remains in .caws/worktrees.json " +
|
|
120
|
+
"(ownership) and .caws/specs/<id>.yaml (scope) — leases are " +
|
|
121
|
+
"visibility only.";
|
|
122
|
+
process.stdout.write(JSON.stringify({
|
|
123
|
+
hookSpecificOutput: {
|
|
124
|
+
hookEventName: "PreToolUse",
|
|
125
|
+
additionalContext: ctx,
|
|
126
|
+
},
|
|
127
|
+
}));
|
|
128
|
+
});
|
|
129
|
+
' 2>/dev/null || exit 0
|
|
130
|
+
|
|
131
|
+
exit 0
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# CAWS-MANAGED-HOOK
|
|
3
|
+
# hook_pack: claude-code
|
|
4
|
+
# hook_pack_version: 5
|
|
5
|
+
# caws_min_major: 11
|
|
6
|
+
# lineage_refs: 19
|
|
7
|
+
# do_not_edit_directly: update via `caws init --agent-surface claude-code`
|
|
8
|
+
#
|
|
9
|
+
# SessionStart handler — agent self-registration into the .caws/leases/
|
|
10
|
+
# liveness substrate (MULTI-AGENT-ACTIVITY-REGISTRY-001).
|
|
11
|
+
#
|
|
12
|
+
# Sourcing: invoked by dispatch/session_start.sh after parse-input.sh has
|
|
13
|
+
# populated HOOK_SESSION_ID. Reads HOOK_INPUT_JSON from stdin (unused for
|
|
14
|
+
# this handler beyond the parse-input contract).
|
|
15
|
+
#
|
|
16
|
+
# Behavior:
|
|
17
|
+
# - Refuses to run when HOOK_SESSION_ID is empty or "unknown" (the
|
|
18
|
+
# parse-input.sh fallback). A lease whose filename is "unknown.json"
|
|
19
|
+
# would collide across every session that hits the same fallback.
|
|
20
|
+
# - Invokes `caws agents register --session-id <id> --platform claude-code
|
|
21
|
+
# --reason session_start` to write the lease through the CLI.
|
|
22
|
+
# - Non-blocking. Any failure of the CLI surfaces as stderr only;
|
|
23
|
+
# SessionStart never fails on hook errors.
|
|
24
|
+
#
|
|
25
|
+
# IO boundary: this script is the only place that knows about Claude Code's
|
|
26
|
+
# SessionStart payload. The CLI receives explicit flags and returns
|
|
27
|
+
# CAWS-native JSON. The hook script does not produce additionalContext
|
|
28
|
+
# at SessionStart — the parallel-agent surfacing happens at PreToolUse
|
|
29
|
+
# via agent-heartbeat.sh.
|
|
30
|
+
|
|
31
|
+
set -uo pipefail
|
|
32
|
+
|
|
33
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
34
|
+
|
|
35
|
+
# shellcheck source=lib/parse-input.sh
|
|
36
|
+
source "$SCRIPT_DIR/lib/parse-input.sh" 2>/dev/null || exit 0
|
|
37
|
+
parse_hook_input || exit 0
|
|
38
|
+
|
|
39
|
+
# Refuse on empty/unknown session id. Writing a lease at "unknown.json"
|
|
40
|
+
# would collide across every session that hits the parse-input fallback.
|
|
41
|
+
if [[ -z "${HOOK_SESSION_ID:-}" || "$HOOK_SESSION_ID" == "unknown" ]]; then
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Locate caws binary. Prefer a project-local install (consistent with the
|
|
46
|
+
# repo's installed CLI version); fall back to PATH.
|
|
47
|
+
CAWS_BIN="${CAWS_BIN:-caws}"
|
|
48
|
+
if ! command -v "$CAWS_BIN" >/dev/null 2>&1; then
|
|
49
|
+
# No CAWS binary on PATH — silent skip. Liveness is best-effort.
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Invoke register. Send stderr to a buffer; we may want to attribute it
|
|
54
|
+
# in dispatcher output (prefixed by run-handlers).
|
|
55
|
+
"$CAWS_BIN" agents register \
|
|
56
|
+
--session-id "$HOOK_SESSION_ID" \
|
|
57
|
+
--platform claude-code \
|
|
58
|
+
--reason session_start \
|
|
59
|
+
>/dev/null 2>&1 || true
|
|
60
|
+
|
|
61
|
+
# Never block SessionStart.
|
|
62
|
+
exit 0
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# CAWS-MANAGED-HOOK
|
|
3
|
+
# hook_pack: claude-code
|
|
4
|
+
# hook_pack_version: 5
|
|
5
|
+
# caws_min_major: 11
|
|
6
|
+
# lineage_refs: 19
|
|
7
|
+
# do_not_edit_directly: update via `caws init --agent-surface claude-code`
|
|
8
|
+
#
|
|
9
|
+
# Stop handler — marks the current session's lease as stopped on clean
|
|
10
|
+
# session exit (MULTI-AGENT-ACTIVITY-REGISTRY-001).
|
|
11
|
+
#
|
|
12
|
+
# Sourcing: invoked by dispatch/stop.sh after parse-input.sh has populated
|
|
13
|
+
# HOOK_SESSION_ID.
|
|
14
|
+
#
|
|
15
|
+
# Behavior:
|
|
16
|
+
# - Refuses on empty/unknown HOOK_SESSION_ID.
|
|
17
|
+
# - Invokes `caws agents stop --session-id <id> --platform claude-code`
|
|
18
|
+
# which writes a mark_stopped LeasePatch (status: stopped, stopped_at
|
|
19
|
+
# timestamp). The lease file is preserved as evidence; hard deletion
|
|
20
|
+
# happens only via explicit `caws agents prune`.
|
|
21
|
+
# - Non-blocking. Stop semantics already require all handlers to be
|
|
22
|
+
# best-effort; a Stop failure is a warn, not a block.
|
|
23
|
+
#
|
|
24
|
+
# Note: Stop is NOT a guaranteed signal. A SIGKILL'd or crashed Claude
|
|
25
|
+
# Code session never reaches Stop. The primary liveness mechanism is
|
|
26
|
+
# heartbeat — Stop is the clean-exit optimization that lets observers
|
|
27
|
+
# distinguish "stopped cleanly" from "went stale and is presumed dead."
|
|
28
|
+
|
|
29
|
+
set -uo pipefail
|
|
30
|
+
|
|
31
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
32
|
+
|
|
33
|
+
# shellcheck source=lib/parse-input.sh
|
|
34
|
+
source "$SCRIPT_DIR/lib/parse-input.sh" 2>/dev/null || exit 0
|
|
35
|
+
parse_hook_input || exit 0
|
|
36
|
+
|
|
37
|
+
if [[ -z "${HOOK_SESSION_ID:-}" || "$HOOK_SESSION_ID" == "unknown" ]]; then
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
CAWS_BIN="${CAWS_BIN:-caws}"
|
|
42
|
+
if ! command -v "$CAWS_BIN" >/dev/null 2>&1; then
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
"$CAWS_BIN" agents stop \
|
|
47
|
+
--session-id "$HOOK_SESSION_ID" \
|
|
48
|
+
--platform claude-code \
|
|
49
|
+
>/dev/null 2>&1 || true
|
|
50
|
+
|
|
51
|
+
exit 0
|