fraim-framework 2.0.26 → 2.0.30
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/.github/workflows/deploy-fraim.yml +1 -1
- package/dist/registry/scripts/build-scripts-generator.js +205 -0
- package/dist/registry/scripts/cleanup-branch.js +258 -0
- package/dist/registry/scripts/evaluate-code-quality.js +66 -0
- package/dist/registry/scripts/exec-with-timeout.js +142 -0
- package/dist/registry/scripts/fraim-config.js +61 -0
- package/dist/registry/scripts/generate-engagement-emails.js +630 -0
- package/dist/registry/scripts/generic-issues-api.js +100 -0
- package/dist/registry/scripts/newsletter-helpers.js +731 -0
- package/dist/registry/scripts/openapi-generator.js +664 -0
- package/dist/registry/scripts/performance/profile-server.js +390 -0
- package/dist/registry/scripts/run-thank-you-workflow.js +92 -0
- package/dist/registry/scripts/send-newsletter-simple.js +85 -0
- package/dist/registry/scripts/send-thank-you-emails.js +54 -0
- package/dist/registry/scripts/validate-openapi-limits.js +311 -0
- package/dist/registry/scripts/validate-test-coverage.js +262 -0
- package/dist/registry/scripts/verify-test-coverage.js +66 -0
- package/dist/src/cli/commands/init.js +14 -12
- package/dist/src/cli/commands/sync.js +19 -2
- package/dist/src/cli/fraim.js +24 -22
- package/dist/src/cli/setup/first-run.js +13 -6
- package/dist/src/fraim/config-loader.js +0 -8
- package/dist/src/fraim/db-service.js +26 -15
- package/dist/src/fraim/issues.js +67 -0
- package/dist/src/fraim/setup-wizard.js +1 -69
- package/dist/src/fraim/types.js +0 -11
- package/dist/src/fraim-mcp-server.js +272 -18
- package/dist/src/utils/git-utils.js +1 -1
- package/dist/src/utils/version-utils.js +32 -0
- package/dist/tests/debug-tools.js +79 -0
- package/dist/tests/esm-compat.js +11 -0
- package/dist/tests/test-chalk-esm-issue.js +159 -0
- package/dist/tests/test-chalk-real-world.js +265 -0
- package/dist/tests/test-chalk-regression.js +327 -0
- package/dist/tests/test-chalk-resolution-issue.js +304 -0
- package/dist/tests/test-cli.js +0 -2
- package/dist/tests/test-fraim-install-chalk-issue.js +254 -0
- package/dist/tests/test-fraim-issues.js +59 -0
- package/dist/tests/test-genericization.js +1 -3
- package/dist/tests/test-mcp-connection.js +166 -0
- package/dist/tests/test-mcp-issue-integration.js +144 -0
- package/dist/tests/test-mcp-lifecycle-methods.js +312 -0
- package/dist/tests/test-node-compatibility.js +71 -0
- package/dist/tests/test-npm-install.js +66 -0
- package/dist/tests/test-npm-resolution-diagnostic.js +140 -0
- package/dist/tests/test-session-rehydration.js +145 -0
- package/dist/tests/test-standalone.js +2 -8
- package/dist/tests/test-sync-version-update.js +93 -0
- package/dist/tests/test-telemetry.js +190 -0
- package/package.json +10 -8
- package/registry/agent-guardrails.md +62 -54
- package/registry/rules/agent-success-criteria.md +52 -0
- package/registry/rules/agent-testing-guidelines.md +502 -502
- package/registry/rules/communication.md +121 -121
- package/registry/rules/continuous-learning.md +54 -54
- package/registry/rules/ephemeral-execution.md +10 -5
- package/registry/rules/hitl-ppe-record-analysis.md +302 -302
- package/registry/rules/local-development.md +251 -251
- package/registry/rules/software-development-lifecycle.md +104 -104
- package/registry/rules/successful-debugging-patterns.md +482 -478
- package/registry/rules/telemetry.md +67 -0
- package/registry/scripts/build-scripts-generator.ts +216 -215
- package/registry/scripts/cleanup-branch.ts +303 -284
- package/registry/scripts/code-quality-check.sh +559 -559
- package/registry/scripts/detect-tautological-tests.sh +38 -38
- package/registry/scripts/evaluate-code-quality.ts +1 -1
- package/registry/scripts/generate-engagement-emails.ts +744 -744
- package/registry/scripts/generic-issues-api.ts +110 -150
- package/registry/scripts/newsletter-helpers.ts +874 -874
- package/registry/scripts/openapi-generator.ts +695 -693
- package/registry/scripts/performance/profile-server.ts +5 -3
- package/registry/scripts/prep-issue.sh +468 -455
- package/registry/scripts/validate-openapi-limits.ts +366 -365
- package/registry/scripts/validate-test-coverage.ts +280 -280
- package/registry/scripts/verify-pr-comments.sh +70 -70
- package/registry/scripts/verify-test-coverage.ts +1 -1
- package/registry/templates/bootstrap/ARCHITECTURE-TEMPLATE.md +53 -53
- package/registry/templates/evidence/Implementation-BugEvidence.md +85 -85
- package/registry/templates/evidence/Implementation-FeatureEvidence.md +120 -120
- package/registry/templates/marketing/HBR-ARTICLE-TEMPLATE.md +66 -0
- package/registry/workflows/bootstrap/create-architecture.md +2 -2
- package/registry/workflows/bootstrap/evaluate-code-quality.md +3 -3
- package/registry/workflows/bootstrap/verify-test-coverage.md +2 -2
- package/registry/workflows/customer-development/insight-analysis.md +156 -156
- package/registry/workflows/customer-development/interview-preparation.md +421 -421
- package/registry/workflows/customer-development/strategic-brainstorming.md +146 -146
- package/registry/workflows/customer-development/thank-customers.md +193 -191
- package/registry/workflows/customer-development/weekly-newsletter.md +362 -352
- package/registry/workflows/improve-fraim/contribute.md +32 -0
- package/registry/workflows/improve-fraim/file-issue.md +32 -0
- package/registry/workflows/marketing/hbr-article.md +73 -0
- package/registry/workflows/performance/analyze-performance.md +63 -59
- package/registry/workflows/product-building/design.md +3 -2
- package/registry/workflows/product-building/implement.md +4 -3
- package/registry/workflows/product-building/prep-issue.md +28 -17
- package/registry/workflows/product-building/resolve.md +3 -2
- package/registry/workflows/product-building/retrospect.md +3 -2
- package/registry/workflows/product-building/spec.md +5 -4
- package/registry/workflows/product-building/test.md +3 -2
- package/registry/workflows/quality-assurance/iterative-improvement-cycle.md +562 -562
- package/registry/workflows/replicate/website-discovery-analysis.md +3 -3
- package/registry/workflows/reviewer/review-implementation-vs-design-spec.md +632 -632
- package/registry/workflows/reviewer/review-implementation-vs-feature-spec.md +669 -669
- package/tsconfig.json +2 -1
|
@@ -8,10 +8,11 @@ const commander_1 = require("commander");
|
|
|
8
8
|
const fs_1 = __importDefault(require("fs"));
|
|
9
9
|
const path_1 = __importDefault(require("path"));
|
|
10
10
|
const chalk_1 = __importDefault(require("chalk"));
|
|
11
|
-
const
|
|
12
|
-
const
|
|
13
|
-
const
|
|
14
|
-
const
|
|
11
|
+
const first_run_1 = require("../setup/first-run");
|
|
12
|
+
const sync_1 = require("./sync");
|
|
13
|
+
const types_1 = require("../../fraim/types");
|
|
14
|
+
const git_utils_1 = require("../../utils/git-utils");
|
|
15
|
+
const version_utils_1 = require("../../utils/version-utils");
|
|
15
16
|
const runInit = async () => {
|
|
16
17
|
const projectRoot = process.cwd();
|
|
17
18
|
const fraimDir = path_1.default.join(projectRoot, '.fraim');
|
|
@@ -25,17 +26,18 @@ const runInit = async () => {
|
|
|
25
26
|
console.log(chalk_1.default.yellow('ℹ️ .fraim directory already exists'));
|
|
26
27
|
}
|
|
27
28
|
if (!fs_1.default.existsSync(configPath)) {
|
|
28
|
-
const remoteInfo = (0,
|
|
29
|
+
const remoteInfo = (0, git_utils_1.getGitRemoteInfo)();
|
|
29
30
|
const config = {
|
|
30
|
-
...
|
|
31
|
+
...types_1.DEFAULT_FRAIM_CONFIG,
|
|
32
|
+
version: (0, version_utils_1.getFraimVersion)(),
|
|
31
33
|
project: {
|
|
32
|
-
...
|
|
34
|
+
...types_1.DEFAULT_FRAIM_CONFIG.project,
|
|
33
35
|
name: path_1.default.basename(projectRoot)
|
|
34
36
|
},
|
|
35
37
|
git: {
|
|
36
|
-
...
|
|
37
|
-
repoOwner: remoteInfo.owner ||
|
|
38
|
-
repoName: remoteInfo.repo ||
|
|
38
|
+
...types_1.DEFAULT_FRAIM_CONFIG.git,
|
|
39
|
+
repoOwner: remoteInfo.owner || types_1.DEFAULT_FRAIM_CONFIG.git.repoOwner,
|
|
40
|
+
repoName: remoteInfo.repo || types_1.DEFAULT_FRAIM_CONFIG.git.repoName
|
|
39
41
|
}
|
|
40
42
|
};
|
|
41
43
|
fs_1.default.writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
@@ -51,9 +53,9 @@ const runInit = async () => {
|
|
|
51
53
|
});
|
|
52
54
|
console.log(chalk_1.default.blue('\n🎉 FRAIM initialized successfully!'));
|
|
53
55
|
// Sync workflows from registry
|
|
54
|
-
await (0,
|
|
56
|
+
await (0, sync_1.runSync)({});
|
|
55
57
|
// Trigger First Run Experience
|
|
56
|
-
await (0,
|
|
58
|
+
await (0, first_run_1.runFirstRunExperience)();
|
|
57
59
|
process.exit(0);
|
|
58
60
|
};
|
|
59
61
|
exports.runInit = runInit;
|
|
@@ -10,10 +10,11 @@ const path_1 = __importDefault(require("path"));
|
|
|
10
10
|
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
|
-
const
|
|
13
|
+
const config_loader_1 = require("../../fraim/config-loader");
|
|
14
|
+
const version_utils_1 = require("../../utils/version-utils");
|
|
14
15
|
const runSync = async (options) => {
|
|
15
16
|
const projectRoot = process.cwd();
|
|
16
|
-
const config = (0,
|
|
17
|
+
const config = (0, config_loader_1.loadFraimConfig)();
|
|
17
18
|
const fraimDir = path_1.default.join(projectRoot, '.fraim');
|
|
18
19
|
const workflowsRelativePath = config.customizations?.workflowsPath || '.fraim/workflows';
|
|
19
20
|
const workflowsDir = path_1.default.resolve(projectRoot, workflowsRelativePath);
|
|
@@ -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_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') : '';
|
package/dist/src/cli/fraim.js
CHANGED
|
@@ -5,39 +5,41 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
};
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
const commander_1 = require("commander");
|
|
8
|
-
const
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
const
|
|
12
|
-
const
|
|
8
|
+
const init_1 = require("./commands/init");
|
|
9
|
+
const sync_1 = require("./commands/sync");
|
|
10
|
+
const doctor_1 = require("./commands/doctor");
|
|
11
|
+
const list_1 = require("./commands/list");
|
|
12
|
+
const wizard_1 = require("./commands/wizard");
|
|
13
13
|
const fs_1 = __importDefault(require("fs"));
|
|
14
14
|
const path_1 = __importDefault(require("path"));
|
|
15
15
|
const program = new commander_1.Command();
|
|
16
16
|
// Load version from package.json
|
|
17
17
|
// Handle both src/ (dev) and dist/ (prod) execution paths
|
|
18
|
-
let packageJson;
|
|
18
|
+
let packageJson = { version: 'unknown' };
|
|
19
19
|
try {
|
|
20
|
-
//
|
|
21
|
-
|
|
20
|
+
// Robustly find package.json by searching upwards from this file's directory
|
|
21
|
+
let currentDir = __dirname;
|
|
22
|
+
let found = false;
|
|
23
|
+
for (let i = 0; i < 5; i++) { // Max search depth 5
|
|
24
|
+
const pkgPath = path_1.default.join(currentDir, 'package.json');
|
|
25
|
+
if (fs_1.default.existsSync(pkgPath)) {
|
|
26
|
+
packageJson = JSON.parse(fs_1.default.readFileSync(pkgPath, 'utf8'));
|
|
27
|
+
found = true;
|
|
28
|
+
break;
|
|
29
|
+
}
|
|
30
|
+
currentDir = path_1.default.dirname(currentDir);
|
|
31
|
+
}
|
|
22
32
|
}
|
|
23
33
|
catch (e) {
|
|
24
|
-
|
|
25
|
-
// Try 3 levels up (dist/src/cli -> root) - for compiled js
|
|
26
|
-
packageJson = JSON.parse(fs_1.default.readFileSync(path_1.default.join(__dirname, '..', '..', '..', 'package.json'), 'utf8'));
|
|
27
|
-
}
|
|
28
|
-
catch (e2) {
|
|
29
|
-
// Fallback or throw
|
|
30
|
-
console.error('Could not locate package.json');
|
|
31
|
-
process.exit(1);
|
|
32
|
-
}
|
|
34
|
+
console.warn('⚠️ Could not fully resolve package.json version.');
|
|
33
35
|
}
|
|
34
36
|
program
|
|
35
37
|
.name('fraim')
|
|
36
38
|
.description('FRAIM Framework CLI - Manage your AI workflows and rules')
|
|
37
39
|
.version(packageJson.version);
|
|
38
|
-
program.addCommand(
|
|
39
|
-
program.addCommand(
|
|
40
|
-
program.addCommand(
|
|
41
|
-
program.addCommand(
|
|
42
|
-
program.addCommand(
|
|
40
|
+
program.addCommand(init_1.initCommand);
|
|
41
|
+
program.addCommand(sync_1.syncCommand);
|
|
42
|
+
program.addCommand(doctor_1.doctorCommand);
|
|
43
|
+
program.addCommand(list_1.listCommand);
|
|
44
|
+
program.addCommand(wizard_1.wizardCommand);
|
|
43
45
|
program.parse(process.argv);
|
|
@@ -47,12 +47,19 @@ const runFirstRunExperience = async () => {
|
|
|
47
47
|
}
|
|
48
48
|
console.log(chalk_1.default.blue('\n👋 Welcome to FRAIM! Let\'s get you set up.\n'));
|
|
49
49
|
// 1. Ask for FRAIM key
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
50
|
+
let response;
|
|
51
|
+
try {
|
|
52
|
+
response = await (0, prompts_1.default)({
|
|
53
|
+
type: 'text',
|
|
54
|
+
name: 'fraimKey',
|
|
55
|
+
message: 'Do you have a FRAIM key? (Input key or press Enter to skip)',
|
|
56
|
+
validate: (value) => true // Optional input
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
catch (e) {
|
|
60
|
+
console.warn(chalk_1.default.yellow('\n⚠️ Interactive prompts experienced an issue. Skipping setup.\n'));
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
56
63
|
if (response.fraimKey && response.fraimKey.trim().length > 0) {
|
|
57
64
|
const key = response.fraimKey.trim();
|
|
58
65
|
console.log(chalk_1.default.green('\n✅ Key received.'));
|
|
@@ -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 || {})
|
|
@@ -17,32 +17,43 @@ class FraimDbService {
|
|
|
17
17
|
this.db = this.client.db(dbName);
|
|
18
18
|
// Use fraim_ prefix for standalone server collections
|
|
19
19
|
this.keysCollection = this.db.collection('fraim_api_keys');
|
|
20
|
-
this.
|
|
20
|
+
this.sessionsCollection = this.db.collection('fraim_telemetry_sessions');
|
|
21
21
|
// Create indexes
|
|
22
22
|
await this.keysCollection.createIndex({ key: 1 }, { unique: true });
|
|
23
|
-
await this.
|
|
24
|
-
await this.
|
|
23
|
+
await this.sessionsCollection.createIndex({ sessionId: 1 }, { unique: true });
|
|
24
|
+
await this.sessionsCollection.createIndex({ userId: 1 });
|
|
25
|
+
await this.sessionsCollection.createIndex({ lastActive: -1 });
|
|
25
26
|
console.log(`✅ Connected to Fraim DB: ${dbName}`);
|
|
26
27
|
}
|
|
28
|
+
async createSession(session) {
|
|
29
|
+
if (!this.sessionsCollection)
|
|
30
|
+
throw new Error('DB not connected');
|
|
31
|
+
await this.sessionsCollection.insertOne(session);
|
|
32
|
+
}
|
|
33
|
+
async updateSessionActivity(sessionId, lastActive) {
|
|
34
|
+
if (!this.sessionsCollection)
|
|
35
|
+
return; // Fail silently
|
|
36
|
+
await this.sessionsCollection.updateOne({ sessionId }, { $set: { lastActive } });
|
|
37
|
+
}
|
|
27
38
|
async verifyApiKey(key) {
|
|
28
39
|
if (!this.keysCollection)
|
|
29
40
|
throw new Error('DB not connected');
|
|
30
41
|
const apiKey = await this.keysCollection.findOne({ key, isActive: true });
|
|
31
42
|
return apiKey;
|
|
32
43
|
}
|
|
33
|
-
async
|
|
34
|
-
if (!this.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
}
|
|
44
|
+
async getActiveSessionByApiKey(key) {
|
|
45
|
+
if (!this.keysCollection || !this.sessionsCollection)
|
|
46
|
+
throw new Error('DB not connected');
|
|
47
|
+
// 1. Get user for this key
|
|
48
|
+
const apiKeyData = await this.verifyApiKey(key);
|
|
49
|
+
if (!apiKeyData)
|
|
50
|
+
return null;
|
|
51
|
+
// 2. Get latest session for this user (within last 24h)
|
|
52
|
+
const dayAgo = new Date(Date.now() - 24 * 60 * 60 * 1000);
|
|
53
|
+
const session = await this.sessionsCollection.findOne({ userId: apiKeyData.userId, lastActive: { $gt: dayAgo } }, { sort: { lastActive: -1 } });
|
|
54
|
+
return session;
|
|
45
55
|
}
|
|
56
|
+
// ... (rest of methods)
|
|
46
57
|
async listApiKeys() {
|
|
47
58
|
if (!this.keysCollection)
|
|
48
59
|
throw new Error('DB not connected');
|
|
@@ -0,0 +1,67 @@
|
|
|
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.fileFraimIssue = fileFraimIssue;
|
|
7
|
+
const axios_1 = __importDefault(require("axios"));
|
|
8
|
+
const config_loader_1 = require("./config-loader");
|
|
9
|
+
/**
|
|
10
|
+
* File a GitHub issue in the configured FRAIM repository
|
|
11
|
+
*/
|
|
12
|
+
async function fileFraimIssue(params) {
|
|
13
|
+
const { title, body, labels, dryRun } = params;
|
|
14
|
+
// Load config
|
|
15
|
+
const config = (0, config_loader_1.loadFraimConfig)();
|
|
16
|
+
const owner = config.git?.repoOwner || 'mathursrus';
|
|
17
|
+
const repo = config.git?.repoName || 'FRAIM';
|
|
18
|
+
const url = `https://api.github.com/repos/${owner}/${repo}/issues`;
|
|
19
|
+
const payload = {
|
|
20
|
+
title,
|
|
21
|
+
body
|
|
22
|
+
};
|
|
23
|
+
if (labels && labels.length > 0) {
|
|
24
|
+
payload.labels = labels;
|
|
25
|
+
}
|
|
26
|
+
if (dryRun) {
|
|
27
|
+
return {
|
|
28
|
+
success: true,
|
|
29
|
+
dryRun: true,
|
|
30
|
+
message: `[DRY RUN] Would POST to ${url} with title: "${title}"`
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const token = process.env.GITHUB_TOKEN;
|
|
34
|
+
if (!token) {
|
|
35
|
+
return {
|
|
36
|
+
success: false,
|
|
37
|
+
message: 'GITHUB_TOKEN environment variable is required'
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
try {
|
|
41
|
+
const response = await axios_1.default.post(url, payload, {
|
|
42
|
+
headers: {
|
|
43
|
+
'Authorization': `Bearer ${token}`,
|
|
44
|
+
'Accept': 'application/vnd.github.v3+json',
|
|
45
|
+
'Content-Type': 'application/json',
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
return {
|
|
49
|
+
success: true,
|
|
50
|
+
issueNumber: response.data.number,
|
|
51
|
+
htmlUrl: response.data.html_url
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
let errorMessage = 'Unknown error';
|
|
56
|
+
if (axios_1.default.isAxiosError(error)) {
|
|
57
|
+
errorMessage = `Status: ${error.response?.status} - ${JSON.stringify(error.response?.data)}`;
|
|
58
|
+
}
|
|
59
|
+
else if (error instanceof Error) {
|
|
60
|
+
errorMessage = error.message;
|
|
61
|
+
}
|
|
62
|
+
return {
|
|
63
|
+
success: false,
|
|
64
|
+
message: errorMessage
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -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-
|
|
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
|
}
|
package/dist/src/fraim/types.js
CHANGED
|
@@ -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
|
},
|