fraim-framework 2.0.147 → 2.0.149
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/ai-hub/server.js +50 -16
- package/index.js +1 -1
- package/package.json +3 -3
- package/public/ai-hub/index.html +67 -67
- package/public/ai-hub/script.js +347 -347
- package/public/ai-hub/styles.css +561 -561
- package/public/first-run/index.html +35 -35
- package/public/first-run/script.js +667 -667
- package/public/first-run/styles.css +73 -73
- package/dist/src/cli/commands/test-mcp.js +0 -171
- package/dist/src/cli/setup/first-run.js +0 -242
- package/dist/src/core/config-writer.js +0 -75
- package/dist/src/core/utils/job-aliases.js +0 -47
- package/dist/src/core/utils/workflow-parser.js +0 -174
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.DEPRECATED_FRAIM_JOB_NAMES = void 0;
|
|
4
|
-
exports.resolveFraimJobName = resolveFraimJobName;
|
|
5
|
-
exports.isListableFraimJob = isListableFraimJob;
|
|
6
|
-
const DEPRECATED_TO_CANONICAL_JOB_MAP = {
|
|
7
|
-
'learn-and-scale': 'upskill-employee',
|
|
8
|
-
'model-behavior': 'upskill-employee',
|
|
9
|
-
'promote-learning': 'upskill-employee',
|
|
10
|
-
'refine-jobs': 'upskill-employee',
|
|
11
|
-
'refine-skills': 'upskill-employee'
|
|
12
|
-
};
|
|
13
|
-
const DIRECT_JOB_ALIASES = {
|
|
14
|
-
'sleep on learnings': 'sleep-on-learnings'
|
|
15
|
-
};
|
|
16
|
-
exports.DEPRECATED_FRAIM_JOB_NAMES = new Set(Object.keys(DEPRECATED_TO_CANONICAL_JOB_MAP));
|
|
17
|
-
function normalizeJobLookupInput(input) {
|
|
18
|
-
return input.trim().toLowerCase().replace(/[_\s]+/g, '-');
|
|
19
|
-
}
|
|
20
|
-
function resolveFraimJobName(input) {
|
|
21
|
-
const normalizedJobName = normalizeJobLookupInput(input);
|
|
22
|
-
const directAliasTarget = DIRECT_JOB_ALIASES[input.trim().toLowerCase()];
|
|
23
|
-
if (directAliasTarget) {
|
|
24
|
-
return {
|
|
25
|
-
requestedJobName: input,
|
|
26
|
-
normalizedJobName,
|
|
27
|
-
canonicalJobName: directAliasTarget
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
const deprecatedAliasTarget = DEPRECATED_TO_CANONICAL_JOB_MAP[normalizedJobName];
|
|
31
|
-
if (deprecatedAliasTarget) {
|
|
32
|
-
return {
|
|
33
|
-
requestedJobName: input,
|
|
34
|
-
normalizedJobName,
|
|
35
|
-
canonicalJobName: deprecatedAliasTarget,
|
|
36
|
-
deprecatedAliasTarget
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
return {
|
|
40
|
-
requestedJobName: input,
|
|
41
|
-
normalizedJobName,
|
|
42
|
-
canonicalJobName: normalizedJobName
|
|
43
|
-
};
|
|
44
|
-
}
|
|
45
|
-
function isListableFraimJob(jobName) {
|
|
46
|
-
return !exports.DEPRECATED_FRAIM_JOB_NAMES.has(normalizeJobLookupInput(jobName));
|
|
47
|
-
}
|
|
@@ -1,174 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.WorkflowParser = void 0;
|
|
4
|
-
const fs_1 = require("fs");
|
|
5
|
-
const path_1 = require("path");
|
|
6
|
-
class WorkflowParser {
|
|
7
|
-
static extractMetadataBlock(content) {
|
|
8
|
-
const frontmatterMatch = content.match(/^---\r?\n([\s\S]+?)\r?\n---/);
|
|
9
|
-
if (frontmatterMatch) {
|
|
10
|
-
try {
|
|
11
|
-
return {
|
|
12
|
-
state: 'valid',
|
|
13
|
-
metadata: JSON.parse(frontmatterMatch[1]),
|
|
14
|
-
bodyStartIndex: frontmatterMatch[0].length
|
|
15
|
-
};
|
|
16
|
-
}
|
|
17
|
-
catch {
|
|
18
|
-
return { state: 'invalid' };
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
const trimmedStart = content.search(/\S/);
|
|
22
|
-
if (trimmedStart === -1 || content[trimmedStart] !== '{') {
|
|
23
|
-
return { state: 'none' };
|
|
24
|
-
}
|
|
25
|
-
let depth = 0;
|
|
26
|
-
let inString = false;
|
|
27
|
-
let escaping = false;
|
|
28
|
-
for (let i = trimmedStart; i < content.length; i++) {
|
|
29
|
-
const ch = content[i];
|
|
30
|
-
if (inString) {
|
|
31
|
-
if (escaping) {
|
|
32
|
-
escaping = false;
|
|
33
|
-
}
|
|
34
|
-
else if (ch === '\\') {
|
|
35
|
-
escaping = true;
|
|
36
|
-
}
|
|
37
|
-
else if (ch === '"') {
|
|
38
|
-
inString = false;
|
|
39
|
-
}
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
if (ch === '"') {
|
|
43
|
-
inString = true;
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
if (ch === '{') {
|
|
47
|
-
depth++;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (ch === '}') {
|
|
51
|
-
depth--;
|
|
52
|
-
if (depth === 0) {
|
|
53
|
-
const bodyStartIndex = i + 1;
|
|
54
|
-
const remainder = content.slice(bodyStartIndex).trimStart();
|
|
55
|
-
// `{...}\n---` is usually malformed frontmatter, not bare JSON metadata.
|
|
56
|
-
if (remainder.startsWith('---')) {
|
|
57
|
-
return { state: 'none' };
|
|
58
|
-
}
|
|
59
|
-
try {
|
|
60
|
-
return {
|
|
61
|
-
state: 'valid',
|
|
62
|
-
metadata: JSON.parse(content.slice(trimmedStart, bodyStartIndex)),
|
|
63
|
-
bodyStartIndex
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
catch {
|
|
67
|
-
return { state: 'invalid' };
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
return { state: 'none' };
|
|
73
|
-
}
|
|
74
|
-
/**
|
|
75
|
-
* Parse a workflow markdown file into a structured definition
|
|
76
|
-
* Supports three formats:
|
|
77
|
-
* 1. Phase-based workflows with JSON frontmatter
|
|
78
|
-
* 2. Phase-based workflows with bare leading JSON metadata
|
|
79
|
-
* 3. Simple workflows without metadata
|
|
80
|
-
*/
|
|
81
|
-
static parse(filePath) {
|
|
82
|
-
if (!(0, fs_1.existsSync)(filePath))
|
|
83
|
-
return null;
|
|
84
|
-
let content = (0, fs_1.readFileSync)(filePath, 'utf-8');
|
|
85
|
-
if (content.charCodeAt(0) === 0xfeff) {
|
|
86
|
-
content = content.slice(1);
|
|
87
|
-
}
|
|
88
|
-
const metadataBlock = this.extractMetadataBlock(content);
|
|
89
|
-
if (metadataBlock.state === 'invalid') {
|
|
90
|
-
return null;
|
|
91
|
-
}
|
|
92
|
-
if (metadataBlock.state === 'valid') {
|
|
93
|
-
return this.parsePhaseBasedWorkflow(filePath, content, metadataBlock.metadata, metadataBlock.bodyStartIndex);
|
|
94
|
-
}
|
|
95
|
-
return this.parseSimpleWorkflow(filePath, content);
|
|
96
|
-
}
|
|
97
|
-
static parsePhaseBasedWorkflow(filePath, content, metadata, bodyStartIndex) {
|
|
98
|
-
const contentAfterMetadata = content.substring(bodyStartIndex).trim();
|
|
99
|
-
const firstPhaseIndex = contentAfterMetadata.search(/^##\s+Phase:/m);
|
|
100
|
-
let overview = '';
|
|
101
|
-
let restOfContent = '';
|
|
102
|
-
if (firstPhaseIndex !== -1) {
|
|
103
|
-
overview = contentAfterMetadata.substring(0, firstPhaseIndex).trim();
|
|
104
|
-
restOfContent = contentAfterMetadata.substring(firstPhaseIndex);
|
|
105
|
-
}
|
|
106
|
-
else {
|
|
107
|
-
overview = contentAfterMetadata;
|
|
108
|
-
}
|
|
109
|
-
const phases = new Map();
|
|
110
|
-
const phaseSections = restOfContent.split(/^##\s+Phase:\s+/m);
|
|
111
|
-
if (!metadata.phases) {
|
|
112
|
-
metadata.phases = {};
|
|
113
|
-
}
|
|
114
|
-
for (let i = 1; i < phaseSections.length; i++) {
|
|
115
|
-
const section = phaseSections[i];
|
|
116
|
-
const sectionLines = section.split('\n');
|
|
117
|
-
const firstLine = sectionLines[0].trim();
|
|
118
|
-
const id = firstLine.split(/[ (]/)[0].trim().toLowerCase();
|
|
119
|
-
phases.set(id, `## Phase: ${section.trim()}`);
|
|
120
|
-
}
|
|
121
|
-
return {
|
|
122
|
-
metadata,
|
|
123
|
-
overview,
|
|
124
|
-
phases,
|
|
125
|
-
isSimple: false,
|
|
126
|
-
path: filePath
|
|
127
|
-
};
|
|
128
|
-
}
|
|
129
|
-
static parseSimpleWorkflow(filePath, content) {
|
|
130
|
-
const workflowName = (0, path_1.basename)(filePath, '.md');
|
|
131
|
-
const metadata = {
|
|
132
|
-
name: workflowName
|
|
133
|
-
};
|
|
134
|
-
return {
|
|
135
|
-
metadata,
|
|
136
|
-
overview: content.trim(),
|
|
137
|
-
phases: new Map(),
|
|
138
|
-
isSimple: true,
|
|
139
|
-
path: filePath
|
|
140
|
-
};
|
|
141
|
-
}
|
|
142
|
-
static parseContent(content, name, path) {
|
|
143
|
-
if (content.charCodeAt(0) === 0xfeff) {
|
|
144
|
-
content = content.slice(1);
|
|
145
|
-
}
|
|
146
|
-
const metadataBlock = this.extractMetadataBlock(content);
|
|
147
|
-
if (metadataBlock.state === 'invalid') {
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
if (metadataBlock.state === 'valid') {
|
|
151
|
-
return this.parsePhaseBasedWorkflow(path || `content:${name}`, content, metadataBlock.metadata, metadataBlock.bodyStartIndex);
|
|
152
|
-
}
|
|
153
|
-
return this.parseSimpleWorkflow(path || `content:${name}`, content);
|
|
154
|
-
}
|
|
155
|
-
static getOverviewFromContent(content, name) {
|
|
156
|
-
const wf = this.parseContent(content, name);
|
|
157
|
-
return wf ? wf.overview : null;
|
|
158
|
-
}
|
|
159
|
-
static getOverview(filePath) {
|
|
160
|
-
const wf = this.parse(filePath);
|
|
161
|
-
return wf ? wf.overview : null;
|
|
162
|
-
}
|
|
163
|
-
static extractDescription(filePath) {
|
|
164
|
-
const wf = this.parse(filePath);
|
|
165
|
-
if (!wf)
|
|
166
|
-
return '';
|
|
167
|
-
const intentMatch = wf.overview.match(/## Intent\s+([\s\S]+?)(?:\r?\n##|$)/);
|
|
168
|
-
if (intentMatch)
|
|
169
|
-
return intentMatch[1].trim().split(/\r?\n/)[0];
|
|
170
|
-
const firstPara = wf.overview.split(/\r?\n/).find(l => l.trim() !== '' && !l.startsWith('#'));
|
|
171
|
-
return firstPara ? firstPara.trim() : '';
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
exports.WorkflowParser = WorkflowParser;
|