@promptscript/cli 1.3.0 → 1.3.1

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,13 @@ 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.3.1](https://github.com/mrwogu/promptscript/compare/v1.3.0...v1.3.1) (2026-03-13)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * init config schema, migrate flow, and skill consolidation ([#100](https://github.com/mrwogu/promptscript/issues/100)) ([af6fb5f](https://github.com/mrwogu/promptscript/commit/af6fb5f2deb8984ba6545a68c6398a20b1d8ab85))
14
+
8
15
  ## [1.3.0](https://github.com/mrwogu/promptscript/compare/v1.2.0...v1.3.0) (2026-03-11)
9
16
 
10
17
 
package/index.js CHANGED
@@ -1696,14 +1696,22 @@ async function initCommand(options, services = createDefaultServices()) {
1696
1696
  await fs4.writeFile(".promptscript/project.prs", projectPsContent, "utf-8");
1697
1697
  const installedSkillPaths = [];
1698
1698
  if (options.migrate) {
1699
- const skillName = "migrate-to-promptscript";
1699
+ const skillName = "promptscript";
1700
1700
  const skillSource = resolve2(BUNDLED_SKILLS_DIR, skillName, "SKILL.md");
1701
- const skillDest = `.promptscript/skills/${skillName}`;
1702
1701
  try {
1703
1702
  const skillContent = readFileSync3(skillSource, "utf-8");
1703
+ const skillDest = `.promptscript/skills/${skillName}`;
1704
1704
  await fs4.mkdir(skillDest, { recursive: true });
1705
1705
  await fs4.writeFile(`${skillDest}/SKILL.md`, skillContent, "utf-8");
1706
1706
  installedSkillPaths.push(`${skillDest}/SKILL.md`);
1707
+ for (const target of config.targets) {
1708
+ const targetSkillDir = getTargetSkillDir(target, skillName);
1709
+ if (targetSkillDir) {
1710
+ await fs4.mkdir(targetSkillDir.dir, { recursive: true });
1711
+ await fs4.writeFile(targetSkillDir.path, skillContent, "utf-8");
1712
+ installedSkillPaths.push(targetSkillDir.path);
1713
+ }
1714
+ }
1707
1715
  } catch {
1708
1716
  ConsoleOutput.warn(`Could not install migration skill from ${skillSource}`);
1709
1717
  }
@@ -1744,12 +1752,13 @@ async function initCommand(options, services = createDefaultServices()) {
1744
1752
  ConsoleOutput.newline();
1745
1753
  console.log("Next steps:");
1746
1754
  if (options.migrate && installedSkillPaths.length > 0) {
1747
- ConsoleOutput.muted("1. Run: prs compile");
1748
- ConsoleOutput.muted("2. Use the migration skill in your AI tool:");
1749
- ConsoleOutput.muted(" Claude Code / Factory AI: /migrate-to-promptscript");
1750
- ConsoleOutput.muted(" GitHub Copilot: @workspace /migrate-to-promptscript");
1751
- ConsoleOutput.muted(" Cursor: /migrate-to-promptscript");
1752
- ConsoleOutput.muted("3. Review generated .promptscript/project.prs");
1755
+ ConsoleOutput.muted("1. Use the migration skill in your AI tool:");
1756
+ const skillInvocations = getSkillInvocationHints(config.targets);
1757
+ for (const hint of skillInvocations) {
1758
+ ConsoleOutput.muted(` ${hint}`);
1759
+ }
1760
+ ConsoleOutput.muted("2. Review generated .promptscript/project.prs");
1761
+ ConsoleOutput.muted("3. Run: prs compile");
1753
1762
  } else {
1754
1763
  ConsoleOutput.muted("1. Edit .promptscript/project.prs to customize your AI instructions");
1755
1764
  ConsoleOutput.muted("2. Run: prs compile");
@@ -2017,11 +2026,39 @@ function formatTargetName(target) {
2017
2026
  };
2018
2027
  return names[target] ?? target;
2019
2028
  }
2020
- function generateConfig(config) {
2021
- const lines = ["version: '1'", "", "project:", ` id: '${config.projectId}'`];
2022
- if (config.team) {
2023
- lines.push(` team: '${config.team}'`);
2029
+ function getTargetSkillDir(target, skillName) {
2030
+ const skillDirs = {
2031
+ claude: { dotDir: ".claude", fileName: "SKILL.md" },
2032
+ factory: { dotDir: ".factory", fileName: "SKILL.md" },
2033
+ github: { dotDir: ".github", fileName: "SKILL.md" },
2034
+ opencode: { dotDir: ".opencode", fileName: "SKILL.md" },
2035
+ gemini: { dotDir: ".gemini", fileName: "skill.md" }
2036
+ };
2037
+ const config = skillDirs[target];
2038
+ if (!config) return null;
2039
+ const dir = `${config.dotDir}/skills/${skillName}`;
2040
+ return { dir, path: `${dir}/${config.fileName}` };
2041
+ }
2042
+ function getSkillInvocationHints(targets) {
2043
+ const hints = [];
2044
+ const skillSupport = {
2045
+ claude: "Claude Code: /promptscript",
2046
+ factory: "Factory AI: /promptscript",
2047
+ opencode: "OpenCode: /promptscript",
2048
+ gemini: "Gemini CLI: /promptscript",
2049
+ github: "GitHub Copilot: /promptscript"
2050
+ };
2051
+ for (const target of targets) {
2052
+ const hint = skillSupport[target];
2053
+ if (hint) {
2054
+ hints.push(hint);
2055
+ }
2024
2056
  }
2057
+ return hints;
2058
+ }
2059
+ function generateConfig(config) {
2060
+ const syntaxVersion = getPackageVersion(__dirname, "./package.json");
2061
+ const lines = [`id: ${config.projectId}`, `syntax: "${syntaxVersion}"`];
2025
2062
  lines.push("");
2026
2063
  if (config.inherit) {
2027
2064
  lines.push(`inherit: '${config.inherit}'`);
@@ -2059,7 +2096,7 @@ function generateConfig(config) {
2059
2096
  for (const target of config.targets) {
2060
2097
  lines.push(` - ${target}`);
2061
2098
  }
2062
- lines.push("", "validation:", " rules:", " empty-block: warn");
2099
+ lines.push("", "validation:", " rules:", " empty-block: warning");
2063
2100
  lines.push("");
2064
2101
  if (config.prettierConfigPath) {
2065
2102
  lines.push("formatting:", " prettier: true # Auto-detected from project");
@@ -6607,6 +6644,16 @@ var FactoryFormatter = class extends MarkdownInstructionFormatter {
6607
6644
  lines.push("---");
6608
6645
  lines.push(`name: ${skillName}`);
6609
6646
  lines.push(`description: ${this.yamlString(factoryConfig.description)}`);
6647
+ if (factoryConfig.userInvocable === false) {
6648
+ lines.push("user-invocable: false");
6649
+ }
6650
+ if (factoryConfig.disableModelInvocation === true) {
6651
+ lines.push("disable-model-invocation: true");
6652
+ }
6653
+ if (factoryConfig.allowedTools && factoryConfig.allowedTools.length > 0) {
6654
+ const toolsArray = factoryConfig.allowedTools.map((t) => `"${t}"`).join(", ");
6655
+ lines.push(`allowed-tools: [${toolsArray}]`);
6656
+ }
6610
6657
  lines.push("---");
6611
6658
  lines.push("");
6612
6659
  if (factoryConfig.content) {
@@ -23050,6 +23097,21 @@ var Compiler = class _Compiler {
23050
23097
  while (queue.length > 0) {
23051
23098
  const additionalFile = queue.shift();
23052
23099
  this.logger.verbose(` \u2192 ${additionalFile.path} (additional)`);
23100
+ const existingAdditionalOwner = outputPathOwners.get(additionalFile.path);
23101
+ if (existingAdditionalOwner) {
23102
+ formatWarnings.push({
23103
+ ruleId: "PS4001",
23104
+ ruleName: "output-path-collision",
23105
+ severity: "warning",
23106
+ message: `Output path '${additionalFile.path}' is written by both '${existingAdditionalOwner}' and '${formatter.name}'. The latter will overwrite the former.`,
23107
+ suggestion: `Configure distinct output paths for these formatters, or disable one of them.`
23108
+ });
23109
+ if (additionalFile.additionalFiles) {
23110
+ queue.push(...additionalFile.additionalFiles);
23111
+ }
23112
+ continue;
23113
+ }
23114
+ outputPathOwners.set(additionalFile.path, formatter.name);
23053
23115
  outputs.set(additionalFile.path, addMarkerToOutput(additionalFile));
23054
23116
  if (additionalFile.additionalFiles) {
23055
23117
  queue.push(...additionalFile.additionalFiles);
@@ -24219,18 +24281,18 @@ async function checkCommand(_options) {
24219
24281
  process.exitCode = 1;
24220
24282
  return;
24221
24283
  }
24222
- if (!config.version) {
24284
+ if (!config.syntax) {
24223
24285
  results.push({
24224
- name: "Schema version",
24286
+ name: "Syntax version",
24225
24287
  status: "warning",
24226
- message: `Missing "version" field. Add version: '1' to config`
24288
+ message: 'Missing "syntax" field. Add syntax: "<version>" to config'
24227
24289
  });
24228
24290
  hasWarnings = true;
24229
24291
  } else {
24230
24292
  results.push({
24231
- name: "Schema version",
24293
+ name: "Syntax version",
24232
24294
  status: "ok",
24233
- message: `v${config.version}`
24295
+ message: `v${config.syntax}`
24234
24296
  });
24235
24297
  }
24236
24298
  const entryPath = config.input?.entry ?? ".promptscript/project.prs";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promptscript/cli",
3
- "version": "1.3.0",
3
+ "version": "1.3.1",
4
4
  "description": "CLI for PromptScript - standardize AI instructions across GitHub Copilot, Claude, Cursor and other AI tools",
5
5
  "keywords": [
6
6
  "cli",
@@ -300,7 +300,9 @@ Requires an aliased @use:
300
300
  ## Configuration: promptscript.yaml
301
301
 
302
302
  ```
303
- version: '1'
303
+ id: my-project
304
+ syntax: "1.1.0"
305
+ description: "My project description"
304
306
  input:
305
307
  entry: .promptscript/project.prs
306
308
  include: ['.promptscript/**/*.prs']
@@ -379,3 +381,79 @@ The entry file uses `@use ./context`, `@use ./standards`, etc. to compose them.
379
381
  4. Unquoted strings with special chars - quote strings containing `:`, `#`, `{`, `}`
380
382
  5. Forgetting to compile - `.prs` changes need `prs compile` to take effect
381
383
  6. Triple quotes inside triple quotes - not supported; describe content textually instead
384
+
385
+ ## Migrating Existing AI Instructions to PromptScript
386
+
387
+ Use this workflow when converting existing AI instruction files (CLAUDE.md, .cursorrules, copilot-instructions.md, etc.) to PromptScript `.prs` format.
388
+
389
+ ### Step 1: Discovery
390
+
391
+ Find all existing AI instruction files in the project:
392
+
393
+ - `CLAUDE.md` (Claude Code)
394
+ - `.github/copilot-instructions.md` (GitHub Copilot)
395
+ - `.cursorrules` or `.cursor/rules/*.mdc` (Cursor)
396
+ - `.agent/rules/*.md` (Antigravity)
397
+ - `AGENTS.md` (Factory AI / Codex)
398
+ - `.clinerules` (Cline)
399
+ - `.roorules` (Roo Code)
400
+ - `.windsurf/rules/*.md` (Windsurf)
401
+ - Any other AI instruction files
402
+
403
+ ### Step 2: Read and Analyze
404
+
405
+ Read each discovered file and identify:
406
+
407
+ - Identity/persona instructions ("You are...")
408
+ - Project context (tech stack, architecture)
409
+ - Coding standards and conventions
410
+ - Hard restrictions and rules
411
+ - Command shortcuts or slash commands
412
+ - Skill definitions
413
+ - Agent/subagent definitions
414
+
415
+ ### Step 3: Content Mapping
416
+
417
+ Map content from source files to PromptScript blocks:
418
+
419
+ | Source Pattern | PromptScript Block |
420
+ | ----------------------------------- | ------------------ |
421
+ | "You are..." persona text | `@identity` |
422
+ | Project description, tech stack | `@context` |
423
+ | Coding conventions, style rules | `@standards` |
424
+ | "Never...", "Always...", hard rules | `@restrictions` |
425
+ | `/command` definitions | `@shortcuts` |
426
+ | Skill/tool definitions | `@skills` |
427
+ | Agent/subagent configs | `@agents` |
428
+ | Reference docs, API specs | `@knowledge` |
429
+
430
+ ### Step 4: Generate PromptScript
431
+
432
+ Create `.prs` files in `.promptscript/` directory using the mapped content. Start with `project.prs` containing `@meta` with project id and syntax version.
433
+
434
+ ### Step 5: File Organization
435
+
436
+ Split content into logical files:
437
+
438
+ - `project.prs` - entry point with `@meta`, `@inherit`, `@use`, `@identity`
439
+ - `context.prs` - `@context` block
440
+ - `standards.prs` - `@standards` block
441
+ - `restrictions.prs` - `@restrictions` block
442
+ - `commands.prs` - `@shortcuts` and `@knowledge` blocks
443
+
444
+ Use `@use ./context`, `@use ./standards`, etc. in `project.prs` to compose them.
445
+
446
+ ### Step 6: Configuration
447
+
448
+ Create or update `promptscript.yaml` with appropriate targets matching the original AI tools being used.
449
+
450
+ ### Step 7: Validation
451
+
452
+ Run `prs validate --strict` to check syntax, then `prs compile` to generate output files. Compare compiled output with original files to verify content was preserved.
453
+
454
+ ### Migration Tips
455
+
456
+ - Preserve the original intent and tone of instructions
457
+ - Don't lose any rules or restrictions during mapping
458
+ - Use `@knowledge` for large reference sections that don't fit other blocks
459
+ - Back up original files before overwriting with compiled output
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,gBAAgB,CAAC;AAmBzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAyD/C;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,QAAQ,GAAE,WAAqC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAyJf"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../../../packages/cli/src/commands/init.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,WAAW,EAAyB,MAAM,gBAAgB,CAAC;AAmBzE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAyD/C;;;GAGG;AACH,wBAAsB,WAAW,CAC/B,OAAO,EAAE,WAAW,EACpB,QAAQ,GAAE,WAAqC,GAC9C,OAAO,CAAC,IAAI,CAAC,CAwKf"}
@@ -1,228 +0,0 @@
1
- ---
2
- name: migrate-to-promptscript
3
- description: Migrate existing AI instruction files to PromptScript format. Use when converting CLAUDE.md, .cursorrules, copilot-instructions.md, AGENTS.md, or other AI instruction files into a unified .prs source.
4
- ---
5
-
6
- # Migrate to PromptScript
7
-
8
- ## Overview
9
-
10
- This skill guides you through migrating existing AI instruction files
11
- to PromptScript format, creating a unified source of truth for all
12
- AI coding assistants.
13
-
14
- ## Step 1: Discovery
15
-
16
- Search for existing instruction files using these patterns:
17
-
18
- Claude Code:
19
-
20
- - CLAUDE.md, claude.md, CLAUDE.local.md
21
-
22
- Cursor:
23
-
24
- - .cursorrules
25
- - .cursor/rules/\*.md
26
- - .cursor/rules/\*.mdc
27
-
28
- GitHub Copilot:
29
-
30
- - .github/copilot-instructions.md
31
- - .github/instructions/\*.md
32
-
33
- Factory AI:
34
-
35
- - AGENTS.md
36
- - .factory/skills/\*/SKILL.md
37
-
38
- Other:
39
-
40
- - AI_INSTRUCTIONS.md
41
- - AI.md
42
- - .ai/instructions.md
43
-
44
- Use Glob tool to find these files.
45
-
46
- ## Step 2: Read and Analyze
47
-
48
- For each discovered file:
49
-
50
- 1. Read the full content using the Read tool
51
- 2. Identify sections by headers (##, ###) and patterns
52
- 3. Classify content type using the mapping table below
53
- 4. Note any tool-specific content that may need special handling
54
-
55
- ## Step 3: Content Mapping
56
-
57
- Map source content to PromptScript blocks:
58
-
59
- | Source Pattern | PromptScript Block |
60
- | ------------------------------------ | ------------------ |
61
- | You are, persona, identity, role | @identity |
62
- | Tech stack, languages, frameworks | @context |
63
- | Coding standards, conventions, rules | @standards |
64
- | Don't, Never, restrictions | @restrictions |
65
- | Commands, shortcuts | @shortcuts |
66
- | API docs, references, knowledge base | @knowledge |
67
- | Parameters, config values | @params |
68
- | File patterns, globs, applyTo | @guards |
69
- | Skills, capabilities | @skills |
70
- | Agents, subagents | @agents |
71
- | Local-only settings | @local |
72
-
73
- ## Step 4: Generate PromptScript
74
-
75
- ### Required: @meta block
76
-
77
- Every PromptScript file needs metadata with id and syntax fields.
78
-
79
- ### Identity (persona)
80
-
81
- Convert persona descriptions to @identity block with triple-quote string.
82
-
83
- ### Context (project info)
84
-
85
- Convert tech stack to @context block with structured properties
86
- like project, languages, frameworks.
87
-
88
- ### Standards (conventions)
89
-
90
- Convert coding standards to @standards block organized by category:
91
- code, naming, commits, etc.
92
-
93
- ### Restrictions (don'ts)
94
-
95
- Convert restrictions to @restrictions block using dash prefix for each item.
96
-
97
- ### Shortcuts (commands)
98
-
99
- Convert custom commands to @shortcuts block. Simple shortcuts use
100
- key-value format. Complex shortcuts use object format with
101
- prompt, description, and content fields.
102
-
103
- ### Knowledge (references)
104
-
105
- Convert API docs and reference material to @knowledge block
106
- using triple-quote string for rich content.
107
-
108
- ### Guards (file patterns)
109
-
110
- Convert file-specific rules to @guards block with globs array
111
- specifying file patterns.
112
-
113
- ### Params (configuration)
114
-
115
- Convert configuration parameters to @params block with type annotations:
116
- range(), enum(), boolean.
117
-
118
- ### Skills (capabilities)
119
-
120
- Convert skill definitions to @skills block with description,
121
- trigger, and content fields.
122
-
123
- ### Agents (subagents)
124
-
125
- Convert agent definitions to @agents block with description,
126
- tools, model, and content fields.
127
-
128
- ## Step 5: File Organization
129
-
130
- Simple Projects - single file structure:
131
-
132
- - .promptscript/project.prs
133
- - promptscript.yaml
134
-
135
- Complex Projects - modular file structure:
136
-
137
- - .promptscript/project.prs (main with @use imports)
138
- - .promptscript/context.prs
139
- - .promptscript/standards.prs
140
- - .promptscript/restrictions.prs
141
- - .promptscript/commands.prs
142
- - promptscript.yaml
143
-
144
- ## Step 6: Configuration
145
-
146
- Create promptscript.yaml with:
147
-
148
- - version: '1'
149
- - project.id
150
- - input.entry pointing to main .prs file
151
- - targets for github, claude, cursor, factory, etc.
152
-
153
- ## Step 7: Validation
154
-
155
- After generating PromptScript files:
156
-
157
- 1. Validate syntax: prs validate
158
- 2. Test compilation: prs compile --dry-run
159
- 3. Compare output with original files
160
- 4. Iterate if content is missing or incorrect
161
-
162
- ## Common Patterns
163
-
164
- ### Merging Multiple Sources
165
-
166
- When instructions exist in multiple files:
167
-
168
- 1. Identity: Take from most detailed source
169
- 2. Standards: Merge all, deduplicate
170
- 3. Restrictions: Combine all (union)
171
- 4. Commands: Merge, resolve conflicts
172
-
173
- ### Tool-Specific Content
174
-
175
- Handle tool-specific content:
176
-
177
- - GitHub prompts: Use @shortcuts with prompt: true
178
- - Claude agents: Use @agents block
179
- - Cursor rules: Map to @standards
180
- - Local content: Use @local block
181
-
182
- ### Preserving Formatting
183
-
184
- Use triple-quote multiline strings for:
185
-
186
- - Rich markdown content
187
- - Code examples
188
- - Complex instructions
189
-
190
- ## Syntax Rules
191
-
192
- Quick reference for PromptScript syntax:
193
-
194
- - Strings: quoted or identifier
195
- - Multi-line: triple quotes
196
- - Arrays: [item1, item2] or - item prefix
197
- - Objects: { key: value }
198
- - Comments: # comment
199
- - Required @meta fields: id, syntax
200
-
201
- ## Quality Checklist
202
-
203
- Before completing migration:
204
-
205
- - @meta block has id and syntax
206
- - Identity is clear and specific
207
- - Standards are organized by category
208
- - Restrictions use dash prefix (-)
209
- - Shortcuts work in target tools
210
- - prs validate passes
211
- - prs compile produces correct output
212
- - No duplicate content across blocks
213
-
214
- ## Troubleshooting
215
-
216
- ### Missing @meta Error
217
-
218
- Add required metadata block at the start.
219
-
220
- ### Multiline String in Object Error
221
-
222
- Assign multiline strings to named keys, don't leave them loose
223
- inside objects.
224
-
225
- ### Content Not Appearing in Output
226
-
227
- Check block names match expected patterns and
228
- verify syntax with prs validate --verbose.