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.
Files changed (102) hide show
  1. package/README.md +61 -3
  2. package/dist/adapters/laravel/adapter.d.ts +21 -0
  3. package/dist/adapters/laravel/adapter.d.ts.map +1 -0
  4. package/dist/adapters/laravel/adapter.js +133 -0
  5. package/dist/adapters/laravel/adapter.js.map +1 -0
  6. package/dist/adapters/laravel/route-scanner.d.ts +39 -0
  7. package/dist/adapters/laravel/route-scanner.d.ts.map +1 -0
  8. package/dist/adapters/laravel/route-scanner.js +238 -0
  9. package/dist/adapters/laravel/route-scanner.js.map +1 -0
  10. package/dist/adapters/nodejs/ast-scanner.d.ts +5 -3
  11. package/dist/adapters/nodejs/ast-scanner.d.ts.map +1 -1
  12. package/dist/adapters/nodejs/ast-scanner.js +104 -29
  13. package/dist/adapters/nodejs/ast-scanner.js.map +1 -1
  14. package/dist/adapters/registry.d.ts.map +1 -1
  15. package/dist/adapters/registry.js +2 -0
  16. package/dist/adapters/registry.js.map +1 -1
  17. package/dist/adapters/rest/adapter.d.ts +1 -0
  18. package/dist/adapters/rest/adapter.d.ts.map +1 -1
  19. package/dist/adapters/rest/adapter.js +124 -2
  20. package/dist/adapters/rest/adapter.js.map +1 -1
  21. package/dist/adapters/rest/executor.d.ts.map +1 -1
  22. package/dist/adapters/rest/executor.js +1 -2
  23. package/dist/adapters/rest/executor.js.map +1 -1
  24. package/dist/cli/commands/config.d.ts.map +1 -1
  25. package/dist/cli/commands/config.js +27 -3
  26. package/dist/cli/commands/config.js.map +1 -1
  27. package/dist/cli/commands/doctor.d.ts.map +1 -1
  28. package/dist/cli/commands/doctor.js +105 -4
  29. package/dist/cli/commands/doctor.js.map +1 -1
  30. package/dist/cli/commands/generate.d.ts.map +1 -1
  31. package/dist/cli/commands/generate.js +11 -1
  32. package/dist/cli/commands/generate.js.map +1 -1
  33. package/dist/cli/commands/init.d.ts +1 -1
  34. package/dist/cli/commands/init.d.ts.map +1 -1
  35. package/dist/cli/commands/init.js +65 -8
  36. package/dist/cli/commands/init.js.map +1 -1
  37. package/dist/cli/commands/scan.d.ts.map +1 -1
  38. package/dist/cli/commands/scan.js +33 -17
  39. package/dist/cli/commands/scan.js.map +1 -1
  40. package/dist/cli/commands/secrets.d.ts +9 -0
  41. package/dist/cli/commands/secrets.d.ts.map +1 -0
  42. package/dist/cli/commands/secrets.js +50 -0
  43. package/dist/cli/commands/secrets.js.map +1 -0
  44. package/dist/cli/commands/start.d.ts.map +1 -1
  45. package/dist/cli/commands/start.js +14 -1
  46. package/dist/cli/commands/start.js.map +1 -1
  47. package/dist/cli/index.d.ts.map +1 -1
  48. package/dist/cli/index.js +26 -3
  49. package/dist/cli/index.js.map +1 -1
  50. package/dist/cli/ui/banner.d.ts.map +1 -1
  51. package/dist/cli/ui/banner.js +2 -1
  52. package/dist/cli/ui/banner.js.map +1 -1
  53. package/dist/config/credentials-store.d.ts +24 -0
  54. package/dist/config/credentials-store.d.ts.map +1 -0
  55. package/dist/config/credentials-store.js +73 -0
  56. package/dist/config/credentials-store.js.map +1 -0
  57. package/dist/config/global-dir.d.ts +21 -0
  58. package/dist/config/global-dir.d.ts.map +1 -0
  59. package/dist/config/global-dir.js +34 -0
  60. package/dist/config/global-dir.js.map +1 -0
  61. package/dist/config/package-info.d.ts +8 -0
  62. package/dist/config/package-info.d.ts.map +1 -0
  63. package/dist/config/package-info.js +27 -0
  64. package/dist/config/package-info.js.map +1 -0
  65. package/dist/core/authentication/secret-resolver.d.ts +11 -2
  66. package/dist/core/authentication/secret-resolver.d.ts.map +1 -1
  67. package/dist/core/authentication/secret-resolver.js +18 -3
  68. package/dist/core/authentication/secret-resolver.js.map +1 -1
  69. package/dist/core/discovery/project-scanner.d.ts +1 -0
  70. package/dist/core/discovery/project-scanner.d.ts.map +1 -1
  71. package/dist/core/discovery/project-scanner.js +60 -20
  72. package/dist/core/discovery/project-scanner.js.map +1 -1
  73. package/dist/core/permissions/classifier.js +3 -3
  74. package/dist/core/permissions/classifier.js.map +1 -1
  75. package/dist/core/permissions/enforcer.d.ts +10 -0
  76. package/dist/core/permissions/enforcer.d.ts.map +1 -1
  77. package/dist/core/permissions/enforcer.js +16 -0
  78. package/dist/core/permissions/enforcer.js.map +1 -1
  79. package/dist/core/schema/types.d.ts +5 -2
  80. package/dist/core/schema/types.d.ts.map +1 -1
  81. package/dist/core/tool-generator/generator.d.ts +3 -1
  82. package/dist/core/tool-generator/generator.d.ts.map +1 -1
  83. package/dist/core/tool-generator/generator.js +33 -5
  84. package/dist/core/tool-generator/generator.js.map +1 -1
  85. package/dist/core/validation/config-schema.d.ts +10 -5
  86. package/dist/core/validation/config-schema.d.ts.map +1 -1
  87. package/dist/core/validation/config-schema.js +3 -2
  88. package/dist/core/validation/config-schema.js.map +1 -1
  89. package/dist/mcp/server/fridayy-server.d.ts +8 -1
  90. package/dist/mcp/server/fridayy-server.d.ts.map +1 -1
  91. package/dist/mcp/server/fridayy-server.js +29 -1
  92. package/dist/mcp/server/fridayy-server.js.map +1 -1
  93. package/dist/mcp/tools/tool-handler.d.ts.map +1 -1
  94. package/dist/mcp/tools/tool-handler.js +35 -0
  95. package/dist/mcp/tools/tool-handler.js.map +1 -1
  96. package/dist/security/audit-logger.d.ts.map +1 -1
  97. package/dist/security/audit-logger.js +4 -1
  98. package/dist/security/audit-logger.js.map +1 -1
  99. package/dist/security/sanitizer.d.ts.map +1 -1
  100. package/dist/security/sanitizer.js +26 -5
  101. package/dist/security/sanitizer.js.map +1 -1
  102. 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('1.2.0')
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
- if (import.meta.url === `file://${process.argv[1]}` || process.argv[1]?.endsWith('fridayy') || process.argv[1]?.endsWith('index.ts') || process.argv[1]?.endsWith('index.js')) {
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);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
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;AAIH,wBAAgB,SAAS,IAAI,MAAM,CAgBlC;AAID,wBAAgB,WAAW,CAAC,KAAK,UAAQ,GAAG,IAAI,CAK/C;AAED,wBAAgB,eAAe,IAAI,IAAI,CAEtC"}
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"}
@@ -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('v1.2.0')} ${chalk.bgHex('#5e17eb').white.bold(' MCP Standard ')} ${chalk.gray('•')} ${chalk.yellow('⚡')} Developed with ${chalk.red('❤️')} by ${chalk.hex('#00f5d4').bold('Sabarivasan')}\n`;
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;AAE1B,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,QAAQ,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;IAC9O,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"}
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
- constructor(customEnv?: Record<string, string>);
13
+ private credentialsStore;
14
+ constructor(customEnv?: Record<string, string>, credentialsStore?: CredentialsStore);
13
15
  /**
14
- * Resolves a secret value from process.env or custom config.
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;AAOH,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;gBAE9B,SAAS,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAIlD;;;;;;OAMG;IACI,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,GAAE,uBAA4B,GAAG,MAAM,GAAG,SAAS;IAkCpG;;;;;;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"}
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
- constructor(customEnv = {}) {
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 custom config.
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;AAE5B,uBAAuB;AACvB,MAAM,CAAC,MAAM,EAAE,CAAC;AAQhB,MAAM,OAAO,cAAc;IACjB,SAAS,CAAyB;IAE1C,YAAY,YAAoC,EAAE;QAChD,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;IAC7B,CAAC;IAED;;;;;;OAMG;IACI,aAAa,CAAC,WAAmB,EAAE,UAAmC,EAAE;QAC7E,2BAA2B;QAC3B,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;YACnB,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAClF,IAAI,WAAW;gBAAE,OAAO,WAAW,CAAC;QACtC,CAAC;QAED,2DAA2D;QAC3D,MAAM,YAAY,GAAG,WAAW,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QAE3E,MAAM,UAAU,GAAG;YACjB,OAAO,CAAC,MAAM;YACd,WAAW,YAAY,EAAE;YACzB,eAAe,YAAY,EAAE;YAC7B,WAAW,YAAY,MAAM;YAC7B,WAAW,YAAY,QAAQ;YAC/B,iBAAiB;YACjB,sBAAsB;YACtB,oBAAoB;YACpB,WAAW;SACZ,CAAC,MAAM,CAAC,OAAO,CAAa,CAAC;QAE9B,KAAK,MAAM,IAAI,IAAI,UAAU,EAAE,CAAC;YAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;gBACtB,OAAO,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC3B,CAAC;YACD,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC,aAAa,CAAC;IAC/B,CAAC;IAED;;;;;;OAMG;IACI,cAAc,CAAC,aAAsB;QAC1C,OAAO,CACL,OAAO,CAAC,GAAG,CAAC,eAAe;YAC3B,OAAO,CAAC,GAAG,CAAC,gBAAgB;YAC5B,OAAO,CAAC,GAAG,CAAC,OAAO;YACnB,IAAI,CAAC,SAAS,CAAC,eAAe;YAC9B,IAAI,CAAC,SAAS,CAAC,gBAAgB;YAC/B,aAAa,CACd,CAAC;IACJ,CAAC;IAED;;OAEG;IACI,kBAAkB,CAAC,WAA2E;QACnG,MAAM,YAAY,GAAG,IAAI,GAAG,EAAU,CAAC;QAEvC,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAChB,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAChC,CAAC;iBAAM,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBAC3B,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;gBAC5E,YAAY,CAAC,GAAG,CAAC,WAAW,SAAS,EAAE,CAAC,CAAC;YAC3C,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAClC,YAAY,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;YACtC,CAAC;iBAAM,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAClC,YAAY,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YAC3C,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAClC,CAAC;CACF;AAED,MAAM,CAAC,MAAM,qBAAqB,GAAG,IAAI,cAAc,EAAE,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;AAIrF,qBAAa,cAAc;IACzB,OAAO,CAAC,eAAe,CAAkB;IACzC,OAAO,CAAC,aAAa,CAAuB;IAC5C,OAAO,CAAC,aAAa,CAAuB;gBAEhC,eAAe,GAAE,eAAwC;IAIrE;;OAEG;IACU,IAAI,CAAC,OAAO,GAAE,MAAsB,GAAG,OAAO,CAAC,UAAU,CAAC;IAyGvE,OAAO,CAAC,gBAAgB;IAuCxB,OAAO,CAAC,cAAc;CAcvB;AAED,eAAO,MAAM,qBAAqB,gBAAuB,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, schemeDef] of Object.entries(parsed.securityDefinitions)) {
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, 100);
75
- if (discoveredRoutes.length > 0 && !hasOpenApi) {
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: hasOpenApi
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) {