@dedesfr/prompter 0.8.23 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (247) hide show
  1. package/CHANGELOG.md +70 -0
  2. package/README.md +105 -77
  3. package/dist/cli/index.js +25 -1
  4. package/dist/cli/index.js.map +1 -1
  5. package/dist/commands/init.d.ts +1 -7
  6. package/dist/commands/init.d.ts.map +1 -1
  7. package/dist/commands/init.js +60 -299
  8. package/dist/commands/init.js.map +1 -1
  9. package/dist/commands/login.d.ts +4 -0
  10. package/dist/commands/login.d.ts.map +1 -0
  11. package/dist/commands/login.js +56 -0
  12. package/dist/commands/login.js.map +1 -0
  13. package/dist/commands/logout.d.ts +4 -0
  14. package/dist/commands/logout.d.ts.map +1 -0
  15. package/dist/commands/logout.js +14 -0
  16. package/dist/commands/logout.js.map +1 -0
  17. package/dist/commands/update.d.ts.map +1 -1
  18. package/dist/commands/update.js +31 -41
  19. package/dist/commands/update.js.map +1 -1
  20. package/dist/commands/whoami.d.ts +4 -0
  21. package/dist/commands/whoami.d.ts.map +1 -0
  22. package/dist/commands/whoami.js +42 -0
  23. package/dist/commands/whoami.js.map +1 -0
  24. package/dist/core/auth-store.d.ts +10 -0
  25. package/dist/core/auth-store.d.ts.map +1 -0
  26. package/dist/core/auth-store.js +39 -0
  27. package/dist/core/auth-store.js.map +1 -0
  28. package/dist/core/configurators/slash/antigravity.d.ts +2 -5
  29. package/dist/core/configurators/slash/antigravity.d.ts.map +1 -1
  30. package/dist/core/configurators/slash/antigravity.js +2 -57
  31. package/dist/core/configurators/slash/antigravity.js.map +1 -1
  32. package/dist/core/configurators/slash/base.d.ts +6 -18
  33. package/dist/core/configurators/slash/base.d.ts.map +1 -1
  34. package/dist/core/configurators/slash/base.js +8 -77
  35. package/dist/core/configurators/slash/base.js.map +1 -1
  36. package/dist/core/configurators/slash/claude.d.ts +2 -5
  37. package/dist/core/configurators/slash/claude.d.ts.map +1 -1
  38. package/dist/core/configurators/slash/claude.js +2 -57
  39. package/dist/core/configurators/slash/claude.js.map +1 -1
  40. package/dist/core/configurators/slash/codex.d.ts +2 -5
  41. package/dist/core/configurators/slash/codex.d.ts.map +1 -1
  42. package/dist/core/configurators/slash/codex.js +2 -57
  43. package/dist/core/configurators/slash/codex.js.map +1 -1
  44. package/dist/core/configurators/slash/droid.d.ts +2 -5
  45. package/dist/core/configurators/slash/droid.d.ts.map +1 -1
  46. package/dist/core/configurators/slash/droid.js +2 -32
  47. package/dist/core/configurators/slash/droid.js.map +1 -1
  48. package/dist/core/configurators/slash/forge.d.ts +2 -5
  49. package/dist/core/configurators/slash/forge.d.ts.map +1 -1
  50. package/dist/core/configurators/slash/forge.js +2 -32
  51. package/dist/core/configurators/slash/forge.js.map +1 -1
  52. package/dist/core/configurators/slash/github-copilot.d.ts +2 -7
  53. package/dist/core/configurators/slash/github-copilot.d.ts.map +1 -1
  54. package/dist/core/configurators/slash/github-copilot.js +2 -96
  55. package/dist/core/configurators/slash/github-copilot.js.map +1 -1
  56. package/dist/core/configurators/slash/index.d.ts +1 -1
  57. package/dist/core/configurators/slash/index.d.ts.map +1 -1
  58. package/dist/core/configurators/slash/index.js +1 -1
  59. package/dist/core/configurators/slash/index.js.map +1 -1
  60. package/dist/core/configurators/slash/kilocode.d.ts +2 -5
  61. package/dist/core/configurators/slash/kilocode.d.ts.map +1 -1
  62. package/dist/core/configurators/slash/kilocode.js +2 -57
  63. package/dist/core/configurators/slash/kilocode.js.map +1 -1
  64. package/dist/core/configurators/slash/opencode.d.ts +2 -5
  65. package/dist/core/configurators/slash/opencode.d.ts.map +1 -1
  66. package/dist/core/configurators/slash/opencode.js +2 -57
  67. package/dist/core/configurators/slash/opencode.js.map +1 -1
  68. package/dist/core/configurators/slash/registry.d.ts +4 -4
  69. package/dist/core/configurators/slash/registry.d.ts.map +1 -1
  70. package/dist/core/configurators/slash/registry.js.map +1 -1
  71. package/dist/core/registry.d.ts +18 -0
  72. package/dist/core/registry.d.ts.map +1 -0
  73. package/dist/core/registry.js +94 -0
  74. package/dist/core/registry.js.map +1 -0
  75. package/dist/core/templates/index.d.ts +0 -1
  76. package/dist/core/templates/index.d.ts.map +1 -1
  77. package/dist/core/templates/index.js +0 -1
  78. package/dist/core/templates/index.js.map +1 -1
  79. package/package.json +7 -1
  80. package/AGENTS.md +0 -123
  81. package/CLAUDE.md +0 -17
  82. package/build.js +0 -20
  83. package/convex-setup.md +0 -403
  84. package/dist/core/templates/slash-command-templates.d.ts +0 -7
  85. package/dist/core/templates/slash-command-templates.d.ts.map +0 -1
  86. package/dist/core/templates/slash-command-templates.js +0 -1041
  87. package/dist/core/templates/slash-command-templates.js.map +0 -1
  88. package/prompt/ai-humanizer.md +0 -45
  89. package/prompt/api-contract-generator.md +0 -234
  90. package/prompt/apply.md +0 -17
  91. package/prompt/archive.md +0 -21
  92. package/prompt/design-system.md +0 -210
  93. package/prompt/document-explainer.md +0 -149
  94. package/prompt/epic-generator.md +0 -198
  95. package/prompt/epic-single.md +0 -47
  96. package/prompt/erd-generator.md +0 -130
  97. package/prompt/fsd-generator.md +0 -157
  98. package/prompt/prd-agent-generator.md +0 -147
  99. package/prompt/prd-generator.md +0 -195
  100. package/prompt/product-brief.md +0 -289
  101. package/prompt/proposal.md +0 -22
  102. package/prompt/qa-test-scenario.md +0 -133
  103. package/prompt/skill-creator.md +0 -350
  104. package/prompt/story-generator.md +0 -278
  105. package/prompt/story-single.md +0 -70
  106. package/prompt/tdd-generator.md +0 -294
  107. package/prompt/tdd-lite-generator.md +0 -224
  108. package/prompt/wireframe-generator.md +0 -219
  109. package/skills/ai-context-generator/SKILL.md +0 -54
  110. package/skills/ai-context-generator/references/AGENTS.template.md +0 -83
  111. package/skills/ai-context-generator/references/CLAUDE.template.md +0 -39
  112. package/skills/ai-context-generator/references/behavioral-guidelines.md +0 -71
  113. package/skills/ai-context-generator/references/discovery-checklist.md +0 -40
  114. package/skills/ai-context-generator/references/examples/AGENTS.good.md +0 -103
  115. package/skills/ai-context-generator/references/extraction-checklist.md +0 -23
  116. package/skills/ai-context-generator/references/overlays/laravel.md +0 -44
  117. package/skills/cerebro/SKILL.md +0 -187
  118. package/skills/cerebro/references/agents.md +0 -213
  119. package/skills/code-review/SKILL.md +0 -373
  120. package/skills/code-review/assets/report-template-agent.md +0 -212
  121. package/skills/code-review/assets/report-template-compact.md +0 -81
  122. package/skills/code-review/assets/report-template-full.md +0 -264
  123. package/skills/code-review/assets/report-template-human.md +0 -168
  124. package/skills/code-review/references/universal-patterns.md +0 -495
  125. package/skills/design-md/README.md +0 -34
  126. package/skills/design-md/SKILL.md +0 -172
  127. package/skills/design-md/examples/DESIGN.md +0 -154
  128. package/skills/design-system-generator/SKILL.md +0 -324
  129. package/skills/design-system-generator/assets/design-system-template.md +0 -348
  130. package/skills/design-system-generator/references/extraction-patterns.md +0 -321
  131. package/skills/doc-builder/SKILL.md +0 -115
  132. package/skills/doc-builder/references/ui-patterns.md +0 -394
  133. package/skills/document-translator/SKILL.md +0 -58
  134. package/skills/enhance-prompt/README.md +0 -34
  135. package/skills/enhance-prompt/SKILL.md +0 -204
  136. package/skills/enhance-prompt/references/KEYWORDS.md +0 -114
  137. package/skills/feature-planner/SKILL.md +0 -305
  138. package/skills/feature-planner/assets/implementation-plan-template.md +0 -85
  139. package/skills/frontend-design/LICENSE.txt +0 -177
  140. package/skills/frontend-design/SKILL.md +0 -42
  141. package/skills/gamma-builder/SKILL.md +0 -134
  142. package/skills/laravel-code-review/SKILL.md +0 -383
  143. package/skills/laravel-code-review/assets/report-template-agent.md +0 -195
  144. package/skills/laravel-code-review/assets/report-template-compact.md +0 -79
  145. package/skills/laravel-code-review/assets/report-template-full.md +0 -253
  146. package/skills/laravel-code-review/assets/report-template-human.md +0 -159
  147. package/skills/laravel-code-review/references/laravel-patterns.md +0 -571
  148. package/skills/laravel-code-review/references/php84-features.md +0 -442
  149. package/skills/mcp-builder/LICENSE.txt +0 -202
  150. package/skills/mcp-builder/SKILL.md +0 -236
  151. package/skills/mcp-builder/reference/evaluation.md +0 -602
  152. package/skills/mcp-builder/reference/mcp_best_practices.md +0 -249
  153. package/skills/mcp-builder/reference/node_mcp_server.md +0 -970
  154. package/skills/mcp-builder/reference/python_mcp_server.md +0 -719
  155. package/skills/mcp-builder/scripts/connections.py +0 -151
  156. package/skills/mcp-builder/scripts/evaluation.py +0 -373
  157. package/skills/mcp-builder/scripts/example_evaluation.xml +0 -22
  158. package/skills/mcp-builder/scripts/requirements.txt +0 -2
  159. package/skills/meeting-notes/SKILL.md +0 -159
  160. package/skills/meeting-notes/evals/evals.json +0 -23
  161. package/skills/project-orchestrator/SKILL.md +0 -487
  162. package/skills/project-orchestrator/assets/caddy-vps-setup.md +0 -180
  163. package/skills/project-orchestrator/assets/plan-summary-template.md +0 -159
  164. package/skills/prompter-specs/SKILL.md +0 -115
  165. package/skills/prompter-workflow/SKILL.md +0 -166
  166. package/skills/prompter-workflow/evals/evals.json +0 -89
  167. package/skills/sph-generator/SKILL.md +0 -488
  168. package/skills/ui-ux-pro/SKILL.md +0 -199
  169. package/skills/ui-ux-pro/assets/design-spec-template.md +0 -173
  170. package/skills/ui-ux-pro/references/component-patterns.md +0 -255
  171. package/skills/ui-ux-pro/references/design-principles.md +0 -167
  172. package/src/cli/index.ts +0 -223
  173. package/src/commands/archive.ts +0 -302
  174. package/src/commands/change.ts +0 -292
  175. package/src/commands/config.ts +0 -233
  176. package/src/commands/guide.ts +0 -50
  177. package/src/commands/init.ts +0 -899
  178. package/src/commands/list.ts +0 -194
  179. package/src/commands/show.ts +0 -138
  180. package/src/commands/spec.ts +0 -251
  181. package/src/commands/update.ts +0 -156
  182. package/src/commands/upgrade.ts +0 -30
  183. package/src/commands/validate.ts +0 -326
  184. package/src/core/artifact-graph/graph.ts +0 -167
  185. package/src/core/artifact-graph/index.ts +0 -44
  186. package/src/core/artifact-graph/instruction-loader.ts +0 -302
  187. package/src/core/artifact-graph/resolver.ts +0 -226
  188. package/src/core/artifact-graph/schema.ts +0 -124
  189. package/src/core/artifact-graph/state.ts +0 -64
  190. package/src/core/artifact-graph/types.ts +0 -65
  191. package/src/core/completions/command-registry.ts +0 -382
  192. package/src/core/completions/completion-provider.ts +0 -128
  193. package/src/core/completions/generators/bash-generator.ts +0 -191
  194. package/src/core/completions/generators/fish-generator.ts +0 -188
  195. package/src/core/completions/generators/powershell-generator.ts +0 -223
  196. package/src/core/completions/generators/zsh-generator.ts +0 -281
  197. package/src/core/completions/templates/bash-templates.ts +0 -24
  198. package/src/core/completions/templates/fish-templates.ts +0 -40
  199. package/src/core/completions/templates/powershell-templates.ts +0 -25
  200. package/src/core/completions/templates/zsh-templates.ts +0 -36
  201. package/src/core/completions/types.ts +0 -90
  202. package/src/core/config-schema.ts +0 -230
  203. package/src/core/config.ts +0 -181
  204. package/src/core/configurators/slash/antigravity.ts +0 -70
  205. package/src/core/configurators/slash/base.ts +0 -203
  206. package/src/core/configurators/slash/claude.ts +0 -70
  207. package/src/core/configurators/slash/codex.ts +0 -70
  208. package/src/core/configurators/slash/droid.ts +0 -44
  209. package/src/core/configurators/slash/forge.ts +0 -44
  210. package/src/core/configurators/slash/github-copilot.ts +0 -114
  211. package/src/core/configurators/slash/index.ts +0 -10
  212. package/src/core/configurators/slash/kilocode.ts +0 -70
  213. package/src/core/configurators/slash/opencode.ts +0 -70
  214. package/src/core/configurators/slash/registry.ts +0 -51
  215. package/src/core/converters/json-converter.ts +0 -62
  216. package/src/core/global-config.ts +0 -136
  217. package/src/core/parsers/change-parser.ts +0 -234
  218. package/src/core/parsers/markdown-parser.ts +0 -237
  219. package/src/core/parsers/requirement-blocks.ts +0 -234
  220. package/src/core/prompt-templates.ts +0 -3504
  221. package/src/core/schemas/base.schema.ts +0 -20
  222. package/src/core/schemas/change.schema.ts +0 -42
  223. package/src/core/schemas/index.ts +0 -20
  224. package/src/core/schemas/spec.schema.ts +0 -17
  225. package/src/core/skill-discovery.ts +0 -68
  226. package/src/core/specs-apply.ts +0 -483
  227. package/src/core/styles/palette.ts +0 -8
  228. package/src/core/templates/agents-template.ts +0 -459
  229. package/src/core/templates/claude-template.ts +0 -2
  230. package/src/core/templates/index.ts +0 -4
  231. package/src/core/templates/project-template.ts +0 -32
  232. package/src/core/templates/slash-command-templates.ts +0 -1068
  233. package/src/core/validation/constants.ts +0 -48
  234. package/src/core/validation/types.ts +0 -19
  235. package/src/core/validation/validator.ts +0 -449
  236. package/src/core/view.ts +0 -219
  237. package/src/index.ts +0 -1
  238. package/src/utils/change-metadata.ts +0 -171
  239. package/src/utils/change-utils.ts +0 -131
  240. package/src/utils/file-system.ts +0 -252
  241. package/src/utils/index.ts +0 -12
  242. package/src/utils/interactive.ts +0 -29
  243. package/src/utils/item-discovery.ts +0 -66
  244. package/src/utils/match.ts +0 -26
  245. package/src/utils/shell-detection.ts +0 -62
  246. package/src/utils/task-progress.ts +0 -43
  247. package/tsconfig.json +0 -28
