@alxyrgin/agent-forge 1.0.0 → 3.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/README.md +384 -96
- package/dist/index.js +355 -58
- package/dist/index.js.map +1 -1
- package/package.json +12 -2
- package/templates/agents/documentation/gatekeeper.md.ejs +83 -0
- package/templates/agents/documentation/librarian.md.ejs +80 -0
- package/templates/agents/documentation/verifier.md.ejs +92 -0
- package/templates/agents/documentation/writer.md.ejs +189 -0
- package/templates/agents/pipeline/analyst.md.ejs +65 -0
- package/templates/agents/{core → pipeline}/architect.md.ejs +38 -1
- package/templates/agents/pipeline/developer.md.ejs +75 -0
- package/templates/agents/pipeline/inspector.md.ejs +123 -0
- package/templates/agents/pipeline/planner.md.ejs +211 -0
- package/templates/agents/pipeline/reviewer.md.ejs +158 -0
- package/templates/agents/pipeline/skeptic.md.ejs +105 -0
- package/templates/agents/pipeline/tester.md.ejs +134 -0
- package/templates/agents/planning/decomposer.md.ejs +103 -0
- package/templates/agents/planning/interviewer.md.ejs +104 -0
- package/templates/agents/planning/researcher.md.ejs +96 -0
- package/templates/agents/planning/validator.md.ejs +97 -0
- package/templates/agents/security/auditor.md.ejs +105 -0
- package/templates/agents/security/deployer.md.ejs +81 -0
- package/templates/agents/security/prompter.md.ejs +87 -0
- package/templates/agents/security/scaffolder.md.ejs +75 -0
- package/templates/hooks/protect-docs.sh.ejs +25 -0
- package/templates/memory/checkpoint.yml.ejs +21 -0
- package/templates/memory/tech-debt.md.ejs +9 -1
- package/templates/root/CLAUDE.md.ejs +228 -30
- package/templates/root/settings.json.ejs +15 -1
- package/templates/rules/agent-output-format.md.ejs +80 -0
- package/templates/rules/context-loading.md.ejs +70 -0
- package/templates/rules/development-cycle.md.ejs +163 -29
- package/templates/rules/quality-gates.md.ejs +80 -0
- package/templates/rules/rollback-protocol.md.ejs +60 -0
- package/templates/rules/shared-resources.md.ejs +73 -0
- package/templates/skills/core/code/SKILL.md.ejs +85 -0
- package/templates/skills/core/complete-task/SKILL.md.ejs +22 -9
- package/templates/skills/core/done/SKILL.md.ejs +66 -0
- package/templates/skills/core/end-session/SKILL.md.ejs +14 -6
- package/templates/skills/core/review/SKILL.md.ejs +1 -1
- package/templates/skills/core/start-session/SKILL.md.ejs +73 -10
- package/templates/skills/core/take-task/SKILL.md.ejs +279 -30
- package/templates/skills/core/test/SKILL.md.ejs +200 -0
- package/templates/skills/extra/audit-wave/SKILL.md.ejs +58 -0
- package/templates/skills/extra/dashboard/SKILL.md.ejs +64 -0
- package/templates/skills/extra/decompose/SKILL.md.ejs +72 -0
- package/templates/skills/extra/feature/SKILL.md.ejs +83 -0
- package/templates/skills/extra/interview/SKILL.md.ejs +66 -0
- package/templates/skills/extra/prompts/SKILL.md.ejs +65 -0
- package/templates/skills/extra/security/SKILL.md.ejs +77 -0
- package/templates/skills/extra/skill-master/SKILL.md.ejs +51 -0
- package/templates/skills/extra/spec/SKILL.md.ejs +111 -0
- package/templates/skills/extra/techspec/SKILL.md.ejs +97 -0
- package/templates/skills/extra/write-report/SKILL.md.ejs +26 -0
- package/templates/agents/core/analyst.md.ejs +0 -56
- package/templates/agents/core/developer.md.ejs +0 -54
- package/templates/agents/core/doc-writer.md.ejs +0 -50
- package/templates/agents/core/progress-tracker.md.ejs +0 -56
- package/templates/agents/core/reviewer.md.ejs +0 -52
- package/templates/agents/core/security-auditor.md.ejs +0 -51
- package/templates/agents/core/unit-tester.md.ejs +0 -56
- package/templates/agents/extra/acceptance-tester.md.ejs +0 -48
- package/templates/agents/extra/integration-tester.md.ejs +0 -49
- package/templates/agents/extra/planner.md.ejs +0 -89
package/dist/index.js
CHANGED
|
@@ -181,9 +181,9 @@ async function promptProjectSetup(targetDir) {
|
|
|
181
181
|
name: "agentPreset",
|
|
182
182
|
message: "Agent preset:",
|
|
183
183
|
choices: [
|
|
184
|
-
{ name: "Core (8 agents \u2014
|
|
185
|
-
{ name: "Full (
|
|
186
|
-
{ name: "Minimal (
|
|
184
|
+
{ name: "Core (8 agents \u2014 development pipeline)", value: "core" },
|
|
185
|
+
{ name: "Full (20 agents \u2014 all categories + extra skills)", value: "full" },
|
|
186
|
+
{ name: "Minimal (5 agents \u2014 essentials + inspector)", value: "minimal" }
|
|
187
187
|
]
|
|
188
188
|
},
|
|
189
189
|
{
|
|
@@ -276,6 +276,9 @@ async function fileExists(filePath) {
|
|
|
276
276
|
async function readFile(filePath) {
|
|
277
277
|
return fs.readFile(filePath, "utf-8");
|
|
278
278
|
}
|
|
279
|
+
async function makeExecutable(filePath) {
|
|
280
|
+
await fs.chmod(filePath, 493);
|
|
281
|
+
}
|
|
279
282
|
|
|
280
283
|
// src/utils/template.ts
|
|
281
284
|
import fs2 from "fs";
|
|
@@ -302,7 +305,8 @@ var MEMORY_FILES = [
|
|
|
302
305
|
"tech-stack.md",
|
|
303
306
|
"tech-debt.md",
|
|
304
307
|
"patterns.md",
|
|
305
|
-
"troubleshooting.md"
|
|
308
|
+
"troubleshooting.md",
|
|
309
|
+
"checkpoint.yml"
|
|
306
310
|
];
|
|
307
311
|
async function generateMemoryBank(ctx, overwrite) {
|
|
308
312
|
const result = {
|
|
@@ -333,39 +337,82 @@ async function generateMemoryBank(ctx, overwrite) {
|
|
|
333
337
|
|
|
334
338
|
// src/generators/agents.ts
|
|
335
339
|
import path4 from "path";
|
|
336
|
-
var
|
|
340
|
+
var PIPELINE_AGENTS = [
|
|
337
341
|
"analyst",
|
|
338
342
|
"architect",
|
|
343
|
+
"skeptic",
|
|
339
344
|
"developer",
|
|
340
|
-
"
|
|
345
|
+
"tester",
|
|
346
|
+
"inspector",
|
|
341
347
|
"reviewer",
|
|
342
|
-
"
|
|
343
|
-
|
|
344
|
-
|
|
348
|
+
"planner"
|
|
349
|
+
];
|
|
350
|
+
var PLANNING_AGENTS = [
|
|
351
|
+
"researcher",
|
|
352
|
+
"validator",
|
|
353
|
+
"interviewer",
|
|
354
|
+
"decomposer"
|
|
345
355
|
];
|
|
346
|
-
var
|
|
347
|
-
"
|
|
348
|
-
"
|
|
349
|
-
"
|
|
356
|
+
var SECURITY_AGENTS = [
|
|
357
|
+
"auditor",
|
|
358
|
+
"prompter",
|
|
359
|
+
"deployer",
|
|
360
|
+
"scaffolder"
|
|
361
|
+
];
|
|
362
|
+
var DOCUMENTATION_AGENTS = [
|
|
363
|
+
"librarian",
|
|
364
|
+
"writer",
|
|
365
|
+
"gatekeeper",
|
|
366
|
+
"verifier"
|
|
350
367
|
];
|
|
351
368
|
var MINIMAL_AGENTS = [
|
|
352
369
|
"analyst",
|
|
353
370
|
"developer",
|
|
354
|
-
"
|
|
355
|
-
"reviewer"
|
|
371
|
+
"tester",
|
|
372
|
+
"reviewer",
|
|
373
|
+
"inspector"
|
|
356
374
|
];
|
|
375
|
+
var CORE_AGENTS = [...PIPELINE_AGENTS];
|
|
376
|
+
var FULL_AGENTS = [
|
|
377
|
+
...PIPELINE_AGENTS,
|
|
378
|
+
...PLANNING_AGENTS,
|
|
379
|
+
...SECURITY_AGENTS,
|
|
380
|
+
...DOCUMENTATION_AGENTS
|
|
381
|
+
];
|
|
382
|
+
var CATEGORY_MAP = {};
|
|
383
|
+
for (const name of PIPELINE_AGENTS) {
|
|
384
|
+
CATEGORY_MAP[name] = "pipeline";
|
|
385
|
+
}
|
|
386
|
+
for (const name of PLANNING_AGENTS) {
|
|
387
|
+
CATEGORY_MAP[name] = "planning";
|
|
388
|
+
}
|
|
389
|
+
for (const name of SECURITY_AGENTS) {
|
|
390
|
+
CATEGORY_MAP[name] = "security";
|
|
391
|
+
}
|
|
392
|
+
for (const name of DOCUMENTATION_AGENTS) {
|
|
393
|
+
CATEGORY_MAP[name] = "documentation";
|
|
394
|
+
}
|
|
395
|
+
function getAgentCategory(name) {
|
|
396
|
+
return CATEGORY_MAP[name] || "pipeline";
|
|
397
|
+
}
|
|
357
398
|
function getAgentList(preset) {
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
399
|
+
let names;
|
|
400
|
+
switch (preset) {
|
|
401
|
+
case "minimal":
|
|
402
|
+
names = MINIMAL_AGENTS;
|
|
403
|
+
break;
|
|
404
|
+
case "full":
|
|
405
|
+
names = FULL_AGENTS;
|
|
406
|
+
break;
|
|
407
|
+
case "core":
|
|
408
|
+
default:
|
|
409
|
+
names = CORE_AGENTS;
|
|
410
|
+
break;
|
|
362
411
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
}
|
|
368
|
-
return agents;
|
|
412
|
+
return names.map((name) => ({
|
|
413
|
+
name,
|
|
414
|
+
category: getAgentCategory(name)
|
|
415
|
+
}));
|
|
369
416
|
}
|
|
370
417
|
async function generateAgents(ctx, overwrite) {
|
|
371
418
|
const result = {
|
|
@@ -381,7 +428,7 @@ async function generateAgents(ctx, overwrite) {
|
|
|
381
428
|
for (const agent of agents) {
|
|
382
429
|
try {
|
|
383
430
|
const content = await renderTemplate(
|
|
384
|
-
`agents/${agent.
|
|
431
|
+
`agents/${agent.category}/${agent.name}.md.ejs`,
|
|
385
432
|
templateData
|
|
386
433
|
);
|
|
387
434
|
const outputPath = path4.join(ctx.targetDir, ".claude/agents", `${agent.name}.md`);
|
|
@@ -400,15 +447,43 @@ async function generateAgents(ctx, overwrite) {
|
|
|
400
447
|
|
|
401
448
|
// src/generators/skills.ts
|
|
402
449
|
import path5 from "path";
|
|
403
|
-
var
|
|
450
|
+
var CORE_SKILLS = [
|
|
404
451
|
"start-session",
|
|
405
452
|
"end-session",
|
|
406
453
|
"take-task",
|
|
407
454
|
"complete-task",
|
|
408
455
|
"status",
|
|
409
456
|
"plan",
|
|
410
|
-
"review"
|
|
457
|
+
"review",
|
|
458
|
+
"code",
|
|
459
|
+
"test",
|
|
460
|
+
"done"
|
|
461
|
+
];
|
|
462
|
+
var EXTRA_SKILLS = [
|
|
463
|
+
"interview",
|
|
464
|
+
"audit-wave",
|
|
465
|
+
"write-report",
|
|
466
|
+
"dashboard",
|
|
467
|
+
"skill-master",
|
|
468
|
+
"decompose",
|
|
469
|
+
"feature",
|
|
470
|
+
"security",
|
|
471
|
+
"spec",
|
|
472
|
+
"techspec",
|
|
473
|
+
"prompts"
|
|
411
474
|
];
|
|
475
|
+
function getSkillList(preset) {
|
|
476
|
+
const skills = [];
|
|
477
|
+
for (const name of CORE_SKILLS) {
|
|
478
|
+
skills.push({ name, dir: "core" });
|
|
479
|
+
}
|
|
480
|
+
if (preset === "full") {
|
|
481
|
+
for (const name of EXTRA_SKILLS) {
|
|
482
|
+
skills.push({ name, dir: "extra" });
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
return skills;
|
|
486
|
+
}
|
|
412
487
|
async function generateSkills(ctx, overwrite) {
|
|
413
488
|
const result = {
|
|
414
489
|
filesCreated: [],
|
|
@@ -419,13 +494,14 @@ async function generateSkills(ctx, overwrite) {
|
|
|
419
494
|
...ctx,
|
|
420
495
|
defaultBranch: "main"
|
|
421
496
|
};
|
|
422
|
-
|
|
497
|
+
const skills = getSkillList(ctx.agentPreset);
|
|
498
|
+
for (const skill of skills) {
|
|
423
499
|
try {
|
|
424
500
|
const content = await renderTemplate(
|
|
425
|
-
`skills
|
|
501
|
+
`skills/${skill.dir}/${skill.name}/SKILL.md.ejs`,
|
|
426
502
|
templateData
|
|
427
503
|
);
|
|
428
|
-
const outputPath = path5.join(ctx.targetDir, `.claude/skills/${skill}`, "SKILL.md");
|
|
504
|
+
const outputPath = path5.join(ctx.targetDir, `.claude/skills/${skill.name}`, "SKILL.md");
|
|
429
505
|
const status = await writeFileSafe(outputPath, content, overwrite);
|
|
430
506
|
if (status === "skipped") {
|
|
431
507
|
result.filesSkipped.push(outputPath);
|
|
@@ -433,7 +509,7 @@ async function generateSkills(ctx, overwrite) {
|
|
|
433
509
|
result.filesCreated.push(outputPath);
|
|
434
510
|
}
|
|
435
511
|
} catch (err) {
|
|
436
|
-
result.errors.push(`Skill ${skill}: ${err}`);
|
|
512
|
+
result.errors.push(`Skill ${skill.name}: ${err}`);
|
|
437
513
|
}
|
|
438
514
|
}
|
|
439
515
|
return result;
|
|
@@ -444,7 +520,12 @@ import path6 from "path";
|
|
|
444
520
|
var RULES = [
|
|
445
521
|
"commit-conventions",
|
|
446
522
|
"development-cycle",
|
|
447
|
-
"testing-standards"
|
|
523
|
+
"testing-standards",
|
|
524
|
+
"shared-resources",
|
|
525
|
+
"context-loading",
|
|
526
|
+
"agent-output-format",
|
|
527
|
+
"quality-gates",
|
|
528
|
+
"rollback-protocol"
|
|
448
529
|
];
|
|
449
530
|
async function generateRules(ctx, overwrite) {
|
|
450
531
|
const result = {
|
|
@@ -558,14 +639,7 @@ async function generateInfra(ctx, overwrite) {
|
|
|
558
639
|
}
|
|
559
640
|
}
|
|
560
641
|
try {
|
|
561
|
-
const manifest =
|
|
562
|
-
version: "1.0.0",
|
|
563
|
-
createdAt: ctx.today,
|
|
564
|
-
projectName: ctx.projectName,
|
|
565
|
-
agentPreset: ctx.agentPreset,
|
|
566
|
-
language: ctx.language,
|
|
567
|
-
expectedFiles: getExpectedFiles(ctx)
|
|
568
|
-
};
|
|
642
|
+
const manifest = buildManifest(ctx);
|
|
569
643
|
const outputPath = path8.join(ctx.targetDir, ".claude-forge.json");
|
|
570
644
|
const status = await writeFileSafe(
|
|
571
645
|
outputPath,
|
|
@@ -582,6 +656,25 @@ async function generateInfra(ctx, overwrite) {
|
|
|
582
656
|
}
|
|
583
657
|
return result;
|
|
584
658
|
}
|
|
659
|
+
function buildManifest(ctx) {
|
|
660
|
+
return {
|
|
661
|
+
version: "3.0.0",
|
|
662
|
+
createdAt: ctx.today,
|
|
663
|
+
updatedAt: ctx.today,
|
|
664
|
+
projectName: ctx.projectName,
|
|
665
|
+
projectDescription: ctx.projectDescription,
|
|
666
|
+
language: ctx.language,
|
|
667
|
+
agentPreset: ctx.agentPreset,
|
|
668
|
+
stack: ctx.stack,
|
|
669
|
+
framework: ctx.framework,
|
|
670
|
+
testFramework: ctx.testFramework,
|
|
671
|
+
testCommand: ctx.testCommand,
|
|
672
|
+
srcDir: ctx.srcDir,
|
|
673
|
+
testDir: ctx.testDir,
|
|
674
|
+
commitStyle: ctx.commitStyle,
|
|
675
|
+
expectedFiles: getExpectedFiles(ctx)
|
|
676
|
+
};
|
|
677
|
+
}
|
|
585
678
|
function getExpectedFiles(ctx) {
|
|
586
679
|
const files = [
|
|
587
680
|
".claude/CLAUDE.md",
|
|
@@ -595,44 +688,105 @@ function getExpectedFiles(ctx) {
|
|
|
595
688
|
"dev-infra/memory/tech-stack.md",
|
|
596
689
|
"dev-infra/memory/tech-debt.md",
|
|
597
690
|
"dev-infra/memory/patterns.md",
|
|
598
|
-
"dev-infra/memory/troubleshooting.md"
|
|
691
|
+
"dev-infra/memory/troubleshooting.md",
|
|
692
|
+
"dev-infra/memory/checkpoint.yml"
|
|
599
693
|
];
|
|
694
|
+
files.push(".claude/hooks/protect-docs.sh");
|
|
600
695
|
files.push(
|
|
601
696
|
".claude/rules/commit-conventions.md",
|
|
602
697
|
".claude/rules/development-cycle.md",
|
|
603
|
-
".claude/rules/testing-standards.md"
|
|
698
|
+
".claude/rules/testing-standards.md",
|
|
699
|
+
".claude/rules/shared-resources.md",
|
|
700
|
+
".claude/rules/context-loading.md",
|
|
701
|
+
".claude/rules/agent-output-format.md",
|
|
702
|
+
".claude/rules/quality-gates.md",
|
|
703
|
+
".claude/rules/rollback-protocol.md"
|
|
604
704
|
);
|
|
605
|
-
const
|
|
705
|
+
const coreSkills = [
|
|
606
706
|
"start-session",
|
|
607
707
|
"end-session",
|
|
608
708
|
"take-task",
|
|
609
709
|
"complete-task",
|
|
610
710
|
"status",
|
|
611
711
|
"plan",
|
|
612
|
-
"review"
|
|
712
|
+
"review",
|
|
713
|
+
"code",
|
|
714
|
+
"test",
|
|
715
|
+
"done"
|
|
613
716
|
];
|
|
717
|
+
const extraSkills = [
|
|
718
|
+
"interview",
|
|
719
|
+
"audit-wave",
|
|
720
|
+
"write-report",
|
|
721
|
+
"dashboard",
|
|
722
|
+
"skill-master",
|
|
723
|
+
"decompose",
|
|
724
|
+
"feature",
|
|
725
|
+
"security",
|
|
726
|
+
"spec",
|
|
727
|
+
"techspec",
|
|
728
|
+
"prompts"
|
|
729
|
+
];
|
|
730
|
+
const skills = ctx.agentPreset === "full" ? [...coreSkills, ...extraSkills] : coreSkills;
|
|
614
731
|
for (const skill of skills) {
|
|
615
732
|
files.push(`.claude/skills/${skill}/SKILL.md`);
|
|
616
733
|
}
|
|
617
|
-
const
|
|
734
|
+
const pipelineAgents = [
|
|
618
735
|
"analyst",
|
|
619
736
|
"architect",
|
|
737
|
+
"skeptic",
|
|
620
738
|
"developer",
|
|
621
|
-
"
|
|
739
|
+
"tester",
|
|
740
|
+
"inspector",
|
|
622
741
|
"reviewer",
|
|
623
|
-
"
|
|
624
|
-
|
|
625
|
-
|
|
742
|
+
"planner"
|
|
743
|
+
];
|
|
744
|
+
const planningAgents = ["researcher", "validator", "interviewer", "decomposer"];
|
|
745
|
+
const securityAgents = ["auditor", "prompter", "deployer", "scaffolder"];
|
|
746
|
+
const documentationAgents = ["librarian", "writer", "gatekeeper", "verifier"];
|
|
747
|
+
const minimalAgents = ["analyst", "developer", "tester", "reviewer", "inspector"];
|
|
748
|
+
const coreAgents = [...pipelineAgents];
|
|
749
|
+
const fullAgents = [
|
|
750
|
+
...pipelineAgents,
|
|
751
|
+
...planningAgents,
|
|
752
|
+
...securityAgents,
|
|
753
|
+
...documentationAgents
|
|
626
754
|
];
|
|
627
|
-
const
|
|
628
|
-
const extraAgents = ["planner", "integration-tester", "acceptance-tester"];
|
|
629
|
-
const agents = ctx.agentPreset === "minimal" ? minimalAgents : ctx.agentPreset === "full" ? [...coreAgents, ...extraAgents] : coreAgents;
|
|
755
|
+
const agents = ctx.agentPreset === "minimal" ? minimalAgents : ctx.agentPreset === "full" ? fullAgents : coreAgents;
|
|
630
756
|
for (const agent of agents) {
|
|
631
757
|
files.push(`.claude/agents/${agent}.md`);
|
|
632
758
|
}
|
|
633
759
|
return files;
|
|
634
760
|
}
|
|
635
761
|
|
|
762
|
+
// src/generators/hooks.ts
|
|
763
|
+
import path9 from "path";
|
|
764
|
+
async function generateHooks(ctx, overwrite) {
|
|
765
|
+
const result = {
|
|
766
|
+
filesCreated: [],
|
|
767
|
+
filesSkipped: [],
|
|
768
|
+
errors: []
|
|
769
|
+
};
|
|
770
|
+
const templateData = {
|
|
771
|
+
...ctx,
|
|
772
|
+
defaultBranch: "main"
|
|
773
|
+
};
|
|
774
|
+
try {
|
|
775
|
+
const content = await renderTemplate("hooks/protect-docs.sh.ejs", templateData);
|
|
776
|
+
const outputPath = path9.join(ctx.targetDir, ".claude/hooks/protect-docs.sh");
|
|
777
|
+
const status = await writeFileSafe(outputPath, content, overwrite);
|
|
778
|
+
if (status === "skipped") {
|
|
779
|
+
result.filesSkipped.push(outputPath);
|
|
780
|
+
} else {
|
|
781
|
+
result.filesCreated.push(outputPath);
|
|
782
|
+
await makeExecutable(outputPath);
|
|
783
|
+
}
|
|
784
|
+
} catch (err) {
|
|
785
|
+
result.errors.push(`Hook protect-docs.sh: ${err}`);
|
|
786
|
+
}
|
|
787
|
+
return result;
|
|
788
|
+
}
|
|
789
|
+
|
|
636
790
|
// src/generators/index.ts
|
|
637
791
|
async function generateAll(ctx, overwrite = false) {
|
|
638
792
|
const result = {
|
|
@@ -646,6 +800,7 @@ async function generateAll(ctx, overwrite = false) {
|
|
|
646
800
|
generateSkills,
|
|
647
801
|
generateRules,
|
|
648
802
|
generateMemoryBank,
|
|
803
|
+
generateHooks,
|
|
649
804
|
generateInfra
|
|
650
805
|
];
|
|
651
806
|
for (const generator of generators) {
|
|
@@ -665,7 +820,7 @@ async function generateAll(ctx, overwrite = false) {
|
|
|
665
820
|
async function initCommand(options) {
|
|
666
821
|
const targetDir = process.cwd();
|
|
667
822
|
console.log();
|
|
668
|
-
console.log(chalk.bold(" agent-forge
|
|
823
|
+
console.log(chalk.bold(" agent-forge v3.0.0"));
|
|
669
824
|
console.log(chalk.dim(" AI-driven Development Framework for Claude Code"));
|
|
670
825
|
console.log();
|
|
671
826
|
let ctx;
|
|
@@ -708,7 +863,7 @@ async function initCommand(options) {
|
|
|
708
863
|
}
|
|
709
864
|
|
|
710
865
|
// src/commands/doctor.ts
|
|
711
|
-
import
|
|
866
|
+
import path10 from "path";
|
|
712
867
|
import chalk2 from "chalk";
|
|
713
868
|
async function doctorCommand() {
|
|
714
869
|
const targetDir = process.cwd();
|
|
@@ -716,7 +871,7 @@ async function doctorCommand() {
|
|
|
716
871
|
console.log(chalk2.bold(" agent-forge doctor"));
|
|
717
872
|
console.log(chalk2.dim(" Checking project structure integrity..."));
|
|
718
873
|
console.log();
|
|
719
|
-
const manifestPath =
|
|
874
|
+
const manifestPath = path10.join(targetDir, ".claude-forge.json");
|
|
720
875
|
const manifestExists = await fileExists(manifestPath);
|
|
721
876
|
if (!manifestExists) {
|
|
722
877
|
console.log(chalk2.red(" .claude-forge.json not found"));
|
|
@@ -739,7 +894,7 @@ async function doctorCommand() {
|
|
|
739
894
|
let okCount = 0;
|
|
740
895
|
let failCount = 0;
|
|
741
896
|
for (const file of manifest.expectedFiles) {
|
|
742
|
-
const filePath =
|
|
897
|
+
const filePath = path10.join(targetDir, file);
|
|
743
898
|
const exists = await fileExists(filePath);
|
|
744
899
|
const check = {
|
|
745
900
|
name: file,
|
|
@@ -799,10 +954,152 @@ async function doctorCommand() {
|
|
|
799
954
|
}
|
|
800
955
|
}
|
|
801
956
|
|
|
957
|
+
// src/commands/update.ts
|
|
958
|
+
import path11 from "path";
|
|
959
|
+
import chalk3 from "chalk";
|
|
960
|
+
import ora2 from "ora";
|
|
961
|
+
function today2() {
|
|
962
|
+
return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
963
|
+
}
|
|
964
|
+
function contextFromManifest(manifest, targetDir) {
|
|
965
|
+
return {
|
|
966
|
+
projectName: manifest.projectName || targetDir.split("/").pop() || "my-project",
|
|
967
|
+
projectDescription: manifest.projectDescription || "AI-driven project",
|
|
968
|
+
stack: manifest.stack || "typescript",
|
|
969
|
+
framework: manifest.framework || "None",
|
|
970
|
+
testFramework: manifest.testFramework || "vitest",
|
|
971
|
+
testCommand: manifest.testCommand || "npx vitest run",
|
|
972
|
+
srcDir: manifest.srcDir || "src/",
|
|
973
|
+
testDir: manifest.testDir || "tests/",
|
|
974
|
+
team: [],
|
|
975
|
+
milestones: [],
|
|
976
|
+
agentPreset: manifest.agentPreset || "core",
|
|
977
|
+
language: manifest.language || "ru",
|
|
978
|
+
commitStyle: manifest.commitStyle || "standard",
|
|
979
|
+
today: today2(),
|
|
980
|
+
targetDir
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
async function updateCommand() {
|
|
984
|
+
const targetDir = process.cwd();
|
|
985
|
+
console.log();
|
|
986
|
+
console.log(chalk3.bold(" agent-forge update v3.0.0"));
|
|
987
|
+
console.log(chalk3.dim(" Updating framework files..."));
|
|
988
|
+
console.log();
|
|
989
|
+
const manifestPath = path11.join(targetDir, ".claude-forge.json");
|
|
990
|
+
const manifestExists = await fileExists(manifestPath);
|
|
991
|
+
if (!manifestExists) {
|
|
992
|
+
console.log(chalk3.red(" .claude-forge.json not found"));
|
|
993
|
+
console.log(
|
|
994
|
+
chalk3.dim(" This project is not initialized. Run `agent-forge init` first.")
|
|
995
|
+
);
|
|
996
|
+
console.log();
|
|
997
|
+
process.exit(1);
|
|
998
|
+
}
|
|
999
|
+
const manifestRaw = await readFile(manifestPath);
|
|
1000
|
+
let existingManifest;
|
|
1001
|
+
try {
|
|
1002
|
+
existingManifest = JSON.parse(manifestRaw);
|
|
1003
|
+
} catch {
|
|
1004
|
+
console.log(chalk3.red(" .claude-forge.json is corrupted. Cannot update."));
|
|
1005
|
+
console.log(
|
|
1006
|
+
chalk3.dim(" Run `agent-forge init --overwrite` to reinitialize.")
|
|
1007
|
+
);
|
|
1008
|
+
console.log();
|
|
1009
|
+
process.exit(1);
|
|
1010
|
+
}
|
|
1011
|
+
const previousVersion = existingManifest.version || "unknown";
|
|
1012
|
+
const ctx = contextFromManifest(existingManifest, targetDir);
|
|
1013
|
+
const spinner = ora2("Updating framework files...").start();
|
|
1014
|
+
try {
|
|
1015
|
+
const result = {
|
|
1016
|
+
filesCreated: [],
|
|
1017
|
+
filesSkipped: [],
|
|
1018
|
+
errors: []
|
|
1019
|
+
};
|
|
1020
|
+
const frameworkGenerators = [
|
|
1021
|
+
generateClaudeMd,
|
|
1022
|
+
generateAgents,
|
|
1023
|
+
generateSkills,
|
|
1024
|
+
generateRules,
|
|
1025
|
+
generateHooks
|
|
1026
|
+
];
|
|
1027
|
+
for (const generator of frameworkGenerators) {
|
|
1028
|
+
try {
|
|
1029
|
+
const partial = await generator(ctx, true);
|
|
1030
|
+
result.filesCreated.push(...partial.filesCreated);
|
|
1031
|
+
result.filesSkipped.push(...partial.filesSkipped);
|
|
1032
|
+
result.errors.push(...partial.errors);
|
|
1033
|
+
} catch (err) {
|
|
1034
|
+
result.errors.push(`Generator error: ${err}`);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
const userDataGenerators = [
|
|
1038
|
+
generateMemoryBank,
|
|
1039
|
+
generateInfra
|
|
1040
|
+
];
|
|
1041
|
+
for (const generator of userDataGenerators) {
|
|
1042
|
+
try {
|
|
1043
|
+
const partial = await generator(ctx, false);
|
|
1044
|
+
result.filesCreated.push(...partial.filesCreated);
|
|
1045
|
+
result.filesSkipped.push(...partial.filesSkipped);
|
|
1046
|
+
result.errors.push(...partial.errors);
|
|
1047
|
+
} catch (err) {
|
|
1048
|
+
result.errors.push(`Generator error: ${err}`);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
const updatedManifest = buildManifest(ctx);
|
|
1052
|
+
updatedManifest.createdAt = existingManifest.createdAt || updatedManifest.createdAt;
|
|
1053
|
+
updatedManifest.updatedAt = today2();
|
|
1054
|
+
await writeFileSafe(
|
|
1055
|
+
manifestPath,
|
|
1056
|
+
JSON.stringify(updatedManifest, null, 2) + "\n",
|
|
1057
|
+
true
|
|
1058
|
+
);
|
|
1059
|
+
spinner.succeed(chalk3.green("Framework files updated"));
|
|
1060
|
+
const newFiles = result.filesCreated.filter((f) => !result.filesSkipped.includes(f));
|
|
1061
|
+
const updatedCount = newFiles.length;
|
|
1062
|
+
const skippedCount = result.filesSkipped.length;
|
|
1063
|
+
console.log();
|
|
1064
|
+
if (updatedCount > 0) {
|
|
1065
|
+
console.log(
|
|
1066
|
+
chalk3.green(` + ${updatedCount} files updated/added`)
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
if (skippedCount > 0) {
|
|
1070
|
+
console.log(
|
|
1071
|
+
chalk3.yellow(` ~ ${skippedCount} files skipped (user data preserved)`)
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
if (result.errors.length > 0) {
|
|
1075
|
+
console.log(chalk3.red(` ! ${result.errors.length} errors:`));
|
|
1076
|
+
for (const err of result.errors) {
|
|
1077
|
+
console.log(chalk3.red(` - ${err}`));
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
console.log();
|
|
1081
|
+
if (previousVersion !== updatedManifest.version) {
|
|
1082
|
+
console.log(
|
|
1083
|
+
chalk3.dim(` .claude-forge.json updated: ${previousVersion} -> v${updatedManifest.version}`)
|
|
1084
|
+
);
|
|
1085
|
+
} else {
|
|
1086
|
+
console.log(
|
|
1087
|
+
chalk3.dim(` .claude-forge.json updated (v${updatedManifest.version})`)
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
console.log();
|
|
1091
|
+
} catch (err) {
|
|
1092
|
+
spinner.fail(chalk3.red("Failed to update framework files"));
|
|
1093
|
+
console.error(err);
|
|
1094
|
+
process.exit(1);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
802
1098
|
// src/index.ts
|
|
803
1099
|
var program = new Command();
|
|
804
|
-
program.name("agent-forge").description("AI-driven Development Framework for Claude Code").version("
|
|
1100
|
+
program.name("agent-forge").description("AI-driven Development Framework for Claude Code").version("3.0.0");
|
|
805
1101
|
program.command("init").description("Initialize AI-driven development infrastructure in the current project").option("-y, --yes", "Skip prompts and use defaults").option("--overwrite", "Overwrite existing files").action(initCommand);
|
|
806
1102
|
program.command("doctor").description("Check integrity of the generated structure").action(doctorCommand);
|
|
1103
|
+
program.command("update").description("Update framework files to the latest version (preserves user data)").action(updateCommand);
|
|
807
1104
|
program.parse();
|
|
808
1105
|
//# sourceMappingURL=index.js.map
|