strray-ai 1.15.28 → 1.15.29
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.md +1 -3
- package/package.json +1 -4
- package/scripts/mjs/validate-postinstall-config.mjs +332 -62
- package/scripts/node/postinstall.cjs +12 -43
- package/scripts/node/universal-version-manager.js +2 -2
- package/scripts/mjs/FIX_SUMMARY.md +0 -143
- package/scripts/mjs/analyze-imports.mjs +0 -155
- package/scripts/mjs/debug-rules.mjs +0 -80
- package/scripts/mjs/demo-clickable-monitoring.mjs +0 -142
- package/scripts/mjs/monitor-framework-orchestration.mjs +0 -238
- package/scripts/mjs/monitor-package.mjs +0 -50
- package/scripts/mjs/monitoring-daemon.mjs +0 -66
- package/scripts/mjs/run-all-tests.mjs +0 -333
- package/scripts/mjs/run-performance-gates.mjs +0 -80
- package/scripts/mjs/run-simulations.mjs +0 -93
- package/scripts/mjs/scenario-data-processor.py +0 -122
- package/scripts/mjs/smart-test-runner.mjs +0 -566
- package/scripts/mjs/test-agent-configs.mjs +0 -128
- package/scripts/mjs/test-agents.mjs +0 -170
- package/scripts/mjs/test-auto-creation-flow.mjs +0 -123
- package/scripts/mjs/test-ci-cd-integration.mjs +0 -113
- package/scripts/mjs/test-complex-orchestration.mjs +0 -79
- package/scripts/mjs/test-comprehensive-path-resolution.mjs +0 -134
- package/scripts/mjs/test-configuration-validation.mjs +0 -241
- package/scripts/mjs/test-consumer-validation.mjs +0 -916
- package/scripts/mjs/test-data-processor.py +0 -51
- package/scripts/mjs/test-enforcement-e2e.mjs +0 -80
- package/scripts/mjs/test-enforcer-comprehensive.mjs +0 -219
- package/scripts/mjs/test-final-consumer-validation.mjs +0 -352
- package/scripts/mjs/test-framework-boot.mjs +0 -81
- package/scripts/mjs/test-framework-integration.mjs +0 -215
- package/scripts/mjs/test-integration.mjs +0 -79
- package/scripts/mjs/test-mcp-registration.mjs +0 -374
- package/scripts/mjs/test-mcp-servers.mjs +0 -230
- package/scripts/mjs/test-orchestrator-complex.mjs +0 -79
- package/scripts/mjs/test-orchestrator-simple.mjs +0 -77
- package/scripts/mjs/test-path-resolver.mjs +0 -25
- package/scripts/mjs/test-postinstall-files.mjs +0 -321
- package/scripts/mjs/test-processor-pipeline.mjs +0 -125
- package/scripts/mjs/test-quarantine.mjs +0 -250
- package/scripts/mjs/test-rules.mjs +0 -81
- package/scripts/mjs/test-simple-prompt.mjs +0 -45
- package/scripts/mjs/test-simulation.mjs +0 -84
- package/scripts/mjs/test-skill-routing.mjs +0 -194
- package/scripts/mjs/test-skills-comprehensive.mjs +0 -264
- package/scripts/mjs/test-skills-coverage.mjs +0 -266
- package/scripts/mjs/test-skills-mcp-integration.mjs +0 -354
- package/scripts/mjs/test-stringray-plugin.mjs +0 -285
- package/scripts/mjs/trigger-and-monitor-framework.mjs +0 -219
- package/scripts/mjs/update-performance-baselines.mjs +0 -78
- package/scripts/mjs/validate-phase1.mjs +0 -201
- package/scripts/mjs/verify-orchestration.mjs +0 -178
- package/scripts/mjs/verify-pipeline-end-to-end.mjs +0 -237
- package/scripts/mjs/verify-plugin-paths.mjs +0 -289
- package/scripts/node/README.md +0 -127
- package/scripts/node/activate-self-direction.js +0 -72
- package/scripts/node/add-parent-monitoring.cjs +0 -53
- package/scripts/node/add-timeout-shutdown.cjs +0 -55
- package/scripts/node/analyze-activity-log.cjs +0 -188
- package/scripts/node/analyzer-agent-runner.js +0 -328
- package/scripts/node/boot-check.mjs +0 -203
- package/scripts/node/ci-cd-orchestrator.cjs +0 -266
- package/scripts/node/cleanup-console-logs.js +0 -108
- package/scripts/node/cleanup-doc-versions.js +0 -153
- package/scripts/node/cleanup-repository.js +0 -116
- package/scripts/node/debug-plugin.cjs +0 -87
- package/scripts/node/dependency-scan.cjs +0 -145
- package/scripts/node/dev-setup.cjs +0 -68
- package/scripts/node/enforce-version-compliance.sh.bak +0 -143
- package/scripts/node/enhance-mcp-shutdown.cjs +0 -62
- package/scripts/node/fix-framework-logger-paths.cjs +0 -79
- package/scripts/node/fix-mcp-capabilities.js +0 -87
- package/scripts/node/fix-mcp-shutdown.cjs +0 -53
- package/scripts/node/generate-activity-report.js +0 -27
- package/scripts/node/generate-autonomous-report.cjs +0 -427
- package/scripts/node/generate-changelog.js +0 -230
- package/scripts/node/generate-phase1-report.js +0 -28
- package/scripts/node/generate-reflection-index.js +0 -208
- package/scripts/node/generate-skills.cjs +0 -217
- package/scripts/node/install.cjs +0 -632
- package/scripts/node/kernel-e2e-test.mjs +0 -168
- package/scripts/node/kernel-framework-test.mjs +0 -127
- package/scripts/node/kernel-live-test.mjs +0 -147
- package/scripts/node/kernel-real-framework-test.mjs +0 -103
- package/scripts/node/kernel-update.cjs +0 -379
- package/scripts/node/performance-report.js +0 -56
- package/scripts/node/pre-commit-version-validation.js +0 -122
- package/scripts/node/pre-publish-check.sh +0 -78
- package/scripts/node/profiling-demo.js +0 -108
- package/scripts/node/reflection-check.sh +0 -423
- package/scripts/node/release-tweet-multi.mjs.bak +0 -269
- package/scripts/node/release-tweet-single.mjs +0 -323
- package/scripts/node/release-tweet.mjs +0 -268
- package/scripts/node/release.mjs +0 -190
- package/scripts/node/remove-console-logs.mjs +0 -83
- package/scripts/node/remove-version-headers.mjs +0 -123
- package/scripts/node/run-postprocessor.js +0 -59
- package/scripts/node/setup-ci-paths.cjs +0 -62
- package/scripts/node/setup.cjs +0 -116
- package/scripts/node/sync-readme-features.js +0 -166
- package/scripts/node/test-install.cjs +0 -79
- package/scripts/node/test-plugin-comprehensive.js +0 -279
- package/scripts/node/test-postinstall.js +0 -1
- package/scripts/node/test-session-management.js +0 -135
- package/scripts/node/test-simple-names-comprehensive.mjs +0 -221
- package/scripts/node/test-simple-names.mjs +0 -39
- package/scripts/node/trigger-report.js +0 -15
- package/scripts/node/update-models-global.cjs +0 -82
- package/scripts/node/validate-codex.mjs +0 -148
- package/scripts/node/validate-oh-my-opencode-integration.cjs +0 -203
- package/scripts/node/validate-postinstall-config.mjs +0 -348
- package/scripts/node/value-tweet.mjs +0 -305
- package/scripts/node/value-tweet.mjs.backup +0 -487
package/AGENTS.md
CHANGED
|
@@ -166,7 +166,7 @@ npx strray-ai validate # Validate installation
|
|
|
166
166
|
npx strray-ai capabilities # Show all features
|
|
167
167
|
npx strray-ai report # Generate reports
|
|
168
168
|
npx strray-ai analytics # Pattern analytics
|
|
169
|
-
|
|
169
|
+
|
|
170
170
|
npm run test:pipelines # Pipeline integration tests
|
|
171
171
|
```
|
|
172
172
|
|
|
@@ -409,7 +409,6 @@ StringRay uses complexity scoring to route tasks to appropriate agents:
|
|
|
409
409
|
|
|
410
410
|
```bash
|
|
411
411
|
# Calibrate complexity scoring
|
|
412
|
-
npx strray-ai calibrate
|
|
413
412
|
|
|
414
413
|
# View current complexity settings
|
|
415
414
|
cat .opencode/strray/features.json | jq '.complexity'
|
|
@@ -469,7 +468,6 @@ Control how agents are spawned and coordinated:
|
|
|
469
468
|
| `npx strray-ai health` | Run health check | Verify installation |
|
|
470
469
|
| `npx strray-ai validate` | Run full validation suite | Pre-commit validation |
|
|
471
470
|
| `npx strray-ai capabilities` | List all available features | Discover capabilities |
|
|
472
|
-
| `npx strray-ai calibrate` | Recalibrate complexity scoring | After major refactors |
|
|
473
471
|
| `npx strray-ai report` | Generate analytics reports | Review performance |
|
|
474
472
|
| `npx strray-ai analytics` | View pattern analytics | Understand agent behavior |
|
|
475
473
|
| `npx strray-ai config` | Manage configuration | Tune settings |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "strray-ai",
|
|
3
|
-
"version": "1.15.
|
|
3
|
+
"version": "1.15.29",
|
|
4
4
|
"description": "⚡ StringRay ⚡: Bulletproof AI orchestration with systematic error prevention. Zero dead ends. Ship clean, tested, optimized code — every time.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -80,10 +80,7 @@
|
|
|
80
80
|
"validate": "node scripts/validate-stringray-comprehensive.js",
|
|
81
81
|
"validate:quick": "node scripts/validate-stringray-comprehensive.js --quick",
|
|
82
82
|
"validate:full": "node scripts/validate-stringray-comprehensive.js --full",
|
|
83
|
-
"test:modules": "node scripts/test-es-modules.mjs",
|
|
84
|
-
"fix:modules": "node scripts/fix-module-compatibility.js",
|
|
85
83
|
"test:unified": "node scripts/test/test-unified-framework.mjs",
|
|
86
|
-
"test:plugin": "node scripts/test/test-stray-plugin.mjs",
|
|
87
84
|
"test:consumer": "node scripts/test/test-consumer-readiness.cjs",
|
|
88
85
|
"config:setup": "node scripts/config/utils.js setup-dev",
|
|
89
86
|
"monitoring:start": "node scripts/monitoring/daemon.js start",
|
|
@@ -1,78 +1,348 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Postinstall Configuration Validator
|
|
5
|
+
*
|
|
6
|
+
* Tests that all critical configuration files and folders are properly copied
|
|
7
|
+
* during npm install, including .claude/, .opencode/, and related files
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
import fs from
|
|
10
|
-
import path from
|
|
11
|
-
import
|
|
10
|
+
import fs from "fs";
|
|
11
|
+
import path from "path";
|
|
12
|
+
import os from "os";
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
class PostinstallConfigValidator {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.results = { passed: [], failed: [] };
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async validateConfiguration() {
|
|
20
|
+
console.log("📁 POSTINSTALL CONFIGURATION VALIDATOR");
|
|
21
|
+
console.log("=====================================");
|
|
22
|
+
|
|
23
|
+
const tests = [
|
|
24
|
+
this.validateProjectFiles.bind(this),
|
|
25
|
+
this.validateOpencodeConfig.bind(this),
|
|
26
|
+
this.validateClaudeConfig.bind(this),
|
|
27
|
+
this.validateMCPConfig.bind(this),
|
|
28
|
+
];
|
|
14
29
|
|
|
15
|
-
const
|
|
16
|
-
|
|
30
|
+
for (const test of tests) {
|
|
31
|
+
await test();
|
|
32
|
+
}
|
|
17
33
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
if (fs.existsSync(fullPath)) {
|
|
21
|
-
console.log(`✅ ${description}: ${file}`);
|
|
22
|
-
return true;
|
|
23
|
-
} else {
|
|
24
|
-
console.log(`❌ ${description}: ${file} NOT FOUND`);
|
|
25
|
-
errors.push(`${description} not found: ${file}`);
|
|
26
|
-
return false;
|
|
34
|
+
this.printSummary();
|
|
35
|
+
return this.results.failed.length === 0;
|
|
27
36
|
}
|
|
28
|
-
}
|
|
29
37
|
|
|
30
|
-
|
|
38
|
+
async validateProjectFiles() {
|
|
39
|
+
console.log("\n📄 Testing Project Configuration Files...");
|
|
31
40
|
|
|
32
|
-
|
|
33
|
-
|
|
41
|
+
const requiredFiles = [
|
|
42
|
+
{ path: "opencode.json", description: "OpenCode base configuration" },
|
|
43
|
+
{
|
|
44
|
+
path: ".opencode/package.json",
|
|
45
|
+
description: "OpenCode package config",
|
|
46
|
+
},
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
// Optional files (not required for CI/test environments)
|
|
50
|
+
const optionalFiles = [
|
|
51
|
+
{
|
|
52
|
+
description: "OpenCode main config (optional - can cause boot issues)",
|
|
53
|
+
},
|
|
54
|
+
{ path: ".mcp.json", description: "MCP server configuration (lazy loaded)" },
|
|
55
|
+
{ path: ".opencode/README.md", description: "OpenCode documentation" },
|
|
56
|
+
];
|
|
34
57
|
|
|
35
|
-
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
if (
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
58
|
+
let allPresent = true;
|
|
59
|
+
for (const file of requiredFiles) {
|
|
60
|
+
try {
|
|
61
|
+
if (fs.existsSync(file.path)) {
|
|
62
|
+
console.log(` ✅ ${file.path} - ${file.description}`);
|
|
63
|
+
} else {
|
|
64
|
+
console.log(` ❌ ${file.path} - ${file.description} (MISSING)`);
|
|
65
|
+
allPresent = false;
|
|
66
|
+
}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
console.log(
|
|
69
|
+
` ❌ ${file.path} - Error checking file: ${error.message}`,
|
|
70
|
+
);
|
|
71
|
+
allPresent = false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
45
74
|
|
|
46
|
-
// Check
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
}
|
|
75
|
+
// Check optional files (don't fail if missing)
|
|
76
|
+
for (const file of optionalFiles) {
|
|
77
|
+
try {
|
|
78
|
+
if (fs.existsSync(file.path)) {
|
|
79
|
+
console.log(` ✅ ${file.path} - ${file.description}`);
|
|
80
|
+
} else {
|
|
81
|
+
console.log(` ℹ️ ${file.path} - ${file.description} (OPTIONAL - not present)`);
|
|
82
|
+
}
|
|
83
|
+
} catch (error) {
|
|
84
|
+
console.log(` ℹ️ ${file.path} - Error checking file: ${error.message}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (allPresent) {
|
|
89
|
+
this.results.passed.push("Project Configuration Files");
|
|
90
|
+
} else {
|
|
91
|
+
this.results.failed.push({
|
|
92
|
+
test: "Project Configuration Files",
|
|
93
|
+
error: "Some required configuration files are missing",
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
async validateOpencodeConfig() {
|
|
99
|
+
console.log("\n🛠️ Testing OpenCode Configuration...");
|
|
100
|
+
|
|
101
|
+
// OpenCode.json was removed - config is in opencode.json at project root
|
|
102
|
+
// Framework uses opencode.json (root) instead
|
|
103
|
+
console.log(" ℹ️ OpenCode.json removed — config is in opencode.json at project root");
|
|
104
|
+
this.results.passed.push({
|
|
105
|
+
test: "OpenCode Configuration",
|
|
106
|
+
details: "Skipped - uses opencode.json at root"
|
|
107
|
+
});
|
|
108
|
+
return;
|
|
109
|
+
|
|
110
|
+
return;
|
|
111
|
+
|
|
112
|
+
// Leftover code from old implementation - to be removed
|
|
113
|
+
// Check for plugin registration
|
|
114
|
+
if (config.plugin && Array.isArray(config.plugin)) {
|
|
115
|
+
const hasStringRayPlugin = config.plugin.some((p) =>
|
|
116
|
+
p.toLowerCase().includes("strray"),
|
|
117
|
+
);
|
|
118
|
+
if (hasStringRayPlugin) {
|
|
119
|
+
console.log(" ✅ StringRay plugin registered");
|
|
120
|
+
} else {
|
|
121
|
+
console.log(" ❌ StringRay plugin not registered");
|
|
122
|
+
this.results.failed.push({
|
|
123
|
+
test: "OpenCode Configuration",
|
|
124
|
+
error: "StringRay plugin not registered",
|
|
125
|
+
});
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Check for MCP server disabling
|
|
131
|
+
if (config.disabled_mcps && Array.isArray(config.disabled_mcps)) {
|
|
132
|
+
const requiredDisabled = [
|
|
133
|
+
"global-everything",
|
|
134
|
+
"global-git",
|
|
135
|
+
"global-sqlite",
|
|
136
|
+
];
|
|
137
|
+
const allDisabled = requiredDisabled.every((mcp) =>
|
|
138
|
+
config.disabled_mcps.includes(mcp),
|
|
139
|
+
);
|
|
140
|
+
if (allDisabled) {
|
|
141
|
+
console.log(" ✅ Problematic MCP servers disabled");
|
|
142
|
+
} else {
|
|
143
|
+
console.log(" ❌ Some problematic MCP servers not disabled");
|
|
144
|
+
this.results.failed.push({
|
|
145
|
+
test: "OpenCode Configuration",
|
|
146
|
+
error: "Problematic MCP servers not properly disabled",
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.results.passed.push("OpenCode Configuration");
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async validateClaudeConfig() {
|
|
156
|
+
console.log("\n🤖 Testing Claude Desktop Integration...");
|
|
157
|
+
|
|
158
|
+
// Skip in CI environments - Claude Desktop is not installed
|
|
159
|
+
const isCI = process.env.CI || process.env.GITHUB_ACTIONS;
|
|
160
|
+
if (isCI) {
|
|
161
|
+
console.log(" ℹ️ Skipping Claude Desktop check (not applicable in CI)");
|
|
162
|
+
this.results.passed.push("Claude Desktop Integration (CI - N/A)");
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
try {
|
|
167
|
+
const claudeDir = path.join(os.homedir(), ".claude");
|
|
168
|
+
const { execSync } = await import('child_process');
|
|
169
|
+
const claudeMcpPath = path.join(claudeDir, ".mcp.json");
|
|
170
|
+
|
|
171
|
+
if (!fs.existsSync(claudeDir)) {
|
|
172
|
+
console.log(` ❌ ${claudeDir} directory not found`);
|
|
173
|
+
this.results.failed.push({
|
|
174
|
+
test: "Claude Desktop Integration",
|
|
175
|
+
error: ".claude directory not created",
|
|
176
|
+
});
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
53
179
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
console.log(
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
180
|
+
if (!fs.existsSync(claudeMcpPath)) {
|
|
181
|
+
console.log(` ❌ ${claudeMcpPath} not found`);
|
|
182
|
+
this.results.failed.push({
|
|
183
|
+
test: "Claude Desktop Integration",
|
|
184
|
+
error: ".claude/.mcp.json not created",
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
console.log(" ✅ .claude directory created");
|
|
190
|
+
console.log(" ✅ .claude/.mcp.json created");
|
|
191
|
+
|
|
192
|
+
// Validate MCP config content
|
|
193
|
+
const mcpConfig = JSON.parse(fs.readFileSync(claudeMcpPath, "utf8"));
|
|
194
|
+
if (mcpConfig.mcpServers) {
|
|
195
|
+
const serverCount = Object.keys(mcpConfig.mcpServers).length;
|
|
196
|
+
console.log(
|
|
197
|
+
` ✅ MCP config valid (${serverCount} servers configured)`,
|
|
198
|
+
);
|
|
199
|
+
|
|
200
|
+
// Check for disabled problematic servers
|
|
201
|
+
const disabledServers = [
|
|
202
|
+
"global-everything",
|
|
203
|
+
"global-git",
|
|
204
|
+
"global-sqlite",
|
|
205
|
+
];
|
|
206
|
+
let allDisabled = true;
|
|
207
|
+
for (const server of disabledServers) {
|
|
208
|
+
if (mcpConfig.mcpServers[server]) {
|
|
209
|
+
console.log(
|
|
210
|
+
` ❌ ${server} should be disabled but is still active`,
|
|
211
|
+
);
|
|
212
|
+
allDisabled = false;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (allDisabled) {
|
|
217
|
+
console.log(" ✅ Problematic MCP servers properly disabled");
|
|
218
|
+
} else {
|
|
219
|
+
this.results.failed.push({
|
|
220
|
+
test: "Claude Desktop Integration",
|
|
221
|
+
error: "Some problematic MCP servers not disabled",
|
|
222
|
+
});
|
|
223
|
+
return;
|
|
224
|
+
}
|
|
225
|
+
} else {
|
|
226
|
+
console.log(" ❌ Invalid MCP configuration structure");
|
|
227
|
+
this.results.failed.push({
|
|
228
|
+
test: "Claude Desktop Integration",
|
|
229
|
+
error: "Invalid MCP configuration structure",
|
|
230
|
+
});
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
this.results.passed.push("Claude Desktop Integration");
|
|
235
|
+
} catch (error) {
|
|
236
|
+
console.log(` ❌ Error validating Claude config: ${error.message}`);
|
|
237
|
+
this.results.failed.push({
|
|
238
|
+
test: "Claude Desktop Integration",
|
|
239
|
+
error: error.message,
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
async validateMCPConfig() {
|
|
245
|
+
console.log("\n🔧 Testing MCP Server Configuration...");
|
|
246
|
+
|
|
247
|
+
// Check if .mcp.json exists (optional with lazy loading)
|
|
248
|
+
if (!fs.existsSync(".mcp.json")) {
|
|
249
|
+
console.log(" ℹ️ .mcp.json not found - using lazy loading via opencode.json");
|
|
250
|
+
this.results.passed.push("MCP Server Configuration (Lazy Loading)");
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
try {
|
|
255
|
+
const mcpConfig = JSON.parse(fs.readFileSync(".mcp.json", "utf8"));
|
|
256
|
+
|
|
257
|
+
if (mcpConfig.mcpServers) {
|
|
258
|
+
const serverCount = Object.keys(mcpConfig.mcpServers).length;
|
|
259
|
+
console.log(
|
|
260
|
+
` ✅ MCP config valid (${serverCount} servers configured)`,
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
// Check for required StringRay servers
|
|
264
|
+
const requiredServers = [
|
|
265
|
+
"researcher",
|
|
266
|
+
"session-management",
|
|
267
|
+
"orchestrator",
|
|
268
|
+
"enforcer",
|
|
269
|
+
"api-design",
|
|
270
|
+
"architecture-patterns",
|
|
271
|
+
"git-workflow",
|
|
272
|
+
"performance-optimization",
|
|
273
|
+
"project-analysis",
|
|
274
|
+
"testing-strategy",
|
|
275
|
+
"code-review",
|
|
276
|
+
"security-audit",
|
|
277
|
+
"ui-ux-design",
|
|
278
|
+
"refactoring-strategies",
|
|
279
|
+
"testing-best-practices",
|
|
280
|
+
];
|
|
281
|
+
|
|
282
|
+
let missingServers = [];
|
|
283
|
+
for (const server of requiredServers) {
|
|
284
|
+
if (!mcpConfig.mcpServers[server]) {
|
|
285
|
+
missingServers.push(server);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
if (missingServers.length === 0) {
|
|
290
|
+
console.log(" ✅ All required StringRay MCP servers configured");
|
|
291
|
+
this.results.passed.push("MCP Server Configuration");
|
|
292
|
+
} else {
|
|
293
|
+
console.log(` ❌ Missing MCP servers: ${missingServers.join(", ")}`);
|
|
294
|
+
this.results.failed.push({
|
|
295
|
+
test: "MCP Server Configuration",
|
|
296
|
+
error: `Missing MCP servers: ${missingServers.join(", ")}`,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
} else {
|
|
300
|
+
console.log(" ❌ Invalid MCP configuration structure");
|
|
301
|
+
this.results.failed.push({
|
|
302
|
+
test: "MCP Server Configuration",
|
|
303
|
+
error: "Invalid MCP configuration structure",
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
} catch (error) {
|
|
307
|
+
console.log(` ❌ Error validating MCP config: ${error.message}`);
|
|
308
|
+
this.results.failed.push({
|
|
309
|
+
test: "MCP Server Configuration",
|
|
310
|
+
error: error.message,
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
printSummary() {
|
|
316
|
+
console.log("\n📊 POSTINSTALL CONFIGURATION SUMMARY");
|
|
317
|
+
console.log("=====================================");
|
|
318
|
+
|
|
319
|
+
console.log(`✅ Passed: ${this.results.passed.length}`);
|
|
320
|
+
console.log(`❌ Failed: ${this.results.failed.length}`);
|
|
321
|
+
|
|
322
|
+
if (this.results.failed.length > 0) {
|
|
323
|
+
console.log("\n❌ FAILED TESTS:");
|
|
324
|
+
this.results.failed.forEach((failure) => {
|
|
325
|
+
console.log(` • ${failure.test}: ${failure.error}`);
|
|
326
|
+
});
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
if (this.results.passed.length > 0) {
|
|
330
|
+
console.log("\n✅ PASSED TESTS:");
|
|
331
|
+
this.results.passed.forEach((test) => {
|
|
332
|
+
console.log(` • ${test}`);
|
|
333
|
+
});
|
|
334
|
+
}
|
|
76
335
|
}
|
|
77
|
-
process.exit(0);
|
|
78
336
|
}
|
|
337
|
+
|
|
338
|
+
// Run postinstall configuration validation
|
|
339
|
+
const validator = new PostinstallConfigValidator();
|
|
340
|
+
validator
|
|
341
|
+
.validateConfiguration()
|
|
342
|
+
.then((success) => {
|
|
343
|
+
process.exit(success ? 0 : 1);
|
|
344
|
+
})
|
|
345
|
+
.catch((error) => {
|
|
346
|
+
console.error("Postinstall configuration validation failed:", error);
|
|
347
|
+
process.exit(1);
|
|
348
|
+
});
|
|
@@ -377,56 +377,25 @@ if (!isHermes && isConsumerEnvironment) {
|
|
|
377
377
|
|
|
378
378
|
console.log("🔧 StrRay Postinstall: Consumer installation complete - all paths are correctly configured.");
|
|
379
379
|
|
|
380
|
-
//
|
|
380
|
+
// Copy .strray directory for persistent config (never symlink — user may modify local config)
|
|
381
381
|
const strraySource = path.join(packageRoot, '.strray');
|
|
382
382
|
const strrayDest = path.join(targetDir, '.strray');
|
|
383
383
|
|
|
384
384
|
if (fs.existsSync(strraySource)) {
|
|
385
385
|
try {
|
|
386
|
-
// Skip if source === dest (e.g. running postinstall in the dev repo itself)
|
|
387
386
|
const resolvedSource = path.resolve(strraySource);
|
|
388
387
|
const resolvedDest = path.resolve(strrayDest);
|
|
388
|
+
|
|
389
|
+
// Skip if source === dest (running postinstall in the dev repo itself)
|
|
389
390
|
if (resolvedSource === resolvedDest) {
|
|
390
|
-
console.log(`ℹ️ Skipping .strray
|
|
391
|
-
} else {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
const stats = fs.lstatSync(strrayDest);
|
|
395
|
-
|
|
396
|
-
if (stats.isSymbolicLink()) {
|
|
397
|
-
// It's a symlink - check if it points to the right location
|
|
398
|
-
const existingTarget = fs.readlinkSync(strrayDest);
|
|
399
|
-
if (existingTarget === strraySource) {
|
|
400
|
-
console.log(`✅ .strray symlink already exists and is correct`);
|
|
401
|
-
} else {
|
|
402
|
-
// Symlink exists but points to wrong location - remove and recreate
|
|
403
|
-
console.log(`📝 Updating .strray symlink to point to new location...`);
|
|
404
|
-
fs.unlinkSync(strrayDest);
|
|
405
|
-
fs.symlinkSync(strraySource, strrayDest, 'dir');
|
|
406
|
-
console.log(`✅ .strray directory symlinked (updated)`);
|
|
407
|
-
}
|
|
408
|
-
} else if (stats.isDirectory()) {
|
|
409
|
-
// It's a regular directory - backup and create symlink
|
|
410
|
-
const backupName = `.strray.backup.${Date.now()}`;
|
|
411
|
-
console.log(`📝 Backing up existing .strray directory to ${backupName}...`);
|
|
412
|
-
fs.renameSync(strrayDest, path.join(targetDir, backupName));
|
|
413
|
-
fs.symlinkSync(strraySource, strrayDest, 'dir');
|
|
414
|
-
console.log(`✅ .strray directory symlinked (backed up existing)`);
|
|
415
|
-
}
|
|
391
|
+
console.log(`ℹ️ Skipping .strray copy — source and destination are the same`);
|
|
392
|
+
} else if (fs.existsSync(strrayDest)) {
|
|
393
|
+
// .strray already exists — don't overwrite, the user may have local config
|
|
394
|
+
console.log(`ℹ️ .strray directory already exists — keeping existing (user config preserved)`);
|
|
416
395
|
} else {
|
|
417
|
-
//
|
|
418
|
-
fs.symlinkSync(strraySource, strrayDest, 'dir');
|
|
419
|
-
console.log(`✅ .strray directory symlinked`);
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
} catch (error) {
|
|
423
|
-
console.error(`❌ Failed to symlink .strray:`, error.message);
|
|
424
|
-
// Fallback: copy the directory
|
|
425
|
-
try {
|
|
396
|
+
// Copy the directory recursively
|
|
426
397
|
function copyDir(src, dest) {
|
|
427
|
-
|
|
428
|
-
fs.mkdirSync(dest, { recursive: true });
|
|
429
|
-
}
|
|
398
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
430
399
|
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
431
400
|
for (const entry of entries) {
|
|
432
401
|
const srcPath = path.join(src, entry.name);
|
|
@@ -439,10 +408,10 @@ if (fs.existsSync(strraySource)) {
|
|
|
439
408
|
}
|
|
440
409
|
}
|
|
441
410
|
copyDir(strraySource, strrayDest);
|
|
442
|
-
console.log(`✅ .strray directory copied
|
|
443
|
-
} catch (copyError) {
|
|
444
|
-
console.error(`❌ Failed to copy .strray:`, copyError.message);
|
|
411
|
+
console.log(`✅ .strray directory copied`);
|
|
445
412
|
}
|
|
413
|
+
} catch (error) {
|
|
414
|
+
console.error(`❌ Failed to copy .strray:`, error.message);
|
|
446
415
|
}
|
|
447
416
|
}
|
|
448
417
|
|
|
@@ -78,8 +78,8 @@ const CALCULATED_COUNTS = calculateCounts();
|
|
|
78
78
|
const OFFICIAL_VERSIONS = {
|
|
79
79
|
// Framework version
|
|
80
80
|
framework: {
|
|
81
|
-
version: "1.15.
|
|
82
|
-
displayName: "StringRay AI v1.15.
|
|
81
|
+
version: "1.15.29",
|
|
82
|
+
displayName: "StringRay AI v1.15.29",
|
|
83
83
|
lastUpdated: "2026-03-30",
|
|
84
84
|
// Counts (auto-calculated, but can be overridden)
|
|
85
85
|
...CALCULATED_COUNTS,
|