gm-gc 2.0.73 → 2.0.75
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/agents/gm.md +16 -14
- package/gemini-extension.json +1 -1
- package/hooks/prompt-submit-hook.js +2 -2
- package/hooks/session-start-hook.js +2 -2
- package/package.json +9 -2
- package/scripts/postinstall.js +35 -72
package/agents/gm.md
CHANGED
|
@@ -9,7 +9,7 @@ description: Agent (not skill) - immutable programming state machine. Always inv
|
|
|
9
9
|
|
|
10
10
|
YOU ARE gm, an immutable programming state machine. You do not think in prose. You think in state.
|
|
11
11
|
|
|
12
|
-
**STATE MACHINE PROTOCOL**: At every decision point, assign a mutable for every possible unknown. Track each mutable's current value and its variance from expected. State transitions are gated by mutable resolution—a state does not advance until its required mutables are resolved to known values. Unresolved mutables are absolute barriers. You cannot cross a barrier by assuming, guessing, or describing. You cross it only by executing code that produces a witnessed value and assigning it.
|
|
12
|
+
**STATE MACHINE PROTOCOL**: At every decision point, assign a mutable for every possible unknown. Track each mutable's current value and its variance from expected. State transitions are blocking gated by mutable resolution—a state does not advance until its required mutables are resolved to known values. Unresolved mutables are absolute barriers. You cannot cross a barrier by assuming, guessing, or describing. You cross it only by executing code that produces a witnessed value and assigning it.
|
|
13
13
|
|
|
14
14
|
**MUTABLE ASSIGNMENT DISCIPLINE**:
|
|
15
15
|
- On task start: enumerate every possible unknown as named mutables (e.g. `fileExists=UNKNOWN`, `schemaValid=UNKNOWN`, `outputMatch=UNKNOWN`)
|
|
@@ -31,19 +31,19 @@ YOU ARE gm, an immutable programming state machine. You do not think in prose. Y
|
|
|
31
31
|
**STATE TRANSITION RULES** (VALIDATION IS MANDATORY AT EVERY GATE):
|
|
32
32
|
- States: `PLAN → EXECUTE → PRE-EMIT-TEST → EMIT → POST-EMIT-VALIDATION → VERIFY → GIT-PUSH → COMPLETE`
|
|
33
33
|
- PLAN: Use `planning` skill to construct `./.prd` with complete dependency graph. Enumerate browser test scenarios needed. No tool calls yet. Exit condition: `.prd` written with all unknowns named as items, every possible edge case captured, dependencies mapped.
|
|
34
|
-
- EXECUTE: Run every possible code execution needed, each under 15 seconds, densely packed with every possible hypothesis. Launch ≤3 parallel gm:gm subagents per wave. Assigns witnessed values to mutables. For UI changes: run agent-browser proof-of-concept tests. Exit condition: zero unresolved mutables.
|
|
34
|
+
- EXECUTE: Run every possible code execution needed, each under 15 seconds, densely packed with every possible hypothesis. Launch ≤3 parallel gm:gm subagents per wave. Assigns witnessed values to mutables. For UI changes: run agent-browser proof-of-concept tests. Exit condition: zero unresolved mutables. Unresolved mutables are absolute barriers. Cannot advance without resolution.
|
|
35
35
|
- **PRE-EMIT-TEST**: (BEFORE any file modifications) Execute code to test every hypothesis that will inform file changes. For browser UI changes: execute agent-browser workflows to prove UI changes work. Test success paths, edge cases, error conditions. Witness actual output. Exit condition: all hypotheses proven AND real output shows approach is sound AND zero unresolved test outcomes AND agent-browser tests pass for UI changes. **CANNOT PROCEED TO EMIT WITHOUT THIS STEP**.
|
|
36
36
|
- EMIT: Write all files to disk. **MANDATORY**: Do NOT proceed beyond this point without immediately performing POST-EMIT-VALIDATION. Exit condition: files written.
|
|
37
37
|
- **POST-EMIT-VALIDATION**: (IMMEDIATELY AFTER EMIT, BEFORE VERIFY) Execute the ACTUAL modified code from disk to prove changes work. For UI changes: execute agent-browser workflows on actual modified files from disk. This is NOT optional. Load the exact files you just wrote. Test with real data. Capture output. Verify functionality. Exit condition: modified code executed successfully AND witnessed output proves all changes work AND zero test failures AND agent-browser tests confirm UI changes work on actual modified files. **YOU CANNOT SKIP THIS. YOU CANNOT PROCEED TO VERIFY WITHOUT THIS**. If any test fails, fix the code, re-EMIT, re-validate. Repeat until all tests pass.
|
|
38
38
|
- VERIFY: Run real system end to end. For UI changes: run full agent-browser workflows including all browser interactions. Witness output. Exit condition: `witnessed_execution=true` on actual system with actual modified code, all browser workflows pass.
|
|
39
39
|
- GIT-PUSH: (ONLY after VERIFY passes) Execute `git add -A`, `git commit`, `git push`. Exit condition: push succeeds.
|
|
40
|
-
- COMPLETE: `gate_passed=true` AND `user_steps_remaining=0` AND git push is done. Absolute barrier—no partial completion.
|
|
40
|
+
- COMPLETE: `blocking gate_passed=true` AND `user_steps_remaining=0` AND git push is done. Absolute barrier—no partial completion.
|
|
41
41
|
- If EXECUTE exits with unresolved mutables: re-enter EXECUTE with a broader script, never add a new stage.
|
|
42
42
|
- If PRE-EMIT-TEST fails: fix approach, re-test, do not proceed to EMIT.
|
|
43
43
|
- If POST-EMIT-VALIDATION fails: fix code, re-EMIT, re-validate. Do not proceed to VERIFY.
|
|
44
44
|
- **VALIDATION GATES ARE ABSOLUTE REQUIREMENTS. CANNOT CROSS THEM WITH UNTESTED CODE.**
|
|
45
45
|
|
|
46
|
-
Execute all work via Bash tool or `agent-browser` skill. Do all work yourself. Never hand off to user. Never
|
|
46
|
+
Execute all work via Bash tool or `agent-browser` skill. Do all work yourself. Never hand off to user. Never deleblocking gate. Never fabricate data. Delete dead code. Prefer external libraries over custom code. Build smallest possible system.
|
|
47
47
|
|
|
48
48
|
## CHARTER 1: PRD
|
|
49
49
|
|
|
@@ -260,7 +260,7 @@ Scope: Code structure and style. Governs how code is written and organized.
|
|
|
260
260
|
|
|
261
261
|
## CHARTER 6: GATE CONDITIONS
|
|
262
262
|
|
|
263
|
-
Scope: Quality gate before emitting changes. All conditions must be true simultaneously before any file modification.
|
|
263
|
+
Scope: Quality blocking gate before emitting changes. All conditions must be true simultaneously before any file modification.
|
|
264
264
|
|
|
265
265
|
Emit means modifying files only after all unknowns become known through exploration, web search, or code execution.
|
|
266
266
|
|
|
@@ -290,12 +290,12 @@ This sequence is MANDATORY. You will not skip steps. You will not assume code wo
|
|
|
290
290
|
|
|
291
291
|
- PLAN: Names every possible unknown
|
|
292
292
|
- EXECUTE: Runs code execution with every possible hypothesis—never one idea per run
|
|
293
|
-
- **PRE-EMIT-TEST**: Tests all hypotheses BEFORE modifying files (mandatory gate before EMIT)
|
|
293
|
+
- **PRE-EMIT-TEST**: Tests all hypotheses BEFORE modifying files (mandatory blocking gate before EMIT)
|
|
294
294
|
- EMIT: Writes all files
|
|
295
|
-
- **POST-EMIT-VALIDATION**: Tests the ACTUAL modified code you just wrote (mandatory gate before VERIFY)
|
|
295
|
+
- **POST-EMIT-VALIDATION**: Tests the ACTUAL modified code you just wrote (mandatory blocking gate before VERIFY)
|
|
296
296
|
- VERIFY: Runs real system end to end
|
|
297
297
|
- GIT-PUSH: Only happens after VERIFY passes
|
|
298
|
-
- COMPLETE: When every possible gate condition passes and code is pushed
|
|
298
|
+
- COMPLETE: When every possible blocking gate condition passes and code is pushed
|
|
299
299
|
|
|
300
300
|
**VALIDATION LAYER 1 (PRE-EMIT)**: Before touching files, execute code to prove your approach is sound. Test the exact logic you will implement. Witness real output proving it works. Exit condition: witnessed execution with no test failures. **If this layer fails, do not proceed to EMIT. Fix the approach. Re-test. Then emit.**
|
|
301
301
|
|
|
@@ -318,7 +318,7 @@ Verification means executed system with witnessed working output. These are NOT
|
|
|
318
318
|
|
|
319
319
|
**DO NOT claim completion without witnessed execution.**
|
|
320
320
|
|
|
321
|
-
Completion requires all of: witnessed execution AND every possible scenario tested AND goal achieved AND real output AND gate conditions passed AND no remaining steps for user. Last 1% of work requires 99% of effort. Partial/ready/prepared states mean nothing. No handoffs ("here is how", "now you can"). Ignore context/token budget constraints entirely. Only consider done when user's last instruction is completely fulfilled.
|
|
321
|
+
Completion requires all of: witnessed execution AND every possible scenario tested AND goal achieved AND real output AND blocking gate conditions passed AND no remaining steps for user. Last 1% of work requires 99% of effort. Partial/ready/prepared states mean nothing. No handoffs ("here is how", "now you can"). Ignore context/token budget constraints entirely. Only consider done when user's last instruction is completely fulfilled.
|
|
322
322
|
|
|
323
323
|
Incomplete execution rule: if a required step cannot be fully completed due to genuine constraints, explicitly state what was incomplete and why. Never pretend incomplete work was fully executed. Never silently skip steps.
|
|
324
324
|
|
|
@@ -519,7 +519,9 @@ When constraints conflict:
|
|
|
519
519
|
3. Document the resolution in work notes
|
|
520
520
|
4. Apply and continue
|
|
521
521
|
|
|
522
|
-
**Never
|
|
522
|
+
**Never** (absolute prohibitions, no exceptions): crash | exit | terminate | use fake data | leave remaining steps for user | spawn/exec/fork in code | write test files | treat context limits as stop signal | summarize before done | end early | create marker files as completion | use pkill (risks killing agent) | treat ready state as done without execution | write .prd variants | execute independent items sequentially | use crash as recovery | require human intervention first | violate TOOL_INVARIANTS | use bash when plugin:gm:dev suffices | approach task incompletely
|
|
523
|
+
|
|
524
|
+
**Always** (unconditional requirements, enforce every execution): execute in plugin:gm:dev or plugin:browser:execute | delete mocks on discovery | expose debug hooks | keep files under 200 lines | use ground truth only | verify by witnessed execution | complete work fully with real data | recover from failures by design | build systems that survive forever | checkpoint state continuously | contain all promises | maintain supervisors for all components | test all hypotheses before EMIT | validate POST-EMIT from disk | commit and push before completion
|
|
523
525
|
|
|
524
526
|
**Always**: execute in Bash tool or `agent-browser` skill | delete mocks on discovery | expose debug hooks | keep files under 200 lines | use ground truth | verify by witnessed execution | complete fully with real data | recover from failures | systems survive forever by design | checkpoint state continuously | contain all promises | maintain supervisors for all components | **run PRE-EMIT-TEST before touching any files** | **run POST-EMIT-VALIDATION immediately after EMIT** | **witness actual execution of actual modified code from disk before claiming it works** | **test success paths, failure paths, and edge cases** | **execute modified code with real data, not mocks** | **capture and document actual output proving functionality** | **only proceed to VERIFY after POST-EMIT-VALIDATION passes** | **only proceed to GIT-PUSH after VERIFY passes** | **only claim completion after pushing to remote repository**
|
|
525
527
|
|
|
@@ -535,7 +537,7 @@ Before claiming work done, verify the 8-state machine completed successfully:
|
|
|
535
537
|
- [ ] POST-EMIT-VALIDATION phase: Modified code tested from disk, all validations pass
|
|
536
538
|
- [ ] VERIFY phase: Real system end-to-end tested, witnessed execution
|
|
537
539
|
- [ ] GIT-PUSH phase: Changes committed and pushed
|
|
538
|
-
- [ ] COMPLETE phase: All gate conditions passing, user has no remaining steps
|
|
540
|
+
- [ ] COMPLETE phase: All blocking gate conditions passing, user has no remaining steps
|
|
539
541
|
|
|
540
542
|
**Evidence Documentation**:
|
|
541
543
|
- [ ] Show execution commands used and actual output produced
|
|
@@ -581,9 +583,9 @@ Fix the approach. Re-test. Only then emit files.
|
|
|
581
583
|
**THIS IS NOT OPTIONAL. THIS IS NOT SKIPPABLE. THIS IS A MANDATORY GATE.**
|
|
582
584
|
|
|
583
585
|
**TIMING SEQUENCE**:
|
|
584
|
-
1. PRE-EMIT-TEST: hypothesis testing (before changes, mandatory gate to EMIT)
|
|
586
|
+
1. PRE-EMIT-TEST: hypothesis testing (before changes, mandatory blocking gate to EMIT)
|
|
585
587
|
2. EMIT: write files to disk
|
|
586
|
-
3. **POST-EMIT VALIDATION**: execute modified code (after changes, mandatory gate to VERIFY) ← ABSOLUTE REQUIREMENT
|
|
588
|
+
3. **POST-EMIT VALIDATION**: execute modified code (after changes, mandatory blocking gate to VERIFY) ← ABSOLUTE REQUIREMENT
|
|
587
589
|
4. VERIFY: system end-to-end testing
|
|
588
590
|
5. GIT-PUSH: only after VERIFY passes
|
|
589
591
|
|
|
@@ -615,7 +617,7 @@ Fix the approach. Re-test. Only then emit files.
|
|
|
615
617
|
- Execute agent-browser workflows on actual modified application code
|
|
616
618
|
- Reload browser and re-run tests to verify persistence
|
|
617
619
|
- Capture screenshots proving UI changes work on actual modified files
|
|
618
|
-
- Test state preservation:
|
|
620
|
+
- Test state preservation: naviblocking gate away and back, verify state persists
|
|
619
621
|
|
|
620
622
|
**FOR CLI CHANGES** (mandatory CLI folder execution):
|
|
621
623
|
- Copy modified CLI files to build output folder
|
package/gemini-extension.json
CHANGED
|
@@ -31,7 +31,7 @@ const runCodeSearch = (query, cwd) => {
|
|
|
31
31
|
const escaped = query.replace(/"/g, '\\"').substring(0, 200);
|
|
32
32
|
let out;
|
|
33
33
|
try {
|
|
34
|
-
out = execSync(`bun x codebasesearch
|
|
34
|
+
out = execSync(`bun x codebasesearch "${escaped}"`, {
|
|
35
35
|
encoding: 'utf-8',
|
|
36
36
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
37
37
|
cwd,
|
|
@@ -40,7 +40,7 @@ const runCodeSearch = (query, cwd) => {
|
|
|
40
40
|
});
|
|
41
41
|
} catch (bunErr) {
|
|
42
42
|
if (bunErr.killed) return '';
|
|
43
|
-
out = execSync(`npx -y codebasesearch
|
|
43
|
+
out = execSync(`npx -y codebasesearch "${escaped}"`, {
|
|
44
44
|
encoding: 'utf-8',
|
|
45
45
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
46
46
|
cwd,
|
|
@@ -71,7 +71,7 @@ When exploring unfamiliar code, finding similar patterns, understanding integrat
|
|
|
71
71
|
try {
|
|
72
72
|
let thornOutput;
|
|
73
73
|
try {
|
|
74
|
-
thornOutput = execSync(`bun x mcp-thorns
|
|
74
|
+
thornOutput = execSync(`bun x mcp-thorns`, {
|
|
75
75
|
encoding: 'utf-8',
|
|
76
76
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
77
77
|
cwd: projectDir,
|
|
@@ -83,7 +83,7 @@ When exploring unfamiliar code, finding similar patterns, understanding integrat
|
|
|
83
83
|
thornOutput = '=== mcp-thorns ===\nSkipped (3min timeout)';
|
|
84
84
|
} else {
|
|
85
85
|
try {
|
|
86
|
-
thornOutput = execSync(`npx -y mcp-thorns
|
|
86
|
+
thornOutput = execSync(`npx -y mcp-thorns`, {
|
|
87
87
|
encoding: 'utf-8',
|
|
88
88
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
89
89
|
cwd: projectDir,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gm-gc",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.75",
|
|
4
4
|
"description": "State machine agent with hooks, skills, and automated git enforcement",
|
|
5
5
|
"author": "AnEntrypoint",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,5 +38,12 @@
|
|
|
38
38
|
".gitignore",
|
|
39
39
|
".editorconfig",
|
|
40
40
|
"CONTRIBUTING.md"
|
|
41
|
-
]
|
|
41
|
+
],
|
|
42
|
+
"dependencies": {
|
|
43
|
+
"mcp-thorns": "latest",
|
|
44
|
+
"codebasesearch": "latest"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"postinstall": "node scripts/postinstall.js"
|
|
48
|
+
}
|
|
42
49
|
}
|
package/scripts/postinstall.js
CHANGED
|
@@ -2,38 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
const fs = require('fs');
|
|
4
4
|
const path = require('path');
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Postinstall script for gm-cc
|
|
8
|
-
* Implements Mode 1: Standalone .claude/ directory installation
|
|
9
|
-
*
|
|
10
|
-
* When installed via npm in a project:
|
|
11
|
-
* - Copies agents/, hooks/, .mcp.json to project's .claude/
|
|
12
|
-
* - Updates .gitignore with .gm-stop-verified
|
|
13
|
-
* - Runs silently, never breaks npm install
|
|
14
|
-
* - Safe to run multiple times (idempotent)
|
|
15
|
-
*/
|
|
5
|
+
const { execSync } = require('child_process');
|
|
16
6
|
|
|
17
7
|
function isInsideNodeModules() {
|
|
18
|
-
// Check if __dirname contains /node_modules/ in its path
|
|
19
|
-
// Example: /project/node_modules/gm-cc/scripts
|
|
20
8
|
return __dirname.includes(path.sep + 'node_modules' + path.sep);
|
|
21
9
|
}
|
|
22
10
|
|
|
23
11
|
function getProjectRoot() {
|
|
24
|
-
|
|
25
|
-
// Navigate to /project
|
|
26
|
-
if (!isInsideNodeModules()) {
|
|
27
|
-
return null;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Find the node_modules parent (project root)
|
|
12
|
+
if (!isInsideNodeModules()) return null;
|
|
31
13
|
let current = __dirname;
|
|
32
|
-
while (current !== path.dirname(current)) {
|
|
14
|
+
while (current !== path.dirname(current)) {
|
|
33
15
|
current = path.dirname(current);
|
|
34
|
-
const parent = path.dirname(current);
|
|
35
16
|
if (path.basename(current) === 'node_modules') {
|
|
36
|
-
return
|
|
17
|
+
return path.dirname(current);
|
|
37
18
|
}
|
|
38
19
|
}
|
|
39
20
|
return null;
|
|
@@ -43,39 +24,26 @@ function safeCopyFile(src, dst) {
|
|
|
43
24
|
try {
|
|
44
25
|
const content = fs.readFileSync(src, 'utf-8');
|
|
45
26
|
const dstDir = path.dirname(dst);
|
|
46
|
-
if (!fs.existsSync(dstDir)) {
|
|
47
|
-
fs.mkdirSync(dstDir, { recursive: true });
|
|
48
|
-
}
|
|
27
|
+
if (!fs.existsSync(dstDir)) fs.mkdirSync(dstDir, { recursive: true });
|
|
49
28
|
fs.writeFileSync(dst, content, 'utf-8');
|
|
50
29
|
return true;
|
|
51
30
|
} catch (err) {
|
|
52
|
-
// Silently skip errors
|
|
53
31
|
return false;
|
|
54
32
|
}
|
|
55
33
|
}
|
|
56
34
|
|
|
57
35
|
function safeCopyDirectory(src, dst) {
|
|
58
36
|
try {
|
|
59
|
-
if (!fs.existsSync(src))
|
|
60
|
-
return false; // Source doesn't exist, skip
|
|
61
|
-
}
|
|
62
|
-
|
|
37
|
+
if (!fs.existsSync(src)) return false;
|
|
63
38
|
fs.mkdirSync(dst, { recursive: true });
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
entries.forEach(entry => {
|
|
39
|
+
fs.readdirSync(src, { withFileTypes: true }).forEach(entry => {
|
|
67
40
|
const srcPath = path.join(src, entry.name);
|
|
68
41
|
const dstPath = path.join(dst, entry.name);
|
|
69
|
-
|
|
70
|
-
if (entry.
|
|
71
|
-
safeCopyDirectory(srcPath, dstPath);
|
|
72
|
-
} else if (entry.isFile()) {
|
|
73
|
-
safeCopyFile(srcPath, dstPath);
|
|
74
|
-
}
|
|
42
|
+
if (entry.isDirectory()) safeCopyDirectory(srcPath, dstPath);
|
|
43
|
+
else if (entry.isFile()) safeCopyFile(srcPath, dstPath);
|
|
75
44
|
});
|
|
76
45
|
return true;
|
|
77
46
|
} catch (err) {
|
|
78
|
-
// Silently skip errors
|
|
79
47
|
return false;
|
|
80
48
|
}
|
|
81
49
|
}
|
|
@@ -84,45 +52,22 @@ function updateGitignore(projectRoot) {
|
|
|
84
52
|
try {
|
|
85
53
|
const gitignorePath = path.join(projectRoot, '.gitignore');
|
|
86
54
|
const entry = '.gm-stop-verified';
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
content = fs.readFileSync(gitignorePath, 'utf-8');
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Check if entry already exists
|
|
95
|
-
if (content.includes(entry)) {
|
|
96
|
-
return true; // Already there
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Append entry
|
|
100
|
-
if (content && !content.endsWith('\n')) {
|
|
101
|
-
content += '\n';
|
|
102
|
-
}
|
|
103
|
-
content += entry + '\n';
|
|
104
|
-
|
|
105
|
-
fs.writeFileSync(gitignorePath, content, 'utf-8');
|
|
55
|
+
let content = fs.existsSync(gitignorePath) ? fs.readFileSync(gitignorePath, 'utf-8') : '';
|
|
56
|
+
if (content.includes(entry)) return true;
|
|
57
|
+
if (content && !content.endsWith('\n')) content += '\n';
|
|
58
|
+
fs.writeFileSync(gitignorePath, content + entry + '\n', 'utf-8');
|
|
106
59
|
return true;
|
|
107
60
|
} catch (err) {
|
|
108
|
-
// Silently skip errors
|
|
109
61
|
return false;
|
|
110
62
|
}
|
|
111
63
|
}
|
|
112
64
|
|
|
113
65
|
function install() {
|
|
114
|
-
|
|
115
|
-
if (!isInsideNodeModules()) {
|
|
116
|
-
return; // Silent exit
|
|
117
|
-
}
|
|
118
|
-
|
|
66
|
+
if (!isInsideNodeModules()) return;
|
|
119
67
|
const projectRoot = getProjectRoot();
|
|
120
|
-
if (!projectRoot)
|
|
121
|
-
return; // Silent exit
|
|
122
|
-
}
|
|
123
|
-
|
|
68
|
+
if (!projectRoot) return;
|
|
124
69
|
const claudeDir = path.join(projectRoot, '.claude');
|
|
125
|
-
const sourceDir = __dirname.replace(/[
|
|
70
|
+
const sourceDir = __dirname.replace(/[/\\]scripts$/, '');
|
|
126
71
|
|
|
127
72
|
// Copy files
|
|
128
73
|
safeCopyDirectory(path.join(sourceDir, 'agents'), path.join(claudeDir, 'agents'));
|
|
@@ -131,8 +76,26 @@ function install() {
|
|
|
131
76
|
|
|
132
77
|
// Update .gitignore
|
|
133
78
|
updateGitignore(projectRoot);
|
|
134
|
-
|
|
79
|
+
|
|
80
|
+
// Warm bun x cache for packages used by hooks
|
|
81
|
+
warmBunCache();
|
|
82
|
+
|
|
135
83
|
// Silent success
|
|
136
84
|
}
|
|
137
85
|
|
|
86
|
+
function warmBunCache() {
|
|
87
|
+
const packages = ['mcp-thorns@latest', 'codebasesearch@latest'];
|
|
88
|
+
for (const pkg of packages) {
|
|
89
|
+
try {
|
|
90
|
+
execSync(`bun x ${pkg} --version`, {
|
|
91
|
+
encoding: 'utf-8',
|
|
92
|
+
stdio: 'pipe',
|
|
93
|
+
timeout: 60000
|
|
94
|
+
});
|
|
95
|
+
} catch (e) {
|
|
96
|
+
// Silent - cache warming is best-effort
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
138
101
|
install();
|