@codewalla_india/openspec 1.3.1 → 1.3.3

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 (333) hide show
  1. package/LICENSE +22 -22
  2. package/README.md +214 -133
  3. package/bin/openspec.js +5 -5
  4. package/dist/cli/index.js +99 -62
  5. package/dist/commands/change.d.ts +0 -2
  6. package/dist/commands/change.js +107 -86
  7. package/dist/commands/config.js +14 -16
  8. package/dist/commands/doctor.js +9 -4
  9. package/dist/commands/feedback.js +79 -30
  10. package/dist/commands/modify.d.ts +26 -0
  11. package/dist/commands/modify.js +147 -0
  12. package/dist/commands/schema.js +170 -91
  13. package/dist/commands/show.js +5 -2
  14. package/dist/commands/spec.js +49 -29
  15. package/dist/commands/store.js +15 -21
  16. package/dist/commands/validate.d.ts +8 -0
  17. package/dist/commands/validate.js +43 -20
  18. package/dist/commands/workflow/index.d.ts +2 -2
  19. package/dist/commands/workflow/index.js +1 -1
  20. package/dist/commands/workflow/instructions.d.ts +6 -26
  21. package/dist/commands/workflow/instructions.js +183 -376
  22. package/dist/commands/workflow/new-change.d.ts +0 -4
  23. package/dist/commands/workflow/new-change.js +10 -28
  24. package/dist/commands/workflow/shared.d.ts +34 -19
  25. package/dist/commands/workflow/shared.js +34 -4
  26. package/dist/commands/workflow/status.js +10 -32
  27. package/dist/commands/workflow/templates.js +15 -5
  28. package/dist/commands/workset.d.ts +2 -2
  29. package/dist/commands/workset.js +19 -22
  30. package/dist/comprehension-quiz/fingerprint.d.ts +39 -0
  31. package/dist/comprehension-quiz/fingerprint.js +84 -0
  32. package/dist/comprehension-quiz/index.d.ts +42 -0
  33. package/dist/comprehension-quiz/index.js +47 -0
  34. package/dist/comprehension-quiz/pass-record.d.ts +44 -0
  35. package/dist/comprehension-quiz/pass-record.js +98 -0
  36. package/dist/comprehension-quiz/providers/anthropic.d.ts +35 -0
  37. package/dist/comprehension-quiz/providers/anthropic.js +69 -0
  38. package/dist/comprehension-quiz/providers/factory.d.ts +44 -0
  39. package/dist/comprehension-quiz/providers/factory.js +174 -0
  40. package/dist/comprehension-quiz/providers/interface.d.ts +98 -0
  41. package/dist/comprehension-quiz/providers/interface.js +150 -0
  42. package/dist/comprehension-quiz/providers/local.d.ts +35 -0
  43. package/dist/comprehension-quiz/providers/local.js +69 -0
  44. package/dist/comprehension-quiz/providers/ollama.d.ts +35 -0
  45. package/dist/comprehension-quiz/providers/ollama.js +69 -0
  46. package/dist/comprehension-quiz/providers/openai.d.ts +35 -0
  47. package/dist/comprehension-quiz/providers/openai.js +72 -0
  48. package/dist/comprehension-quiz/question-generator.d.ts +117 -0
  49. package/dist/comprehension-quiz/question-generator.js +203 -0
  50. package/dist/comprehension-quiz/quiz-executor.d.ts +75 -0
  51. package/dist/comprehension-quiz/quiz-executor.js +181 -0
  52. package/dist/comprehension-quiz/types.d.ts +137 -0
  53. package/dist/comprehension-quiz/types.js +11 -0
  54. package/dist/core/archive.d.ts +14 -1
  55. package/dist/core/archive.js +1350 -190
  56. package/dist/core/artifact-graph/graph.d.ts +28 -9
  57. package/dist/core/artifact-graph/graph.js +94 -43
  58. package/dist/core/artifact-graph/index.d.ts +1 -1
  59. package/dist/core/artifact-graph/index.js +1 -1
  60. package/dist/core/artifact-graph/instruction-loader.d.ts +30 -3
  61. package/dist/core/artifact-graph/instruction-loader.js +70 -12
  62. package/dist/core/artifact-graph/outputs.d.ts +1 -0
  63. package/dist/core/artifact-graph/outputs.js +67 -5
  64. package/dist/core/artifact-graph/resolver.d.ts +14 -0
  65. package/dist/core/artifact-graph/resolver.js +69 -15
  66. package/dist/core/artifact-graph/types.js +21 -3
  67. package/dist/core/available-tools.d.ts +2 -2
  68. package/dist/core/available-tools.js +14 -3
  69. package/dist/core/change-metadata/schema.d.ts +2 -0
  70. package/dist/core/change-metadata/schema.js +13 -0
  71. package/dist/core/change-status-policy.d.ts +10 -1
  72. package/dist/core/change-status-policy.js +30 -2
  73. package/dist/core/command-generation/adapters/amazon-q.d.ts +4 -0
  74. package/dist/core/command-generation/adapters/amazon-q.js +11 -5
  75. package/dist/core/command-generation/adapters/antigravity.js +6 -5
  76. package/dist/core/command-generation/adapters/auggie.js +7 -6
  77. package/dist/core/command-generation/adapters/bob.d.ts +5 -1
  78. package/dist/core/command-generation/adapters/bob.js +11 -10
  79. package/dist/core/command-generation/adapters/claude.d.ts +1 -1
  80. package/dist/core/command-generation/adapters/claude.js +12 -17
  81. package/dist/core/command-generation/adapters/cline.js +5 -5
  82. package/dist/core/command-generation/adapters/codebuddy.js +8 -7
  83. package/dist/core/command-generation/adapters/continue.js +8 -7
  84. package/dist/core/command-generation/adapters/costrict.js +7 -6
  85. package/dist/core/command-generation/adapters/crush.js +9 -9
  86. package/dist/core/command-generation/adapters/cursor.js +8 -8
  87. package/dist/core/command-generation/adapters/devin.d.ts +19 -0
  88. package/dist/core/command-generation/adapters/devin.js +36 -0
  89. package/dist/core/command-generation/adapters/factory.js +7 -6
  90. package/dist/core/command-generation/adapters/gemini.js +40 -5
  91. package/dist/core/command-generation/adapters/github-copilot.js +6 -5
  92. package/dist/core/command-generation/adapters/iflow.js +9 -8
  93. package/dist/core/command-generation/adapters/index.d.ts +4 -2
  94. package/dist/core/command-generation/adapters/index.js +4 -2
  95. package/dist/core/command-generation/adapters/junie.js +6 -5
  96. package/dist/core/command-generation/adapters/kilocode.js +1 -1
  97. package/dist/core/command-generation/adapters/kiro.js +6 -5
  98. package/dist/core/command-generation/adapters/lingma.js +9 -9
  99. package/dist/core/command-generation/adapters/oh-my-pi.d.ts +21 -0
  100. package/dist/core/command-generation/adapters/oh-my-pi.js +42 -0
  101. package/dist/core/command-generation/adapters/opencode.js +6 -8
  102. package/dist/core/command-generation/adapters/pi.d.ts +2 -2
  103. package/dist/core/command-generation/adapters/pi.js +7 -10
  104. package/dist/core/command-generation/adapters/qoder.js +9 -9
  105. package/dist/core/command-generation/adapters/qwen.d.ts +7 -3
  106. package/dist/core/command-generation/adapters/qwen.js +14 -9
  107. package/dist/core/command-generation/adapters/roocode.d.ts +4 -4
  108. package/dist/core/command-generation/adapters/roocode.js +9 -9
  109. package/dist/core/command-generation/adapters/trae.d.ts +13 -0
  110. package/dist/core/command-generation/adapters/trae.js +28 -0
  111. package/dist/core/command-generation/adapters/zcode.d.ts +16 -0
  112. package/dist/core/command-generation/adapters/zcode.js +33 -0
  113. package/dist/core/command-generation/generator.d.ts +8 -0
  114. package/dist/core/command-generation/generator.js +15 -1
  115. package/dist/core/command-generation/index.d.ts +1 -1
  116. package/dist/core/command-generation/index.js +1 -1
  117. package/dist/core/command-generation/invocation.d.ts +73 -0
  118. package/dist/core/command-generation/invocation.js +77 -0
  119. package/dist/core/command-generation/registry.js +8 -4
  120. package/dist/core/command-generation/types.d.ts +9 -2
  121. package/dist/core/command-generation/yaml.d.ts +20 -6
  122. package/dist/core/command-generation/yaml.js +31 -21
  123. package/dist/core/command-surface.d.ts +15 -0
  124. package/dist/core/command-surface.js +33 -0
  125. package/dist/core/completions/command-registry.js +16 -61
  126. package/dist/core/completions/generators/bash-generator.js +41 -41
  127. package/dist/core/completions/generators/fish-generator.js +7 -7
  128. package/dist/core/completions/generators/powershell-generator.js +44 -37
  129. package/dist/core/completions/generators/zsh-generator.js +33 -33
  130. package/dist/core/completions/installers/zsh-installer.d.ts +9 -0
  131. package/dist/core/completions/installers/zsh-installer.js +20 -4
  132. package/dist/core/completions/templates/bash-templates.js +24 -24
  133. package/dist/core/completions/templates/fish-templates.js +38 -38
  134. package/dist/core/completions/templates/powershell-templates.js +28 -28
  135. package/dist/core/completions/templates/zsh-templates.js +39 -39
  136. package/dist/core/config-prompts.d.ts +1 -1
  137. package/dist/core/config-prompts.js +14 -1
  138. package/dist/core/config-schema.d.ts +10 -1
  139. package/dist/core/config-schema.js +67 -1
  140. package/dist/core/config.d.ts +15 -0
  141. package/dist/core/config.js +46 -5
  142. package/dist/core/file-state.js +56 -24
  143. package/dist/core/github-copilot/cloud-agent.d.ts +95 -0
  144. package/dist/core/github-copilot/cloud-agent.js +497 -0
  145. package/dist/core/global-config.d.ts +16 -0
  146. package/dist/core/init.d.ts +58 -0
  147. package/dist/core/init.js +474 -73
  148. package/dist/core/legacy-cleanup.d.ts +59 -0
  149. package/dist/core/legacy-cleanup.js +253 -24
  150. package/dist/core/list.js +23 -16
  151. package/dist/core/migration.d.ts +73 -1
  152. package/dist/core/migration.js +360 -11
  153. package/dist/core/modify/conflict-detector.d.ts +26 -0
  154. package/dist/core/modify/conflict-detector.js +62 -0
  155. package/dist/core/modify/dependency-propagator.d.ts +38 -0
  156. package/dist/core/modify/dependency-propagator.js +103 -0
  157. package/dist/core/modify/history-tracker.d.ts +34 -0
  158. package/dist/core/modify/history-tracker.js +114 -0
  159. package/dist/core/modify/index.d.ts +7 -0
  160. package/dist/core/modify/index.js +7 -0
  161. package/dist/core/onboarding-commands.d.ts +30 -0
  162. package/dist/core/onboarding-commands.js +38 -0
  163. package/dist/core/openspec-root.js +18 -15
  164. package/dist/core/parsers/change-parser.d.ts +17 -2
  165. package/dist/core/parsers/change-parser.js +35 -21
  166. package/dist/core/parsers/code-fence.d.ts +15 -0
  167. package/dist/core/parsers/code-fence.js +49 -0
  168. package/dist/core/parsers/markdown-parser.d.ts +0 -3
  169. package/dist/core/parsers/markdown-parser.js +7 -60
  170. package/dist/core/parsers/requirement-blocks.d.ts +29 -0
  171. package/dist/core/parsers/requirement-blocks.js +150 -31
  172. package/dist/core/parsers/requirement-text.d.ts +48 -0
  173. package/dist/core/parsers/requirement-text.js +98 -0
  174. package/dist/core/parsers/spec-structure.d.ts +1 -1
  175. package/dist/core/parsers/spec-structure.js +20 -30
  176. package/dist/core/profile-sync-drift.d.ts +0 -8
  177. package/dist/core/profile-sync-drift.js +49 -50
  178. package/dist/core/profiles.d.ts +2 -2
  179. package/dist/core/profiles.js +2 -2
  180. package/dist/core/project-config.d.ts +27 -18
  181. package/dist/core/project-config.js +101 -34
  182. package/dist/core/references.js +42 -4
  183. package/dist/core/relationship-health.d.ts +8 -0
  184. package/dist/core/relationship-health.js +13 -0
  185. package/dist/core/root-selection.d.ts +9 -6
  186. package/dist/core/root-selection.js +42 -5
  187. package/dist/core/schemas/base.schema.js +7 -2
  188. package/dist/core/shared/allowed-tools.d.ts +12 -0
  189. package/dist/core/shared/allowed-tools.js +12 -0
  190. package/dist/core/shared/index.d.ts +1 -0
  191. package/dist/core/shared/index.js +1 -0
  192. package/dist/core/shared/skill-content-equivalence.d.ts +7 -0
  193. package/dist/core/shared/skill-content-equivalence.js +41 -0
  194. package/dist/core/shared/skill-generation.js +17 -13
  195. package/dist/core/shared/skill-paths.d.ts +13 -0
  196. package/dist/core/shared/skill-paths.js +23 -0
  197. package/dist/core/shared/tool-detection.d.ts +27 -7
  198. package/dist/core/shared/tool-detection.js +167 -37
  199. package/dist/core/shared-skill-target.d.ts +16 -0
  200. package/dist/core/shared-skill-target.js +156 -0
  201. package/dist/core/specs-apply.d.ts +80 -33
  202. package/dist/core/specs-apply.js +667 -145
  203. package/dist/core/store/git.d.ts +13 -0
  204. package/dist/core/store/git.js +24 -0
  205. package/dist/core/store/operations.js +20 -0
  206. package/dist/core/templates/skill-templates.d.ts +3 -2
  207. package/dist/core/templates/skill-templates.js +3 -2
  208. package/dist/core/templates/workflows/apply-change.d.ts +10 -0
  209. package/dist/core/templates/workflows/apply-change.js +186 -224
  210. package/dist/core/templates/workflows/archive-change.js +387 -260
  211. package/dist/core/templates/workflows/bulk-archive-change.js +655 -475
  212. package/dist/core/templates/workflows/continue-change.js +210 -219
  213. package/dist/core/templates/workflows/explore.js +479 -443
  214. package/dist/core/templates/workflows/feedback.js +97 -97
  215. package/dist/core/templates/workflows/ff-change.js +200 -191
  216. package/dist/core/templates/workflows/modify-change.d.ts +4 -1
  217. package/dist/core/templates/workflows/modify-change.js +193 -71
  218. package/dist/core/templates/workflows/new-change.js +127 -134
  219. package/dist/core/templates/workflows/onboard.js +548 -542
  220. package/dist/core/templates/workflows/propose.js +273 -217
  221. package/dist/core/templates/workflows/store-selection.d.ts +1 -1
  222. package/dist/core/templates/workflows/store-selection.js +1 -1
  223. package/dist/core/templates/workflows/sync-specs.js +500 -273
  224. package/dist/core/templates/workflows/update-change.d.ts +10 -0
  225. package/dist/core/templates/workflows/update-change.js +177 -0
  226. package/dist/core/templates/workflows/verify-change.js +324 -326
  227. package/dist/core/update.d.ts +40 -5
  228. package/dist/core/update.js +411 -96
  229. package/dist/core/validation/constants.d.ts +4 -1
  230. package/dist/core/validation/constants.js +4 -1
  231. package/dist/core/validation/plan-validator.d.ts +8 -0
  232. package/dist/core/validation/plan-validator.js +45 -0
  233. package/dist/core/validation/task-numbering.d.ts +16 -0
  234. package/dist/core/validation/task-numbering.js +57 -0
  235. package/dist/core/validation/validator.d.ts +27 -3
  236. package/dist/core/validation/validator.js +337 -48
  237. package/dist/core/version-check.d.ts +152 -0
  238. package/dist/core/version-check.js +731 -0
  239. package/dist/core/view.js +13 -18
  240. package/dist/prompts/searchable-multi-select.js +1 -1
  241. package/dist/telemetry/caller-detection.d.ts +27 -0
  242. package/dist/telemetry/caller-detection.js +85 -0
  243. package/dist/telemetry/caller-detection.test.d.ts +5 -0
  244. package/dist/telemetry/config.d.ts +48 -2
  245. package/dist/telemetry/config.js +113 -11
  246. package/dist/telemetry/config.test.d.ts +5 -0
  247. package/dist/telemetry/deduplication.d.ts +35 -0
  248. package/dist/telemetry/deduplication.js +82 -0
  249. package/dist/telemetry/deduplication.test.d.ts +5 -0
  250. package/dist/telemetry/identity.d.ts +62 -22
  251. package/dist/telemetry/identity.js +147 -102
  252. package/dist/telemetry/index.d.ts +126 -15
  253. package/dist/telemetry/index.js +569 -37
  254. package/dist/telemetry/sanitization.d.ts +40 -0
  255. package/dist/telemetry/sanitization.js +114 -0
  256. package/dist/telemetry/sanitization.test.d.ts +5 -0
  257. package/dist/telemetry/throttling.d.ts +20 -0
  258. package/dist/telemetry/throttling.js +70 -0
  259. package/dist/ui/welcome-screen.d.ts +9 -1
  260. package/dist/ui/welcome-screen.js +91 -38
  261. package/dist/utils/change-metadata.d.ts +43 -0
  262. package/dist/utils/change-metadata.js +123 -7
  263. package/dist/utils/change-utils.d.ts +10 -4
  264. package/dist/utils/change-utils.js +20 -13
  265. package/dist/utils/ci.d.ts +12 -0
  266. package/dist/utils/ci.js +16 -0
  267. package/dist/utils/command-references.d.ts +92 -6
  268. package/dist/utils/command-references.js +180 -7
  269. package/dist/utils/date.d.ts +8 -0
  270. package/dist/utils/date.js +13 -0
  271. package/dist/utils/file-system.d.ts +10 -0
  272. package/dist/utils/file-system.js +70 -0
  273. package/dist/utils/index.d.ts +1 -1
  274. package/dist/utils/index.js +1 -1
  275. package/dist/utils/interactive.d.ts +23 -0
  276. package/dist/utils/interactive.js +32 -0
  277. package/dist/utils/item-discovery.d.ts +19 -0
  278. package/dist/utils/item-discovery.js +30 -48
  279. package/dist/utils/shell-detection.d.ts +1 -1
  280. package/dist/utils/shell-detection.js +64 -11
  281. package/dist/utils/spec-discovery.d.ts +40 -0
  282. package/dist/utils/spec-discovery.js +115 -0
  283. package/dist/utils/task-progress.d.ts +29 -1
  284. package/dist/utils/task-progress.js +109 -15
  285. package/package.json +96 -84
  286. package/schemas/spec-driven/schema.yaml +252 -184
  287. package/schemas/spec-driven/templates/design.md +19 -19
  288. package/schemas/spec-driven/templates/plan-template.md +91 -0
  289. package/schemas/spec-driven/templates/proposal.md +29 -24
  290. package/schemas/spec-driven/templates/spec.md +11 -8
  291. package/schemas/spec-driven/templates/tasks.md +9 -9
  292. package/scripts/postinstall.js +83 -83
  293. package/dist/core/command-generation/adapters/codex.d.ts +0 -16
  294. package/dist/core/command-generation/adapters/codex.js +0 -39
  295. package/dist/core/command-generation/adapters/windsurf.d.ts +0 -14
  296. package/dist/core/command-generation/adapters/windsurf.js +0 -38
  297. package/dist/core/comprehension/config.d.ts +0 -20
  298. package/dist/core/comprehension/config.js +0 -23
  299. package/dist/core/comprehension/fingerprint.d.ts +0 -14
  300. package/dist/core/comprehension/fingerprint.js +0 -33
  301. package/dist/core/comprehension/index.d.ts +0 -57
  302. package/dist/core/comprehension/index.js +0 -87
  303. package/dist/core/comprehension/pass-record.d.ts +0 -29
  304. package/dist/core/comprehension/pass-record.js +0 -64
  305. package/dist/core/comprehension/stats.d.ts +0 -35
  306. package/dist/core/comprehension/stats.js +0 -133
  307. package/dist/core/templates/workflows/comprehension-guidance.d.ts +0 -9
  308. package/dist/core/templates/workflows/comprehension-guidance.js +0 -73
  309. package/dist/core/templates/workflows/mcp-guidance.d.ts +0 -13
  310. package/dist/core/templates/workflows/mcp-guidance.js +0 -131
  311. package/dist/core/templates/workflows/user-prompt-guidance.d.ts +0 -16
  312. package/dist/core/templates/workflows/user-prompt-guidance.js +0 -48
  313. package/dist/telemetry/caller.d.ts +0 -5
  314. package/dist/telemetry/caller.js +0 -29
  315. package/dist/telemetry/client.d.ts +0 -27
  316. package/dist/telemetry/client.js +0 -127
  317. package/dist/telemetry/command-context.d.ts +0 -13
  318. package/dist/telemetry/command-context.js +0 -59
  319. package/dist/telemetry/comprehension.d.ts +0 -44
  320. package/dist/telemetry/comprehension.js +0 -105
  321. package/dist/telemetry/content.d.ts +0 -10
  322. package/dist/telemetry/content.js +0 -56
  323. package/dist/telemetry/git-stats.d.ts +0 -12
  324. package/dist/telemetry/git-stats.js +0 -69
  325. package/dist/telemetry/identify-cache.d.ts +0 -7
  326. package/dist/telemetry/identify-cache.js +0 -47
  327. package/dist/telemetry/input.d.ts +0 -17
  328. package/dist/telemetry/input.js +0 -68
  329. package/dist/telemetry/marker.d.ts +0 -37
  330. package/dist/telemetry/marker.js +0 -67
  331. package/dist/telemetry/workflow.d.ts +0 -85
  332. package/dist/telemetry/workflow.js +0 -318
  333. package/schemas/spec-driven/templates/plan.md +0 -19
