fraim-framework 2.0.26 → 2.0.27

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.
@@ -12,6 +12,7 @@ const first_run_js_1 = require("../setup/first-run.js");
12
12
  const sync_js_1 = require("./sync.js");
13
13
  const types_js_1 = require("../../fraim/types.js");
14
14
  const git_utils_js_1 = require("../../utils/git-utils.js");
15
+ const version_utils_js_1 = require("../../utils/version-utils.js");
15
16
  const runInit = async () => {
16
17
  const projectRoot = process.cwd();
17
18
  const fraimDir = path_1.default.join(projectRoot, '.fraim');
@@ -28,6 +29,7 @@ const runInit = async () => {
28
29
  const remoteInfo = (0, git_utils_js_1.getGitRemoteInfo)();
29
30
  const config = {
30
31
  ...types_js_1.DEFAULT_FRAIM_CONFIG,
32
+ version: (0, version_utils_js_1.getFraimVersion)(),
31
33
  project: {
32
34
  ...types_js_1.DEFAULT_FRAIM_CONFIG.project,
33
35
  name: path_1.default.basename(projectRoot)
@@ -11,6 +11,7 @@ const chalk_1 = __importDefault(require("chalk"));
11
11
  const digest_utils_1 = require("../../utils/digest-utils");
12
12
  const stub_generator_1 = require("../../utils/stub-generator");
13
13
  const config_loader_js_1 = require("../../fraim/config-loader.js");
14
+ const version_utils_js_1 = require("../../utils/version-utils.js");
14
15
  const runSync = async (options) => {
15
16
  const projectRoot = process.cwd();
16
17
  const config = (0, config_loader_js_1.loadFraimConfig)();
@@ -37,6 +38,22 @@ const runSync = async (options) => {
37
38
  if (!fs_1.default.existsSync(workflowsDir)) {
38
39
  fs_1.default.mkdirSync(workflowsDir, { recursive: true });
39
40
  }
41
+ // Update version in config.json
42
+ const configPath = path_1.default.join(fraimDir, 'config.json');
43
+ if (fs_1.default.existsSync(configPath)) {
44
+ try {
45
+ const currentConfig = JSON.parse(fs_1.default.readFileSync(configPath, 'utf8'));
46
+ const newVersion = (0, version_utils_js_1.getFraimVersion)();
47
+ if (currentConfig.version !== newVersion) {
48
+ currentConfig.version = newVersion;
49
+ fs_1.default.writeFileSync(configPath, JSON.stringify(currentConfig, null, 2));
50
+ console.log(chalk_1.default.green(`✅ Updated FRAIM version to ${newVersion} in config.`));
51
+ }
52
+ }
53
+ catch (e) {
54
+ console.warn(chalk_1.default.yellow('⚠️ Could not update version in config.json.'));
55
+ }
56
+ }
40
57
  console.log(chalk_1.default.blue('🔄 Syncing FRAIM workflows...'));
41
58
  const currentDigest = await (0, digest_utils_1.generateDigest)(registryPath);
42
59
  const existingDigest = fs_1.default.existsSync(digestPath) ? fs_1.default.readFileSync(digestPath, 'utf8') : '';
@@ -38,14 +38,6 @@ function loadFraimConfig() {
38
38
  ...types_1.DEFAULT_FRAIM_CONFIG.customizations,
39
39
  ...(config.customizations || {})
40
40
  },
41
- architecture: {
42
- ...types_1.DEFAULT_FRAIM_CONFIG.architecture,
43
- ...(config.architecture || {})
44
- },
45
- testing: {
46
- ...types_1.DEFAULT_FRAIM_CONFIG.testing,
47
- ...(config.testing || {})
48
- },
49
41
  persona: {
50
42
  ...types_1.DEFAULT_FRAIM_CONFIG.persona,
51
43
  ...(config.persona || {})
@@ -7,8 +7,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
7
7
  exports.generateConfigFromAnswers = generateConfigFromAnswers;
8
8
  exports.writeConfig = writeConfig;
9
9
  exports.createDirectoryStructure = createDirectoryStructure;
10
- exports.generateArchitectureTemplate = generateArchitectureTemplate;
11
- exports.writeArchitectureTemplate = writeArchitectureTemplate;
12
10
  exports.runSetup = runSetup;
13
11
  const fs_1 = require("fs");
14
12
  const path_1 = require("path");
@@ -65,70 +63,6 @@ function createDirectoryStructure() {
65
63
  }
66
64
  }
67
65
  }
68
- /**
69
- * Generate architecture.md template
70
- */
71
- function generateArchitectureTemplate(config) {
72
- const arch = config.architecture;
73
- let template = `# Project Architecture
74
-
75
- This document describes the architecture patterns and conventions for ${config.project.name}.
76
-
77
- ## Overview
78
-
79
- - **Project Name:** ${config.project.name}
80
- - **Project Type:** ${config.project.type || 'Not specified'}
81
- - **Primary Language:** ${config.project.primaryLanguage || 'Not specified'}
82
- - **Database:** ${config.project.database || 'Not specified'}
83
- - **ORM:** ${config.project.orm || 'Not specified'}
84
-
85
- `;
86
- if (arch) {
87
- template += `## Architecture Pattern
88
-
89
- **Pattern:** ${arch.pattern || 'Not specified'}
90
-
91
- `;
92
- if (arch.llmFramework) {
93
- template += `### LLM Integration
94
-
95
- - **Framework:** ${arch.llmFramework}
96
- - **Usage:** ${arch.llmUsage?.join(', ') || 'Not specified'}
97
- - **Deterministic Usage:** ${arch.deterministicUsage?.join(', ') || 'Not specified'}
98
-
99
- `;
100
- }
101
- }
102
- template += `## Development Guidelines
103
-
104
- ### Testing
105
- - **Framework:** ${config.testing?.framework || 'Not specified'}
106
- - **Test Location:** ${config.testing?.testLocation || 'Not specified'}
107
- - **Test Naming:** ${config.testing?.testNaming || 'Not specified'}
108
-
109
- ### Git Workflow
110
- - **Default Branch:** ${config.git.defaultBranch}
111
-
112
- ## Customization
113
-
114
- This project uses FRAIM with customizations in \`.fraim/\`:
115
- - Custom rules: \`.fraim/rules/\`
116
- - Custom workflows: \`.fraim/workflows/\`
117
- - Custom templates: \`.fraim/templates/\`
118
- - Custom scripts: \`.fraim/scripts/\`
119
- `;
120
- return template;
121
- }
122
- /**
123
- * Write architecture.md template
124
- */
125
- function writeArchitectureTemplate(config) {
126
- const fraimDir = (0, path_1.join)(process.cwd(), '.fraim');
127
- const archPath = (0, path_1.join)(fraimDir, 'architecture.md');
128
- const template = generateArchitectureTemplate(config);
129
- (0, fs_1.writeFileSync)(archPath, template, 'utf-8');
130
- console.log(`✅ Created .fraim/architecture.md`);
131
- }
132
66
  /**
133
67
  * Run setup wizard
134
68
  */
@@ -148,11 +82,9 @@ function runSetup(answers) {
148
82
  createDirectoryStructure();
149
83
  // Write config
150
84
  writeConfig(config);
151
- // Write architecture template
152
- writeArchitectureTemplate(config);
153
85
  return {
154
86
  success: true,
155
- message: `✅ FRAIM setup complete!\n\nCreated:\n- .fraim/config.json\n- .fraim/architecture.md\n- Directory structure\n\nNext steps:\n1. Review .fraim/config.json and adjust as needed\n2. Add custom rules to .fraim/rules/\n3. Add custom workflows to .fraim/workflows/\n4. Customize templates in .fraim/templates/`,
87
+ message: `✅ FRAIM setup complete!\n\nCreated:\n- .fraim/config.json\n- Directory structure\n\nNext steps:\n1. Review .fraim/config.json and adjust as needed\n2. Add custom rules to .fraim/rules/\n3. Add custom workflows to .fraim/workflows/\n4. Customize templates in .fraim/templates/`,
156
88
  config
157
89
  };
158
90
  }
@@ -18,17 +18,6 @@ exports.DEFAULT_FRAIM_CONFIG = {
18
18
  repoOwner: '',
19
19
  repoName: ''
20
20
  },
21
- architecture: {
22
- pattern: 'llm-deterministic-separation',
23
- llmFramework: 'baml',
24
- llmUsage: [],
25
- deterministicUsage: ['data-processing', 'api-calls']
26
- },
27
- testing: {
28
- framework: 'tsx-test',
29
- testLocation: 'root',
30
- testNaming: 'test-*.ts'
31
- },
32
21
  customizations: {
33
22
  workflowsPath: '.fraim/workflows'
34
23
  },
@@ -0,0 +1,32 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.getFraimVersion = getFraimVersion;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ function getFraimVersion() {
10
+ // Try reliable paths to find package.json relative to this file
11
+ // locally: src/utils/version-utils.ts -> package.json is ../../package.json
12
+ // dist: dist/src/utils/version-utils.js -> package.json is ../../../package.json
13
+ const possiblePaths = [
14
+ path_1.default.join(__dirname, '../../package.json'), // Local dev (src)
15
+ path_1.default.join(__dirname, '../../../package.json'), // Dist (dist/src)
16
+ path_1.default.join(process.cwd(), 'package.json') // Fallback to CWD (unlikely to be correct for global install but safe fallback)
17
+ ];
18
+ for (const pkgPath of possiblePaths) {
19
+ if (fs_1.default.existsSync(pkgPath)) {
20
+ try {
21
+ const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf-8'));
22
+ if (pkg.name === 'fraim-framework') {
23
+ return pkg.version;
24
+ }
25
+ }
26
+ catch (e) {
27
+ // Ignore parsing errors
28
+ }
29
+ }
30
+ }
31
+ return '1.0.0'; // Fallback
32
+ }
@@ -110,8 +110,6 @@ async function testCliLifecycle() {
110
110
  }
111
111
  node_assert_1.default.ok(config.customizations, 'config.customizations should exist');
112
112
  node_assert_1.default.strictEqual(config.customizations.workflowsPath, '.fraim/workflows');
113
- node_assert_1.default.ok(config.architecture, 'architecture should be in generated config');
114
- node_assert_1.default.ok(config.testing, 'testing should be in generated config');
115
113
  node_assert_1.default.ok(!config.mcp, 'mcp should not be in generated config');
116
114
  // 2. Test `fraim sync`
117
115
  // We need a fake registry for sync to work against
@@ -12,8 +12,6 @@ async function testConfigDefaults() {
12
12
  try {
13
13
  node_assert_1.default.strictEqual(types_1.DEFAULT_FRAIM_CONFIG.persona.name, 'AI Agent', 'Default persona name should be "AI Agent"');
14
14
  node_assert_1.default.ok(types_1.DEFAULT_FRAIM_CONFIG.customizations?.workflowsPath, 'workflowsPath should exist');
15
- node_assert_1.default.ok(types_1.DEFAULT_FRAIM_CONFIG.architecture, 'architecture should be restored');
16
- node_assert_1.default.ok(types_1.DEFAULT_FRAIM_CONFIG.testing, 'testing should be restored');
17
15
  node_assert_1.default.ok(!types_1.DEFAULT_FRAIM_CONFIG.mcp, 'mcp should still be removed');
18
16
  return true;
19
17
  }
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const node_child_process_1 = require("node:child_process");
7
+ const test_utils_1 = require("./test-utils");
8
+ const node_assert_1 = __importDefault(require("node:assert"));
9
+ const fs_1 = __importDefault(require("fs"));
10
+ const path_1 = __importDefault(require("path"));
11
+ const os_1 = __importDefault(require("os"));
12
+ const version_utils_1 = require("../src/utils/version-utils");
13
+ const types_1 = require("../src/fraim/types");
14
+ async function testSyncUpdateVersion() {
15
+ console.log(' 🚀 Testing "fraim sync" version update...');
16
+ // Create a temp directory for the test project
17
+ const tempDir = fs_1.default.mkdtempSync(path_1.default.join(os_1.default.tmpdir(), 'fraim-test-sync-'));
18
+ console.log(` 📂 Created temp dir: ${tempDir}`);
19
+ try {
20
+ const platform = process.platform;
21
+ const npx = platform === 'win32' ? 'npx.cmd' : 'npx';
22
+ const cliScript = path_1.default.resolve(__dirname, '../src/cli/fraim.ts');
23
+ // Setup .fraim/config.json with an OLD version
24
+ const fraimDir = path_1.default.join(tempDir, '.fraim');
25
+ fs_1.default.mkdirSync(fraimDir, { recursive: true });
26
+ const oldVersion = '0.0.0';
27
+ const initialConfig = {
28
+ ...types_1.DEFAULT_FRAIM_CONFIG,
29
+ version: oldVersion,
30
+ project: { name: 'test-project' },
31
+ git: { repoOwner: 'test', repoName: 'test' }
32
+ };
33
+ fs_1.default.writeFileSync(path_1.default.join(fraimDir, 'config.json'), JSON.stringify(initialConfig, null, 2));
34
+ // Create a fake registry so sync doesn't fail hard
35
+ const registryDir = path_1.default.join(tempDir, 'registry', 'workflows');
36
+ fs_1.default.mkdirSync(registryDir, { recursive: true });
37
+ fs_1.default.writeFileSync(path_1.default.join(registryDir, 'dummy.md'), '---\nintent: test\n---\n# Dummy');
38
+ // Helper to run CLI commands
39
+ const runFraim = (args) => {
40
+ return new Promise((resolve) => {
41
+ const ps = (0, node_child_process_1.spawn)(npx, ['tsx', `"${cliScript}"`, ...args], {
42
+ cwd: tempDir,
43
+ env: { ...process.env, TEST_MODE: 'true' },
44
+ shell: true
45
+ });
46
+ let stdout = '';
47
+ let stderr = '';
48
+ ps.stdout.on('data', d => stdout += d.toString());
49
+ ps.stderr.on('data', d => stderr += d.toString());
50
+ ps.on('close', (code) => resolve({ stdout, stderr, code }));
51
+ });
52
+ };
53
+ // Run `fraim sync`
54
+ console.log(' Running "fraim sync"...');
55
+ const res = await runFraim(['sync']);
56
+ if (res.code !== 0) {
57
+ console.error(' ❌ Sync failed:', res.stderr);
58
+ return false;
59
+ }
60
+ // Verify config.json has the NEW/Current version
61
+ const updatedConfig = JSON.parse(fs_1.default.readFileSync(path_1.default.join(fraimDir, 'config.json'), 'utf-8'));
62
+ const currentPackageVersion = (0, version_utils_1.getFraimVersion)();
63
+ console.log(` ℹ️ Old Version: ${oldVersion}`);
64
+ console.log(` ℹ️ New Version in Config: ${updatedConfig.version}`);
65
+ console.log(` ℹ️ Current Package Version: ${currentPackageVersion}`);
66
+ node_assert_1.default.strictEqual(updatedConfig.version, currentPackageVersion, 'Config version should match package version after sync');
67
+ node_assert_1.default.notStrictEqual(updatedConfig.version, oldVersion, 'Config version should have been updated from 0.0.0');
68
+ console.log(' ✅ Validated: Version was updated correctly.');
69
+ return true;
70
+ }
71
+ catch (error) {
72
+ console.error(' ❌ Test failed:', error);
73
+ return false;
74
+ }
75
+ finally {
76
+ try {
77
+ fs_1.default.rmSync(tempDir, { recursive: true, force: true });
78
+ }
79
+ catch (e) { }
80
+ }
81
+ }
82
+ async function runTest(testCase) {
83
+ return await testCase.testFunction();
84
+ }
85
+ const testCases = [
86
+ {
87
+ name: 'Sync Version Update',
88
+ description: 'Verifies that fraim sync updates the version in config.json',
89
+ testFunction: testSyncUpdateVersion,
90
+ tags: ['cli', 'sync']
91
+ },
92
+ ];
93
+ (0, test_utils_1.runTests)(testCases, runTest, 'Fraim Sync Update Tests');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim-framework",
3
- "version": "2.0.26",
3
+ "version": "2.0.27",
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": {