fraim-framework 2.0.85 → 2.0.86

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.
@@ -16,6 +16,7 @@ const version_utils_1 = require("../utils/version-utils");
16
16
  const ide_detector_1 = require("../setup/ide-detector");
17
17
  const codex_local_config_1 = require("../setup/codex-local-config");
18
18
  const provider_registry_1 = require("../providers/provider-registry");
19
+ const fraim_gitignore_1 = require("../utils/fraim-gitignore");
19
20
  const promptForJiraProjectKey = async (jiraBaseUrl) => {
20
21
  console.log(chalk_1.default.blue('\nšŸŽ« Jira Project Configuration'));
21
22
  console.log(chalk_1.default.gray(`Jira instance: ${jiraBaseUrl}`));
@@ -166,6 +167,9 @@ const runInitProject = async () => {
166
167
  console.log(chalk_1.default.green(`Created .fraim/${dir}`));
167
168
  }
168
169
  });
170
+ if ((0, fraim_gitignore_1.ensureFraimSyncedContentIgnored)(projectRoot)) {
171
+ console.log(chalk_1.default.green('Updated .gitignore with FRAIM synced content ignore rules'));
172
+ }
169
173
  if (!process.env.FRAIM_SKIP_SYNC) {
170
174
  await (0, sync_1.runSync)({});
171
175
  }
@@ -46,11 +46,19 @@ const path_1 = __importDefault(require("path"));
46
46
  const auto_mcp_setup_1 = require("../setup/auto-mcp-setup");
47
47
  const version_utils_1 = require("../utils/version-utils");
48
48
  const platform_detection_1 = require("../utils/platform-detection");
49
- const get_provider_client_1 = require("../api/get-provider-client");
49
+ const provider_client_1 = require("../api/provider-client");
50
50
  const provider_prompts_1 = require("../setup/provider-prompts");
51
51
  const provider_registry_1 = require("../providers/provider-registry");
52
52
  const init_project_1 = require("./init-project");
53
53
  const script_sync_utils_1 = require("../utils/script-sync-utils");
