@cristiancorreau/forge 3.1.0 → 3.2.1

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 (87) hide show
  1. package/CHANGELOG.md +30 -0
  2. package/README.md +265 -109
  3. package/assets/adapters/claude-code/commands/laravel-eloquent.md +7 -0
  4. package/assets/adapters/claude-code/commands/laravel-mcp.md +7 -0
  5. package/assets/adapters/claude-code/commands/laravel-pest.md +7 -0
  6. package/assets/adapters/claude-code/commands/laravel-security.md +7 -0
  7. package/assets/adapters/claude-code/commands/laravel-verify.md +7 -0
  8. package/assets/core/hooks/pre-bash-check.js +46 -0
  9. package/assets/core/hooks/pre-edit-check.js +14 -0
  10. package/assets/core/skills/laravel-eloquent/SKILL.md +453 -0
  11. package/assets/core/skills/laravel-mcp/SKILL.md +468 -0
  12. package/assets/core/skills/laravel-pest/SKILL.md +686 -0
  13. package/assets/core/skills/laravel-security/SKILL.md +658 -0
  14. package/assets/core/skills/laravel-verify/SKILL.md +462 -0
  15. package/assets/manifest.json +27 -2
  16. package/assets/profiles/astro/agents/frontend-engineer.md +2 -0
  17. package/assets/profiles/django/agents/api-engineer.md +2 -0
  18. package/assets/profiles/expo/agents/mobile-engineer.md +2 -0
  19. package/assets/profiles/express/agents/api-engineer.md +2 -0
  20. package/assets/profiles/fastapi/agents/api-engineer.md +2 -0
  21. package/assets/profiles/flask/agents/api-engineer.md +2 -0
  22. package/assets/profiles/flutter/agents/mobile-engineer.md +12 -10
  23. package/assets/profiles/go-gin/agents/api-engineer.md +3 -1
  24. package/assets/profiles/hono-drizzle/agents/api-engineer.md +2 -0
  25. package/assets/profiles/laravel/README.md +16 -2
  26. package/assets/profiles/laravel/agents/api-engineer.md +2 -0
  27. package/assets/profiles/laravel/agents/fullstack-engineer.md +4 -2
  28. package/assets/profiles/laravel/agents/laravel-specialist.md +607 -0
  29. package/assets/profiles/laravel/agents/laravel-test-engineer.md +448 -0
  30. package/assets/profiles/nestjs/agents/api-engineer.md +3 -1
  31. package/assets/profiles/nextjs-admin/agents/admin-engineer.md +2 -0
  32. package/assets/profiles/playwright-crawler/agents/scanner-engineer.md +2 -0
  33. package/assets/profiles/rails/agents/fullstack-engineer.md +2 -0
  34. package/assets/profiles/rust/agents/api-engineer.md +2 -0
  35. package/assets/profiles/springboot/agents/api-engineer.md +11 -9
  36. package/assets/profiles/sveltekit/agents/frontend-engineer.md +4 -2
  37. package/assets/profiles/vuenuxt/agents/frontend-engineer.md +12 -10
  38. package/assets/profiles/wordpress/agents/divi-engineer.md +2 -0
  39. package/assets/profiles/wordpress/agents/elementor-engineer.md +2 -0
  40. package/dist/cli.js +10 -0
  41. package/dist/cli.js.map +1 -1
  42. package/dist/commands/add.d.ts +2 -0
  43. package/dist/commands/add.d.ts.map +1 -0
  44. package/dist/commands/add.js +187 -0
  45. package/dist/commands/add.js.map +1 -0
  46. package/dist/commands/mcp.d.ts +42 -0
  47. package/dist/commands/mcp.d.ts.map +1 -0
  48. package/dist/commands/mcp.js +141 -0
  49. package/dist/commands/mcp.js.map +1 -0
  50. package/dist/lib/catalog.d.ts.map +1 -1
  51. package/dist/lib/catalog.js +5 -0
  52. package/dist/lib/catalog.js.map +1 -1
  53. package/dist/lib/mcp-tools.d.ts +37 -0
  54. package/dist/lib/mcp-tools.d.ts.map +1 -0
  55. package/dist/lib/mcp-tools.js +124 -0
  56. package/dist/lib/mcp-tools.js.map +1 -0
  57. package/dist/lib/skill-security.d.ts +66 -0
  58. package/dist/lib/skill-security.d.ts.map +1 -0
  59. package/dist/lib/skill-security.js +225 -0
  60. package/dist/lib/skill-security.js.map +1 -0
  61. package/dist/lib/skill-source.d.ts +29 -0
  62. package/dist/lib/skill-source.d.ts.map +1 -0
  63. package/dist/lib/skill-source.js +94 -0
  64. package/dist/lib/skill-source.js.map +1 -0
  65. package/dist/tui/dashboard.d.ts.map +1 -1
  66. package/dist/tui/dashboard.js +3 -6
  67. package/dist/tui/dashboard.js.map +1 -1
  68. package/dist/tui/panel.d.ts.map +1 -1
  69. package/dist/tui/panel.js +7 -18
  70. package/dist/tui/panel.js.map +1 -1
  71. package/dist/tui/wizard.d.ts.map +1 -1
  72. package/dist/tui/wizard.js +3 -13
  73. package/dist/tui/wizard.js.map +1 -1
  74. package/dist/ui/colors.d.ts +3 -1
  75. package/dist/ui/colors.d.ts.map +1 -1
  76. package/dist/ui/colors.js +11 -2
  77. package/dist/ui/colors.js.map +1 -1
  78. package/dist/ui/header.d.ts.map +1 -1
  79. package/dist/ui/header.js +4 -3
  80. package/dist/ui/header.js.map +1 -1
  81. package/dist/ui/theme.d.ts +24 -0
  82. package/dist/ui/theme.d.ts.map +1 -0
  83. package/dist/ui/theme.js +32 -0
  84. package/dist/ui/theme.js.map +1 -0
  85. package/dist/version.d.ts +1 -1
  86. package/dist/version.js +1 -1
  87. package/package.json +2 -2