@@ -0,0 +1,203 @@
1
+ /**
2
+ * Question generator for quiz questions
3
+ *
4
+ * This module handles reading artifact content and generating quiz questions
5
+ * using LLM providers. It includes logic for question count scaling based on
6
+ * artifact size and proportional question allocation across artifact types.
7
+ *
8
+ * @module comprehension-quiz/question-generator
9
+ */
10
+ import { createProviderWithFallback } from './providers/factory.js';
11
+ /**
12
+ * Read artifact content from file
13
+ *
14
+ * @param filePath - Path to the artifact file
15
+ * @returns File content as string
16
+ */
17
+ async function readArtifactContent(filePath) {
18
+ const { promises: fs } = await import('fs');
19
+ try {
20
+ return await fs.readFile(filePath, 'utf-8');
21
+ }
22
+ catch (error) {
23
+ throw new Error(`Failed to read artifact file ${filePath}: ${error}`);
24
+ }
25
+ }
26
+ /**
27
+ * Determine question count based on artifact size
28
+ *
29
+ * @param totalSize - Total size of all artifacts in bytes
30
+ * @returns Number of questions to generate (5, 7, or 10)
31
+ */
32
+ export function getQuestionCount(totalSize) {
33
+ if (totalSize < 2048) {
34
+ return 5; // < 2KB
35
+ }
36
+ else if (totalSize < 10240) {
37
+ return 7; // 2-10KB
38
+ }
39
+ else {
40
+ return 10; // > 10KB
41
+ }
42
+ }
43
+ /**
44
+ * Calculate question allocation per artifact type
45
+ *
46
+ * Distributes questions proportionally to artifact size, ensuring at least
47
+ * one question per artifact type if it has content.
48
+ *
49
+ * @param totalQuestions - Total number of questions to generate
50
+ * @param artifactSizes - Size of each artifact type in bytes
51
+ * @returns Object with question count per artifact type
52
+ */
53
+ export function calculateQuestionAllocation(totalQuestions, artifactSizes) {
54
+ const totalSize = Object.values(artifactSizes).reduce((sum, size) => sum + size, 0);
55
+ const allocation = {
56
+ proposal: 0,
57
+ design: 0,
58
+ specs: 0,
59
+ plan: 0,
60
+ tasks: 0,
61
+ };
62
+ // Allocate questions proportionally to artifact size
63
+ let allocated = 0;
64
+ for (const [artifactType, size] of Object.entries(artifactSizes)) {
65
+ const proportion = size / totalSize;
66
+ const count = Math.round(proportion * totalQuestions);
67
+ allocation[artifactType] = count;
68
+ allocated += count;
69
+ }
70
+ // Ensure at least 1 question per artifact type if it has content
71
+ for (const [artifactType, size] of Object.entries(artifactSizes)) {
72
+ if (size > 0 && allocation[artifactType] === 0 && allocated < totalQuestions) {
73
+ allocation[artifactType] = 1;
74
+ allocated += 1;
75
+ }
76
+ }
77
+ // Adjust to match totalQuestions exactly
78
+ const currentTotal = Object.values(allocation).reduce((sum, count) => sum + count, 0);
79
+ if (currentTotal !== totalQuestions) {
80
+ const diff = totalQuestions - currentTotal;
81
+ // Add remaining questions to the largest artifact
82
+ const largestArtifact = Object.entries(artifactSizes).sort((a, b) => b[1] - a[1])[0][0];
83
+ allocation[largestArtifact] += diff;
84
+ }
85
+ return allocation;
86
+ }
87
+ /**
88
+ * Generate questions for a specific artifact type
89
+ *
90
+ * @param artifactContent - Content of the artifact
91
+ * @param artifactType - Type of artifact
92
+ * @param questionCount - Number of questions to generate
93
+ * @param provider - LLM provider to use
94
+ * @returns Array of generated questions
95
+ */
96
+ export async function generateQuestionsForArtifact(artifactContent, artifactType, questionCount, provider) {
97
+ return provider.generateQuestions(artifactContent, questionCount, artifactType);
98
+ }
99
+ /**
100
+ * On-demand question stream for the quiz executor.
101
+ *
102
+ * This class resolves the artifact contents and allocation plan upfront, but
103
+ * NEVER pre-generates questions. Each call to `next()` fetches exactly ONE
104
+ * question from the LLM — only after the previous question has been answered.
105
+ *
106
+ * This enforces FR-10: questions are fetched on-demand, never pre-generated.
107
+ * The correct answer (correctOption) is held in process memory; it is never
108
+ * written to stdout, disk, or any external surface.
109
+ */
110
+ export class QuizQuestionStream {
111
+ provider;
112
+ plan = [];
113
+ totalQuestions = 0;
114
+ fetchedCount = 0;
115
+ askedTexts = [];
116
+ constructor(provider) {
117
+ this.provider = provider;
118
+ }
119
+ /**
120
+ * Create and initialise a QuizQuestionStream.
121
+ * Reads artifact files and builds the question plan, but does NOT generate any questions.
122
+ *
123
+ * @param artifactPaths - Object mapping artifact types to file paths
124
+ * @param totalQuestions - Total number of questions the quiz will ask
125
+ * @param provider - LLM provider (optional, uses fallback if not provided)
126
+ */
127
+ static async create(artifactPaths, totalQuestions, provider) {
128
+ const llmProvider = provider ?? (await createProviderWithFallback());
129
+ const stream = new QuizQuestionStream(llmProvider);
130
+ // Read artifact contents
131
+ const artifactContents = {};
132
+ const artifactSizes = { proposal: 0, design: 0, specs: 0, plan: 0, tasks: 0 };
133
+ for (const [artifactType, filePath] of Object.entries(artifactPaths)) {
134
+ if (filePath) {
135
+ const content = await readArtifactContent(filePath);
136
+ artifactContents[artifactType] = content;
137
+ artifactSizes[artifactType] = content.length;
138
+ }
139
+ }
140
+ // Build flat ordered plan: [artifactType, content] pairs for each question slot
141
+ const allocation = calculateQuestionAllocation(totalQuestions, artifactSizes);
142
+ for (const [artifactType, count] of Object.entries(allocation)) {
143
+ if (count > 0 && artifactContents[artifactType]) {
144
+ for (let i = 0; i < count; i++) {
145
+ stream.plan.push({
146
+ artifactType: artifactType,
147
+ content: artifactContents[artifactType],
148
+ });
149
+ }
150
+ }
151
+ }
152
+ stream.totalQuestions = stream.plan.length;
153
+ return stream;
154
+ }
155
+ /** Total number of questions this quiz will ask. */
156
+ get total() {
157
+ return this.totalQuestions;
158
+ }
159
+ /** Whether there are more questions to fetch. */
160
+ get hasNext() {
161
+ return this.fetchedCount < this.totalQuestions;
162
+ }
163
+ /**
164
+ * Fetch the next question from the LLM.
165
+ * MUST only be called after the user has answered the current question.
166
+ * Only one question is held in memory at a time; this method discards the
167
+ * previous question before fetching the next.
168
+ *
169
+ * @returns The next Question, or null if all questions have been asked.
170
+ */
171
+ async next() {
172
+ if (!this.hasNext)
173
+ return null;
174
+ const slot = this.plan[this.fetchedCount];
175
+ const question = await this.provider.generateSingleQuestion(slot.content, slot.artifactType, this.fetchedCount, this.totalQuestions, this.askedTexts);
176
+ this.fetchedCount += 1;
177
+ this.askedTexts.push(question.text);
178
+ return question;
179
+ }
180
+ }
181
+ /**
182
+ * Generate complete quiz question set for all artifacts.
183
+ *
184
+ * NOTE: This function pre-generates all questions and should only be used for
185
+ * non-interactive contexts (e.g. testing, pass recording). During live quiz
186
+ * execution use QuizQuestionStream.create() instead.
187
+ *
188
+ * @param artifactPaths - Object mapping artifact types to file paths
189
+ * @param totalQuestions - Total number of questions to generate
190
+ * @param provider - LLM provider to use (optional, uses fallback if not provided)
191
+ * @returns Array of all generated questions
192
+ */
193
+ export async function generateQuizQuestions(artifactPaths, totalQuestions, provider) {
194
+ const stream = await QuizQuestionStream.create(artifactPaths, totalQuestions, provider);
195
+ const allQuestions = [];
196
+ while (stream.hasNext) {
197
+ const q = await stream.next();
198
+ if (q)
199
+ allQuestions.push(q);
200
+ }
201
+ return allQuestions;
202
+ }
203
+ //# sourceMappingURL=question-generator.js.map
@@ -0,0 +1,75 @@
1
+ /**
2
+ * Quiz executor with state machine and CLI interaction
3
+ *
4
+ * This module implements the quiz execution engine with a strict state machine
5
+ * and timing constraints to enforce human-only participation. It handles question
6
+ * presentation, answer collection, timing validation, and feedback display.
7
+ *
8
+ * @module comprehension-quiz/quiz-executor
9
+ */
10
+ import type { QuizResult } from './types.js';
11
+ import type { QuizQuestionStream } from './question-generator.js';
12
+ /**
13
+ * Quiz executor class
14
+ *
15
+ * Manages the quiz state machine and CLI interaction. Enforces timing
16
+ * constraints (4-second wait before accepting input, 2-second minimum answer time)
17
+ * to prevent AI agents from programmatically answering questions.
18
+ */
19
+ export declare class QuizExecutor {
20
+ private state;
21
+ private totalQuestions;
22
+ private correctCount;
23
+ private questionDisplayedAt;
24
+ private changeName;
25
+ private attemptNumber;
26
+ /** Minimum ms the question must be visible before ANY input is accepted (FR-4, NFR-4). */
27
+ private static readonly DISPLAY_LOCK_MS;
28
+ /** Minimum ms between question display and a valid answer (FR-9). */
29
+ private static readonly MIN_ANSWER_MS;
30
+ /**
31
+ * Execute quiz using an on-demand question stream.
32
+ *
33
+ * Questions are fetched one at a time from the stream — the next question is
34
+ * NOT fetched until the user has answered the current one. This means at most
35
+ * one Question object is in memory at any point, and its correctOption never
36
+ * appears in stdout.
37
+ *
38
+ * @param stream - QuizQuestionStream supplying one question per call
39
+ * @param changeName - Name of the change being tested
40
+ * @returns Quiz result with score and pass/fail status
41
+ */
42
+ executeQuiz(stream: QuizQuestionStream, changeName: string): Promise<QuizResult>;
43
+ private transitionTo;
44
+ /**
45
+ * Display a question to the user.
46
+ * Records the display timestamp for timing enforcement.
47
+ * correctOption is NOT printed — it stays in process memory only.
48
+ */
49
+ private displayQuestion;
50
+ /**
51
+ * Collect a valid answer from stdin, looping until one is received.
52
+ *
53
+ * Enforces:
54
+ * - 4-second display lock: any input before 4s is silently discarded (FR-4 / NFR-4)
55
+ * - Batch input rejection: multiple newline-separated values in one write → re-prompt
56
+ * - Skip/show-all rejection: any non-option text → "Answer this question to continue."
57
+ * - 2-second minimum read time: answers faster than 2s after display → re-prompt (FR-9)
58
+ *
59
+ * @returns The user's selected option number (1, 2, or 3)
60
+ */
61
+ private collectValidAnswer;
62
+ /**
63
+ * Read a single line from stdin without echoing the prompt.
64
+ * Uses raw mode to capture the full write in one shot so batch detection works.
65
+ */
66
+ private readLine;
67
+ /**
68
+ * Show pass/fail feedback for a single answer.
69
+ * Does NOT reveal the correctOption number to stdout if the user was correct —
70
+ * only shows "Correct" or "Incorrect" with the correct option disclosed on wrong answers.
71
+ */
72
+ private showFeedback;
73
+ private sleep;
74
+ }
75
+ //# sourceMappingURL=quiz-executor.d.ts.map
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Quiz executor with state machine and CLI interaction
3
+ *
4
+ * This module implements the quiz execution engine with a strict state machine
5
+ * and timing constraints to enforce human-only participation. It handles question
6
+ * presentation, answer collection, timing validation, and feedback display.
7
+ *
8
+ * @module comprehension-quiz/quiz-executor
9
+ */
10
+ import * as readline from 'readline';
11
+ import { trackComprehensionAttempt, trackComprehensionCompletion, trackApplyReady } from '../telemetry/index.js';
12
+ import { getPassRecord } from './pass-record.js';
13
+ /**
14
+ * Quiz executor class
15
+ *
16
+ * Manages the quiz state machine and CLI interaction. Enforces timing
17
+ * constraints (4-second wait before accepting input, 2-second minimum answer time)
18
+ * to prevent AI agents from programmatically answering questions.
19
+ */
20
+ export class QuizExecutor {
21
+ state = 'START';
22
+ totalQuestions = 0;
23
+ correctCount = 0;
24
+ questionDisplayedAt = 0;
25
+ changeName = '';
26
+ attemptNumber = 1;
27
+ /** Minimum ms the question must be visible before ANY input is accepted (FR-4, NFR-4). */
28
+ static DISPLAY_LOCK_MS = 4000;
29
+ /** Minimum ms between question display and a valid answer (FR-9). */
30
+ static MIN_ANSWER_MS = 2000;
31
+ /**
32
+ * Execute quiz using an on-demand question stream.
33
+ *
34
+ * Questions are fetched one at a time from the stream — the next question is
35
+ * NOT fetched until the user has answered the current one. This means at most
36
+ * one Question object is in memory at any point, and its correctOption never
37
+ * appears in stdout.
38
+ *
39
+ * @param stream - QuizQuestionStream supplying one question per call
40
+ * @param changeName - Name of the change being tested
41
+ * @returns Quiz result with score and pass/fail status
42
+ */
43
+ async executeQuiz(stream, changeName) {
44
+ this.changeName = changeName;
45
+ this.totalQuestions = stream.total;
46
+ this.correctCount = 0;
47
+ this.state = 'START';
48
+ const existingRecord = await getPassRecord(changeName);
49
+ this.attemptNumber = existingRecord ? existingRecord.attemptCount + 1 : 1;
50
+ await trackComprehensionAttempt(changeName, this.attemptNumber);
51
+ let questionIndex = 0;
52
+ while (stream.hasNext) {
53
+ await this.transitionTo(`WAITING_FOR_QUESTION_${questionIndex + 1}`);
54
+ // Fetch exactly one question — only now, not before
55
+ const question = await stream.next();
56
+ if (!question)
57
+ break;
58
+ this.displayQuestion(question, questionIndex);
59
+ // Loop until a valid answer is received (re-prompt on any invalid/early/batch/skip input)
60
+ const userAnswer = await this.collectValidAnswer(question);
61
+ await this.transitionTo('ACCEPTING_ANSWER');
62
+ if (userAnswer === question.correctOption + 1) {
63
+ this.correctCount += 1;
64
+ }
65
+ await this.transitionTo('FEEDBACK');
66
+ this.showFeedback(question, userAnswer);
67
+ questionIndex += 1;
68
+ }
69
+ await this.transitionTo('DONE');
70
+ const scorePercent = this.totalQuestions > 0
71
+ ? Math.round((this.correctCount / this.totalQuestions) * 100)
72
+ : 0;
73
+ const passed = scorePercent >= 80;
74
+ console.log(`\n${'─'.repeat(50)}`);
75
+ console.log(`Result: ${this.correctCount}/${this.totalQuestions} correct (${scorePercent}%)`);
76
+ console.log(passed ? '✓ PASS — apply is now unblocked.' : '✗ FAIL — retry to proceed.');
77
+ console.log('─'.repeat(50));
78
+ await trackComprehensionCompletion(changeName, scorePercent, passed ? 'pass' : 'fail', this.attemptNumber);
79
+ if (passed) {
80
+ await trackApplyReady(changeName);
81
+ }
82
+ return {
83
+ correct: this.correctCount,
84
+ total: this.totalQuestions,
85
+ scorePercent,
86
+ passed,
87
+ attemptNumber: this.attemptNumber,
88
+ };
89
+ }
90
+ async transitionTo(newState) {
91
+ this.state = newState;
92
+ }
93
+ /**
94
+ * Display a question to the user.
95
+ * Records the display timestamp for timing enforcement.
96
+ * correctOption is NOT printed — it stays in process memory only.
97
+ */
98
+ displayQuestion(question, index) {
99
+ console.clear();
100
+ console.log(`Question ${index + 1} of ${this.totalQuestions}\n`);
101
+ console.log(question.text);
102
+ console.log('');
103
+ console.log(` 1) ${question.options[0]}`);
104
+ console.log(` 2) ${question.options[1]}`);
105
+ console.log(` 3) ${question.options[2]}`);
106
+ console.log('');
107
+ this.questionDisplayedAt = Date.now();
108
+ }
109
+ /**
110
+ * Collect a valid answer from stdin, looping until one is received.
111
+ *
112
+ * Enforces:
113
+ * - 4-second display lock: any input before 4s is silently discarded (FR-4 / NFR-4)
114
+ * - Batch input rejection: multiple newline-separated values in one write → re-prompt
115
+ * - Skip/show-all rejection: any non-option text → "Answer this question to continue."
116
+ * - 2-second minimum read time: answers faster than 2s after display → re-prompt (FR-9)
117
+ *
118
+ * @returns The user's selected option number (1, 2, or 3)
119
+ */
120
+ async collectValidAnswer(question) {
121
+ while (true) {
122
+ const elapsed = Date.now() - this.questionDisplayedAt;
123
+ if (elapsed < QuizExecutor.DISPLAY_LOCK_MS) {
124
+ // Still within the 4-second display lock — wait out the remainder silently
125
+ await this.sleep(QuizExecutor.DISPLAY_LOCK_MS - elapsed);
126
+ }
127
+ const raw = await this.readLine();
128
+ const answerReceivedAt = Date.now();
129
+ // Reject batch input: more than one non-empty line in a single write
130
+ if (raw.includes('\n') && raw.split('\n').filter((l) => l.trim()).length > 1) {
131
+ console.log('Answer this question to continue.');
132
+ continue;
133
+ }
134
+ const trimmed = raw.trim();
135
+ // Reject empty, skip commands, show-all, or anything not "1" / "2" / "3"
136
+ if (trimmed === '' || !['1', '2', '3'].includes(trimmed)) {
137
+ console.log('Answer this question to continue.');
138
+ continue;
139
+ }
140
+ // Enforce minimum 2-second read time after question was displayed
141
+ const timeSinceDisplay = answerReceivedAt - this.questionDisplayedAt;
142
+ if (timeSinceDisplay < QuizExecutor.MIN_ANSWER_MS) {
143
+ console.log('Answer this question to continue.');
144
+ continue;
145
+ }
146
+ return parseInt(trimmed, 10);
147
+ }
148
+ }
149
+ /**
150
+ * Read a single line from stdin without echoing the prompt.
151
+ * Uses raw mode to capture the full write in one shot so batch detection works.
152
+ */
153
+ readLine() {
154
+ return new Promise((resolve) => {
155
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
156
+ rl.question('Enter 1, 2, or 3: ', (answer) => {
157
+ rl.close();
158
+ resolve(answer);
159
+ });
160
+ });
161
+ }
162
+ /**
163
+ * Show pass/fail feedback for a single answer.
164
+ * Does NOT reveal the correctOption number to stdout if the user was correct —
165
+ * only shows "Correct" or "Incorrect" with the correct option disclosed on wrong answers.
166
+ */
167
+ showFeedback(question, userAnswer) {
168
+ const isCorrect = userAnswer === question.correctOption + 1;
169
+ if (isCorrect) {
170
+ console.log('\n✓ Correct\n');
171
+ }
172
+ else {
173
+ console.log('\n✗ Incorrect');
174
+ console.log(` The correct answer was option ${question.correctOption + 1}.\n`);
175
+ }
176
+ }
177
+ sleep(ms) {
178
+ return new Promise((resolve) => setTimeout(resolve, ms));
179
+ }
180
+ }
181
+ //# sourceMappingURL=quiz-executor.js.map
@@ -0,0 +1,137 @@
1
+ /**
2
+ * Shared types for the comprehension quiz system
3
+ *
4
+ * This module defines all TypeScript interfaces and types used across the
5
+ * comprehension quiz system, including questions, pass records, quiz states,
6
+ * and LLM provider interfaces.
7
+ *
8
+ * @module comprehension-quiz/types
9
+ */
10
+ /**
11
+ * A quiz question with multiple-choice options
12
+ */
13
+ export interface Question {
14
+ /** The question text */
15
+ text: string;
16
+ /** Answer options (exactly 3 for this system) */
17
+ options: string[];
18
+ /** Index of the correct answer (0-2) */
19
+ correctOption: number;
20
+ /** Which artifact this question was generated from */
21
+ artifactSource: 'proposal' | 'design' | 'specs' | 'plan' | 'tasks';
22
+ }
23
+ /**
24
+ * A recorded quiz pass with metadata
25
+ *
26
+ * Pass records are stored in `.openspec/comprehension-quiz-passes.json` and
27
+ * include fingerprint information to detect when artifacts have changed
28
+ * since the quiz was passed.
29
+ */
30
+ export interface PassRecord {
31
+ /** Change name this pass is for */
32
+ changeName: string;
33
+ /** ISO 8601 timestamp when quiz was passed */
34
+ passedAt: string;
35
+ /** Score percentage (0-100) */
36
+ score: number;
37
+ /** SHA-256 fingerprint of all artifact files at time of pass */
38
+ fingerprint: string;
39
+ /** Total number of quiz attempts for this change */
40
+ attemptCount: number;
41
+ /** Number of failed attempts before passing */
42
+ failureCount?: number;
43
+ /** Optional: LLM provider used */
44
+ provider?: string;
45
+ /** Optional: Model used */
46
+ model?: string;
47
+ /** Optional: Number of questions in the quiz */
48
+ questionCount?: number;
49
+ /** Optional: Duration of quiz in seconds */
50
+ duration?: number;
51
+ }
52
+ /**
53
+ * Quiz state machine states
54
+ *
55
+ * The quiz executes through a strict state machine with timing constraints
56
+ * to enforce human-only participation. States include START, WAITING_FOR_QUESTION_N,
57
+ * ACCEPTING_ANSWER, FEEDBACK, and DONE.
58
+ */
59
+ export type QuizState = 'START' | 'WAITING_FOR_QUESTION_1' | 'WAITING_FOR_QUESTION_2' | 'WAITING_FOR_QUESTION_3' | 'WAITING_FOR_QUESTION_4' | 'WAITING_FOR_QUESTION_5' | 'WAITING_FOR_QUESTION_6' | 'WAITING_FOR_QUESTION_7' | 'WAITING_FOR_QUESTION_8' | 'WAITING_FOR_QUESTION_9' | 'WAITING_FOR_QUESTION_10' | 'ACCEPTING_ANSWER' | 'FEEDBACK' | 'DONE';
60
+ /**
61
+ * LLM provider interface for question generation
62
+ *
63
+ * All LLM providers (OpenAI, Anthropic, Ollama, local) must implement
64
+ * this interface to enable question generation from artifact content.
65
+ */
66
+ export interface LLMProvider {
67
+ /**
68
+ * Generate quiz questions from artifact content
69
+ * @param artifactContent - The content of the artifact to generate questions from
70
+ * @param questionCount - Number of questions to generate
71
+ * @param artifactType - Type of artifact (proposal, design, specs, plan, tasks)
72
+ * @returns Array of generated questions
73
+ */
74
+ generateQuestions(artifactContent: string, questionCount: number, artifactType: 'proposal' | 'design' | 'specs' | 'plan' | 'tasks'): Promise<Question[]>;
75
+ /**
76
+ * Generate a single quiz question on-demand from artifact content.
77
+ *
78
+ * This method MUST be used during quiz execution to fetch one question at a time.
79
+ * The correct answer index is included in the returned Question object so the CLI
80
+ * process can validate the user's answer locally. The correct answer MUST NOT be
81
+ * included in any conversational context or stdout — it stays in process memory only.
82
+ *
83
+ * The LLM prompt used by implementors MUST:
84
+ * 1. Ask for exactly ONE question, not a list or array.
85
+ * 2. Return a JSON object with: text, options (3 strings), correctOption (0-2), artifactSource.
86
+ * 3. NEVER ask the LLM to explain the answer or include the answer text in any prose.
87
+ * 4. Use a system message that forbids the model from listing multiple questions.
88
+ *
89
+ * @param artifactContent - The content of the artifact to generate from
90
+ * @param artifactType - Type of artifact (proposal, design, specs, plan, tasks)
91
+ * @param questionIndex - 0-based index of this question in the quiz (for diversity)
92
+ * @param totalQuestions - Total number of questions in the quiz (for context)
93
+ * @param previousQuestionTexts - Texts of already-asked questions to avoid duplicates
94
+ * @returns A single generated question (text + options + correctOption + artifactSource)
95
+ */
96
+ generateSingleQuestion(artifactContent: string, artifactType: 'proposal' | 'design' | 'specs' | 'plan' | 'tasks', questionIndex: number, totalQuestions: number, previousQuestionTexts: string[]): Promise<Question>;
97
+ /**
98
+ * Validate provider configuration
99
+ * @throws Error if configuration is invalid
100
+ */
101
+ validateConfig(): void;
102
+ }
103
+ /**
104
+ * Provider configuration
105
+ *
106
+ * Configuration options for LLM providers, including API keys, model names,
107
+ * and endpoint URLs.
108
+ */
109
+ export interface ProviderConfig {
110
+ /** API key for cloud providers */
111
+ apiKey?: string;
112
+ /** Model name to use */
113
+ model?: string;
114
+ /** Endpoint URL (for local providers) */
115
+ endpoint?: string;
116
+ /** Model type (for local providers) */
117
+ modelType?: string;
118
+ }
119
+ /**
120
+ * Quiz result from execution
121
+ *
122
+ * Contains the final score, pass/fail status, and attempt information
123
+ * after a quiz has been completed.
124
+ */
125
+ export interface QuizResult {
126
+ /** Number of correct answers */
127
+ correct: number;
128
+ /** Total number of questions */
129
+ total: number;
130
+ /** Score percentage (0-100) */
131
+ scorePercent: number;
132
+ /** Whether the quiz was passed (≥80%) */
133
+ passed: boolean;
134
+ /** Attempt number */
135
+ attemptNumber: number;
136
+ }
137
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shared types for the comprehension quiz system
3
+ *
4
+ * This module defines all TypeScript interfaces and types used across the
5
+ * comprehension quiz system, including questions, pass records, quiz states,
6
+ * and LLM provider interfaces.
7
+ *
8
+ * @module comprehension-quiz/types
9
+ */
10
+ export {};
11
+ //# sourceMappingURL=types.js.map
@@ -1,3 +1,17 @@
1
+ /**
2
+ * True when the ONLY thing wrong with a rebuilt spec is that it has no
3
+ * requirements. That is the exact failure retiring a capability replaces
4
+ * (#1302); anything else means the spec is broken in a way the author still has
5
+ * to fix, so archive must abort exactly as it always did instead of retiring.
6
+ *
7
+ * Asking the validator - rather than counting requirement blocks a second time -
8
+ * is what makes "this spec could not have been written anyway" true by
9
+ * construction. The two counts genuinely disagree: `MarkdownParser` accepts any
10
+ * `###` heading under `## Requirements` as a requirement, while the delta block
11
+ * parser only indexes canonical `### Requirement:` headers and sweeps the rest
12
+ * into the preamble, which survives into the rebuilt spec.
13
+ */
14
+ export declare function isRetirableSpec(specName: string, rebuilt: string): Promise<boolean>;
1
15
  export interface ArchiveOptions {
2
16
  yes?: boolean;
3
17
  skipSpecs?: boolean;
@@ -17,6 +31,5 @@ export declare class ArchiveCommand {
17
31
  */
18
32
  private run;
19
33
  private selectChange;
20
- private getArchiveDate;
21
34
  }
22
35
  //# sourceMappingURL=archive.d.ts.map