54
+ function parseModeOption(mode) {
55
+ if (mode === 'conversational' || mode === 'integrated' || mode === 'split') {
56
+ return mode;
57
+ }
58
+ console.log(chalk_1.default.red(`āŒ Invalid mode "${mode}"`));
59
+ console.log(chalk_1.default.yellow('šŸ’” Valid values: integrated, split, conversational'));
60
+ process.exit(1);
61
+ }
54
62
  const promptForFraimKey = async () => {
55
63
  console.log(chalk_1.default.blue('šŸ”‘ FRAIM Key Setup'));
56
64
  console.log('FRAIM requires a valid API key to access workflows and features.\n');
@@ -293,22 +301,28 @@ const runSetup = async (options) => {
293
301
  // Get FRAIM key
294
302
  fraimKey = options.key || await promptForFraimKey();
295
303
  console.log(chalk_1.default.green('āœ… FRAIM key accepted\n'));
296
- // Ask for mode preference
297
- mode = await promptForMode();
304
+ // Ask for mode preference (or use explicit option)
305
+ mode = options.mode ? parseModeOption(options.mode) : await promptForMode();
306
+ // Parse provider CLI flags on first-time setup too
307
+ const parsed = await parseLegacyOptions(options, fraimKey);
308
+ requestedProviders = parsed.requestedProviders;
309
+ providedTokens = parsed.providedTokens;
310
+ providedConfigs = parsed.providedConfigs;
298
311
  }
312
+ const providerClient = new provider_client_1.ProviderClient(fraimKey, process.env.FRAIM_REMOTE_URL || undefined);
299
313
  // Handle platform tokens based on mode
300
314
  if (mode === 'integrated') {
301
315
  let providersToSetup = requestedProviders;
302
316
  // If no specific providers requested and not an update, ask user
303
317
  if (!isUpdate && providersToSetup.length === 0) {
304
- providersToSetup = await (0, provider_prompts_1.promptForProviders)((0, get_provider_client_1.getProviderClient)());
318
+ providersToSetup = await (0, provider_prompts_1.promptForProviders)(providerClient);
305
319
  }
306
320
  // Get credentials for each provider
307
321
  for (const providerId of providersToSetup) {
308
322
  if (!tokens[providerId]) {
309
323
  try {
310
324
  // Use provided tokens if available, otherwise prompt
311
- const creds = await (0, provider_prompts_1.promptForProviderCredentials)((0, get_provider_client_1.getProviderClient)(), providerId, providedTokens[providerId], providedConfigs[providerId]);
325
+ const creds = await (0, provider_prompts_1.promptForProviderCredentials)(providerClient, providerId, providedTokens[providerId], providedConfigs[providerId]);
312
326
  tokens[providerId] = creds.token;
313
327
  if (creds.config) {
314
328
  configs[providerId] = creds.config;
@@ -336,12 +350,12 @@ const runSetup = async (options) => {
336
350
  console.log(chalk_1.default.blue('\nšŸ”€ Split Mode Configuration'));
337
351
  console.log(chalk_1.default.gray('Configure separate platforms for code hosting and issue tracking.\n'));
338
352
  // Get code repository platform
339
- const codeRepoProvider = await (0, provider_prompts_1.promptForSingleProvider)((0, get_provider_client_1.getProviderClient)(), 'code');
353
+ const codeRepoProvider = await (0, provider_prompts_1.promptForSingleProvider)(providerClient, 'code');
340
354
  // Get code repository credentials
341
355
  if (!tokens[codeRepoProvider]) {
342
356
  try {
343
357
  // Use provided tokens if available, otherwise prompt
344
- const creds = await (0, provider_prompts_1.promptForProviderCredentials)((0, get_provider_client_1.getProviderClient)(), codeRepoProvider, providedTokens[codeRepoProvider], providedConfigs[codeRepoProvider]);
358
+ const creds = await (0, provider_prompts_1.promptForProviderCredentials)(providerClient, codeRepoProvider, providedTokens[codeRepoProvider], providedConfigs[codeRepoProvider]);
345
359
  tokens[codeRepoProvider] = creds.token;
346
360
  if (creds.config) {
347
361
  configs[codeRepoProvider] = creds.config;
@@ -354,12 +368,12 @@ const runSetup = async (options) => {
354
368
  }
355
369
  }
356
370
  // Get issue tracking platform
357
- const issueProvider = await (0, provider_prompts_1.promptForSingleProvider)((0, get_provider_client_1.getProviderClient)(), 'issues');
371
+ const issueProvider = await (0, provider_prompts_1.promptForSingleProvider)(providerClient, 'issues');
358
372
  // Get issue tracking credentials (if different from code repo)
359
373
  if (!tokens[issueProvider]) {
360
374
  try {
361
375
  // Use provided tokens if available, otherwise prompt
362
- const creds = await (0, provider_prompts_1.promptForProviderCredentials)((0, get_provider_client_1.getProviderClient)(), issueProvider, providedTokens[issueProvider], providedConfigs[issueProvider]);
376
+ const creds = await (0, provider_prompts_1.promptForProviderCredentials)(providerClient, issueProvider, providedTokens[issueProvider], providedConfigs[issueProvider]);
363
377
  tokens[issueProvider] = creds.token;
364
378
  if (creds.config) {
365
379
  configs[issueProvider] = creds.config;
@@ -474,6 +488,7 @@ exports.runSetup = runSetup;
474
488
  exports.setupCommand = new commander_1.Command('setup')
475
489
  .description('Complete global FRAIM setup with platform configuration')
476
490
  .option('--key <key>', 'FRAIM API key')
491
+ .option('--mode <mode>', 'Usage mode: integrated | split | conversational')
477
492
  .option('--ide <ides>', 'Configure specific IDEs');
478
493
  // Track initialization promise for CLI entry point
479
494
  exports.setupCommandInitialization = null;
@@ -0,0 +1,46 @@
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.ensureFraimSyncedContentIgnored = exports.FRAIM_SYNC_GITIGNORE_ENTRIES = exports.FRAIM_SYNC_GITIGNORE_END = exports.FRAIM_SYNC_GITIGNORE_START = void 0;
7
+ const fs_1 = __importDefault(require("fs"));
8
+ const path_1 = __importDefault(require("path"));
9
+ exports.FRAIM_SYNC_GITIGNORE_START = '# BEGIN FRAIM SYNCED CONTENT';
10
+ exports.FRAIM_SYNC_GITIGNORE_END = '# END FRAIM SYNCED CONTENT';
11
+ exports.FRAIM_SYNC_GITIGNORE_ENTRIES = [
12
+ '.fraim/workflows/',
13
+ '.fraim/docs/',
14
+ '.fraim/ai-employee/',
15
+ '.fraim/ai-manager/'
16
+ ];
17
+ const escapeRegExp = (value) => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
18
+ /**
19
+ * Ensures the repo .gitignore contains a managed FRAIM synced-content block.
20
+ * Returns true when the file was modified.
21
+ */
22
+ const ensureFraimSyncedContentIgnored = (projectRoot) => {
23
+ const gitignorePath = path_1.default.join(projectRoot, '.gitignore');
24
+ const existingRaw = fs_1.default.existsSync(gitignorePath)
25
+ ? fs_1.default.readFileSync(gitignorePath, 'utf8')
26
+ : '';
27
+ const newline = existingRaw.includes('\r\n') ? '\r\n' : '\n';
28
+ const normalized = existingRaw.replace(/\r\n/g, '\n');
29
+ const managedBlock = [
30
+ exports.FRAIM_SYNC_GITIGNORE_START,
31
+ '# Synced by fraim init-project (generated content)',
32
+ ...exports.FRAIM_SYNC_GITIGNORE_ENTRIES,
33
+ exports.FRAIM_SYNC_GITIGNORE_END
34
+ ].join('\n');
35
+ const blockPattern = new RegExp(`${escapeRegExp(exports.FRAIM_SYNC_GITIGNORE_START)}[\\s\\S]*?${escapeRegExp(exports.FRAIM_SYNC_GITIGNORE_END)}\\n?`, 'm');
36
+ const hasManagedBlock = blockPattern.test(normalized);
37
+ const updatedNormalized = hasManagedBlock
38
+ ? normalized.replace(blockPattern, `${managedBlock}\n`)
39
+ : `${normalized.trimEnd()}${normalized.trimEnd().length > 0 ? '\n\n' : ''}${managedBlock}\n`;
40
+ if (updatedNormalized !== normalized) {
41
+ fs_1.default.writeFileSync(gitignorePath, updatedNormalized.replace(/\n/g, newline), 'utf8');
42
+ return true;
43
+ }
44
+ return false;
45
+ };
46
+ exports.ensureFraimSyncedContentIgnored = ensureFraimSyncedContentIgnored;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fraim-framework",
3
- "version": "2.0.85",
3
+ "version": "2.0.86",
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": {