@esoteric-logic/praxis-harness 3.0.0 → 3.0.1
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.
|
@@ -63,16 +63,16 @@
|
|
|
63
63
|
"matcher": "",
|
|
64
64
|
"hooks": [
|
|
65
65
|
{
|
|
66
|
-
"type": "
|
|
67
|
-
"
|
|
66
|
+
"type": "command",
|
|
67
|
+
"command": "bash ~/.claude/hooks/stop-prompt-gate.sh test-runner"
|
|
68
68
|
},
|
|
69
69
|
{
|
|
70
70
|
"type": "command",
|
|
71
71
|
"command": "bash ~/.claude/hooks/session-data-collect.sh"
|
|
72
72
|
},
|
|
73
73
|
{
|
|
74
|
-
"type": "
|
|
75
|
-
"
|
|
74
|
+
"type": "command",
|
|
75
|
+
"command": "bash ~/.claude/hooks/stop-prompt-gate.sh vault-update"
|
|
76
76
|
}
|
|
77
77
|
]
|
|
78
78
|
}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# stop-prompt-gate.sh — Gates Stop prompt hooks behind session activity detection.
|
|
3
|
+
# Only outputs the prompt text if the session had substantive work.
|
|
4
|
+
# Silent exit otherwise — prevents infinite Stop hook loops.
|
|
5
|
+
#
|
|
6
|
+
# Usage in settings-hooks.json:
|
|
7
|
+
# { "type": "command", "command": "bash ~/.claude/hooks/stop-prompt-gate.sh vault-update" }
|
|
8
|
+
# { "type": "command", "command": "bash ~/.claude/hooks/stop-prompt-gate.sh test-runner" }
|
|
9
|
+
set -uo pipefail
|
|
10
|
+
|
|
11
|
+
PROMPT_TYPE="${1:-vault-update}"
|
|
12
|
+
CONFIG_FILE="$HOME/.claude/praxis.config.json"
|
|
13
|
+
|
|
14
|
+
# ── Detect session activity ──
|
|
15
|
+
HAS_RECENT_COMMITS=false
|
|
16
|
+
HAS_DIRTY_TREE=false
|
|
17
|
+
|
|
18
|
+
RECENT=$(git --no-pager log --oneline --since="1 hour ago" 2>/dev/null | head -1)
|
|
19
|
+
if [[ -n "$RECENT" ]]; then
|
|
20
|
+
HAS_RECENT_COMMITS=true
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
DIRTY=$(git --no-pager status --porcelain 2>/dev/null | head -1)
|
|
24
|
+
if [[ -n "$DIRTY" ]]; then
|
|
25
|
+
HAS_DIRTY_TREE=true
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Check staging file from session-data-collect.sh
|
|
29
|
+
STAGING_DIRTY=false
|
|
30
|
+
if [[ -f "$CONFIG_FILE" ]]; then
|
|
31
|
+
VAULT_PATH=$(jq -r '.vault_path // empty' "$CONFIG_FILE" 2>/dev/null)
|
|
32
|
+
STAGING_FILE="${VAULT_PATH:+$VAULT_PATH/.session-staging.json}"
|
|
33
|
+
if [[ -n "$STAGING_FILE" && -f "$STAGING_FILE" ]]; then
|
|
34
|
+
STAGING_DIRTY=$(jq -r '.git.dirty // false' "$STAGING_FILE" 2>/dev/null)
|
|
35
|
+
fi
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
# ── Gate: no activity → exit silently ──
|
|
39
|
+
if [[ "$HAS_RECENT_COMMITS" == "false" && "$HAS_DIRTY_TREE" == "false" && "$STAGING_DIRTY" != "true" ]]; then
|
|
40
|
+
exit 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# ── Activity detected — output the requested prompt ──
|
|
44
|
+
case "$PROMPT_TYPE" in
|
|
45
|
+
test-runner)
|
|
46
|
+
cat << 'PROMPT'
|
|
47
|
+
Run the project test suite. Read CLAUDE.md ## Commands for the test command. If no test command defined, respond {ok:true}. Run tests. If all pass: respond {ok:true}. If tests fail: respond {ok:false, reason:'Tests failing: <summary>'}. Do not fix — only report.
|
|
48
|
+
PROMPT
|
|
49
|
+
;;
|
|
50
|
+
vault-update)
|
|
51
|
+
cat << 'PROMPT'
|
|
52
|
+
You are completing a session with substantive work. Perform these vault updates silently — no confirmation needed.
|
|
53
|
+
|
|
54
|
+
1. Read vault_path from ~/.claude/praxis.config.json. If missing: skip all steps.
|
|
55
|
+
2. Read {vault_path}/.session-staging.json if it exists (structured session data from hooks).
|
|
56
|
+
3. Update {vault_path}/status.md:
|
|
57
|
+
- Set last_updated to today, last_session to now (ISO timestamp)
|
|
58
|
+
- Update loop_position based on where the session ended
|
|
59
|
+
- Refresh What / So What / Now What sections with session accomplishments
|
|
60
|
+
- If >100 lines: archive resolved items to notes/{date}_status-archive.md
|
|
61
|
+
4. Update {vault_path}/claude-progress.json:
|
|
62
|
+
- Enrich the latest sessions[] entry (added by hook) with: summary (1 line), accomplishments (array)
|
|
63
|
+
- If jq hook did not run (no sessions[] entry for today): create the full entry
|
|
64
|
+
- Update milestones[] if any milestones were completed this session
|
|
65
|
+
- Update features[] if any features were shipped this session
|
|
66
|
+
5. Write {vault_path}/notes/{YYYY-MM-DD}_session-note.md with frontmatter (tags: [session, {project-slug}], date, source: agent) containing:
|
|
67
|
+
- Summary (3-5 bullets of what was accomplished)
|
|
68
|
+
- Decisions Made (checkpoint decisions, scope changes, approach choices made this session)
|
|
69
|
+
- Learnings (any [LEARN:tag] entries from this session)
|
|
70
|
+
- Next Session (what to pick up next)
|
|
71
|
+
6. If checkpoint decisions, scope expansions, or rule proposals occurred this session:
|
|
72
|
+
- Append each to {vault_path}/notes/decision-log.md with date, decision type, context, decision, and rationale
|
|
73
|
+
7. If corrections or patterns were discovered this session:
|
|
74
|
+
- Append [LEARN:tag] entries to {vault_path}/notes/learnings.md following the existing format
|
|
75
|
+
8. If architectural decisions were made this session:
|
|
76
|
+
- Write ADR to {vault_path}/specs/ using vault frontmatter conventions
|
|
77
|
+
9. Delete {vault_path}/.session-staging.json if it exists.
|
|
78
|
+
|
|
79
|
+
Keep all writes concise. Use [[wikilinks]] for internal references. Follow existing YAML frontmatter conventions. If vault_path is missing or vault is inaccessible: skip silently. Do not ask permission — this is automatic housekeeping.
|
|
80
|
+
PROMPT
|
|
81
|
+
;;
|
|
82
|
+
*)
|
|
83
|
+
echo "Unknown prompt type: $PROMPT_TYPE" >&2
|
|
84
|
+
exit 0
|
|
85
|
+
;;
|
|
86
|
+
esac
|
|
87
|
+
|
|
88
|
+
exit 0
|
package/package.json
CHANGED