@codewalla_india/openspec 1.3.0 → 1.3.2

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 +272 -230
  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 +34 -0
  37. package/dist/comprehension-quiz/providers/anthropic.js +53 -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 +59 -0
  41. package/dist/comprehension-quiz/providers/interface.js +63 -0
  42. package/dist/comprehension-quiz/providers/local.d.ts +34 -0
  43. package/dist/comprehension-quiz/providers/local.js +53 -0
  44. package/dist/comprehension-quiz/providers/ollama.d.ts +34 -0
  45. package/dist/comprehension-quiz/providers/ollama.js +53 -0
  46. package/dist/comprehension-quiz/providers/openai.d.ts +34 -0
  47. package/dist/comprehension-quiz/providers/openai.js +53 -0
  48. package/dist/comprehension-quiz/question-generator.d.ts +69 -0
  49. package/dist/comprehension-quiz/question-generator.js +141 -0
  50. package/dist/comprehension-quiz/quiz-executor.d.ts +70 -0
  51. package/dist/comprehension-quiz/quiz-executor.js +165 -0
  52. package/dist/comprehension-quiz/types.d.ts +115 -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 -323
  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 +237 -115
  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 -71
  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,53 @@
1
+ /**
2
+ * Local model provider implementation
3
+ *
4
+ * This module implements the local model LLM provider for question generation.
5
+ * It supports running local models for offline or private question generation.
6
+ *
7
+ * @module comprehension-quiz/providers/local
8
+ */
9
+ import { BaseProvider } from './interface.js';
10
+ /**
11
+ * Local model provider for question generation
12
+ *
13
+ * Requires LOCAL_MODEL_PATH environment variable to be set.
14
+ */
15
+ export class LocalProvider extends BaseProvider {
16
+ constructor(config) {
17
+ super(config);
18
+ }
19
+ /**
20
+ * Validate local model configuration
21
+ *
22
+ * @throws Error if model path is missing
23
+ */
24
+ validateConfig() {
25
+ if (!this.config.model) {
26
+ throw new Error('LOCAL_MODEL_PATH environment variable is required for local provider');
27
+ }
28
+ }
29
+ /**
30
+ * Generate quiz questions using local model
31
+ *
32
+ * @param artifactContent - The content of the artifact to generate questions from
33
+ * @param questionCount - Number of questions to generate
34
+ * @param artifactType - Type of artifact (proposal, design, specs, plan, tasks)
35
+ * @returns Array of generated questions
36
+ */
37
+ async generateQuestions(artifactContent, questionCount, artifactType) {
38
+ // TODO: Implement local model inference
39
+ // For now, return placeholder questions
40
+ const questions = [];
41
+ for (let i = 0; i < questionCount; i++) {
42
+ questions.push({
43
+ text: `Sample question ${i + 1} for ${artifactType}`,
44
+ options: ['Option A', 'Option B', 'Option C'],
45
+ correctOption: 0,
46
+ artifactSource: artifactType,
47
+ });
48
+ }
49
+ this.validateQuestions(questions);
50
+ return questions;
51
+ }
52
+ }
53
+ //# sourceMappingURL=local.js.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Ollama provider implementation
3
+ *
4
+ * This module implements the Ollama LLM provider for question generation.
5
+ * It uses the Ollama API to generate quiz questions from artifact content.
6
+ *
7
+ * @module comprehension-quiz/providers/ollama
8
+ */
9
+ import { BaseProvider } from './interface.js';
10
+ import type { ProviderConfig, Question } from '../types.js';
11
+ /**
12
+ * Ollama provider for question generation
13
+ *
14
+ * Requires OLLAMA_BASE_URL environment variable to be set.
15
+ */
16
+ export declare class OllamaProvider extends BaseProvider {
17
+ constructor(config: ProviderConfig);
18
+ /**
19
+ * Validate Ollama configuration
20
+ *
21
+ * @throws Error if endpoint is missing
22
+ */
23
+ validateConfig(): void;
24
+ /**
25
+ * Generate quiz questions using Ollama API
26
+ *
27
+ * @param artifactContent - The content of the artifact to generate questions from
28
+ * @param questionCount - Number of questions to generate
29
+ * @param artifactType - Type of artifact (proposal, design, specs, plan, tasks)
30
+ * @returns Array of generated questions
31
+ */
32
+ generateQuestions(artifactContent: string, questionCount: number, artifactType: 'proposal' | 'design' | 'specs' | 'plan' | 'tasks'): Promise<Question[]>;
33
+ }
34
+ //# sourceMappingURL=ollama.d.ts.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Ollama provider implementation
3
+ *
4
+ * This module implements the Ollama LLM provider for question generation.
5
+ * It uses the Ollama API to generate quiz questions from artifact content.
6
+ *
7
+ * @module comprehension-quiz/providers/ollama
8
+ */
9
+ import { BaseProvider } from './interface.js';
10
+ /**
11
+ * Ollama provider for question generation
12
+ *
13
+ * Requires OLLAMA_BASE_URL environment variable to be set.
14
+ */
15
+ export class OllamaProvider extends BaseProvider {
16
+ constructor(config) {
17
+ super(config);
18
+ }
19
+ /**
20
+ * Validate Ollama configuration
21
+ *
22
+ * @throws Error if endpoint is missing
23
+ */
24
+ validateConfig() {
25
+ if (!this.config.endpoint) {
26
+ throw new Error('OLLAMA_BASE_URL environment variable is required for Ollama provider');
27
+ }
28
+ }
29
+ /**
30
+ * Generate quiz questions using Ollama API
31
+ *
32
+ * @param artifactContent - The content of the artifact to generate questions from
33
+ * @param questionCount - Number of questions to generate
34
+ * @param artifactType - Type of artifact (proposal, design, specs, plan, tasks)
35
+ * @returns Array of generated questions
36
+ */
37
+ async generateQuestions(artifactContent, questionCount, artifactType) {
38
+ // TODO: Implement Ollama API call
39
+ // For now, return placeholder questions
40
+ const questions = [];
41
+ for (let i = 0; i < questionCount; i++) {
42
+ questions.push({
43
+ text: `Sample question ${i + 1} for ${artifactType}`,
44
+ options: ['Option A', 'Option B', 'Option C'],
45
+ correctOption: 0,
46
+ artifactSource: artifactType,
47
+ });
48
+ }
49
+ this.validateQuestions(questions);
50
+ return questions;
51
+ }
52
+ }
53
+ //# sourceMappingURL=ollama.js.map
@@ -0,0 +1,34 @@
1
+ /**
2
+ * OpenAI provider implementation
3
+ *
4
+ * This module implements the OpenAI LLM provider for question generation.
5
+ * It uses the OpenAI API to generate quiz questions from artifact content.
6
+ *
7
+ * @module comprehension-quiz/providers/openai
8
+ */
9
+ import { BaseProvider } from './interface.js';
10
+ import type { ProviderConfig, Question } from '../types.js';
11
+ /**
12
+ * OpenAI provider for question generation
13
+ *
14
+ * Requires OPENAI_API_KEY environment variable to be set.
15
+ */
16
+ export declare class OpenAIProvider extends BaseProvider {
17
+ constructor(config: ProviderConfig);
18
+ /**
19
+ * Validate OpenAI configuration
20
+ *
21
+ * @throws Error if API key is missing
22
+ */
23
+ validateConfig(): void;
24
+ /**
25
+ * Generate quiz questions using OpenAI API
26
+ *
27
+ * @param artifactContent - The content of the artifact to generate questions from
28
+ * @param questionCount - Number of questions to generate
29
+ * @param artifactType - Type of artifact (proposal, design, specs, plan, tasks)
30
+ * @returns Array of generated questions
31
+ */
32
+ generateQuestions(artifactContent: string, questionCount: number, artifactType: 'proposal' | 'design' | 'specs' | 'plan' | 'tasks'): Promise<Question[]>;
33
+ }
34
+ //# sourceMappingURL=openai.d.ts.map
@@ -0,0 +1,53 @@
1
+ /**
2
+ * OpenAI provider implementation
3
+ *
4
+ * This module implements the OpenAI LLM provider for question generation.
5
+ * It uses the OpenAI API to generate quiz questions from artifact content.
6
+ *
7
+ * @module comprehension-quiz/providers/openai
8
+ */
9
+ import { BaseProvider } from './interface.js';
10
+ /**
11
+ * OpenAI provider for question generation
12
+ *
13
+ * Requires OPENAI_API_KEY environment variable to be set.
14
+ */
15
+ export class OpenAIProvider extends BaseProvider {
16
+ constructor(config) {
17
+ super(config);
18
+ }
19
+ /**
20
+ * Validate OpenAI configuration
21
+ *
22
+ * @throws Error if API key is missing
23
+ */
24
+ validateConfig() {
25
+ if (!this.config.apiKey) {
26
+ throw new Error('OPENAI_API_KEY environment variable is required for OpenAI provider');
27
+ }
28
+ }
29
+ /**
30
+ * Generate quiz questions using OpenAI API
31
+ *
32
+ * @param artifactContent - The content of the artifact to generate questions from
33
+ * @param questionCount - Number of questions to generate
34
+ * @param artifactType - Type of artifact (proposal, design, specs, plan, tasks)
35
+ * @returns Array of generated questions
36
+ */
37
+ async generateQuestions(artifactContent, questionCount, artifactType) {
38
+ // TODO: Implement OpenAI API call
39
+ // For now, return placeholder questions
40
+ const questions = [];
41
+ for (let i = 0; i < questionCount; i++) {
42
+ questions.push({
43
+ text: `Sample question ${i + 1} for ${artifactType}`,
44
+ options: ['Option A', 'Option B', 'Option C'],
45
+ correctOption: 0,
46
+ artifactSource: artifactType,
47
+ });
48
+ }
49
+ this.validateQuestions(questions);
50
+ return questions;
51
+ }
52
+ }
53
+ //# sourceMappingURL=openai.js.map
@@ -0,0 +1,69 @@
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 type { Question, LLMProvider } from './types.js';
11
+ /**
12
+ * Determine question count based on artifact size
13
+ *
14
+ * @param totalSize - Total size of all artifacts in bytes
15
+ * @returns Number of questions to generate (5, 7, or 10)
16
+ */
17
+ export declare function getQuestionCount(totalSize: number): number;
18
+ /**
19
+ * Calculate question allocation per artifact type
20
+ *
21
+ * Distributes questions proportionally to artifact size, ensuring at least
22
+ * one question per artifact type if it has content.
23
+ *
24
+ * @param totalQuestions - Total number of questions to generate
25
+ * @param artifactSizes - Size of each artifact type in bytes
26
+ * @returns Object with question count per artifact type
27
+ */
28
+ export declare function calculateQuestionAllocation(totalQuestions: number, artifactSizes: {
29
+ proposal: number;
30
+ design: number;
31
+ specs: number;
32
+ plan: number;
33
+ tasks: number;
34
+ }): {
35
+ proposal: number;
36
+ design: number;
37
+ specs: number;
38
+ plan: number;
39
+ tasks: number;
40
+ };
41
+ /**
42
+ * Generate questions for a specific artifact type
43
+ *
44
+ * @param artifactContent - Content of the artifact
45
+ * @param artifactType - Type of artifact
46
+ * @param questionCount - Number of questions to generate
47
+ * @param provider - LLM provider to use
48
+ * @returns Array of generated questions
49
+ */
50
+ export declare function generateQuestionsForArtifact(artifactContent: string, artifactType: 'proposal' | 'design' | 'specs' | 'plan' | 'tasks', questionCount: number, provider: LLMProvider): Promise<Question[]>;
51
+ /**
52
+ * Generate complete quiz question set for all artifacts
53
+ *
54
+ * Reads all artifact files, calculates question allocation, and generates
55
+ * questions for each artifact type using the provided or fallback LLM provider.
56
+ *
57
+ * @param artifactPaths - Object mapping artifact types to file paths
58
+ * @param totalQuestions - Total number of questions to generate
59
+ * @param provider - LLM provider to use (optional, uses fallback if not provided)
60
+ * @returns Array of all generated questions
61
+ */
62
+ export declare function generateQuizQuestions(artifactPaths: {
63
+ proposal?: string;
64
+ design?: string;
65
+ specs?: string;
66
+ plan?: string;
67
+ tasks?: string;
68
+ }, totalQuestions: number, provider?: LLMProvider): Promise<Question[]>;
69
+ //# sourceMappingURL=question-generator.d.ts.map
@@ -0,0 +1,141 @@
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
+ * Generate complete quiz question set for all artifacts
101
+ *
102
+ * Reads all artifact files, calculates question allocation, and generates
103
+ * questions for each artifact type using the provided or fallback LLM provider.
104
+ *
105
+ * @param artifactPaths - Object mapping artifact types to file paths
106
+ * @param totalQuestions - Total number of questions to generate
107
+ * @param provider - LLM provider to use (optional, uses fallback if not provided)
108
+ * @returns Array of all generated questions
109
+ */
110
+ export async function generateQuizQuestions(artifactPaths, totalQuestions, provider) {
111
+ // Use fallback provider if not provided
112
+ const llmProvider = provider || await createProviderWithFallback();
113
+ // Read all artifact contents and calculate sizes
114
+ const artifactContents = {};
115
+ const artifactSizes = {
116
+ proposal: 0,
117
+ design: 0,
118
+ specs: 0,
119
+ plan: 0,
120
+ tasks: 0,
121
+ };
122
+ for (const [artifactType, filePath] of Object.entries(artifactPaths)) {
123
+ if (filePath) {
124
+ const content = await readArtifactContent(filePath);
125
+ artifactContents[artifactType] = content;
126
+ artifactSizes[artifactType] = content.length;
127
+ }
128
+ }
129
+ // Calculate question allocation
130
+ const allocation = calculateQuestionAllocation(totalQuestions, artifactSizes);
131
+ // Generate questions for each artifact type
132
+ const allQuestions = [];
133
+ for (const [artifactType, count] of Object.entries(allocation)) {
134
+ if (count > 0 && artifactContents[artifactType]) {
135
+ const questions = await generateQuestionsForArtifact(artifactContents[artifactType], artifactType, count, llmProvider);
136
+ allQuestions.push(...questions);
137
+ }
138
+ }
139
+ return allQuestions;
140
+ }
141
+ //# sourceMappingURL=question-generator.js.map
@@ -0,0 +1,70 @@
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 { Question, QuizResult } from './types.js';
11
+ /**
12
+ * Quiz executor class
13
+ *
14
+ * Manages the quiz state machine and CLI interaction. Enforces timing
15
+ * constraints (4-second wait before accepting input, 2-second minimum answer time)
16
+ * to prevent AI agents from programmatically answering questions.
17
+ */
18
+ export declare class QuizExecutor {
19
+ private state;
20
+ private currentQuestionIndex;
21
+ private questions;
22
+ private answers;
23
+ private questionDisplayedAt;
24
+ private answerReceivedAt;
25
+ private changeName;
26
+ private attemptNumber;
27
+ /**
28
+ * Execute quiz with given questions
29
+ *
30
+ * @param questions - Array of questions to ask
31
+ * @param changeName - Name of the change being tested
32
+ * @returns Quiz result with score and pass/fail status
33
+ */
34
+ executeQuiz(questions: Question[], changeName: string): Promise<QuizResult>;
35
+ /**
36
+ * Transition to a new state
37
+ *
38
+ * @param newState - New state to transition to
39
+ */
40
+ private transitionTo;
41
+ /**
42
+ * Ask a question to the user
43
+ *
44
+ * @param questionIndex - Index of the question to ask
45
+ */
46
+ private askQuestion;
47
+ /**
48
+ * Wait for user answer with timing constraints
49
+ *
50
+ * Enforces a minimum 2-second wait time after question display before
51
+ * accepting input to prevent automated answering.
52
+ *
53
+ * @returns User's answer (1, 2, or 3), or -1 if invalid/too early
54
+ */
55
+ private waitForAnswer;
56
+ /**
57
+ * Show feedback on the answer
58
+ *
59
+ * @param questionIndex - Index of the question
60
+ * @param answer - User's answer
61
+ */
62
+ private showFeedback;
63
+ /**
64
+ * Calculate quiz result
65
+ *
66
+ * @returns Quiz result with score and pass/fail status
67
+ */
68
+ private calculateResult;
69
+ }
70
+ //# sourceMappingURL=quiz-executor.d.ts.map
@@ -0,0 +1,165 @@
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
+ currentQuestionIndex = 0;
23
+ questions = [];
24
+ answers = [];
25
+ questionDisplayedAt = 0;
26
+ answerReceivedAt = 0;
27
+ changeName = '';
28
+ attemptNumber = 1;
29
+ /**
30
+ * Execute quiz with given questions
31
+ *
32
+ * @param questions - Array of questions to ask
33
+ * @param changeName - Name of the change being tested
34
+ * @returns Quiz result with score and pass/fail status
35
+ */
36
+ async executeQuiz(questions, changeName) {
37
+ this.questions = questions;
38
+ this.changeName = changeName;
39
+ this.currentQuestionIndex = 0;
40
+ this.answers = [];
41
+ this.state = 'START';
42
+ // Track attempt number from existing pass record
43
+ const existingRecord = await getPassRecord(changeName);
44
+ this.attemptNumber = existingRecord ? existingRecord.attemptCount + 1 : 1;
45
+ // Track attempt start
46
+ await trackComprehensionAttempt(changeName, this.attemptNumber);
47
+ // Start the quiz
48
+ await this.transitionTo('WAITING_FOR_QUESTION_1');
49
+ for (let i = 0; i < questions.length; i++) {
50
+ await this.askQuestion(i);
51
+ const answer = await this.waitForAnswer();
52
+ this.answers.push(answer);
53
+ await this.showFeedback(i, answer);
54
+ if (i < questions.length - 1) {
55
+ await this.transitionTo(`WAITING_FOR_QUESTION_${i + 2}`);
56
+ }
57
+ }
58
+ await this.transitionTo('DONE');
59
+ const result = this.calculateResult();
60
+ // Track completion
61
+ await trackComprehensionCompletion(changeName, result.scorePercent, result.passed ? 'pass' : 'fail', this.attemptNumber);
62
+ // If passed, emit apply_ready milestone
63
+ if (result.passed) {
64
+ await trackApplyReady(changeName);
65
+ }
66
+ return result;
67
+ }
68
+ /**
69
+ * Transition to a new state
70
+ *
71
+ * @param newState - New state to transition to
72
+ */
73
+ async transitionTo(newState) {
74
+ this.state = newState;
75
+ }
76
+ /**
77
+ * Ask a question to the user
78
+ *
79
+ * @param questionIndex - Index of the question to ask
80
+ */
81
+ async askQuestion(questionIndex) {
82
+ const question = this.questions[questionIndex];
83
+ console.log(`\nQuestion ${questionIndex + 1}/${this.questions.length}:`);
84
+ console.log(question.text);
85
+ console.log('');
86
+ console.log('1)', question.options[0]);
87
+ console.log('2)', question.options[1]);
88
+ console.log('3)', question.options[2]);
89
+ console.log('');
90
+ this.questionDisplayedAt = Date.now();
91
+ }
92
+ /**
93
+ * Wait for user answer with timing constraints
94
+ *
95
+ * Enforces a minimum 2-second wait time after question display before
96
+ * accepting input to prevent automated answering.
97
+ *
98
+ * @returns User's answer (1, 2, or 3), or -1 if invalid/too early
99
+ */
100
+ async waitForAnswer() {
101
+ const rl = readline.createInterface({
102
+ input: process.stdin,
103
+ output: process.stdout,
104
+ });
105
+ const answer = await new Promise((resolve) => {
106
+ rl.question('', (answer) => {
107
+ rl.close();
108
+ const trimmed = answer.trim();
109
+ // Check if answer was submitted too early (less than 2 seconds after question display)
110
+ const timeSinceDisplay = Date.now() - this.questionDisplayedAt;
111
+ if (timeSinceDisplay < 2000) {
112
+ console.log('Answer submitted too early. Please wait at least 2 seconds before answering.');
113
+ resolve(-1);
114
+ return;
115
+ }
116
+ // Validate input
117
+ if (trimmed === '1' || trimmed === '2' || trimmed === '3') {
118
+ resolve(parseInt(trimmed, 10));
119
+ }
120
+ else {
121
+ console.log('Answer this question to continue.');
122
+ resolve(-1);
123
+ }
124
+ });
125
+ });
126
+ return answer;
127
+ }
128
+ /**
129
+ * Show feedback on the answer
130
+ *
131
+ * @param questionIndex - Index of the question
132
+ * @param answer - User's answer
133
+ */
134
+ async showFeedback(questionIndex, answer) {
135
+ const question = this.questions[questionIndex];
136
+ const isCorrect = answer === question.correctOption + 1;
137
+ if (isCorrect) {
138
+ console.log('✓ Correct');
139
+ }
140
+ else {
141
+ console.log('✗ Incorrect');
142
+ console.log(`The correct answer was ${question.correctOption + 1}`);
143
+ }
144
+ // Clear terminal screen
145
+ console.clear();
146
+ }
147
+ /**
148
+ * Calculate quiz result
149
+ *
150
+ * @returns Quiz result with score and pass/fail status
151
+ */
152
+ calculateResult() {
153
+ const correct = this.answers.filter((answer, index) => answer === this.questions[index].correctOption + 1).length;
154
+ const total = this.questions.length;
155
+ const scorePercent = Math.round((correct / total) * 100);
156
+ return {
157
+ correct,
158
+ total,
159
+ scorePercent,
160
+ passed: scorePercent >= 80,
161
+ attemptNumber: 1, // TODO: Track attempt count
162
+ };
163
+ }
164
+ }
165
+ //# sourceMappingURL=quiz-executor.js.map