@promptscript/cli 1.0.0-alpha.5 → 1.0.0-alpha.6

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 CHANGED
@@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.0-alpha.6](https://github.com/mrwogu/promptscript/compare/v1.0.0-alpha.5...v1.0.0-alpha.6) (2026-01-28)
9
+
10
+
11
+ ### chore
12
+
13
+ * prepare alpha release ([970c1c8](https://github.com/mrwogu/promptscript/commit/970c1c8c6bc2ebdc4a508314ce7c9c38ddc10a6d))
14
+
15
+
16
+ ### Features
17
+
18
+ * **cli:** add --migrate flag to init command for AI-assisted migration ([3e567c6](https://github.com/mrwogu/promptscript/commit/3e567c606ddff779b841f76615a2aac93e35dec3))
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * **cli:** skip writing unchanged files during compilation ([8542512](https://github.com/mrwogu/promptscript/commit/854251214d927dd5f5dea0aea04a65e0f96819a2))
24
+
8
25
  ## [1.0.0-alpha.5](https://github.com/mrwogu/promptscript/compare/v1.0.0-alpha.4...v1.0.0-alpha.5) (2026-01-27)
9
26
 
10
27
 
package/index.js CHANGED
@@ -405,6 +405,13 @@ var ConsoleOutput = {
405
405
  if (isQuiet()) return;
406
406
  console.log(chalk.yellow(` \u2298 ${message}`));
407
407
  },
408
+ /**
409
+ * Print an unchanged file message.
410
+ */
411
+ unchanged(message) {
412
+ if (isQuiet()) return;
413
+ console.log(chalk.gray(` \u25CB ${message}`));
414
+ },
408
415
  /**
409
416
  * Print an info message.
410
417
  */
@@ -859,6 +866,506 @@ async function resolvePrettierOptions(config, basePath = process.cwd()) {
859
866
  return result;
860
867
  }
861
868
 
869
+ // packages/cli/src/templates/migrate-skill.ts
870
+ var MIGRATE_SKILL_CLAUDE = `---
871
+ name: 'migrate-to-promptscript'
872
+ description: 'Migrate existing AI instruction files to PromptScript format'
873
+ allowed-tools:
874
+ - Read
875
+ - Write
876
+ - Glob
877
+ - Grep
878
+ - Bash
879
+ user-invocable: true
880
+ ---
881
+
882
+ # Migrate to PromptScript
883
+
884
+ ## Overview
885
+
886
+ This skill guides you through migrating existing AI instruction files
887
+ to PromptScript format, creating a unified source of truth for all
888
+ AI coding assistants.
889
+
890
+ ## Step 1: Discovery
891
+
892
+ Search for existing instruction files using these patterns:
893
+
894
+ Claude Code:
895
+
896
+ - CLAUDE.md, claude.md, CLAUDE.local.md
897
+
898
+ Cursor:
899
+
900
+ - .cursorrules
901
+ - .cursor/rules/\\*.md
902
+ - .cursor/rules/\\*.mdc
903
+
904
+ GitHub Copilot:
905
+
906
+ - .github/copilot-instructions.md
907
+ - .github/instructions/\\*.md
908
+
909
+ Other:
910
+
911
+ - AGENTS.md
912
+ - AI_INSTRUCTIONS.md
913
+ - AI.md
914
+ - .ai/instructions.md
915
+
916
+ Use Glob tool to find these files.
917
+
918
+ ## Step 2: Read and Analyze
919
+
920
+ For each discovered file:
921
+
922
+ 1. Read the full content using the Read tool
923
+ 2. Identify sections by headers (##, ###) and patterns
924
+ 3. Classify content type using the mapping table below
925
+ 4. Note any tool-specific content that may need special handling
926
+
927
+ ## Step 3: Content Mapping
928
+
929
+ Map source content to PromptScript blocks:
930
+
931
+ | Source Pattern | PromptScript Block |
932
+ | ------------------------------------ | ------------------ |
933
+ | You are, persona, identity, role | @identity |
934
+ | Tech stack, languages, frameworks | @context |
935
+ | Coding standards, conventions, rules | @standards |
936
+ | Don't, Never, restrictions | @restrictions |
937
+ | Commands, shortcuts | @shortcuts |
938
+ | API docs, references, knowledge base | @knowledge |
939
+ | Parameters, config values | @params |
940
+ | File patterns, globs, applyTo | @guards |
941
+ | Skills, capabilities | @skills |
942
+ | Agents, subagents | @agents |
943
+ | Local-only settings | @local |
944
+
945
+ ## Step 4: Generate PromptScript
946
+
947
+ ### Required: @meta block
948
+
949
+ Every PromptScript file needs metadata with id and syntax fields.
950
+
951
+ ### Identity (persona)
952
+
953
+ Convert persona descriptions to @identity block with triple-quote string.
954
+
955
+ ### Context (project info)
956
+
957
+ Convert tech stack to @context block with structured properties
958
+ like project, languages, frameworks.
959
+
960
+ ### Standards (conventions)
961
+
962
+ Convert coding standards to @standards block organized by category:
963
+ code, naming, commits, etc.
964
+
965
+ ### Restrictions (don'ts)
966
+
967
+ Convert restrictions to @restrictions block using dash prefix for each item.
968
+
969
+ ### Shortcuts (commands)
970
+
971
+ Convert custom commands to @shortcuts block. Simple shortcuts use
972
+ key-value format. Complex shortcuts use object format with
973
+ prompt, description, and content fields.
974
+
975
+ ### Knowledge (references)
976
+
977
+ Convert API docs and reference material to @knowledge block
978
+ using triple-quote string for rich content.
979
+
980
+ ### Guards (file patterns)
981
+
982
+ Convert file-specific rules to @guards block with globs array
983
+ specifying file patterns.
984
+
985
+ ### Params (configuration)
986
+
987
+ Convert configuration parameters to @params block with type annotations:
988
+ range(), enum(), boolean.
989
+
990
+ ### Skills (capabilities)
991
+
992
+ Convert skill definitions to @skills block with description,
993
+ trigger, and content fields.
994
+
995
+ ### Agents (subagents)
996
+
997
+ Convert agent definitions to @agents block with description,
998
+ tools, model, and content fields.
999
+
1000
+ ## Step 5: File Organization
1001
+
1002
+ Simple Projects - single file structure:
1003
+
1004
+ - .promptscript/project.prs
1005
+ - promptscript.yaml
1006
+
1007
+ Complex Projects - modular file structure:
1008
+
1009
+ - .promptscript/project.prs (main with @use imports)
1010
+ - .promptscript/context.prs
1011
+ - .promptscript/standards.prs
1012
+ - .promptscript/restrictions.prs
1013
+ - .promptscript/commands.prs
1014
+ - promptscript.yaml
1015
+
1016
+ ## Step 6: Configuration
1017
+
1018
+ Create promptscript.yaml with:
1019
+
1020
+ - version: '1'
1021
+ - project.id
1022
+ - input.entry pointing to main .prs file
1023
+ - targets for github, claude, cursor
1024
+
1025
+ ## Step 7: Validation
1026
+
1027
+ After generating PromptScript files:
1028
+
1029
+ 1. Validate syntax: prs validate
1030
+ 2. Test compilation: prs compile --dry-run
1031
+ 3. Compare output with original files
1032
+ 4. Iterate if content is missing or incorrect
1033
+
1034
+ ## Common Patterns
1035
+
1036
+ ### Merging Multiple Sources
1037
+
1038
+ When instructions exist in multiple files:
1039
+
1040
+ 1. Identity: Take from most detailed source
1041
+ 2. Standards: Merge all, deduplicate
1042
+ 3. Restrictions: Combine all (union)
1043
+ 4. Commands: Merge, resolve conflicts
1044
+
1045
+ ### Tool-Specific Content
1046
+
1047
+ Handle tool-specific content:
1048
+
1049
+ - GitHub prompts: Use @shortcuts with prompt: true
1050
+ - Claude agents: Use @agents block
1051
+ - Cursor rules: Map to @standards
1052
+ - Local content: Use @local block
1053
+
1054
+ ### Preserving Formatting
1055
+
1056
+ Use triple-quote multiline strings for:
1057
+
1058
+ - Rich markdown content
1059
+ - Code examples
1060
+ - Complex instructions
1061
+
1062
+ ## Syntax Rules
1063
+
1064
+ Quick reference for PromptScript syntax:
1065
+
1066
+ - Strings: quoted or identifier
1067
+ - Multi-line: triple quotes
1068
+ - Arrays: [item1, item2] or - item prefix
1069
+ - Objects: { key: value }
1070
+ - Comments: # comment
1071
+ - Required @meta fields: id, syntax
1072
+
1073
+ ## Quality Checklist
1074
+
1075
+ Before completing migration:
1076
+
1077
+ - @meta block has id and syntax
1078
+ - Identity is clear and specific
1079
+ - Standards are organized by category
1080
+ - Restrictions use dash prefix (-)
1081
+ - Shortcuts work in target tools
1082
+ - prs validate passes
1083
+ - prs compile produces correct output
1084
+ - No duplicate content across blocks
1085
+
1086
+ ## Troubleshooting
1087
+
1088
+ ### Missing @meta Error
1089
+ Add required metadata block at the start.
1090
+
1091
+ ### Multiline String in Object Error
1092
+ Assign multiline strings to named keys, don't leave them loose
1093
+ inside objects.
1094
+
1095
+ ### Content Not Appearing in Output
1096
+ Check block names match expected patterns and
1097
+ verify syntax with prs validate --verbose.
1098
+ `;
1099
+ var MIGRATE_SKILL_CURSOR = `# Migrate to PromptScript
1100
+
1101
+ Use this command to migrate existing AI instruction files to PromptScript format.
1102
+
1103
+ ## Step 1: Discovery
1104
+
1105
+ Search for existing instruction files:
1106
+
1107
+ - CLAUDE.md, claude.md, CLAUDE.local.md
1108
+ - .cursorrules, .cursor/rules/*.mdc
1109
+ - .github/copilot-instructions.md
1110
+ - AGENTS.md, AI_INSTRUCTIONS.md
1111
+
1112
+ ## Step 2: Content Mapping
1113
+
1114
+ Map source content to PromptScript blocks:
1115
+
1116
+ | Source Pattern | PromptScript Block |
1117
+ | ------------------------------------ | ------------------ |
1118
+ | You are, persona, identity, role | @identity |
1119
+ | Tech stack, languages, frameworks | @context |
1120
+ | Coding standards, conventions, rules | @standards |
1121
+ | Don't, Never, restrictions | @restrictions |
1122
+ | Commands, shortcuts | @shortcuts |
1123
+ | API docs, references | @knowledge |
1124
+
1125
+ ## Step 3: Generate PromptScript
1126
+
1127
+ Create \`.promptscript/project.prs\` with:
1128
+
1129
+ 1. **@meta** block with id and syntax fields (required)
1130
+ 2. **@identity** for persona/role descriptions
1131
+ 3. **@context** for tech stack info
1132
+ 4. **@standards** organized by category
1133
+ 5. **@restrictions** with dash prefix for each item
1134
+ 6. **@shortcuts** for commands
1135
+
1136
+ ## Step 4: Validation
1137
+
1138
+ After generating:
1139
+
1140
+ 1. Run \`prs validate\`
1141
+ 2. Run \`prs compile --dry-run\`
1142
+ 3. Compare output with original files
1143
+
1144
+ ## Syntax Quick Reference
1145
+
1146
+ - Strings: quoted or identifier
1147
+ - Multi-line: triple quotes (\`"""\`)
1148
+ - Arrays: \`[item1, item2]\`
1149
+ - Objects: \`{ key: value }\`
1150
+ - Comments: \`# comment\`
1151
+
1152
+ ## Quality Checklist
1153
+
1154
+ - @meta block has id and syntax
1155
+ - Standards organized by category
1156
+ - Restrictions use dash prefix (-)
1157
+ - prs validate passes
1158
+ `;
1159
+ var MIGRATE_SKILL_ANTIGRAVITY = `# Migrate to PromptScript
1160
+
1161
+ This rule provides guidance for migrating existing AI instruction files to PromptScript format.
1162
+
1163
+ ## Overview
1164
+
1165
+ PromptScript creates a unified source of truth for all AI coding assistants,
1166
+ compiling to native formats for Claude, GitHub Copilot, Cursor, and Antigravity.
1167
+
1168
+ ## Step 1: Discovery
1169
+
1170
+ Search for existing instruction files:
1171
+
1172
+ - CLAUDE.md, claude.md, CLAUDE.local.md
1173
+ - .cursorrules, .cursor/rules/*.mdc
1174
+ - .github/copilot-instructions.md
1175
+ - .agent/rules/*.md
1176
+ - AGENTS.md, AI_INSTRUCTIONS.md
1177
+
1178
+ ## Step 2: Content Mapping
1179
+
1180
+ Map source content to PromptScript blocks:
1181
+
1182
+ | Source Pattern | PromptScript Block |
1183
+ | ------------------------------------ | ------------------ |
1184
+ | You are, persona, identity, role | @identity |
1185
+ | Tech stack, languages, frameworks | @context |
1186
+ | Coding standards, conventions, rules | @standards |
1187
+ | Don't, Never, restrictions | @restrictions |
1188
+ | Commands, shortcuts | @shortcuts |
1189
+ | API docs, references | @knowledge |
1190
+
1191
+ ## Step 3: Generate PromptScript
1192
+
1193
+ Create \`.promptscript/project.prs\` with required blocks:
1194
+
1195
+ 1. **@meta** - id and syntax fields (required)
1196
+ 2. **@identity** - persona/role descriptions
1197
+ 3. **@context** - tech stack info
1198
+ 4. **@standards** - coding rules organized by category
1199
+ 5. **@restrictions** - things to avoid (dash prefix)
1200
+ 6. **@shortcuts** - commands
1201
+
1202
+ ## Step 4: Validation
1203
+
1204
+ After generating PromptScript files:
1205
+
1206
+ 1. Run \`prs validate\` to check syntax
1207
+ 2. Run \`prs compile --dry-run\` to preview output
1208
+ 3. Compare compiled output with original files
1209
+
1210
+ ## Syntax Reference
1211
+
1212
+ - Strings: quoted or identifier
1213
+ - Multi-line: triple quotes
1214
+ - Arrays: [item1, item2]
1215
+ - Objects: { key: value }
1216
+ - Comments: # comment
1217
+ `;
1218
+ var MIGRATE_SKILL_GITHUB = `---
1219
+ name: 'migrate-to-promptscript'
1220
+ description: 'Migrate existing AI instruction files to PromptScript format'
1221
+ allowed-tools:
1222
+ - read
1223
+ - write
1224
+ - glob
1225
+ - grep
1226
+ - execute
1227
+ user-invocable: true
1228
+ ---
1229
+
1230
+ # Migrate to PromptScript
1231
+
1232
+ ## Overview
1233
+
1234
+ This skill guides you through migrating existing AI instruction files
1235
+ to PromptScript format, creating a unified source of truth for all
1236
+ AI coding assistants.
1237
+
1238
+ ## Step 1: Discovery
1239
+
1240
+ Search for existing instruction files using these patterns:
1241
+
1242
+ Claude Code:
1243
+
1244
+ - CLAUDE.md, claude.md, CLAUDE.local.md
1245
+
1246
+ Cursor:
1247
+
1248
+ - .cursorrules
1249
+ - .cursor/rules/\\*.md
1250
+ - .cursor/rules/\\*.mdc
1251
+
1252
+ GitHub Copilot:
1253
+
1254
+ - .github/copilot-instructions.md
1255
+ - .github/instructions/\\*.md
1256
+
1257
+ Other:
1258
+
1259
+ - AGENTS.md
1260
+ - AI_INSTRUCTIONS.md
1261
+ - AI.md
1262
+ - .ai/instructions.md
1263
+
1264
+ ## Step 2: Read and Analyze
1265
+
1266
+ For each discovered file:
1267
+
1268
+ 1. Read the full content
1269
+ 2. Identify sections by headers (##, ###) and patterns
1270
+ 3. Classify content type using the mapping table below
1271
+ 4. Note any tool-specific content that may need special handling
1272
+
1273
+ ## Step 3: Content Mapping
1274
+
1275
+ Map source content to PromptScript blocks:
1276
+
1277
+ | Source Pattern | PromptScript Block |
1278
+ | ------------------------------------ | ------------------ |
1279
+ | You are, persona, identity, role | @identity |
1280
+ | Tech stack, languages, frameworks | @context |
1281
+ | Coding standards, conventions, rules | @standards |
1282
+ | Don't, Never, restrictions | @restrictions |
1283
+ | Commands, shortcuts | @shortcuts |
1284
+ | API docs, references, knowledge base | @knowledge |
1285
+ | Parameters, config values | @params |
1286
+ | File patterns, globs, applyTo | @guards |
1287
+ | Skills, capabilities | @skills |
1288
+ | Agents, subagents | @agents |
1289
+ | Local-only settings | @local |
1290
+
1291
+ ## Step 4: Generate PromptScript
1292
+
1293
+ ### Required: @meta block
1294
+
1295
+ Every PromptScript file needs metadata with id and syntax fields.
1296
+
1297
+ ### Identity (persona)
1298
+
1299
+ Convert persona descriptions to @identity block with triple-quote string.
1300
+
1301
+ ### Context (project info)
1302
+
1303
+ Convert tech stack to @context block with structured properties
1304
+ like project, languages, frameworks.
1305
+
1306
+ ### Standards (conventions)
1307
+
1308
+ Convert coding standards to @standards block organized by category:
1309
+ code, naming, commits, etc.
1310
+
1311
+ ### Restrictions (don'ts)
1312
+
1313
+ Convert restrictions to @restrictions block using dash prefix for each item.
1314
+
1315
+ ### Shortcuts (commands)
1316
+
1317
+ Convert custom commands to @shortcuts block. Simple shortcuts use
1318
+ key-value format. Complex shortcuts use object format with
1319
+ prompt, description, and content fields.
1320
+
1321
+ ## Step 5: File Organization
1322
+
1323
+ Simple Projects - single file structure:
1324
+
1325
+ - .promptscript/project.prs
1326
+ - promptscript.yaml
1327
+
1328
+ Complex Projects - modular file structure:
1329
+
1330
+ - .promptscript/project.prs (main with @use imports)
1331
+ - .promptscript/context.prs
1332
+ - .promptscript/standards.prs
1333
+ - .promptscript/restrictions.prs
1334
+ - .promptscript/commands.prs
1335
+ - promptscript.yaml
1336
+
1337
+ ## Step 6: Configuration
1338
+
1339
+ Create promptscript.yaml with:
1340
+
1341
+ - version: '1'
1342
+ - project.id
1343
+ - input.entry pointing to main .prs file
1344
+ - targets for github, claude, cursor
1345
+
1346
+ ## Step 7: Validation
1347
+
1348
+ After generating PromptScript files:
1349
+
1350
+ 1. Validate syntax: prs validate
1351
+ 2. Test compilation: prs compile --dry-run
1352
+ 3. Compare output with original files
1353
+ 4. Iterate if content is missing or incorrect
1354
+
1355
+ ## Quality Checklist
1356
+
1357
+ Before completing migration:
1358
+
1359
+ - @meta block has id and syntax
1360
+ - Identity is clear and specific
1361
+ - Standards are organized by category
1362
+ - Restrictions use dash prefix (-)
1363
+ - Shortcuts work in target tools
1364
+ - prs validate passes
1365
+ - prs compile produces correct output
1366
+ - No duplicate content across blocks
1367
+ `;
1368
+
862
1369
  // packages/cli/src/commands/init.ts
863
1370
  var __filename = fileURLToPath(import.meta.url);
864
1371
  var __dirname = dirname2(__filename);
@@ -886,11 +1393,45 @@ async function initCommand(options, services = createDefaultServices()) {
886
1393
  await fs4.writeFile("promptscript.yaml", configContent, "utf-8");
887
1394
  const projectPsContent = generateProjectPs(config, projectInfo);
888
1395
  await fs4.writeFile(".promptscript/project.prs", projectPsContent, "utf-8");
1396
+ const installedSkillPaths = [];
1397
+ if (options.migrate) {
1398
+ if (config.targets.includes("claude")) {
1399
+ await fs4.mkdir(".claude/skills/migrate-to-promptscript", { recursive: true });
1400
+ await fs4.writeFile(
1401
+ ".claude/skills/migrate-to-promptscript/SKILL.md",
1402
+ MIGRATE_SKILL_CLAUDE,
1403
+ "utf-8"
1404
+ );
1405
+ installedSkillPaths.push(".claude/skills/migrate-to-promptscript/SKILL.md");
1406
+ }
1407
+ if (config.targets.includes("github")) {
1408
+ await fs4.mkdir(".github/skills/migrate-to-promptscript", { recursive: true });
1409
+ await fs4.writeFile(
1410
+ ".github/skills/migrate-to-promptscript/SKILL.md",
1411
+ MIGRATE_SKILL_GITHUB,
1412
+ "utf-8"
1413
+ );
1414
+ installedSkillPaths.push(".github/skills/migrate-to-promptscript/SKILL.md");
1415
+ }
1416
+ if (config.targets.includes("cursor")) {
1417
+ await fs4.mkdir(".cursor/commands", { recursive: true });
1418
+ await fs4.writeFile(".cursor/commands/migrate.md", MIGRATE_SKILL_CURSOR, "utf-8");
1419
+ installedSkillPaths.push(".cursor/commands/migrate.md");
1420
+ }
1421
+ if (config.targets.includes("antigravity")) {
1422
+ await fs4.mkdir(".agent/rules", { recursive: true });
1423
+ await fs4.writeFile(".agent/rules/migrate.md", MIGRATE_SKILL_ANTIGRAVITY, "utf-8");
1424
+ installedSkillPaths.push(".agent/rules/migrate.md");
1425
+ }
1426
+ }
889
1427
  spinner.succeed("PromptScript initialized");
890
1428
  ConsoleOutput.newline();
891
1429
  console.log("Created:");
892
1430
  ConsoleOutput.success("promptscript.yaml");
893
1431
  ConsoleOutput.success(".promptscript/project.prs");
1432
+ for (const skillPath of installedSkillPaths) {
1433
+ ConsoleOutput.success(skillPath);
1434
+ }
894
1435
  ConsoleOutput.newline();
895
1436
  console.log("Configuration:");
896
1437
  ConsoleOutput.muted(` Project: ${config.projectId}`);
@@ -911,17 +1452,35 @@ async function initCommand(options, services = createDefaultServices()) {
911
1452
  }
912
1453
  ConsoleOutput.newline();
913
1454
  console.log("Next steps:");
914
- ConsoleOutput.muted("1. Edit .promptscript/project.prs to customize your AI instructions");
915
- ConsoleOutput.muted("2. Run: prs compile");
916
- if (hasMigrationCandidates(aiToolsDetection)) {
917
- const migrationHint = formatMigrationHint(aiToolsDetection);
918
- for (const line of migrationHint) {
919
- if (line.startsWith("\u{1F4CB}") || line.includes("migrated") || line.includes("See:") || line.includes("Or use")) {
920
- ConsoleOutput.info(line.replace(/^\s+/, ""));
921
- } else if (line.trim().startsWith("\u2022")) {
922
- ConsoleOutput.muted(line);
923
- } else if (line.trim()) {
924
- console.log(line);
1455
+ if (options.migrate && installedSkillPaths.length > 0) {
1456
+ ConsoleOutput.muted("1. Use the migration skill to convert existing instructions:");
1457
+ if (config.targets.includes("claude")) {
1458
+ ConsoleOutput.muted(" Claude Code: /migrate");
1459
+ }
1460
+ if (config.targets.includes("github")) {
1461
+ ConsoleOutput.muted(" GitHub Copilot: @workspace /migrate");
1462
+ }
1463
+ if (config.targets.includes("cursor")) {
1464
+ ConsoleOutput.muted(" Cursor: /migrate");
1465
+ }
1466
+ if (config.targets.includes("antigravity")) {
1467
+ ConsoleOutput.muted(' Antigravity: Ask to "migrate to PromptScript"');
1468
+ }
1469
+ ConsoleOutput.muted("2. Review generated .promptscript/project.prs");
1470
+ ConsoleOutput.muted("3. Run: prs compile");
1471
+ } else {
1472
+ ConsoleOutput.muted("1. Edit .promptscript/project.prs to customize your AI instructions");
1473
+ ConsoleOutput.muted("2. Run: prs compile");
1474
+ if (hasMigrationCandidates(aiToolsDetection)) {
1475
+ const migrationHint = formatMigrationHint(aiToolsDetection);
1476
+ for (const line of migrationHint) {
1477
+ if (line.startsWith("\u{1F4CB}") || line.includes("migrated") || line.includes("See:") || line.includes("Or use")) {
1478
+ ConsoleOutput.info(line.replace(/^\s+/, ""));
1479
+ } else if (line.trim().startsWith("\u2022")) {
1480
+ ConsoleOutput.muted(line);
1481
+ } else if (line.trim()) {
1482
+ console.log(line);
1483
+ }
925
1484
  }
926
1485
  }
927
1486
  }
@@ -1365,10 +1924,26 @@ ${this.convention.rootWrapper.end}`;
1365
1924
  /**
1366
1925
  * Escape markdown special characters for Prettier compatibility.
1367
1926
  * - Escapes __ to \_\_ (to avoid emphasis)
1368
- * - Escapes /* to /\* (to avoid glob patterns being interpreted)
1927
+ * - Escapes * in glob patterns (like packages/*) outside backticks
1369
1928
  */
1370
1929
  escapeMarkdownSpecialChars(content) {
1371
- return content.replace(/__/g, "\\_\\_").replace(/\/\*/g, "/\\*");
1930
+ return content.split("\n").map((line) => {
1931
+ let result = line.replace(/__/g, "\\_\\_");
1932
+ result = this.escapeGlobAsteriskOutsideBackticks(result);
1933
+ return result;
1934
+ }).join("\n");
1935
+ }
1936
+ /**
1937
+ * Escape glob asterisks (like packages/* or .cursor/rules/*.md) outside of backticks.
1938
+ */
1939
+ escapeGlobAsteriskOutsideBackticks(line) {
1940
+ const parts = line.split("`");
1941
+ return parts.map((part, index) => {
1942
+ if (index % 2 === 0) {
1943
+ return part.replace(/\/\*/g, "/\\*");
1944
+ }
1945
+ return part;
1946
+ }).join("`");
1372
1947
  }
1373
1948
  indentContent(content, renderer, level) {
1374
1949
  const indent = renderer.indent ?? "";
@@ -1540,6 +2115,7 @@ var BaseFormatter = class {
1540
2115
  * - Trims trailing whitespace from lines
1541
2116
  * - Normalizes markdown table formatting
1542
2117
  * - Adds blank lines before lists when preceded by text
2118
+ * - Adds blank lines before code blocks when preceded by text
1543
2119
  * - Escapes markdown special characters in paths
1544
2120
  */
1545
2121
  normalizeMarkdownForPrettier(content) {
@@ -1548,8 +2124,13 @@ var BaseFormatter = class {
1548
2124
  let inCodeBlock = false;
1549
2125
  for (const line of lines) {
1550
2126
  const trimmed = line.trimEnd();
1551
- if (trimmed.startsWith("```")) {
2127
+ if (trimmed.trimStart().startsWith("```")) {
1552
2128
  inCodeBlock = !inCodeBlock;
2129
+ if (trimmed.length > 0) {
2130
+ const match2 = line.match(/^(\s*)/);
2131
+ const leadingSpaces2 = match2?.[1]?.length ?? 0;
2132
+ minIndent = Math.min(minIndent, leadingSpaces2);
2133
+ }
1553
2134
  continue;
1554
2135
  }
1555
2136
  if (inCodeBlock) continue;
@@ -1565,17 +2146,30 @@ var BaseFormatter = class {
1565
2146
  inCodeBlock = false;
1566
2147
  for (const line of lines) {
1567
2148
  const trimmedLine = line.trimEnd();
1568
- if (trimmedLine.trimStart().startsWith("```")) {
2149
+ const unindentedLine = minIndent > 0 ? trimmedLine.slice(minIndent) : trimmedLine;
2150
+ const isCodeBlockMarker = trimmedLine.trimStart().startsWith("```");
2151
+ const isCodeBlockStart = isCodeBlockMarker && !inCodeBlock;
2152
+ if (isCodeBlockMarker) {
1569
2153
  inCodeBlock = !inCodeBlock;
1570
2154
  }
1571
- const unindentedLine = minIndent > 0 ? trimmedLine.slice(minIndent) : trimmedLine;
1572
2155
  if (inCodeBlock || unindentedLine.startsWith("```")) {
2156
+ if (isCodeBlockStart) {
2157
+ const prevLine2 = result.length > 0 ? result[result.length - 1] ?? "" : "";
2158
+ if (prevLine2.trim() && !prevLine2.startsWith("#")) {
2159
+ result.push("");
2160
+ }
2161
+ }
1573
2162
  result.push(unindentedLine);
1574
2163
  continue;
1575
2164
  }
1576
2165
  let processedLine = unindentedLine;
1577
2166
  processedLine = processedLine.replace(/__([^_]+)__/g, "\\_\\_$1\\_\\_");
1578
- processedLine = processedLine.replace(/\/\*/g, "/\\*");
2167
+ processedLine = this.escapeGlobAsteriskOutsideBackticks(processedLine);
2168
+ const prevLine = result.length > 0 ? result[result.length - 1] : "";
2169
+ const isHeader = prevLine?.trimStart().startsWith("#");
2170
+ if (isHeader && processedLine.trim()) {
2171
+ result.push("");
2172
+ }
1579
2173
  if (processedLine.trimStart().startsWith("|") && processedLine.trimEnd().endsWith("|")) {
1580
2174
  inTable = true;
1581
2175
  tableLines.push(processedLine.trim());
@@ -1585,9 +2179,14 @@ var BaseFormatter = class {
1585
2179
  tableLines = [];
1586
2180
  inTable = false;
1587
2181
  }
1588
- const prevLine = result.length > 0 ? result[result.length - 1] : "";
1589
2182
  const isListItem = processedLine.trimStart().startsWith("- ");
1590
- if (isListItem && prevLine && !prevLine.trimStart().startsWith("- ")) {
2183
+ const isNumberedItem = /^\d+\.\s/.test(processedLine.trimStart());
2184
+ const prevLineTrimmed = prevLine?.trimStart() ?? "";
2185
+ const isPrevListItem = prevLineTrimmed.startsWith("- ") || /^\d+\.\s/.test(prevLineTrimmed);
2186
+ const prevEndsWithColon = prevLine?.trimEnd().endsWith(":") ?? false;
2187
+ if ((isListItem || isNumberedItem) && prevLine && !isPrevListItem && !isHeader) {
2188
+ result.push("");
2189
+ } else if ((isListItem || isNumberedItem) && prevEndsWithColon) {
1591
2190
  result.push("");
1592
2191
  }
1593
2192
  result.push(processedLine);
@@ -1598,6 +2197,19 @@ var BaseFormatter = class {
1598
2197
  }
1599
2198
  return result.join("\n");
1600
2199
  }
2200
+ /**
2201
+ * Escape glob asterisks (like packages/* or .cursor/rules/*.md) outside of backticks.
2202
+ * Prettier escapes these to prevent them from being interpreted as emphasis markers.
2203
+ */
2204
+ escapeGlobAsteriskOutsideBackticks(line) {
2205
+ const parts = line.split("`");
2206
+ return parts.map((part, index) => {
2207
+ if (index % 2 === 0) {
2208
+ return part.replace(/\/\*/g, "/\\*");
2209
+ }
2210
+ return part;
2211
+ }).join("`");
2212
+ }
1601
2213
  /**
1602
2214
  * Strip all leading indentation from markdown content.
1603
2215
  * Used for AGENTS.md where content from multiple sources has inconsistent indentation.
@@ -1611,7 +2223,7 @@ var BaseFormatter = class {
1611
2223
  const trimmedEnd = line.trimEnd();
1612
2224
  if (trimmedEnd.trimStart().startsWith("```")) {
1613
2225
  if (!inCodeBlock) {
1614
- const prevLine2 = result.length > 0 ? result[result.length - 1] : "";
2226
+ const prevLine2 = result.length > 0 ? result[result.length - 1] ?? "" : "";
1615
2227
  if (prevLine2 && prevLine2.trim()) {
1616
2228
  result.push("");
1617
2229
  }
@@ -1626,9 +2238,14 @@ var BaseFormatter = class {
1626
2238
  }
1627
2239
  let stripped = trimmedEnd.trimStart();
1628
2240
  stripped = stripped.replace(/__/g, "\\_\\_");
1629
- stripped = stripped.replace(/\/\*/g, "/\\*");
1630
- const prevLine = result.length > 0 ? result[result.length - 1] : "";
1631
- if (stripped.startsWith("- ") && prevLine && !prevLine.startsWith("- ")) {
2241
+ stripped = this.escapeGlobAsteriskOutsideBackticks(stripped);
2242
+ const prevLine = result.length > 0 ? result[result.length - 1] ?? "" : "";
2243
+ const isListItem = stripped.startsWith("- ") || /^\d+\.\s/.test(stripped);
2244
+ const isPrevList = prevLine.startsWith("- ") || /^\d+\.\s/.test(prevLine);
2245
+ const prevEndsWithColon = prevLine.trimEnd().endsWith(":");
2246
+ if (isListItem && prevLine && !isPrevList) {
2247
+ result.push("");
2248
+ } else if (isListItem && prevEndsWithColon) {
1632
2249
  result.push("");
1633
2250
  }
1634
2251
  result.push(stripped);
@@ -1969,7 +2586,9 @@ var GitHubFormatter = class extends BaseFormatter {
1969
2586
  lines.push(`# ${config.description}`);
1970
2587
  lines.push("");
1971
2588
  if (config.content) {
1972
- lines.push(config.content);
2589
+ const dedentedContent = this.dedent(config.content);
2590
+ const normalizedContent = this.normalizeMarkdownForPrettier(dedentedContent);
2591
+ lines.push(normalizedContent);
1973
2592
  }
1974
2593
  return {
1975
2594
  path: `.github/instructions/${config.name}.instructions.md`,
@@ -2057,7 +2676,8 @@ var GitHubFormatter = class extends BaseFormatter {
2057
2676
  generatePromptFile(config) {
2058
2677
  const lines = [];
2059
2678
  lines.push("---");
2060
- lines.push(`description: "${config.description}"`);
2679
+ const descQuote = config.description.includes("'") ? '"' : "'";
2680
+ lines.push(`description: ${descQuote}${config.description}${descQuote}`);
2061
2681
  if (config.mode === "agent") {
2062
2682
  lines.push("mode: agent");
2063
2683
  if (config.tools && config.tools.length > 0) {
@@ -2069,11 +2689,13 @@ var GitHubFormatter = class extends BaseFormatter {
2069
2689
  lines.push("---");
2070
2690
  lines.push("");
2071
2691
  if (config.content) {
2072
- lines.push(config.content);
2692
+ const dedentedContent = this.dedent(config.content);
2693
+ const normalizedContent = this.normalizeMarkdownForPrettier(dedentedContent);
2694
+ lines.push(normalizedContent);
2073
2695
  }
2074
2696
  return {
2075
2697
  path: `.github/prompts/${config.name}.prompt.md`,
2076
- content: lines.join("\n")
2698
+ content: lines.join("\n") + "\n"
2077
2699
  };
2078
2700
  }
2079
2701
  // ============================================================
@@ -2115,7 +2737,8 @@ var GitHubFormatter = class extends BaseFormatter {
2115
2737
  lines.push("---");
2116
2738
  lines.push("");
2117
2739
  if (config.content) {
2118
- const normalizedContent = this.normalizeMarkdownForPrettier(config.content);
2740
+ const dedentedContent = this.dedent(config.content);
2741
+ const normalizedContent = this.normalizeMarkdownForPrettier(dedentedContent);
2119
2742
  lines.push(normalizedContent);
2120
2743
  }
2121
2744
  return {
@@ -2123,6 +2746,28 @@ var GitHubFormatter = class extends BaseFormatter {
2123
2746
  content: lines.join("\n") + "\n"
2124
2747
  };
2125
2748
  }
2749
+ /**
2750
+ * Remove common leading indentation from multiline text.
2751
+ * Calculates minimum indent from lines 2+ only, since line 1 may have been
2752
+ * trimmed (losing its indentation) while subsequent lines retain theirs.
2753
+ */
2754
+ dedent(text) {
2755
+ const lines = text.split("\n");
2756
+ if (lines.length <= 1) return text.trim();
2757
+ const minIndent = lines.slice(1).filter((line) => line.trim().length > 0).reduce((min, line) => {
2758
+ const match = line.match(/^(\s*)/);
2759
+ const indent = match?.[1]?.length ?? 0;
2760
+ return Math.min(min, indent);
2761
+ }, Infinity);
2762
+ if (minIndent === 0 || minIndent === Infinity) {
2763
+ return text.trim();
2764
+ }
2765
+ const firstLine = lines[0] ?? "";
2766
+ return [
2767
+ firstLine.trim(),
2768
+ ...lines.slice(1).map((line) => line.trim().length > 0 ? line.slice(minIndent) : "")
2769
+ ].join("\n").trim();
2770
+ }
2126
2771
  // ============================================================
2127
2772
  // AGENTS.md Generation
2128
2773
  // ============================================================
@@ -2258,7 +2903,9 @@ var GitHubFormatter = class extends BaseFormatter {
2258
2903
  lines.push("---");
2259
2904
  lines.push("");
2260
2905
  if (config.content) {
2261
- lines.push(config.content);
2906
+ const dedentedContent = this.dedent(config.content);
2907
+ const normalizedContent = this.normalizeMarkdownForPrettier(dedentedContent);
2908
+ lines.push(normalizedContent);
2262
2909
  }
2263
2910
  return {
2264
2911
  path: `.github/agents/${config.name}.md`,
@@ -2713,7 +3360,9 @@ var ClaudeFormatter = class extends BaseFormatter {
2713
3360
  lines.push(`# ${config.description}`);
2714
3361
  lines.push("");
2715
3362
  if (config.content) {
2716
- lines.push(config.content);
3363
+ const dedentedContent = this.dedent(config.content);
3364
+ const normalizedContent = this.normalizeMarkdownForPrettier(dedentedContent);
3365
+ lines.push(normalizedContent);
2717
3366
  }
2718
3367
  return {
2719
3368
  path: `.claude/rules/${config.name}.md`,
@@ -2812,7 +3461,8 @@ var ClaudeFormatter = class extends BaseFormatter {
2812
3461
  lines.push("---");
2813
3462
  lines.push("");
2814
3463
  if (config.content) {
2815
- const normalizedContent = this.normalizeMarkdownForPrettier(config.content);
3464
+ const dedentedContent = this.dedent(config.content);
3465
+ const normalizedContent = this.normalizeMarkdownForPrettier(dedentedContent);
2816
3466
  lines.push(normalizedContent);
2817
3467
  }
2818
3468
  return {
@@ -2820,6 +3470,28 @@ var ClaudeFormatter = class extends BaseFormatter {
2820
3470
  content: lines.join("\n") + "\n"
2821
3471
  };
2822
3472
  }
3473
+ /**
3474
+ * Remove common leading indentation from multiline text.
3475
+ * Calculates minimum indent from lines 2+ only, since line 1 may have been
3476
+ * trimmed (losing its indentation) while subsequent lines retain theirs.
3477
+ */
3478
+ dedent(text) {
3479
+ const lines = text.split("\n");
3480
+ if (lines.length <= 1) return text.trim();
3481
+ const minIndent = lines.slice(1).filter((line) => line.trim().length > 0).reduce((min, line) => {
3482
+ const match = line.match(/^(\s*)/);
3483
+ const indent = match?.[1]?.length ?? 0;
3484
+ return Math.min(min, indent);
3485
+ }, Infinity);
3486
+ if (minIndent === 0 || minIndent === Infinity) {
3487
+ return text.trim();
3488
+ }
3489
+ const firstLine = lines[0] ?? "";
3490
+ return [
3491
+ firstLine.trim(),
3492
+ ...lines.slice(1).map((line) => line.trim().length > 0 ? line.slice(minIndent) : "")
3493
+ ].join("\n").trim();
3494
+ }
2823
3495
  // ============================================================
2824
3496
  // Agent File Generation
2825
3497
  // ============================================================
@@ -2922,7 +3594,9 @@ var ClaudeFormatter = class extends BaseFormatter {
2922
3594
  lines.push("---");
2923
3595
  lines.push("");
2924
3596
  if (config.content) {
2925
- lines.push(config.content);
3597
+ const dedentedContent = this.dedent(config.content);
3598
+ const normalizedContent = this.normalizeMarkdownForPrettier(dedentedContent);
3599
+ lines.push(normalizedContent);
2926
3600
  }
2927
3601
  return {
2928
3602
  path: `.claude/agents/${config.name}.md`,
@@ -2977,7 +3651,8 @@ var ClaudeFormatter = class extends BaseFormatter {
2977
3651
  const cleanText = text.split(/\n{2,}/).map(
2978
3652
  (para) => para.split("\n").map((line) => line.trim()).filter((line) => line).join("\n")
2979
3653
  ).filter((para) => para).join("\n\n");
2980
- return renderer.renderSection("Project", cleanText) + "\n";
3654
+ const normalizedText = this.normalizeMarkdownForPrettier(cleanText);
3655
+ return renderer.renderSection("Project", normalizedText) + "\n";
2981
3656
  }
2982
3657
  techStack(ast, renderer) {
2983
3658
  const context = this.findBlock(ast, "context");
@@ -3035,8 +3710,9 @@ var ClaudeFormatter = class extends BaseFormatter {
3035
3710
  const text = this.extractText(context.content);
3036
3711
  const archMatch = this.extractSectionWithCodeBlock(text, "## Architecture");
3037
3712
  if (!archMatch) return null;
3038
- const content = archMatch.replace("## Architecture", "").trim();
3039
- return renderer.renderSection("Architecture", content) + "\n";
3713
+ const content = archMatch.replace("## Architecture", "");
3714
+ const normalizedContent = this.normalizeMarkdownForPrettier(content);
3715
+ return renderer.renderSection("Architecture", normalizedContent.trim()) + "\n";
3040
3716
  }
3041
3717
  codeStandards(ast, renderer) {
3042
3718
  const standards = this.findBlock(ast, "standards");
@@ -3117,7 +3793,7 @@ var ClaudeFormatter = class extends BaseFormatter {
3117
3793
  const props = this.getProps(shortcuts.content);
3118
3794
  for (const [cmd, desc] of Object.entries(props)) {
3119
3795
  const shortDesc = this.valueToString(desc).split("\n")[0] ?? "";
3120
- commandLines.push(`${cmd.padEnd(10)} - ${shortDesc}`);
3796
+ commandLines.push(`${cmd.padEnd(10)} - ${shortDesc}`.trimEnd());
3121
3797
  }
3122
3798
  }
3123
3799
  if (commandLines.length === 0) return null;
@@ -3126,8 +3802,9 @@ var ClaudeFormatter = class extends BaseFormatter {
3126
3802
  const text = this.extractText(knowledge.content);
3127
3803
  const match = this.extractSectionWithCodeBlock(text, "## Development Commands");
3128
3804
  if (match) {
3129
- const devCmds = match.replace("## Development Commands", "").trim();
3130
- content += "\n\n" + devCmds;
3805
+ const devCmds = match.replace("## Development Commands", "");
3806
+ const normalizedDevCmds = this.normalizeMarkdownForPrettier(devCmds);
3807
+ content += "\n\n" + normalizedDevCmds.trim();
3131
3808
  }
3132
3809
  }
3133
3810
  return renderer.renderSection("Commands", content) + "\n";
@@ -3138,8 +3815,9 @@ var ClaudeFormatter = class extends BaseFormatter {
3138
3815
  const text = this.extractText(knowledge.content);
3139
3816
  const match = this.extractSectionWithCodeBlock(text, "## Post-Work Verification");
3140
3817
  if (!match) return null;
3141
- const content = match.replace("## Post-Work Verification", "").trim();
3142
- return renderer.renderSection("Post-Work Verification", content) + "\n";
3818
+ const content = match.replace("## Post-Work Verification", "");
3819
+ const normalizedContent = this.normalizeMarkdownForPrettier(content);
3820
+ return renderer.renderSection("Post-Work Verification", normalizedContent.trim()) + "\n";
3143
3821
  }
3144
3822
  documentation(ast, renderer) {
3145
3823
  const standards = this.findBlock(ast, "standards");
@@ -3517,13 +4195,39 @@ var CursorFormatter = class extends BaseFormatter {
3517
4195
  if (never) sections.push(never);
3518
4196
  }
3519
4197
  intro(ast) {
3520
- const projectInfo = this.extractProjectInfo(ast);
3521
- if (projectInfo.text.toLowerCase().startsWith("you are")) {
3522
- return projectInfo.text;
4198
+ const identity2 = this.findBlock(ast, "identity");
4199
+ if (identity2) {
4200
+ const fullText = this.dedent(this.extractText(identity2.content));
4201
+ if (fullText.toLowerCase().startsWith("you are")) {
4202
+ return fullText;
4203
+ }
3523
4204
  }
4205
+ const projectInfo = this.extractProjectInfo(ast);
3524
4206
  const orgSuffix = projectInfo.org ? ` at ${projectInfo.org}` : "";
3525
4207
  return `You are working on ${projectInfo.text}${orgSuffix}.`;
3526
4208
  }
4209
+ /**
4210
+ * Remove common leading whitespace from all lines (dedent).
4211
+ * Handles the case where trim() was already called, causing the first line
4212
+ * to lose its indentation while subsequent lines retain theirs.
4213
+ */
4214
+ dedent(text) {
4215
+ const lines = text.split("\n");
4216
+ if (lines.length <= 1) return text.trim();
4217
+ const minIndent = lines.slice(1).filter((line) => line.trim().length > 0).reduce((min, line) => {
4218
+ const match = line.match(/^(\s*)/);
4219
+ const indent = match?.[1]?.length ?? 0;
4220
+ return Math.min(min, indent);
4221
+ }, Infinity);
4222
+ if (minIndent === 0 || minIndent === Infinity) {
4223
+ return text.trim();
4224
+ }
4225
+ const firstLine = lines[0] ?? "";
4226
+ return [
4227
+ firstLine.trim(),
4228
+ ...lines.slice(1).map((line) => line.trim().length > 0 ? line.slice(minIndent) : "")
4229
+ ].join("\n").trim();
4230
+ }
3527
4231
  /**
3528
4232
  * Generate YAML frontmatter for Cursor MDC format.
3529
4233
  * @see https://cursor.com/docs/context/rules
@@ -17410,6 +18114,10 @@ var PROMPTSCRIPT_MARKERS = [
17410
18114
  "> Auto-generated by PromptScript"
17411
18115
  // Legacy - for backwards compatibility
17412
18116
  ];
18117
+ var MARKER_REGEX = /<!-- PromptScript [^>]+ -->\n*/g;
18118
+ function stripMarkers(content) {
18119
+ return content.replace(MARKER_REGEX, "");
18120
+ }
17413
18121
  function createCliLogger() {
17414
18122
  return {
17415
18123
  verbose: (message) => {
@@ -17468,7 +18176,7 @@ function printErrors(errors) {
17468
18176
  }
17469
18177
  }
17470
18178
  async function writeOutputs(outputs, options, _config, services) {
17471
- const result = { written: [], skipped: [] };
18179
+ const result = { written: [], skipped: [], unchanged: [] };
17472
18180
  let overwriteAll = false;
17473
18181
  const conflicts = [];
17474
18182
  for (const output of outputs.values()) {
@@ -17478,14 +18186,24 @@ async function writeOutputs(outputs, options, _config, services) {
17478
18186
  if (fileExists2) {
17479
18187
  const isGenerated2 = await isPromptScriptGenerated2(outputPath);
17480
18188
  if (isGenerated2) {
17481
- ConsoleOutput.dryRun(`Would overwrite: ${outputPath}`);
18189
+ const existingContent = await readFile6(outputPath, "utf-8");
18190
+ const existingWithoutMarker = stripMarkers(existingContent);
18191
+ const newWithoutMarker = stripMarkers(output.content);
18192
+ if (existingWithoutMarker === newWithoutMarker) {
18193
+ ConsoleOutput.dryRun(`Unchanged: ${outputPath}`);
18194
+ result.unchanged.push(outputPath);
18195
+ } else {
18196
+ ConsoleOutput.dryRun(`Would overwrite: ${outputPath}`);
18197
+ result.written.push(outputPath);
18198
+ }
17482
18199
  } else {
17483
18200
  ConsoleOutput.warning(`Would conflict: ${outputPath} (not generated by PromptScript)`);
18201
+ result.written.push(outputPath);
17484
18202
  }
17485
18203
  } else {
17486
18204
  ConsoleOutput.dryRun(`Would write: ${outputPath}`);
18205
+ result.written.push(outputPath);
17487
18206
  }
17488
- result.written.push(outputPath);
17489
18207
  continue;
17490
18208
  }
17491
18209
  if (!fileExists2) {
@@ -17497,6 +18215,14 @@ async function writeOutputs(outputs, options, _config, services) {
17497
18215
  }
17498
18216
  const isGenerated = await isPromptScriptGenerated2(outputPath);
17499
18217
  if (isGenerated) {
18218
+ const existingContent = await readFile6(outputPath, "utf-8");
18219
+ const existingWithoutMarker = stripMarkers(existingContent);
18220
+ const newWithoutMarker = stripMarkers(output.content);
18221
+ if (existingWithoutMarker === newWithoutMarker) {
18222
+ ConsoleOutput.unchanged(outputPath);
18223
+ result.unchanged.push(outputPath);
18224
+ continue;
18225
+ }
17500
18226
  await mkdir2(dirname5(outputPath), { recursive: true });
17501
18227
  await writeFile2(outputPath, output.content, "utf-8");
17502
18228
  ConsoleOutput.success(outputPath);
@@ -17602,6 +18328,9 @@ async function compileCommand(options, services = createDefaultServices()) {
17602
18328
  spinner.succeed("Compilation successful");
17603
18329
  ConsoleOutput.newline();
17604
18330
  const writeResult = await writeOutputs(result.outputs, options, config, services);
18331
+ if (writeResult.unchanged.length > 0) {
18332
+ ConsoleOutput.muted(`Unchanged ${writeResult.unchanged.length} file(s)`);
18333
+ }
17605
18334
  if (writeResult.skipped.length > 0) {
17606
18335
  ConsoleOutput.muted(`Skipped ${writeResult.skipped.length} file(s)`);
17607
18336
  }
@@ -18247,7 +18976,7 @@ program.name("prs").description("PromptScript CLI - Standardize AI instructions"
18247
18976
  setContext({ logLevel: 2 /* Verbose */ });
18248
18977
  }
18249
18978
  });
18250
- 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));
18979
+ 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").option("-m, --migrate", "Install migration skill for AI-assisted migration").action((opts) => initCommand(opts));
18251
18980
  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));
18252
18981
  program.command("validate").description("Validate PromptScript files").option("--strict", "Treat warnings as errors").option("--format <format>", "Output format (text, json)", "text").action(validateCommand);
18253
18982
  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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptscript/cli",
3
- "version": "1.0.0-alpha.5",
3
+ "version": "1.0.0-alpha.6",
4
4
  "description": "CLI for PromptScript - standardize AI instructions across GitHub Copilot, Claude, Cursor and other AI tools",
5
5
  "keywords": [
6
6
  "cli",
package/src/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../../packages/cli/src/cli.ts"],"names":[],"mappings":";AA6GA;;;GAGG;AACH,wBAAgB,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,IAAI,CAEvD"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../../../../packages/cli/src/cli.ts"],"names":[],"mappings":";AA8GA;;;GAGG;AACH,wBAAgB,GAAG,CAAC,IAAI,GAAE,MAAM,EAAiB,GAAG,IAAI,CAEvD"}
@@ -1 +1 @@
1
- {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/compile.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,gBAAgB,CAAC;AAqPzE;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,QAAQ,GAAE,WAAqC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAkFf"}
1
+ {"version":3,"file":"compile.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/compile.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAQlD,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,gBAAgB,CAAC;AA6RzE;;GAEG;AACH,wBAAsB,cAAc,CAClC,OAAO,EAAE,cAAc,EACvB,QAAQ,GAAE,WAAqC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAqFf"}
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,gBAAgB,CAAC;AAKzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AA2B/C;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,QAAQ,GAAE,WAAqC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAkGf"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/init.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,gBAAgB,CAAC;AAKzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAiC/C;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,QAAQ,GAAE,WAAqC,GAC9C,OAAO,CAAC,IAAI,CAAC,CA0Jf"}
@@ -74,6 +74,10 @@ export declare const ConsoleOutput: {
74
74
  * Print a skipped file message.
75
75
  */
76
76
  skipped(message: string): void;
77
+ /**
78
+ * Print an unchanged file message.
79
+ */
80
+ unchanged(message: string): void;
77
81
  /**
78
82
  * Print an info message.
79
83
  */
@@ -1 +1 @@
1
- {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/output/console.ts"],"names":[],"mappings":"AACA,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAEpC;;GAEG;AACH,oBAAY,QAAQ;IAClB,wCAAwC;IACxC,KAAK,IAAI;IACT,8BAA8B;IAC9B,MAAM,IAAI;IACV,6CAA6C;IAC7C,OAAO,IAAI;IACX,wCAAwC;IACxC,KAAK,IAAI;CACV;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iCAAiC;IACjC,MAAM,EAAE,OAAO,CAAC;CACjB;AAUD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAEvC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAQ/C;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;;OAGG;mBACY,MAAM,GAAG,IAAI;IAI5B;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;OAEG;kBACW,MAAM,GAAG,IAAI;IAK3B;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;OAEG;kBACW,MAAM,GAAG,IAAI;IAK3B;;OAEG;mBACY,MAAM,GAAG,IAAI;IAK5B;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;OAEG;mBACY,MAAM,GAAG,IAAI;IAK5B;;OAEG;oBACa,MAAM,GAAG,IAAI;IAK7B;;OAEG;eACQ,IAAI;IAKf;;OAEG;oBACa,MAAM,GAAG,IAAI;IAK7B;;OAEG;mBACY,MAAM,GAAG,IAAI;IAK5B;;OAEG;qBACc,MAAM,GAAG,MAAM;IAIhC;;OAEG;yBACkB,MAAM,SAAS,MAAM,WAAW,MAAM,GAAG,MAAM;CAUrE,CAAC"}
1
+ {"version":3,"file":"console.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/output/console.ts"],"names":[],"mappings":"AACA,OAAY,EAAE,KAAK,GAAG,EAAE,MAAM,KAAK,CAAC;AAEpC;;GAEG;AACH,oBAAY,QAAQ;IAClB,wCAAwC;IACxC,KAAK,IAAI;IACT,8BAA8B;IAC9B,MAAM,IAAI;IACV,6CAA6C;IAC7C,OAAO,IAAI;IACX,wCAAwC;IACxC,KAAK,IAAI;CACV;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,wBAAwB;IACxB,QAAQ,EAAE,QAAQ,CAAC;IACnB,iCAAiC;IACjC,MAAM,EAAE,OAAO,CAAC;CACjB;AAUD;;GAEG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,UAAU,CAEvC;AAED;;GAEG;AACH,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;GAEG;AACH,wBAAgB,OAAO,IAAI,OAAO,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,GAAG,CAQ/C;AAED;;;GAGG;AACH,eAAO,MAAM,aAAa;IACxB;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;;OAGG;mBACY,MAAM,GAAG,IAAI;IAI5B;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;OAEG;kBACW,MAAM,GAAG,IAAI;IAK3B;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;OAEG;uBACgB,MAAM,GAAG,IAAI;IAKhC;;OAEG;kBACW,MAAM,GAAG,IAAI;IAK3B;;OAEG;mBACY,MAAM,GAAG,IAAI;IAK5B;;OAEG;qBACc,MAAM,GAAG,IAAI;IAK9B;;OAEG;mBACY,MAAM,GAAG,IAAI;IAK5B;;OAEG;oBACa,MAAM,GAAG,IAAI;IAK7B;;OAEG;eACQ,IAAI;IAKf;;OAEG;oBACa,MAAM,GAAG,IAAI;IAK7B;;OAEG;mBACY,MAAM,GAAG,IAAI;IAK5B;;OAEG;qBACc,MAAM,GAAG,MAAM;IAIhC;;OAEG;yBACkB,MAAM,SAAS,MAAM,WAAW,MAAM,GAAG,MAAM;CAUrE,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Migration skill template for AI-assisted migration.
3
+ * This skill is installed when using `prs init --migrate`.
4
+ */
5
+ export declare const MIGRATE_SKILL_CLAUDE = "---\nname: 'migrate-to-promptscript'\ndescription: 'Migrate existing AI instruction files to PromptScript format'\nallowed-tools:\n - Read\n - Write\n - Glob\n - Grep\n - Bash\nuser-invocable: true\n---\n\n# Migrate to PromptScript\n\n## Overview\n\nThis skill guides you through migrating existing AI instruction files\nto PromptScript format, creating a unified source of truth for all\nAI coding assistants.\n\n## Step 1: Discovery\n\nSearch for existing instruction files using these patterns:\n\nClaude Code:\n\n- CLAUDE.md, claude.md, CLAUDE.local.md\n\nCursor:\n\n- .cursorrules\n- .cursor/rules/\\*.md\n- .cursor/rules/\\*.mdc\n\nGitHub Copilot:\n\n- .github/copilot-instructions.md\n- .github/instructions/\\*.md\n\nOther:\n\n- AGENTS.md\n- AI_INSTRUCTIONS.md\n- AI.md\n- .ai/instructions.md\n\nUse Glob tool to find these files.\n\n## Step 2: Read and Analyze\n\nFor each discovered file:\n\n1. Read the full content using the Read tool\n2. Identify sections by headers (##, ###) and patterns\n3. Classify content type using the mapping table below\n4. Note any tool-specific content that may need special handling\n\n## Step 3: Content Mapping\n\nMap source content to PromptScript blocks:\n\n| Source Pattern | PromptScript Block |\n| ------------------------------------ | ------------------ |\n| You are, persona, identity, role | @identity |\n| Tech stack, languages, frameworks | @context |\n| Coding standards, conventions, rules | @standards |\n| Don't, Never, restrictions | @restrictions |\n| Commands, shortcuts | @shortcuts |\n| API docs, references, knowledge base | @knowledge |\n| Parameters, config values | @params |\n| File patterns, globs, applyTo | @guards |\n| Skills, capabilities | @skills |\n| Agents, subagents | @agents |\n| Local-only settings | @local |\n\n## Step 4: Generate PromptScript\n\n### Required: @meta block\n\nEvery PromptScript file needs metadata with id and syntax fields.\n\n### Identity (persona)\n\nConvert persona descriptions to @identity block with triple-quote string.\n\n### Context (project info)\n\nConvert tech stack to @context block with structured properties\nlike project, languages, frameworks.\n\n### Standards (conventions)\n\nConvert coding standards to @standards block organized by category:\ncode, naming, commits, etc.\n\n### Restrictions (don'ts)\n\nConvert restrictions to @restrictions block using dash prefix for each item.\n\n### Shortcuts (commands)\n\nConvert custom commands to @shortcuts block. Simple shortcuts use\nkey-value format. Complex shortcuts use object format with\nprompt, description, and content fields.\n\n### Knowledge (references)\n\nConvert API docs and reference material to @knowledge block\nusing triple-quote string for rich content.\n\n### Guards (file patterns)\n\nConvert file-specific rules to @guards block with globs array\nspecifying file patterns.\n\n### Params (configuration)\n\nConvert configuration parameters to @params block with type annotations:\nrange(), enum(), boolean.\n\n### Skills (capabilities)\n\nConvert skill definitions to @skills block with description,\ntrigger, and content fields.\n\n### Agents (subagents)\n\nConvert agent definitions to @agents block with description,\ntools, model, and content fields.\n\n## Step 5: File Organization\n\nSimple Projects - single file structure:\n\n- .promptscript/project.prs\n- promptscript.yaml\n\nComplex Projects - modular file structure:\n\n- .promptscript/project.prs (main with @use imports)\n- .promptscript/context.prs\n- .promptscript/standards.prs\n- .promptscript/restrictions.prs\n- .promptscript/commands.prs\n- promptscript.yaml\n\n## Step 6: Configuration\n\nCreate promptscript.yaml with:\n\n- version: '1'\n- project.id\n- input.entry pointing to main .prs file\n- targets for github, claude, cursor\n\n## Step 7: Validation\n\nAfter generating PromptScript files:\n\n1. Validate syntax: prs validate\n2. Test compilation: prs compile --dry-run\n3. Compare output with original files\n4. Iterate if content is missing or incorrect\n\n## Common Patterns\n\n### Merging Multiple Sources\n\nWhen instructions exist in multiple files:\n\n1. Identity: Take from most detailed source\n2. Standards: Merge all, deduplicate\n3. Restrictions: Combine all (union)\n4. Commands: Merge, resolve conflicts\n\n### Tool-Specific Content\n\nHandle tool-specific content:\n\n- GitHub prompts: Use @shortcuts with prompt: true\n- Claude agents: Use @agents block\n- Cursor rules: Map to @standards\n- Local content: Use @local block\n\n### Preserving Formatting\n\nUse triple-quote multiline strings for:\n\n- Rich markdown content\n- Code examples\n- Complex instructions\n\n## Syntax Rules\n\nQuick reference for PromptScript syntax:\n\n- Strings: quoted or identifier\n- Multi-line: triple quotes\n- Arrays: [item1, item2] or - item prefix\n- Objects: { key: value }\n- Comments: # comment\n- Required @meta fields: id, syntax\n\n## Quality Checklist\n\nBefore completing migration:\n\n- @meta block has id and syntax\n- Identity is clear and specific\n- Standards are organized by category\n- Restrictions use dash prefix (-)\n- Shortcuts work in target tools\n- prs validate passes\n- prs compile produces correct output\n- No duplicate content across blocks\n\n## Troubleshooting\n\n### Missing @meta Error\nAdd required metadata block at the start.\n\n### Multiline String in Object Error\nAssign multiline strings to named keys, don't leave them loose\ninside objects.\n\n### Content Not Appearing in Output\nCheck block names match expected patterns and\nverify syntax with prs validate --verbose.\n";
6
+ export declare const MIGRATE_SKILL_CURSOR = "# Migrate to PromptScript\n\nUse this command to migrate existing AI instruction files to PromptScript format.\n\n## Step 1: Discovery\n\nSearch for existing instruction files:\n\n- CLAUDE.md, claude.md, CLAUDE.local.md\n- .cursorrules, .cursor/rules/*.mdc\n- .github/copilot-instructions.md\n- AGENTS.md, AI_INSTRUCTIONS.md\n\n## Step 2: Content Mapping\n\nMap source content to PromptScript blocks:\n\n| Source Pattern | PromptScript Block |\n| ------------------------------------ | ------------------ |\n| You are, persona, identity, role | @identity |\n| Tech stack, languages, frameworks | @context |\n| Coding standards, conventions, rules | @standards |\n| Don't, Never, restrictions | @restrictions |\n| Commands, shortcuts | @shortcuts |\n| API docs, references | @knowledge |\n\n## Step 3: Generate PromptScript\n\nCreate `.promptscript/project.prs` with:\n\n1. **@meta** block with id and syntax fields (required)\n2. **@identity** for persona/role descriptions\n3. **@context** for tech stack info\n4. **@standards** organized by category\n5. **@restrictions** with dash prefix for each item\n6. **@shortcuts** for commands\n\n## Step 4: Validation\n\nAfter generating:\n\n1. Run `prs validate`\n2. Run `prs compile --dry-run`\n3. Compare output with original files\n\n## Syntax Quick Reference\n\n- Strings: quoted or identifier\n- Multi-line: triple quotes (`\"\"\"`)\n- Arrays: `[item1, item2]`\n- Objects: `{ key: value }`\n- Comments: `# comment`\n\n## Quality Checklist\n\n- @meta block has id and syntax\n- Standards organized by category\n- Restrictions use dash prefix (-)\n- prs validate passes\n";
7
+ export declare const MIGRATE_SKILL_ANTIGRAVITY = "# Migrate to PromptScript\n\nThis rule provides guidance for migrating existing AI instruction files to PromptScript format.\n\n## Overview\n\nPromptScript creates a unified source of truth for all AI coding assistants,\ncompiling to native formats for Claude, GitHub Copilot, Cursor, and Antigravity.\n\n## Step 1: Discovery\n\nSearch for existing instruction files:\n\n- CLAUDE.md, claude.md, CLAUDE.local.md\n- .cursorrules, .cursor/rules/*.mdc\n- .github/copilot-instructions.md\n- .agent/rules/*.md\n- AGENTS.md, AI_INSTRUCTIONS.md\n\n## Step 2: Content Mapping\n\nMap source content to PromptScript blocks:\n\n| Source Pattern | PromptScript Block |\n| ------------------------------------ | ------------------ |\n| You are, persona, identity, role | @identity |\n| Tech stack, languages, frameworks | @context |\n| Coding standards, conventions, rules | @standards |\n| Don't, Never, restrictions | @restrictions |\n| Commands, shortcuts | @shortcuts |\n| API docs, references | @knowledge |\n\n## Step 3: Generate PromptScript\n\nCreate `.promptscript/project.prs` with required blocks:\n\n1. **@meta** - id and syntax fields (required)\n2. **@identity** - persona/role descriptions\n3. **@context** - tech stack info\n4. **@standards** - coding rules organized by category\n5. **@restrictions** - things to avoid (dash prefix)\n6. **@shortcuts** - commands\n\n## Step 4: Validation\n\nAfter generating PromptScript files:\n\n1. Run `prs validate` to check syntax\n2. Run `prs compile --dry-run` to preview output\n3. Compare compiled output with original files\n\n## Syntax Reference\n\n- Strings: quoted or identifier\n- Multi-line: triple quotes\n- Arrays: [item1, item2]\n- Objects: { key: value }\n- Comments: # comment\n";
8
+ export declare const MIGRATE_SKILL_GITHUB = "---\nname: 'migrate-to-promptscript'\ndescription: 'Migrate existing AI instruction files to PromptScript format'\nallowed-tools:\n - read\n - write\n - glob\n - grep\n - execute\nuser-invocable: true\n---\n\n# Migrate to PromptScript\n\n## Overview\n\nThis skill guides you through migrating existing AI instruction files\nto PromptScript format, creating a unified source of truth for all\nAI coding assistants.\n\n## Step 1: Discovery\n\nSearch for existing instruction files using these patterns:\n\nClaude Code:\n\n- CLAUDE.md, claude.md, CLAUDE.local.md\n\nCursor:\n\n- .cursorrules\n- .cursor/rules/\\*.md\n- .cursor/rules/\\*.mdc\n\nGitHub Copilot:\n\n- .github/copilot-instructions.md\n- .github/instructions/\\*.md\n\nOther:\n\n- AGENTS.md\n- AI_INSTRUCTIONS.md\n- AI.md\n- .ai/instructions.md\n\n## Step 2: Read and Analyze\n\nFor each discovered file:\n\n1. Read the full content\n2. Identify sections by headers (##, ###) and patterns\n3. Classify content type using the mapping table below\n4. Note any tool-specific content that may need special handling\n\n## Step 3: Content Mapping\n\nMap source content to PromptScript blocks:\n\n| Source Pattern | PromptScript Block |\n| ------------------------------------ | ------------------ |\n| You are, persona, identity, role | @identity |\n| Tech stack, languages, frameworks | @context |\n| Coding standards, conventions, rules | @standards |\n| Don't, Never, restrictions | @restrictions |\n| Commands, shortcuts | @shortcuts |\n| API docs, references, knowledge base | @knowledge |\n| Parameters, config values | @params |\n| File patterns, globs, applyTo | @guards |\n| Skills, capabilities | @skills |\n| Agents, subagents | @agents |\n| Local-only settings | @local |\n\n## Step 4: Generate PromptScript\n\n### Required: @meta block\n\nEvery PromptScript file needs metadata with id and syntax fields.\n\n### Identity (persona)\n\nConvert persona descriptions to @identity block with triple-quote string.\n\n### Context (project info)\n\nConvert tech stack to @context block with structured properties\nlike project, languages, frameworks.\n\n### Standards (conventions)\n\nConvert coding standards to @standards block organized by category:\ncode, naming, commits, etc.\n\n### Restrictions (don'ts)\n\nConvert restrictions to @restrictions block using dash prefix for each item.\n\n### Shortcuts (commands)\n\nConvert custom commands to @shortcuts block. Simple shortcuts use\nkey-value format. Complex shortcuts use object format with\nprompt, description, and content fields.\n\n## Step 5: File Organization\n\nSimple Projects - single file structure:\n\n- .promptscript/project.prs\n- promptscript.yaml\n\nComplex Projects - modular file structure:\n\n- .promptscript/project.prs (main with @use imports)\n- .promptscript/context.prs\n- .promptscript/standards.prs\n- .promptscript/restrictions.prs\n- .promptscript/commands.prs\n- promptscript.yaml\n\n## Step 6: Configuration\n\nCreate promptscript.yaml with:\n\n- version: '1'\n- project.id\n- input.entry pointing to main .prs file\n- targets for github, claude, cursor\n\n## Step 7: Validation\n\nAfter generating PromptScript files:\n\n1. Validate syntax: prs validate\n2. Test compilation: prs compile --dry-run\n3. Compare output with original files\n4. Iterate if content is missing or incorrect\n\n## Quality Checklist\n\nBefore completing migration:\n\n- @meta block has id and syntax\n- Identity is clear and specific\n- Standards are organized by category\n- Restrictions use dash prefix (-)\n- Shortcuts work in target tools\n- prs validate passes\n- prs compile produces correct output\n- No duplicate content across blocks\n";
9
+ //# sourceMappingURL=migrate-skill.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate-skill.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/templates/migrate-skill.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,eAAO,MAAM,oBAAoB,+rLAoOhC,CAAC;AAEF,eAAO,MAAM,oBAAoB,gtDA2DhC,CAAC;AAEF,eAAO,MAAM,yBAAyB,m0DA0DrC,CAAC;AAEF,eAAO,MAAM,oBAAoB,+zHAqJhC,CAAC"}
package/src/types.d.ts CHANGED
@@ -18,6 +18,8 @@ export interface InitOptions {
18
18
  yes?: boolean;
19
19
  /** Force reinitialize even if already initialized */
20
20
  force?: boolean;
21
+ /** Install migration skill for AI-assisted migration */
22
+ migrate?: boolean;
21
23
  }
22
24
  /**
23
25
  * Options for the compile command.
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../packages/cli/src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iCAAiC;IACjC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,wCAAwC;IACxC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,GAAG,CAAC,EAAE,OAAO,CAAC;CACf"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../packages/cli/src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,qBAAqB;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,iDAAiD;IACjD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,iCAAiC;IACjC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,4CAA4C;IAC5C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,uBAAuB;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,4CAA4C;IAC5C,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8CAA8C;IAC9C,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,kCAAkC;IAClC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,sCAAsC;IACtC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2BAA2B;IAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mCAAmC;IACnC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,kDAAkD;IAClD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8BAA8B;IAC9B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wCAAwC;IACxC,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,wCAAwC;IACxC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,0CAA0C;IAC1C,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2BAA2B;IAC3B,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,0CAA0C;IAC1C,GAAG,CAAC,EAAE,OAAO,CAAC;CACf"}