create-agdf 0.4.3 → 0.4.5
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/bin/create-agdf.js
CHANGED
|
@@ -555,22 +555,73 @@ function printOpenCodeStatus(report, json) {
|
|
|
555
555
|
}
|
|
556
556
|
|
|
557
557
|
function installCodexGlobalPlugin() {
|
|
558
|
+
const expectedVersion = pluginDefinition.version;
|
|
559
|
+
|
|
558
560
|
try {
|
|
559
561
|
execFileSync("codex", ["plugin", "marketplace", "add", "arndtgold/ai-native-governance-delivery-framework"], { stdio: "inherit" });
|
|
562
|
+
execFileSync("codex", ["plugin", "marketplace", "upgrade", "agdf"], { stdio: "inherit" });
|
|
560
563
|
execFileSync("codex", ["plugin", "add", "agdf", "--marketplace", "agdf"], { stdio: "inherit" });
|
|
564
|
+
const listOutput = execFileSync("codex", ["plugin", "list"], { encoding: "utf8", stdio: "pipe" });
|
|
565
|
+
const installedVersion = pluginVersionFromList(listOutput, "agdf@agdf");
|
|
566
|
+
if (installedVersion !== expectedVersion) {
|
|
567
|
+
throw new Error(versionMismatchMessage("Codex", "agdf@agdf", expectedVersion, installedVersion, "codex plugin marketplace upgrade agdf && codex plugin add agdf --marketplace agdf"));
|
|
568
|
+
}
|
|
569
|
+
console.log(`AGDF Codex plugin version verified: ${installedVersion}.`);
|
|
561
570
|
} catch (error) {
|
|
562
|
-
|
|
571
|
+
if (error.message?.startsWith("AGDF Codex plugin version mismatch")) throw error;
|
|
572
|
+
throw new Error(`Failed to install the AGDF Codex plugin. Make sure the Codex CLI is installed and available on PATH, then rerun this command. ${commandErrorText(error)}`.trim());
|
|
563
573
|
}
|
|
564
574
|
}
|
|
565
575
|
|
|
566
576
|
function installClaudeGlobalPlugin() {
|
|
577
|
+
const expectedVersion = pluginDefinition.version;
|
|
578
|
+
|
|
567
579
|
try {
|
|
568
|
-
execFileSync("claude", ["plugin", "add", "arndtgold/ai-native-governance-delivery-framework"], { stdio: "inherit" });
|
|
569
|
-
|
|
570
|
-
|
|
580
|
+
execFileSync("claude", ["plugin", "marketplace", "add", "arndtgold/ai-native-governance-delivery-framework"], { stdio: "inherit" });
|
|
581
|
+
execFileSync("claude", ["plugin", "marketplace", "update", "agdf"], { stdio: "inherit" });
|
|
582
|
+
const beforeList = execFileSync("claude", ["plugin", "list"], { encoding: "utf8", stdio: "pipe" });
|
|
583
|
+
const alreadyInstalled = pluginListHasPlugin(beforeList, "agdf@agdf");
|
|
584
|
+
execFileSync("claude", ["plugin", alreadyInstalled ? "update" : "install", "agdf@agdf"], { stdio: "inherit" });
|
|
585
|
+
const afterList = execFileSync("claude", ["plugin", "list"], { encoding: "utf8", stdio: "pipe" });
|
|
586
|
+
const installedVersion = pluginVersionFromList(afterList, "agdf@agdf");
|
|
587
|
+
if (installedVersion) {
|
|
588
|
+
if (installedVersion !== expectedVersion) {
|
|
589
|
+
throw new Error(versionMismatchMessage("Claude Code", "agdf@agdf", expectedVersion, installedVersion, "claude plugin marketplace update agdf && claude plugin update agdf@agdf"));
|
|
590
|
+
}
|
|
591
|
+
console.log(`AGDF Claude Code plugin version verified: ${installedVersion}.`);
|
|
592
|
+
} else {
|
|
593
|
+
console.log("AGDF Claude Code plugin installed or updated. Claude Code did not expose a plugin version in `claude plugin list`; verify with `claude plugin list` after restart if needed.");
|
|
594
|
+
}
|
|
595
|
+
} catch (error) {
|
|
596
|
+
if (error.message?.startsWith("AGDF Claude Code plugin version mismatch")) throw error;
|
|
597
|
+
throw new Error(`Failed to install the AGDF Claude Code plugin. Make sure the Claude Code CLI is installed and available on PATH, then rerun this command. ${commandErrorText(error)}`.trim());
|
|
571
598
|
}
|
|
572
599
|
}
|
|
573
600
|
|
|
601
|
+
function commandErrorText(error) {
|
|
602
|
+
return (error.stderr || error.stdout || error.message || "").toString().trim();
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
function pluginListHasPlugin(output, pluginId) {
|
|
606
|
+
return output
|
|
607
|
+
.split(/\r?\n/)
|
|
608
|
+
.some((line) => line.includes(pluginId));
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
function pluginVersionFromList(output, pluginId) {
|
|
612
|
+
const escapedPluginId = pluginId.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
613
|
+
const line = output
|
|
614
|
+
.split(/\r?\n/)
|
|
615
|
+
.find((entry) => new RegExp(`(^|\\s)${escapedPluginId}(\\s|$)`).test(entry));
|
|
616
|
+
if (!line) return "";
|
|
617
|
+
const versionMatch = line.match(/\b(\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?)\b/);
|
|
618
|
+
return versionMatch?.[1] ?? "";
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
function versionMismatchMessage(surface, pluginId, expectedVersion, installedVersion, correctiveCommand) {
|
|
622
|
+
return `AGDF ${surface} plugin version mismatch for ${pluginId}: expected ${expectedVersion}, observed ${installedVersion || "unknown"}. Refresh with: ${correctiveCommand}`;
|
|
623
|
+
}
|
|
624
|
+
|
|
574
625
|
function loadAsset(relativePath) {
|
|
575
626
|
return readFileSync(join(generatedRoot, relativePath), "utf8");
|
|
576
627
|
}
|
|
@@ -586,6 +637,55 @@ function writeGeneratedFile(targetDir, relativePath, content, force, allowOverwr
|
|
|
586
637
|
writeFileSync(outputPath, content, "utf8");
|
|
587
638
|
}
|
|
588
639
|
|
|
640
|
+
function assertGeneratedWritePlan(targetDir, files, force) {
|
|
641
|
+
const blocked = files.find((file) => existsSync(join(targetDir, file.path)) && !force && !file.allowOverwrite);
|
|
642
|
+
if (blocked) {
|
|
643
|
+
throw new Error(`Refusing to overwrite existing file: ${blocked.path}. Re-run with --force if you want to replace it.`);
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
function isAgdfOwnedAgentsFile(content) {
|
|
648
|
+
return content.includes("## Surface Convention")
|
|
649
|
+
&& content.includes("GitHub Copilot repository skills do not have a plugin namespace")
|
|
650
|
+
&& content.includes("AGDF is agent-native first and CLI-verifiable by design");
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
function addCopilotAgentsFile(files, targetDir, force) {
|
|
654
|
+
const agentsPath = join(targetDir, "AGENTS.md");
|
|
655
|
+
if (!existsSync(agentsPath) || force) {
|
|
656
|
+
files.push({
|
|
657
|
+
path: "AGENTS.md",
|
|
658
|
+
content: loadAsset("AGENTS.md"),
|
|
659
|
+
});
|
|
660
|
+
return;
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
const existingAgents = readFileSync(agentsPath, "utf8");
|
|
664
|
+
if (isAgdfOwnedAgentsFile(existingAgents)) {
|
|
665
|
+
files.push({
|
|
666
|
+
path: "AGENTS.md",
|
|
667
|
+
content: loadAsset("AGENTS.md"),
|
|
668
|
+
allowOverwrite: true,
|
|
669
|
+
action: "refreshed",
|
|
670
|
+
});
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
files.push({
|
|
675
|
+
path: agdfFragmentPath,
|
|
676
|
+
content: loadAsset("AGENTS.md"),
|
|
677
|
+
allowOverwrite: true,
|
|
678
|
+
action: "refreshed",
|
|
679
|
+
preserved: "AGENTS.md",
|
|
680
|
+
});
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
function shouldWriteLanguageConfig(target, targetDir, force) {
|
|
684
|
+
if (force) return true;
|
|
685
|
+
if ((target === "copilot" || target === "both") && existsSync(join(targetDir, ".agdf", "control", "config.json"))) return false;
|
|
686
|
+
return true;
|
|
687
|
+
}
|
|
688
|
+
|
|
589
689
|
function addLanguageConfig(files, languagePreference) {
|
|
590
690
|
files.push({
|
|
591
691
|
path: join(".agdf", "control", "config.json"),
|
|
@@ -630,7 +730,7 @@ function generatedFilesForTarget(target, targetDir, force, languagePreference) {
|
|
|
630
730
|
}
|
|
631
731
|
|
|
632
732
|
if (target === "codex-repo" || target === "both") {
|
|
633
|
-
addLanguageConfig(files, languagePreference);
|
|
733
|
+
if (shouldWriteLanguageConfig(target, targetDir, force)) addLanguageConfig(files, languagePreference);
|
|
634
734
|
for (const codexPath of codexPluginFiles) {
|
|
635
735
|
files.push({
|
|
636
736
|
path: codexPath,
|
|
@@ -640,17 +740,15 @@ function generatedFilesForTarget(target, targetDir, force, languagePreference) {
|
|
|
640
740
|
}
|
|
641
741
|
|
|
642
742
|
if (target === "copilot" || target === "both") {
|
|
643
|
-
if (target !== "both") addLanguageConfig(files, languagePreference);
|
|
644
|
-
|
|
645
|
-
files.push({
|
|
646
|
-
path: agentsTargetPath,
|
|
647
|
-
content: loadAsset("AGENTS.md"),
|
|
648
|
-
});
|
|
743
|
+
if (target !== "both" && shouldWriteLanguageConfig(target, targetDir, force)) addLanguageConfig(files, languagePreference);
|
|
744
|
+
addCopilotAgentsFile(files, targetDir, force);
|
|
649
745
|
|
|
650
746
|
for (const controlPath of controlFiles) {
|
|
651
747
|
files.push({
|
|
652
748
|
path: controlPath,
|
|
653
749
|
content: loadAsset(controlPath),
|
|
750
|
+
allowOverwrite: true,
|
|
751
|
+
action: "refreshed",
|
|
654
752
|
});
|
|
655
753
|
}
|
|
656
754
|
|
|
@@ -658,6 +756,8 @@ function generatedFilesForTarget(target, targetDir, force, languagePreference) {
|
|
|
658
756
|
files.push({
|
|
659
757
|
path: instructionPath,
|
|
660
758
|
content: loadAsset(instructionPath),
|
|
759
|
+
allowOverwrite: true,
|
|
760
|
+
action: "refreshed",
|
|
661
761
|
});
|
|
662
762
|
}
|
|
663
763
|
|
|
@@ -665,6 +765,8 @@ function generatedFilesForTarget(target, targetDir, force, languagePreference) {
|
|
|
665
765
|
files.push({
|
|
666
766
|
path: skillPath,
|
|
667
767
|
content: loadAsset(skillPath),
|
|
768
|
+
allowOverwrite: true,
|
|
769
|
+
action: "refreshed",
|
|
668
770
|
});
|
|
669
771
|
}
|
|
670
772
|
}
|
|
@@ -701,7 +803,15 @@ function printNextSteps(target, destination, files, wroteAgentsFragment, wroteOp
|
|
|
701
803
|
console.log("");
|
|
702
804
|
console.log("Generated:");
|
|
703
805
|
for (const file of files) {
|
|
704
|
-
|
|
806
|
+
const action = file.action ? `${file.action}: ` : "";
|
|
807
|
+
console.log(`- ${action}${file.path}`);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
const preservedFiles = [...new Set(files.map((file) => file.preserved).filter(Boolean))];
|
|
811
|
+
if (preservedFiles.length > 0) {
|
|
812
|
+
console.log("");
|
|
813
|
+
console.log("Preserved:");
|
|
814
|
+
for (const preserved of preservedFiles) console.log(`- ${preserved}`);
|
|
705
815
|
}
|
|
706
816
|
|
|
707
817
|
console.log("");
|
|
@@ -2146,6 +2256,7 @@ async function main() {
|
|
|
2146
2256
|
const wroteOpenCodeConfigFragment = files.some(file => file.path === openCodeConfigFragmentPath);
|
|
2147
2257
|
|
|
2148
2258
|
try {
|
|
2259
|
+
assertGeneratedWritePlan(options.dir, files, options.force);
|
|
2149
2260
|
for (const file of files) {
|
|
2150
2261
|
writeGeneratedFile(options.dir, file.path, file.content, options.force, file.allowOverwrite);
|
|
2151
2262
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"id": "agdf",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.5",
|
|
5
5
|
"displayName": "AI Governance & Delivery Framework",
|
|
6
6
|
"developerName": "AI-native Governance & Delivery Framework",
|
|
7
7
|
"description": "Codex-first workflow skills for gated, auditable AI-assisted software delivery.",
|
package/package.json
CHANGED