xtrm-tools 2.1.30 → 2.3.0
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 +13 -6
- package/cli/dist/index.cjs +1003 -917
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/config/hooks.json +7 -5
- package/config/pi/extensions/beads.ts +47 -16
- package/config/pi/extensions/core/adapter.ts +19 -0
- package/config/pi/extensions/custom-footer.ts +20 -13
- package/config/pi/extensions/main-guard.ts +3 -3
- package/config/pi/extensions/service-skills.ts +16 -40
- package/config/pi/extensions/xtrm-loader.ts +4 -4
- package/config/pi/install-schema.json +2 -1
- package/hooks/beads-claim-sync.mjs +39 -22
- package/hooks/beads-commit-gate.mjs +5 -3
- package/hooks/beads-edit-gate.mjs +6 -6
- package/hooks/beads-gate-messages.mjs +21 -17
- package/hooks/branch-state.mjs +51 -0
- package/hooks/main-guard-post-push.mjs +9 -7
- package/hooks/main-guard.mjs +6 -4
- package/package.json +1 -1
- package/project-skills/tdd-guard/.claude/skills/using-tdd-guard/SKILL.md +5 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// branch-state.mjs — UserPromptSubmit hook
|
|
3
|
+
// Re-injects current git branch and active beads claim at each prompt.
|
|
4
|
+
// Keeps the agent oriented after /compact or long sessions.
|
|
5
|
+
// Output: { hookSpecificOutput: { additionalSystemPrompt } }
|
|
6
|
+
|
|
7
|
+
import { execSync } from 'node:child_process';
|
|
8
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
9
|
+
import { join } from 'node:path';
|
|
10
|
+
|
|
11
|
+
function readInput() {
|
|
12
|
+
try { return JSON.parse(readFileSync(0, 'utf-8')); } catch { return null; }
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function getBranch(cwd) {
|
|
16
|
+
try {
|
|
17
|
+
return execSync('git branch --show-current', {
|
|
18
|
+
encoding: 'utf8', cwd,
|
|
19
|
+
stdio: ['pipe', 'pipe', 'pipe'], timeout: 3000,
|
|
20
|
+
}).trim() || null;
|
|
21
|
+
} catch { return null; }
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function getSessionClaim(sessionId, cwd) {
|
|
25
|
+
try {
|
|
26
|
+
const out = execSync(`bd kv get "claimed:${sessionId}"`, {
|
|
27
|
+
encoding: 'utf8', cwd,
|
|
28
|
+
stdio: ['pipe', 'pipe', 'pipe'], timeout: 3000,
|
|
29
|
+
}).trim();
|
|
30
|
+
return out || null;
|
|
31
|
+
} catch { return null; }
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const input = readInput();
|
|
35
|
+
if (!input) process.exit(0);
|
|
36
|
+
|
|
37
|
+
const cwd = input.cwd || process.cwd();
|
|
38
|
+
const sessionId = input.session_id ?? input.sessionId;
|
|
39
|
+
const branch = getBranch(cwd);
|
|
40
|
+
const isBeads = existsSync(join(cwd, '.beads'));
|
|
41
|
+
const claim = isBeads && sessionId ? getSessionClaim(sessionId, cwd) : null;
|
|
42
|
+
|
|
43
|
+
if (!branch && !claim) process.exit(0);
|
|
44
|
+
|
|
45
|
+
const context = `[Context: branch=${branch ?? 'unknown'}${claim ? ', claim=' + claim : ''}]`;
|
|
46
|
+
|
|
47
|
+
process.stdout.write(JSON.stringify({
|
|
48
|
+
hookSpecificOutput: { additionalSystemPrompt: context },
|
|
49
|
+
}));
|
|
50
|
+
process.stdout.write('\n');
|
|
51
|
+
process.exit(0);
|
|
@@ -59,11 +59,13 @@ const explicitlyProtectedTarget = protectedBranches
|
|
|
59
59
|
.some((b) => lastToken === b || lastToken.endsWith(`:${b}`));
|
|
60
60
|
if (explicitlyProtectedTarget) process.exit(0);
|
|
61
61
|
|
|
62
|
-
process.stdout.write(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
)
|
|
62
|
+
process.stdout.write(JSON.stringify({
|
|
63
|
+
additionalContext:
|
|
64
|
+
`✅ Pushed '${branch}'. Next steps:\n` +
|
|
65
|
+
' 1. gh pr create --fill\n' +
|
|
66
|
+
' 2. gh pr merge --squash\n' +
|
|
67
|
+
' 3. git checkout main && git reset --hard origin/main\n' +
|
|
68
|
+
'Ensure beads state is updated (e.g. bd close <id>).',
|
|
69
|
+
}));
|
|
70
|
+
process.stdout.write('\n');
|
|
69
71
|
process.exit(0);
|
package/hooks/main-guard.mjs
CHANGED
|
@@ -37,10 +37,11 @@ const hookEventName = input.hook_event_name ?? 'PreToolUse';
|
|
|
37
37
|
|
|
38
38
|
function deny(reason) {
|
|
39
39
|
process.stdout.write(JSON.stringify({
|
|
40
|
-
|
|
40
|
+
decision: 'block',
|
|
41
|
+
reason,
|
|
41
42
|
}));
|
|
42
43
|
process.stdout.write('\n');
|
|
43
|
-
process.exit(
|
|
44
|
+
process.exit(0);
|
|
44
45
|
}
|
|
45
46
|
|
|
46
47
|
const WRITE_TOOLS = new Set([
|
|
@@ -55,8 +56,9 @@ const WRITE_TOOLS = new Set([
|
|
|
55
56
|
]);
|
|
56
57
|
|
|
57
58
|
if (WRITE_TOOLS.has(tool)) {
|
|
58
|
-
deny(`⛔ On '${branch}' —
|
|
59
|
-
+ ' git checkout -b feature/<name>\n'
|
|
59
|
+
deny(`⛔ On '${branch}' — start on a feature branch and claim an issue.\n`
|
|
60
|
+
+ ' git checkout -b feature/<name>\n'
|
|
61
|
+
+ ' bd update <id> --claim\n');
|
|
60
62
|
}
|
|
61
63
|
|
|
62
64
|
const WORKFLOW =
|
package/package.json
CHANGED
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: using-tdd-guard
|
|
3
|
+
description: TDD Guard enforces Test-Driven Development workflow in Claude Code. Blocks implementation code until failing tests are written.
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Using TDD Guard
|
|
2
7
|
|
|
3
8
|
**TDD Guard** enforces Test-Driven Development workflow in Claude Code. It blocks implementation code until failing tests are written.
|