@@ -1,252 +0,0 @@
1
- import { promises as fs, constants as fsConstants } from 'fs';
2
- import path from 'path';
3
-
4
- function isMarkerOnOwnLine(content: string, markerIndex: number, markerLength: number): boolean {
5
- let leftIndex = markerIndex - 1;
6
- while (leftIndex >= 0 && content[leftIndex] !== '\n') {
7
- const char = content[leftIndex];
8
- if (char !== ' ' && char !== '\t' && char !== '\r') {
9
- return false;
10
- }
11
- leftIndex--;
12
- }
13
-
14
- let rightIndex = markerIndex + markerLength;
15
- while (rightIndex < content.length && content[rightIndex] !== '\n') {
16
- const char = content[rightIndex];
17
- if (char !== ' ' && char !== '\t' && char !== '\r') {
18
- return false;
19
- }
20
- rightIndex++;
21
- }
22
-
23
- return true;
24
- }
25
-
26
- function findMarkerIndex(
27
- content: string,
28
- marker: string,
29
- fromIndex = 0
30
- ): number {
31
- let currentIndex = content.indexOf(marker, fromIndex);
32
-
33
- while (currentIndex !== -1) {
34
- if (isMarkerOnOwnLine(content, currentIndex, marker.length)) {
35
- return currentIndex;
36
- }
37
-
38
- currentIndex = content.indexOf(marker, currentIndex + marker.length);
39
- }
40
-
41
- return -1;
42
- }
43
-
44
- export class FileSystemUtils {
45
- /**
46
- * Converts a path to use forward slashes (POSIX style).
47
- * Essential for cross-platform compatibility with glob libraries like fast-glob.
48
- */
49
- static toPosixPath(p: string): string {
50
- return p.replace(/\\/g, '/');
51
- }
52
-
53
- private static isWindowsBasePath(basePath: string): boolean {
54
- return /^[A-Za-z]:[\\/]/.test(basePath) || basePath.startsWith('\\');
55
- }
56
-
57
- private static normalizeSegments(segments: string[]): string[] {
58
- return segments
59
- .flatMap((segment) => segment.split(/[\\/]+/u))
60
- .filter((part) => part.length > 0);
61
- }
62
-
63
- static joinPath(basePath: string, ...segments: string[]): string {
64
- const normalizedSegments = this.normalizeSegments(segments);
65
-
66
- if (this.isWindowsBasePath(basePath)) {
67
- const normalizedBasePath = path.win32.normalize(basePath);
68
- return normalizedSegments.length
69
- ? path.win32.join(normalizedBasePath, ...normalizedSegments)
70
- : normalizedBasePath;
71
- }
72
-
73
- const posixBasePath = basePath.replace(/\\/g, '/');
74
-
75
- return normalizedSegments.length
76
- ? path.posix.join(posixBasePath, ...normalizedSegments)
77
- : path.posix.normalize(posixBasePath);
78
- }
79
-
80
- static async createDirectory(dirPath: string): Promise<void> {
81
- await fs.mkdir(dirPath, { recursive: true });
82
- }
83
-
84
- static async fileExists(filePath: string): Promise<boolean> {
85
- try {
86
- await fs.access(filePath);
87
- return true;
88
- } catch (error: any) {
89
- if (error.code !== 'ENOENT') {
90
- console.debug(`Unable to check if file exists at ${filePath}: ${error.message}`);
91
- }
92
- return false;
93
- }
94
- }
95
-
96
- /**
97
- * Finds the first existing parent directory by walking up the directory tree.
98
- * @param dirPath Starting directory path
99
- * @returns The first existing directory path, or null if root is reached without finding one
100
- */
101
- private static async findFirstExistingDirectory(dirPath: string): Promise<string | null> {
102
- let currentDir = dirPath;
103
-
104
- while (true) {
105
- try {
106
- const stats = await fs.stat(currentDir);
107
- if (stats.isDirectory()) {
108
- return currentDir;
109
- }
110
- // Path component exists but is not a directory (edge case)
111
- console.debug(`Path component ${currentDir} exists but is not a directory`);
112
- return null;
113
- } catch (error: any) {
114
- if (error.code === 'ENOENT') {
115
- // Directory doesn't exist, move up one level
116
- const parentDir = path.dirname(currentDir);
117
- if (parentDir === currentDir) {
118
- // Reached filesystem root without finding existing directory
119
- return null;
120
- }
121
- currentDir = parentDir;
122
- } else {
123
- // Unexpected error (permissions, I/O error, etc.)
124
- console.debug(`Error checking directory ${currentDir}: ${error.message}`);
125
- return null;
126
- }
127
- }
128
- }
129
- }
130
-
131
- static async canWriteFile(filePath: string): Promise<boolean> {
132
- try {
133
- const stats = await fs.stat(filePath);
134
-
135
- if (!stats.isFile()) {
136
- return true;
137
- }
138
-
139
- // On Windows, stats.mode doesn't reliably indicate write permissions.
140
- // Use fs.access with W_OK to check actual write permissions cross-platform.
141
- try {
142
- await fs.access(filePath, fsConstants.W_OK);
143
- return true;
144
- } catch {
145
- return false;
146
- }
147
- } catch (error: any) {
148
- if (error.code === 'ENOENT') {
149
- // File doesn't exist - find first existing parent directory and check its permissions
150
- const parentDir = path.dirname(filePath);
151
- const existingDir = await this.findFirstExistingDirectory(parentDir);
152
-
153
- if (existingDir === null) {
154
- // No existing parent directory found (edge case)
155
- return false;
156
- }
157
-
158
- // Check if the existing parent directory is writable
159
- try {
160
- await fs.access(existingDir, fsConstants.W_OK);
161
- return true;
162
- } catch {
163
- return false;
164
- }
165
- }
166
-
167
- console.debug(`Unable to determine write permissions for ${filePath}: ${error.message}`);
168
- return false;
169
- }
170
- }
171
-
172
- static async directoryExists(dirPath: string): Promise<boolean> {
173
- try {
174
- const stats = await fs.stat(dirPath);
175
- return stats.isDirectory();
176
- } catch (error: any) {
177
- if (error.code !== 'ENOENT') {
178
- console.debug(`Unable to check if directory exists at ${dirPath}: ${error.message}`);
179
- }
180
- return false;
181
- }
182
- }
183
-
184
- static async writeFile(filePath: string, content: string): Promise<void> {
185
- const dir = path.dirname(filePath);
186
- await this.createDirectory(dir);
187
- await fs.writeFile(filePath, content, 'utf-8');
188
- }
189
-
190
- static async readFile(filePath: string): Promise<string> {
191
- return await fs.readFile(filePath, 'utf-8');
192
- }
193
-
194
- static async updateFileWithMarkers(
195
- filePath: string,
196
- content: string,
197
- startMarker: string,
198
- endMarker: string
199
- ): Promise<void> {
200
- let existingContent = '';
201
-
202
- if (await this.fileExists(filePath)) {
203
- existingContent = await this.readFile(filePath);
204
-
205
- const startIndex = findMarkerIndex(existingContent, startMarker);
206
- const endIndex = startIndex !== -1
207
- ? findMarkerIndex(existingContent, endMarker, startIndex + startMarker.length)
208
- : findMarkerIndex(existingContent, endMarker);
209
-
210
- if (startIndex !== -1 && endIndex !== -1) {
211
- if (endIndex < startIndex) {
212
- throw new Error(
213
- `Invalid marker state in ${filePath}. End marker appears before start marker.`
214
- );
215
- }
216
-
217
- const before = existingContent.substring(0, startIndex);
218
- const after = existingContent.substring(endIndex + endMarker.length);
219
- existingContent = before + startMarker + '\n' + content + '\n' + endMarker + after;
220
- } else if (startIndex === -1 && endIndex === -1) {
221
- existingContent = startMarker + '\n' + content + '\n' + endMarker + '\n\n' + existingContent;
222
- } else {
223
- throw new Error(`Invalid marker state in ${filePath}. Found start: ${startIndex !== -1}, Found end: ${endIndex !== -1}`);
224
- }
225
- } else {
226
- existingContent = startMarker + '\n' + content + '\n' + endMarker;
227
- }
228
-
229
- await this.writeFile(filePath, existingContent);
230
- }
231
-
232
- static async ensureWritePermissions(dirPath: string): Promise<boolean> {
233
- try {
234
- // If directory doesn't exist, check parent directory permissions
235
- if (!await this.directoryExists(dirPath)) {
236
- const parentDir = path.dirname(dirPath);
237
- if (!await this.directoryExists(parentDir)) {
238
- await this.createDirectory(parentDir);
239
- }
240
- return await this.ensureWritePermissions(parentDir);
241
- }
242
-
243
- const testFile = path.join(dirPath, '.prompter-test-' + Date.now());
244
- await fs.writeFile(testFile, '');
245
- await fs.unlink(testFile);
246
- return true;
247
- } catch (error: any) {
248
- console.debug(`Insufficient permissions to write to ${dirPath}: ${error.message}`);
249
- return false;
250
- }
251
- }
252
- }
@@ -1,12 +0,0 @@
1
- // Shared utilities
2
- export { validateChangeName, createChange } from './change-utils.js';
3
- export type { ValidationResult, CreateChangeOptions } from './change-utils.js';
4
-
5
- // Change metadata utilities
6
- export {
7
- readChangeMetadata,
8
- writeChangeMetadata,
9
- resolveSchemaForChange,
10
- validateSchemaName,
11
- ChangeMetadataError,
12
- } from './change-metadata.js';
@@ -1,29 +0,0 @@
1
- export type InteractiveOptions = {
2
- /**
3
- * Explicit "disable prompts" flag passed by internal callers.
4
- */
5
- noInteractive?: boolean;
6
- /**
7
- * Commander-style negated option: `--no-interactive` sets this to false.
8
- */
9
- interactive?: boolean;
10
- };
11
-
12
- /**
13
- * Resolves whether non-interactive mode is requested.
14
- * Handles both explicit `noInteractive: true` and Commander.js style `interactive: false`.
15
- * Use this helper instead of manually checking options.noInteractive to avoid bugs.
16
- */
17
- export function resolveNoInteractive(value?: boolean | InteractiveOptions): boolean {
18
- if (typeof value === 'boolean') return value;
19
- return value?.noInteractive === true || value?.interactive === false;
20
- }
21
-
22
- export function isInteractive(value?: boolean | InteractiveOptions): boolean {
23
- if (resolveNoInteractive(value)) return false;
24
- if (process.env.OPEN_SPEC_INTERACTIVE === '0') return false;
25
- // Respect the standard CI environment variable (set by GitHub Actions, GitLab CI, Travis, etc.)
26
- if ('CI' in process.env) return false;
27
- return !!process.stdin.isTTY;
28
- }
29
-
@@ -1,66 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
-
4
- export async function getActiveChangeIds(root: string = process.cwd()): Promise<string[]> {
5
- const changesPath = path.join(root, 'prompter', 'changes');
6
- try {
7
- const entries = await fs.readdir(changesPath, { withFileTypes: true });
8
- const result: string[] = [];
9
- for (const entry of entries) {
10
- if (!entry.isDirectory() || entry.name.startsWith('.') || entry.name === 'archive') continue;
11
- const proposalPath = path.join(changesPath, entry.name, 'proposal.md');
12
- try {
13
- await fs.access(proposalPath);
14
- result.push(entry.name);
15
- } catch {
16
- // skip directories without proposal.md
17
- }
18
- }
19
- return result.sort();
20
- } catch {
21
- return [];
22
- }
23
- }
24
-
25
- export async function getSpecIds(root: string = process.cwd()): Promise<string[]> {
26
- const specsPath = path.join(root, 'prompter', 'specs');
27
- const result: string[] = [];
28
- try {
29
- const entries = await fs.readdir(specsPath, { withFileTypes: true });
30
- for (const entry of entries) {
31
- if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
32
- const specFile = path.join(specsPath, entry.name, 'spec.md');
33
- try {
34
- await fs.access(specFile);
35
- result.push(entry.name);
36
- } catch {
37
- // ignore
38
- }
39
- }
40
- } catch {
41
- // ignore
42
- }
43
- return result.sort();
44
- }
45
-
46
- export async function getArchivedChangeIds(root: string = process.cwd()): Promise<string[]> {
47
- const archivePath = path.join(root, 'prompter', 'changes', 'archive');
48
- try {
49
- const entries = await fs.readdir(archivePath, { withFileTypes: true });
50
- const result: string[] = [];
51
- for (const entry of entries) {
52
- if (!entry.isDirectory() || entry.name.startsWith('.')) continue;
53
- const proposalPath = path.join(archivePath, entry.name, 'proposal.md');
54
- try {
55
- await fs.access(proposalPath);
56
- result.push(entry.name);
57
- } catch {
58
- // skip directories without proposal.md
59
- }
60
- }
61
- return result.sort();
62
- } catch {
63
- return [];
64
- }
65
- }
66
-
@@ -1,26 +0,0 @@
1
- export function nearestMatches(input: string, candidates: string[], max: number = 5): string[] {
2
- const scored = candidates.map(candidate => ({ candidate, distance: levenshtein(input, candidate) }));
3
- scored.sort((a, b) => a.distance - b.distance);
4
- return scored.slice(0, max).map(s => s.candidate);
5
- }
6
-
7
- export function levenshtein(a: string, b: string): number {
8
- const m = a.length;
9
- const n = b.length;
10
- const dp: number[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(0));
11
- for (let i = 0; i <= m; i++) dp[i][0] = i;
12
- for (let j = 0; j <= n; j++) dp[0][j] = j;
13
- for (let i = 1; i <= m; i++) {
14
- for (let j = 1; j <= n; j++) {
15
- const cost = a[i - 1] === b[j - 1] ? 0 : 1;
16
- dp[i][j] = Math.min(
17
- dp[i - 1][j] + 1,
18
- dp[i][j - 1] + 1,
19
- dp[i - 1][j - 1] + cost
20
- );
21
- }
22
- }
23
- return dp[m][n];
24
- }
25
-
26
-
@@ -1,62 +0,0 @@
1
- /**
2
- * Supported shell types for completion generation
3
- */
4
- export type SupportedShell = 'zsh' | 'bash' | 'fish' | 'powershell';
5
-
6
- /**
7
- * Result of shell detection
8
- */
9
- export interface ShellDetectionResult {
10
- /** The detected shell if supported, otherwise undefined */
11
- shell: SupportedShell | undefined;
12
- /** The raw shell name detected (even if unsupported), or undefined if nothing detected */
13
- detected: string | undefined;
14
- }
15
-
16
- /**
17
- * Detects the current user's shell based on environment variables
18
- *
19
- * @returns Detection result with supported shell and raw detected name
20
- */
21
- export function detectShell(): ShellDetectionResult {
22
- // Try SHELL environment variable first (Unix-like systems)
23
- const shellPath = process.env.SHELL;
24
-
25
- if (shellPath) {
26
- const shellName = shellPath.toLowerCase();
27
-
28
- if (shellName.includes('zsh')) {
29
- return { shell: 'zsh', detected: 'zsh' };
30
- }
31
- if (shellName.includes('bash')) {
32
- return { shell: 'bash', detected: 'bash' };
33
- }
34
- if (shellName.includes('fish')) {
35
- return { shell: 'fish', detected: 'fish' };
36
- }
37
-
38
- // Shell detected but not supported
39
- // Extract shell name from path (e.g., /bin/tcsh -> tcsh)
40
- const match = shellPath.match(/\/([^/]+)$/);
41
- const detectedName = match ? match[1] : shellPath;
42
- return { shell: undefined, detected: detectedName };
43
- }
44
-
45
- // Check for PowerShell on Windows
46
- // PSModulePath is a reliable PowerShell-specific environment variable
47
- if (process.env.PSModulePath || process.platform === 'win32') {
48
- const comspec = process.env.COMSPEC?.toLowerCase();
49
-
50
- // If PSModulePath exists, we're definitely in PowerShell
51
- if (process.env.PSModulePath) {
52
- return { shell: 'powershell', detected: 'powershell' };
53
- }
54
-
55
- // On Windows without PSModulePath, we might be in cmd.exe
56
- if (comspec?.includes('cmd.exe')) {
57
- return { shell: undefined, detected: 'cmd.exe' };
58
- }
59
- }
60
-
61
- return { shell: undefined, detected: undefined };
62
- }
@@ -1,43 +0,0 @@
1
- import { promises as fs } from 'fs';
2
- import path from 'path';
3
-
4
- const TASK_PATTERN = /^[-*]\s+\[[\sx]\]/i;
5
- const COMPLETED_TASK_PATTERN = /^[-*]\s+\[x\]/i;
6
-
7
- export interface TaskProgress {
8
- total: number;
9
- completed: number;
10
- }
11
-
12
- export function countTasksFromContent(content: string): TaskProgress {
13
- const lines = content.split('\n');
14
- let total = 0;
15
- let completed = 0;
16
- for (const line of lines) {
17
- if (line.match(TASK_PATTERN)) {
18
- total++;
19
- if (line.match(COMPLETED_TASK_PATTERN)) {
20
- completed++;
21
- }
22
- }
23
- }
24
- return { total, completed };
25
- }
26
-
27
- export async function getTaskProgressForChange(changesDir: string, changeName: string): Promise<TaskProgress> {
28
- const tasksPath = path.join(changesDir, changeName, 'tasks.md');
29
- try {
30
- const content = await fs.readFile(tasksPath, 'utf-8');
31
- return countTasksFromContent(content);
32
- } catch {
33
- return { total: 0, completed: 0 };
34
- }
35
- }
36
-
37
- export function formatTaskStatus(progress: TaskProgress): string {
38
- if (progress.total === 0) return 'No tasks';
39
- if (progress.completed === progress.total) return '✓ Complete';
40
- return `${progress.completed}/${progress.total} tasks`;
41
- }
42
-
43
-
package/tsconfig.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ES2022",
4
- "module": "NodeNext",
5
- "moduleResolution": "NodeNext",
6
- "lib": [
7
- "ES2022"
8
- ],
9
- "outDir": "./dist",
10
- "rootDir": "./src",
11
- "strict": true,
12
- "esModuleInterop": true,
13
- "skipLibCheck": true,
14
- "forceConsistentCasingInFileNames": true,
15
- "resolveJsonModule": true,
16
- "declaration": true,
17
- "declarationMap": true,
18
- "sourceMap": true
19
- },
20
- "include": [
21
- "src/**/*"
22
- ],
23
- "exclude": [
24
- "node_modules",
25
- "dist",
26
- "test"
27
- ]
28
- }