fraim-framework 2.0.76 → 2.0.78
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/dist/src/cli/commands/add-ide.js +25 -11
- package/dist/src/cli/commands/init-project.js +42 -40
- package/dist/src/cli/commands/setup.js +125 -15
- package/dist/src/cli/setup/auto-mcp-setup.js +27 -10
- package/dist/src/cli/setup/mcp-config-generator.js +153 -39
- package/dist/src/cli/setup/token-validator.js +8 -0
- package/dist/src/cli/utils/platform-detection.js +45 -0
- package/dist/src/core/config-loader.js +4 -1
- package/dist/src/core/utils/provider-utils.js +5 -1
- package/dist/src/local-mcp-server/stdio-server.js +237 -59
- package/package.json +1 -1
|
@@ -106,19 +106,49 @@ class FraimTemplateEngine {
|
|
|
106
106
|
return null;
|
|
107
107
|
}
|
|
108
108
|
substitutePlatformActions(content) {
|
|
109
|
-
const
|
|
110
|
-
const
|
|
111
|
-
|
|
112
|
-
|
|
109
|
+
const codeProvider = this.getCodeProvider();
|
|
110
|
+
const issueProvider = this.getIssueProvider();
|
|
111
|
+
const codeTemplates = this.loadProviderTemplates(codeProvider);
|
|
112
|
+
const issueTemplates = issueProvider ? this.loadProviderTemplates(issueProvider) : null;
|
|
113
113
|
let result = content;
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
114
|
+
if (issueTemplates) {
|
|
115
|
+
for (const [action, template] of Object.entries(issueTemplates)) {
|
|
116
|
+
if (!FraimTemplateEngine.ISSUE_ACTIONS.has(action))
|
|
117
|
+
continue;
|
|
118
|
+
const escapedAction = action.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
119
|
+
const regex = new RegExp(`\\{\\{${FraimTemplateEngine.PROXY_ACTION_PREFIX}${escapedAction}\\}\\}`, 'g');
|
|
120
|
+
result = result.replace(regex, this.renderActionTemplate(template));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (codeTemplates) {
|
|
124
|
+
for (const [action, template] of Object.entries(codeTemplates)) {
|
|
125
|
+
if (issueProvider && issueProvider !== codeProvider && FraimTemplateEngine.ISSUE_ACTIONS.has(action))
|
|
126
|
+
continue;
|
|
127
|
+
const escapedAction = action.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
128
|
+
const regex = new RegExp(`\\{\\{${FraimTemplateEngine.PROXY_ACTION_PREFIX}${escapedAction}\\}\\}`, 'g');
|
|
129
|
+
result = result.replace(regex, this.renderActionTemplate(template));
|
|
130
|
+
}
|
|
119
131
|
}
|
|
120
132
|
return result;
|
|
121
133
|
}
|
|
134
|
+
getCodeProvider() {
|
|
135
|
+
const repoProvider = this.repoInfo?.provider || this.config?.repository?.provider;
|
|
136
|
+
if (typeof repoProvider === 'string' && repoProvider.trim().length > 0) {
|
|
137
|
+
return repoProvider;
|
|
138
|
+
}
|
|
139
|
+
return (0, provider_utils_1.detectProvider)(this.repoInfo?.url || this.config?.repository?.url);
|
|
140
|
+
}
|
|
141
|
+
getIssueProvider() {
|
|
142
|
+
const fromRepoInfo = this.repoInfo?.issueTracking?.provider;
|
|
143
|
+
if (typeof fromRepoInfo === 'string' && fromRepoInfo.trim().length > 0) {
|
|
144
|
+
return fromRepoInfo;
|
|
145
|
+
}
|
|
146
|
+
const fromConfig = this.config?.issueTracking?.provider;
|
|
147
|
+
if (typeof fromConfig === 'string' && fromConfig.trim().length > 0) {
|
|
148
|
+
return fromConfig;
|
|
149
|
+
}
|
|
150
|
+
return null;
|
|
151
|
+
}
|
|
122
152
|
loadProviderTemplates(provider) {
|
|
123
153
|
if (this.providerTemplatesCache[provider])
|
|
124
154
|
return this.providerTemplatesCache[provider];
|
|
@@ -130,11 +160,12 @@ class FraimTemplateEngine {
|
|
|
130
160
|
return null;
|
|
131
161
|
}
|
|
132
162
|
renderActionTemplate(template) {
|
|
133
|
-
if (!this.repoInfo && !this.config?.repository) {
|
|
163
|
+
if (!this.repoInfo && !this.config?.repository && !this.config?.issueTracking) {
|
|
134
164
|
return template;
|
|
135
165
|
}
|
|
136
166
|
return template.replace(/\{\{([^}]+)\}\}/g, (match, path) => {
|
|
137
167
|
const trimmedPath = path.trim();
|
|
168
|
+
// Handle proxy.repository.* variables
|
|
138
169
|
if (trimmedPath.startsWith('proxy.repository.')) {
|
|
139
170
|
const repoPath = trimmedPath.substring('proxy.repository.'.length);
|
|
140
171
|
if (this.repoInfo) {
|
|
@@ -148,12 +179,36 @@ class FraimTemplateEngine {
|
|
|
148
179
|
return String(value);
|
|
149
180
|
}
|
|
150
181
|
}
|
|
182
|
+
// Handle proxy.issueTracking.* variables (for split provider mode)
|
|
183
|
+
if (trimmedPath.startsWith('proxy.issueTracking.')) {
|
|
184
|
+
const issueTrackingPath = trimmedPath.substring('proxy.issueTracking.'.length);
|
|
185
|
+
if (this.repoInfo?.issueTracking) {
|
|
186
|
+
const value = (0, object_utils_1.getNestedValue)(this.repoInfo.issueTracking, issueTrackingPath);
|
|
187
|
+
if (value !== undefined)
|
|
188
|
+
return String(value);
|
|
189
|
+
}
|
|
190
|
+
if (this.config?.issueTracking) {
|
|
191
|
+
const value = (0, object_utils_1.getNestedValue)(this.config.issueTracking, issueTrackingPath);
|
|
192
|
+
if (value !== undefined)
|
|
193
|
+
return String(value);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
151
196
|
return match;
|
|
152
197
|
});
|
|
153
198
|
}
|
|
154
199
|
}
|
|
155
200
|
exports.FraimTemplateEngine = FraimTemplateEngine;
|
|
156
201
|
FraimTemplateEngine.PROXY_ACTION_PREFIX = 'proxy.action.';
|
|
202
|
+
FraimTemplateEngine.ISSUE_ACTIONS = new Set([
|
|
203
|
+
'get_issue',
|
|
204
|
+
'update_issue_status',
|
|
205
|
+
'add_issue_comment',
|
|
206
|
+
'create_issue',
|
|
207
|
+
'assign_issue',
|
|
208
|
+
'search_issues',
|
|
209
|
+
'close_issue',
|
|
210
|
+
'list_issues'
|
|
211
|
+
]);
|
|
157
212
|
class FraimLocalMCPServer {
|
|
158
213
|
constructor() {
|
|
159
214
|
this.config = null;
|
|
@@ -365,48 +420,71 @@ class FraimLocalMCPServer {
|
|
|
365
420
|
}).trim();
|
|
366
421
|
}
|
|
367
422
|
catch (error) {
|
|
368
|
-
// If git command fails, construct URL from config if available
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
423
|
+
// If git command fails, construct URL from config if available.
|
|
424
|
+
const repositoryConfig = this.config?.repository;
|
|
425
|
+
if (repositoryConfig?.url) {
|
|
426
|
+
repoUrl = repositoryConfig.url;
|
|
427
|
+
this.log(`Constructed repo URL from config: ${repoUrl}`);
|
|
428
|
+
}
|
|
429
|
+
else if (repositoryConfig?.provider === 'github' && repositoryConfig.owner && repositoryConfig.name) {
|
|
430
|
+
repoUrl = `https://github.com/${repositoryConfig.owner}/${repositoryConfig.name}.git`;
|
|
431
|
+
this.log(`Constructed repo URL from config: ${repoUrl}`);
|
|
432
|
+
}
|
|
433
|
+
else if (repositoryConfig?.provider === 'ado' &&
|
|
434
|
+
repositoryConfig.organization &&
|
|
435
|
+
repositoryConfig.project &&
|
|
436
|
+
repositoryConfig.name) {
|
|
437
|
+
repoUrl = `https://dev.azure.com/${repositoryConfig.organization}/${repositoryConfig.project}/_git/${repositoryConfig.name}`;
|
|
438
|
+
this.log(`Constructed repo URL from config: ${repoUrl}`);
|
|
439
|
+
}
|
|
440
|
+
else if (repositoryConfig?.provider === 'gitlab') {
|
|
441
|
+
const projectPath = repositoryConfig.projectPath
|
|
442
|
+
|| (repositoryConfig.namespace && repositoryConfig.name
|
|
443
|
+
? `${repositoryConfig.namespace}/${repositoryConfig.name}`
|
|
444
|
+
: null);
|
|
445
|
+
if (projectPath) {
|
|
446
|
+
repoUrl = `https://gitlab.com/${projectPath}.git`;
|
|
447
|
+
this.log(`Constructed repo URL from config: ${repoUrl}`);
|
|
377
448
|
}
|
|
378
|
-
this.log(`📋 Constructed repo URL from config: ${repoUrl}`);
|
|
379
449
|
}
|
|
380
450
|
}
|
|
381
451
|
if (!repoUrl) {
|
|
382
|
-
this.log('
|
|
452
|
+
this.log('No git repository found and no config available');
|
|
383
453
|
return null;
|
|
384
454
|
}
|
|
385
|
-
// Parse
|
|
386
|
-
let owner = '';
|
|
455
|
+
// Parse repository identity from URL
|
|
387
456
|
let name = '';
|
|
457
|
+
let owner = '';
|
|
388
458
|
let organization = '';
|
|
389
459
|
let project = '';
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
const
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
460
|
+
let namespace = '';
|
|
461
|
+
let projectPath = '';
|
|
462
|
+
const githubMatch = repoUrl.match(/github\.com[\/:]([^\/]+)\/([^\/\.]+)/i);
|
|
463
|
+
const adoMatch = repoUrl.match(/dev\.azure\.com\/([^\/]+)\/([^\/]+)\/_git\/([^\/]+)/i);
|
|
464
|
+
const gitlabMatch = repoUrl.match(/gitlab[^\/:]*[\/:]([^?\s#]+?)(?:\.git)?$/i);
|
|
465
|
+
if (githubMatch) {
|
|
466
|
+
owner = githubMatch[1];
|
|
467
|
+
name = githubMatch[2];
|
|
396
468
|
}
|
|
397
469
|
else if (adoMatch) {
|
|
398
|
-
// Azure DevOps: organization and project are separate fields
|
|
399
470
|
organization = adoMatch[1];
|
|
400
471
|
project = adoMatch[2];
|
|
401
|
-
owner = organization; // For compatibility
|
|
402
472
|
name = adoMatch[3];
|
|
403
473
|
}
|
|
474
|
+
else if (gitlabMatch) {
|
|
475
|
+
projectPath = gitlabMatch[1].replace(/^\/+/, '');
|
|
476
|
+
const segments = projectPath.split('/').filter(Boolean);
|
|
477
|
+
name = segments[segments.length - 1] || '';
|
|
478
|
+
namespace = segments.slice(0, -1).join('/');
|
|
479
|
+
}
|
|
404
480
|
else if (this.config?.repository) {
|
|
405
481
|
// Fall back to config if URL parsing fails
|
|
406
482
|
owner = this.config.repository.owner || '';
|
|
407
483
|
name = this.config.repository.name || '';
|
|
408
484
|
organization = this.config.repository.organization || '';
|
|
409
485
|
project = this.config.repository.project || '';
|
|
486
|
+
namespace = this.config.repository.namespace || '';
|
|
487
|
+
projectPath = this.config.repository.projectPath || (namespace && name ? `${namespace}/${name}` : '');
|
|
410
488
|
}
|
|
411
489
|
// Get current branch
|
|
412
490
|
let branch = '';
|
|
@@ -423,15 +501,23 @@ class FraimLocalMCPServer {
|
|
|
423
501
|
branch = this.config.repository.defaultBranch;
|
|
424
502
|
}
|
|
425
503
|
}
|
|
426
|
-
|
|
504
|
+
const repoInfo = {
|
|
427
505
|
url: repoUrl,
|
|
428
|
-
owner: owner || 'unknown',
|
|
429
506
|
name: name || 'unknown',
|
|
430
507
|
...(organization && { organization }),
|
|
431
508
|
...(project && { project }),
|
|
509
|
+
...(namespace && { namespace }),
|
|
510
|
+
...(projectPath && { projectPath }),
|
|
432
511
|
...(branch && { branch })
|
|
433
512
|
};
|
|
434
|
-
|
|
513
|
+
if (owner) {
|
|
514
|
+
repoInfo.owner = owner;
|
|
515
|
+
}
|
|
516
|
+
this.repoInfo = repoInfo;
|
|
517
|
+
const repoLabel = this.repoInfo.owner
|
|
518
|
+
? `${this.repoInfo.owner}/${this.repoInfo.name}`
|
|
519
|
+
: this.repoInfo.projectPath || this.repoInfo.name;
|
|
520
|
+
this.log(`Detected repo info: ${repoLabel}`);
|
|
435
521
|
return this.repoInfo;
|
|
436
522
|
}
|
|
437
523
|
catch (error) {
|
|
@@ -630,25 +716,57 @@ class FraimLocalMCPServer {
|
|
|
630
716
|
if (!hasDirectProviderPlaceholders && !hasDeliveryPlaceholders)
|
|
631
717
|
return;
|
|
632
718
|
const engine = this.ensureEngine();
|
|
633
|
-
const
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
719
|
+
const codeProvider = engine.getCodeProvider();
|
|
720
|
+
const issueProvider = engine.getIssueProvider();
|
|
721
|
+
const providers = Array.from(new Set([codeProvider, issueProvider].filter((provider) => typeof provider === 'string' && provider.length > 0)));
|
|
722
|
+
for (const provider of providers) {
|
|
723
|
+
if (engine.hasProviderTemplates(provider))
|
|
724
|
+
continue;
|
|
725
|
+
if (engine.loadProviderTemplates(provider))
|
|
726
|
+
continue;
|
|
727
|
+
const filename = `${provider}.json`;
|
|
728
|
+
const cached = this.readCachedTemplateFile(filename);
|
|
729
|
+
if (cached) {
|
|
730
|
+
engine.setProviderTemplates(provider, cached);
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
const remoteContent = await this.fetchRegistryFileFromServer(`providers/${filename}`, requestSessionId);
|
|
734
|
+
if (remoteContent) {
|
|
735
|
+
const parsed = this.parseTemplateJson(remoteContent, `providers/${filename}`);
|
|
736
|
+
if (parsed) {
|
|
737
|
+
engine.setProviderTemplates(provider, parsed);
|
|
738
|
+
this.writeCachedTemplateFile(filename, parsed);
|
|
739
|
+
continue;
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
const bundled = this.readBundledTemplateFile(filename);
|
|
743
|
+
if (bundled) {
|
|
744
|
+
engine.setProviderTemplates(provider, bundled);
|
|
745
|
+
}
|
|
643
746
|
}
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
747
|
+
}
|
|
748
|
+
readBundledTemplateFile(filename) {
|
|
749
|
+
const candidates = [
|
|
750
|
+
(0, path_1.join)(__dirname, '..', '..', '..', 'registry', 'providers', filename),
|
|
751
|
+
(0, path_1.join)(__dirname, '..', '..', 'registry', 'providers', filename),
|
|
752
|
+
(0, path_1.join)(process.cwd(), 'registry', 'providers', filename)
|
|
753
|
+
];
|
|
754
|
+
for (const candidate of candidates) {
|
|
755
|
+
try {
|
|
756
|
+
if (!(0, fs_1.existsSync)(candidate))
|
|
757
|
+
continue;
|
|
758
|
+
const content = (0, fs_1.readFileSync)(candidate, 'utf8');
|
|
759
|
+
const parsed = JSON.parse(content);
|
|
760
|
+
if (parsed && typeof parsed === 'object') {
|
|
761
|
+
this.log(`✅ Loaded bundled provider template: ${candidate}`);
|
|
762
|
+
return parsed;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
catch (error) {
|
|
766
|
+
this.log(`⚠️ Failed to load bundled template ${candidate}: ${error.message}`);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
return null;
|
|
652
770
|
}
|
|
653
771
|
async hydrateTemplateCachesForResponse(response, requestSessionId) {
|
|
654
772
|
if (!response.result)
|
|
@@ -661,10 +779,12 @@ class FraimLocalMCPServer {
|
|
|
661
779
|
let processedResponse = this.processResponse(response);
|
|
662
780
|
// Delivery substitution can introduce provider action placeholders (e.g. {{proxy.action.update_issue_status}})
|
|
663
781
|
// that were not visible pre-substitution. Run one targeted re-hydration pass if needed.
|
|
664
|
-
const provider = (0, provider_utils_1.detectProvider)(this.detectRepoInfo()?.url);
|
|
665
782
|
const engine = this.ensureEngine();
|
|
666
|
-
|
|
667
|
-
|
|
783
|
+
const codeProvider = engine.getCodeProvider();
|
|
784
|
+
const issueProvider = engine.getIssueProvider();
|
|
785
|
+
const providers = Array.from(new Set([codeProvider, issueProvider].filter((provider) => typeof provider === 'string' && provider.length > 0)));
|
|
786
|
+
const hasMissingProviderTemplate = providers.some((provider) => !engine.hasProviderTemplates(provider));
|
|
787
|
+
if (this.responseHasPotentialProviderPlaceholders(processedResponse) && hasMissingProviderTemplate) {
|
|
668
788
|
await this.ensureProviderTemplatesAvailable(processedResponse, requestSessionId);
|
|
669
789
|
processedResponse = this.processResponse(processedResponse);
|
|
670
790
|
}
|
|
@@ -960,6 +1080,44 @@ class FraimLocalMCPServer {
|
|
|
960
1080
|
request.params.arguments.sessionId = requestSessionId;
|
|
961
1081
|
}
|
|
962
1082
|
}
|
|
1083
|
+
normalizeRepoContext(repo) {
|
|
1084
|
+
if (!repo || typeof repo !== 'object')
|
|
1085
|
+
return repo;
|
|
1086
|
+
const normalized = { ...repo };
|
|
1087
|
+
const detectedProvider = (0, provider_utils_1.detectProvider)(normalized.url);
|
|
1088
|
+
if (typeof detectedProvider === 'string' && detectedProvider.length > 0) {
|
|
1089
|
+
normalized.provider = detectedProvider;
|
|
1090
|
+
}
|
|
1091
|
+
if (normalized.provider !== 'gitlab')
|
|
1092
|
+
return normalized;
|
|
1093
|
+
if (!normalized.projectPath && typeof normalized.url === 'string') {
|
|
1094
|
+
const gitlabMatch = normalized.url.match(/gitlab[^\/:]*[\/:]([^?\s#]+?)(?:\.git)?$/i);
|
|
1095
|
+
if (gitlabMatch) {
|
|
1096
|
+
normalized.projectPath = gitlabMatch[1].replace(/^\/+/, '');
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
if (!normalized.name && typeof normalized.projectPath === 'string') {
|
|
1100
|
+
const segments = normalized.projectPath.split('/').filter(Boolean);
|
|
1101
|
+
normalized.name = segments[segments.length - 1] || normalized.name;
|
|
1102
|
+
normalized.namespace = normalized.namespace || segments.slice(0, -1).join('/');
|
|
1103
|
+
}
|
|
1104
|
+
if (normalized.projectPath || !normalized.namespace || !normalized.name)
|
|
1105
|
+
return normalized;
|
|
1106
|
+
normalized.projectPath = `${normalized.namespace}/${normalized.name}`;
|
|
1107
|
+
return normalized;
|
|
1108
|
+
}
|
|
1109
|
+
normalizeIssueTrackingContext(issueTracking) {
|
|
1110
|
+
if (!issueTracking || typeof issueTracking !== 'object')
|
|
1111
|
+
return issueTracking;
|
|
1112
|
+
if (issueTracking.provider !== 'gitlab')
|
|
1113
|
+
return issueTracking;
|
|
1114
|
+
if (issueTracking.projectPath || !issueTracking.namespace || !issueTracking.name)
|
|
1115
|
+
return issueTracking;
|
|
1116
|
+
return {
|
|
1117
|
+
...issueTracking,
|
|
1118
|
+
projectPath: `${issueTracking.namespace}/${issueTracking.name}`
|
|
1119
|
+
};
|
|
1120
|
+
}
|
|
963
1121
|
/**
|
|
964
1122
|
* Proxy request to remote FRAIM server
|
|
965
1123
|
*/
|
|
@@ -988,7 +1146,9 @@ class FraimLocalMCPServer {
|
|
|
988
1146
|
...args.repo, // Agent values as fallback
|
|
989
1147
|
...detectedRepo // Detected values override (always win)
|
|
990
1148
|
};
|
|
991
|
-
|
|
1149
|
+
args.repo = this.normalizeRepoContext(args.repo);
|
|
1150
|
+
const repoLabel = args.repo.owner ? `${args.repo.owner}/${args.repo.name}` : args.repo.name;
|
|
1151
|
+
this.log(`[req:${requestId}] Auto-detected and injected repo info: ${repoLabel}`);
|
|
992
1152
|
}
|
|
993
1153
|
else {
|
|
994
1154
|
// If detection fails, use agent-provided values (if any)
|
|
@@ -1004,12 +1164,30 @@ class FraimLocalMCPServer {
|
|
|
1004
1164
|
}
|
|
1005
1165
|
};
|
|
1006
1166
|
}
|
|
1007
|
-
|
|
1167
|
+
args.repo = this.normalizeRepoContext(args.repo);
|
|
1168
|
+
const repoLabel = args.repo.owner ? `${args.repo.owner}/${args.repo.name}` : args.repo.name;
|
|
1169
|
+
this.log(`[req:${requestId}] Using agent-provided repo info: ${repoLabel}`);
|
|
1008
1170
|
}
|
|
1171
|
+
const configuredIssueTracking = this.config?.issueTracking;
|
|
1172
|
+
if (configuredIssueTracking && typeof configuredIssueTracking === 'object') {
|
|
1173
|
+
args.issueTracking = {
|
|
1174
|
+
...(args.issueTracking || {}),
|
|
1175
|
+
...configuredIssueTracking
|
|
1176
|
+
};
|
|
1177
|
+
args.issueTracking = this.normalizeIssueTrackingContext(args.issueTracking);
|
|
1178
|
+
this.log(`[req:${requestId}] Applied issueTracking context: ${args.issueTracking.provider || 'unknown'}`);
|
|
1179
|
+
}
|
|
1180
|
+
else if (args.issueTracking) {
|
|
1181
|
+
args.issueTracking = this.normalizeIssueTrackingContext(args.issueTracking);
|
|
1182
|
+
}
|
|
1183
|
+
const runtimeRepoContext = {
|
|
1184
|
+
...args.repo,
|
|
1185
|
+
...(args.issueTracking ? { issueTracking: args.issueTracking } : {})
|
|
1186
|
+
};
|
|
1009
1187
|
// Keep proxy runtime repository context in sync with connect payload.
|
|
1010
|
-
this.repoInfo =
|
|
1188
|
+
this.repoInfo = runtimeRepoContext;
|
|
1011
1189
|
if (this.engine) {
|
|
1012
|
-
this.engine.setRepoInfo(
|
|
1190
|
+
this.engine.setRepoInfo(runtimeRepoContext);
|
|
1013
1191
|
}
|
|
1014
1192
|
// Update the request with injected info
|
|
1015
1193
|
request.params.arguments = args;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fraim-framework",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.78",
|
|
4
4
|
"description": "FRAIM v2: Framework for Rigor-based AI Management - Transform from solo developer to AI manager orchestrating production-ready code with enterprise-grade discipline",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|