@promptscript/cli 1.0.0-alpha.2 → 1.0.0-alpha.4
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 +29 -0
- package/README.md +8 -0
- package/index.js +921 -410
- package/package.json +1 -1
- package/src/cli.d.ts.map +1 -1
- package/src/commands/compile.d.ts +2 -1
- package/src/commands/compile.d.ts.map +1 -1
- package/src/commands/init.d.ts.map +1 -1
- package/src/output/console.d.ts +4 -0
- package/src/output/console.d.ts.map +1 -1
- package/src/prettier/index.d.ts +2 -0
- package/src/prettier/index.d.ts.map +1 -0
- package/src/prettier/loader.d.ts +36 -0
- package/src/prettier/loader.d.ts.map +1 -0
- package/src/services.d.ts +1 -0
- package/src/services.d.ts.map +1 -1
- package/src/types.d.ts +2 -0
- package/src/types.d.ts.map +1 -1
package/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// packages/cli/src/cli.ts
|
|
2
2
|
import { Command } from "commander";
|
|
3
3
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
4
|
-
import { dirname as
|
|
4
|
+
import { dirname as dirname7 } from "path";
|
|
5
5
|
|
|
6
6
|
// packages/core/src/types/constants.ts
|
|
7
7
|
var BLOCK_TYPES = [
|
|
@@ -86,6 +86,13 @@ function isBuiltInConvention(name) {
|
|
|
86
86
|
return name in BUILT_IN_CONVENTIONS;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
// packages/core/src/types/prettier.ts
|
|
90
|
+
var DEFAULT_PRETTIER_OPTIONS = {
|
|
91
|
+
proseWrap: "preserve",
|
|
92
|
+
tabWidth: 2,
|
|
93
|
+
printWidth: 80
|
|
94
|
+
};
|
|
95
|
+
|
|
89
96
|
// packages/core/src/errors/base.ts
|
|
90
97
|
var PSError = class extends Error {
|
|
91
98
|
/** Error code */
|
|
@@ -291,7 +298,7 @@ function getPackageVersion(baseDir, relativePath = "../package.json") {
|
|
|
291
298
|
|
|
292
299
|
// packages/cli/src/commands/init.ts
|
|
293
300
|
import { fileURLToPath } from "url";
|
|
294
|
-
import { dirname } from "path";
|
|
301
|
+
import { dirname as dirname2 } from "path";
|
|
295
302
|
|
|
296
303
|
// packages/cli/src/services.ts
|
|
297
304
|
import { writeFile, mkdir, readFile, readdir } from "fs/promises";
|
|
@@ -308,7 +315,8 @@ var defaultFileSystem = {
|
|
|
308
315
|
var defaultPrompts = {
|
|
309
316
|
input: prompts.input,
|
|
310
317
|
confirm: prompts.confirm,
|
|
311
|
-
checkbox: prompts.checkbox
|
|
318
|
+
checkbox: prompts.checkbox,
|
|
319
|
+
select: prompts.select
|
|
312
320
|
};
|
|
313
321
|
var createDefaultServices = () => ({
|
|
314
322
|
fs: defaultFileSystem,
|
|
@@ -378,6 +386,13 @@ var ConsoleOutput = {
|
|
|
378
386
|
if (isQuiet()) return;
|
|
379
387
|
console.log(chalk.yellow(` \u26A0 ${message}`));
|
|
380
388
|
},
|
|
389
|
+
/**
|
|
390
|
+
* Print a skipped file message.
|
|
391
|
+
*/
|
|
392
|
+
skipped(message) {
|
|
393
|
+
if (isQuiet()) return;
|
|
394
|
+
console.log(chalk.yellow(` \u2298 ${message}`));
|
|
395
|
+
},
|
|
381
396
|
/**
|
|
382
397
|
* Print an info message.
|
|
383
398
|
*/
|
|
@@ -680,9 +695,114 @@ function formatDetectionResults(detection) {
|
|
|
680
695
|
return lines;
|
|
681
696
|
}
|
|
682
697
|
|
|
698
|
+
// packages/cli/src/prettier/loader.ts
|
|
699
|
+
import { existsSync as existsSync2 } from "fs";
|
|
700
|
+
import { readFile as readFile2 } from "fs/promises";
|
|
701
|
+
import { join as join2, dirname, resolve } from "path";
|
|
702
|
+
import { parse as parseYaml } from "yaml";
|
|
703
|
+
var PRETTIER_CONFIG_FILES = [
|
|
704
|
+
".prettierrc",
|
|
705
|
+
".prettierrc.json",
|
|
706
|
+
".prettierrc.yaml",
|
|
707
|
+
".prettierrc.yml"
|
|
708
|
+
];
|
|
709
|
+
function findPrettierConfig(startDir = process.cwd()) {
|
|
710
|
+
let currentDir = resolve(startDir);
|
|
711
|
+
const root2 = dirname(currentDir);
|
|
712
|
+
while (currentDir !== root2) {
|
|
713
|
+
for (const configFile of PRETTIER_CONFIG_FILES) {
|
|
714
|
+
const configPath = join2(currentDir, configFile);
|
|
715
|
+
if (existsSync2(configPath)) {
|
|
716
|
+
return configPath;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
currentDir = dirname(currentDir);
|
|
720
|
+
}
|
|
721
|
+
for (const configFile of PRETTIER_CONFIG_FILES) {
|
|
722
|
+
const configPath = join2(currentDir, configFile);
|
|
723
|
+
if (existsSync2(configPath)) {
|
|
724
|
+
return configPath;
|
|
725
|
+
}
|
|
726
|
+
}
|
|
727
|
+
return null;
|
|
728
|
+
}
|
|
729
|
+
async function loadPrettierConfig(configPath) {
|
|
730
|
+
try {
|
|
731
|
+
const content = await readFile2(configPath, "utf-8");
|
|
732
|
+
const isYaml = configPath.endsWith(".yaml") || configPath.endsWith(".yml");
|
|
733
|
+
let parsed;
|
|
734
|
+
if (isYaml || configPath.endsWith(".prettierrc")) {
|
|
735
|
+
try {
|
|
736
|
+
parsed = parseYaml(content);
|
|
737
|
+
} catch {
|
|
738
|
+
parsed = JSON.parse(content);
|
|
739
|
+
}
|
|
740
|
+
} else {
|
|
741
|
+
parsed = JSON.parse(content);
|
|
742
|
+
}
|
|
743
|
+
if (!parsed || typeof parsed !== "object") {
|
|
744
|
+
return null;
|
|
745
|
+
}
|
|
746
|
+
const config = parsed;
|
|
747
|
+
const result = {};
|
|
748
|
+
if (typeof config["proseWrap"] === "string") {
|
|
749
|
+
const proseWrap = config["proseWrap"];
|
|
750
|
+
if (proseWrap === "always" || proseWrap === "never" || proseWrap === "preserve") {
|
|
751
|
+
result.proseWrap = proseWrap;
|
|
752
|
+
}
|
|
753
|
+
}
|
|
754
|
+
if (typeof config["tabWidth"] === "number") {
|
|
755
|
+
result.tabWidth = config["tabWidth"];
|
|
756
|
+
}
|
|
757
|
+
if (typeof config["printWidth"] === "number") {
|
|
758
|
+
result.printWidth = config["printWidth"];
|
|
759
|
+
}
|
|
760
|
+
return result;
|
|
761
|
+
} catch {
|
|
762
|
+
return null;
|
|
763
|
+
}
|
|
764
|
+
}
|
|
765
|
+
async function resolvePrettierOptions(config, basePath = process.cwd()) {
|
|
766
|
+
const formatting = config?.formatting;
|
|
767
|
+
if (!formatting) {
|
|
768
|
+
return { ...DEFAULT_PRETTIER_OPTIONS };
|
|
769
|
+
}
|
|
770
|
+
const result = { ...DEFAULT_PRETTIER_OPTIONS };
|
|
771
|
+
const prettier = formatting.prettier;
|
|
772
|
+
if (prettier === true) {
|
|
773
|
+
const configPath = findPrettierConfig(basePath);
|
|
774
|
+
if (configPath) {
|
|
775
|
+
const loadedOptions = await loadPrettierConfig(configPath);
|
|
776
|
+
if (loadedOptions) {
|
|
777
|
+
Object.assign(result, loadedOptions);
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
} else if (typeof prettier === "string") {
|
|
781
|
+
const configPath = resolve(basePath, prettier);
|
|
782
|
+
if (existsSync2(configPath)) {
|
|
783
|
+
const loadedOptions = await loadPrettierConfig(configPath);
|
|
784
|
+
if (loadedOptions) {
|
|
785
|
+
Object.assign(result, loadedOptions);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
} else if (prettier && typeof prettier === "object") {
|
|
789
|
+
Object.assign(result, prettier);
|
|
790
|
+
}
|
|
791
|
+
if (formatting.proseWrap !== void 0) {
|
|
792
|
+
result.proseWrap = formatting.proseWrap;
|
|
793
|
+
}
|
|
794
|
+
if (formatting.tabWidth !== void 0) {
|
|
795
|
+
result.tabWidth = formatting.tabWidth;
|
|
796
|
+
}
|
|
797
|
+
if (formatting.printWidth !== void 0) {
|
|
798
|
+
result.printWidth = formatting.printWidth;
|
|
799
|
+
}
|
|
800
|
+
return result;
|
|
801
|
+
}
|
|
802
|
+
|
|
683
803
|
// packages/cli/src/commands/init.ts
|
|
684
804
|
var __filename = fileURLToPath(import.meta.url);
|
|
685
|
-
var __dirname =
|
|
805
|
+
var __dirname = dirname2(__filename);
|
|
686
806
|
async function initCommand(options, services = createDefaultServices()) {
|
|
687
807
|
const { fs: fs4 } = services;
|
|
688
808
|
if (fs4.existsSync("promptscript.yaml") && !options.force) {
|
|
@@ -693,7 +813,14 @@ async function initCommand(options, services = createDefaultServices()) {
|
|
|
693
813
|
try {
|
|
694
814
|
const projectInfo = await detectProject(services);
|
|
695
815
|
const aiToolsDetection = await detectAITools(services);
|
|
696
|
-
const
|
|
816
|
+
const prettierConfigPath = findPrettierConfig(process.cwd());
|
|
817
|
+
const config = await resolveConfig(
|
|
818
|
+
options,
|
|
819
|
+
projectInfo,
|
|
820
|
+
aiToolsDetection,
|
|
821
|
+
prettierConfigPath,
|
|
822
|
+
services
|
|
823
|
+
);
|
|
697
824
|
const spinner = createSpinner("Creating PromptScript configuration...").start();
|
|
698
825
|
await fs4.mkdir(".promptscript", { recursive: true });
|
|
699
826
|
const configContent = generateConfig(config);
|
|
@@ -716,6 +843,14 @@ async function initCommand(options, services = createDefaultServices()) {
|
|
|
716
843
|
ConsoleOutput.muted(` Registry: ${config.registry}`);
|
|
717
844
|
}
|
|
718
845
|
ConsoleOutput.newline();
|
|
846
|
+
if (config.prettierConfigPath) {
|
|
847
|
+
ConsoleOutput.info(`Prettier config detected: ${config.prettierConfigPath}`);
|
|
848
|
+
ConsoleOutput.muted(" Output formatting will respect your Prettier settings");
|
|
849
|
+
} else {
|
|
850
|
+
ConsoleOutput.muted("No Prettier config found");
|
|
851
|
+
ConsoleOutput.muted(" Default formatting options added to config (tabWidth: 2)");
|
|
852
|
+
}
|
|
853
|
+
ConsoleOutput.newline();
|
|
719
854
|
console.log("Next steps:");
|
|
720
855
|
ConsoleOutput.muted("1. Edit .promptscript/project.prs to customize your AI instructions");
|
|
721
856
|
ConsoleOutput.muted("2. Run: prs compile");
|
|
@@ -729,14 +864,15 @@ async function initCommand(options, services = createDefaultServices()) {
|
|
|
729
864
|
process.exit(1);
|
|
730
865
|
}
|
|
731
866
|
}
|
|
732
|
-
async function resolveConfig(options, projectInfo, aiToolsDetection, services) {
|
|
867
|
+
async function resolveConfig(options, projectInfo, aiToolsDetection, prettierConfigPath, services) {
|
|
733
868
|
if (options.yes) {
|
|
734
869
|
return {
|
|
735
870
|
projectId: options.name ?? projectInfo.name,
|
|
736
871
|
team: options.team,
|
|
737
872
|
inherit: options.inherit,
|
|
738
873
|
registry: options.registry ?? "./registry",
|
|
739
|
-
targets: options.targets ?? getSuggestedTargets(aiToolsDetection)
|
|
874
|
+
targets: options.targets ?? getSuggestedTargets(aiToolsDetection),
|
|
875
|
+
prettierConfigPath
|
|
740
876
|
};
|
|
741
877
|
}
|
|
742
878
|
if (!options.interactive && options.name && options.targets) {
|
|
@@ -745,12 +881,19 @@ async function resolveConfig(options, projectInfo, aiToolsDetection, services) {
|
|
|
745
881
|
team: options.team,
|
|
746
882
|
inherit: options.inherit,
|
|
747
883
|
registry: options.registry,
|
|
748
|
-
targets: options.targets
|
|
884
|
+
targets: options.targets,
|
|
885
|
+
prettierConfigPath
|
|
749
886
|
};
|
|
750
887
|
}
|
|
751
|
-
return await runInteractivePrompts(
|
|
888
|
+
return await runInteractivePrompts(
|
|
889
|
+
options,
|
|
890
|
+
projectInfo,
|
|
891
|
+
aiToolsDetection,
|
|
892
|
+
prettierConfigPath,
|
|
893
|
+
services
|
|
894
|
+
);
|
|
752
895
|
}
|
|
753
|
-
async function runInteractivePrompts(options, projectInfo, aiToolsDetection, services) {
|
|
896
|
+
async function runInteractivePrompts(options, projectInfo, aiToolsDetection, prettierConfigPath, services) {
|
|
754
897
|
const { prompts: prompts2 } = services;
|
|
755
898
|
ConsoleOutput.newline();
|
|
756
899
|
console.log("\u{1F680} PromptScript Setup");
|
|
@@ -768,6 +911,9 @@ async function runInteractivePrompts(options, projectInfo, aiToolsDetection, ser
|
|
|
768
911
|
for (const line of detectionLines) {
|
|
769
912
|
ConsoleOutput.muted(line);
|
|
770
913
|
}
|
|
914
|
+
if (prettierConfigPath) {
|
|
915
|
+
ConsoleOutput.muted(`Prettier: ${prettierConfigPath}`);
|
|
916
|
+
}
|
|
771
917
|
ConsoleOutput.newline();
|
|
772
918
|
const projectId = await prompts2.input({
|
|
773
919
|
message: "Project name:",
|
|
@@ -829,7 +975,8 @@ async function runInteractivePrompts(options, projectInfo, aiToolsDetection, ser
|
|
|
829
975
|
team,
|
|
830
976
|
inherit,
|
|
831
977
|
registry,
|
|
832
|
-
targets
|
|
978
|
+
targets,
|
|
979
|
+
prettierConfigPath
|
|
833
980
|
};
|
|
834
981
|
}
|
|
835
982
|
function formatTargetName(target) {
|
|
@@ -862,7 +1009,18 @@ function generateConfig(config) {
|
|
|
862
1009
|
for (const target of config.targets) {
|
|
863
1010
|
lines.push(` - ${target}`);
|
|
864
1011
|
}
|
|
865
|
-
lines.push("", "validation:", " rules:", " empty-block: warn"
|
|
1012
|
+
lines.push("", "validation:", " rules:", " empty-block: warn");
|
|
1013
|
+
lines.push("");
|
|
1014
|
+
if (config.prettierConfigPath) {
|
|
1015
|
+
lines.push("formatting:", " prettier: true # Auto-detected from project");
|
|
1016
|
+
} else {
|
|
1017
|
+
lines.push(
|
|
1018
|
+
"formatting:",
|
|
1019
|
+
" tabWidth: 2",
|
|
1020
|
+
" proseWrap: preserve # 'always' | 'never' | 'preserve'"
|
|
1021
|
+
);
|
|
1022
|
+
}
|
|
1023
|
+
lines.push("");
|
|
866
1024
|
return lines.join("\n");
|
|
867
1025
|
}
|
|
868
1026
|
function generateProjectPs(config, projectInfo) {
|
|
@@ -912,15 +1070,15 @@ ${frameworksLine}
|
|
|
912
1070
|
}
|
|
913
1071
|
|
|
914
1072
|
// packages/cli/src/commands/compile.ts
|
|
915
|
-
import { resolve as
|
|
916
|
-
import { writeFile as writeFile2, mkdir as mkdir2 } from "fs/promises";
|
|
917
|
-
import { existsSync as
|
|
1073
|
+
import { resolve as resolve4, dirname as dirname5 } from "path";
|
|
1074
|
+
import { writeFile as writeFile2, mkdir as mkdir2, readFile as readFile6 } from "fs/promises";
|
|
1075
|
+
import { existsSync as existsSync7 } from "fs";
|
|
918
1076
|
import chokidar from "chokidar";
|
|
919
1077
|
|
|
920
1078
|
// packages/cli/src/config/loader.ts
|
|
921
|
-
import { readFile as
|
|
922
|
-
import { existsSync as
|
|
923
|
-
import { parse as
|
|
1079
|
+
import { readFile as readFile3 } from "fs/promises";
|
|
1080
|
+
import { existsSync as existsSync3 } from "fs";
|
|
1081
|
+
import { parse as parseYaml2 } from "yaml";
|
|
924
1082
|
var CONFIG_FILES = [
|
|
925
1083
|
"promptscript.yaml",
|
|
926
1084
|
"promptscript.yml",
|
|
@@ -943,14 +1101,14 @@ function interpolateEnvVars(text) {
|
|
|
943
1101
|
}
|
|
944
1102
|
function findConfigFile(customPath) {
|
|
945
1103
|
if (customPath) {
|
|
946
|
-
return
|
|
1104
|
+
return existsSync3(customPath) ? customPath : null;
|
|
947
1105
|
}
|
|
948
1106
|
const envConfig = process.env["PROMPTSCRIPT_CONFIG"];
|
|
949
|
-
if (envConfig &&
|
|
1107
|
+
if (envConfig && existsSync3(envConfig)) {
|
|
950
1108
|
return envConfig;
|
|
951
1109
|
}
|
|
952
1110
|
for (const file of CONFIG_FILES) {
|
|
953
|
-
if (
|
|
1111
|
+
if (existsSync3(file)) {
|
|
954
1112
|
return file;
|
|
955
1113
|
}
|
|
956
1114
|
}
|
|
@@ -964,10 +1122,10 @@ async function loadConfig(customPath) {
|
|
|
964
1122
|
}
|
|
965
1123
|
throw new Error("No PromptScript configuration found. Run: prs init");
|
|
966
1124
|
}
|
|
967
|
-
let content = await
|
|
1125
|
+
let content = await readFile3(configFile, "utf-8");
|
|
968
1126
|
content = interpolateEnvVars(content);
|
|
969
1127
|
try {
|
|
970
|
-
return
|
|
1128
|
+
return parseYaml2(content);
|
|
971
1129
|
} catch (error) {
|
|
972
1130
|
const message = error instanceof Error ? error.message : "Unknown parse error";
|
|
973
1131
|
throw new Error(`Failed to parse ${configFile}: ${message}`);
|
|
@@ -977,7 +1135,17 @@ async function loadConfig(customPath) {
|
|
|
977
1135
|
// packages/formatters/src/convention-renderer.ts
|
|
978
1136
|
var ConventionRenderer = class {
|
|
979
1137
|
convention;
|
|
980
|
-
|
|
1138
|
+
prettierOptions;
|
|
1139
|
+
constructor(conventionOrOptions = "xml") {
|
|
1140
|
+
let convention;
|
|
1141
|
+
let prettier;
|
|
1142
|
+
if (typeof conventionOrOptions === "object" && ("convention" in conventionOrOptions || "prettier" in conventionOrOptions)) {
|
|
1143
|
+
const opts = conventionOrOptions;
|
|
1144
|
+
convention = opts.convention ?? "xml";
|
|
1145
|
+
prettier = opts.prettier;
|
|
1146
|
+
} else {
|
|
1147
|
+
convention = conventionOrOptions;
|
|
1148
|
+
}
|
|
981
1149
|
if (typeof convention === "string") {
|
|
982
1150
|
if (isBuiltInConvention(convention)) {
|
|
983
1151
|
this.convention = BUILT_IN_CONVENTIONS[convention];
|
|
@@ -989,6 +1157,16 @@ var ConventionRenderer = class {
|
|
|
989
1157
|
} else {
|
|
990
1158
|
this.convention = convention;
|
|
991
1159
|
}
|
|
1160
|
+
this.prettierOptions = {
|
|
1161
|
+
...DEFAULT_PRETTIER_OPTIONS,
|
|
1162
|
+
...prettier
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
/**
|
|
1166
|
+
* Get the current Prettier options.
|
|
1167
|
+
*/
|
|
1168
|
+
getPrettierOptions() {
|
|
1169
|
+
return this.prettierOptions;
|
|
992
1170
|
}
|
|
993
1171
|
/**
|
|
994
1172
|
* Get the current convention.
|
|
@@ -1008,16 +1186,24 @@ var ConventionRenderer = class {
|
|
|
1008
1186
|
const transformedName = this.transformName(name, renderer.nameTransform);
|
|
1009
1187
|
const start = this.applyTemplate(renderer.start, { name: transformedName, level });
|
|
1010
1188
|
const end = renderer.end ? this.applyTemplate(renderer.end, { name: transformedName, level }) : "";
|
|
1011
|
-
|
|
1189
|
+
let trimmedContent = content.trim();
|
|
1012
1190
|
if (!trimmedContent) {
|
|
1013
1191
|
return end ? `${start}
|
|
1014
1192
|
${end}` : start;
|
|
1015
1193
|
}
|
|
1194
|
+
if (this.convention.name === "markdown") {
|
|
1195
|
+
trimmedContent = this.escapeMarkdownSpecialChars(trimmedContent);
|
|
1196
|
+
}
|
|
1016
1197
|
const indentedContent = this.indentContent(trimmedContent, renderer, level);
|
|
1017
1198
|
if (end) {
|
|
1018
1199
|
return `${start}
|
|
1019
1200
|
${indentedContent}
|
|
1020
1201
|
${end}`;
|
|
1202
|
+
}
|
|
1203
|
+
if (this.convention.name === "markdown") {
|
|
1204
|
+
return `${start}
|
|
1205
|
+
|
|
1206
|
+
${indentedContent}`;
|
|
1021
1207
|
}
|
|
1022
1208
|
return `${start}
|
|
1023
1209
|
${indentedContent}`;
|
|
@@ -1105,13 +1291,22 @@ ${this.convention.rootWrapper.end}`;
|
|
|
1105
1291
|
}
|
|
1106
1292
|
return result;
|
|
1107
1293
|
}
|
|
1294
|
+
/**
|
|
1295
|
+
* Escape markdown special characters for Prettier compatibility.
|
|
1296
|
+
* - Escapes __ to \_\_ (to avoid emphasis)
|
|
1297
|
+
* - Escapes /* to /\* (to avoid glob patterns being interpreted)
|
|
1298
|
+
*/
|
|
1299
|
+
escapeMarkdownSpecialChars(content) {
|
|
1300
|
+
return content.replace(/__/g, "\\_\\_").replace(/\/\*/g, "/\\*");
|
|
1301
|
+
}
|
|
1108
1302
|
indentContent(content, renderer, level) {
|
|
1109
1303
|
const indent = renderer.indent ?? "";
|
|
1110
1304
|
if (!indent) {
|
|
1111
1305
|
return content;
|
|
1112
1306
|
}
|
|
1113
1307
|
if (this.convention.name === "xml") {
|
|
1114
|
-
const
|
|
1308
|
+
const indentStr = " ".repeat(this.prettierOptions.tabWidth);
|
|
1309
|
+
const baseIndent = indentStr.repeat(level);
|
|
1115
1310
|
return content.split("\n").map((line) => line.trim() ? `${baseIndent}${line}` : line).join("\n");
|
|
1116
1311
|
}
|
|
1117
1312
|
return content;
|
|
@@ -1130,7 +1325,19 @@ var BaseFormatter = class {
|
|
|
1130
1325
|
*/
|
|
1131
1326
|
createRenderer(options) {
|
|
1132
1327
|
const convention = options?.convention ?? this.defaultConvention;
|
|
1133
|
-
return new ConventionRenderer(
|
|
1328
|
+
return new ConventionRenderer({
|
|
1329
|
+
convention,
|
|
1330
|
+
prettier: options?.prettier
|
|
1331
|
+
});
|
|
1332
|
+
}
|
|
1333
|
+
/**
|
|
1334
|
+
* Get resolved Prettier options, merging provided options with defaults.
|
|
1335
|
+
*/
|
|
1336
|
+
getPrettierOptions(options) {
|
|
1337
|
+
return {
|
|
1338
|
+
...DEFAULT_PRETTIER_OPTIONS,
|
|
1339
|
+
...options?.prettier
|
|
1340
|
+
};
|
|
1134
1341
|
}
|
|
1135
1342
|
/**
|
|
1136
1343
|
* Get the output path, respecting options override.
|
|
@@ -1183,6 +1390,14 @@ var BaseFormatter = class {
|
|
|
1183
1390
|
return {};
|
|
1184
1391
|
}
|
|
1185
1392
|
}
|
|
1393
|
+
/**
|
|
1394
|
+
* Format standards list from array of values (pass-through).
|
|
1395
|
+
* Returns array of strings for rendering as bullet list.
|
|
1396
|
+
*/
|
|
1397
|
+
formatStandardsList(items) {
|
|
1398
|
+
if (!Array.isArray(items)) return [];
|
|
1399
|
+
return items.map((item) => this.valueToString(item)).filter((s) => s.length > 0);
|
|
1400
|
+
}
|
|
1186
1401
|
/**
|
|
1187
1402
|
* Format an array as comma-separated string.
|
|
1188
1403
|
*/
|
|
@@ -1248,6 +1463,136 @@ var BaseFormatter = class {
|
|
|
1248
1463
|
const endPos = endCodeBlock + 3;
|
|
1249
1464
|
return text.substring(headerIndex, endPos);
|
|
1250
1465
|
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Normalize markdown content to match Prettier formatting.
|
|
1468
|
+
* - Strips common leading indentation from lines
|
|
1469
|
+
* - Trims trailing whitespace from lines
|
|
1470
|
+
* - Normalizes markdown table formatting
|
|
1471
|
+
* - Adds blank lines before lists when preceded by text
|
|
1472
|
+
* - Escapes markdown special characters in paths
|
|
1473
|
+
*/
|
|
1474
|
+
normalizeMarkdownForPrettier(content) {
|
|
1475
|
+
const lines = content.split("\n");
|
|
1476
|
+
let minIndent = Infinity;
|
|
1477
|
+
let inCodeBlock = false;
|
|
1478
|
+
for (const line of lines) {
|
|
1479
|
+
const trimmed = line.trimEnd();
|
|
1480
|
+
if (trimmed.startsWith("```")) {
|
|
1481
|
+
inCodeBlock = !inCodeBlock;
|
|
1482
|
+
continue;
|
|
1483
|
+
}
|
|
1484
|
+
if (inCodeBlock) continue;
|
|
1485
|
+
if (trimmed.length === 0) continue;
|
|
1486
|
+
const match = line.match(/^(\s*)/);
|
|
1487
|
+
const leadingSpaces = match?.[1]?.length ?? 0;
|
|
1488
|
+
minIndent = Math.min(minIndent, leadingSpaces);
|
|
1489
|
+
}
|
|
1490
|
+
if (minIndent === Infinity) minIndent = 0;
|
|
1491
|
+
const result = [];
|
|
1492
|
+
let inTable = false;
|
|
1493
|
+
let tableLines = [];
|
|
1494
|
+
inCodeBlock = false;
|
|
1495
|
+
for (const line of lines) {
|
|
1496
|
+
const trimmedLine = line.trimEnd();
|
|
1497
|
+
if (trimmedLine.trimStart().startsWith("```")) {
|
|
1498
|
+
inCodeBlock = !inCodeBlock;
|
|
1499
|
+
}
|
|
1500
|
+
const unindentedLine = minIndent > 0 ? trimmedLine.slice(minIndent) : trimmedLine;
|
|
1501
|
+
if (inCodeBlock || unindentedLine.startsWith("```")) {
|
|
1502
|
+
result.push(unindentedLine);
|
|
1503
|
+
continue;
|
|
1504
|
+
}
|
|
1505
|
+
let processedLine = unindentedLine;
|
|
1506
|
+
processedLine = processedLine.replace(/__([^_]+)__/g, "\\_\\_$1\\_\\_");
|
|
1507
|
+
processedLine = processedLine.replace(/\/\*/g, "/\\*");
|
|
1508
|
+
if (processedLine.trimStart().startsWith("|") && processedLine.trimEnd().endsWith("|")) {
|
|
1509
|
+
inTable = true;
|
|
1510
|
+
tableLines.push(processedLine.trim());
|
|
1511
|
+
} else {
|
|
1512
|
+
if (inTable && tableLines.length > 0) {
|
|
1513
|
+
result.push(...this.formatMarkdownTable(tableLines));
|
|
1514
|
+
tableLines = [];
|
|
1515
|
+
inTable = false;
|
|
1516
|
+
}
|
|
1517
|
+
const prevLine = result.length > 0 ? result[result.length - 1] : "";
|
|
1518
|
+
const isListItem = processedLine.trimStart().startsWith("- ");
|
|
1519
|
+
if (isListItem && prevLine && !prevLine.trimStart().startsWith("- ")) {
|
|
1520
|
+
result.push("");
|
|
1521
|
+
}
|
|
1522
|
+
result.push(processedLine);
|
|
1523
|
+
}
|
|
1524
|
+
}
|
|
1525
|
+
if (tableLines.length > 0) {
|
|
1526
|
+
result.push(...this.formatMarkdownTable(tableLines));
|
|
1527
|
+
}
|
|
1528
|
+
return result.join("\n");
|
|
1529
|
+
}
|
|
1530
|
+
/**
|
|
1531
|
+
* Strip all leading indentation from markdown content.
|
|
1532
|
+
* Used for AGENTS.md where content from multiple sources has inconsistent indentation.
|
|
1533
|
+
* Preserves indentation inside code blocks.
|
|
1534
|
+
*/
|
|
1535
|
+
stripAllIndent(content) {
|
|
1536
|
+
const lines = content.split("\n");
|
|
1537
|
+
const result = [];
|
|
1538
|
+
let inCodeBlock = false;
|
|
1539
|
+
for (const line of lines) {
|
|
1540
|
+
const trimmedEnd = line.trimEnd();
|
|
1541
|
+
if (trimmedEnd.trimStart().startsWith("```")) {
|
|
1542
|
+
if (!inCodeBlock) {
|
|
1543
|
+
const prevLine2 = result.length > 0 ? result[result.length - 1] : "";
|
|
1544
|
+
if (prevLine2 && prevLine2.trim()) {
|
|
1545
|
+
result.push("");
|
|
1546
|
+
}
|
|
1547
|
+
}
|
|
1548
|
+
inCodeBlock = !inCodeBlock;
|
|
1549
|
+
result.push(trimmedEnd.trimStart());
|
|
1550
|
+
continue;
|
|
1551
|
+
}
|
|
1552
|
+
if (inCodeBlock) {
|
|
1553
|
+
result.push(trimmedEnd);
|
|
1554
|
+
continue;
|
|
1555
|
+
}
|
|
1556
|
+
let stripped = trimmedEnd.trimStart();
|
|
1557
|
+
stripped = stripped.replace(/__/g, "\\_\\_");
|
|
1558
|
+
stripped = stripped.replace(/\/\*/g, "/\\*");
|
|
1559
|
+
const prevLine = result.length > 0 ? result[result.length - 1] : "";
|
|
1560
|
+
if (stripped.startsWith("- ") && prevLine && !prevLine.startsWith("- ")) {
|
|
1561
|
+
result.push("");
|
|
1562
|
+
}
|
|
1563
|
+
result.push(stripped);
|
|
1564
|
+
}
|
|
1565
|
+
return result.join("\n");
|
|
1566
|
+
}
|
|
1567
|
+
/**
|
|
1568
|
+
* Format a markdown table to match Prettier output.
|
|
1569
|
+
* Prettier removes trailing whitespace from cells.
|
|
1570
|
+
*/
|
|
1571
|
+
formatMarkdownTable(tableLines) {
|
|
1572
|
+
if (tableLines.length === 0) return [];
|
|
1573
|
+
const rows = tableLines.map(
|
|
1574
|
+
(line) => line.split("|").slice(1, -1).map((cell) => cell.trim())
|
|
1575
|
+
);
|
|
1576
|
+
const colCount = rows[0]?.length ?? 0;
|
|
1577
|
+
const colWidths = new Array(colCount).fill(0);
|
|
1578
|
+
for (const row of rows) {
|
|
1579
|
+
for (let i = 0; i < row.length; i++) {
|
|
1580
|
+
const cell = row[i] ?? "";
|
|
1581
|
+
const width = cell.match(/^-+$/) ? 3 : cell.length;
|
|
1582
|
+
colWidths[i] = Math.max(colWidths[i] ?? 0, width);
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
return rows.map((row) => {
|
|
1586
|
+
const cells = row.map((cell, colIndex) => {
|
|
1587
|
+
const width = colWidths[colIndex] ?? 0;
|
|
1588
|
+
if (cell.match(/^-+$/)) {
|
|
1589
|
+
return "-".repeat(width);
|
|
1590
|
+
}
|
|
1591
|
+
return cell.padEnd(width);
|
|
1592
|
+
});
|
|
1593
|
+
return "| " + cells.join(" | ") + " |";
|
|
1594
|
+
});
|
|
1595
|
+
}
|
|
1251
1596
|
};
|
|
1252
1597
|
|
|
1253
1598
|
// packages/formatters/src/registry.ts
|
|
@@ -1327,6 +1672,51 @@ var GITHUB_VERSIONS = {
|
|
|
1327
1672
|
outputPath: ".github/copilot-instructions.md"
|
|
1328
1673
|
}
|
|
1329
1674
|
};
|
|
1675
|
+
var TOOL_NAME_MAPPING = {
|
|
1676
|
+
// Read tools
|
|
1677
|
+
Read: "read",
|
|
1678
|
+
NotebookRead: "read",
|
|
1679
|
+
// Edit tools
|
|
1680
|
+
Edit: "edit",
|
|
1681
|
+
MultiEdit: "edit",
|
|
1682
|
+
Write: "edit",
|
|
1683
|
+
NotebookEdit: "edit",
|
|
1684
|
+
// Search tools
|
|
1685
|
+
Grep: "search",
|
|
1686
|
+
Glob: "search",
|
|
1687
|
+
// Execute tools
|
|
1688
|
+
Bash: "execute",
|
|
1689
|
+
// Web tools
|
|
1690
|
+
WebFetch: "web",
|
|
1691
|
+
WebSearch: "web",
|
|
1692
|
+
// Agent tools
|
|
1693
|
+
Task: "agent",
|
|
1694
|
+
// Todo tools
|
|
1695
|
+
TodoWrite: "todo",
|
|
1696
|
+
TodoRead: "todo"
|
|
1697
|
+
};
|
|
1698
|
+
var MODEL_NAME_MAPPING = {
|
|
1699
|
+
// Claude models - default aliases map to latest versions (4.5)
|
|
1700
|
+
sonnet: "Claude Sonnet 4.5",
|
|
1701
|
+
opus: "Claude Opus 4.5",
|
|
1702
|
+
haiku: "Claude Haiku 4.5",
|
|
1703
|
+
// Explicit version mappings
|
|
1704
|
+
"sonnet-4": "Claude Sonnet 4",
|
|
1705
|
+
"sonnet-4.5": "Claude Sonnet 4.5",
|
|
1706
|
+
"opus-4": "Claude Opus 4",
|
|
1707
|
+
"opus-4.5": "Claude Opus 4.5",
|
|
1708
|
+
"haiku-4": "Claude Haiku 4",
|
|
1709
|
+
"haiku-4.5": "Claude Haiku 4.5",
|
|
1710
|
+
// OpenAI models (pass through if already in correct format)
|
|
1711
|
+
"gpt-4o": "GPT-4o",
|
|
1712
|
+
"gpt-4.1": "GPT-4.1",
|
|
1713
|
+
"gpt-5": "GPT-5",
|
|
1714
|
+
"gpt-5-mini": "GPT-5 mini",
|
|
1715
|
+
// Special values
|
|
1716
|
+
inherit: "",
|
|
1717
|
+
// Empty string means omit the model property
|
|
1718
|
+
auto: "Auto"
|
|
1719
|
+
};
|
|
1330
1720
|
var GitHubFormatter = class extends BaseFormatter {
|
|
1331
1721
|
name = "github";
|
|
1332
1722
|
outputPath = ".github/copilot-instructions.md";
|
|
@@ -1368,7 +1758,7 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1368
1758
|
this.addCommonSections(ast, renderer, sections);
|
|
1369
1759
|
return {
|
|
1370
1760
|
path: this.getOutputPath(options),
|
|
1371
|
-
content: sections.join("\n\n")
|
|
1761
|
+
content: sections.join("\n\n") + "\n"
|
|
1372
1762
|
};
|
|
1373
1763
|
}
|
|
1374
1764
|
// ============================================================
|
|
@@ -1392,7 +1782,7 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1392
1782
|
this.addCommonSections(ast, renderer, sections);
|
|
1393
1783
|
return {
|
|
1394
1784
|
path: this.getOutputPath(options),
|
|
1395
|
-
content: sections.join("\n\n"),
|
|
1785
|
+
content: sections.join("\n\n") + "\n",
|
|
1396
1786
|
additionalFiles: additionalFiles.length > 0 ? additionalFiles : void 0
|
|
1397
1787
|
};
|
|
1398
1788
|
}
|
|
@@ -1429,7 +1819,7 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1429
1819
|
this.addCommonSections(ast, renderer, sections);
|
|
1430
1820
|
return {
|
|
1431
1821
|
path: this.getOutputPath(options),
|
|
1432
|
-
content: sections.join("\n\n"),
|
|
1822
|
+
content: sections.join("\n\n") + "\n",
|
|
1433
1823
|
additionalFiles: additionalFiles.length > 0 ? additionalFiles : void 0
|
|
1434
1824
|
};
|
|
1435
1825
|
}
|
|
@@ -1600,10 +1990,9 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1600
1990
|
if (config.mode === "agent") {
|
|
1601
1991
|
lines.push("mode: agent");
|
|
1602
1992
|
if (config.tools && config.tools.length > 0) {
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
}
|
|
1993
|
+
const mappedTools = config.tools.map((tool) => TOOL_NAME_MAPPING[tool] ?? tool.toLowerCase()).filter((t, i, arr) => arr.indexOf(t) === i);
|
|
1994
|
+
const toolsArray = mappedTools.map((t) => `'${t}'`).join(", ");
|
|
1995
|
+
lines.push(`tools: [${toolsArray}]`);
|
|
1607
1996
|
}
|
|
1608
1997
|
}
|
|
1609
1998
|
lines.push("---");
|
|
@@ -1646,19 +2035,21 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1646
2035
|
generateSkillFile(config) {
|
|
1647
2036
|
const lines = [];
|
|
1648
2037
|
lines.push("---");
|
|
1649
|
-
lines.push(`name:
|
|
1650
|
-
|
|
2038
|
+
lines.push(`name: '${config.name}'`);
|
|
2039
|
+
const descQuote = config.description.includes("'") ? '"' : "'";
|
|
2040
|
+
lines.push(`description: ${descQuote}${config.description}${descQuote}`);
|
|
1651
2041
|
if (config.disableModelInvocation) {
|
|
1652
2042
|
lines.push("disable-model-invocation: true");
|
|
1653
2043
|
}
|
|
1654
2044
|
lines.push("---");
|
|
1655
2045
|
lines.push("");
|
|
1656
2046
|
if (config.content) {
|
|
1657
|
-
|
|
2047
|
+
const normalizedContent = this.normalizeMarkdownForPrettier(config.content);
|
|
2048
|
+
lines.push(normalizedContent);
|
|
1658
2049
|
}
|
|
1659
2050
|
return {
|
|
1660
2051
|
path: `.github/skills/${config.name}/SKILL.md`,
|
|
1661
|
-
content: lines.join("\n")
|
|
2052
|
+
content: lines.join("\n") + "\n"
|
|
1662
2053
|
};
|
|
1663
2054
|
}
|
|
1664
2055
|
// ============================================================
|
|
@@ -1673,13 +2064,11 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1673
2064
|
const lines = [];
|
|
1674
2065
|
lines.push("# Agent Instructions");
|
|
1675
2066
|
lines.push("");
|
|
1676
|
-
lines.push("> Auto-generated by PromptScript");
|
|
1677
|
-
lines.push("");
|
|
1678
2067
|
const identityText = this.extractText(identity2.content);
|
|
1679
2068
|
if (identityText) {
|
|
1680
2069
|
lines.push("## Identity");
|
|
1681
2070
|
lines.push("");
|
|
1682
|
-
lines.push(identityText);
|
|
2071
|
+
lines.push(this.stripAllIndent(identityText));
|
|
1683
2072
|
lines.push("");
|
|
1684
2073
|
}
|
|
1685
2074
|
const context = this.findBlock(ast, "context");
|
|
@@ -1688,7 +2077,7 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1688
2077
|
if (contextText) {
|
|
1689
2078
|
lines.push("## Context");
|
|
1690
2079
|
lines.push("");
|
|
1691
|
-
lines.push(contextText);
|
|
2080
|
+
lines.push(this.stripAllIndent(contextText));
|
|
1692
2081
|
lines.push("");
|
|
1693
2082
|
}
|
|
1694
2083
|
}
|
|
@@ -1701,12 +2090,11 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1701
2090
|
for (const item of items) {
|
|
1702
2091
|
lines.push(`- ${item}`);
|
|
1703
2092
|
}
|
|
1704
|
-
lines.push("");
|
|
1705
2093
|
}
|
|
1706
2094
|
}
|
|
1707
2095
|
return {
|
|
1708
2096
|
path: "AGENTS.md",
|
|
1709
|
-
content: lines.join("\n")
|
|
2097
|
+
content: lines.join("\n") + "\n"
|
|
1710
2098
|
};
|
|
1711
2099
|
}
|
|
1712
2100
|
/**
|
|
@@ -1757,12 +2145,26 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1757
2145
|
return agents;
|
|
1758
2146
|
}
|
|
1759
2147
|
/**
|
|
1760
|
-
* Parse tools array from a Value.
|
|
2148
|
+
* Parse tools array from a Value and map to GitHub Copilot canonical names.
|
|
2149
|
+
*
|
|
2150
|
+
* @see https://docs.github.com/en/copilot/reference/custom-agents-configuration
|
|
1761
2151
|
*/
|
|
1762
2152
|
parseToolsArray(value) {
|
|
1763
2153
|
if (!value || !Array.isArray(value)) return void 0;
|
|
1764
|
-
const
|
|
1765
|
-
|
|
2154
|
+
const mapped = value.map((v) => this.valueToString(v)).filter((s) => s.length > 0).map((tool) => TOOL_NAME_MAPPING[tool] ?? tool.toLowerCase());
|
|
2155
|
+
const unique = [...new Set(mapped)];
|
|
2156
|
+
return unique.length > 0 ? unique : void 0;
|
|
2157
|
+
}
|
|
2158
|
+
/**
|
|
2159
|
+
* Map a model name from PromptScript/Claude Code format to GitHub Copilot format.
|
|
2160
|
+
*
|
|
2161
|
+
* @returns The mapped model name, or undefined if the model should be omitted (e.g., "inherit")
|
|
2162
|
+
*/
|
|
2163
|
+
mapModelName(model) {
|
|
2164
|
+
if (!model) return void 0;
|
|
2165
|
+
const mapped = MODEL_NAME_MAPPING[model.toLowerCase()];
|
|
2166
|
+
if (mapped === "") return void 0;
|
|
2167
|
+
return mapped ?? model;
|
|
1766
2168
|
}
|
|
1767
2169
|
/**
|
|
1768
2170
|
* Generate a .github/agents/<name>.md file.
|
|
@@ -1775,13 +2177,12 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1775
2177
|
lines.push(`name: ${config.name}`);
|
|
1776
2178
|
lines.push(`description: ${config.description}`);
|
|
1777
2179
|
if (config.tools && config.tools.length > 0) {
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
lines.push(` - ${tool}`);
|
|
1781
|
-
}
|
|
2180
|
+
const toolsArray = config.tools.map((t) => `'${t}'`).join(", ");
|
|
2181
|
+
lines.push(`tools: [${toolsArray}]`);
|
|
1782
2182
|
}
|
|
1783
|
-
|
|
1784
|
-
|
|
2183
|
+
const mappedModel = this.mapModelName(config.model);
|
|
2184
|
+
if (mappedModel) {
|
|
2185
|
+
lines.push(`model: ${mappedModel}`);
|
|
1785
2186
|
}
|
|
1786
2187
|
lines.push("---");
|
|
1787
2188
|
lines.push("");
|
|
@@ -1790,7 +2191,7 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1790
2191
|
}
|
|
1791
2192
|
return {
|
|
1792
2193
|
path: `.github/agents/${config.name}.md`,
|
|
1793
|
-
content: lines.join("\n")
|
|
2194
|
+
content: lines.join("\n") + "\n"
|
|
1794
2195
|
};
|
|
1795
2196
|
}
|
|
1796
2197
|
// ============================================================
|
|
@@ -1822,22 +2223,14 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1822
2223
|
const knowledge = this.knowledge(ast, renderer);
|
|
1823
2224
|
if (knowledge) sections.push(knowledge);
|
|
1824
2225
|
}
|
|
1825
|
-
header(
|
|
1826
|
-
|
|
1827
|
-
const syntax = this.getMetaField(ast, "syntax") ?? "0.0.0";
|
|
1828
|
-
return `# GitHub Copilot Instructions
|
|
1829
|
-
|
|
1830
|
-
> Auto-generated by PromptScript
|
|
1831
|
-
> Source: ${id} (syntax ${syntax})
|
|
1832
|
-
> Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
1833
|
-
>
|
|
1834
|
-
> **Do not edit manually**`;
|
|
2226
|
+
header(_ast) {
|
|
2227
|
+
return `# GitHub Copilot Instructions`;
|
|
1835
2228
|
}
|
|
1836
2229
|
project(ast, renderer) {
|
|
1837
2230
|
const identity2 = this.findBlock(ast, "identity");
|
|
1838
2231
|
if (!identity2) return null;
|
|
1839
2232
|
const content = this.extractText(identity2.content);
|
|
1840
|
-
return renderer.renderSection("project", content);
|
|
2233
|
+
return renderer.renderSection("project", this.stripAllIndent(content));
|
|
1841
2234
|
}
|
|
1842
2235
|
techStack(ast, renderer) {
|
|
1843
2236
|
const context = this.findBlock(ast, "context");
|
|
@@ -1875,50 +2268,30 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1875
2268
|
const archMatch = this.extractSectionWithCodeBlock(text, "## Architecture");
|
|
1876
2269
|
if (!archMatch) return null;
|
|
1877
2270
|
const content = archMatch.replace("## Architecture", "").trim();
|
|
1878
|
-
return renderer.renderSection("architecture", content);
|
|
2271
|
+
return renderer.renderSection("architecture", this.stripAllIndent(content));
|
|
1879
2272
|
}
|
|
1880
2273
|
codeStandards(ast, renderer) {
|
|
1881
2274
|
const standards = this.findBlock(ast, "standards");
|
|
1882
2275
|
if (!standards) return null;
|
|
1883
2276
|
const props = this.getProps(standards.content);
|
|
1884
2277
|
const subsections = [];
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
"
|
|
1890
|
-
|
|
1891
|
-
)
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
this.addStandardsSubsection(
|
|
1900
|
-
subsections,
|
|
1901
|
-
renderer,
|
|
1902
|
-
props["errors"],
|
|
1903
|
-
"error-handling",
|
|
1904
|
-
this.formatErrorStandards.bind(this)
|
|
1905
|
-
);
|
|
1906
|
-
this.addStandardsSubsection(
|
|
1907
|
-
subsections,
|
|
1908
|
-
renderer,
|
|
1909
|
-
props["testing"],
|
|
1910
|
-
"testing",
|
|
1911
|
-
this.formatTestingStandards.bind(this)
|
|
1912
|
-
);
|
|
1913
|
-
if (subsections.length === 0) return null;
|
|
1914
|
-
return renderer.renderSection("code-standards", subsections.join("\n"));
|
|
1915
|
-
}
|
|
1916
|
-
addStandardsSubsection(subsections, renderer, value, name, formatter) {
|
|
1917
|
-
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
1918
|
-
const items = formatter(value);
|
|
1919
|
-
if (items.length > 0) {
|
|
1920
|
-
subsections.push(renderer.renderSection(name, renderer.renderList(items), 2));
|
|
2278
|
+
const sectionMap = {
|
|
2279
|
+
typescript: "typescript",
|
|
2280
|
+
naming: "naming",
|
|
2281
|
+
errors: "error-handling",
|
|
2282
|
+
testing: "testing"
|
|
2283
|
+
};
|
|
2284
|
+
for (const [key, sectionName] of Object.entries(sectionMap)) {
|
|
2285
|
+
const value = props[key];
|
|
2286
|
+
if (Array.isArray(value)) {
|
|
2287
|
+
const items = this.formatStandardsList(value);
|
|
2288
|
+
if (items.length > 0) {
|
|
2289
|
+
subsections.push(renderer.renderSection(sectionName, renderer.renderList(items), 2));
|
|
2290
|
+
}
|
|
2291
|
+
}
|
|
1921
2292
|
}
|
|
2293
|
+
if (subsections.length === 0) return null;
|
|
2294
|
+
return renderer.renderSection("code-standards", subsections.join("\n\n"));
|
|
1922
2295
|
}
|
|
1923
2296
|
commands(ast, renderer) {
|
|
1924
2297
|
const knowledge = this.findBlock(ast, "knowledge");
|
|
@@ -1927,7 +2300,7 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1927
2300
|
const commandsMatch = this.extractSectionWithCodeBlock(text, "## Development Commands");
|
|
1928
2301
|
if (!commandsMatch) return null;
|
|
1929
2302
|
const content = commandsMatch.replace("## Development Commands", "").trim();
|
|
1930
|
-
return renderer.renderSection("commands", content);
|
|
2303
|
+
return renderer.renderSection("commands", this.stripAllIndent(content));
|
|
1931
2304
|
}
|
|
1932
2305
|
gitCommits(ast, renderer) {
|
|
1933
2306
|
const standards = this.findBlock(ast, "standards");
|
|
@@ -1978,7 +2351,7 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
1978
2351
|
subsections.push(renderer.renderSection("vite-vitest", `Vite root: ${value}`, 2));
|
|
1979
2352
|
}
|
|
1980
2353
|
if (subsections.length === 0) return null;
|
|
1981
|
-
return renderer.renderSection("configuration-files", subsections.join("\n"));
|
|
2354
|
+
return renderer.renderSection("configuration-files", subsections.join("\n\n"));
|
|
1982
2355
|
}
|
|
1983
2356
|
documentation(ast, renderer) {
|
|
1984
2357
|
const standards = this.findBlock(ast, "standards");
|
|
@@ -2014,8 +2387,11 @@ var GitHubFormatter = class extends BaseFormatter {
|
|
|
2014
2387
|
if (!postMatch) return null;
|
|
2015
2388
|
const intro = "After completing any code changes, run the following commands to ensure code quality:";
|
|
2016
2389
|
const content = postMatch.replace("## Post-Work Verification", "").trim();
|
|
2017
|
-
return renderer.renderSection(
|
|
2018
|
-
|
|
2390
|
+
return renderer.renderSection(
|
|
2391
|
+
"post-work-verification",
|
|
2392
|
+
`${intro}
|
|
2393
|
+
${this.stripAllIndent(content)}`
|
|
2394
|
+
);
|
|
2019
2395
|
}
|
|
2020
2396
|
restrictions(ast, renderer) {
|
|
2021
2397
|
const block = this.findBlock(ast, "restrictions");
|
|
@@ -2070,47 +2446,6 @@ ${content}`);
|
|
|
2070
2446
|
formatTechItem(arr) {
|
|
2071
2447
|
return arr.map(String).join(", ");
|
|
2072
2448
|
}
|
|
2073
|
-
formatStandardsObject(obj) {
|
|
2074
|
-
const items = [];
|
|
2075
|
-
if (obj["strictMode"]) items.push("Strict mode enabled, no `any` types");
|
|
2076
|
-
if (obj["useUnknown"]) items.push(`Use \`unknown\` ${this.valueToString(obj["useUnknown"])}`);
|
|
2077
|
-
if (obj["interfaces"])
|
|
2078
|
-
items.push(`Prefer \`interface\` ${this.valueToString(obj["interfaces"])}`);
|
|
2079
|
-
if (obj["types"]) items.push(`Use \`type\` ${this.valueToString(obj["types"])}`);
|
|
2080
|
-
if (obj["exports"]) items.push(`${this.capitalize(this.valueToString(obj["exports"]))}`);
|
|
2081
|
-
if (obj["returnTypes"])
|
|
2082
|
-
items.push(`Explicit return types ${this.valueToString(obj["returnTypes"])}`);
|
|
2083
|
-
return items;
|
|
2084
|
-
}
|
|
2085
|
-
formatNamingStandards(obj) {
|
|
2086
|
-
const items = [];
|
|
2087
|
-
if (obj["files"]) items.push(`Files: \`${this.valueToString(obj["files"])}\``);
|
|
2088
|
-
if (obj["classes"]) items.push(`Classes/Interfaces: \`${this.valueToString(obj["classes"])}\``);
|
|
2089
|
-
if (obj["functions"])
|
|
2090
|
-
items.push(`Functions/Variables: \`${this.valueToString(obj["functions"])}\``);
|
|
2091
|
-
if (obj["constants"]) items.push(`Constants: \`${this.valueToString(obj["constants"])}\``);
|
|
2092
|
-
return items;
|
|
2093
|
-
}
|
|
2094
|
-
formatErrorStandards(obj) {
|
|
2095
|
-
const items = [];
|
|
2096
|
-
if (obj["customClasses"])
|
|
2097
|
-
items.push(
|
|
2098
|
-
`Use custom error classes extending \`${this.valueToString(obj["customClasses"])}\``
|
|
2099
|
-
);
|
|
2100
|
-
if (obj["locationInfo"]) items.push("Always include location information");
|
|
2101
|
-
if (obj["messages"])
|
|
2102
|
-
items.push(`Provide ${this.valueToString(obj["messages"])} error messages`);
|
|
2103
|
-
return items;
|
|
2104
|
-
}
|
|
2105
|
-
formatTestingStandards(obj) {
|
|
2106
|
-
const items = [];
|
|
2107
|
-
if (obj["filePattern"]) items.push(`Test files: \`${this.valueToString(obj["filePattern"])}\``);
|
|
2108
|
-
if (obj["pattern"]) items.push(`Follow ${this.valueToString(obj["pattern"])} pattern`);
|
|
2109
|
-
if (obj["coverage"])
|
|
2110
|
-
items.push(`Target >${this.valueToString(obj["coverage"])}% coverage for libraries`);
|
|
2111
|
-
if (obj["fixtures"]) items.push(`Use fixtures ${this.valueToString(obj["fixtures"])}`);
|
|
2112
|
-
return items;
|
|
2113
|
-
}
|
|
2114
2449
|
formatRestriction(text) {
|
|
2115
2450
|
const formatted = text.replace(/^-\s*/, "").replace(/^"/, "").replace(/"$/, "").replace(/^Never\s+/i, "Don't ");
|
|
2116
2451
|
return formatted;
|
|
@@ -2385,8 +2720,9 @@ var ClaudeFormatter = class extends BaseFormatter {
|
|
|
2385
2720
|
generateSkillFile(config) {
|
|
2386
2721
|
const lines = [];
|
|
2387
2722
|
lines.push("---");
|
|
2388
|
-
lines.push(`name:
|
|
2389
|
-
|
|
2723
|
+
lines.push(`name: '${config.name}'`);
|
|
2724
|
+
const descQuote = config.description.includes("'") ? '"' : "'";
|
|
2725
|
+
lines.push(`description: ${descQuote}${config.description}${descQuote}`);
|
|
2390
2726
|
if (config.context) {
|
|
2391
2727
|
lines.push(`context: ${config.context}`);
|
|
2392
2728
|
}
|
|
@@ -2405,11 +2741,12 @@ var ClaudeFormatter = class extends BaseFormatter {
|
|
|
2405
2741
|
lines.push("---");
|
|
2406
2742
|
lines.push("");
|
|
2407
2743
|
if (config.content) {
|
|
2408
|
-
|
|
2744
|
+
const normalizedContent = this.normalizeMarkdownForPrettier(config.content);
|
|
2745
|
+
lines.push(normalizedContent);
|
|
2409
2746
|
}
|
|
2410
2747
|
return {
|
|
2411
2748
|
path: `.claude/skills/${config.name}/SKILL.md`,
|
|
2412
|
-
content: lines.join("\n")
|
|
2749
|
+
content: lines.join("\n") + "\n"
|
|
2413
2750
|
};
|
|
2414
2751
|
}
|
|
2415
2752
|
// ============================================================
|
|
@@ -2518,7 +2855,7 @@ var ClaudeFormatter = class extends BaseFormatter {
|
|
|
2518
2855
|
}
|
|
2519
2856
|
return {
|
|
2520
2857
|
path: `.claude/agents/${config.name}.md`,
|
|
2521
|
-
content: lines.join("\n")
|
|
2858
|
+
content: lines.join("\n") + "\n"
|
|
2522
2859
|
};
|
|
2523
2860
|
}
|
|
2524
2861
|
// ============================================================
|
|
@@ -3567,7 +3904,7 @@ var AntigravityFormatter = class extends BaseFormatter {
|
|
|
3567
3904
|
if (diagrams) sections.push(diagrams);
|
|
3568
3905
|
const restrictions = this.restrictions(ast, renderer);
|
|
3569
3906
|
if (restrictions) sections.push(restrictions);
|
|
3570
|
-
const content = sections.join("\n\n");
|
|
3907
|
+
const content = sections.join("\n\n") + "\n";
|
|
3571
3908
|
this.validateContentLength(content);
|
|
3572
3909
|
const mainOutput = {
|
|
3573
3910
|
path: this.getOutputPath(options),
|
|
@@ -3721,17 +4058,8 @@ var AntigravityFormatter = class extends BaseFormatter {
|
|
|
3721
4058
|
formatWorkflowTitle(name) {
|
|
3722
4059
|
return name.replace(/^\//, "").split(/[-_]/).map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
|
|
3723
4060
|
}
|
|
3724
|
-
header(
|
|
3725
|
-
|
|
3726
|
-
const syntax = this.getMetaField(ast, "syntax") ?? "0.0.0";
|
|
3727
|
-
return `# Project Rules
|
|
3728
|
-
|
|
3729
|
-
> Auto-generated by PromptScript
|
|
3730
|
-
> Source: ${id} (syntax ${syntax})
|
|
3731
|
-
> Generated: ${(/* @__PURE__ */ new Date()).toISOString()}
|
|
3732
|
-
>
|
|
3733
|
-
> **Do not edit manually** - these rules are generated from PromptScript.
|
|
3734
|
-
> To modify, update the source .prs file and recompile.`;
|
|
4061
|
+
header(_ast) {
|
|
4062
|
+
return `# Project Rules`;
|
|
3735
4063
|
}
|
|
3736
4064
|
identity(ast, _renderer) {
|
|
3737
4065
|
const identity2 = this.findBlock(ast, "identity");
|
|
@@ -3740,7 +4068,7 @@ var AntigravityFormatter = class extends BaseFormatter {
|
|
|
3740
4068
|
if (!content) return null;
|
|
3741
4069
|
return `## Project Identity
|
|
3742
4070
|
|
|
3743
|
-
${content}`;
|
|
4071
|
+
${this.stripAllIndent(content)}`;
|
|
3744
4072
|
}
|
|
3745
4073
|
/**
|
|
3746
4074
|
* Extract tech stack from @context block (same as GitHub/Cursor).
|
|
@@ -3794,7 +4122,7 @@ ${items.join("\n")}`;
|
|
|
3794
4122
|
const content = archMatch.replace("## Architecture", "").trim();
|
|
3795
4123
|
return `## Architecture
|
|
3796
4124
|
|
|
3797
|
-
${content}`;
|
|
4125
|
+
${this.stripAllIndent(content)}`;
|
|
3798
4126
|
}
|
|
3799
4127
|
const props = this.getProps(context.content);
|
|
3800
4128
|
const arch = props["architecture"];
|
|
@@ -3803,7 +4131,7 @@ ${content}`;
|
|
|
3803
4131
|
if (archText.trim()) {
|
|
3804
4132
|
return `## Architecture
|
|
3805
4133
|
|
|
3806
|
-
${archText.trim()}`;
|
|
4134
|
+
${this.stripAllIndent(archText.trim())}`;
|
|
3807
4135
|
}
|
|
3808
4136
|
}
|
|
3809
4137
|
}
|
|
@@ -3813,53 +4141,35 @@ ${archText.trim()}`;
|
|
|
3813
4141
|
if (content) {
|
|
3814
4142
|
return `## Architecture
|
|
3815
4143
|
|
|
3816
|
-
${content}`;
|
|
4144
|
+
${this.stripAllIndent(content)}`;
|
|
3817
4145
|
}
|
|
3818
4146
|
}
|
|
3819
4147
|
return null;
|
|
3820
4148
|
}
|
|
3821
4149
|
/**
|
|
3822
|
-
* Extract code standards from @standards block
|
|
4150
|
+
* Extract code standards from @standards block.
|
|
4151
|
+
* Expects arrays of strings (pass-through format).
|
|
3823
4152
|
*/
|
|
3824
4153
|
codeStandards(ast, _renderer) {
|
|
3825
4154
|
const standards = this.findBlock(ast, "standards");
|
|
3826
4155
|
if (!standards) return null;
|
|
3827
4156
|
const props = this.getProps(standards.content);
|
|
3828
4157
|
const subsections = [];
|
|
3829
|
-
const
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
if (items.length > 0) {
|
|
3842
|
-
subsections.push(`### Naming Conventions
|
|
3843
|
-
|
|
3844
|
-
${items.map((i) => "- " + i).join("\n")}`);
|
|
3845
|
-
}
|
|
3846
|
-
}
|
|
3847
|
-
const errors = props["errors"];
|
|
3848
|
-
if (errors && typeof errors === "object" && !Array.isArray(errors)) {
|
|
3849
|
-
const items = this.formatErrorStandards(errors);
|
|
3850
|
-
if (items.length > 0) {
|
|
3851
|
-
subsections.push(`### Error Handling
|
|
3852
|
-
|
|
3853
|
-
${items.map((i) => "- " + i).join("\n")}`);
|
|
3854
|
-
}
|
|
3855
|
-
}
|
|
3856
|
-
const testing = props["testing"];
|
|
3857
|
-
if (testing && typeof testing === "object" && !Array.isArray(testing)) {
|
|
3858
|
-
const items = this.formatTestingStandards(testing);
|
|
3859
|
-
if (items.length > 0) {
|
|
3860
|
-
subsections.push(`### Testing
|
|
4158
|
+
const sectionMap = {
|
|
4159
|
+
typescript: "TypeScript",
|
|
4160
|
+
naming: "Naming Conventions",
|
|
4161
|
+
errors: "Error Handling",
|
|
4162
|
+
testing: "Testing"
|
|
4163
|
+
};
|
|
4164
|
+
for (const [key, title] of Object.entries(sectionMap)) {
|
|
4165
|
+
const value = props[key];
|
|
4166
|
+
if (Array.isArray(value)) {
|
|
4167
|
+
const items = this.formatStandardsList(value);
|
|
4168
|
+
if (items.length > 0) {
|
|
4169
|
+
subsections.push(`### ${title}
|
|
3861
4170
|
|
|
3862
4171
|
${items.map((i) => "- " + i).join("\n")}`);
|
|
4172
|
+
}
|
|
3863
4173
|
}
|
|
3864
4174
|
}
|
|
3865
4175
|
if (subsections.length === 0) return null;
|
|
@@ -3922,7 +4232,7 @@ ${items.map((i) => "- " + i).join("\n")}`;
|
|
|
3922
4232
|
}
|
|
3923
4233
|
const vite = configObj["viteRoot"];
|
|
3924
4234
|
if (vite) {
|
|
3925
|
-
const value = this.valueToString(vite);
|
|
4235
|
+
const value = this.valueToString(vite).replace(/__/g, "\\_\\_").replace(/\/\*/g, "/\\*");
|
|
3926
4236
|
subsections.push(`### Vite/Vitest
|
|
3927
4237
|
|
|
3928
4238
|
- Vite root: ${value}`);
|
|
@@ -3944,7 +4254,11 @@ ${subsections.join("\n\n")}`;
|
|
|
3944
4254
|
for (const [key, value] of Object.entries(props)) {
|
|
3945
4255
|
if (this.isWorkflow(value)) continue;
|
|
3946
4256
|
const valueStr = this.valueToString(value);
|
|
3947
|
-
|
|
4257
|
+
if (valueStr) {
|
|
4258
|
+
lines.push(`- **${key}**: ${valueStr}`);
|
|
4259
|
+
} else {
|
|
4260
|
+
lines.push(`- **${key}**:`);
|
|
4261
|
+
}
|
|
3948
4262
|
}
|
|
3949
4263
|
if (lines.length === 0) return null;
|
|
3950
4264
|
return `## Commands
|
|
@@ -3963,7 +4277,7 @@ ${lines.join("\n")}`;
|
|
|
3963
4277
|
const content = commandsMatch.replace("## Development Commands", "").trim();
|
|
3964
4278
|
return `## Development Commands
|
|
3965
4279
|
|
|
3966
|
-
${content}`;
|
|
4280
|
+
${this.stripAllIndent(content)}`;
|
|
3967
4281
|
}
|
|
3968
4282
|
/**
|
|
3969
4283
|
* Extract post-work verification from @knowledge block (same as GitHub/Cursor).
|
|
@@ -3979,7 +4293,7 @@ ${content}`;
|
|
|
3979
4293
|
return `## Post-Work Verification
|
|
3980
4294
|
|
|
3981
4295
|
${intro}
|
|
3982
|
-
${content}`;
|
|
4296
|
+
${this.stripAllIndent(content)}`;
|
|
3983
4297
|
}
|
|
3984
4298
|
/**
|
|
3985
4299
|
* Extract documentation standards from @standards.documentation (same as GitHub/Cursor).
|
|
@@ -4025,9 +4339,8 @@ ${items.map((i) => "- " + i).join("\n")}`;
|
|
|
4025
4339
|
const items = [];
|
|
4026
4340
|
const format2 = diagObj["format"];
|
|
4027
4341
|
if (format2) {
|
|
4028
|
-
|
|
4029
|
-
|
|
4030
|
-
);
|
|
4342
|
+
const formatValue = this.valueToString(format2).replace(/__/g, "\\_\\_").replace(/\/\*/g, "/\\*");
|
|
4343
|
+
items.push(`Always use **${formatValue}** syntax for diagrams in documentation`);
|
|
4031
4344
|
}
|
|
4032
4345
|
const types = diagObj["types"];
|
|
4033
4346
|
if (types && Array.isArray(types)) {
|
|
@@ -4072,55 +4385,6 @@ ${items.map((i) => "- " + i).join("\n")}`;
|
|
|
4072
4385
|
formatRestriction(text) {
|
|
4073
4386
|
return text.replace(/^-\s*/, "").replace(/^"/, "").replace(/"$/, "").replace(/^Never\s+/i, "Don't ");
|
|
4074
4387
|
}
|
|
4075
|
-
// Helper methods for formatting standards
|
|
4076
|
-
formatTypeScriptStandards(obj) {
|
|
4077
|
-
const items = [];
|
|
4078
|
-
if (obj["strictMode"]) items.push("Strict mode enabled, no `any` types");
|
|
4079
|
-
if (obj["noAny"]) items.push("Never use `any` type - use `unknown` with type guards");
|
|
4080
|
-
if (obj["useUnknown"]) items.push(`Use \`unknown\` ${this.valueToString(obj["useUnknown"])}`);
|
|
4081
|
-
if (obj["interfaces"])
|
|
4082
|
-
items.push(`Prefer \`interface\` ${this.valueToString(obj["interfaces"])}`);
|
|
4083
|
-
if (obj["types"]) items.push(`Use \`type\` ${this.valueToString(obj["types"])}`);
|
|
4084
|
-
if (obj["exports"]) items.push(`${this.capitalize(this.valueToString(obj["exports"]))}`);
|
|
4085
|
-
if (obj["returnTypes"])
|
|
4086
|
-
items.push(`Explicit return types ${this.valueToString(obj["returnTypes"])}`);
|
|
4087
|
-
return items;
|
|
4088
|
-
}
|
|
4089
|
-
formatNamingStandards(obj) {
|
|
4090
|
-
const items = [];
|
|
4091
|
-
if (obj["files"]) items.push(`Files: \`${this.valueToString(obj["files"])}\``);
|
|
4092
|
-
if (obj["classes"]) items.push(`Classes/Interfaces: \`${this.valueToString(obj["classes"])}\``);
|
|
4093
|
-
if (obj["interfaces"]) items.push(`Interfaces: \`${this.valueToString(obj["interfaces"])}\``);
|
|
4094
|
-
if (obj["functions"])
|
|
4095
|
-
items.push(`Functions/Variables: \`${this.valueToString(obj["functions"])}\``);
|
|
4096
|
-
if (obj["variables"]) items.push(`Variables: \`${this.valueToString(obj["variables"])}\``);
|
|
4097
|
-
if (obj["constants"]) items.push(`Constants: \`${this.valueToString(obj["constants"])}\``);
|
|
4098
|
-
return items;
|
|
4099
|
-
}
|
|
4100
|
-
formatErrorStandards(obj) {
|
|
4101
|
-
const items = [];
|
|
4102
|
-
if (obj["customClasses"])
|
|
4103
|
-
items.push(
|
|
4104
|
-
`Use custom error classes extending \`${this.valueToString(obj["customClasses"])}\``
|
|
4105
|
-
);
|
|
4106
|
-
if (obj["locationInfo"]) items.push("Always include location information");
|
|
4107
|
-
if (obj["messages"])
|
|
4108
|
-
items.push(`Provide ${this.valueToString(obj["messages"])} error messages`);
|
|
4109
|
-
return items;
|
|
4110
|
-
}
|
|
4111
|
-
formatTestingStandards(obj) {
|
|
4112
|
-
const items = [];
|
|
4113
|
-
if (obj["filePattern"]) items.push(`Test files: \`${this.valueToString(obj["filePattern"])}\``);
|
|
4114
|
-
if (obj["pattern"]) items.push(`Follow ${this.valueToString(obj["pattern"])} pattern`);
|
|
4115
|
-
if (obj["framework"]) items.push(`Framework: ${this.valueToString(obj["framework"])}`);
|
|
4116
|
-
if (obj["coverage"])
|
|
4117
|
-
items.push(`Target >${this.valueToString(obj["coverage"])}% coverage for libraries`);
|
|
4118
|
-
if (obj["fixtures"]) items.push(`Use fixtures ${this.valueToString(obj["fixtures"])}`);
|
|
4119
|
-
return items;
|
|
4120
|
-
}
|
|
4121
|
-
capitalize(str) {
|
|
4122
|
-
return str.charAt(0).toUpperCase() + str.slice(1);
|
|
4123
|
-
}
|
|
4124
4388
|
};
|
|
4125
4389
|
|
|
4126
4390
|
// packages/formatters/src/index.ts
|
|
@@ -14277,8 +14541,8 @@ function parse(source, options = {}) {
|
|
|
14277
14541
|
}
|
|
14278
14542
|
|
|
14279
14543
|
// packages/resolver/src/loader.ts
|
|
14280
|
-
import { readFile as
|
|
14281
|
-
import { resolve, dirname as
|
|
14544
|
+
import { readFile as readFile4 } from "fs/promises";
|
|
14545
|
+
import { resolve as resolve2, dirname as dirname3, isAbsolute } from "path";
|
|
14282
14546
|
var FileLoader = class {
|
|
14283
14547
|
registryPath;
|
|
14284
14548
|
localPath;
|
|
@@ -14295,7 +14559,7 @@ var FileLoader = class {
|
|
|
14295
14559
|
*/
|
|
14296
14560
|
async load(path) {
|
|
14297
14561
|
try {
|
|
14298
|
-
return await
|
|
14562
|
+
return await readFile4(path, "utf-8");
|
|
14299
14563
|
} catch (err) {
|
|
14300
14564
|
if (err.code === "ENOENT") {
|
|
14301
14565
|
throw new FileNotFoundError(path);
|
|
@@ -14324,11 +14588,11 @@ var FileLoader = class {
|
|
|
14324
14588
|
const namespace = match[1];
|
|
14325
14589
|
const segments = match[2];
|
|
14326
14590
|
const fileName2 = segments.endsWith(".prs") ? segments : `${segments}.prs`;
|
|
14327
|
-
return
|
|
14591
|
+
return resolve2(this.registryPath, `@${namespace}`, fileName2);
|
|
14328
14592
|
}
|
|
14329
14593
|
}
|
|
14330
14594
|
const fileName = path.endsWith(".prs") ? path : `${path}.prs`;
|
|
14331
|
-
return
|
|
14595
|
+
return resolve2(this.localPath, fileName);
|
|
14332
14596
|
}
|
|
14333
14597
|
/**
|
|
14334
14598
|
* Resolve a PathReference to an absolute path.
|
|
@@ -14339,9 +14603,9 @@ var FileLoader = class {
|
|
|
14339
14603
|
*/
|
|
14340
14604
|
resolveRef(ref, fromFile) {
|
|
14341
14605
|
if (ref.isRelative) {
|
|
14342
|
-
const dir =
|
|
14343
|
-
const
|
|
14344
|
-
return
|
|
14606
|
+
const dir = dirname3(fromFile);
|
|
14607
|
+
const rawPath = ref.raw.endsWith(".prs") ? ref.raw : `${ref.raw}.prs`;
|
|
14608
|
+
return resolve2(dir, rawPath);
|
|
14345
14609
|
}
|
|
14346
14610
|
return this.toAbsolutePath(ref.raw);
|
|
14347
14611
|
}
|
|
@@ -14665,9 +14929,7 @@ function mergeProperties2(source, target) {
|
|
|
14665
14929
|
sourceVal,
|
|
14666
14930
|
targetVal
|
|
14667
14931
|
);
|
|
14668
|
-
} else if (typeof sourceVal === typeof targetVal) {
|
|
14669
14932
|
} else {
|
|
14670
|
-
result[key] = deepCloneValue2(targetVal);
|
|
14671
14933
|
}
|
|
14672
14934
|
}
|
|
14673
14935
|
return result;
|
|
@@ -15001,6 +15263,115 @@ function uniqueConcat3(parent, child) {
|
|
|
15001
15263
|
return result;
|
|
15002
15264
|
}
|
|
15003
15265
|
|
|
15266
|
+
// packages/resolver/src/skills.ts
|
|
15267
|
+
import { readFile as readFile5, access } from "fs/promises";
|
|
15268
|
+
import { resolve as resolve3, dirname as dirname4 } from "path";
|
|
15269
|
+
function parseSkillMd(content) {
|
|
15270
|
+
const lines = content.split("\n");
|
|
15271
|
+
let inFrontmatter = false;
|
|
15272
|
+
let frontmatterStart = -1;
|
|
15273
|
+
let frontmatterEnd = -1;
|
|
15274
|
+
for (let i = 0; i < lines.length; i++) {
|
|
15275
|
+
const line = lines[i]?.trim() ?? "";
|
|
15276
|
+
if (line === "---") {
|
|
15277
|
+
if (!inFrontmatter) {
|
|
15278
|
+
inFrontmatter = true;
|
|
15279
|
+
frontmatterStart = i;
|
|
15280
|
+
} else {
|
|
15281
|
+
frontmatterEnd = i;
|
|
15282
|
+
break;
|
|
15283
|
+
}
|
|
15284
|
+
}
|
|
15285
|
+
}
|
|
15286
|
+
let name;
|
|
15287
|
+
let description;
|
|
15288
|
+
let bodyContent;
|
|
15289
|
+
if (frontmatterStart >= 0 && frontmatterEnd > frontmatterStart) {
|
|
15290
|
+
const frontmatterLines = lines.slice(frontmatterStart + 1, frontmatterEnd);
|
|
15291
|
+
for (const line of frontmatterLines) {
|
|
15292
|
+
const nameMatch = line.match(/^name:\s*(?:"([^"]+)"|'([^']+)'|(.+))\s*$/);
|
|
15293
|
+
if (nameMatch) {
|
|
15294
|
+
name = (nameMatch[1] ?? nameMatch[2] ?? nameMatch[3])?.trim();
|
|
15295
|
+
}
|
|
15296
|
+
const descMatch = line.match(/^description:\s*(?:"([^"]+)"|'([^']+)'|(.+))\s*$/);
|
|
15297
|
+
if (descMatch) {
|
|
15298
|
+
description = (descMatch[1] ?? descMatch[2] ?? descMatch[3])?.trim();
|
|
15299
|
+
}
|
|
15300
|
+
}
|
|
15301
|
+
bodyContent = lines.slice(frontmatterEnd + 1).join("\n").trim();
|
|
15302
|
+
} else {
|
|
15303
|
+
bodyContent = content.trim();
|
|
15304
|
+
}
|
|
15305
|
+
return { name, description, content: bodyContent };
|
|
15306
|
+
}
|
|
15307
|
+
async function fileExists(path) {
|
|
15308
|
+
try {
|
|
15309
|
+
await access(path);
|
|
15310
|
+
return true;
|
|
15311
|
+
} catch {
|
|
15312
|
+
return false;
|
|
15313
|
+
}
|
|
15314
|
+
}
|
|
15315
|
+
async function resolveNativeSkills(ast, registryPath, sourceFile) {
|
|
15316
|
+
const skillsBlock = ast.blocks.find((b) => b.name === "skills");
|
|
15317
|
+
if (!skillsBlock || skillsBlock.content.type !== "ObjectContent") {
|
|
15318
|
+
return ast;
|
|
15319
|
+
}
|
|
15320
|
+
const skillsContent = skillsBlock.content;
|
|
15321
|
+
const updatedProperties = { ...skillsContent.properties };
|
|
15322
|
+
let hasUpdates = false;
|
|
15323
|
+
const sourceDir = dirname4(sourceFile);
|
|
15324
|
+
const isSkillsDir = sourceDir.includes("@skills");
|
|
15325
|
+
for (const [skillName, skillValue] of Object.entries(skillsContent.properties)) {
|
|
15326
|
+
if (typeof skillValue !== "object" || skillValue === null || Array.isArray(skillValue)) {
|
|
15327
|
+
continue;
|
|
15328
|
+
}
|
|
15329
|
+
const skillObj = skillValue;
|
|
15330
|
+
let skillMdPath = null;
|
|
15331
|
+
if (isSkillsDir) {
|
|
15332
|
+
const basePath = sourceDir;
|
|
15333
|
+
skillMdPath = resolve3(basePath, skillName, "SKILL.md");
|
|
15334
|
+
} else {
|
|
15335
|
+
skillMdPath = resolve3(registryPath, "@skills", skillName, "SKILL.md");
|
|
15336
|
+
}
|
|
15337
|
+
if (skillMdPath && await fileExists(skillMdPath)) {
|
|
15338
|
+
try {
|
|
15339
|
+
const rawContent = await readFile5(skillMdPath, "utf-8");
|
|
15340
|
+
const parsed = parseSkillMd(rawContent);
|
|
15341
|
+
const updatedSkill = { ...skillObj };
|
|
15342
|
+
if (parsed.content) {
|
|
15343
|
+
updatedSkill["content"] = {
|
|
15344
|
+
type: "TextContent",
|
|
15345
|
+
value: parsed.content,
|
|
15346
|
+
loc: { file: skillMdPath, line: 1, column: 1, offset: 0 }
|
|
15347
|
+
};
|
|
15348
|
+
}
|
|
15349
|
+
if (parsed.description && (!skillObj["description"] || typeof skillObj["description"] === "string" && parsed.description.length > skillObj["description"].length)) {
|
|
15350
|
+
updatedSkill["description"] = parsed.description;
|
|
15351
|
+
}
|
|
15352
|
+
updatedProperties[skillName] = updatedSkill;
|
|
15353
|
+
hasUpdates = true;
|
|
15354
|
+
} catch {
|
|
15355
|
+
}
|
|
15356
|
+
}
|
|
15357
|
+
}
|
|
15358
|
+
if (!hasUpdates) {
|
|
15359
|
+
return ast;
|
|
15360
|
+
}
|
|
15361
|
+
const updatedSkillsBlock = {
|
|
15362
|
+
...skillsBlock,
|
|
15363
|
+
content: {
|
|
15364
|
+
...skillsContent,
|
|
15365
|
+
properties: updatedProperties
|
|
15366
|
+
}
|
|
15367
|
+
};
|
|
15368
|
+
const updatedBlocks = ast.blocks.map((b) => b.name === "skills" ? updatedSkillsBlock : b);
|
|
15369
|
+
return {
|
|
15370
|
+
...ast,
|
|
15371
|
+
blocks: updatedBlocks
|
|
15372
|
+
};
|
|
15373
|
+
}
|
|
15374
|
+
|
|
15004
15375
|
// packages/resolver/src/resolver.ts
|
|
15005
15376
|
var Resolver = class {
|
|
15006
15377
|
loader;
|
|
@@ -15053,6 +15424,7 @@ var Resolver = class {
|
|
|
15053
15424
|
ast = await this.resolveInherit(ast, absPath, sources, errors);
|
|
15054
15425
|
ast = await this.resolveImports(ast, absPath, sources, errors);
|
|
15055
15426
|
ast = applyExtends(ast);
|
|
15427
|
+
ast = await resolveNativeSkills(ast, this.loader.getRegistryPath(), absPath);
|
|
15056
15428
|
return {
|
|
15057
15429
|
ast,
|
|
15058
15430
|
sources: [...new Set(sources)],
|
|
@@ -15146,7 +15518,7 @@ var Resolver = class {
|
|
|
15146
15518
|
};
|
|
15147
15519
|
|
|
15148
15520
|
// packages/resolver/src/registry.ts
|
|
15149
|
-
import { existsSync as
|
|
15521
|
+
import { existsSync as existsSync4, promises as fs } from "fs";
|
|
15150
15522
|
import { join as join3 } from "path";
|
|
15151
15523
|
var FileSystemRegistry = class {
|
|
15152
15524
|
rootPath;
|
|
@@ -15173,7 +15545,7 @@ var FileSystemRegistry = class {
|
|
|
15173
15545
|
}
|
|
15174
15546
|
async exists(path) {
|
|
15175
15547
|
const fullPath = this.resolvePath(path);
|
|
15176
|
-
return
|
|
15548
|
+
return existsSync4(fullPath);
|
|
15177
15549
|
}
|
|
15178
15550
|
async list(path) {
|
|
15179
15551
|
const fullPath = this.resolvePath(path);
|
|
@@ -15229,7 +15601,7 @@ var HttpRegistry = class {
|
|
|
15229
15601
|
* Sleep for specified milliseconds.
|
|
15230
15602
|
*/
|
|
15231
15603
|
sleep(ms) {
|
|
15232
|
-
return new Promise((
|
|
15604
|
+
return new Promise((resolve9) => setTimeout(resolve9, ms));
|
|
15233
15605
|
}
|
|
15234
15606
|
/**
|
|
15235
15607
|
* Fetch with timeout.
|
|
@@ -15371,12 +15743,12 @@ function createHttpRegistry(options) {
|
|
|
15371
15743
|
}
|
|
15372
15744
|
|
|
15373
15745
|
// packages/resolver/src/git-registry.ts
|
|
15374
|
-
import { existsSync as
|
|
15746
|
+
import { existsSync as existsSync6, promises as fs3 } from "fs";
|
|
15375
15747
|
import { join as join5 } from "path";
|
|
15376
15748
|
import { simpleGit } from "simple-git";
|
|
15377
15749
|
|
|
15378
15750
|
// packages/resolver/src/git-cache-manager.ts
|
|
15379
|
-
import { existsSync as
|
|
15751
|
+
import { existsSync as existsSync5, promises as fs2 } from "fs";
|
|
15380
15752
|
import { join as join4 } from "path";
|
|
15381
15753
|
import { homedir } from "os";
|
|
15382
15754
|
|
|
@@ -15526,7 +15898,7 @@ var GitCacheManager = class {
|
|
|
15526
15898
|
*/
|
|
15527
15899
|
async get(url, ref) {
|
|
15528
15900
|
const cachePath = this.getCachePath(url, ref);
|
|
15529
|
-
if (!
|
|
15901
|
+
if (!existsSync5(cachePath)) {
|
|
15530
15902
|
return null;
|
|
15531
15903
|
}
|
|
15532
15904
|
const metadata = await this.readMetadata(cachePath);
|
|
@@ -15591,7 +15963,7 @@ var GitCacheManager = class {
|
|
|
15591
15963
|
*/
|
|
15592
15964
|
async remove(url, ref) {
|
|
15593
15965
|
const cachePath = this.getCachePath(url, ref);
|
|
15594
|
-
if (
|
|
15966
|
+
if (existsSync5(cachePath)) {
|
|
15595
15967
|
await fs2.rm(cachePath, { recursive: true, force: true });
|
|
15596
15968
|
}
|
|
15597
15969
|
}
|
|
@@ -15601,7 +15973,7 @@ var GitCacheManager = class {
|
|
|
15601
15973
|
* @returns Array of cache entries
|
|
15602
15974
|
*/
|
|
15603
15975
|
async list() {
|
|
15604
|
-
if (!
|
|
15976
|
+
if (!existsSync5(this.cacheDir)) {
|
|
15605
15977
|
return [];
|
|
15606
15978
|
}
|
|
15607
15979
|
const entries = [];
|
|
@@ -15636,7 +16008,7 @@ var GitCacheManager = class {
|
|
|
15636
16008
|
* Remove all cache entries.
|
|
15637
16009
|
*/
|
|
15638
16010
|
async clear() {
|
|
15639
|
-
if (
|
|
16011
|
+
if (existsSync5(this.cacheDir)) {
|
|
15640
16012
|
await fs2.rm(this.cacheDir, { recursive: true, force: true });
|
|
15641
16013
|
}
|
|
15642
16014
|
}
|
|
@@ -15646,7 +16018,7 @@ var GitCacheManager = class {
|
|
|
15646
16018
|
* @returns Total cache size in bytes
|
|
15647
16019
|
*/
|
|
15648
16020
|
async getSize() {
|
|
15649
|
-
if (!
|
|
16021
|
+
if (!existsSync5(this.cacheDir)) {
|
|
15650
16022
|
return 0;
|
|
15651
16023
|
}
|
|
15652
16024
|
return this.calculateDirSize(this.cacheDir);
|
|
@@ -15673,7 +16045,7 @@ var GitCacheManager = class {
|
|
|
15673
16045
|
*/
|
|
15674
16046
|
async readMetadata(cachePath) {
|
|
15675
16047
|
const metadataPath = join4(cachePath, METADATA_FILE);
|
|
15676
|
-
if (!
|
|
16048
|
+
if (!existsSync5(metadataPath)) {
|
|
15677
16049
|
return null;
|
|
15678
16050
|
}
|
|
15679
16051
|
try {
|
|
@@ -15756,7 +16128,7 @@ var GitRegistry = class {
|
|
|
15756
16128
|
const ref = version ?? this.defaultRef;
|
|
15757
16129
|
const repoPath = await this.ensureCloned(ref);
|
|
15758
16130
|
const filePath = this.resolveFilePath(repoPath, basePath);
|
|
15759
|
-
if (!
|
|
16131
|
+
if (!existsSync6(filePath)) {
|
|
15760
16132
|
throw new FileNotFoundError(path);
|
|
15761
16133
|
}
|
|
15762
16134
|
return fs3.readFile(filePath, "utf-8");
|
|
@@ -15773,7 +16145,7 @@ var GitRegistry = class {
|
|
|
15773
16145
|
const ref = version ?? this.defaultRef;
|
|
15774
16146
|
const repoPath = await this.ensureCloned(ref);
|
|
15775
16147
|
const filePath = this.resolveFilePath(repoPath, basePath);
|
|
15776
|
-
return
|
|
16148
|
+
return existsSync6(filePath);
|
|
15777
16149
|
} catch {
|
|
15778
16150
|
return false;
|
|
15779
16151
|
}
|
|
@@ -15790,7 +16162,7 @@ var GitRegistry = class {
|
|
|
15790
16162
|
const ref = version ?? this.defaultRef;
|
|
15791
16163
|
const repoPath = await this.ensureCloned(ref);
|
|
15792
16164
|
const dirPath = this.resolveDirectoryPath(repoPath, basePath);
|
|
15793
|
-
if (!
|
|
16165
|
+
if (!existsSync6(dirPath)) {
|
|
15794
16166
|
return [];
|
|
15795
16167
|
}
|
|
15796
16168
|
const entries = await fs3.readdir(dirPath, { withFileTypes: true });
|
|
@@ -15852,7 +16224,7 @@ var GitRegistry = class {
|
|
|
15852
16224
|
* Clone the repository to the specified path.
|
|
15853
16225
|
*/
|
|
15854
16226
|
async clone(targetPath, ref) {
|
|
15855
|
-
if (
|
|
16227
|
+
if (existsSync6(targetPath)) {
|
|
15856
16228
|
await fs3.rm(targetPath, { recursive: true, force: true });
|
|
15857
16229
|
}
|
|
15858
16230
|
await fs3.mkdir(targetPath, { recursive: true });
|
|
@@ -16487,6 +16859,39 @@ var Validator = class {
|
|
|
16487
16859
|
};
|
|
16488
16860
|
|
|
16489
16861
|
// packages/compiler/src/compiler.ts
|
|
16862
|
+
function generateMarker() {
|
|
16863
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString();
|
|
16864
|
+
return `<!-- PromptScript ${timestamp} - do not edit -->`;
|
|
16865
|
+
}
|
|
16866
|
+
function addMarkerToOutput(output) {
|
|
16867
|
+
const { content, path } = output;
|
|
16868
|
+
if (content.includes("<!-- PromptScript")) {
|
|
16869
|
+
return output;
|
|
16870
|
+
}
|
|
16871
|
+
const marker = generateMarker();
|
|
16872
|
+
if (!path.endsWith(".md") && !path.endsWith(".mdc")) {
|
|
16873
|
+
return output;
|
|
16874
|
+
}
|
|
16875
|
+
if (content.startsWith("---")) {
|
|
16876
|
+
const closingIndex = content.indexOf("---", 3);
|
|
16877
|
+
if (closingIndex !== -1) {
|
|
16878
|
+
const beforeMarker = content.slice(0, closingIndex + 3);
|
|
16879
|
+
const afterMarker = content.slice(closingIndex + 3);
|
|
16880
|
+
const newContent = `${beforeMarker}
|
|
16881
|
+
|
|
16882
|
+
${marker}
|
|
16883
|
+
${afterMarker.replace(/^\n+/, "\n")}`;
|
|
16884
|
+
return { ...output, content: newContent };
|
|
16885
|
+
}
|
|
16886
|
+
}
|
|
16887
|
+
const lines = content.split("\n");
|
|
16888
|
+
if (lines[0]?.startsWith("# ")) {
|
|
16889
|
+
lines.splice(1, 0, "", marker);
|
|
16890
|
+
} else {
|
|
16891
|
+
lines.unshift(marker, "");
|
|
16892
|
+
}
|
|
16893
|
+
return { ...output, content: lines.join("\n") };
|
|
16894
|
+
}
|
|
16490
16895
|
var Compiler = class _Compiler {
|
|
16491
16896
|
constructor(options) {
|
|
16492
16897
|
this.options = options;
|
|
@@ -16557,10 +16962,10 @@ var Compiler = class _Compiler {
|
|
|
16557
16962
|
try {
|
|
16558
16963
|
const formatOptions = this.getFormatOptionsForTarget(formatter.name, config);
|
|
16559
16964
|
const output = formatter.format(resolved.ast, formatOptions);
|
|
16560
|
-
outputs.set(output.path, output);
|
|
16965
|
+
outputs.set(output.path, addMarkerToOutput(output));
|
|
16561
16966
|
if (output.additionalFiles) {
|
|
16562
16967
|
for (const additionalFile of output.additionalFiles) {
|
|
16563
|
-
outputs.set(additionalFile.path, additionalFile);
|
|
16968
|
+
outputs.set(additionalFile.path, addMarkerToOutput(additionalFile));
|
|
16564
16969
|
}
|
|
16565
16970
|
}
|
|
16566
16971
|
} catch (err) {
|
|
@@ -16644,12 +17049,12 @@ var Compiler = class _Compiler {
|
|
|
16644
17049
|
*/
|
|
16645
17050
|
async watch(entryPath, options = {}) {
|
|
16646
17051
|
const { default: chokidar2 } = await import("chokidar");
|
|
16647
|
-
const { dirname:
|
|
16648
|
-
const baseDir =
|
|
17052
|
+
const { dirname: dirname8, resolve: resolve9 } = await import("path");
|
|
17053
|
+
const baseDir = dirname8(resolve9(entryPath));
|
|
16649
17054
|
const includePatterns = options.include ?? ["**/*.prs"];
|
|
16650
17055
|
const excludePatterns = options.exclude ?? ["**/node_modules/**"];
|
|
16651
17056
|
const debounceMs = options.debounce ?? 300;
|
|
16652
|
-
const watchPatterns = includePatterns.map((p) =>
|
|
17057
|
+
const watchPatterns = includePatterns.map((p) => resolve9(baseDir, p));
|
|
16653
17058
|
let debounceTimer = null;
|
|
16654
17059
|
let pendingChanges = [];
|
|
16655
17060
|
const handleChange = async (changedFiles) => {
|
|
@@ -16704,14 +17109,13 @@ var Compiler = class _Compiler {
|
|
|
16704
17109
|
*/
|
|
16705
17110
|
getFormatOptionsForTarget(_targetName, config) {
|
|
16706
17111
|
const customConventions = this.options.customConventions;
|
|
16707
|
-
|
|
16708
|
-
return {};
|
|
16709
|
-
}
|
|
16710
|
-
const conventionName = config?.convention;
|
|
17112
|
+
const prettierOptions = this.options.prettier;
|
|
16711
17113
|
const options = {
|
|
16712
17114
|
outputPath: config?.output,
|
|
16713
|
-
version: config?.version
|
|
17115
|
+
version: config?.version,
|
|
17116
|
+
prettier: prettierOptions
|
|
16714
17117
|
};
|
|
17118
|
+
const conventionName = config?.convention;
|
|
16715
17119
|
if (conventionName && customConventions?.[conventionName]) {
|
|
16716
17120
|
options.convention = customConventions[conventionName];
|
|
16717
17121
|
} else if (conventionName) {
|
|
@@ -16788,7 +17192,91 @@ var Compiler = class _Compiler {
|
|
|
16788
17192
|
}
|
|
16789
17193
|
};
|
|
16790
17194
|
|
|
17195
|
+
// packages/cli/src/output/pager.ts
|
|
17196
|
+
import { spawn } from "child_process";
|
|
17197
|
+
function isTTY() {
|
|
17198
|
+
return process.stdout.isTTY === true;
|
|
17199
|
+
}
|
|
17200
|
+
function getPagerCommand() {
|
|
17201
|
+
return process.env["PAGER"] ?? "less";
|
|
17202
|
+
}
|
|
17203
|
+
var Pager = class {
|
|
17204
|
+
lines = [];
|
|
17205
|
+
enabled;
|
|
17206
|
+
constructor(enabled = true) {
|
|
17207
|
+
this.enabled = enabled && isTTY();
|
|
17208
|
+
}
|
|
17209
|
+
/**
|
|
17210
|
+
* Write a line to the pager buffer.
|
|
17211
|
+
*/
|
|
17212
|
+
write(line) {
|
|
17213
|
+
this.lines.push(line);
|
|
17214
|
+
}
|
|
17215
|
+
/**
|
|
17216
|
+
* Write multiple lines to the pager buffer.
|
|
17217
|
+
*/
|
|
17218
|
+
writeLines(lines) {
|
|
17219
|
+
this.lines.push(...lines);
|
|
17220
|
+
}
|
|
17221
|
+
/**
|
|
17222
|
+
* Flush all buffered content through the pager.
|
|
17223
|
+
* If pager is disabled or not a TTY, just prints to stdout.
|
|
17224
|
+
*/
|
|
17225
|
+
async flush() {
|
|
17226
|
+
const content = this.lines.join("\n");
|
|
17227
|
+
if (!this.enabled || this.lines.length === 0) {
|
|
17228
|
+
if (content) {
|
|
17229
|
+
console.log(content);
|
|
17230
|
+
}
|
|
17231
|
+
return;
|
|
17232
|
+
}
|
|
17233
|
+
return new Promise((resolve9) => {
|
|
17234
|
+
const pagerCmd = getPagerCommand();
|
|
17235
|
+
const [cmd, ...args] = pagerCmd.split(" ");
|
|
17236
|
+
if (cmd === "less" && !args.includes("-R")) {
|
|
17237
|
+
args.push("-R");
|
|
17238
|
+
}
|
|
17239
|
+
if (!cmd) {
|
|
17240
|
+
console.log(content);
|
|
17241
|
+
resolve9();
|
|
17242
|
+
return;
|
|
17243
|
+
}
|
|
17244
|
+
const pager = spawn(cmd, args, {
|
|
17245
|
+
stdio: ["pipe", "inherit", "inherit"],
|
|
17246
|
+
env: {
|
|
17247
|
+
...process.env,
|
|
17248
|
+
// Ensure less handles colors properly
|
|
17249
|
+
LESS: process.env["LESS"] ?? "-R"
|
|
17250
|
+
}
|
|
17251
|
+
});
|
|
17252
|
+
pager.on("error", (_err) => {
|
|
17253
|
+
console.log(content);
|
|
17254
|
+
resolve9();
|
|
17255
|
+
});
|
|
17256
|
+
pager.on("close", () => {
|
|
17257
|
+
resolve9();
|
|
17258
|
+
});
|
|
17259
|
+
if (pager.stdin) {
|
|
17260
|
+
pager.stdin.write(content);
|
|
17261
|
+
pager.stdin.end();
|
|
17262
|
+
} else {
|
|
17263
|
+
console.log(content);
|
|
17264
|
+
resolve9();
|
|
17265
|
+
}
|
|
17266
|
+
});
|
|
17267
|
+
}
|
|
17268
|
+
};
|
|
17269
|
+
function createPager(enabled = true) {
|
|
17270
|
+
return new Pager(enabled);
|
|
17271
|
+
}
|
|
17272
|
+
|
|
16791
17273
|
// packages/cli/src/commands/compile.ts
|
|
17274
|
+
var PROMPTSCRIPT_MARKERS = [
|
|
17275
|
+
"<!-- PromptScript",
|
|
17276
|
+
// Current marker (HTML comment with date)
|
|
17277
|
+
"> Auto-generated by PromptScript"
|
|
17278
|
+
// Legacy - for backwards compatibility
|
|
17279
|
+
];
|
|
16792
17280
|
function parseTargets(targets) {
|
|
16793
17281
|
return targets.map((entry) => {
|
|
16794
17282
|
if (typeof entry === "string") {
|
|
@@ -16802,6 +17290,28 @@ function parseTargets(targets) {
|
|
|
16802
17290
|
return { name, config };
|
|
16803
17291
|
}).filter((target) => target.config?.enabled !== false);
|
|
16804
17292
|
}
|
|
17293
|
+
async function isPromptScriptGenerated(filePath) {
|
|
17294
|
+
try {
|
|
17295
|
+
const content = await readFile6(filePath, "utf-8");
|
|
17296
|
+
const lines = content.split("\n").slice(0, 10);
|
|
17297
|
+
return lines.some((line) => PROMPTSCRIPT_MARKERS.some((marker) => line.includes(marker)));
|
|
17298
|
+
} catch {
|
|
17299
|
+
return false;
|
|
17300
|
+
}
|
|
17301
|
+
}
|
|
17302
|
+
async function promptForOverwrite(filePath, services) {
|
|
17303
|
+
const response = await services.prompts.select({
|
|
17304
|
+
message: `File exists and was not generated by PromptScript: ${filePath}
|
|
17305
|
+
Overwrite?`,
|
|
17306
|
+
choices: [
|
|
17307
|
+
{ name: "No (skip this file)", value: "no" },
|
|
17308
|
+
{ name: "Yes (overwrite this file)", value: "yes" },
|
|
17309
|
+
{ name: "All (overwrite all remaining files)", value: "all" }
|
|
17310
|
+
],
|
|
17311
|
+
default: "no"
|
|
17312
|
+
});
|
|
17313
|
+
return response;
|
|
17314
|
+
}
|
|
16805
17315
|
function printErrors(errors) {
|
|
16806
17316
|
for (const err of errors) {
|
|
16807
17317
|
ConsoleOutput.error(err.message);
|
|
@@ -16810,17 +17320,84 @@ function printErrors(errors) {
|
|
|
16810
17320
|
}
|
|
16811
17321
|
}
|
|
16812
17322
|
}
|
|
16813
|
-
async function writeOutputs(outputs, options, _config) {
|
|
17323
|
+
async function writeOutputs(outputs, options, _config, services) {
|
|
17324
|
+
const result = { written: [], skipped: [] };
|
|
17325
|
+
let overwriteAll = false;
|
|
17326
|
+
const conflicts = [];
|
|
16814
17327
|
for (const output of outputs.values()) {
|
|
16815
|
-
const outputPath = options.output ?
|
|
17328
|
+
const outputPath = options.output ? resolve4(options.output, output.path) : resolve4(output.path);
|
|
17329
|
+
const fileExists2 = existsSync7(outputPath);
|
|
16816
17330
|
if (options.dryRun) {
|
|
16817
|
-
|
|
16818
|
-
|
|
16819
|
-
|
|
17331
|
+
if (fileExists2) {
|
|
17332
|
+
const isGenerated2 = await isPromptScriptGenerated(outputPath);
|
|
17333
|
+
if (isGenerated2) {
|
|
17334
|
+
ConsoleOutput.dryRun(`Would overwrite: ${outputPath}`);
|
|
17335
|
+
} else {
|
|
17336
|
+
ConsoleOutput.warning(`Would conflict: ${outputPath} (not generated by PromptScript)`);
|
|
17337
|
+
}
|
|
17338
|
+
} else {
|
|
17339
|
+
ConsoleOutput.dryRun(`Would write: ${outputPath}`);
|
|
17340
|
+
}
|
|
17341
|
+
result.written.push(outputPath);
|
|
17342
|
+
continue;
|
|
17343
|
+
}
|
|
17344
|
+
if (!fileExists2) {
|
|
17345
|
+
await mkdir2(dirname5(outputPath), { recursive: true });
|
|
17346
|
+
await writeFile2(outputPath, output.content, "utf-8");
|
|
17347
|
+
ConsoleOutput.success(outputPath);
|
|
17348
|
+
result.written.push(outputPath);
|
|
17349
|
+
continue;
|
|
17350
|
+
}
|
|
17351
|
+
const isGenerated = await isPromptScriptGenerated(outputPath);
|
|
17352
|
+
if (isGenerated) {
|
|
17353
|
+
await mkdir2(dirname5(outputPath), { recursive: true });
|
|
17354
|
+
await writeFile2(outputPath, output.content, "utf-8");
|
|
17355
|
+
ConsoleOutput.success(outputPath);
|
|
17356
|
+
result.written.push(outputPath);
|
|
17357
|
+
continue;
|
|
17358
|
+
}
|
|
17359
|
+
if (options.force || overwriteAll) {
|
|
17360
|
+
await mkdir2(dirname5(outputPath), { recursive: true });
|
|
16820
17361
|
await writeFile2(outputPath, output.content, "utf-8");
|
|
16821
17362
|
ConsoleOutput.success(outputPath);
|
|
17363
|
+
result.written.push(outputPath);
|
|
17364
|
+
continue;
|
|
17365
|
+
}
|
|
17366
|
+
if (!isTTY()) {
|
|
17367
|
+
conflicts.push(outputPath);
|
|
17368
|
+
continue;
|
|
16822
17369
|
}
|
|
17370
|
+
const response = await promptForOverwrite(outputPath, services);
|
|
17371
|
+
switch (response) {
|
|
17372
|
+
case "yes":
|
|
17373
|
+
await mkdir2(dirname5(outputPath), { recursive: true });
|
|
17374
|
+
await writeFile2(outputPath, output.content, "utf-8");
|
|
17375
|
+
ConsoleOutput.success(outputPath);
|
|
17376
|
+
result.written.push(outputPath);
|
|
17377
|
+
break;
|
|
17378
|
+
case "no":
|
|
17379
|
+
ConsoleOutput.skipped(outputPath);
|
|
17380
|
+
result.skipped.push(outputPath);
|
|
17381
|
+
break;
|
|
17382
|
+
case "all":
|
|
17383
|
+
overwriteAll = true;
|
|
17384
|
+
await mkdir2(dirname5(outputPath), { recursive: true });
|
|
17385
|
+
await writeFile2(outputPath, output.content, "utf-8");
|
|
17386
|
+
ConsoleOutput.success(outputPath);
|
|
17387
|
+
result.written.push(outputPath);
|
|
17388
|
+
break;
|
|
17389
|
+
}
|
|
17390
|
+
}
|
|
17391
|
+
if (conflicts.length > 0) {
|
|
17392
|
+
const fileList = conflicts.map((f) => ` - ${f}`).join("\n");
|
|
17393
|
+
throw new Error(
|
|
17394
|
+
`Cannot overwrite files not generated by PromptScript in non-interactive mode:
|
|
17395
|
+
${fileList}
|
|
17396
|
+
|
|
17397
|
+
Use --force to overwrite these files.`
|
|
17398
|
+
);
|
|
16823
17399
|
}
|
|
17400
|
+
return result;
|
|
16824
17401
|
}
|
|
16825
17402
|
function printStats(stats) {
|
|
16826
17403
|
ConsoleOutput.newline();
|
|
@@ -16837,7 +17414,7 @@ function printWarnings(warnings) {
|
|
|
16837
17414
|
}
|
|
16838
17415
|
}
|
|
16839
17416
|
}
|
|
16840
|
-
async function compileCommand(options) {
|
|
17417
|
+
async function compileCommand(options, services = createDefaultServices()) {
|
|
16841
17418
|
const spinner = createSpinner("Loading configuration...").start();
|
|
16842
17419
|
try {
|
|
16843
17420
|
const config = await loadConfig(options.config);
|
|
@@ -16845,6 +17422,7 @@ async function compileCommand(options) {
|
|
|
16845
17422
|
const selectedTarget = options.target ?? options.format;
|
|
16846
17423
|
const targets = selectedTarget ? [{ name: selectedTarget }] : parseTargets(config.targets);
|
|
16847
17424
|
const registryPath = options.registry ?? config.registry?.path ?? "./registry";
|
|
17425
|
+
const prettierOptions = await resolvePrettierOptions(config, process.cwd());
|
|
16848
17426
|
const compiler = new Compiler({
|
|
16849
17427
|
resolver: {
|
|
16850
17428
|
registryPath,
|
|
@@ -16852,10 +17430,11 @@ async function compileCommand(options) {
|
|
|
16852
17430
|
},
|
|
16853
17431
|
validator: config.validation,
|
|
16854
17432
|
formatters: targets,
|
|
16855
|
-
customConventions: config.customConventions
|
|
17433
|
+
customConventions: config.customConventions,
|
|
17434
|
+
prettier: prettierOptions
|
|
16856
17435
|
});
|
|
16857
|
-
const entryPath =
|
|
16858
|
-
if (!
|
|
17436
|
+
const entryPath = resolve4("./.promptscript/project.prs");
|
|
17437
|
+
if (!existsSync7(entryPath)) {
|
|
16859
17438
|
spinner.fail("Entry file not found");
|
|
16860
17439
|
ConsoleOutput.error(`File not found: ${entryPath}`);
|
|
16861
17440
|
ConsoleOutput.muted("Run: prs init");
|
|
@@ -16870,15 +17449,27 @@ async function compileCommand(options) {
|
|
|
16870
17449
|
}
|
|
16871
17450
|
spinner.succeed("Compilation successful");
|
|
16872
17451
|
ConsoleOutput.newline();
|
|
16873
|
-
await writeOutputs(result.outputs, options, config);
|
|
17452
|
+
const writeResult = await writeOutputs(result.outputs, options, config, services);
|
|
17453
|
+
if (writeResult.skipped.length > 0) {
|
|
17454
|
+
ConsoleOutput.muted(`Skipped ${writeResult.skipped.length} file(s)`);
|
|
17455
|
+
}
|
|
16874
17456
|
printStats(result.stats);
|
|
16875
17457
|
printWarnings(result.warnings);
|
|
16876
17458
|
if (options.watch) {
|
|
16877
17459
|
ConsoleOutput.newline();
|
|
16878
17460
|
ConsoleOutput.info("Watching for changes... (Ctrl+C to stop)");
|
|
16879
|
-
watchForChanges(
|
|
17461
|
+
watchForChanges(
|
|
17462
|
+
"./.promptscript",
|
|
17463
|
+
() => compileCommand({ ...options, watch: false }, services)
|
|
17464
|
+
);
|
|
16880
17465
|
}
|
|
16881
17466
|
} catch (error) {
|
|
17467
|
+
if (error.name === "ExitPromptError") {
|
|
17468
|
+
spinner.stop();
|
|
17469
|
+
ConsoleOutput.newline();
|
|
17470
|
+
ConsoleOutput.muted("Compilation cancelled");
|
|
17471
|
+
return;
|
|
17472
|
+
}
|
|
16882
17473
|
spinner.fail("Error");
|
|
16883
17474
|
ConsoleOutput.error(error.message);
|
|
16884
17475
|
process.exit(1);
|
|
@@ -16919,8 +17510,8 @@ function watchForChanges(dir, callback) {
|
|
|
16919
17510
|
}
|
|
16920
17511
|
|
|
16921
17512
|
// packages/cli/src/commands/validate.ts
|
|
16922
|
-
import { resolve as
|
|
16923
|
-
import { existsSync as
|
|
17513
|
+
import { resolve as resolve5 } from "path";
|
|
17514
|
+
import { existsSync as existsSync8 } from "fs";
|
|
16924
17515
|
function printValidationErrors(errors) {
|
|
16925
17516
|
if (errors.length === 0) return;
|
|
16926
17517
|
console.log(`Errors (${errors.length}):`);
|
|
@@ -17010,8 +17601,8 @@ async function validateCommand(options) {
|
|
|
17010
17601
|
formatters: []
|
|
17011
17602
|
// No formatters needed for validation only
|
|
17012
17603
|
});
|
|
17013
|
-
const entryPath =
|
|
17014
|
-
if (!
|
|
17604
|
+
const entryPath = resolve5("./.promptscript/project.prs");
|
|
17605
|
+
if (!existsSync8(entryPath)) {
|
|
17015
17606
|
handleEntryNotFound(entryPath, isJsonFormat, spinner);
|
|
17016
17607
|
}
|
|
17017
17608
|
const result = await compiler.compile(entryPath);
|
|
@@ -17051,8 +17642,8 @@ function outputJsonResult(result) {
|
|
|
17051
17642
|
|
|
17052
17643
|
// packages/cli/src/commands/pull.ts
|
|
17053
17644
|
import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
|
|
17054
|
-
import { existsSync as
|
|
17055
|
-
import { resolve as
|
|
17645
|
+
import { existsSync as existsSync9 } from "fs";
|
|
17646
|
+
import { resolve as resolve6, dirname as dirname6 } from "path";
|
|
17056
17647
|
async function pullCommand(options) {
|
|
17057
17648
|
const spinner = createSpinner("Loading configuration...").start();
|
|
17058
17649
|
try {
|
|
@@ -17075,8 +17666,8 @@ async function pullCommand(options) {
|
|
|
17075
17666
|
}
|
|
17076
17667
|
spinner.text = `Fetching ${inheritPath}...`;
|
|
17077
17668
|
const content = await registry.fetch(inheritPath);
|
|
17078
|
-
const destPath =
|
|
17079
|
-
if (
|
|
17669
|
+
const destPath = resolve6("./.promptscript/.inherited", inheritPath);
|
|
17670
|
+
if (existsSync9(destPath) && !options.force && !options.dryRun) {
|
|
17080
17671
|
spinner.warn("File already exists (use --force to overwrite)");
|
|
17081
17672
|
ConsoleOutput.muted(destPath);
|
|
17082
17673
|
return;
|
|
@@ -17086,12 +17677,12 @@ async function pullCommand(options) {
|
|
|
17086
17677
|
ConsoleOutput.newline();
|
|
17087
17678
|
ConsoleOutput.dryRun(`Would fetch: ${config.inherit}`);
|
|
17088
17679
|
ConsoleOutput.dryRun(` to: ${destPath}`);
|
|
17089
|
-
if (
|
|
17680
|
+
if (existsSync9(destPath)) {
|
|
17090
17681
|
ConsoleOutput.dryRun("(would overwrite existing file)");
|
|
17091
17682
|
}
|
|
17092
17683
|
return;
|
|
17093
17684
|
}
|
|
17094
|
-
await mkdir3(
|
|
17685
|
+
await mkdir3(dirname6(destPath), { recursive: true });
|
|
17095
17686
|
await writeFile3(destPath, content, "utf-8");
|
|
17096
17687
|
spinner.succeed("Pulled from registry");
|
|
17097
17688
|
ConsoleOutput.success(destPath);
|
|
@@ -17134,10 +17725,10 @@ async function createRegistry(config, options, spinner) {
|
|
|
17134
17725
|
}
|
|
17135
17726
|
const registryPath = config.registry?.path ?? "./registry";
|
|
17136
17727
|
spinner.text = `Using local registry: ${registryPath}...`;
|
|
17137
|
-
if (!
|
|
17728
|
+
if (!existsSync9(registryPath)) {
|
|
17138
17729
|
throw new Error(`Local registry path not found: ${registryPath}`);
|
|
17139
17730
|
}
|
|
17140
|
-
return createFileSystemRegistry(
|
|
17731
|
+
return createFileSystemRegistry(resolve6(registryPath));
|
|
17141
17732
|
}
|
|
17142
17733
|
function parseInheritPath(inheritPath) {
|
|
17143
17734
|
const versionIndex = inheritPath.lastIndexOf("@");
|
|
@@ -17184,89 +17775,9 @@ function handlePullError(error, spinner) {
|
|
|
17184
17775
|
}
|
|
17185
17776
|
|
|
17186
17777
|
// packages/cli/src/commands/diff.ts
|
|
17187
|
-
import { resolve as
|
|
17188
|
-
import { readFile as
|
|
17189
|
-
import { existsSync as
|
|
17190
|
-
|
|
17191
|
-
// packages/cli/src/output/pager.ts
|
|
17192
|
-
import { spawn } from "child_process";
|
|
17193
|
-
function isTTY() {
|
|
17194
|
-
return process.stdout.isTTY === true;
|
|
17195
|
-
}
|
|
17196
|
-
function getPagerCommand() {
|
|
17197
|
-
return process.env["PAGER"] ?? "less";
|
|
17198
|
-
}
|
|
17199
|
-
var Pager = class {
|
|
17200
|
-
lines = [];
|
|
17201
|
-
enabled;
|
|
17202
|
-
constructor(enabled = true) {
|
|
17203
|
-
this.enabled = enabled && isTTY();
|
|
17204
|
-
}
|
|
17205
|
-
/**
|
|
17206
|
-
* Write a line to the pager buffer.
|
|
17207
|
-
*/
|
|
17208
|
-
write(line) {
|
|
17209
|
-
this.lines.push(line);
|
|
17210
|
-
}
|
|
17211
|
-
/**
|
|
17212
|
-
* Write multiple lines to the pager buffer.
|
|
17213
|
-
*/
|
|
17214
|
-
writeLines(lines) {
|
|
17215
|
-
this.lines.push(...lines);
|
|
17216
|
-
}
|
|
17217
|
-
/**
|
|
17218
|
-
* Flush all buffered content through the pager.
|
|
17219
|
-
* If pager is disabled or not a TTY, just prints to stdout.
|
|
17220
|
-
*/
|
|
17221
|
-
async flush() {
|
|
17222
|
-
const content = this.lines.join("\n");
|
|
17223
|
-
if (!this.enabled || this.lines.length === 0) {
|
|
17224
|
-
if (content) {
|
|
17225
|
-
console.log(content);
|
|
17226
|
-
}
|
|
17227
|
-
return;
|
|
17228
|
-
}
|
|
17229
|
-
return new Promise((resolve7) => {
|
|
17230
|
-
const pagerCmd = getPagerCommand();
|
|
17231
|
-
const [cmd, ...args] = pagerCmd.split(" ");
|
|
17232
|
-
if (cmd === "less" && !args.includes("-R")) {
|
|
17233
|
-
args.push("-R");
|
|
17234
|
-
}
|
|
17235
|
-
if (!cmd) {
|
|
17236
|
-
console.log(content);
|
|
17237
|
-
resolve7();
|
|
17238
|
-
return;
|
|
17239
|
-
}
|
|
17240
|
-
const pager = spawn(cmd, args, {
|
|
17241
|
-
stdio: ["pipe", "inherit", "inherit"],
|
|
17242
|
-
env: {
|
|
17243
|
-
...process.env,
|
|
17244
|
-
// Ensure less handles colors properly
|
|
17245
|
-
LESS: process.env["LESS"] ?? "-R"
|
|
17246
|
-
}
|
|
17247
|
-
});
|
|
17248
|
-
pager.on("error", (_err) => {
|
|
17249
|
-
console.log(content);
|
|
17250
|
-
resolve7();
|
|
17251
|
-
});
|
|
17252
|
-
pager.on("close", () => {
|
|
17253
|
-
resolve7();
|
|
17254
|
-
});
|
|
17255
|
-
if (pager.stdin) {
|
|
17256
|
-
pager.stdin.write(content);
|
|
17257
|
-
pager.stdin.end();
|
|
17258
|
-
} else {
|
|
17259
|
-
console.log(content);
|
|
17260
|
-
resolve7();
|
|
17261
|
-
}
|
|
17262
|
-
});
|
|
17263
|
-
}
|
|
17264
|
-
};
|
|
17265
|
-
function createPager(enabled = true) {
|
|
17266
|
-
return new Pager(enabled);
|
|
17267
|
-
}
|
|
17268
|
-
|
|
17269
|
-
// packages/cli/src/commands/diff.ts
|
|
17778
|
+
import { resolve as resolve7 } from "path";
|
|
17779
|
+
import { readFile as readFile7 } from "fs/promises";
|
|
17780
|
+
import { existsSync as existsSync10 } from "fs";
|
|
17270
17781
|
import chalk2 from "chalk";
|
|
17271
17782
|
function configureColors(options) {
|
|
17272
17783
|
if (options.color === false) {
|
|
@@ -17300,16 +17811,16 @@ function printNewFilePreview(content, showFull, pager) {
|
|
|
17300
17811
|
}
|
|
17301
17812
|
}
|
|
17302
17813
|
async function compareOutput(_name, output, _config, showFull, pager) {
|
|
17303
|
-
const outputPath =
|
|
17814
|
+
const outputPath = resolve7(output.path);
|
|
17304
17815
|
const newContent = output.content;
|
|
17305
|
-
if (!
|
|
17816
|
+
if (!existsSync10(outputPath)) {
|
|
17306
17817
|
pager.write(chalk2.green(`+ ${outputPath} (new file)`));
|
|
17307
17818
|
pager.write("");
|
|
17308
17819
|
printNewFilePreview(newContent, showFull, pager);
|
|
17309
17820
|
pager.write("");
|
|
17310
17821
|
return true;
|
|
17311
17822
|
}
|
|
17312
|
-
const existingContent = await
|
|
17823
|
+
const existingContent = await readFile7(outputPath, "utf-8");
|
|
17313
17824
|
if (existingContent === newContent) {
|
|
17314
17825
|
pager.write(chalk2.gray(` ${outputPath} (no changes)`));
|
|
17315
17826
|
return false;
|
|
@@ -17338,8 +17849,8 @@ async function diffCommand(options) {
|
|
|
17338
17849
|
formatters: targets,
|
|
17339
17850
|
customConventions: config.customConventions
|
|
17340
17851
|
});
|
|
17341
|
-
const entryPath =
|
|
17342
|
-
if (!
|
|
17852
|
+
const entryPath = resolve7("./.promptscript/project.prs");
|
|
17853
|
+
if (!existsSync10(entryPath)) {
|
|
17343
17854
|
spinner.fail("Entry file not found");
|
|
17344
17855
|
ConsoleOutput.error(`File not found: ${entryPath}`);
|
|
17345
17856
|
ConsoleOutput.muted("Run: prs init");
|
|
@@ -17405,8 +17916,8 @@ function printSimpleDiff(existingLines, newLines, showFull, pager) {
|
|
|
17405
17916
|
}
|
|
17406
17917
|
|
|
17407
17918
|
// packages/cli/src/commands/check.ts
|
|
17408
|
-
import { existsSync as
|
|
17409
|
-
import { resolve as
|
|
17919
|
+
import { existsSync as existsSync11 } from "fs";
|
|
17920
|
+
import { resolve as resolve8 } from "path";
|
|
17410
17921
|
async function checkCommand(_options) {
|
|
17411
17922
|
const spinner = createSpinner("Checking project health...").start();
|
|
17412
17923
|
const results = [];
|
|
@@ -17468,7 +17979,7 @@ async function checkCommand(_options) {
|
|
|
17468
17979
|
});
|
|
17469
17980
|
}
|
|
17470
17981
|
const entryPath = config.input?.entry ?? ".promptscript/project.prs";
|
|
17471
|
-
if (
|
|
17982
|
+
if (existsSync11(entryPath)) {
|
|
17472
17983
|
results.push({
|
|
17473
17984
|
name: "Entry file",
|
|
17474
17985
|
status: "ok",
|
|
@@ -17483,8 +17994,8 @@ async function checkCommand(_options) {
|
|
|
17483
17994
|
hasErrors = true;
|
|
17484
17995
|
}
|
|
17485
17996
|
if (config.registry?.path) {
|
|
17486
|
-
const registryPath =
|
|
17487
|
-
if (
|
|
17997
|
+
const registryPath = resolve8(config.registry.path);
|
|
17998
|
+
if (existsSync11(registryPath)) {
|
|
17488
17999
|
results.push({
|
|
17489
18000
|
name: "Registry path",
|
|
17490
18001
|
status: "ok",
|
|
@@ -17567,7 +18078,7 @@ function printResults(results) {
|
|
|
17567
18078
|
|
|
17568
18079
|
// packages/cli/src/cli.ts
|
|
17569
18080
|
var __filename2 = fileURLToPath2(import.meta.url);
|
|
17570
|
-
var __dirname2 =
|
|
18081
|
+
var __dirname2 = dirname7(__filename2);
|
|
17571
18082
|
var program = new Command();
|
|
17572
18083
|
program.name("prs").description("PromptScript CLI - Standardize AI instructions").version(getPackageVersion(__dirname2, "./package.json")).option("--verbose", "Enable verbose output").option("--quiet", "Suppress non-error output").hook("preAction", (thisCommand) => {
|
|
17573
18084
|
const opts = thisCommand.opts();
|
|
@@ -17581,7 +18092,7 @@ program.name("prs").description("PromptScript CLI - Standardize AI instructions"
|
|
|
17581
18092
|
}
|
|
17582
18093
|
});
|
|
17583
18094
|
program.command("init").description("Initialize PromptScript in current directory").option("-n, --name <name>", "Project name (auto-detected from package.json, etc.)").option("-t, --team <team>", "Team namespace").option("--inherit <path>", "Inheritance path (e.g., @company/team)").option("--registry <path>", "Registry path").option("--targets <targets...>", "Target AI tools (github, claude, cursor)").option("-i, --interactive", "Force interactive mode").option("-y, --yes", "Skip prompts, use defaults").option("-f, --force", "Force reinitialize even if already initialized").action((opts) => initCommand(opts));
|
|
17584
|
-
program.command("compile").description("Compile PromptScript to target formats").option("-t, --target <target>", "Specific target (github, claude, cursor)").option("-f, --format <format>", "Output format (alias for --target)").option("-a, --all", "All configured targets", true).option("-w, --watch", "Watch mode").option("-o, --output <dir>", "Output directory").option("--dry-run", "Preview changes").option("--registry <path>", "Registry path (overrides config)").option("-c, --config <path>", "Path to custom config file").action(compileCommand);
|
|
18095
|
+
program.command("compile").description("Compile PromptScript to target formats").option("-t, --target <target>", "Specific target (github, claude, cursor)").option("-f, --format <format>", "Output format (alias for --target)").option("-a, --all", "All configured targets", true).option("-w, --watch", "Watch mode").option("-o, --output <dir>", "Output directory").option("--dry-run", "Preview changes").option("--registry <path>", "Registry path (overrides config)").option("-c, --config <path>", "Path to custom config file").option("--force", "Force overwrite existing files without prompts").action((opts) => compileCommand(opts));
|
|
17585
18096
|
program.command("validate").description("Validate PromptScript files").option("--strict", "Treat warnings as errors").option("--format <format>", "Output format (text, json)", "text").action(validateCommand);
|
|
17586
18097
|
program.command("pull").description("Pull updates from registry").option("-f, --force", "Force overwrite").option("--dry-run", "Preview changes without pulling").option("-b, --branch <name>", "Git branch to pull from").option("--tag <name>", "Git tag to pull from").option("--commit <hash>", "Git commit to pull from").option("--refresh", "Force re-fetch from remote (ignore cache)").action(pullCommand);
|
|
17587
18098
|
program.command("diff").description("Show diff for compiled output").option("-t, --target <target>", "Specific target").option("-a, --all", "Show diff for all targets at once").option("--full", "Show full diff without truncation").option("--no-pager", "Disable pager output").option("--color", "Force colored output").option("--no-color", "Disable colored output").action(diffCommand);
|