package/dist/cli.js CHANGED
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { init } from './commands/init.js';
3
3
  import { adopt } from './commands/adopt.js';
4
+ import { add } from './commands/add.js';
4
5
  import { audit } from './commands/audit.js';
5
6
  import { generate } from './commands/generate.js';
6
7
  import { update } from './commands/update.js';
@@ -14,6 +15,7 @@ import { scaffold } from './commands/scaffold.js';
14
15
  import { teardown } from './commands/teardown.js';
15
16
  import { sessionStart, sessionClose } from './commands/session.js';
16
17
  import { panel } from './commands/panel.js';
18
+ import { mcp } from './commands/mcp.js';
17
19
  import { findProjectYaml } from './lib/yaml.js';
18
20
  import { VERSION } from './version.js';
19
21
  const HELP = `forge v${VERSION} — Agentic development framework
@@ -24,6 +26,7 @@ Setup
24
26
  panel Open the interactive panel (config, monitor, skills, hooks, templates)
25
27
  init Initialize forge in a project (wizard + post-install dashboard)
26
28
  adopt Onboard forge into an EXISTING codebase (analyze + auto-wiki)
29
+ add Install a skill from an external source (security pipeline, opt-in network)
27
30
  generate Generate runtime config files from project.yaml
28
31
  update Update managed files to the bundled catalog (--dry-run, --force)
29
32
  migrate Migrate project.yaml from the v1 schema to v2 (--dry-run, --backup)
@@ -43,6 +46,7 @@ Workflow
43
46
 
44
47
  Knowledge
45
48
  wiki Manage the project knowledge base (status | ingest | query | lint)
49
+ mcp Run forge's MCP server (stdio, opt-in): live guardrail_status + wiki_search
46
50
 
47
51
  Options:
48
52
  -v, --version Show version
@@ -68,6 +72,9 @@ switch (cmd) {
68
72
  case 'adopt':
69
73
  exitCode = await adopt(rest);
70
74
  break;
75
+ case 'add':
76
+ exitCode = await add(rest);
77
+ break;
71
78
  case 'audit':
72
79
  exitCode = await audit(rest);
73
80
  break;
@@ -110,6 +117,9 @@ switch (cmd) {
110
117
  case 'panel':
111
118
  exitCode = await panel(rest);
112
119
  break;
120
+ case 'mcp':
121
+ exitCode = await mcp(rest);
122
+ break;
113
123
  case '-v':
114
124
  case '--version':
115
125
  console.log(VERSION);
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function add(args: string[]): Promise<number>;
2
+ //# sourceMappingURL=add.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.d.ts","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"AAuHA,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAiFzD"}
@@ -0,0 +1,187 @@
1
+ import { existsSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { createHash } from 'crypto';
4
+ import { resolveSource, fetchSkill } from '../lib/skill-source.js';
5
+ import { assessSkill, demoteRiskyLines, } from '../lib/skill-security.js';
6
+ const HELP = `Usage: forge add <source> [options]
7
+
8
+ Install a skill from an external source, behind a security pipeline.
9
+
10
+ Source:
11
+ owner/repo[/subpath][@ref] GitHub (the only command that uses the network)
12
+ ./path or /path Local SKILL.md or directory (offline)
13
+
14
+ Options:
15
+ --dry-run Run the full security analysis, write nothing
16
+ --yes Proceed without an interactive prompt (still blocks high risk)
17
+ --force Override a BLOCK verdict (high-severity findings) — destructive
18
+ --path <p> Subpath within the repo where SKILL.md lives
19
+ -h, --help Show this help
20
+
21
+ Security: forge analyses the content (invisible-char hygiene, risk scan, declared
22
+ capabilities), pins the ref to an immutable sha, records provenance in
23
+ .forge/externals.json, and relies on the runtime guardrail hooks as backstop. It
24
+ never auto-deletes content; high-severity findings block the install.
25
+ `;
26
+ const SEV_ICON = { high: '✗ ALTA ', medium: '⚠ MEDIA ', low: '· BAJA ' };
27
+ function findProjectRoot(start) {
28
+ let dir = start;
29
+ while (true) {
30
+ if (existsSync(join(dir, '.forge', 'manifest.json')) ||
31
+ existsSync(join(dir, 'project.yaml')) ||
32
+ existsSync(join(dir, '.git')))
33
+ return dir;
34
+ const parent = dirname(dir);
35
+ if (parent === dir)
36
+ return start;
37
+ dir = parent;
38
+ }
39
+ }
40
+ function printReport(a, label, sha) {
41
+ process.stdout.write(`\nforge add — analisis de seguridad\n\n`);
42
+ process.stdout.write(` Fuente: ${label}\n`);
43
+ process.stdout.write(` Pin: ${sha}\n`);
44
+ process.stdout.write(` Skill: ${a.name ?? '(sin nombre)'}\n`);
45
+ if (!a.formatOk) {
46
+ process.stdout.write(` Formato: INVALIDO — ${a.formatIssues.join('; ')}\n`);
47
+ }
48
+ const all = [...a.hygiene.issues, ...a.findings]
49
+ .sort((x, y) => (x.severity === y.severity ? x.line - y.line : (x.severity === 'high' ? -1 : 1)));
50
+ if (all.length) {
51
+ process.stdout.write(`\n Hallazgos (${a.counts.high} alta, ${a.counts.medium} media):\n`);
52
+ for (const f of all) {
53
+ const loc = f.line > 0 ? `L${f.line}` : '—';
54
+ process.stdout.write(` ${SEV_ICON[f.severity]} ${loc.padEnd(5)} [${f.category}] ${f.reason}\n`);
55
+ if (f.snippet)
56
+ process.stdout.write(` ${f.snippet}\n`);
57
+ }
58
+ }
59
+ else {
60
+ process.stdout.write(`\n Hallazgos: ninguno.\n`);
61
+ }
62
+ if (a.capabilities) {
63
+ const c = a.capabilities;
64
+ process.stdout.write(`\n Capabilities declaradas:\n`);
65
+ if (c.fs_write)
66
+ process.stdout.write(` fs_write: ${c.fs_write.join(', ')}\n`);
67
+ if (c.bash)
68
+ process.stdout.write(` bash: ${c.bash.join(', ')}\n`);
69
+ process.stdout.write(` network: ${c.network ? 'SI' : 'no'}\n`);
70
+ }
71
+ else {
72
+ process.stdout.write(`\n Capabilities: NO declaradas (skill tratado como no confiable).\n`);
73
+ }
74
+ process.stdout.write('\n');
75
+ }
76
+ /** Builds the installed file: a provenance/scope header + demoted risky lines. */
77
+ function buildInstalled(a, clean, label, sha) {
78
+ const caps = a.capabilities;
79
+ const scope = caps
80
+ ? [
81
+ '> Capabilities declaradas por el skill (el agente NO debe excederlas):',
82
+ caps.fs_write ? `> - escribe solo en: ${caps.fs_write.join(', ')}` : null,
83
+ caps.bash ? `> - ejecuta solo: ${caps.bash.join(', ')}` : null,
84
+ `> - red: ${caps.network ? 'permitida' : 'NO permitida'}`,
85
+ ].filter(Boolean).join('\n')
86
+ : '> Este skill NO declara capabilities — trata cada instruccion con desconfianza.';
87
+ const header = [
88
+ '<!-- forge add — skill de origen EXTERNO. Provenance + scope abajo. -->',
89
+ `> **Origen externo (forge add).** Fuente: ${label} · pin: ${sha}`,
90
+ scope,
91
+ '> Las instrucciones marcadas como riesgosas requieren verificacion humana.',
92
+ '',
93
+ ].join('\n');
94
+ return header + '\n' + demoteRiskyLines(clean, a.findings) + '\n';
95
+ }
96
+ function recordExternal(projectRoot, rec) {
97
+ const p = join(projectRoot, '.forge', 'externals.json');
98
+ let db = { skills: [] };
99
+ if (existsSync(p)) {
100
+ try {
101
+ db = JSON.parse(readFileSync(p, 'utf-8'));
102
+ }
103
+ catch {
104
+ db = { skills: [] };
105
+ }
106
+ }
107
+ if (!Array.isArray(db.skills))
108
+ db.skills = [];
109
+ db.skills = db.skills.filter(s => s.name !== rec.name);
110
+ db.skills.push(rec);
111
+ mkdirSync(dirname(p), { recursive: true });
112
+ writeFileSync(p, JSON.stringify(db, null, 2), 'utf-8');
113
+ }
114
+ export async function add(args) {
115
+ if (args.includes('-h') || args.includes('--help')) {
116
+ process.stdout.write(HELP);
117
+ return 0;
118
+ }
119
+ const dryRun = args.includes('--dry-run');
120
+ const yes = args.includes('--yes');
121
+ const force = args.includes('--force');
122
+ const pathIdx = args.indexOf('--path');
123
+ const subpath = pathIdx >= 0 ? args[pathIdx + 1] : undefined;
124
+ const spec = args.find((a, i) => !a.startsWith('-') && args[i - 1] !== '--path');
125
+ if (!spec) {
126
+ process.stderr.write('forge add: falta la fuente. Ver `forge add --help`.\n');
127
+ return 1;
128
+ }
129
+ // Resolve + fetch (the only network step, only for github sources).
130
+ let source, fetched;
131
+ try {
132
+ source = resolveSource(spec, { path: subpath });
133
+ fetched = await fetchSkill(source);
134
+ }
135
+ catch (e) {
136
+ process.stderr.write(`forge add: no se pudo obtener el skill — ${e.message}\n`);
137
+ return 1;
138
+ }
139
+ const a = assessSkill(fetched.content);
140
+ printReport(a, fetched.label, fetched.sha);
141
+ // Policy gate.
142
+ if (!a.formatOk) {
143
+ process.stderr.write('BLOQUEADO: el contenido no es un SKILL.md valido. No se instalo nada.\n');
144
+ return 1;
145
+ }
146
+ if (a.decision === 'block' && !force) {
147
+ process.stderr.write(`BLOQUEADO: ${a.counts.high} hallazgo(s) de severidad alta. Revisa la fuente.\n` +
148
+ `Si confias en ella, podes forzar con --force (destructivo). No se instalo nada.\n`);
149
+ return 1;
150
+ }
151
+ if (a.decision !== 'allow' && !yes && !force) {
152
+ process.stdout.write('Requiere confirmacion: volve a correr con --yes para instalar (o --force si hay severidad alta).\n' +
153
+ 'No se instalo nada.\n');
154
+ return dryRun ? 0 : 1;
155
+ }
156
+ if (a.decision === 'block' && force) {
157
+ process.stdout.write('⚠ --force: instalando pese a hallazgos de severidad alta. Bajo tu responsabilidad.\n');
158
+ }
159
+ if (dryRun) {
160
+ process.stdout.write('--dry-run: analisis completo, no se escribio nada.\n');
161
+ return 0;
162
+ }
163
+ // Install: provenance header + demoted risky lines, into .claude/skills/<name>/.
164
+ const projectRoot = findProjectRoot(process.cwd());
165
+ const installed = buildInstalled(a, a.hygiene.clean, fetched.label, fetched.sha);
166
+ const rel = join('.claude', 'skills', a.name, 'SKILL.md');
167
+ const dest = join(projectRoot, rel);
168
+ mkdirSync(dirname(dest), { recursive: true });
169
+ writeFileSync(dest, installed, 'utf-8');
170
+ recordExternal(projectRoot, {
171
+ name: a.name,
172
+ source: source.kind === 'github' ? `${source.owner}/${source.repo}` : 'local',
173
+ ref: source.ref ?? (source.kind === 'local' ? 'local' : 'HEAD'),
174
+ sha: fetched.sha,
175
+ contentSha256: createHash('sha256').update(a.hygiene.clean, 'utf-8').digest('hex'),
176
+ capabilities: a.capabilities,
177
+ risk: { high: a.counts.high, medium: a.counts.medium },
178
+ path: rel,
179
+ installedAt: new Date().toISOString(),
180
+ });
181
+ process.stdout.write(`Instalado: ${rel} (registrado en .forge/externals.json).\n`);
182
+ if (!a.capabilities) {
183
+ process.stdout.write('Recordatorio: skill sin capabilities declaradas — revisalo antes de activarlo.\n');
184
+ }
185
+ return 0;
186
+ }
187
+ //# sourceMappingURL=add.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"add.js","sourceRoot":"","sources":["../../src/commands/add.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,42 @@
1
+ /** The advertised tools. MUST stay a subset of MCP_TOOLS (golden-rule allowlist). */
2
+ export declare const TOOL_DEFS: ({
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ type: string;
7
+ properties: {
8
+ command: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ file: {
13
+ type: string;
14
+ description: string;
15
+ };
16
+ content: {
17
+ type: string;
18
+ description: string;
19
+ };
20
+ query?: undefined;
21
+ };
22
+ required?: undefined;
23
+ };
24
+ } | {
25
+ name: string;
26
+ description: string;
27
+ inputSchema: {
28
+ type: string;
29
+ properties: {
30
+ query: {
31
+ type: string;
32
+ description: string;
33
+ };
34
+ command?: undefined;
35
+ file?: undefined;
36
+ content?: undefined;
37
+ };
38
+ required: string[];
39
+ };
40
+ })[];
41
+ export declare function mcp(args: string[]): Promise<number>;
42
+ //# sourceMappingURL=mcp.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.d.ts","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"AAqEA,qFAAqF;AACrF,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwBrB,CAAC;AAEF,wBAAsB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAsDzD"}
@@ -0,0 +1,141 @@
1
+ import { existsSync } from 'fs';
2
+ import { join, dirname } from 'path';
3
+ import { createRequire } from 'module';
4
+ import { fileURLToPath } from 'url';
5
+ import { VERSION } from '../version.js';
6
+ import { guardrailStatus, wikiSearch, MCP_TOOLS, } from '../lib/mcp-tools.js';
7
+ const HELP = `Usage: forge mcp [options]
8
+
9
+ Run forge's MCP server (stdio) so an MCP-aware runtime can query the project's
10
+ LIVE state. Opt-in and additive: everything forge knows is still in the static
11
+ files; MCP only adds two dynamic, read-only tools.
12
+
13
+ Tools:
14
+ guardrail_status Live verdict of the project's guardrail hooks for a command
15
+ or a file edit (would it be blocked/warned?).
16
+ wiki_search Search the project's wiki/ knowledge pages (confined corpus).
17
+
18
+ Transport: stdio only (no network, no HTTP). Register it once with your runtime:
19
+ claude mcp add -s local -t stdio forge -- forge mcp
20
+
21
+ Requires @modelcontextprotocol/sdk (lazy, NOT a forge dependency — install it in
22
+ your project: npm i @modelcontextprotocol/sdk). This keeps the cold-start of
23
+ forge's other commands untouched for everyone who does not use MCP.
24
+
25
+ Options:
26
+ -h, --help Show this help
27
+ `;
28
+ function findProjectRoot(start) {
29
+ let dir = start;
30
+ while (true) {
31
+ if (existsSync(join(dir, '.forge', 'manifest.json')) ||
32
+ existsSync(join(dir, 'project.yaml')) ||
33
+ existsSync(join(dir, '.git')))
34
+ return dir;
35
+ const parent = dirname(dir);
36
+ if (parent === dir)
37
+ return start;
38
+ dir = parent;
39
+ }
40
+ }
41
+ /**
42
+ * Lazily resolves @modelcontextprotocol/sdk, trying the consuming project's
43
+ * node_modules first, then forge's own. Returns null if not resolvable (the
44
+ * caller prints an actionable message). Typed `any` on purpose: the SDK is not a
45
+ * forge dependency, so tsc must not try to resolve it at build time.
46
+ */
47
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
48
+ function loadSdk() {
49
+ const makers = [
50
+ () => createRequire(join(process.cwd(), 'index.js')),
51
+ () => createRequire(fileURLToPath(import.meta.url)),
52
+ ];
53
+ for (const make of makers) {
54
+ try {
55
+ const req = make();
56
+ return {
57
+ Server: req('@modelcontextprotocol/sdk/server/index.js').Server,
58
+ StdioServerTransport: req('@modelcontextprotocol/sdk/server/stdio.js').StdioServerTransport,
59
+ types: req('@modelcontextprotocol/sdk/types.js'),
60
+ };
61
+ }
62
+ catch { /* try the next resolver */ }
63
+ }
64
+ return null;
65
+ }
66
+ /** The advertised tools. MUST stay a subset of MCP_TOOLS (golden-rule allowlist). */
67
+ export const TOOL_DEFS = [
68
+ {
69
+ name: 'guardrail_status',
70
+ description: "Live verdict of the project's guardrail hooks. Pass `command` (shell) or " +
71
+ '`file` (+ optional `content`). Read-only: it never runs the command.',
72
+ inputSchema: {
73
+ type: 'object',
74
+ properties: {
75
+ command: { type: 'string', description: 'A shell command to evaluate.' },
76
+ file: { type: 'string', description: 'A file path to evaluate for editing.' },
77
+ content: { type: 'string', description: 'Optional new content for the file edit.' },
78
+ },
79
+ },
80
+ },
81
+ {
82
+ name: 'wiki_search',
83
+ description: "Search the project's wiki/ knowledge pages (lexical, confined to wiki/).",
84
+ inputSchema: {
85
+ type: 'object',
86
+ properties: { query: { type: 'string', description: 'Text to search for.' } },
87
+ required: ['query'],
88
+ },
89
+ },
90
+ ];
91
+ export async function mcp(args) {
92
+ if (args.includes('-h') || args.includes('--help')) {
93
+ process.stdout.write(HELP);
94
+ return 0;
95
+ }
96
+ const sdk = loadSdk();
97
+ if (!sdk) {
98
+ process.stderr.write('forge mcp: falta @modelcontextprotocol/sdk.\n' +
99
+ ' Es una dependencia opt-in (no se instala con forge para no pesar en el cold-start).\n' +
100
+ ' Instalala en tu proyecto: npm i @modelcontextprotocol/sdk\n');
101
+ return 1;
102
+ }
103
+ const projectRoot = findProjectRoot(process.cwd());
104
+ const { Server, StdioServerTransport, types } = sdk;
105
+ const server = new Server({ name: 'forge', version: VERSION }, { capabilities: { tools: {} } });
106
+ server.setRequestHandler(types.ListToolsRequestSchema, async () => ({ tools: TOOL_DEFS }));
107
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
108
+ server.setRequestHandler(types.CallToolRequestSchema, async (req) => {
109
+ const name = req.params?.name;
110
+ const a = (req.params?.arguments ?? {});
111
+ // Hard allowlist: only the two declared tools are callable.
112
+ if (!MCP_TOOLS.includes(name)) {
113
+ return { isError: true, content: [{ type: 'text', text: `tool desconocida: ${name}` }] };
114
+ }
115
+ if (name === 'guardrail_status') {
116
+ const input = {
117
+ command: typeof a.command === 'string' ? a.command : undefined,
118
+ file: typeof a.file === 'string' ? a.file : undefined,
119
+ content: typeof a.content === 'string' ? a.content : undefined,
120
+ };
121
+ const r = guardrailStatus(input, projectRoot);
122
+ return { content: [{ type: 'text', text: JSON.stringify(r, null, 2) }] };
123
+ }
124
+ // wiki_search
125
+ const hits = wikiSearch(typeof a.query === 'string' ? a.query : '', projectRoot);
126
+ const text = hits.length
127
+ ? hits.map(h => `${h.page}:${h.line} ${h.snippet}`).join('\n')
128
+ : 'sin coincidencias en wiki/';
129
+ return { content: [{ type: 'text', text }] };
130
+ });
131
+ const transport = new StdioServerTransport();
132
+ await server.connect(transport);
133
+ process.stderr.write('forge mcp: servidor MCP (stdio) activo. Ctrl-C para salir.\n');
134
+ // Keep the process alive until the client disconnects or we are interrupted.
135
+ return await new Promise((resolve) => {
136
+ transport.onclose = () => resolve(0);
137
+ process.on('SIGINT', () => resolve(0));
138
+ process.on('SIGTERM', () => resolve(0));
139
+ });
140
+ }
141
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../../src/commands/mcp.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/lib/catalog.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAAE;AAC/G,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AAE3G,eAAO,MAAM,MAAM,EAAE,SAAS,EAe7B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,WAAW,EAKjC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAO/D;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAAE,CAiB3G"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/lib/catalog.ts"],"names":[],"mappings":"AAQA,MAAM,WAAW,SAAS;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;CAAE;AAC/G,MAAM,WAAW,WAAW;IAAG,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;CAAE;AAE3G,eAAO,MAAM,MAAM,EAAE,SAAS,EAoB7B,CAAC;AAEF,eAAO,MAAM,QAAQ,EAAE,WAAW,EAKjC,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAO/D;AAED,2EAA2E;AAC3E,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,EAAE,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;CAAE,CAiB3G"}
@@ -20,6 +20,11 @@ export const SKILLS = [
20
20
  { id: 'wiki-lint', command: '/wiki-lint', category: 'Wiki', purpose: 'Verifica integridad del wiki (links, huérfanos)', trigger: '"verificar wiki"' },
21
21
  { id: 'aitmpl-search', command: '/aitmpl-search', category: 'Catálogo', purpose: 'Busca en el catálogo de frameworks/MCP/profiles', trigger: '"buscar templates", "buscar MCP"' },
22
22
  { id: 'obsidian-sync', command: '/obsidian-sync', category: 'Integración', purpose: 'Sincroniza un vault de Obsidian con el código', trigger: '"actualizar obsidian", "sync vault"' },
23
+ { id: 'laravel-eloquent', command: '/laravel-eloquent', category: 'Laravel', purpose: 'Eloquent: relaciones, eager loading, evitar N+1, casts, pgvector', trigger: '"modelo eloquent", "evitar N+1", "query lenta"' },
24
+ { id: 'laravel-pest', command: '/laravel-pest', category: 'Laravel', purpose: 'TDD con Pest 3: factories, fakes, HTTP tests, coverage', trigger: '"test laravel", "pest", "factory"' },
25
+ { id: 'laravel-security', command: '/laravel-security', category: 'Laravel', purpose: 'Auth, policies, Form Requests, CSRF, rate limiting, deploy seguro', trigger: '"seguridad laravel", "auth laravel", "policy"' },
26
+ { id: 'laravel-verify', command: '/laravel-verify', category: 'Laravel', purpose: 'Loop Pint + Larastan + Pest (coverage) + composer audit', trigger: '"verificar laravel", "pint phpstan pest"' },
27
+ { id: 'laravel-mcp', command: '/laravel-mcp', category: 'Laravel', purpose: 'Laravel 13 agents/MCP: Boost, laravel/mcp, AI SDK, embeddings/RAG', trigger: '"laravel mcp", "laravel boost", "laravel ai sdk"' },
23
28
  ];
24
29
  export const RUNTIMES = [
25
30
  { id: 'claude-code', label: 'Claude Code', cmd: ['claude', '--version'], install: 'npm i -g @anthropic-ai/claude-code', marker: 'CLAUDE.md + .claude/' },
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/lib/catalog.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/lib/catalog.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ /** The exact, allowlisted set of tools. Adding to this is a deliberate review. */
2
+ export declare const MCP_TOOLS: readonly ["guardrail_status", "wiki_search"];
3
+ export interface GuardrailInput {
4
+ /** A shell command to evaluate against pre-bash-check. */
5
+ command?: string;
6
+ /** A file path to evaluate against pre-edit-check (with optional new content). */
7
+ file?: string;
8
+ content?: string;
9
+ }
10
+ export interface GuardrailResult {
11
+ verdict: 'allow' | 'warn' | 'block';
12
+ blocked: boolean;
13
+ message: string;
14
+ }
15
+ /**
16
+ * Returns the LIVE guardrail verdict by running the project's OWN installed hook
17
+ * (.claude/hooks/*) with the given payload and interpreting its exit code. This
18
+ * reuses the exact same logic the runtime enforces — no duplication, no drift.
19
+ * Read-only: it never executes the command, only asks the hook for a verdict.
20
+ */
21
+ export declare function guardrailStatus(input: GuardrailInput, projectRoot: string): GuardrailResult;
22
+ export interface WikiHit {
23
+ /** Page path relative to wiki/ (e.g. "concepts/auth.md"). */
24
+ page: string;
25
+ line: number;
26
+ snippet: string;
27
+ }
28
+ /**
29
+ * Lexical, case-insensitive search over the project's `wiki/` knowledge pages.
30
+ * CONFINED by construction: it only ever reads files under `<projectRoot>/wiki/`
31
+ * and takes a query STRING (never a path), so there is no path-traversal surface.
32
+ * Mirrors `forge wiki query` (the static floor); this is the additive interface.
33
+ */
34
+ export declare function wikiSearch(query: string, projectRoot: string, opts?: {
35
+ limit?: number;
36
+ }): WikiHit[];
37
+ //# sourceMappingURL=mcp-tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-tools.d.ts","sourceRoot":"","sources":["../../src/lib/mcp-tools.ts"],"names":[],"mappings":"AAiBA,kFAAkF;AAClF,eAAO,MAAM,SAAS,8CAA+C,CAAC;AAItE,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kFAAkF;IAClF,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,GAAG,eAAe,CAiC3F;AAID,MAAM,WAAW,OAAO;IACtB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAuBD;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,OAAO,EAAE,CAwBvG"}