fridayy 1.2.0 → 1.3.0
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/README.md +61 -3
- package/dist/adapters/laravel/adapter.d.ts +21 -0
- package/dist/adapters/laravel/adapter.d.ts.map +1 -0
- package/dist/adapters/laravel/adapter.js +133 -0
- package/dist/adapters/laravel/adapter.js.map +1 -0
- package/dist/adapters/laravel/route-scanner.d.ts +39 -0
- package/dist/adapters/laravel/route-scanner.d.ts.map +1 -0
- package/dist/adapters/laravel/route-scanner.js +238 -0
- package/dist/adapters/laravel/route-scanner.js.map +1 -0
- package/dist/adapters/nodejs/ast-scanner.d.ts +5 -3
- package/dist/adapters/nodejs/ast-scanner.d.ts.map +1 -1
- package/dist/adapters/nodejs/ast-scanner.js +104 -29
- package/dist/adapters/nodejs/ast-scanner.js.map +1 -1
- package/dist/adapters/registry.d.ts.map +1 -1
- package/dist/adapters/registry.js +2 -0
- package/dist/adapters/registry.js.map +1 -1
- package/dist/adapters/rest/adapter.d.ts +1 -0
- package/dist/adapters/rest/adapter.d.ts.map +1 -1
- package/dist/adapters/rest/adapter.js +124 -2
- package/dist/adapters/rest/adapter.js.map +1 -1
- package/dist/adapters/rest/executor.d.ts.map +1 -1
- package/dist/adapters/rest/executor.js +1 -2
- package/dist/adapters/rest/executor.js.map +1 -1
- package/dist/cli/commands/config.d.ts.map +1 -1
- package/dist/cli/commands/config.js +27 -3
- package/dist/cli/commands/config.js.map +1 -1
- package/dist/cli/commands/doctor.d.ts.map +1 -1
- package/dist/cli/commands/doctor.js +105 -4
- package/dist/cli/commands/doctor.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +11 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.d.ts +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +65 -8
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/scan.d.ts.map +1 -1
- package/dist/cli/commands/scan.js +33 -17
- package/dist/cli/commands/scan.js.map +1 -1
- package/dist/cli/commands/secrets.d.ts +9 -0
- package/dist/cli/commands/secrets.d.ts.map +1 -0
- package/dist/cli/commands/secrets.js +50 -0
- package/dist/cli/commands/secrets.js.map +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +14 -1
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +26 -3
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/ui/banner.d.ts.map +1 -1
- package/dist/cli/ui/banner.js +2 -1
- package/dist/cli/ui/banner.js.map +1 -1
- package/dist/config/credentials-store.d.ts +24 -0
- package/dist/config/credentials-store.d.ts.map +1 -0
- package/dist/config/credentials-store.js +73 -0
- package/dist/config/credentials-store.js.map +1 -0
- package/dist/config/global-dir.d.ts +21 -0
- package/dist/config/global-dir.d.ts.map +1 -0
- package/dist/config/global-dir.js +34 -0
- package/dist/config/global-dir.js.map +1 -0
- package/dist/config/package-info.d.ts +8 -0
- package/dist/config/package-info.d.ts.map +1 -0
- package/dist/config/package-info.js +27 -0
- package/dist/config/package-info.js.map +1 -0
- package/dist/core/authentication/secret-resolver.d.ts +11 -2
- package/dist/core/authentication/secret-resolver.d.ts.map +1 -1
- package/dist/core/authentication/secret-resolver.js +18 -3
- package/dist/core/authentication/secret-resolver.js.map +1 -1
- package/dist/core/discovery/project-scanner.d.ts +1 -0
- package/dist/core/discovery/project-scanner.d.ts.map +1 -1
- package/dist/core/discovery/project-scanner.js +60 -20
- package/dist/core/discovery/project-scanner.js.map +1 -1
- package/dist/core/permissions/classifier.js +3 -3
- package/dist/core/permissions/classifier.js.map +1 -1
- package/dist/core/permissions/enforcer.d.ts +10 -0
- package/dist/core/permissions/enforcer.d.ts.map +1 -1
- package/dist/core/permissions/enforcer.js +16 -0
- package/dist/core/permissions/enforcer.js.map +1 -1
- package/dist/core/schema/types.d.ts +5 -2
- package/dist/core/schema/types.d.ts.map +1 -1
- package/dist/core/tool-generator/generator.d.ts +3 -1
- package/dist/core/tool-generator/generator.d.ts.map +1 -1
- package/dist/core/tool-generator/generator.js +33 -5
- package/dist/core/tool-generator/generator.js.map +1 -1
- package/dist/core/validation/config-schema.d.ts +10 -5
- package/dist/core/validation/config-schema.d.ts.map +1 -1
- package/dist/core/validation/config-schema.js +3 -2
- package/dist/core/validation/config-schema.js.map +1 -1
- package/dist/mcp/server/fridayy-server.d.ts +8 -1
- package/dist/mcp/server/fridayy-server.d.ts.map +1 -1
- package/dist/mcp/server/fridayy-server.js +29 -1
- package/dist/mcp/server/fridayy-server.js.map +1 -1
- package/dist/mcp/tools/tool-handler.d.ts.map +1 -1
- package/dist/mcp/tools/tool-handler.js +35 -0
- package/dist/mcp/tools/tool-handler.js.map +1 -1
- package/dist/security/audit-logger.d.ts.map +1 -1
- package/dist/security/audit-logger.js +4 -1
- package/dist/security/audit-logger.js.map +1 -1
- package/dist/security/sanitizer.d.ts.map +1 -1
- package/dist/security/sanitizer.js +26 -5
- package/dist/security/sanitizer.js.map +1 -1
- package/package.json +4 -2
package/dist/cli/index.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* Fridayy - Universal Application-to-MCP Platform CLI
|
|
4
4
|
*/
|
|
5
5
|
import { Command } from 'commander';
|
|
6
|
+
import { fileURLToPath } from 'node:url';
|
|
7
|
+
import path from 'node:path';
|
|
6
8
|
import { registerInitCommand } from './commands/init.js';
|
|
7
9
|
import { registerScanCommand } from './commands/scan.js';
|
|
8
10
|
import { registerGenerateCommand } from './commands/generate.js';
|
|
@@ -10,16 +12,18 @@ import { registerReviewCommand } from './commands/review.js';
|
|
|
10
12
|
import { registerStartCommand } from './commands/start.js';
|
|
11
13
|
import { registerToolsCommand } from './commands/tools.js';
|
|
12
14
|
import { registerConfigCommand } from './commands/config.js';
|
|
15
|
+
import { registerSecretsCommand } from './commands/secrets.js';
|
|
13
16
|
import { registerDoctorCommand } from './commands/doctor.js';
|
|
14
17
|
import { registerUseCommand } from './commands/use.js';
|
|
15
18
|
import { printBanner } from './ui/banner.js';
|
|
16
19
|
import { runStartupAnimation } from './ui/startup-animation.js';
|
|
20
|
+
import { getPackageVersion } from '../config/package-info.js';
|
|
17
21
|
export function createCli() {
|
|
18
22
|
const program = new Command();
|
|
19
23
|
program
|
|
20
24
|
.name('fridayy')
|
|
21
25
|
.description('Universal Application-to-MCP Platform — Turn existing APIs into AI-ready MCP tools')
|
|
22
|
-
.version(
|
|
26
|
+
.version(getPackageVersion())
|
|
23
27
|
.action(async () => {
|
|
24
28
|
printBanner();
|
|
25
29
|
await runStartupAnimation();
|
|
@@ -31,6 +35,7 @@ export function createCli() {
|
|
|
31
35
|
console.log(' fridayy review → Review and approve tools');
|
|
32
36
|
console.log(' fridayy start → Start the MCP server');
|
|
33
37
|
console.log(' fridayy tools → List all tools and statuses');
|
|
38
|
+
console.log(' fridayy secrets → Manage the global per-device credentials store');
|
|
34
39
|
console.log(' fridayy doctor → Run diagnostics and health check\n');
|
|
35
40
|
});
|
|
36
41
|
// Register subcommands
|
|
@@ -42,6 +47,7 @@ export function createCli() {
|
|
|
42
47
|
registerStartCommand(program);
|
|
43
48
|
registerToolsCommand(program);
|
|
44
49
|
registerConfigCommand(program);
|
|
50
|
+
registerSecretsCommand(program);
|
|
45
51
|
registerDoctorCommand(program);
|
|
46
52
|
return program;
|
|
47
53
|
}
|
|
@@ -49,8 +55,25 @@ export async function run() {
|
|
|
49
55
|
const program = createCli();
|
|
50
56
|
await program.parseAsync(process.argv);
|
|
51
57
|
}
|
|
52
|
-
// If directly executed
|
|
53
|
-
|
|
58
|
+
// If directly executed. Compares resolved filesystem paths (via fileURLToPath)
|
|
59
|
+
// rather than raw URL/argv strings, since those differ in separator style and
|
|
60
|
+
// percent-encoding between POSIX and Windows and would otherwise never match
|
|
61
|
+
// on Windows, silently falling through to the `endsWith` heuristics below.
|
|
62
|
+
const isDirectlyExecuted = (() => {
|
|
63
|
+
const entry = process.argv[1];
|
|
64
|
+
if (!entry)
|
|
65
|
+
return false;
|
|
66
|
+
try {
|
|
67
|
+
if (path.resolve(fileURLToPath(import.meta.url)) === path.resolve(entry)) {
|
|
68
|
+
return true;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// import.meta.url wasn't a file:// URL; fall through to heuristics below
|
|
73
|
+
}
|
|
74
|
+
return entry.endsWith('fridayy') || entry.endsWith('index.ts') || entry.endsWith('index.js');
|
|
75
|
+
})();
|
|
76
|
+
if (isDirectlyExecuted) {
|
|
54
77
|
run().catch((err) => {
|
|
55
78
|
console.error('Fatal error:', err);
|
|
56
79
|
process.exit(1);
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7C,OAAO,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../../src/cli/ui/banner.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"banner.d.ts","sourceRoot":"","sources":["../../../src/cli/ui/banner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,wBAAgB,SAAS,IAAI,MAAM,CAgBlC;AAID,wBAAgB,WAAW,CAAC,KAAK,UAAQ,GAAG,IAAI,CAK/C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
|
package/dist/cli/ui/banner.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* Exact layout and styling matching Fridayy design specifications.
|
|
4
4
|
*/
|
|
5
5
|
import chalk from 'chalk';
|
|
6
|
+
import { getPackageVersion } from '../../config/package-info.js';
|
|
6
7
|
export function getBanner() {
|
|
7
8
|
const line1 = chalk.bold.white(' ███████╗██████╗ ██╗██████╗ █████╗ ██╗ ██╗██╗ ██╗');
|
|
8
9
|
const line2 = chalk.bold.white(' ██╔════╝██╔══██╗██║██╔══██╗██╔══██╗╚██╗ ██╔╝╚██╗ ██╔╝');
|
|
@@ -13,7 +14,7 @@ export function getBanner() {
|
|
|
13
14
|
const logo = `\n${line1}\n${line2}\n${line3}\n${line4}\n${line5}\n${line6}\n`;
|
|
14
15
|
const authorSub = chalk.gray(' sabarivasan\n');
|
|
15
16
|
const tagline = chalk.bold.white(' Universal Application-to-MCP Platform – Turn existing APIs into AI tools\n');
|
|
16
|
-
const badges = ` ${chalk.cyan.bold(
|
|
17
|
+
const badges = ` ${chalk.cyan.bold(`v${getPackageVersion()}`)} ${chalk.bgHex('#5e17eb').white.bold(' MCP Standard ')} ${chalk.gray('•')} ${chalk.yellow('⚡')} Developed with ${chalk.red('❤️')} by ${chalk.hex('#00f5d4').bold('Sabarivasan')}\n`;
|
|
17
18
|
const repo = ` ${chalk.gray('Repository:')} ${chalk.underline.hex('#00d2ff')('https://github.com/Sabari-Vasan-SM/fridayy')}\n`;
|
|
18
19
|
return `${logo}${authorSub}${tagline}${badges}${repo}`;
|
|
19
20
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../../src/cli/ui/banner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"banner.js","sourceRoot":"","sources":["../../../src/cli/ui/banner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AAEjE,MAAM,UAAU,SAAS;IACvB,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAC1F,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;IAE1F,MAAM,IAAI,GAAG,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,IAAI,CAAC;IAE9E,MAAM,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,4CAA4C,CAAC,CAAC;IAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,+EAA+E,CAAC,CAAC;IAClH,MAAM,MAAM,GAAG,aAAa,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,iBAAiB,EAAE,EAAE,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,mBAAmB,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;IAC/P,MAAM,IAAI,GAAG,oBAAoB,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,4CAA4C,CAAC,IAAI,CAAC;IAE/I,OAAO,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,IAAI,EAAE,CAAC;AACzD,CAAC;AAED,IAAI,aAAa,GAAG,KAAK,CAAC;AAE1B,MAAM,UAAU,WAAW,CAAC,KAAK,GAAG,KAAK;IACvC,IAAI,CAAC,aAAa,IAAI,KAAK,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACzB,aAAa,GAAG,IAAI,CAAC;IACvB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,aAAa,GAAG,KAAK,CAAC;AACxB,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Global Credentials Store
|
|
3
|
+
* Reads/writes a per-user credentials file (see global-dir.ts) so secrets can be
|
|
4
|
+
* configured once per device and reused across every Fridayy project, instead of
|
|
5
|
+
* being duplicated in plaintext inside per-project fridayy.config.json files.
|
|
6
|
+
*
|
|
7
|
+
* This is a plain JSON file, not an OS keychain — it is restricted to the
|
|
8
|
+
* current user via filesystem permissions (chmod 600 on POSIX) but is not
|
|
9
|
+
* encrypted at rest. Prefer real environment variables / a secrets manager for
|
|
10
|
+
* production deployments.
|
|
11
|
+
*/
|
|
12
|
+
export type CredentialsMap = Record<string, string>;
|
|
13
|
+
export declare class CredentialsStore {
|
|
14
|
+
private readonly filePath;
|
|
15
|
+
constructor(filePath?: string);
|
|
16
|
+
getPath(): string;
|
|
17
|
+
load(): CredentialsMap;
|
|
18
|
+
get(key: string): string | undefined;
|
|
19
|
+
set(key: string, value: string): void;
|
|
20
|
+
remove(key: string): boolean;
|
|
21
|
+
list(): string[];
|
|
22
|
+
}
|
|
23
|
+
export declare const defaultCredentialsStore: CredentialsStore;
|
|
24
|
+
//# sourceMappingURL=credentials-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-store.d.ts","sourceRoot":"","sources":["../../src/config/credentials-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,MAAM,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;AAEpD,qBAAa,gBAAgB;IACf,OAAO,CAAC,QAAQ,CAAC,QAAQ;gBAAR,QAAQ,GAAE,MAAmC;IAEnE,OAAO,IAAI,MAAM;IAIjB,IAAI,IAAI,cAAc;IAetB,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAIpC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAoBrC,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAU5B,IAAI,IAAI,MAAM,EAAE;CAGxB;AAED,eAAO,MAAM,uBAAuB,kBAAyB,CAAC"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Global Credentials Store
|
|
3
|
+
* Reads/writes a per-user credentials file (see global-dir.ts) so secrets can be
|
|
4
|
+
* configured once per device and reused across every Fridayy project, instead of
|
|
5
|
+
* being duplicated in plaintext inside per-project fridayy.config.json files.
|
|
6
|
+
*
|
|
7
|
+
* This is a plain JSON file, not an OS keychain — it is restricted to the
|
|
8
|
+
* current user via filesystem permissions (chmod 600 on POSIX) but is not
|
|
9
|
+
* encrypted at rest. Prefer real environment variables / a secrets manager for
|
|
10
|
+
* production deployments.
|
|
11
|
+
*/
|
|
12
|
+
import fs from 'node:fs';
|
|
13
|
+
import path from 'node:path';
|
|
14
|
+
import { getGlobalCredentialsPath } from './global-dir.js';
|
|
15
|
+
export class CredentialsStore {
|
|
16
|
+
filePath;
|
|
17
|
+
constructor(filePath = getGlobalCredentialsPath()) {
|
|
18
|
+
this.filePath = filePath;
|
|
19
|
+
}
|
|
20
|
+
getPath() {
|
|
21
|
+
return this.filePath;
|
|
22
|
+
}
|
|
23
|
+
load() {
|
|
24
|
+
if (!fs.existsSync(this.filePath)) {
|
|
25
|
+
return {};
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const raw = fs.readFileSync(this.filePath, 'utf-8');
|
|
29
|
+
const parsed = JSON.parse(raw);
|
|
30
|
+
return parsed && typeof parsed === 'object' ? parsed : {};
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
// A corrupt or unreadable credentials file must never crash secret
|
|
34
|
+
// resolution; treat it as empty and let env vars / config still work.
|
|
35
|
+
return {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
get(key) {
|
|
39
|
+
return this.load()[key];
|
|
40
|
+
}
|
|
41
|
+
set(key, value) {
|
|
42
|
+
const dir = path.dirname(this.filePath);
|
|
43
|
+
if (!fs.existsSync(dir)) {
|
|
44
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
45
|
+
}
|
|
46
|
+
const store = this.load();
|
|
47
|
+
store[key] = value;
|
|
48
|
+
fs.writeFileSync(this.filePath, JSON.stringify(store, null, 2), { encoding: 'utf-8', mode: 0o600 });
|
|
49
|
+
// Ensure permissions are tightened even if the file already existed with
|
|
50
|
+
// looser permissions (writeFileSync's `mode` only applies when creating).
|
|
51
|
+
try {
|
|
52
|
+
fs.chmodSync(this.filePath, 0o600);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
// Best-effort on platforms (e.g. Windows) where POSIX chmod semantics
|
|
56
|
+
// don't apply; the directory/file are still user-scoped by their location.
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
remove(key) {
|
|
60
|
+
const store = this.load();
|
|
61
|
+
if (!(key in store)) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
delete store[key];
|
|
65
|
+
fs.writeFileSync(this.filePath, JSON.stringify(store, null, 2), { encoding: 'utf-8', mode: 0o600 });
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
list() {
|
|
69
|
+
return Object.keys(this.load());
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
export const defaultCredentialsStore = new CredentialsStore();
|
|
73
|
+
//# sourceMappingURL=credentials-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credentials-store.js","sourceRoot":"","sources":["../../src/config/credentials-store.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;AAI3D,MAAM,OAAO,gBAAgB;IACE;IAA7B,YAA6B,WAAmB,wBAAwB,EAAE;QAA7C,aAAQ,GAAR,QAAQ,CAAqC;IAAG,CAAC;IAEvE,OAAO;QACZ,OAAO,IAAI,CAAC,QAAQ,CAAC;IACvB,CAAC;IAEM,IAAI;QACT,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClC,OAAO,EAAE,CAAC;QACZ,CAAC;QACD,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;YACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,OAAO,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5D,CAAC;QAAC,MAAM,CAAC;YACP,mEAAmE;YACnE,sEAAsE;YACtE,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEM,GAAG,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;IAC1B,CAAC;IAEM,GAAG,CAAC,GAAW,EAAE,KAAa;QACnC,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACxB,EAAE,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,KAAK,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACnB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAEpG,yEAAyE;QACzE,0EAA0E;QAC1E,IAAI,CAAC;YACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,sEAAsE;YACtE,2EAA2E;QAC7E,CAAC;IACH,CAAC;IAEM,MAAM,CAAC,GAAW;QACvB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC1B,IAAI,CAAC,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE,CAAC;YACpB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACpG,OAAO,IAAI,CAAC;IACd,CAAC;IAEM,IAAI;QACT,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;IAClC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,IAAI,gBAAgB,EAAE,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Cross-Platform Global Directory Resolver
|
|
3
|
+
* Resolves an OS-appropriate, per-user directory for Fridayy state that should
|
|
4
|
+
* be shared across projects on the same machine (e.g. credentials), following
|
|
5
|
+
* each platform's own convention instead of assuming a POSIX-style home layout.
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Returns the OS-appropriate root directory for per-user application config:
|
|
9
|
+
* - Windows: %APPDATA% (falls back to <home>/AppData/Roaming)
|
|
10
|
+
* - macOS: <home>/Library/Application Support
|
|
11
|
+
* - Linux/other: $XDG_CONFIG_HOME (falls back to <home>/.config)
|
|
12
|
+
*/
|
|
13
|
+
export declare function getGlobalConfigDir(): string;
|
|
14
|
+
/**
|
|
15
|
+
* Path to the global credentials store shared across every Fridayy project on
|
|
16
|
+
* this device. Intended as a safer alternative to embedding `auth.*.value`
|
|
17
|
+
* secrets directly inside a per-project fridayy.config.json (which is easy to
|
|
18
|
+
* accidentally commit to source control).
|
|
19
|
+
*/
|
|
20
|
+
export declare function getGlobalCredentialsPath(): string;
|
|
21
|
+
//# sourceMappingURL=global-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-dir.d.ts","sourceRoot":"","sources":["../../src/config/global-dir.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH;;;;;GAKG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAY3C;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,IAAI,MAAM,CAEjD"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Cross-Platform Global Directory Resolver
|
|
3
|
+
* Resolves an OS-appropriate, per-user directory for Fridayy state that should
|
|
4
|
+
* be shared across projects on the same machine (e.g. credentials), following
|
|
5
|
+
* each platform's own convention instead of assuming a POSIX-style home layout.
|
|
6
|
+
*/
|
|
7
|
+
import os from 'node:os';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
/**
|
|
10
|
+
* Returns the OS-appropriate root directory for per-user application config:
|
|
11
|
+
* - Windows: %APPDATA% (falls back to <home>/AppData/Roaming)
|
|
12
|
+
* - macOS: <home>/Library/Application Support
|
|
13
|
+
* - Linux/other: $XDG_CONFIG_HOME (falls back to <home>/.config)
|
|
14
|
+
*/
|
|
15
|
+
export function getGlobalConfigDir() {
|
|
16
|
+
const home = os.homedir();
|
|
17
|
+
if (process.platform === 'win32') {
|
|
18
|
+
return path.join(process.env.APPDATA || path.join(home, 'AppData', 'Roaming'), 'fridayy');
|
|
19
|
+
}
|
|
20
|
+
if (process.platform === 'darwin') {
|
|
21
|
+
return path.join(home, 'Library', 'Application Support', 'fridayy');
|
|
22
|
+
}
|
|
23
|
+
return path.join(process.env.XDG_CONFIG_HOME || path.join(home, '.config'), 'fridayy');
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Path to the global credentials store shared across every Fridayy project on
|
|
27
|
+
* this device. Intended as a safer alternative to embedding `auth.*.value`
|
|
28
|
+
* secrets directly inside a per-project fridayy.config.json (which is easy to
|
|
29
|
+
* accidentally commit to source control).
|
|
30
|
+
*/
|
|
31
|
+
export function getGlobalCredentialsPath() {
|
|
32
|
+
return path.join(getGlobalConfigDir(), 'credentials.json');
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=global-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global-dir.js","sourceRoot":"","sources":["../../src/config/global-dir.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,IAAI,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC;IAE1B,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;IAC5F,CAAC;IAED,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,SAAS,CAAC,CAAC;IACtE,CAAC;IAED,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,SAAS,CAAC,CAAC;AACzF,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,wBAAwB;IACtC,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Package Metadata Reader
|
|
3
|
+
* Reads the CLI's own version from package.json at runtime, so the version
|
|
4
|
+
* displayed by `--version` and the banner can never drift out of sync with a
|
|
5
|
+
* hardcoded string left behind after a release bump.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getPackageVersion(): string;
|
|
8
|
+
//# sourceMappingURL=package-info.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-info.d.ts","sourceRoot":"","sources":["../../src/config/package-info.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,wBAAgB,iBAAiB,IAAI,MAAM,CAgB1C"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fridayy - Package Metadata Reader
|
|
3
|
+
* Reads the CLI's own version from package.json at runtime, so the version
|
|
4
|
+
* displayed by `--version` and the banner can never drift out of sync with a
|
|
5
|
+
* hardcoded string left behind after a release bump.
|
|
6
|
+
*/
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
let cachedVersion;
|
|
11
|
+
export function getPackageVersion() {
|
|
12
|
+
if (cachedVersion)
|
|
13
|
+
return cachedVersion;
|
|
14
|
+
const moduleDir = path.dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
// This file lives at src/config/ (or dist/config/ once built), two levels
|
|
16
|
+
// below the repository/package root in both cases.
|
|
17
|
+
const pkgPath = path.resolve(moduleDir, '../../package.json');
|
|
18
|
+
try {
|
|
19
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, 'utf-8'));
|
|
20
|
+
cachedVersion = pkg.version || '0.0.0';
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
cachedVersion = '0.0.0';
|
|
24
|
+
}
|
|
25
|
+
return cachedVersion;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=package-info.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-info.js","sourceRoot":"","sources":["../../src/config/package-info.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,IAAI,aAAiC,CAAC;AAEtC,MAAM,UAAU,iBAAiB;IAC/B,IAAI,aAAa;QAAE,OAAO,aAAa,CAAC;IAExC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC/D,0EAA0E;IAC1E,mDAAmD;IACnD,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;IAE9D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAC1D,aAAa,GAAI,GAAG,CAAC,OAAkB,IAAI,OAAO,CAAC;IACrD,CAAC;IAAC,MAAM,CAAC;QACP,aAAa,GAAG,OAAO,CAAC;IAC1B,CAAC;IAED,OAAO,aAAa,CAAC;AACvB,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
* Fridayy - Secret Resolver & Isolation Engine
|
|
3
3
|
* Manages secret extraction from environment variables with zero leakage to LLM prompts/schemas.
|
|
4
4
|
*/
|
|
5
|
+
import { CredentialsStore } from '../../config/credentials-store.js';
|
|
5
6
|
export interface SecretResolutionOptions {
|
|
6
7
|
envKey?: string;
|
|
7
8
|
prefix?: string;
|
|
@@ -9,13 +10,21 @@ export interface SecretResolutionOptions {
|
|
|
9
10
|
}
|
|
10
11
|
export declare class SecretResolver {
|
|
11
12
|
private customEnv;
|
|
12
|
-
|
|
13
|
+
private credentialsStore;
|
|
14
|
+
constructor(customEnv?: Record<string, string>, credentialsStore?: CredentialsStore);
|
|
13
15
|
/**
|
|
14
|
-
* Resolves a secret value from process.env or
|
|
16
|
+
* Resolves a secret value from process.env, custom config, or the global
|
|
17
|
+
* per-device credentials store.
|
|
15
18
|
* Priority:
|
|
16
19
|
* 1. Direct envKey if specified in tool/auth definition
|
|
17
20
|
* 2. Standard FRIDAYY_<SCHEME>_KEY or FRIDAYY_<NAME>
|
|
18
21
|
* 3. customEnv lookup
|
|
22
|
+
* 4. Global credentials store (~/.config/fridayy/credentials.json or the
|
|
23
|
+
* OS-appropriate equivalent — see config/global-dir.ts), keyed by the same
|
|
24
|
+
* candidate env-var-shaped names. This lets a secret be configured once per
|
|
25
|
+
* device (`fridayy secrets set <NAME> <value>`) and reused by every project
|
|
26
|
+
* on that machine, instead of being duplicated in plaintext per-project
|
|
27
|
+
* config files.
|
|
19
28
|
*/
|
|
20
29
|
resolveSecret(keyOrScheme: string, options?: SecretResolutionOptions): string | undefined;
|
|
21
30
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-resolver.d.ts","sourceRoot":"","sources":["../../../src/core/authentication/secret-resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"secret-resolver.d.ts","sourceRoot":"","sources":["../../../src/core/authentication/secret-resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAA2B,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AAK9F,MAAM,WAAW,uBAAuB;IACtC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,gBAAgB,CAAmB;gBAE/B,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM,EAAE,gBAAgB,GAAE,gBAA0C;IAKhH;;;;;;;;;;;;;OAaG;IACI,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,MAAM,GAAG,SAAS;IAwCpG;;;;;;OAMG;IACI,cAAc,CAAC,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAWjE;;OAEG;IACI,kBAAkB,CAAC,WAAW,EAAE,KAAK,CAAC;QAAE,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG,MAAM,EAAE;CAkBjH;AAED,eAAO,MAAM,qBAAqB,gBAAuB,CAAC"}
|
|
@@ -3,24 +3,34 @@
|
|
|
3
3
|
* Manages secret extraction from environment variables with zero leakage to LLM prompts/schemas.
|
|
4
4
|
*/
|
|
5
5
|
import dotenv from 'dotenv';
|
|
6
|
+
import { defaultCredentialsStore } from '../../config/credentials-store.js';
|
|
6
7
|
// Load .env if present
|
|
7
8
|
dotenv.config();
|
|
8
9
|
export class SecretResolver {
|
|
9
10
|
customEnv;
|
|
10
|
-
|
|
11
|
+
credentialsStore;
|
|
12
|
+
constructor(customEnv = {}, credentialsStore = defaultCredentialsStore) {
|
|
11
13
|
this.customEnv = customEnv;
|
|
14
|
+
this.credentialsStore = credentialsStore;
|
|
12
15
|
}
|
|
13
16
|
/**
|
|
14
|
-
* Resolves a secret value from process.env or
|
|
17
|
+
* Resolves a secret value from process.env, custom config, or the global
|
|
18
|
+
* per-device credentials store.
|
|
15
19
|
* Priority:
|
|
16
20
|
* 1. Direct envKey if specified in tool/auth definition
|
|
17
21
|
* 2. Standard FRIDAYY_<SCHEME>_KEY or FRIDAYY_<NAME>
|
|
18
22
|
* 3. customEnv lookup
|
|
23
|
+
* 4. Global credentials store (~/.config/fridayy/credentials.json or the
|
|
24
|
+
* OS-appropriate equivalent — see config/global-dir.ts), keyed by the same
|
|
25
|
+
* candidate env-var-shaped names. This lets a secret be configured once per
|
|
26
|
+
* device (`fridayy secrets set <NAME> <value>`) and reused by every project
|
|
27
|
+
* on that machine, instead of being duplicated in plaintext per-project
|
|
28
|
+
* config files.
|
|
19
29
|
*/
|
|
20
30
|
resolveSecret(keyOrScheme, options = {}) {
|
|
21
31
|
// 1. Check explicit envKey
|
|
22
32
|
if (options.envKey) {
|
|
23
|
-
const explicitVal = process.env[options.envKey] || this.customEnv[options.envKey];
|
|
33
|
+
const explicitVal = process.env[options.envKey] || this.customEnv[options.envKey] || this.credentialsStore.get(options.envKey);
|
|
24
34
|
if (explicitVal)
|
|
25
35
|
return explicitVal;
|
|
26
36
|
}
|
|
@@ -45,6 +55,11 @@ export class SecretResolver {
|
|
|
45
55
|
return this.customEnv[cand];
|
|
46
56
|
}
|
|
47
57
|
}
|
|
58
|
+
for (const cand of candidates) {
|
|
59
|
+
const stored = this.credentialsStore.get(cand);
|
|
60
|
+
if (stored)
|
|
61
|
+
return stored;
|
|
62
|
+
}
|
|
48
63
|
return options.fallbackValue;
|
|
49
64
|
}
|
|
50
65
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"secret-resolver.js","sourceRoot":"","sources":["../../../src/core/authentication/secret-resolver.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,MAAM,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"secret-resolver.js","sourceRoot":"","sources":["../../../src/core/authentication/secret-resolver.ts"],"names":[],"mappings":"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"}
|
|
@@ -8,6 +8,7 @@ export declare class ProjectScanner {
|
|
|
8
8
|
private adapterRegistry;
|
|
9
9
|
private openApiParser;
|
|
10
10
|
private nodeJsScanner;
|
|
11
|
+
private laravelScanner;
|
|
11
12
|
constructor(adapterRegistry?: AdapterRegistry);
|
|
12
13
|
/**
|
|
13
14
|
* Scans a root directory and returns comprehensive capability detection results.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-scanner.d.ts","sourceRoot":"","sources":["../../../src/core/discovery/project-scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAA0B,MAAM,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"project-scanner.d.ts","sourceRoot":"","sources":["../../../src/core/discovery/project-scanner.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,OAAO,EAAE,UAAU,EAAiB,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,eAAe,EAA0B,MAAM,4BAA4B,CAAC;AAKrF,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,cAAc,CAA6B;gBAEvC,eAAe,GAAE,eAAwC;IAIrE;;OAEG;IACU,IAAI,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IA2IvE,OAAO,CAAC,gBAAgB;IAyCxB,OAAO,CAAC,cAAc;CAcvB;AAED,eAAO,MAAM,qBAAqB,gBAAuB,CAAC"}
|
|
@@ -7,10 +7,12 @@ import path from 'node:path';
|
|
|
7
7
|
import { defaultAdapterRegistry } from '../../adapters/registry.js';
|
|
8
8
|
import { OpenApiParser } from '../../adapters/openapi/parser.js';
|
|
9
9
|
import { NodeJsScanner } from '../../adapters/nodejs/ast-scanner.js';
|
|
10
|
+
import { LaravelRouteScanner } from '../../adapters/laravel/route-scanner.js';
|
|
10
11
|
export class ProjectScanner {
|
|
11
12
|
adapterRegistry;
|
|
12
13
|
openApiParser = new OpenApiParser();
|
|
13
14
|
nodeJsScanner = new NodeJsScanner();
|
|
15
|
+
laravelScanner = new LaravelRouteScanner();
|
|
14
16
|
constructor(adapterRegistry = defaultAdapterRegistry) {
|
|
15
17
|
this.adapterRegistry = adapterRegistry;
|
|
16
18
|
}
|
|
@@ -38,7 +40,7 @@ export class ProjectScanner {
|
|
|
38
40
|
});
|
|
39
41
|
// Collect security schemes
|
|
40
42
|
if (parsed.securityDefinitions) {
|
|
41
|
-
for (const [schemeName
|
|
43
|
+
for (const [schemeName] of Object.entries(parsed.securityDefinitions)) {
|
|
42
44
|
authSchemesDetected.add(schemeName);
|
|
43
45
|
}
|
|
44
46
|
}
|
|
@@ -64,6 +66,8 @@ export class ProjectScanner {
|
|
|
64
66
|
nodeJsFramework = 'koa';
|
|
65
67
|
else if (allDeps['@nestjs/core'])
|
|
66
68
|
nodeJsFramework = 'nestjs';
|
|
69
|
+
else if (allDeps.next)
|
|
70
|
+
nodeJsFramework = 'custom';
|
|
67
71
|
else
|
|
68
72
|
nodeJsFramework = 'custom';
|
|
69
73
|
}
|
|
@@ -71,29 +75,62 @@ export class ProjectScanner {
|
|
|
71
75
|
nodeJsFramework = 'custom';
|
|
72
76
|
}
|
|
73
77
|
}
|
|
74
|
-
const discoveredRoutes = await this.nodeJsScanner.scanDirectory(absRoot,
|
|
75
|
-
if (discoveredRoutes.length > 0
|
|
78
|
+
const discoveredRoutes = await this.nodeJsScanner.scanDirectory(absRoot, 500);
|
|
79
|
+
if (!hasOpenApi && discoveredRoutes.length > 0) {
|
|
76
80
|
totalEndpoints += discoveredRoutes.length;
|
|
77
81
|
}
|
|
82
|
+
// 2b. Scan for a Laravel project (artisan CLI, laravel/framework composer
|
|
83
|
+
// dependency, or an actual routes/*.php with Route:: declarations).
|
|
84
|
+
const hasArtisanFile = fs.existsSync(path.join(absRoot, 'artisan'));
|
|
85
|
+
let hasLaravelComposerDep = false;
|
|
86
|
+
const composerJsonPath = path.join(absRoot, 'composer.json');
|
|
87
|
+
if (fs.existsSync(composerJsonPath)) {
|
|
88
|
+
try {
|
|
89
|
+
const composer = JSON.parse(fs.readFileSync(composerJsonPath, 'utf-8'));
|
|
90
|
+
const allPhpDeps = { ...composer.require, ...composer['require-dev'] };
|
|
91
|
+
hasLaravelComposerDep = Boolean(allPhpDeps['laravel/framework'] || allPhpDeps['laravel/lumen-framework']);
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// ignore malformed composer.json
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
const laravelRoutes = hasArtisanFile || hasLaravelComposerDep ? await this.laravelScanner.scanDirectory(absRoot) : [];
|
|
98
|
+
const hasLaravel = hasArtisanFile || hasLaravelComposerDep || laravelRoutes.length > 0;
|
|
99
|
+
if (!hasOpenApi && !hasNodeJs && laravelRoutes.length > 0) {
|
|
100
|
+
totalEndpoints += laravelRoutes.length;
|
|
101
|
+
}
|
|
78
102
|
// 3. Formulate recommended configuration
|
|
79
103
|
const projectName = path.basename(absRoot);
|
|
104
|
+
let recommendedSource;
|
|
105
|
+
if (hasOpenApi) {
|
|
106
|
+
recommendedSource = {
|
|
107
|
+
type: 'openapi',
|
|
108
|
+
path: openApiFiles[0]
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
else if (hasLaravel) {
|
|
112
|
+
recommendedSource = {
|
|
113
|
+
type: 'laravel',
|
|
114
|
+
rootDir: './',
|
|
115
|
+
baseUrl: 'http://localhost:8000'
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
else if (hasNodeJs) {
|
|
119
|
+
recommendedSource = {
|
|
120
|
+
type: 'nodejs',
|
|
121
|
+
rootDir: './'
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
else {
|
|
125
|
+
recommendedSource = {
|
|
126
|
+
type: 'rest',
|
|
127
|
+
baseUrl: 'http://localhost:3000'
|
|
128
|
+
};
|
|
129
|
+
}
|
|
80
130
|
const recommendedConfig = {
|
|
81
131
|
name: projectName,
|
|
82
132
|
version: '1.0.0',
|
|
83
|
-
source:
|
|
84
|
-
? {
|
|
85
|
-
type: 'openapi',
|
|
86
|
-
path: openApiFiles[0]
|
|
87
|
-
}
|
|
88
|
-
: hasNodeJs && discoveredRoutes.length > 0
|
|
89
|
-
? {
|
|
90
|
-
type: 'nodejs',
|
|
91
|
-
rootDir: './'
|
|
92
|
-
}
|
|
93
|
-
: {
|
|
94
|
-
type: 'openapi',
|
|
95
|
-
path: './openapi.yaml'
|
|
96
|
-
},
|
|
133
|
+
source: recommendedSource,
|
|
97
134
|
server: {
|
|
98
135
|
name: `${projectName}-mcp`,
|
|
99
136
|
version: '1.0.0',
|
|
@@ -110,12 +147,13 @@ export class ProjectScanner {
|
|
|
110
147
|
openApiFiles,
|
|
111
148
|
hasNodeJs,
|
|
112
149
|
nodeJsFramework,
|
|
150
|
+
hasLaravel,
|
|
113
151
|
discoveredEndpointsCount: totalEndpoints,
|
|
114
152
|
authSchemesDetected: Array.from(authSchemesDetected),
|
|
115
153
|
recommendedConfig,
|
|
116
154
|
details: {
|
|
117
155
|
openApiSpecs: openApiSpecsDetails,
|
|
118
|
-
routes: discoveredRoutes
|
|
156
|
+
routes: hasLaravel && !hasOpenApi && !hasNodeJs ? laravelRoutes : discoveredRoutes
|
|
119
157
|
}
|
|
120
158
|
};
|
|
121
159
|
}
|
|
@@ -130,7 +168,9 @@ export class ProjectScanner {
|
|
|
130
168
|
'api/openapi.yaml',
|
|
131
169
|
'api/openapi.json',
|
|
132
170
|
'docs/openapi.yaml',
|
|
133
|
-
'docs/openapi.json'
|
|
171
|
+
'docs/openapi.json',
|
|
172
|
+
'src/openapi.yaml',
|
|
173
|
+
'src/openapi.json'
|
|
134
174
|
];
|
|
135
175
|
const found = [];
|
|
136
176
|
for (const rel of candidates) {
|
|
@@ -138,7 +178,7 @@ export class ProjectScanner {
|
|
|
138
178
|
found.push(rel);
|
|
139
179
|
}
|
|
140
180
|
}
|
|
141
|
-
// Also search root for any *.openapi.json or *.swagger.yaml
|
|
181
|
+
// Also search root and common folders for any *.openapi.json or *.swagger.yaml
|
|
142
182
|
try {
|
|
143
183
|
const files = fs.readdirSync(rootDir);
|
|
144
184
|
for (const file of files) {
|