fraim 2.0.359 → 2.0.360-next.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/dist/registry/domains.json +159 -0
- package/dist/registry/scripts/domains/catalog.js +112 -0
- package/dist/registry/scripts/learning/entry-authoring.js +63 -25
- package/dist/registry/scripts/learning/run-application.js +12 -2
- package/dist/registry/scripts/learning/run-publication.js +169 -16
- package/dist/registry/scripts/learning-usage/local-runtime.js +1 -3
- package/dist/src/cli/learning/runtime.js +2 -0
- package/dist/src/cli/utils/remote-sync.js +7 -0
- package/dist/src/cli/utils/script-sync-utils.js +4 -0
- package/dist/src/config/learning-domains.js +24 -108
- package/dist/src/core/ai-mentor.js +7 -0
- package/dist/src/core/utils/domain-rule-assembler.js +206 -0
- package/dist/src/core/utils/local-registry-resolver.js +135 -32
- package/dist/src/local-mcp-server/agent-token-prices.js +25 -1
- package/dist/src/local-mcp-server/learning-context-builder.js +94 -36
- package/dist/src/local-mcp-server/stdio-server.js +122 -39
- package/dist/src/mcp/tool-schemas.js +2 -2
- package/dist/src/services/mcp-service.js +35 -16
- package/dist/src/services/registry-service.js +4 -0
- package/package.json +3 -2
- package/dist/registry/scripts/learning/learning-domains.json +0 -80
|
@@ -205,7 +205,7 @@ For read-only diagnosis or delivery verification, use get_fraim_file({ path: "jo
|
|
|
205
205
|
|
|
206
206
|
Examples:
|
|
207
207
|
- get_fraim_file({ path: "skills/communication/active-listening.md" })
|
|
208
|
-
- get_fraim_file({ path: "rules/
|
|
208
|
+
- get_fraim_file({ path: "rules/engineering/engineering.md" })`,
|
|
209
209
|
annotations: readOnlyClosedWorldAnnotations,
|
|
210
210
|
inputSchema: {
|
|
211
211
|
type: 'object',
|
|
@@ -213,7 +213,7 @@ Examples:
|
|
|
213
213
|
...sessionIdProperty,
|
|
214
214
|
path: {
|
|
215
215
|
type: 'string',
|
|
216
|
-
description: 'Path to the file (e.g., skills/communication/active-listening.md, rules/
|
|
216
|
+
description: 'Path to the file (e.g., skills/communication/active-listening.md, rules/engineering/engineering.md, templates/specs/FEATURESPEC-TEMPLATE.md)'
|
|
217
217
|
},
|
|
218
218
|
raw: {
|
|
219
219
|
type: 'boolean',
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.McpService = exports.REQUIRED_QUALITY_FIELDS = exports.QUALITY_SCORE_JOBS = exports.QUALITY_PRODUCING_JOBS = exports.DEFAULT_LAUNCH_PHRASE_MAPPINGS = void 0;
|
|
37
37
|
exports.buildTrainingModeBlock = buildTrainingModeBlock;
|
|
38
|
+
const domain_rule_assembler_1 = require("../core/utils/domain-rule-assembler");
|
|
38
39
|
const fs_1 = require("fs");
|
|
39
40
|
const crypto_1 = require("crypto");
|
|
40
41
|
const job_parser_1 = require("../core/utils/job-parser");
|
|
@@ -311,8 +312,8 @@ class McpService {
|
|
|
311
312
|
header += `These must be filled by the agent/runtime from the active task context.\n\n`;
|
|
312
313
|
}
|
|
313
314
|
if (metadata.type === 'script') {
|
|
314
|
-
header += `\n##
|
|
315
|
-
header += `
|
|
315
|
+
header += `\n## Script execution\n\n`;
|
|
316
|
+
header += `Use the synchronized installed script with the arguments supplied by its owning skill. If it is missing or stale, restore synchronization before execution.\n\n`;
|
|
316
317
|
}
|
|
317
318
|
header += `---\n\n`;
|
|
318
319
|
return {
|
|
@@ -421,12 +422,9 @@ class McpService {
|
|
|
421
422
|
console.error(`❌ McpService: Failed to fetch executionMode for ${jobName}:`, e);
|
|
422
423
|
}
|
|
423
424
|
}
|
|
424
|
-
return {
|
|
425
|
-
content: [{
|
|
426
|
-
|
|
427
|
-
text: response
|
|
428
|
-
}]
|
|
429
|
-
};
|
|
425
|
+
return this.addRuleDelivery({
|
|
426
|
+
content: [{ type: 'text', text: response }]
|
|
427
|
+
}, jobName);
|
|
430
428
|
}
|
|
431
429
|
async handleListJobs() {
|
|
432
430
|
const jobs = Array.from(this.registryService.getFileIndex().values()).filter((f) => f.type === 'job' && !f.isStub);
|
|
@@ -574,7 +572,7 @@ class McpService {
|
|
|
574
572
|
}
|
|
575
573
|
// Learning context is injected by the local proxy (learning-context-builder.ts)
|
|
576
574
|
// after this response is received, because learning files live in the local workspace.
|
|
577
|
-
return {
|
|
575
|
+
return this.addRuleDelivery({
|
|
578
576
|
content: [{
|
|
579
577
|
type: 'text',
|
|
580
578
|
text: lines.join('\n')
|
|
@@ -587,7 +585,7 @@ class McpService {
|
|
|
587
585
|
repo: session.repo
|
|
588
586
|
},
|
|
589
587
|
sessionId: sessionId
|
|
590
|
-
};
|
|
588
|
+
});
|
|
591
589
|
}
|
|
592
590
|
validateIssueTrackingConfig(issueTracking) {
|
|
593
591
|
if (!issueTracking.provider) {
|
|
@@ -708,7 +706,8 @@ class McpService {
|
|
|
708
706
|
};
|
|
709
707
|
}
|
|
710
708
|
async handleSeekMentoring(args, userId) {
|
|
711
|
-
const
|
|
709
|
+
const restoringInstructions = args.status === 'starting' && args.requestInstructions === true;
|
|
710
|
+
const personaLock = await this.maybeBuildPersonaLockResponse(args.jobName, userId, undefined, args.status === 'starting' && !restoringInstructions);
|
|
712
711
|
if (personaLock) {
|
|
713
712
|
return personaLock;
|
|
714
713
|
}
|
|
@@ -827,7 +826,7 @@ class McpService {
|
|
|
827
826
|
let phaseStartWarning = '';
|
|
828
827
|
const sessionId = typeof args.sessionId === 'string' ? args.sessionId.trim() : '';
|
|
829
828
|
const isPhaseCompletion = args.status === 'complete' || args.status === 'failure';
|
|
830
|
-
if (sessionId && sessionId !== 'unknown') {
|
|
829
|
+
if (!restoringInstructions && sessionId && sessionId !== 'unknown') {
|
|
831
830
|
const markerKey = JSON.stringify([userId ?? null, sessionId, args.jobName]);
|
|
832
831
|
const context = {
|
|
833
832
|
sessionId,
|
|
@@ -864,7 +863,7 @@ class McpService {
|
|
|
864
863
|
phaseStartWarning = `Phase-start notice: phase \`${args.currentPhase}\` has no identifiable session, so its start cannot be matched to this run. The missing match was flagged, but this completion remains accepted.\n\n`;
|
|
865
864
|
}
|
|
866
865
|
// Update job execution tracking using usage events
|
|
867
|
-
if (canTrackJob && userId && this.analyticsService) {
|
|
866
|
+
if (!restoringInstructions && canTrackJob && userId && this.analyticsService) {
|
|
868
867
|
try {
|
|
869
868
|
const sessionId = args.sessionId || 'unknown';
|
|
870
869
|
await this.analyticsService.logMentoringCall(args.jobId, args.jobName, userId, sessionId, args.currentPhase, args.status, result.nextPhase, result.message ? true : false);
|
|
@@ -885,7 +884,7 @@ class McpService {
|
|
|
885
884
|
}
|
|
886
885
|
// Issue #1345: persist executionModeUpdate from findings when present.
|
|
887
886
|
const executionModeUpdate = args.findings?.executionModeUpdate;
|
|
888
|
-
if (userId && executionModeUpdate && typeof executionModeUpdate['jobName'] === 'string') {
|
|
887
|
+
if (!restoringInstructions && userId && executionModeUpdate && typeof executionModeUpdate['jobName'] === 'string') {
|
|
889
888
|
try {
|
|
890
889
|
await this.dbService.upsertJobExecutionMode(userId, executionModeUpdate);
|
|
891
890
|
}
|
|
@@ -893,13 +892,33 @@ class McpService {
|
|
|
893
892
|
console.error(`❌ McpService: Failed to upsert executionMode:`, e);
|
|
894
893
|
}
|
|
895
894
|
}
|
|
896
|
-
return {
|
|
895
|
+
return this.addRuleDelivery({
|
|
897
896
|
content: [{
|
|
898
897
|
type: 'text',
|
|
899
898
|
text: trackingWarning + phaseStartWarning + result.message
|
|
900
899
|
}],
|
|
901
900
|
structuredContent: { phaseAccepted: true, nextPhase: result.nextPhase, phaseStartWarning }
|
|
902
|
-
};
|
|
901
|
+
}, args.jobName, args);
|
|
902
|
+
}
|
|
903
|
+
async addRuleDelivery(response, jobName, phaseArgs) {
|
|
904
|
+
if (response.isError || response.personaLock)
|
|
905
|
+
return response;
|
|
906
|
+
const context = jobName ? await this.aiMentor.getRuleDeliveryContext(jobName) : null;
|
|
907
|
+
if (jobName && !context)
|
|
908
|
+
return response;
|
|
909
|
+
if (phaseArgs && !(phaseArgs.status === 'starting' && (phaseArgs.currentPhase === 'starting' || phaseArgs.currentPhase === context?.initialPhase || phaseArgs.requestInstructions === true)))
|
|
910
|
+
return response;
|
|
911
|
+
const assembly = await (0, domain_rule_assembler_1.assembleDomainRules)({ jobPath: context?.jobPath, resolveFile: async (path) => {
|
|
912
|
+
const content = await this.registryService.getFile(path);
|
|
913
|
+
if (content === null)
|
|
914
|
+
throw new Error(`Rule source unavailable: ${path}`);
|
|
915
|
+
return { content, source: 'remote', personalized: false, inherited: false };
|
|
916
|
+
} });
|
|
917
|
+
const result = (0, domain_rule_assembler_1.attachRuleAssembly)(response, assembly);
|
|
918
|
+
for (const warning of assembly.metadata.warnings) {
|
|
919
|
+
console.warn('Rule delivery warning:', JSON.stringify(warning));
|
|
920
|
+
}
|
|
921
|
+
return result;
|
|
903
922
|
}
|
|
904
923
|
getJobDescription(jobName, fullPath) {
|
|
905
924
|
if (fullPath && (0, fs_1.existsSync)(fullPath)) {
|
|
@@ -308,6 +308,10 @@ class RegistryService {
|
|
|
308
308
|
}
|
|
309
309
|
getSyncBundle() {
|
|
310
310
|
const files = [];
|
|
311
|
+
const domainCatalog = (0, path_1.join)(this.registryPath, 'domains.json');
|
|
312
|
+
if ((0, fs_1.existsSync)(domainCatalog)) {
|
|
313
|
+
files.push({ path: 'domains.json', content: (0, fs_1.readFileSync)(domainCatalog, 'utf8'), type: 'config' });
|
|
314
|
+
}
|
|
311
315
|
const allFiles = Array.from(this.fileIndex.values());
|
|
312
316
|
// 1. Add job STUBS (not full jobs) from registry/stubs/jobs
|
|
313
317
|
const jobStubs = allFiles.filter(f => f.type === 'job' && f.path.includes('stubs/jobs/'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fraim",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.360-next.1",
|
|
4
4
|
"description": "FRAIM core CLI and MCP package.",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"bin": {
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
"files": [
|
|
10
10
|
"dist/registry/scripts/artifact-paths.js",
|
|
11
11
|
"dist/registry/scripts/learning-usage/local-runtime.js",
|
|
12
|
-
"dist/registry/
|
|
12
|
+
"dist/registry/domains.json",
|
|
13
|
+
"dist/registry/scripts/domains/catalog.js",
|
|
13
14
|
"dist/registry/scripts/learning/entry-format.js",
|
|
14
15
|
"dist/registry/scripts/learning/completion-state.js",
|
|
15
16
|
"dist/registry/scripts/learning/corpus-audit.js",
|
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"schemaVersion": 1,
|
|
3
|
-
"mapVersion": 1,
|
|
4
|
-
"domains": [
|
|
5
|
-
"engineering",
|
|
6
|
-
"product",
|
|
7
|
-
"go-to-market",
|
|
8
|
-
"people-ops",
|
|
9
|
-
"finance",
|
|
10
|
-
"legal",
|
|
11
|
-
"compliance",
|
|
12
|
-
"customer",
|
|
13
|
-
"company-building",
|
|
14
|
-
"operations"
|
|
15
|
-
],
|
|
16
|
-
"jobDomainMap": {
|
|
17
|
-
"engineering": "engineering",
|
|
18
|
-
"product-building": "engineering",
|
|
19
|
-
"dev-ops": "engineering",
|
|
20
|
-
"quality-assurance": "engineering",
|
|
21
|
-
"migration": "engineering",
|
|
22
|
-
"replicate": "engineering",
|
|
23
|
-
"reviewer": "engineering",
|
|
24
|
-
"security": "engineering",
|
|
25
|
-
"delivery-ops": "engineering",
|
|
26
|
-
"salesforce": "engineering",
|
|
27
|
-
"ai-engineering": "engineering",
|
|
28
|
-
"product-management": "product",
|
|
29
|
-
"customer-development": "product",
|
|
30
|
-
"brainstorming": "product",
|
|
31
|
-
"marketing": "go-to-market",
|
|
32
|
-
"branding": "go-to-market",
|
|
33
|
-
"sales": "go-to-market",
|
|
34
|
-
"go-to-market": "go-to-market",
|
|
35
|
-
"business-development": "go-to-market",
|
|
36
|
-
"commercial-ops": "go-to-market",
|
|
37
|
-
"people-ops": "people-ops",
|
|
38
|
-
"recruiting": "people-ops",
|
|
39
|
-
"inclusion-ops": "people-ops",
|
|
40
|
-
"career": "people-ops",
|
|
41
|
-
"finance": "finance",
|
|
42
|
-
"invoicing": "finance",
|
|
43
|
-
"banking": "finance",
|
|
44
|
-
"legal": "legal",
|
|
45
|
-
"compliance": "compliance",
|
|
46
|
-
"customer-success": "customer",
|
|
47
|
-
"customer-communication": "customer",
|
|
48
|
-
"company-creation": "company-building",
|
|
49
|
-
"bootstrap": "company-building",
|
|
50
|
-
"fundraising": "company-building",
|
|
51
|
-
"business-ops": "operations",
|
|
52
|
-
"procurement": "operations",
|
|
53
|
-
"project-management": "operations"
|
|
54
|
-
},
|
|
55
|
-
"globalJobCategories": [
|
|
56
|
-
"manager",
|
|
57
|
-
"fraim",
|
|
58
|
-
"1-1",
|
|
59
|
-
"coaching",
|
|
60
|
-
"delegation",
|
|
61
|
-
"hiring",
|
|
62
|
-
"productivity",
|
|
63
|
-
"project-setup",
|
|
64
|
-
"setup-guardrails",
|
|
65
|
-
"team-learning",
|
|
66
|
-
"verification"
|
|
67
|
-
],
|
|
68
|
-
"domainVoice": {
|
|
69
|
-
"engineering": "Precise and technical; file paths, commands, and test names are appropriate.",
|
|
70
|
-
"product": "Product and user-outcome language; behavior and flow, not code symbols.",
|
|
71
|
-
"go-to-market": "Marketing and sales language; campaigns, funnels, messaging, audience.",
|
|
72
|
-
"people-ops": "Plain HR and recruiting language; no engineering jargon.",
|
|
73
|
-
"finance": "Finance and accounting language; figures, close, forecasts.",
|
|
74
|
-
"legal": "Contract and IP language; obligations, clauses, risk.",
|
|
75
|
-
"compliance": "Controls, evidence, and regulation language.",
|
|
76
|
-
"customer": "Customer-relationship and support language.",
|
|
77
|
-
"company-building": "Founder and operations language; setup, entity, funding.",
|
|
78
|
-
"operations": "Business-operations language; process, vendors, planning, coordination."
|
|
79
|
-
}
|
|
80
|
-
}
|