company-skill 3.0.0 → 3.1.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/compiler-check.js +39 -0
- package/hooks/precompact.js +52 -16
- package/hooks/session-restore.js +19 -23
- package/hooks/stop-guard.js +1 -9
- package/package.json +1 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// PostToolUse on Edit/Write: run compiler/linter immediately after code changes.
|
|
4
|
+
// Catches errors before Claude moves on to the next task.
|
|
5
|
+
|
|
6
|
+
const fs = require('fs');
|
|
7
|
+
const path = require('path');
|
|
8
|
+
const { execSync } = require('child_process');
|
|
9
|
+
|
|
10
|
+
// Read tool input from stdin
|
|
11
|
+
let input = '';
|
|
12
|
+
try { input = fs.readFileSync('/dev/stdin', 'utf8'); } catch (e) {}
|
|
13
|
+
|
|
14
|
+
let filePath;
|
|
15
|
+
try {
|
|
16
|
+
const data = JSON.parse(input);
|
|
17
|
+
filePath = data.tool_response?.filePath || data.tool_input?.file_path;
|
|
18
|
+
} catch (e) {}
|
|
19
|
+
|
|
20
|
+
if (!filePath) process.exit(0);
|
|
21
|
+
|
|
22
|
+
const ext = path.extname(filePath);
|
|
23
|
+
let cmd = null;
|
|
24
|
+
|
|
25
|
+
if (['.ts', '.tsx'].includes(ext)) cmd = `npx tsc --noEmit "${filePath}" 2>&1 | head -5`;
|
|
26
|
+
else if (['.js', '.jsx'].includes(ext)) cmd = `node --check "${filePath}" 2>&1`;
|
|
27
|
+
else if (ext === '.py') cmd = `python3 -c "import py_compile; py_compile.compile('${filePath}', doraise=True)" 2>&1`;
|
|
28
|
+
else if (ext === '.json') cmd = `node -e "JSON.parse(require('fs').readFileSync('${filePath}','utf8'))" 2>&1`;
|
|
29
|
+
|
|
30
|
+
if (!cmd) process.exit(0);
|
|
31
|
+
|
|
32
|
+
try {
|
|
33
|
+
execSync(cmd, { timeout: 10000 });
|
|
34
|
+
} catch (e) {
|
|
35
|
+
const err = (e.stdout?.toString() || e.message).substring(0, 300);
|
|
36
|
+
console.log(JSON.stringify({
|
|
37
|
+
systemMessage: "Compile/syntax error in " + path.basename(filePath) + ": " + err
|
|
38
|
+
}));
|
|
39
|
+
}
|
package/hooks/precompact.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// Save company state before context compaction
|
|
3
|
+
// Save company state AND reasoning before context compaction.
|
|
4
|
+
// Saves both numbers (criteria, cycle) and intent (what we're trying and why).
|
|
4
5
|
|
|
5
6
|
const fs = require('fs');
|
|
6
7
|
const path = require('path');
|
|
@@ -8,39 +9,74 @@ const path = require('path');
|
|
|
8
9
|
const companyDir = path.join(process.cwd(), '.company');
|
|
9
10
|
if (!fs.existsSync(companyDir)) process.exit(0);
|
|
10
11
|
|
|
11
|
-
const
|
|
12
|
+
const lines = ['# Company Checkpoint (auto-saved before compaction)', ''];
|
|
12
13
|
|
|
13
|
-
//
|
|
14
|
+
// Goal
|
|
15
|
+
const goalPath = path.join(companyDir, 'GOAL.md');
|
|
16
|
+
if (fs.existsSync(goalPath)) {
|
|
17
|
+
lines.push('## Goal');
|
|
18
|
+
lines.push(fs.readFileSync(goalPath, 'utf8').substring(0, 500));
|
|
19
|
+
lines.push('');
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Cycle number
|
|
14
23
|
const cyclesDir = path.join(companyDir, 'cycles');
|
|
15
24
|
if (fs.existsSync(cyclesDir)) {
|
|
16
25
|
const files = fs.readdirSync(cyclesDir).filter(f => f.startsWith('cycle-'));
|
|
17
26
|
const nums = files.map(f => parseInt(f.match(/cycle-(\d+)/)?.[1] || '0'));
|
|
18
|
-
|
|
27
|
+
const cycle = Math.max(0, ...nums);
|
|
28
|
+
lines.push('## Cycle: ' + cycle);
|
|
29
|
+
lines.push('');
|
|
30
|
+
|
|
31
|
+
// Latest briefing (captures current reasoning/intent)
|
|
32
|
+
const briefing = path.join(cyclesDir, `cycle-${cycle}-briefing.md`);
|
|
33
|
+
if (fs.existsSync(briefing)) {
|
|
34
|
+
lines.push('## Current Reasoning');
|
|
35
|
+
lines.push(fs.readFileSync(briefing, 'utf8').substring(0, 1000));
|
|
36
|
+
lines.push('');
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Latest review (captures what's working/failing)
|
|
40
|
+
const review = path.join(cyclesDir, `cycle-${cycle}-review.md`);
|
|
41
|
+
if (fs.existsSync(review)) {
|
|
42
|
+
lines.push('## Latest Review');
|
|
43
|
+
lines.push(fs.readFileSync(review, 'utf8').substring(0, 500));
|
|
44
|
+
lines.push('');
|
|
45
|
+
}
|
|
19
46
|
}
|
|
20
47
|
|
|
21
|
-
//
|
|
48
|
+
// Criteria status
|
|
22
49
|
const criteriaPath = path.join(companyDir, 'criteria.json');
|
|
23
50
|
if (fs.existsSync(criteriaPath)) {
|
|
24
51
|
try {
|
|
25
52
|
const data = JSON.parse(fs.readFileSync(criteriaPath, 'utf8'));
|
|
26
53
|
const all = data.criteria || [];
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
54
|
+
lines.push('## Criteria: ' + all.filter(c => c.passes).length + '/' + all.length + ' passing');
|
|
55
|
+
for (const c of all) {
|
|
56
|
+
lines.push('- [' + (c.passes ? 'x' : ' ') + '] ' + c.description);
|
|
57
|
+
}
|
|
58
|
+
lines.push('');
|
|
31
59
|
} catch (e) {}
|
|
32
60
|
}
|
|
33
61
|
|
|
34
|
-
//
|
|
62
|
+
// Active roster
|
|
35
63
|
const rosterPath = path.join(companyDir, 'active-roster.md');
|
|
36
64
|
if (fs.existsSync(rosterPath)) {
|
|
37
|
-
|
|
65
|
+
lines.push('## Active Roster');
|
|
66
|
+
lines.push(fs.readFileSync(rosterPath, 'utf8').substring(0, 300));
|
|
67
|
+
lines.push('');
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Playbook (accumulated lessons)
|
|
71
|
+
const playbookPath = path.join(companyDir, 'playbook.md');
|
|
72
|
+
if (fs.existsSync(playbookPath)) {
|
|
73
|
+
lines.push('## Playbook (lessons)');
|
|
74
|
+
lines.push(fs.readFileSync(playbookPath, 'utf8').substring(0, 500));
|
|
75
|
+
lines.push('');
|
|
38
76
|
}
|
|
39
77
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
path.join(companyDir, '.checkpoint.json'),
|
|
43
|
-
JSON.stringify(checkpoint, null, 2)
|
|
44
|
-
);
|
|
78
|
+
lines.push('## Next Action');
|
|
79
|
+
lines.push('Read .company/criteria.json and continue THINK > EXECUTE > VERIFY.');
|
|
45
80
|
|
|
81
|
+
fs.writeFileSync(path.join(companyDir, '.checkpoint.md'), lines.join('\n'));
|
|
46
82
|
process.exit(0);
|
package/hooks/session-restore.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// Restore company state after compaction
|
|
3
|
+
// Restore company state after compaction. Reads the checkpoint with reasoning + state.
|
|
4
4
|
|
|
5
5
|
const fs = require('fs');
|
|
6
6
|
const path = require('path');
|
|
@@ -8,27 +8,23 @@ const path = require('path');
|
|
|
8
8
|
const companyDir = path.join(process.cwd(), '.company');
|
|
9
9
|
if (!fs.existsSync(companyDir)) process.exit(0);
|
|
10
10
|
|
|
11
|
-
const
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
msg.push("Read .company/criteria.json and continue THINK > EXECUTE > VERIFY.");
|
|
11
|
+
const checkpointMd = path.join(companyDir, '.checkpoint.md');
|
|
12
|
+
const checkpointJson = path.join(companyDir, '.checkpoint.json');
|
|
13
|
+
|
|
14
|
+
let msg = null;
|
|
15
|
+
|
|
16
|
+
if (fs.existsSync(checkpointMd)) {
|
|
17
|
+
msg = fs.readFileSync(checkpointMd, 'utf8').substring(0, 2000);
|
|
18
|
+
} else if (fs.existsSync(checkpointJson)) {
|
|
19
|
+
try {
|
|
20
|
+
const cp = JSON.parse(fs.readFileSync(checkpointJson, 'utf8'));
|
|
21
|
+
msg = "[COMPANY RESTORED] Goal: " + (cp.goal || "unknown") +
|
|
22
|
+
", Cycle: " + (cp.cycle || 0) +
|
|
23
|
+
", Criteria: " + (cp.passing || 0) + "/" + (cp.total || 0) +
|
|
24
|
+
". Read .company/criteria.json and continue.";
|
|
25
|
+
} catch (e) {}
|
|
26
|
+
}
|
|
28
27
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}));
|
|
32
|
-
} catch (e) {
|
|
33
|
-
process.exit(0);
|
|
28
|
+
if (msg) {
|
|
29
|
+
console.log(JSON.stringify({ systemMessage: msg }));
|
|
34
30
|
}
|
package/hooks/stop-guard.js
CHANGED
|
@@ -21,15 +21,7 @@ if (fs.existsSync(cancelPath)) {
|
|
|
21
21
|
process.exit(0);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
//
|
|
25
|
-
let count = 0;
|
|
26
|
-
try { count = parseInt(fs.readFileSync(counterPath, 'utf8')) || 0; } catch (e) {}
|
|
27
|
-
count++;
|
|
28
|
-
try { fs.writeFileSync(counterPath, String(count)); } catch (e) {}
|
|
29
|
-
if (count > 10) {
|
|
30
|
-
try { fs.unlinkSync(counterPath); } catch (e) {}
|
|
31
|
-
process.exit(0); // Allow stop, prevent infinite loop
|
|
32
|
-
}
|
|
24
|
+
// No limit. Runs until done or user cancels (touch .company/CANCEL).
|
|
33
25
|
|
|
34
26
|
// Check criteria
|
|
35
27
|
if (fs.existsSync(criteriaPath)) {
|