company-skill 2.2.0 → 2.2.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.
- package/hooks/stop-guard.js +9 -35
- package/package.json +1 -1
package/hooks/stop-guard.js
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Stop Hook Guard for /company skill.
|
|
5
|
-
* Blocks Claude from stopping until ALL criteria in criteria.json pass.
|
|
6
|
-
* Stolen from oh-my-claudecode's persistent-mode pattern.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
3
|
const fs = require('fs');
|
|
10
4
|
const path = require('path');
|
|
11
5
|
|
|
@@ -13,49 +7,36 @@ const criteriaPath = path.join(process.cwd(), '.company', 'criteria.json');
|
|
|
13
7
|
const goalPath = path.join(process.cwd(), '.company', 'GOAL.md');
|
|
14
8
|
const cancelPath = path.join(process.cwd(), '.company', 'CANCEL');
|
|
15
9
|
|
|
16
|
-
// No company running, allow stop
|
|
17
10
|
if (!fs.existsSync(goalPath) && !fs.existsSync(criteriaPath)) {
|
|
18
11
|
process.exit(0);
|
|
19
12
|
}
|
|
20
13
|
|
|
21
|
-
// Cancel signal, allow stop
|
|
22
14
|
if (fs.existsSync(cancelPath)) {
|
|
23
15
|
try { fs.unlinkSync(cancelPath); } catch (e) {}
|
|
24
16
|
process.exit(0);
|
|
25
17
|
}
|
|
26
18
|
|
|
27
|
-
// Check criteria.json
|
|
28
19
|
if (fs.existsSync(criteriaPath)) {
|
|
29
20
|
try {
|
|
30
21
|
const data = JSON.parse(fs.readFileSync(criteriaPath, 'utf8'));
|
|
31
22
|
const all = data.criteria || [];
|
|
32
|
-
const passing = all.filter(c => c.passes === true && c.evidence);
|
|
33
23
|
const failing = all.filter(c => !c.passes || !c.evidence);
|
|
34
24
|
|
|
35
25
|
if (all.length > 0 && failing.length === 0) {
|
|
36
|
-
// All criteria pass, allow stop
|
|
37
26
|
process.exit(0);
|
|
38
27
|
}
|
|
39
28
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
hookSpecificOutput: {
|
|
46
|
-
hookEventName: "Stop",
|
|
47
|
-
additionalContext: `COMPANY GOAL NOT ACHIEVED. ${failing.length} of ${all.length} criteria still failing:\n${failList}\n\nContinue the THINK > EXECUTE > VERIFY cycle. Read .company/criteria.json and the latest cycle briefing.`
|
|
48
|
-
}
|
|
49
|
-
};
|
|
50
|
-
console.log(JSON.stringify(output));
|
|
29
|
+
const failList = failing.map(c => c.description).join(', ');
|
|
30
|
+
console.log(JSON.stringify({
|
|
31
|
+
decision: "block",
|
|
32
|
+
reason: failing.length + "/" + all.length + " criteria not met: " + failList
|
|
33
|
+
}));
|
|
51
34
|
process.exit(0);
|
|
52
35
|
} catch (e) {
|
|
53
|
-
// criteria.json malformed, allow stop to prevent deadlock
|
|
54
36
|
process.exit(0);
|
|
55
37
|
}
|
|
56
38
|
}
|
|
57
39
|
|
|
58
|
-
// No criteria.json but goal exists, check STATUS.md
|
|
59
40
|
const statusPath = path.join(process.cwd(), '.company', 'STATUS.md');
|
|
60
41
|
if (fs.existsSync(statusPath)) {
|
|
61
42
|
const status = fs.readFileSync(statusPath, 'utf8');
|
|
@@ -64,14 +45,7 @@ if (fs.existsSync(statusPath)) {
|
|
|
64
45
|
}
|
|
65
46
|
}
|
|
66
47
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
stopReason: "Company goal not yet achieved.",
|
|
72
|
-
hookSpecificOutput: {
|
|
73
|
-
hookEventName: "Stop",
|
|
74
|
-
additionalContext: `Goal not achieved. Continue cycles.\n\n${goal}`
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
console.log(JSON.stringify(output));
|
|
48
|
+
console.log(JSON.stringify({
|
|
49
|
+
decision: "block",
|
|
50
|
+
reason: "Company goal not yet achieved. Continue cycles."
|
|
51
|
+
}));
|