fraim 2.0.167 → 2.0.168

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.
Files changed (54) hide show
  1. package/dist/src/ai-hub/catalog.js +28 -14
  2. package/dist/src/ai-hub/server.js +10 -403
  3. package/dist/src/cli/commands/init-project.js +1 -98
  4. package/dist/src/cli/commands/manager.js +40 -0
  5. package/dist/src/cli/commands/sync.js +17 -21
  6. package/dist/src/cli/fraim.js +2 -0
  7. package/dist/src/cli/utils/github-workflow-sync.js +12 -146
  8. package/dist/src/cli/utils/manager-pack-sync.js +188 -0
  9. package/dist/src/cli/utils/manager-publish.js +76 -0
  10. package/dist/src/cli/utils/user-config.js +20 -0
  11. package/dist/src/core/fraim-config-schema.generated.js +85 -10
  12. package/dist/src/core/manager-pack.js +26 -0
  13. package/dist/src/first-run/install-state.js +1 -0
  14. package/dist/src/first-run/server.js +9 -0
  15. package/dist/src/first-run/session-service.js +117 -23
  16. package/dist/src/first-run/types.js +2 -5
  17. package/dist/src/local-mcp-server/learning-context-builder.js +45 -8
  18. package/dist/src/local-mcp-server/stdio-server.js +28 -0
  19. package/index.js +1 -1
  20. package/package.json +1 -2
  21. package/public/ai-hub/index.html +0 -81
  22. package/public/ai-hub/powerpoint-taskpane/index.html +236 -236
  23. package/public/ai-hub/powerpoint-taskpane/manifest.xml +29 -29
  24. package/public/ai-hub/script.js +3 -219
  25. package/public/ai-hub/styles.css +8 -36
  26. package/public/first-run/index.html +1 -1
  27. package/public/first-run/script.js +459 -530
  28. package/public/first-run/styles.css +288 -73
  29. package/public/portfolio/ashley.html +1 -1
  30. package/public/portfolio/casey.html +1 -1
  31. package/public/portfolio/celia.html +1 -1
  32. package/public/portfolio/gautam.html +1 -1
  33. package/public/portfolio/hari.html +1 -1
  34. package/public/portfolio/maestro.html +1 -1
  35. package/public/portfolio/mandy.html +1 -1
  36. package/public/portfolio/pam.html +6 -6
  37. package/public/portfolio/qasm.html +1 -1
  38. package/public/portfolio/sade.html +1 -1
  39. package/public/portfolio/sam.html +1 -1
  40. package/public/portfolio/swen.html +6 -6
  41. package/dist/src/ai-hub/word-sideload.js +0 -95
  42. package/dist/src/cli/commands/test-mcp.js +0 -171
  43. package/dist/src/cli/setup/first-run.js +0 -242
  44. package/dist/src/config/ai-manager-hiring.js +0 -121
  45. package/dist/src/config/compat.js +0 -16
  46. package/dist/src/config/feature-flags.js +0 -25
  47. package/dist/src/config/persona-capability-bundles.js +0 -273
  48. package/dist/src/config/persona-hiring.js +0 -270
  49. package/dist/src/config/portfolio-slug-overrides.js +0 -17
  50. package/dist/src/config/pricing.js +0 -37
  51. package/dist/src/config/stripe.js +0 -43
  52. package/dist/src/core/config-writer.js +0 -75
  53. package/dist/src/core/utils/job-aliases.js +0 -47
  54. package/dist/src/core/utils/workflow-parser.js +0 -174
@@ -1,75 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.readFraimConfigRaw = readFraimConfigRaw;
4
- exports.mergeFraimConfig = mergeFraimConfig;
5
- exports.writeFraimConfigUpdate = writeFraimConfigUpdate;
6
- exports.writeFraimConfig = writeFraimConfig;
7
- const fs_1 = require("fs");
8
- const path_1 = require("path");
9
- const config_loader_1 = require("./config-loader");
10
- const types_1 = require("./types");
11
- function isPlainObject(value) {
12
- return typeof value === 'object' && value !== null && !Array.isArray(value);
13
- }
14
- function deepMerge(baseValue, updateValue) {
15
- if (updateValue === undefined) {
16
- return baseValue;
17
- }
18
- if (Array.isArray(updateValue)) {
19
- return [...updateValue];
20
- }
21
- if (!isPlainObject(updateValue)) {
22
- return updateValue;
23
- }
24
- const baseObject = isPlainObject(baseValue) ? baseValue : {};
25
- const merged = { ...baseObject };
26
- for (const [key, value] of Object.entries(updateValue)) {
27
- merged[key] = deepMerge(baseObject[key], value);
28
- }
29
- return merged;
30
- }
31
- function ensureWritableFraimConfigShape(rawConfig) {
32
- const config = { ...rawConfig };
33
- if (typeof config.version !== 'string' || config.version.trim().length === 0) {
34
- config.version = types_1.DEFAULT_FRAIM_CONFIG.version;
35
- }
36
- const projectConfig = isPlainObject(config.project) ? config.project : {};
37
- config.project = {
38
- ...types_1.DEFAULT_FRAIM_CONFIG.project,
39
- ...projectConfig
40
- };
41
- const customizationsConfig = isPlainObject(config.customizations) ? config.customizations : {};
42
- config.customizations = {
43
- ...types_1.DEFAULT_FRAIM_CONFIG.customizations,
44
- ...customizationsConfig
45
- };
46
- return config;
47
- }
48
- function readFraimConfigRaw(configPath) {
49
- if (!(0, fs_1.existsSync)(configPath)) {
50
- return {};
51
- }
52
- const parsed = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf8'));
53
- if (!isPlainObject(parsed)) {
54
- throw new Error('FRAIM config must contain a JSON object at the top level.');
55
- }
56
- return parsed;
57
- }
58
- function mergeFraimConfig(existingRawConfig, update) {
59
- const rawConfig = ensureWritableFraimConfigShape(deepMerge(existingRawConfig, update));
60
- return {
61
- config: (0, config_loader_1.normalizeFraimConfig)(rawConfig),
62
- created: Object.keys(existingRawConfig).length === 0,
63
- rawConfig
64
- };
65
- }
66
- function writeFraimConfigUpdate(configPath, update) {
67
- const existingRawConfig = readFraimConfigRaw(configPath);
68
- const result = mergeFraimConfig(existingRawConfig, update);
69
- (0, fs_1.mkdirSync)((0, path_1.dirname)(configPath), { recursive: true });
70
- (0, fs_1.writeFileSync)(configPath, JSON.stringify(result.rawConfig, null, 2));
71
- return result;
72
- }
73
- function writeFraimConfig(configPath, config) {
74
- return writeFraimConfigUpdate(configPath, config);
75
- }
@@ -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;