@cristiancorreau/forge 2.1.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/CHANGELOG.md +228 -0
- package/LICENSE +191 -0
- package/README.md +156 -0
- package/assets/adapters/claude-code/commands/deploy-check.md +12 -0
- package/assets/adapters/claude-code/commands/new-feature.md +11 -0
- package/assets/adapters/claude-code/commands/plan.md +116 -0
- package/assets/adapters/claude-code/commands/review.md +219 -0
- package/assets/adapters/claude-code/commands/session-close.md +109 -0
- package/assets/adapters/claude-code/commands/session-start.md +59 -0
- package/assets/adapters/claude-code/commands/ship.md +133 -0
- package/assets/adapters/claude-code/commands/wiki-ingest.md +7 -0
- package/assets/adapters/claude-code/commands/wiki-lint.md +5 -0
- package/assets/adapters/claude-code/commands/wiki-query.md +7 -0
- package/assets/adapters/claude-code/commands/work.md +101 -0
- package/assets/adapters/claude-code/generate-claude-md.py +304 -0
- package/assets/adapters/codex/commands/plan.md +63 -0
- package/assets/adapters/codex/commands/review.md +53 -0
- package/assets/adapters/codex/commands/session-close.md +53 -0
- package/assets/adapters/codex/commands/session-start.md +49 -0
- package/assets/adapters/codex/commands/ship.md +53 -0
- package/assets/adapters/codex/commands/work.md +53 -0
- package/assets/adapters/codex/generate-codex-config.py +269 -0
- package/assets/adapters/codex/hooks/codex.yaml.tpl +43 -0
- package/assets/adapters/codex/hooks/forge-codex-finish.sh +158 -0
- package/assets/adapters/codex/hooks/forge-codex-start.sh +186 -0
- package/assets/adapters/kiro/generate-steering.py +367 -0
- package/assets/adapters/opencode/HOOKS.md +123 -0
- package/assets/adapters/opencode/commands/plan.md +119 -0
- package/assets/adapters/opencode/commands/review.md +164 -0
- package/assets/adapters/opencode/commands/session-close.md +111 -0
- package/assets/adapters/opencode/commands/session-start.md +62 -0
- package/assets/adapters/opencode/commands/ship.md +135 -0
- package/assets/adapters/opencode/commands/work.md +82 -0
- package/assets/adapters/opencode/generate-agents-md.py +262 -0
- package/assets/core/agents/backend-engineer.md +61 -0
- package/assets/core/agents/compliance-reviewer.md +83 -0
- package/assets/core/agents/docs-writer.md +77 -0
- package/assets/core/agents/frontend-engineer.md +70 -0
- package/assets/core/agents/orchestrator.md +104 -0
- package/assets/core/agents/security-auditor.md +54 -0
- package/assets/core/agents/test-engineer.md +57 -0
- package/assets/core/hooks/hooks-registry.yaml +48 -0
- package/assets/core/hooks/post-turn-check.sh +139 -0
- package/assets/core/hooks/pre-bash-check.py +202 -0
- package/assets/core/hooks/pre-edit-check.py +317 -0
- package/assets/core/hooks/session-start.sh +184 -0
- package/assets/core/schemas/project.schema.json +503 -0
- package/assets/core/skills/README.md +88 -0
- package/assets/core/skills/aitmpl-search/SKILL.md +74 -0
- package/assets/core/skills/browser-test/SKILL.md +177 -0
- package/assets/core/skills/db-migrate/SKILL.md +163 -0
- package/assets/core/skills/local2prod/SKILL.md +147 -0
- package/assets/core/skills/new-feature/SKILL.md +155 -0
- package/assets/core/skills/obsidian-sync/SKILL.md +152 -0
- package/assets/core/skills/phase-kickoff/SKILL.md +69 -0
- package/assets/core/skills/security-audit/SKILL.md +125 -0
- package/assets/core/skills/spec/SKILL.md +72 -0
- package/assets/core/skills/wiki-ingest/SKILL.md +183 -0
- package/assets/core/skills/wiki-lint/SKILL.md +109 -0
- package/assets/core/skills/wiki-query/SKILL.md +100 -0
- package/assets/core/templates/claude-md/architecture.rules +20 -0
- package/assets/core/templates/claude-md/global.md +30 -0
- package/assets/core/templates/claude-md/project.md +36 -0
- package/assets/core/templates/daily-note.md +38 -0
- package/assets/core/templates/spec-template.md +43 -0
- package/assets/core/workflows/sdd.md +69 -0
- package/assets/core/workflows/sprint.md +59 -0
- package/assets/forge.py +1265 -0
- package/assets/hooks/pre-commit +43 -0
- package/assets/manifest.json +274 -0
- package/assets/profiles/astro/README.md +24 -0
- package/assets/profiles/astro/agents/frontend-engineer.md +74 -0
- package/assets/profiles/django/agents/api-engineer.md +83 -0
- package/assets/profiles/expo/README.md +24 -0
- package/assets/profiles/expo/agents/mobile-engineer.md +69 -0
- package/assets/profiles/express/agents/api-engineer.md +60 -0
- package/assets/profiles/fastapi/README.md +32 -0
- package/assets/profiles/fastapi/agents/api-engineer.md +87 -0
- package/assets/profiles/go-gin/agents/api-engineer.md +98 -0
- package/assets/profiles/hono-drizzle/README.md +31 -0
- package/assets/profiles/hono-drizzle/agents/api-engineer.md +82 -0
- package/assets/profiles/laravel/README.md +32 -0
- package/assets/profiles/laravel/agents/api-engineer.md +114 -0
- package/assets/profiles/laravel/agents/fullstack-engineer.md +67 -0
- package/assets/profiles/laravel/agents/migration-specialist.md +420 -0
- package/assets/profiles/nestjs/agents/api-engineer.md +79 -0
- package/assets/profiles/nextjs-admin/README.md +32 -0
- package/assets/profiles/nextjs-admin/agents/admin-engineer.md +78 -0
- package/assets/profiles/playwright-crawler/agents/scanner-engineer.md +51 -0
- package/assets/profiles/rails/agents/fullstack-engineer.md +61 -0
- package/assets/profiles/sveltekit/agents/frontend-engineer.md +96 -0
- package/assets/profiles/vuenuxt/agents/frontend-engineer.md +82 -0
- package/assets/profiles/wordpress/README.md +30 -0
- package/assets/profiles/wordpress/agents/divi-engineer.md +273 -0
- package/assets/profiles/wordpress/agents/elementor-engineer.md +310 -0
- package/assets/profiles/wordpress/agents/wp-engineer.md +216 -0
- package/assets/requirements.txt +2 -0
- package/assets/scripts/aitmpl-search.py +808 -0
- package/assets/scripts/forge-add-opportunities.py +92 -0
- package/assets/scripts/forge-audit.py +1061 -0
- package/assets/scripts/forge-generate-all.py +283 -0
- package/assets/scripts/forge-init.py +900 -0
- package/assets/scripts/forge-migrate-project-yaml.py +397 -0
- package/assets/scripts/forge-scaffold-profile.py +181 -0
- package/assets/scripts/forge-teardown.py +193 -0
- package/assets/scripts/forge-validate-project-yaml.py +457 -0
- package/assets/scripts/forge-wizard.py +1003 -0
- package/assets/scripts/setup-codex.sh +229 -0
- package/assets/scripts/team-install.sh +147 -0
- package/assets/scripts/token-stats.py +201 -0
- package/assets/templates/modes/enterprise.yaml.tpl +114 -0
- package/assets/templates/modes/multi-runtime.yaml.tpl +89 -0
- package/assets/templates/modes/new-stack.yaml.tpl +101 -0
- package/assets/templates/modes/startup.yaml.tpl +74 -0
- package/assets/templates/project.yaml.tpl +185 -0
- package/assets/templates/wiki/concepts/_template.md +22 -0
- package/assets/templates/wiki/entities/_template.md +19 -0
- package/assets/templates/wiki/index.md +32 -0
- package/assets/templates/wiki/log.md +6 -0
- package/assets/templates/wiki/sources/_template.md +25 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +64 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/audit.d.ts +2 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +21 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/doctor.d.ts +2 -0
- package/dist/commands/doctor.d.ts.map +1 -0
- package/dist/commands/doctor.js +58 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/generate.d.ts +2 -0
- package/dist/commands/generate.d.ts.map +1 -0
- package/dist/commands/generate.js +27 -0
- package/dist/commands/generate.js.map +1 -0
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +22 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/validate.d.ts +2 -0
- package/dist/commands/validate.d.ts.map +1 -0
- package/dist/commands/validate.js +20 -0
- package/dist/commands/validate.js.map +1 -0
- package/dist/lib/paths.d.ts +10 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +49 -0
- package/dist/lib/paths.js.map +1 -0
- package/dist/lib/python.d.ts +4 -0
- package/dist/lib/python.d.ts.map +1 -0
- package/dist/lib/python.js +46 -0
- package/dist/lib/python.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { findPython, hasPyyaml } from '../lib/python.js';
|
|
2
|
+
import { resolveForgeRoot } from '../lib/paths.js';
|
|
3
|
+
export async function doctor(_args) {
|
|
4
|
+
let ok = true;
|
|
5
|
+
console.log('forge doctor — environment check\n');
|
|
6
|
+
// Python
|
|
7
|
+
const python = findPython();
|
|
8
|
+
if (python) {
|
|
9
|
+
console.log(` ✓ Python: ${python}`);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
console.log(' ✗ Python 3.9+ not found');
|
|
13
|
+
console.log(' macOS: brew install python3');
|
|
14
|
+
console.log(' Ubuntu: sudo apt install python3');
|
|
15
|
+
console.log(' Win: https://python.org/downloads');
|
|
16
|
+
ok = false;
|
|
17
|
+
}
|
|
18
|
+
// pyyaml
|
|
19
|
+
if (python) {
|
|
20
|
+
if (hasPyyaml(python)) {
|
|
21
|
+
console.log(' ✓ pyyaml: installed');
|
|
22
|
+
}
|
|
23
|
+
else {
|
|
24
|
+
console.log(' ✗ pyyaml not found');
|
|
25
|
+
console.log(` ${python} -m pip install pyyaml`);
|
|
26
|
+
ok = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// forge root
|
|
30
|
+
try {
|
|
31
|
+
const root = resolveForgeRoot();
|
|
32
|
+
console.log(` ✓ forge root: ${root}`);
|
|
33
|
+
}
|
|
34
|
+
catch (e) {
|
|
35
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
36
|
+
console.log(` ✗ forge root: ${msg}`);
|
|
37
|
+
ok = false;
|
|
38
|
+
}
|
|
39
|
+
// project.yaml
|
|
40
|
+
const { existsSync } = await import('fs');
|
|
41
|
+
const { join } = await import('path');
|
|
42
|
+
const projectYaml = join(process.cwd(), 'project.yaml');
|
|
43
|
+
if (existsSync(projectYaml)) {
|
|
44
|
+
console.log(' ✓ project.yaml: found');
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
console.log(' ~ project.yaml: not found (run forge init)');
|
|
48
|
+
}
|
|
49
|
+
console.log('');
|
|
50
|
+
if (ok) {
|
|
51
|
+
console.log('All checks passed.');
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
console.log('Some checks failed. Fix the issues above and run forge doctor again.');
|
|
55
|
+
}
|
|
56
|
+
return ok ? 0 : 1;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=doctor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAe;IAC1C,IAAI,EAAE,GAAG,IAAI,CAAC;IAEd,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAElD,SAAS;IACT,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,EAAE,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,kCAAkC,CAAC,CAAC;QAChD,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;QACpD,OAAO,CAAC,GAAG,CAAC,0CAA0C,CAAC,CAAC;QACxD,EAAE,GAAG,KAAK,CAAC;IACb,CAAC;IAED,SAAS;IACT,IAAI,MAAM,EAAE,CAAC;QACX,IAAI,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACvC,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;YACpC,OAAO,CAAC,GAAG,CAAC,OAAO,MAAM,wBAAwB,CAAC,CAAC;YACnD,EAAE,GAAG,KAAK,CAAC;QACb,CAAC;IACH,CAAC;IAED,aAAa;IACb,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAAC,OAAO,CAAU,EAAE,CAAC;QACpB,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;QACvD,OAAO,CAAC,GAAG,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QACtC,EAAE,GAAG,KAAK,CAAC;IACb,CAAC;IAED,eAAe;IACf,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1C,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IACxD,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;IACzC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,8CAA8C,CAAC,CAAC;IAC9D,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAChB,IAAI,EAAE,EAAE,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IACpC,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;IACtF,CAAC;IAED,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAoBA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAO9D"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { resolveScript } from '../lib/paths.js';
|
|
2
|
+
import { runPython } from '../lib/python.js';
|
|
3
|
+
const HELP = `Usage: forge generate [options]
|
|
4
|
+
|
|
5
|
+
Generate runtime configuration files from project.yaml.
|
|
6
|
+
Auto-detects active runtimes by filesystem markers.
|
|
7
|
+
|
|
8
|
+
Options:
|
|
9
|
+
--runtime <name> Generate for specific runtime: claude-code, opencode, codex, kiro, all
|
|
10
|
+
--dry-run Show what would be generated without writing files
|
|
11
|
+
--force Overwrite existing files without prompting
|
|
12
|
+
-h, --help Show this help
|
|
13
|
+
|
|
14
|
+
Examples:
|
|
15
|
+
forge generate # auto-detect runtimes
|
|
16
|
+
forge generate --runtime claude-code
|
|
17
|
+
forge generate --runtime all --dry-run
|
|
18
|
+
`;
|
|
19
|
+
export async function generate(args) {
|
|
20
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
21
|
+
process.stdout.write(HELP);
|
|
22
|
+
return 0;
|
|
23
|
+
}
|
|
24
|
+
const script = resolveScript('forge-generate-all.py');
|
|
25
|
+
return runPython(script, args);
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=generate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/commands/generate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,IAAI,GAAG;;;;;;;;;;;;;;;CAeZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAc;IAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,uBAAuB,CAAC,CAAC;IACtD,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAeA,wBAAsB,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAO1D"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { resolveScript } from '../lib/paths.js';
|
|
2
|
+
import { runPython } from '../lib/python.js';
|
|
3
|
+
const HELP = `Usage: forge init [options]
|
|
4
|
+
|
|
5
|
+
Initialize forge in a project. Creates project.yaml via interactive wizard
|
|
6
|
+
and generates agent files for the selected runtime.
|
|
7
|
+
|
|
8
|
+
Options:
|
|
9
|
+
--runtime <name> Target runtime: claude-code, opencode, codex, kiro
|
|
10
|
+
--dry-run Show what would be created without writing files
|
|
11
|
+
--force Skip confirmation prompts
|
|
12
|
+
-h, --help Show this help
|
|
13
|
+
`;
|
|
14
|
+
export async function init(args) {
|
|
15
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
16
|
+
process.stdout.write(HELP);
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
const script = resolveScript('forge-init.py');
|
|
20
|
+
return runPython(script, args);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,IAAI,GAAG;;;;;;;;;;CAUZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,IAAI,CAAC,IAAc;IACvC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,eAAe,CAAC,CAAC;IAC9C,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAaA,wBAAsB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAO9D"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { resolveScript } from '../lib/paths.js';
|
|
2
|
+
import { runPython } from '../lib/python.js';
|
|
3
|
+
const HELP = `Usage: forge validate [options]
|
|
4
|
+
|
|
5
|
+
Validate project.yaml in the current directory against the forge v2 schema.
|
|
6
|
+
Exits with code 1 if validation fails (suitable for CI pre-checks).
|
|
7
|
+
|
|
8
|
+
Options:
|
|
9
|
+
--json Output errors as JSON
|
|
10
|
+
-h, --help Show this help
|
|
11
|
+
`;
|
|
12
|
+
export async function validate(args) {
|
|
13
|
+
if (args.includes('-h') || args.includes('--help')) {
|
|
14
|
+
process.stdout.write(HELP);
|
|
15
|
+
return 0;
|
|
16
|
+
}
|
|
17
|
+
const script = resolveScript('forge-validate-project-yaml.py');
|
|
18
|
+
return runPython(script, args);
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/commands/validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,IAAI,GAAG;;;;;;;;CAQZ,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,IAAc;IAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3B,OAAO,CAAC,CAAC;IACX,CAAC;IACD,MAAM,MAAM,GAAG,aAAa,CAAC,gCAAgC,CAAC,CAAC;IAC/D,OAAO,SAAS,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves the forge root directory in priority order:
|
|
3
|
+
* 1. FORGE_HOME env var
|
|
4
|
+
* 2. assets/ next to the compiled CLI (npm package mode)
|
|
5
|
+
* 3. Walk up from __dirname looking for forge.py (dev mode / legacy .agentic/)
|
|
6
|
+
* 4. .agentic/ or forge/ in cwd (consumer project with submodule)
|
|
7
|
+
*/
|
|
8
|
+
export declare function resolveForgeRoot(): string;
|
|
9
|
+
export declare function resolveScript(name: string): string;
|
|
10
|
+
//# sourceMappingURL=paths.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.d.ts","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAMA;;;;;;GAMG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,CA6BzC;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAOlD"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { existsSync } from 'fs';
|
|
2
|
+
import { join, dirname } from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
5
|
+
/**
|
|
6
|
+
* Resolves the forge root directory in priority order:
|
|
7
|
+
* 1. FORGE_HOME env var
|
|
8
|
+
* 2. assets/ next to the compiled CLI (npm package mode)
|
|
9
|
+
* 3. Walk up from __dirname looking for forge.py (dev mode / legacy .agentic/)
|
|
10
|
+
* 4. .agentic/ or forge/ in cwd (consumer project with submodule)
|
|
11
|
+
*/
|
|
12
|
+
export function resolveForgeRoot() {
|
|
13
|
+
if (process.env.FORGE_HOME) {
|
|
14
|
+
const p = process.env.FORGE_HOME;
|
|
15
|
+
if (existsSync(join(p, 'forge.py')))
|
|
16
|
+
return p;
|
|
17
|
+
throw new Error(`FORGE_HOME="${p}" does not contain forge.py`);
|
|
18
|
+
}
|
|
19
|
+
// npm package mode: __dirname is dist/lib/, assets/ is at package root (two levels up)
|
|
20
|
+
const assetsPath = join(__dirname, '..', '..', 'assets');
|
|
21
|
+
if (existsSync(join(assetsPath, 'forge.py')))
|
|
22
|
+
return assetsPath;
|
|
23
|
+
// dev mode: walk up from __dirname to find forge.py
|
|
24
|
+
let dir = __dirname;
|
|
25
|
+
for (let i = 0; i < 8; i++) {
|
|
26
|
+
if (existsSync(join(dir, 'forge.py')))
|
|
27
|
+
return dir;
|
|
28
|
+
const parent = dirname(dir);
|
|
29
|
+
if (parent === dir)
|
|
30
|
+
break;
|
|
31
|
+
dir = parent;
|
|
32
|
+
}
|
|
33
|
+
// consumer project: look for .agentic/ or forge/ from cwd
|
|
34
|
+
for (const candidate of ['.agentic', 'forge']) {
|
|
35
|
+
const p = join(process.cwd(), candidate);
|
|
36
|
+
if (existsSync(join(p, 'forge.py')))
|
|
37
|
+
return p;
|
|
38
|
+
}
|
|
39
|
+
throw new Error('forge root not found. Set FORGE_HOME or install via: npx @cristiancorreau/forge');
|
|
40
|
+
}
|
|
41
|
+
export function resolveScript(name) {
|
|
42
|
+
const root = resolveForgeRoot();
|
|
43
|
+
const scriptPath = join(root, 'scripts', name);
|
|
44
|
+
if (!existsSync(scriptPath)) {
|
|
45
|
+
throw new Error(`Script not found: ${scriptPath}`);
|
|
46
|
+
}
|
|
47
|
+
return scriptPath;
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=paths.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"paths.js","sourceRoot":"","sources":["../../src/lib/paths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC;QACjC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,eAAe,CAAC,6BAA6B,CAAC,CAAC;IACjE,CAAC;IAED,uFAAuF;IACvF,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;IACzD,IAAI,UAAU,CAAC,IAAI,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QAAE,OAAO,UAAU,CAAC;IAEhE,oDAAoD;IACpD,IAAI,GAAG,GAAG,SAAS,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YAAE,OAAO,GAAG,CAAC;QAClD,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5B,IAAI,MAAM,KAAK,GAAG;YAAE,MAAM;QAC1B,GAAG,GAAG,MAAM,CAAC;IACf,CAAC;IAED,0DAA0D;IAC1D,KAAK,MAAM,SAAS,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,EAAE,CAAC;QAC9C,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,CAAC;QACzC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAED,MAAM,IAAI,KAAK,CACb,iFAAiF,CAClF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,IAAY;IACxC,MAAM,IAAI,GAAG,gBAAgB,EAAE,CAAC;IAChC,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,CAAC;IAC/C,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,EAAE,CAAC,CAAC;IACrD,CAAC;IACD,OAAO,UAAU,CAAC;AACpB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.d.ts","sourceRoot":"","sources":["../../src/lib/python.ts"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,IAAI,MAAM,GAAG,IAAI,CAgB1C;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjD;AAED,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CA2BhE"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { spawnSync } from 'child_process';
|
|
2
|
+
const PYTHON_CANDIDATES = ['python3', 'python'];
|
|
3
|
+
export function findPython() {
|
|
4
|
+
for (const bin of PYTHON_CANDIDATES) {
|
|
5
|
+
try {
|
|
6
|
+
const result = spawnSync(bin, ['--version'], { encoding: 'utf8' });
|
|
7
|
+
if (result.status === 0) {
|
|
8
|
+
const version = result.stdout || result.stderr || '';
|
|
9
|
+
const match = version.match(/Python (\d+)\.(\d+)/);
|
|
10
|
+
if (match && (parseInt(match[1]) > 3 || (parseInt(match[1]) === 3 && parseInt(match[2]) >= 9))) {
|
|
11
|
+
return bin;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
// not found, try next
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
export function hasPyyaml(python) {
|
|
22
|
+
const result = spawnSync(python, ['-c', 'import yaml'], { encoding: 'utf8' });
|
|
23
|
+
return result.status === 0;
|
|
24
|
+
}
|
|
25
|
+
export function runPython(script, args) {
|
|
26
|
+
const python = findPython();
|
|
27
|
+
if (!python) {
|
|
28
|
+
console.error('Error: Python 3.9+ is required but was not found.\n\n' +
|
|
29
|
+
'Install Python:\n' +
|
|
30
|
+
' macOS: brew install python3\n' +
|
|
31
|
+
' Ubuntu: sudo apt install python3\n' +
|
|
32
|
+
' Win: https://python.org/downloads\n');
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
if (!hasPyyaml(python)) {
|
|
36
|
+
console.error('Error: pyyaml is required but not installed.\n\n' +
|
|
37
|
+
` ${python} -m pip install pyyaml\n`);
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
const result = spawnSync(python, [script, ...args], {
|
|
41
|
+
stdio: 'inherit',
|
|
42
|
+
env: { ...process.env },
|
|
43
|
+
});
|
|
44
|
+
return result.status ?? 1;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=python.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"python.js","sourceRoot":"","sources":["../../src/lib/python.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAY,MAAM,eAAe,CAAC;AAEpD,MAAM,iBAAiB,GAAG,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;AAEhD,MAAM,UAAU,UAAU;IACxB,KAAK,MAAM,GAAG,IAAI,iBAAiB,EAAE,CAAC;QACpC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;YACnE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACxB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;gBACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;gBACnD,IAAI,KAAK,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC/F,OAAO,GAAG,CAAC;gBACb,CAAC;YACH,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,sBAAsB;QACxB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc;IACtC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9E,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAAc,EAAE,IAAc;IACtD,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAC5B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CACX,uDAAuD;YACvD,mBAAmB;YACnB,kCAAkC;YAClC,sCAAsC;YACtC,0CAA0C,CAC3C,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CACX,kDAAkD;YAClD,KAAK,MAAM,0BAA0B,CACtC,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE;QAClD,KAAK,EAAE,SAAS;QAChB,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE;KACxB,CAAC,CAAC;IAEH,OAAO,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;AAC5B,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cristiancorreau/forge",
|
|
3
|
+
"version": "2.1.0",
|
|
4
|
+
"description": "Agentic development framework — multi-runtime support for Claude Code, OpenCode, Codex and Kiro",
|
|
5
|
+
"author": "Cristian Correa <cristian@socialweb.cl>",
|
|
6
|
+
"license": "Apache-2.0",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/cristiancorreau/forge"
|
|
10
|
+
},
|
|
11
|
+
"keywords": [
|
|
12
|
+
"ai",
|
|
13
|
+
"agents",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"opencode",
|
|
16
|
+
"codex",
|
|
17
|
+
"kiro",
|
|
18
|
+
"agentic",
|
|
19
|
+
"framework"
|
|
20
|
+
],
|
|
21
|
+
"type": "module",
|
|
22
|
+
"bin": {
|
|
23
|
+
"forge": "dist/cli.js"
|
|
24
|
+
},
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "tsc",
|
|
27
|
+
"build:assets": "node scripts/build-assets.mjs",
|
|
28
|
+
"build:all": "npm run build:assets && npm run build",
|
|
29
|
+
"dev": "tsc --watch",
|
|
30
|
+
"prepublishOnly": "npm run build:all"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"assets",
|
|
35
|
+
"README.md",
|
|
36
|
+
"LICENSE",
|
|
37
|
+
"CHANGELOG.md"
|
|
38
|
+
],
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"@types/node": "^20.0.0",
|
|
41
|
+
"typescript": "^5.4.0"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18.0.0"
|
|
45
|
+
}
|
|
46
|
+
}
|