forgecraft 1.0.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +66 -14
- package/dist/{chunk-2HFEPXBV.js → chunk-P5CLBIGQ.js} +268 -39
- package/dist/chunk-P5CLBIGQ.js.map +1 -0
- package/dist/cli/index.js +78 -21
- package/dist/cli/index.js.map +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-2HFEPXBV.js.map +0 -1
package/dist/cli/index.js
CHANGED
|
@@ -5,11 +5,15 @@ import {
|
|
|
5
5
|
Orchestrator,
|
|
6
6
|
Pipeline,
|
|
7
7
|
Worker,
|
|
8
|
+
buildAttachmentPrompt,
|
|
9
|
+
formatAttachmentList,
|
|
8
10
|
getAdapter,
|
|
9
11
|
listAdapters,
|
|
10
12
|
loadAndValidateConfig,
|
|
13
|
+
parseAttachments,
|
|
14
|
+
stageAttachments,
|
|
11
15
|
stateManager
|
|
12
|
-
} from "../chunk-
|
|
16
|
+
} from "../chunk-P5CLBIGQ.js";
|
|
13
17
|
|
|
14
18
|
// src/cli/index.ts
|
|
15
19
|
import { Command } from "commander";
|
|
@@ -64,7 +68,7 @@ async function initCommand(options) {
|
|
|
64
68
|
{ name: "Next.js (TypeScript + Tailwind + App Router)", value: "nextjs" },
|
|
65
69
|
{ name: "React + Vite (TypeScript SPA)", value: "react" },
|
|
66
70
|
{ name: "Django (Python + DRF)", value: "django" },
|
|
67
|
-
{ name: "
|
|
71
|
+
{ name: "Other (Express, Vue, Svelte, Go, Rust, etc.)", value: "generic" }
|
|
68
72
|
],
|
|
69
73
|
default: options.framework || "nextjs"
|
|
70
74
|
},
|
|
@@ -435,11 +439,20 @@ async function fixCommand(description, options) {
|
|
|
435
439
|
`));
|
|
436
440
|
return;
|
|
437
441
|
}
|
|
442
|
+
const parsed = parseAttachments(description);
|
|
443
|
+
if (parsed.attachments.length > 0) {
|
|
444
|
+
description = parsed.description;
|
|
445
|
+
stageAttachments(parsed.attachments);
|
|
446
|
+
}
|
|
438
447
|
console.log(chalk8.bold("\n forge fix\n"));
|
|
439
448
|
console.log(chalk8.dim(` "${description}"`));
|
|
440
449
|
if (options?.image) {
|
|
441
450
|
console.log(chalk8.dim(` image: ${options.image}`));
|
|
442
451
|
}
|
|
452
|
+
if (parsed.attachments.length > 0) {
|
|
453
|
+
console.log(chalk8.dim("\n Attachments:"));
|
|
454
|
+
console.log(chalk8.cyan(formatAttachmentList(parsed.attachments)));
|
|
455
|
+
}
|
|
443
456
|
console.log("");
|
|
444
457
|
const orchestrator = new Orchestrator(config);
|
|
445
458
|
const worker = new Worker(config, {});
|
|
@@ -472,6 +485,9 @@ async function fixCommand(description, options) {
|
|
|
472
485
|
A screenshot has been saved at: ${options.image}
|
|
473
486
|
Read this image file to see the visual issue the user is referring to.`;
|
|
474
487
|
}
|
|
488
|
+
if (parsed.attachments.length > 0) {
|
|
489
|
+
fixPrompt += "\n" + buildAttachmentPrompt(parsed.attachments);
|
|
490
|
+
}
|
|
475
491
|
const result = await worker.run(mode, fixPrompt, {
|
|
476
492
|
onProgress: (event) => {
|
|
477
493
|
if (event.type === "tool_use") {
|
|
@@ -682,6 +698,7 @@ async function autoCommand(description, options) {
|
|
|
682
698
|
const adapter = getAdapter(config.framework);
|
|
683
699
|
const skipDesign = options.skipDesign || !adapter.designSupport;
|
|
684
700
|
if (!description) {
|
|
701
|
+
console.log(chalk10.dim(" Tip: drag & drop files here to attach references\n"));
|
|
685
702
|
const { desc } = await inquirer5.prompt([
|
|
686
703
|
{
|
|
687
704
|
type: "input",
|
|
@@ -692,14 +709,26 @@ async function autoCommand(description, options) {
|
|
|
692
709
|
]);
|
|
693
710
|
description = desc;
|
|
694
711
|
}
|
|
712
|
+
const parsed = parseAttachments(description);
|
|
713
|
+
let attachments = [];
|
|
714
|
+
if (parsed.attachments.length > 0) {
|
|
715
|
+
attachments = parsed.attachments;
|
|
716
|
+
description = parsed.description;
|
|
717
|
+
stageAttachments(attachments);
|
|
718
|
+
console.log(chalk10.dim("\n Attachments:"));
|
|
719
|
+
console.log(chalk10.cyan(formatAttachmentList(attachments)));
|
|
720
|
+
console.log("");
|
|
721
|
+
}
|
|
695
722
|
const allowedDomains = options.allowNetwork ? options.allowNetwork.split(",").map((d) => d.trim()) : void 0;
|
|
696
723
|
const pipeline = new AutoPipeline(config, {
|
|
697
724
|
sandbox: options.sandbox !== false,
|
|
725
|
+
yes: options.yes ?? false,
|
|
698
726
|
quiet: options.quiet ?? false,
|
|
699
727
|
mute: options.mute ?? false,
|
|
700
728
|
deploy: options.deploy ?? false,
|
|
701
729
|
skipDesign,
|
|
702
|
-
allowedDomains
|
|
730
|
+
allowedDomains,
|
|
731
|
+
attachments
|
|
703
732
|
});
|
|
704
733
|
const result = await pipeline.run(description);
|
|
705
734
|
if (!result.success) {
|
|
@@ -767,18 +796,22 @@ async function resumeCommand(options) {
|
|
|
767
796
|
}
|
|
768
797
|
console.log("");
|
|
769
798
|
}
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
799
|
+
let action = "resume";
|
|
800
|
+
if (!options.yes) {
|
|
801
|
+
const answer = await inquirer6.prompt([
|
|
802
|
+
{
|
|
803
|
+
type: "list",
|
|
804
|
+
name: "action",
|
|
805
|
+
message: "What would you like to do?",
|
|
806
|
+
choices: [
|
|
807
|
+
{ name: `Resume (${remaining.length} stories left)`, value: "resume" },
|
|
808
|
+
...blocked > 0 ? [{ name: `Retry blocked stories (${blocked})`, value: "retry" }] : [],
|
|
809
|
+
{ name: "Cancel", value: "cancel" }
|
|
810
|
+
]
|
|
811
|
+
}
|
|
812
|
+
]);
|
|
813
|
+
action = answer.action;
|
|
814
|
+
}
|
|
782
815
|
if (action === "cancel") {
|
|
783
816
|
console.log(chalk11.dim(" Cancelled.\n"));
|
|
784
817
|
return;
|
|
@@ -802,6 +835,7 @@ async function resumeCommand(options) {
|
|
|
802
835
|
await stateManager.savePlan(plan);
|
|
803
836
|
const pipeline = new AutoPipeline(config, {
|
|
804
837
|
sandbox: options.sandbox !== false,
|
|
838
|
+
yes: options.yes ?? false,
|
|
805
839
|
quiet: options.quiet ?? false,
|
|
806
840
|
mute: options.mute ?? false,
|
|
807
841
|
skipDesign: options.skipDesign ?? false
|
|
@@ -1311,11 +1345,34 @@ async function startCommand() {
|
|
|
1311
1345
|
return;
|
|
1312
1346
|
}
|
|
1313
1347
|
const adapter = getAdapter(config.framework);
|
|
1314
|
-
|
|
1348
|
+
let devCommand = adapter.devCommand;
|
|
1349
|
+
if (adapter.id === "generic") {
|
|
1350
|
+
try {
|
|
1351
|
+
const { readFileSync } = await import("fs");
|
|
1352
|
+
const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
|
|
1353
|
+
if (pkg.scripts?.dev) {
|
|
1354
|
+
devCommand = "npm run dev";
|
|
1355
|
+
} else if (pkg.scripts?.start) {
|
|
1356
|
+
devCommand = "npm start";
|
|
1357
|
+
} else if (pkg.scripts?.serve) {
|
|
1358
|
+
devCommand = "npm run serve";
|
|
1359
|
+
}
|
|
1360
|
+
} catch {
|
|
1361
|
+
const { existsSync: existsSync4 } = await import("fs");
|
|
1362
|
+
if (existsSync4("manage.py")) {
|
|
1363
|
+
devCommand = "python manage.py runserver";
|
|
1364
|
+
} else if (existsSync4("Cargo.toml")) {
|
|
1365
|
+
devCommand = "cargo run";
|
|
1366
|
+
} else if (existsSync4("go.mod")) {
|
|
1367
|
+
devCommand = "go run .";
|
|
1368
|
+
}
|
|
1369
|
+
}
|
|
1370
|
+
}
|
|
1371
|
+
const [cmd, ...args] = devCommand.split(" ");
|
|
1315
1372
|
console.log(chalk18.bold("\n forge") + chalk18.dim(" start"));
|
|
1316
|
-
console.log(chalk18.dim(` ${adapter.
|
|
1373
|
+
console.log(chalk18.dim(` ${adapter.id === "generic" ? "Custom stack" : adapter.name} dev server
|
|
1317
1374
|
`));
|
|
1318
|
-
console.log(chalk18.dim(` Running: ${
|
|
1375
|
+
console.log(chalk18.dim(` Running: ${devCommand}
|
|
1319
1376
|
`));
|
|
1320
1377
|
const child = spawn(cmd, args, {
|
|
1321
1378
|
cwd: process.cwd(),
|
|
@@ -1325,7 +1382,7 @@ async function startCommand() {
|
|
|
1325
1382
|
child.on("error", (err) => {
|
|
1326
1383
|
console.log(chalk18.red(`
|
|
1327
1384
|
Failed to start: ${err.message}`));
|
|
1328
|
-
console.log(chalk18.dim(` Try running manually: ${
|
|
1385
|
+
console.log(chalk18.dim(` Try running manually: ${devCommand}
|
|
1329
1386
|
`));
|
|
1330
1387
|
});
|
|
1331
1388
|
child.on("exit", (code) => {
|
|
@@ -1381,8 +1438,8 @@ var program = new Command();
|
|
|
1381
1438
|
program.name("forge").description(
|
|
1382
1439
|
chalk20.bold("Forge") + " \u2014 AI Development Orchestration Framework\n Structured multi-agent pipeline: plan \u2192 design \u2192 build \u2192 review"
|
|
1383
1440
|
).version("1.0.0");
|
|
1384
|
-
program.command("auto [description]").description("Fully autonomous mode \u2014 plan, build, and review in one command").option("--no-sandbox", "Disable sandbox (not recommended)").option("-q, --quiet", "Hide live agent output, show spinners only").option("--allow-network <domains>", "Comma-separated allowed network domains").option("--mute", "Suppress notification sounds").option("--deploy", "Configure GitHub Pages deployment after build").option("--skip-design", "Skip design phase (faster, no Storybook previews)").action(autoCommand);
|
|
1385
|
-
program.command("resume").description("Resume an interrupted sprint from where it left off").option("--no-sandbox", "Disable sandbox").option("-q, --quiet", "Spinners only").option("--mute", "Suppress sounds").option("--skip-design", "Skip design phase").action(resumeCommand);
|
|
1441
|
+
program.command("auto [description]").description("Fully autonomous mode \u2014 plan, build, and review in one command").option("--no-sandbox", "Disable sandbox (not recommended)").option("-y, --yes", "Skip all confirmation prompts (auto-approve everything)").option("-q, --quiet", "Hide live agent output, show spinners only").option("--allow-network <domains>", "Comma-separated allowed network domains").option("--mute", "Suppress notification sounds").option("--deploy", "Configure GitHub Pages deployment after build").option("--skip-design", "Skip design phase (faster, no Storybook previews)").action(autoCommand);
|
|
1442
|
+
program.command("resume").description("Resume an interrupted sprint from where it left off").option("--no-sandbox", "Disable sandbox").option("-y, --yes", "Skip all confirmation prompts (auto-approve everything)").option("-q, --quiet", "Spinners only").option("--mute", "Suppress sounds").option("--skip-design", "Skip design phase").action(resumeCommand);
|
|
1386
1443
|
program.command("sprint [description]").description("Run full pipeline with human gates between phases").action(sprintCommand);
|
|
1387
1444
|
program.command("init").description("Initialize Forge in the current project").option("-f, --framework <framework>", "Framework (nextjs, react, django)").option("--no-storybook", "Skip Storybook setup").action(initCommand);
|
|
1388
1445
|
program.command("plan [description]").description("Generate a sprint plan from a project description").option("--regen", "Regenerate plan from scratch").action(planCommand);
|