@garygentry/feature-forge 0.2.14 → 0.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (486) hide show
  1. package/README.md +6 -3
  2. package/adapters/GENERATION-REPORT.md +20 -0
  3. package/adapters/claude/.feature-forge-bundle.json +1 -1
  4. package/adapters/claude/agents/forge-verifier.md +1 -1
  5. package/adapters/claude/references/forge-config-schema.json +2 -2
  6. package/adapters/claude/references/pipeline-state-schema.json +1 -1
  7. package/adapters/claude/references/shared-conventions.md +62 -12
  8. package/adapters/claude/references/stage-exit-protocol.md +14 -4
  9. package/adapters/claude/references/vendor-construct-inventory.md +1 -1
  10. package/adapters/claude/scripts/epic-manifest.py +49 -6
  11. package/adapters/claude/scripts/forge-root.sh +47 -3
  12. package/adapters/claude/scripts/forge-session.py +1179 -9
  13. package/adapters/claude/scripts/validate-traceability.py +6 -1
  14. package/adapters/claude/skills/forge/SKILL.md +11 -5
  15. package/adapters/claude/skills/forge/references/pipeline-state-schema.json +1 -1
  16. package/adapters/claude/skills/forge/references/shared-conventions.md +62 -12
  17. package/adapters/claude/skills/forge/references/stage-exit-protocol.md +14 -4
  18. package/adapters/claude/skills/forge-0-epic/SKILL.md +1 -1
  19. package/adapters/claude/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
  20. package/adapters/claude/skills/forge-0-epic/references/shared-conventions.md +62 -12
  21. package/adapters/claude/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
  22. package/adapters/claude/skills/forge-1-prd/SKILL.md +25 -8
  23. package/adapters/claude/skills/forge-1-prd/references/shared-conventions.md +62 -12
  24. package/adapters/claude/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
  25. package/adapters/claude/skills/forge-2-tech/SKILL.md +25 -7
  26. package/adapters/claude/skills/forge-2-tech/references/shared-conventions.md +62 -12
  27. package/adapters/claude/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
  28. package/adapters/claude/skills/forge-3-specs/SKILL.md +24 -7
  29. package/adapters/claude/skills/forge-3-specs/references/shared-conventions.md +62 -12
  30. package/adapters/claude/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
  31. package/adapters/claude/skills/forge-4-backlog/SKILL.md +23 -7
  32. package/adapters/claude/skills/forge-4-backlog/references/shared-conventions.md +62 -12
  33. package/adapters/claude/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
  34. package/adapters/claude/skills/forge-5-loop/SKILL.md +25 -25
  35. package/adapters/claude/skills/forge-5-loop/references/agent-selection.md +116 -0
  36. package/adapters/claude/skills/forge-5-loop/references/runner-contract.md +14 -107
  37. package/adapters/claude/skills/forge-5-loop/references/shared-conventions.md +62 -12
  38. package/adapters/claude/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
  39. package/adapters/claude/skills/forge-6-docs/SKILL.md +11 -5
  40. package/adapters/claude/skills/forge-6-docs/references/shared-conventions.md +62 -12
  41. package/adapters/claude/skills/forge-fix/references/shared-conventions.md +62 -12
  42. package/adapters/claude/skills/forge-fix/references/stage-exit-protocol.md +14 -4
  43. package/adapters/claude/skills/forge-guide/references/forge-config-schema.json +2 -2
  44. package/adapters/claude/skills/forge-guide/references/shared-conventions.md +62 -12
  45. package/adapters/claude/skills/forge-verify/SKILL.md +22 -12
  46. package/adapters/claude/skills/forge-verify/references/findings-template.md +157 -0
  47. package/adapters/claude/skills/forge-verify/references/pipeline-state-schema.json +1 -1
  48. package/adapters/claude/skills/forge-verify/references/shared-conventions.md +62 -12
  49. package/adapters/claude/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
  50. package/adapters/claude/skills/forge-verify/references/verification-checklists/epic.md +79 -0
  51. package/adapters/claude/skills/forge-verify/references/verification-checklists/impl.md +48 -0
  52. package/adapters/claude/skills/forge-verify/references/verification-checklists/prd.md +31 -0
  53. package/adapters/claude/skills/forge-verify/references/verification-checklists/specs.md +64 -0
  54. package/adapters/claude/skills/forge-verify/references/verification-checklists/tech.md +35 -0
  55. package/adapters/codex/.feature-forge-bundle.json +1 -1
  56. package/adapters/codex/agents/forge-verifier.toml +1 -1
  57. package/adapters/codex/references/forge-config-schema.json +2 -2
  58. package/adapters/codex/references/pipeline-state-schema.json +1 -1
  59. package/adapters/codex/references/shared-conventions.md +62 -12
  60. package/adapters/codex/references/stage-exit-protocol.md +14 -4
  61. package/adapters/codex/references/vendor-construct-inventory.md +1 -1
  62. package/adapters/codex/scripts/epic-manifest.py +49 -6
  63. package/adapters/codex/scripts/forge-root.sh +47 -3
  64. package/adapters/codex/scripts/forge-session.py +1179 -9
  65. package/adapters/codex/scripts/validate-traceability.py +6 -1
  66. package/adapters/codex/skills/forge/SKILL.md +11 -5
  67. package/adapters/codex/skills/forge/references/pipeline-state-schema.json +1 -1
  68. package/adapters/codex/skills/forge/references/shared-conventions.md +62 -12
  69. package/adapters/codex/skills/forge/references/stage-exit-protocol.md +14 -4
  70. package/adapters/codex/skills/forge-0-epic/SKILL.md +1 -1
  71. package/adapters/codex/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
  72. package/adapters/codex/skills/forge-0-epic/references/shared-conventions.md +62 -12
  73. package/adapters/codex/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
  74. package/adapters/codex/skills/forge-1-prd/SKILL.md +25 -8
  75. package/adapters/codex/skills/forge-1-prd/references/shared-conventions.md +62 -12
  76. package/adapters/codex/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
  77. package/adapters/codex/skills/forge-2-tech/SKILL.md +25 -7
  78. package/adapters/codex/skills/forge-2-tech/references/shared-conventions.md +62 -12
  79. package/adapters/codex/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
  80. package/adapters/codex/skills/forge-3-specs/SKILL.md +24 -7
  81. package/adapters/codex/skills/forge-3-specs/references/shared-conventions.md +62 -12
  82. package/adapters/codex/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
  83. package/adapters/codex/skills/forge-4-backlog/SKILL.md +23 -7
  84. package/adapters/codex/skills/forge-4-backlog/references/shared-conventions.md +62 -12
  85. package/adapters/codex/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
  86. package/adapters/codex/skills/forge-5-loop/SKILL.md +25 -25
  87. package/adapters/codex/skills/forge-5-loop/references/agent-selection.md +116 -0
  88. package/adapters/codex/skills/forge-5-loop/references/runner-contract.md +14 -107
  89. package/adapters/codex/skills/forge-5-loop/references/shared-conventions.md +62 -12
  90. package/adapters/codex/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
  91. package/adapters/codex/skills/forge-6-docs/SKILL.md +11 -5
  92. package/adapters/codex/skills/forge-6-docs/references/shared-conventions.md +62 -12
  93. package/adapters/codex/skills/forge-fix/references/shared-conventions.md +62 -12
  94. package/adapters/codex/skills/forge-fix/references/stage-exit-protocol.md +14 -4
  95. package/adapters/codex/skills/forge-guide/references/forge-config-schema.json +2 -2
  96. package/adapters/codex/skills/forge-guide/references/shared-conventions.md +62 -12
  97. package/adapters/codex/skills/forge-verify/SKILL.md +22 -12
  98. package/adapters/codex/skills/forge-verify/references/findings-template.md +157 -0
  99. package/adapters/codex/skills/forge-verify/references/pipeline-state-schema.json +1 -1
  100. package/adapters/codex/skills/forge-verify/references/shared-conventions.md +62 -12
  101. package/adapters/codex/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
  102. package/adapters/codex/skills/forge-verify/references/verification-checklists/epic.md +79 -0
  103. package/adapters/codex/skills/forge-verify/references/verification-checklists/impl.md +48 -0
  104. package/adapters/codex/skills/forge-verify/references/verification-checklists/prd.md +31 -0
  105. package/adapters/codex/skills/forge-verify/references/verification-checklists/specs.md +64 -0
  106. package/adapters/codex/skills/forge-verify/references/verification-checklists/tech.md +35 -0
  107. package/adapters/copilot/.feature-forge-bundle.json +1 -1
  108. package/adapters/copilot/agents/forge-verifier.md +1 -1
  109. package/adapters/copilot/references/forge-config-schema.json +2 -2
  110. package/adapters/copilot/references/pipeline-state-schema.json +1 -1
  111. package/adapters/copilot/references/shared-conventions.md +62 -12
  112. package/adapters/copilot/references/stage-exit-protocol.md +14 -4
  113. package/adapters/copilot/references/vendor-construct-inventory.md +1 -1
  114. package/adapters/copilot/scripts/epic-manifest.py +49 -6
  115. package/adapters/copilot/scripts/forge-root.sh +47 -3
  116. package/adapters/copilot/scripts/forge-session.py +1179 -9
  117. package/adapters/copilot/scripts/validate-traceability.py +6 -1
  118. package/adapters/copilot/skills/forge/forge.md +11 -5
  119. package/adapters/copilot/skills/forge/references/pipeline-state-schema.json +1 -1
  120. package/adapters/copilot/skills/forge/references/shared-conventions.md +62 -12
  121. package/adapters/copilot/skills/forge/references/stage-exit-protocol.md +14 -4
  122. package/adapters/copilot/skills/forge-0-epic/forge-0-epic.md +1 -1
  123. package/adapters/copilot/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
  124. package/adapters/copilot/skills/forge-0-epic/references/shared-conventions.md +62 -12
  125. package/adapters/copilot/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
  126. package/adapters/copilot/skills/forge-1-prd/forge-1-prd.md +25 -8
  127. package/adapters/copilot/skills/forge-1-prd/references/shared-conventions.md +62 -12
  128. package/adapters/copilot/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
  129. package/adapters/copilot/skills/forge-2-tech/forge-2-tech.md +25 -7
  130. package/adapters/copilot/skills/forge-2-tech/references/shared-conventions.md +62 -12
  131. package/adapters/copilot/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
  132. package/adapters/copilot/skills/forge-3-specs/forge-3-specs.md +24 -7
  133. package/adapters/copilot/skills/forge-3-specs/references/shared-conventions.md +62 -12
  134. package/adapters/copilot/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
  135. package/adapters/copilot/skills/forge-4-backlog/forge-4-backlog.md +23 -7
  136. package/adapters/copilot/skills/forge-4-backlog/references/shared-conventions.md +62 -12
  137. package/adapters/copilot/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
  138. package/adapters/copilot/skills/forge-5-loop/forge-5-loop.md +25 -25
  139. package/adapters/copilot/skills/forge-5-loop/references/agent-selection.md +116 -0
  140. package/adapters/copilot/skills/forge-5-loop/references/runner-contract.md +14 -107
  141. package/adapters/copilot/skills/forge-5-loop/references/shared-conventions.md +62 -12
  142. package/adapters/copilot/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
  143. package/adapters/copilot/skills/forge-6-docs/forge-6-docs.md +11 -5
  144. package/adapters/copilot/skills/forge-6-docs/references/shared-conventions.md +62 -12
  145. package/adapters/copilot/skills/forge-fix/references/shared-conventions.md +62 -12
  146. package/adapters/copilot/skills/forge-fix/references/stage-exit-protocol.md +14 -4
  147. package/adapters/copilot/skills/forge-guide/references/forge-config-schema.json +2 -2
  148. package/adapters/copilot/skills/forge-guide/references/shared-conventions.md +62 -12
  149. package/adapters/copilot/skills/forge-verify/forge-verify.md +22 -12
  150. package/adapters/copilot/skills/forge-verify/references/findings-template.md +157 -0
  151. package/adapters/copilot/skills/forge-verify/references/pipeline-state-schema.json +1 -1
  152. package/adapters/copilot/skills/forge-verify/references/shared-conventions.md +62 -12
  153. package/adapters/copilot/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
  154. package/adapters/copilot/skills/forge-verify/references/verification-checklists/epic.md +79 -0
  155. package/adapters/copilot/skills/forge-verify/references/verification-checklists/impl.md +48 -0
  156. package/adapters/copilot/skills/forge-verify/references/verification-checklists/prd.md +31 -0
  157. package/adapters/copilot/skills/forge-verify/references/verification-checklists/specs.md +64 -0
  158. package/adapters/copilot/skills/forge-verify/references/verification-checklists/tech.md +35 -0
  159. package/adapters/cursor/.feature-forge-bundle.json +1 -1
  160. package/adapters/cursor/agents/forge-verifier.mdc +1 -1
  161. package/adapters/cursor/references/forge-config-schema.json +2 -2
  162. package/adapters/cursor/references/pipeline-state-schema.json +1 -1
  163. package/adapters/cursor/references/shared-conventions.md +62 -12
  164. package/adapters/cursor/references/stage-exit-protocol.md +14 -4
  165. package/adapters/cursor/references/vendor-construct-inventory.md +1 -1
  166. package/adapters/cursor/scripts/epic-manifest.py +49 -6
  167. package/adapters/cursor/scripts/forge-root.sh +47 -3
  168. package/adapters/cursor/scripts/forge-session.py +1179 -9
  169. package/adapters/cursor/scripts/validate-traceability.py +6 -1
  170. package/adapters/cursor/skills/forge/forge.mdc +11 -5
  171. package/adapters/cursor/skills/forge/references/pipeline-state-schema.json +1 -1
  172. package/adapters/cursor/skills/forge/references/shared-conventions.md +62 -12
  173. package/adapters/cursor/skills/forge/references/stage-exit-protocol.md +14 -4
  174. package/adapters/cursor/skills/forge-0-epic/forge-0-epic.mdc +1 -1
  175. package/adapters/cursor/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
  176. package/adapters/cursor/skills/forge-0-epic/references/shared-conventions.md +62 -12
  177. package/adapters/cursor/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
  178. package/adapters/cursor/skills/forge-1-prd/forge-1-prd.mdc +25 -8
  179. package/adapters/cursor/skills/forge-1-prd/references/shared-conventions.md +62 -12
  180. package/adapters/cursor/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
  181. package/adapters/cursor/skills/forge-2-tech/forge-2-tech.mdc +25 -7
  182. package/adapters/cursor/skills/forge-2-tech/references/shared-conventions.md +62 -12
  183. package/adapters/cursor/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
  184. package/adapters/cursor/skills/forge-3-specs/forge-3-specs.mdc +24 -7
  185. package/adapters/cursor/skills/forge-3-specs/references/shared-conventions.md +62 -12
  186. package/adapters/cursor/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
  187. package/adapters/cursor/skills/forge-4-backlog/forge-4-backlog.mdc +23 -7
  188. package/adapters/cursor/skills/forge-4-backlog/references/shared-conventions.md +62 -12
  189. package/adapters/cursor/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
  190. package/adapters/cursor/skills/forge-5-loop/forge-5-loop.mdc +25 -25
  191. package/adapters/cursor/skills/forge-5-loop/references/agent-selection.md +116 -0
  192. package/adapters/cursor/skills/forge-5-loop/references/runner-contract.md +14 -107
  193. package/adapters/cursor/skills/forge-5-loop/references/shared-conventions.md +62 -12
  194. package/adapters/cursor/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
  195. package/adapters/cursor/skills/forge-6-docs/forge-6-docs.mdc +11 -5
  196. package/adapters/cursor/skills/forge-6-docs/references/shared-conventions.md +62 -12
  197. package/adapters/cursor/skills/forge-fix/references/shared-conventions.md +62 -12
  198. package/adapters/cursor/skills/forge-fix/references/stage-exit-protocol.md +14 -4
  199. package/adapters/cursor/skills/forge-guide/references/forge-config-schema.json +2 -2
  200. package/adapters/cursor/skills/forge-guide/references/shared-conventions.md +62 -12
  201. package/adapters/cursor/skills/forge-verify/forge-verify.mdc +22 -12
  202. package/adapters/cursor/skills/forge-verify/references/findings-template.md +157 -0
  203. package/adapters/cursor/skills/forge-verify/references/pipeline-state-schema.json +1 -1
  204. package/adapters/cursor/skills/forge-verify/references/shared-conventions.md +62 -12
  205. package/adapters/cursor/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
  206. package/adapters/cursor/skills/forge-verify/references/verification-checklists/epic.md +79 -0
  207. package/adapters/cursor/skills/forge-verify/references/verification-checklists/impl.md +48 -0
  208. package/adapters/cursor/skills/forge-verify/references/verification-checklists/prd.md +31 -0
  209. package/adapters/cursor/skills/forge-verify/references/verification-checklists/specs.md +64 -0
  210. package/adapters/cursor/skills/forge-verify/references/verification-checklists/tech.md +35 -0
  211. package/adapters/gemini/.feature-forge-bundle.json +1 -1
  212. package/adapters/gemini/agents/forge-verifier.md +1 -1
  213. package/adapters/gemini/gemini-extension.json +1 -1
  214. package/adapters/gemini/references/forge-config-schema.json +2 -2
  215. package/adapters/gemini/references/pipeline-state-schema.json +1 -1
  216. package/adapters/gemini/references/shared-conventions.md +62 -12
  217. package/adapters/gemini/references/stage-exit-protocol.md +14 -4
  218. package/adapters/gemini/references/vendor-construct-inventory.md +1 -1
  219. package/adapters/gemini/scripts/epic-manifest.py +49 -6
  220. package/adapters/gemini/scripts/forge-root.sh +47 -3
  221. package/adapters/gemini/scripts/forge-session.py +1179 -9
  222. package/adapters/gemini/scripts/validate-traceability.py +6 -1
  223. package/adapters/gemini/skills/forge/forge.md +11 -5
  224. package/adapters/gemini/skills/forge/references/pipeline-state-schema.json +1 -1
  225. package/adapters/gemini/skills/forge/references/shared-conventions.md +62 -12
  226. package/adapters/gemini/skills/forge/references/stage-exit-protocol.md +14 -4
  227. package/adapters/gemini/skills/forge-0-epic/forge-0-epic.md +1 -1
  228. package/adapters/gemini/skills/forge-0-epic/references/pipeline-state-schema.json +1 -1
  229. package/adapters/gemini/skills/forge-0-epic/references/shared-conventions.md +62 -12
  230. package/adapters/gemini/skills/forge-0-epic/references/stage-exit-protocol.md +14 -4
  231. package/adapters/gemini/skills/forge-1-prd/forge-1-prd.md +25 -8
  232. package/adapters/gemini/skills/forge-1-prd/references/shared-conventions.md +62 -12
  233. package/adapters/gemini/skills/forge-1-prd/references/stage-exit-protocol.md +14 -4
  234. package/adapters/gemini/skills/forge-2-tech/forge-2-tech.md +25 -7
  235. package/adapters/gemini/skills/forge-2-tech/references/shared-conventions.md +62 -12
  236. package/adapters/gemini/skills/forge-2-tech/references/stage-exit-protocol.md +14 -4
  237. package/adapters/gemini/skills/forge-3-specs/forge-3-specs.md +24 -7
  238. package/adapters/gemini/skills/forge-3-specs/references/shared-conventions.md +62 -12
  239. package/adapters/gemini/skills/forge-3-specs/references/stage-exit-protocol.md +14 -4
  240. package/adapters/gemini/skills/forge-4-backlog/forge-4-backlog.md +23 -7
  241. package/adapters/gemini/skills/forge-4-backlog/references/shared-conventions.md +62 -12
  242. package/adapters/gemini/skills/forge-4-backlog/references/stage-exit-protocol.md +14 -4
  243. package/adapters/gemini/skills/forge-5-loop/forge-5-loop.md +25 -25
  244. package/adapters/gemini/skills/forge-5-loop/references/agent-selection.md +116 -0
  245. package/adapters/gemini/skills/forge-5-loop/references/runner-contract.md +14 -107
  246. package/adapters/gemini/skills/forge-5-loop/references/shared-conventions.md +62 -12
  247. package/adapters/gemini/skills/forge-5-loop/references/stage-exit-protocol.md +14 -4
  248. package/adapters/gemini/skills/forge-6-docs/forge-6-docs.md +11 -5
  249. package/adapters/gemini/skills/forge-6-docs/references/shared-conventions.md +62 -12
  250. package/adapters/gemini/skills/forge-fix/references/shared-conventions.md +62 -12
  251. package/adapters/gemini/skills/forge-fix/references/stage-exit-protocol.md +14 -4
  252. package/adapters/gemini/skills/forge-guide/references/forge-config-schema.json +2 -2
  253. package/adapters/gemini/skills/forge-guide/references/shared-conventions.md +62 -12
  254. package/adapters/gemini/skills/forge-verify/forge-verify.md +22 -12
  255. package/adapters/gemini/skills/forge-verify/references/findings-template.md +157 -0
  256. package/adapters/gemini/skills/forge-verify/references/pipeline-state-schema.json +1 -1
  257. package/adapters/gemini/skills/forge-verify/references/shared-conventions.md +62 -12
  258. package/adapters/gemini/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
  259. package/adapters/gemini/skills/forge-verify/references/verification-checklists/epic.md +79 -0
  260. package/adapters/gemini/skills/forge-verify/references/verification-checklists/impl.md +48 -0
  261. package/adapters/gemini/skills/forge-verify/references/verification-checklists/prd.md +31 -0
  262. package/adapters/gemini/skills/forge-verify/references/verification-checklists/specs.md +64 -0
  263. package/adapters/gemini/skills/forge-verify/references/verification-checklists/tech.md +35 -0
  264. package/adapters/pi/.feature-forge-bundle.json +6 -0
  265. package/adapters/pi/agents/forge-researcher.md +139 -0
  266. package/adapters/pi/agents/forge-spec-writer.md +116 -0
  267. package/adapters/pi/agents/forge-verifier.md +126 -0
  268. package/adapters/pi/extensions/ask-user-question/LICENSE +21 -0
  269. package/adapters/pi/extensions/ask-user-question/README.md +91 -0
  270. package/adapters/pi/extensions/ask-user-question/ask-user-question.ts +298 -0
  271. package/adapters/pi/extensions/ask-user-question/config.ts +78 -0
  272. package/adapters/pi/extensions/ask-user-question/events.ts +57 -0
  273. package/adapters/pi/extensions/ask-user-question/index.ts +61 -0
  274. package/adapters/pi/extensions/ask-user-question/locales/de.json +27 -0
  275. package/adapters/pi/extensions/ask-user-question/locales/en.json +27 -0
  276. package/adapters/pi/extensions/ask-user-question/locales/es.json +27 -0
  277. package/adapters/pi/extensions/ask-user-question/locales/fr.json +27 -0
  278. package/adapters/pi/extensions/ask-user-question/locales/pt-BR.json +27 -0
  279. package/adapters/pi/extensions/ask-user-question/locales/pt.json +27 -0
  280. package/adapters/pi/extensions/ask-user-question/locales/ru.json +27 -0
  281. package/adapters/pi/extensions/ask-user-question/locales/uk.json +27 -0
  282. package/adapters/pi/extensions/ask-user-question/locales/zh.json +29 -0
  283. package/adapters/pi/extensions/ask-user-question/reconcile.ts +49 -0
  284. package/adapters/pi/extensions/ask-user-question/rpc-fallback.ts +168 -0
  285. package/adapters/pi/extensions/ask-user-question/state/build-questionnaire.ts +302 -0
  286. package/adapters/pi/extensions/ask-user-question/state/i18n-bridge.ts +53 -0
  287. package/adapters/pi/extensions/ask-user-question/state/key-router.ts +277 -0
  288. package/adapters/pi/extensions/ask-user-question/state/questionnaire-session.ts +234 -0
  289. package/adapters/pi/extensions/ask-user-question/state/row-intent.ts +145 -0
  290. package/adapters/pi/extensions/ask-user-question/state/selectors/contract.ts +26 -0
  291. package/adapters/pi/extensions/ask-user-question/state/selectors/derivations.ts +42 -0
  292. package/adapters/pi/extensions/ask-user-question/state/selectors/focus.ts +19 -0
  293. package/adapters/pi/extensions/ask-user-question/state/selectors/projections.ts +101 -0
  294. package/adapters/pi/extensions/ask-user-question/state/state-reducer.ts +292 -0
  295. package/adapters/pi/extensions/ask-user-question/state/state.ts +55 -0
  296. package/adapters/pi/extensions/ask-user-question/tool/format-answer.ts +31 -0
  297. package/adapters/pi/extensions/ask-user-question/tool/response-envelope.ts +49 -0
  298. package/adapters/pi/extensions/ask-user-question/tool/types.ts +147 -0
  299. package/adapters/pi/extensions/ask-user-question/tool/validate-questionnaire.ts +58 -0
  300. package/adapters/pi/extensions/ask-user-question/vendor-config-shim.ts +65 -0
  301. package/adapters/pi/extensions/ask-user-question/view/component-binding.ts +47 -0
  302. package/adapters/pi/extensions/ask-user-question/view/components/inline-input.ts +98 -0
  303. package/adapters/pi/extensions/ask-user-question/view/components/multi-select-view.ts +193 -0
  304. package/adapters/pi/extensions/ask-user-question/view/components/option-list-view.ts +70 -0
  305. package/adapters/pi/extensions/ask-user-question/view/components/preview/markdown-content-cache.ts +79 -0
  306. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-block-renderer.ts +111 -0
  307. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-box-renderer.ts +88 -0
  308. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-layout-decider.ts +202 -0
  309. package/adapters/pi/extensions/ask-user-question/view/components/preview/preview-pane.ts +228 -0
  310. package/adapters/pi/extensions/ask-user-question/view/components/submit-picker.ts +67 -0
  311. package/adapters/pi/extensions/ask-user-question/view/components/tab-bar.ts +59 -0
  312. package/adapters/pi/extensions/ask-user-question/view/components/wrapping-select.ts +293 -0
  313. package/adapters/pi/extensions/ask-user-question/view/dialog-builder.ts +224 -0
  314. package/adapters/pi/extensions/ask-user-question/view/props-adapter.ts +125 -0
  315. package/adapters/pi/extensions/ask-user-question/view/stateful-view.ts +26 -0
  316. package/adapters/pi/extensions/ask-user-question/view/tab-components.ts +18 -0
  317. package/adapters/pi/extensions/ask-user-question/view/tab-content-strategy.ts +252 -0
  318. package/adapters/pi/package.json +26 -0
  319. package/adapters/pi/references/epic-manifest-schema.json +125 -0
  320. package/adapters/{claude/skills/forge-5-loop → pi}/references/forge-config-schema.json +4 -4
  321. package/adapters/{claude/skills/forge-1-prd → pi}/references/pipeline-state-schema.json +1 -1
  322. package/adapters/pi/references/portable-root.md +71 -0
  323. package/adapters/pi/references/process-overview.md +143 -0
  324. package/adapters/pi/references/ralph-loop-contract.md +221 -0
  325. package/adapters/pi/references/shared-conventions.md +345 -0
  326. package/adapters/pi/references/skill-frontmatter.schema.json +17 -0
  327. package/adapters/pi/references/stack-resolution.md +54 -0
  328. package/adapters/pi/references/stacks/_generic.md +111 -0
  329. package/adapters/pi/references/stacks/go.md +157 -0
  330. package/adapters/pi/references/stacks/python.md +184 -0
  331. package/adapters/pi/references/stacks/rust.md +170 -0
  332. package/adapters/pi/references/stacks/typescript.md +134 -0
  333. package/adapters/pi/references/stage-exit-protocol.md +268 -0
  334. package/adapters/pi/references/templates/specs-hygiene/AGENTS.md +32 -0
  335. package/adapters/pi/references/templates/specs-hygiene/CLAUDE.md +31 -0
  336. package/adapters/pi/references/vendor-construct-inventory.md +50 -0
  337. package/adapters/pi/scripts/epic-manifest.py +1737 -0
  338. package/adapters/pi/scripts/forge-bootstrap.py +1070 -0
  339. package/adapters/pi/scripts/forge-init.sh +58 -0
  340. package/adapters/pi/scripts/forge-root.sh +179 -0
  341. package/adapters/pi/scripts/forge-session.py +3036 -0
  342. package/adapters/pi/scripts/validate-traceability.py +155 -0
  343. package/adapters/pi/skills/forge/SKILL.md +249 -0
  344. package/adapters/{claude/skills/forge-4-backlog → pi/skills/forge}/references/pipeline-state-schema.json +1 -1
  345. package/adapters/pi/skills/forge/references/process-overview.md +143 -0
  346. package/adapters/pi/skills/forge/references/shared-conventions.md +345 -0
  347. package/adapters/pi/skills/forge/references/stage-exit-protocol.md +268 -0
  348. package/adapters/pi/skills/forge-0-epic/SKILL.md +308 -0
  349. package/adapters/pi/skills/forge-0-epic/references/edit-mode.md +266 -0
  350. package/adapters/pi/skills/forge-0-epic/references/epic-manifest-subcommands.md +75 -0
  351. package/adapters/{claude/skills/forge-2-tech → pi/skills/forge-0-epic}/references/pipeline-state-schema.json +1 -1
  352. package/adapters/pi/skills/forge-0-epic/references/portable-root.md +71 -0
  353. package/adapters/pi/skills/forge-0-epic/references/shared-conventions.md +345 -0
  354. package/adapters/pi/skills/forge-0-epic/references/stage-exit-protocol.md +268 -0
  355. package/adapters/pi/skills/forge-1-prd/SKILL.md +181 -0
  356. package/adapters/pi/skills/forge-1-prd/references/prd-template.md +106 -0
  357. package/adapters/pi/skills/forge-1-prd/references/shared-conventions.md +345 -0
  358. package/adapters/pi/skills/forge-1-prd/references/stage-exit-protocol.md +268 -0
  359. package/adapters/pi/skills/forge-2-tech/SKILL.md +243 -0
  360. package/adapters/pi/skills/forge-2-tech/references/shared-conventions.md +345 -0
  361. package/adapters/pi/skills/forge-2-tech/references/stack-discovery-checklist.md +95 -0
  362. package/adapters/pi/skills/forge-2-tech/references/stack-resolution.md +54 -0
  363. package/adapters/pi/skills/forge-2-tech/references/stacks/_generic.md +111 -0
  364. package/adapters/pi/skills/forge-2-tech/references/stacks/go.md +157 -0
  365. package/adapters/pi/skills/forge-2-tech/references/stacks/python.md +184 -0
  366. package/adapters/pi/skills/forge-2-tech/references/stacks/rust.md +170 -0
  367. package/adapters/pi/skills/forge-2-tech/references/stacks/typescript.md +134 -0
  368. package/adapters/pi/skills/forge-2-tech/references/stage-exit-protocol.md +268 -0
  369. package/adapters/pi/skills/forge-3-specs/SKILL.md +195 -0
  370. package/adapters/pi/skills/forge-3-specs/references/shared-conventions.md +345 -0
  371. package/adapters/pi/skills/forge-3-specs/references/spec-archetypes.md +106 -0
  372. package/adapters/pi/skills/forge-3-specs/references/spec-examples.md +71 -0
  373. package/adapters/pi/skills/forge-3-specs/references/stacks/_generic.md +111 -0
  374. package/adapters/pi/skills/forge-3-specs/references/stacks/go.md +157 -0
  375. package/adapters/pi/skills/forge-3-specs/references/stacks/python.md +184 -0
  376. package/adapters/pi/skills/forge-3-specs/references/stacks/rust.md +170 -0
  377. package/adapters/pi/skills/forge-3-specs/references/stacks/typescript.md +134 -0
  378. package/adapters/pi/skills/forge-3-specs/references/stage-exit-protocol.md +268 -0
  379. package/adapters/pi/skills/forge-4-backlog/SKILL.md +191 -0
  380. package/adapters/pi/skills/forge-4-backlog/references/shared-conventions.md +345 -0
  381. package/adapters/pi/skills/forge-4-backlog/references/stage-exit-protocol.md +268 -0
  382. package/adapters/pi/skills/forge-5-loop/SKILL.md +314 -0
  383. package/adapters/pi/skills/forge-5-loop/references/agent-selection.md +116 -0
  384. package/adapters/pi/skills/forge-5-loop/references/ralph-loop-contract.md +221 -0
  385. package/adapters/pi/skills/forge-5-loop/references/result-reporting.md +85 -0
  386. package/adapters/pi/skills/forge-5-loop/references/runner-contract.md +248 -0
  387. package/adapters/pi/skills/forge-5-loop/references/shared-conventions.md +345 -0
  388. package/adapters/pi/skills/forge-5-loop/references/stage-exit-protocol.md +268 -0
  389. package/adapters/pi/skills/forge-6-docs/SKILL.md +208 -0
  390. package/adapters/pi/skills/forge-6-docs/references/doc-conventions.md +126 -0
  391. package/adapters/pi/skills/forge-6-docs/references/shared-conventions.md +345 -0
  392. package/adapters/pi/skills/forge-bootstrap/SKILL.md +250 -0
  393. package/adapters/pi/skills/forge-bootstrap/references/templates/ci/github-actions.yml +12 -0
  394. package/adapters/pi/skills/forge-bootstrap/references/templates/generic/run.sh +3 -0
  395. package/adapters/pi/skills/forge-bootstrap/references/templates/generic/test.sh +13 -0
  396. package/adapters/pi/skills/forge-bootstrap/references/templates/go/go.mod +3 -0
  397. package/adapters/pi/skills/forge-bootstrap/references/templates/go/main.go +12 -0
  398. package/adapters/pi/skills/forge-bootstrap/references/templates/go/main_test.go +11 -0
  399. package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/AGENTS.md +35 -0
  400. package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/CLAUDE.md +36 -0
  401. package/adapters/pi/skills/forge-bootstrap/references/templates/hygiene/README.md +11 -0
  402. package/adapters/pi/skills/forge-bootstrap/references/templates/licenses/Apache-2.0/LICENSE +198 -0
  403. package/adapters/pi/skills/forge-bootstrap/references/templates/licenses/MIT/LICENSE +21 -0
  404. package/adapters/pi/skills/forge-bootstrap/references/templates/python/pyproject.toml +24 -0
  405. package/adapters/pi/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/__init__.py +5 -0
  406. package/adapters/pi/skills/forge-bootstrap/references/templates/python/src/{{PKG}}/main.py +13 -0
  407. package/adapters/pi/skills/forge-bootstrap/references/templates/python/tests/test_smoke.py +8 -0
  408. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/Cargo.toml +15 -0
  409. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/src/lib.rs +7 -0
  410. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/src/main.rs +5 -0
  411. package/adapters/pi/skills/forge-bootstrap/references/templates/rust/tests/smoke.rs +6 -0
  412. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/package.json +15 -0
  413. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/src/index.ts +4 -0
  414. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/test/smoke.test.ts +6 -0
  415. package/adapters/pi/skills/forge-bootstrap/references/templates/typescript/tsconfig.json +14 -0
  416. package/adapters/pi/skills/forge-fix/SKILL.md +98 -0
  417. package/adapters/pi/skills/forge-fix/references/shared-conventions.md +345 -0
  418. package/adapters/pi/skills/forge-fix/references/stage-exit-protocol.md +268 -0
  419. package/adapters/pi/skills/forge-guide/SKILL.md +192 -0
  420. package/adapters/{codex/skills/forge-4-backlog → pi/skills/forge-guide}/references/forge-config-schema.json +4 -4
  421. package/adapters/pi/skills/forge-guide/references/process-overview.md +143 -0
  422. package/adapters/pi/skills/forge-guide/references/ralph-loop-contract.md +221 -0
  423. package/adapters/pi/skills/forge-guide/references/shared-conventions.md +345 -0
  424. package/adapters/pi/skills/forge-guide/references/stack-resolution.md +54 -0
  425. package/adapters/pi/skills/forge-guide/references/stacks/_generic.md +111 -0
  426. package/adapters/pi/skills/forge-guide/references/stacks/go.md +157 -0
  427. package/adapters/pi/skills/forge-guide/references/stacks/python.md +184 -0
  428. package/adapters/pi/skills/forge-guide/references/stacks/rust.md +170 -0
  429. package/adapters/pi/skills/forge-guide/references/stacks/typescript.md +134 -0
  430. package/adapters/pi/skills/forge-init/SKILL.md +72 -0
  431. package/adapters/pi/skills/forge-verify/SKILL.md +283 -0
  432. package/adapters/pi/skills/forge-verify/references/findings-template.md +157 -0
  433. package/adapters/{claude/skills/forge-3-specs → pi/skills/forge-verify}/references/pipeline-state-schema.json +1 -1
  434. package/adapters/pi/skills/forge-verify/references/shared-conventions.md +345 -0
  435. package/adapters/pi/skills/forge-verify/references/verification-checklists/backlog.md +97 -0
  436. package/adapters/pi/skills/forge-verify/references/verification-checklists/epic.md +79 -0
  437. package/adapters/pi/skills/forge-verify/references/verification-checklists/impl.md +48 -0
  438. package/adapters/pi/skills/forge-verify/references/verification-checklists/prd.md +31 -0
  439. package/adapters/pi/skills/forge-verify/references/verification-checklists/specs.md +64 -0
  440. package/adapters/pi/skills/forge-verify/references/verification-checklists/tech.md +35 -0
  441. package/dist/agent-targets.d.ts +1 -1
  442. package/dist/agent-targets.js +23 -3
  443. package/dist/detect.d.ts +1 -1
  444. package/dist/detect.js +2 -1
  445. package/dist/manifest.d.ts +1 -1
  446. package/dist/manifest.js +2 -2
  447. package/dist/placements.js +5 -1
  448. package/dist/rauf.d.ts +4 -4
  449. package/dist/rauf.js +3 -3
  450. package/dist/types.d.ts +31 -6
  451. package/dist/types.js +6 -3
  452. package/package.json +14 -3
  453. package/adapters/claude/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
  454. package/adapters/claude/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
  455. package/adapters/claude/skills/forge-verify/references/verification-checklists.md +0 -477
  456. package/adapters/codex/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
  457. package/adapters/codex/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
  458. package/adapters/codex/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
  459. package/adapters/codex/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
  460. package/adapters/codex/skills/forge-5-loop/references/forge-config-schema.json +0 -236
  461. package/adapters/codex/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
  462. package/adapters/codex/skills/forge-verify/references/verification-checklists.md +0 -477
  463. package/adapters/copilot/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
  464. package/adapters/copilot/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
  465. package/adapters/copilot/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
  466. package/adapters/copilot/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
  467. package/adapters/copilot/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
  468. package/adapters/copilot/skills/forge-5-loop/references/forge-config-schema.json +0 -236
  469. package/adapters/copilot/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
  470. package/adapters/copilot/skills/forge-verify/references/verification-checklists.md +0 -477
  471. package/adapters/cursor/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
  472. package/adapters/cursor/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
  473. package/adapters/cursor/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
  474. package/adapters/cursor/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
  475. package/adapters/cursor/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
  476. package/adapters/cursor/skills/forge-5-loop/references/forge-config-schema.json +0 -236
  477. package/adapters/cursor/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
  478. package/adapters/cursor/skills/forge-verify/references/verification-checklists.md +0 -477
  479. package/adapters/gemini/skills/forge-1-prd/references/pipeline-state-schema.json +0 -191
  480. package/adapters/gemini/skills/forge-2-tech/references/pipeline-state-schema.json +0 -191
  481. package/adapters/gemini/skills/forge-3-specs/references/pipeline-state-schema.json +0 -191
  482. package/adapters/gemini/skills/forge-4-backlog/references/forge-config-schema.json +0 -236
  483. package/adapters/gemini/skills/forge-4-backlog/references/pipeline-state-schema.json +0 -191
  484. package/adapters/gemini/skills/forge-5-loop/references/forge-config-schema.json +0 -236
  485. package/adapters/gemini/skills/forge-6-docs/references/pipeline-state-schema.json +0 -191
  486. package/adapters/gemini/skills/forge-verify/references/verification-checklists.md +0 -477
@@ -0,0 +1,298 @@
1
+ // GENERATED — DO NOT EDIT. Source: adapter-src/pi/extensions/ask-user-question/ask-user-question.ts
2
+ // Regenerate with: python3 scripts/build-adapters.py
3
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
4
+ import { isKeyRelease, isKeyRepeat, matchesKey } from "@earendil-works/pi-tui";
5
+ import { loadConfig, resolveCollapseKey, validateGuidanceFields } from "./config.js";
6
+ import {
7
+ ASK_USER_BLOCKED_EVENT,
8
+ ASK_USER_PROMPT_EVENT,
9
+ type AskUserBlockedEventPayload,
10
+ type AskUserPromptEventPayload,
11
+ } from "./events.js";
12
+ // Static import is fine — rpc-fallback pulls only types + the i18n bridge,
13
+ // none of the ~560ms TUI render graph that QuestionnaireSession lazy-loads.
14
+ import { hasDialogUI, runRpcQuestionnaire } from "./rpc-fallback.js";
15
+ import { displayLabel } from "./state/i18n-bridge.js";
16
+ import { sentinelsToAppend } from "./state/row-intent.js";
17
+ import { buildQuestionnaireResponse, buildToolResult } from "./tool/response-envelope.js";
18
+ import {
19
+ MAX_OPTIONS,
20
+ MAX_QUESTIONS,
21
+ MIN_OPTIONS,
22
+ type QuestionData,
23
+ type QuestionnaireError,
24
+ type QuestionnaireResult,
25
+ type QuestionParams,
26
+ QuestionParamsSchema,
27
+ } from "./tool/types.js";
28
+ import { validateQuestionnaire } from "./tool/validate-questionnaire.js";
29
+ import type { WrappingSelectItem } from "./view/components/wrapping-select.js";
30
+
31
+ function emitAskUserPromptEvent(pi: ExtensionAPI, params: QuestionParams): void {
32
+ const payload: AskUserPromptEventPayload = {
33
+ questions: params.questions.map((q) => ({
34
+ question: q.question,
35
+ header: q.header,
36
+ multiSelect: q.multiSelect ?? false,
37
+ options: q.options.map((o) => ({
38
+ label: o.label,
39
+ description: o.description,
40
+ hasPreview: typeof o.preview === "string" && o.preview.length > 0,
41
+ })),
42
+ })),
43
+ };
44
+ pi.events.emit(ASK_USER_PROMPT_EVENT, payload);
45
+ }
46
+
47
+ function emitAskUserBlockedEvent(pi: ExtensionAPI, active: boolean): void {
48
+ const payload: AskUserBlockedEventPayload = { active };
49
+ pi.events.emit(ASK_USER_BLOCKED_EVENT, payload);
50
+ }
51
+
52
+ /** Canonical tool name — single source of truth shared with the reconcile module. */
53
+ export const ASK_USER_QUESTION_TOOL_NAME = "AskUserQuestion"; // FEATURE-FORGE VENDOR PATCH: Claude-parity name
54
+
55
+ const ERROR_NO_UI = "Error: UI not available (running in non-interactive mode)";
56
+
57
+ const ERROR_NO_CUSTOM_UI =
58
+ "Error: this client cannot render the questionnaire (custom UI is unavailable, e.g. RPC/ACP hosts such as Zed or Paseo). The user never saw the questions — do NOT treat this as a decline. Ask the questions as plain chat text instead, without using this tool.";
59
+
60
+ const ERROR_SESSION_LOAD_FAILED =
61
+ "Error: the questionnaire UI failed to load — the host's installed dependencies were likely replaced or removed on disk while Pi was running (e.g. a package-manager install touched the store). The user never saw the questions — do NOT treat this as a decline. Ask the questions as plain chat text instead, and tell the user that restoring this tool requires repairing the install if needed and restarting Pi.";
62
+
63
+ const ERROR_STALE_MODULE_CACHE =
64
+ "Error: the questionnaire UI cannot load — the host's module cache went stale after an earlier failed load (typically dependencies replaced on disk mid-session). This is unrecoverable within the current Pi process. The user never saw the questions — do NOT treat this as a decline. Ask the questions as plain chat text instead, and tell the user to restart Pi to restore this tool.";
65
+
66
+ /** Delay before the background session-graph pre-warm; mirrors rpiv-workflow's /wf prewarm. */
67
+ export const PREWARM_DELAY_MS = 2000;
68
+
69
+ type SessionModule = typeof import("./state/questionnaire-session.js");
70
+
71
+ type SessionLoad =
72
+ | { ok: true; module: SessionModule }
73
+ | { ok: false; error: Extract<QuestionnaireError, "session_load_failed" | "stale_module_cache">; message: string };
74
+
75
+ /**
76
+ * Lazy-load the ~560ms QuestionnaireSession view/TUI render graph, guarding
77
+ * the two failure shapes of issue #107. Pi's jiti loader registers a module in
78
+ * its graph cache BEFORE evaluating the body and does not evict it when
79
+ * evaluation throws (jiti 2.7.0), so one failed load — e.g. `pnpm install
80
+ * --force` replacing the store entry mid-session — leaves every later import
81
+ * of this specifier resolving to a namespace without the class. That state is
82
+ * unrecoverable in-process (cache-busting specifiers fail jiti resolution);
83
+ * both branches therefore return an LLM-facing envelope that names the restart
84
+ * requirement instead of leaking a bare "not a constructor" TypeError.
85
+ */
86
+ export async function loadQuestionnaireSession(): Promise<SessionLoad> {
87
+ let mod: SessionModule;
88
+ try {
89
+ mod = await import("./state/questionnaire-session.js");
90
+ } catch (e) {
91
+ const cause = e instanceof Error ? e.message : String(e);
92
+ return { ok: false, error: "session_load_failed", message: `${ERROR_SESSION_LOAD_FAILED} (cause: ${cause})` };
93
+ }
94
+ if (typeof mod.QuestionnaireSession !== "function") {
95
+ const keys = JSON.stringify(Object.keys(mod));
96
+ return {
97
+ ok: false,
98
+ error: "stale_module_cache",
99
+ message: `${ERROR_STALE_MODULE_CACHE} (resolved namespace keys: ${keys})`,
100
+ };
101
+ }
102
+ return { ok: true, module: mod };
103
+ }
104
+
105
+ export function buildItemsForQuestion(question: QuestionData): WrappingSelectItem[] {
106
+ const items: WrappingSelectItem[] = question.options.map((o) => ({
107
+ kind: "option",
108
+ label: o.label,
109
+ description: o.description,
110
+ }));
111
+ for (const kind of sentinelsToAppend(question)) {
112
+ items.push({ kind, label: displayLabel(kind) });
113
+ }
114
+ return items;
115
+ }
116
+
117
+ export const DEFAULT_PROMPT_SNIPPET = `Ask the user up to ${MAX_QUESTIONS} structured questions (${MIN_OPTIONS}-${MAX_OPTIONS} options each) when requirements are ambiguous`;
118
+ export const DEFAULT_PROMPT_GUIDELINES: string[] = [
119
+ `Use ask_user_question whenever the user's request is underspecified and you cannot proceed without concrete decisions — you can ask up to ${MAX_QUESTIONS} questions per invocation.`,
120
+ `Each question MUST have ${MIN_OPTIONS}-${MAX_OPTIONS} options. Every option requires a concise label (1-5 words) and a description explaining what the choice means or its trade-offs. The user can additionally type a custom answer via the automatically appended "Type something." row on every question, or press Esc to abandon the questionnaire. Do NOT author "Other" or "Type something." labels yourself — reserved labels are rejected at runtime.`,
121
+ `Set multiSelect: true when multiple answers are valid. Provide an options[].preview markdown string when an option benefits from richer side-by-side context (mockups, code snippets, diagrams, configs) — single-select only. The "Type something." row is appended to every question; in preview mode it expands to the full pane width while typing so the custom answer is not cramped into the narrow options column. If you recommend a specific option, make that the first option and append "(Recommended)" to its label.`,
122
+ "Do not stack multiple ask_user_question calls back-to-back — group all clarifying questions into one invocation.",
123
+ ];
124
+
125
+ export function registerAskUserQuestionTool(pi: ExtensionAPI): void {
126
+ const guidance = validateGuidanceFields(loadConfig().guidance);
127
+ pi.registerTool({
128
+ name: ASK_USER_QUESTION_TOOL_NAME,
129
+ label: "Ask User Question",
130
+ description: `Ask the user one or more structured questions during execution. Use when you need to:
131
+ 1. Gather user preferences or requirements
132
+ 2. Clarify ambiguous instructions
133
+ 3. Get decisions on implementation choices as you work
134
+ 4. Offer choices to the user about what direction to take
135
+
136
+ Usage notes:
137
+ - Users can type a custom answer via the automatically appended "Type something." row on every question or press Esc to abandon the questionnaire. Do NOT author "Other" or "Type something." labels yourself — reserved labels are rejected at runtime.
138
+ - Use multiSelect: true when multiple answers are valid. The "Type something." row is available on every question, including when options carry a \`preview\`; in preview mode it expands to the full pane width while typing so the custom answer is not cramped into the narrow options column.
139
+ - If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label.
140
+
141
+ Preview feature:
142
+ Use the optional \`preview\` field on options when presenting concrete artifacts that users need to visually compare:
143
+ - ASCII mockups of UI layouts or components
144
+ - Code snippets showing different implementations
145
+ - Diagram variations
146
+ - Configuration examples
147
+
148
+ Preview content is rendered as markdown in a monospace box. Multi-line text with newlines is supported. When any option has a preview, the UI switches to a side-by-side layout with a vertical option list on the left and preview on the right. Do not use previews for simple preference questions where labels and descriptions suffice. Note: previews are only supported for single-select questions (not multiSelect).`,
149
+ promptSnippet: guidance.promptSnippet ?? DEFAULT_PROMPT_SNIPPET,
150
+ promptGuidelines: guidance.promptGuidelines ?? DEFAULT_PROMPT_GUIDELINES,
151
+ parameters: QuestionParamsSchema,
152
+
153
+ async execute(_toolCallId, params, _signal, _onUpdate, ctx) {
154
+ const typed = params as unknown as QuestionParams;
155
+ if (!ctx.hasUI) return buildToolResult(ERROR_NO_UI, { answers: [], cancelled: true, error: "no_ui" });
156
+
157
+ const validation = validateQuestionnaire(typed);
158
+ if (!validation.ok) {
159
+ return buildToolResult(validation.message, {
160
+ answers: [],
161
+ cancelled: true,
162
+ error: validation.error,
163
+ });
164
+ }
165
+
166
+ // Emit event for external listeners (e.g., notification plugins)
167
+ emitAskUserPromptEvent(pi, typed);
168
+
169
+ // RPC hosts (VSCode pendant, ACP clients like Zed/Paseo — issue #78):
170
+ // ui.custom() cannot render there, but the select/input dialog
171
+ // sub-protocol works. Hosts that advertise ctx.mode (pi ≥0.79) route to
172
+ // the sequential dialog walker up front, skipping the TUI render-graph
173
+ // import entirely; RPC builds that predate ctx.mode are caught by the
174
+ // custom()-resolved-undefined backstop below. See ./rpc-fallback.ts.
175
+ if ((ctx as { mode?: string }).mode === "rpc" && hasDialogUI(ctx.ui)) {
176
+ emitAskUserBlockedEvent(pi, true);
177
+ try {
178
+ return buildQuestionnaireResponse(await runRpcQuestionnaire(ctx.ui, typed), typed);
179
+ } finally {
180
+ emitAskUserBlockedEvent(pi, false);
181
+ }
182
+ }
183
+
184
+ const itemsByTab: WrappingSelectItem[][] = typed.questions.map((q) => buildItemsForQuestion(q));
185
+
186
+ // Lazy — QuestionnaireSession pulls the ~560ms view/TUI render graph;
187
+ // load it only when the tool runs, not at extension registration.
188
+ const sessionLoad = await loadQuestionnaireSession();
189
+ if (!sessionLoad.ok) {
190
+ return buildToolResult(sessionLoad.message, { answers: [], cancelled: true, error: sessionLoad.error });
191
+ }
192
+ const { QuestionnaireSession } = sessionLoad.module;
193
+ // Resolve the collapse/expand key spec from config. Default is `ctrl+]`; users
194
+ // with non-US layouts (e.g. Latin American, where `]` is shifted) can override
195
+ // via the `collapseKey` config field. `resolveCollapseKey` also accepts the
196
+ // sentinel value `"off"` to disable the shortcut entirely.
197
+ const collapseKey = resolveCollapseKey(loadConfig());
198
+
199
+ // Capture the overlay handle so the session can call `setHidden()` when the
200
+ // user toggles collapse, and register a raw terminal input listener for the
201
+ // same key so the toggle still works while the overlay is hidden (pi-tui does
202
+ // not route input to a hidden overlay's `component.handleInput`).
203
+ const sessionRef: {
204
+ current: import("./state/questionnaire-session.js").QuestionnaireSession | null;
205
+ } = { current: null };
206
+ const overlayHandleRef: { current: import("@earendil-works/pi-tui").OverlayHandle | undefined } = {
207
+ current: undefined,
208
+ };
209
+ let hasAnnouncedHide = false;
210
+ let removeOverlayInputListener: (() => void) | undefined;
211
+
212
+ if (collapseKey !== "off" && typeof ctx.ui.onTerminalInput === "function") {
213
+ removeOverlayInputListener = ctx.ui.onTerminalInput((data) => {
214
+ const handle = overlayHandleRef.current;
215
+ if (!handle) return undefined;
216
+ // Only act while the questionnaire is hidden (its handleInput is
217
+ // unreachable) or actually focused. When some other overlay is on
218
+ // top (e.g. `/btw`), leave the keystroke to that overlay instead of
219
+ // toggling the questionnaire from underneath it.
220
+ if (!handle.isHidden() && !handle.isFocused()) return undefined;
221
+ if (!matchesKey(data, collapseKey as Parameters<typeof matchesKey>[1])) return undefined;
222
+ // Kitty-protocol terminals report press, repeat, and release separately.
223
+ // Toggle only on the initial press so a tap does not immediately reopen
224
+ // the overlay and a held key does not toggle it repeatedly.
225
+ if (isKeyRelease(data) || isKeyRepeat(data)) return { consume: true };
226
+ sessionRef.current?.toggleCollapsedExternal();
227
+ if (handle.isHidden() && !hasAnnouncedHide) {
228
+ hasAnnouncedHide = true;
229
+ ctx.ui.notify?.(`ask_user_question hidden — press ${collapseKey} to reopen`, "info");
230
+ }
231
+ return { consume: true };
232
+ });
233
+ }
234
+
235
+ emitAskUserBlockedEvent(pi, true);
236
+ try {
237
+ const result = await ctx.ui.custom<QuestionnaireResult>(
238
+ (tui, theme, _kb, done) => {
239
+ const session = new QuestionnaireSession({
240
+ tui,
241
+ theme,
242
+ params: typed,
243
+ itemsByTab,
244
+ done,
245
+ collapseKey,
246
+ });
247
+ sessionRef.current = session;
248
+ return session.component;
249
+ },
250
+ {
251
+ overlay: true,
252
+ overlayOptions: {
253
+ anchor: "bottom-center",
254
+ width: "100%",
255
+ maxHeight: "100%",
256
+ margin: { left: 0, right: 0, bottom: 0 },
257
+ },
258
+ onHandle: (handle) => {
259
+ overlayHandleRef.current = handle;
260
+ sessionRef.current?.setOverlayHandle(handle);
261
+ },
262
+ },
263
+ );
264
+
265
+ // A TUI questionnaire ALWAYS resolves a QuestionnaireResult (cancel
266
+ // included — state-reducer emits `{ answers, cancelled }`), so
267
+ // `undefined` uniquely means "host cannot render", never "user
268
+ // declined". RPC builds that predate ctx.mode land here: run the
269
+ // dialog walker when the host has the primitives; otherwise tell the
270
+ // model the user never saw the questions.
271
+ if (result === undefined) {
272
+ if (hasDialogUI(ctx.ui)) {
273
+ return buildQuestionnaireResponse(await runRpcQuestionnaire(ctx.ui, typed), typed);
274
+ }
275
+ return buildToolResult(ERROR_NO_CUSTOM_UI, { answers: [], cancelled: true, error: "no_custom_ui" });
276
+ }
277
+
278
+ return buildQuestionnaireResponse(result, typed);
279
+ } finally {
280
+ removeOverlayInputListener?.();
281
+ emitAskUserBlockedEvent(pi, false);
282
+ }
283
+ },
284
+ });
285
+
286
+ // Pre-warm the lazy session graph once startup settles (#107). A graph
287
+ // evaluated while the paths Pi resolved at boot still exist stays in memory
288
+ // for the process lifetime, so later on-disk dependency churn (e.g. `pnpm
289
+ // install --force` replacing the store mid-session) can no longer poison
290
+ // jiti's graph cache. Swallowed failure is safe: the first real call
291
+ // re-imports and surfaces it through loadQuestionnaireSession's structured
292
+ // envelope. unref keeps the timer from holding a non-TUI embedder's process
293
+ // open.
294
+ const timer = setTimeout(() => void loadQuestionnaireSession().catch(() => undefined), PREWARM_DELAY_MS);
295
+ timer.unref?.();
296
+ }
297
+
298
+ export { buildQuestionnaireResponse, buildToolResult };
@@ -0,0 +1,78 @@
1
+ // GENERATED — DO NOT EDIT. Source: adapter-src/pi/extensions/ask-user-question/config.ts
2
+ // Regenerate with: python3 scripts/build-adapters.py
3
+ // FEATURE-FORGE VENDOR PATCH: upstream imports these from @juicesharp/rpiv-config.
4
+ import type { GuidanceFields } from "./vendor-config-shim.js";
5
+ import { loadJsonConfigWithLegacyFallback, validateGuidanceFields } from "./vendor-config-shim.js";
6
+
7
+ /** Key spec for the overlay collapse/expand shortcut, e.g. `"ctrl+]"` or `"alt+o"`. */
8
+ export type CollapseKeySpec = string;
9
+
10
+ export const DEFAULT_COLLAPSE_KEY: CollapseKeySpec = "ctrl+]";
11
+ export const COLLAPSE_KEY_OFF: CollapseKeySpec = "off";
12
+
13
+ export interface AskUserQuestionConfig {
14
+ guidance?: GuidanceFields;
15
+ /**
16
+ * Key spec for the collapse/expand shortcut, in the same format as pi-coding-agent
17
+ * keybinding ids (`modifier+key`, e.g. `ctrl+]`, `alt+o`, `ctrl+shift+h`). Defaults
18
+ * to `"ctrl+]"`. Set this to a key that is reachable on your keyboard layout — Latin
19
+ * American layouts (where `]` is on the shifted layer) often want `"ctrl+}"` instead.
20
+ * Pass `"off"` to disable the collapse shortcut entirely.
21
+ */
22
+ collapseKey?: CollapseKeySpec;
23
+ }
24
+
25
+ // Named keys accepted by pi-tui's `matchesKey` (keys.js switch on the parsed base key).
26
+ // parseKeyId lowercases the id before matching, so lowercase spellings are canonical.
27
+ const SPECIAL_KEYS = new Set([
28
+ "escape",
29
+ "esc",
30
+ "enter",
31
+ "return",
32
+ "tab",
33
+ "space",
34
+ "backspace",
35
+ "delete",
36
+ "insert",
37
+ "clear",
38
+ "home",
39
+ "end",
40
+ "pageup",
41
+ "pagedown",
42
+ "up",
43
+ "down",
44
+ "left",
45
+ "right",
46
+ ...Array.from({ length: 12 }, (_, i) => `f${i + 1}`),
47
+ ]);
48
+
49
+ const MODIFIERS = new Set(["ctrl", "shift", "alt", "super"]);
50
+
51
+ function isValidCollapseKeySpec(spec: string): boolean {
52
+ // Mirror pi-tui's KeyId grammar strictly: zero or more distinct modifiers, then a
53
+ // base key that is a single printable character or a named special key. A loose
54
+ // check is not enough — pi-tui's `parseKeyId` takes the LAST `+`-part as the key
55
+ // and ignores unknown parts, so a typo like `ctr+]` would silently match every
56
+ // bare `]` keypress (and the raw terminal listener would consume them globally).
57
+ if (!spec) return false;
58
+ if (spec.startsWith("+") || spec.endsWith("+") || spec.includes("++")) return false;
59
+ const parts = spec.split("+");
60
+ const base = parts[parts.length - 1] ?? "";
61
+ const modifiers = parts.slice(0, -1);
62
+ if (modifiers.length !== new Set(modifiers).size) return false;
63
+ if (!modifiers.every((m) => MODIFIERS.has(m))) return false;
64
+ return base.length === 1 ? /[a-z0-9_\-!@#$%^&*()|~`'":;,./<>?[\]{}=\\]/.test(base) : SPECIAL_KEYS.has(base);
65
+ }
66
+
67
+ export function resolveCollapseKey(config: Pick<AskUserQuestionConfig, "collapseKey">): CollapseKeySpec {
68
+ const raw = config.collapseKey?.trim().toLowerCase();
69
+ if (raw === undefined || raw === "") return DEFAULT_COLLAPSE_KEY;
70
+ if (raw === COLLAPSE_KEY_OFF) return COLLAPSE_KEY_OFF;
71
+ return isValidCollapseKeySpec(raw) ? raw : DEFAULT_COLLAPSE_KEY;
72
+ }
73
+
74
+ export function loadConfig(): AskUserQuestionConfig {
75
+ return loadJsonConfigWithLegacyFallback<AskUserQuestionConfig>("rpiv-ask-user-question");
76
+ }
77
+
78
+ export { validateGuidanceFields };
@@ -0,0 +1,57 @@
1
+ // GENERATED — DO NOT EDIT. Source: adapter-src/pi/extensions/ask-user-question/events.ts
2
+ // Regenerate with: python3 scripts/build-adapters.py
3
+ /**
4
+ * Public event contract for @juicesharp/rpiv-ask-user-question.
5
+ *
6
+ * STABILITY POLICY — applies to every event in the `rpiv:*` namespace.
7
+ *
8
+ * 1. Channel names are immutable. Once shipped, never rename.
9
+ * 2. Payload changes are append-only. Listeners MUST tolerate unknown
10
+ * fields. New fields ship as optional (`?:`).
11
+ * 3. Breaking changes (rename, retype, remove a field; change emission
12
+ * semantics) require a NEW channel, e.g. `rpiv:ask-user:prompt.v2`,
13
+ * with dual-emit during a deprecation window.
14
+ * 4. No `version` field inside payloads. Version via channel name only.
15
+ * 5. Payloads must be JSON-safe: primitives, arrays, plain objects.
16
+ * No Set/Map/Date/class instances — payloads must survive JSON
17
+ * serialization when listeners forward them across process or
18
+ * network boundaries.
19
+ *
20
+ * Naming: `rpiv:<package-or-tool>:<phase>`, lowercase, hyphen-separated.
21
+ * Aligns with Pi's `"my-extension:status"` example and UniPi's `unipi:*`.
22
+ */
23
+
24
+ export const ASK_USER_PROMPT_EVENT = "rpiv:ask-user:prompt" as const;
25
+
26
+ export interface AskUserPromptEventPayload {
27
+ questions: ReadonlyArray<AskUserPromptQuestion>;
28
+ }
29
+
30
+ /**
31
+ * Emitted while the questionnaire is awaiting user input (TUI `ui.custom` and
32
+ * RPC dialog walker). Cleared with `{ active: false }` in `finally` so listeners
33
+ * can distinguish blocked-on-human from working.
34
+ */
35
+ export const ASK_USER_BLOCKED_EVENT = "rpiv:ask-user:blocked" as const;
36
+
37
+ export interface AskUserBlockedEventPayload {
38
+ /** True while input is awaited; false when the wait ends (answer, cancel, or error). */
39
+ active: boolean;
40
+ }
41
+
42
+ export interface AskUserPromptQuestion {
43
+ /** The full question text, exactly as the agent authored it. */
44
+ question: string;
45
+ /** The short chip/tag shown next to the question. */
46
+ header: string;
47
+ /** True iff the user may pick multiple options. Normalized from optional. */
48
+ multiSelect: boolean;
49
+ options: ReadonlyArray<AskUserPromptOption>;
50
+ }
51
+
52
+ export interface AskUserPromptOption {
53
+ label: string;
54
+ description: string;
55
+ /** True iff the option carries rich preview content (content not shipped). */
56
+ hasPreview: boolean;
57
+ }
@@ -0,0 +1,61 @@
1
+ // GENERATED — DO NOT EDIT. Source: adapter-src/pi/extensions/ask-user-question/index.ts
2
+ // Regenerate with: python3 scripts/build-adapters.py
3
+ /**
4
+ * rpiv-ask-user-question — Pi extension. Registers the `ask_user_question`
5
+ * tool: a structured option selector with an automatically appended
6
+ * `Type something.` custom-answer row.
7
+ *
8
+ * Sentinel labels and TUI chrome strings localize at render time via the i18n
9
+ * bridge. Strings are registered with rpiv-i18n here, once, at module init —
10
+ * but only when the SDK is actually installed. If `@juicesharp/rpiv-i18n` is
11
+ * missing (standalone install of just this package), the dynamic-load shim
12
+ * no-ops and the bridge's `t(key, fallback)` returns the inline English literal
13
+ * at every call site. The extension stays online either way.
14
+ *
15
+ * Adding a locale: drop `locales/<code>.json` next to en.json (mirroring the
16
+ * key set). No edit needed here — `registerLocalesFromDir` iterates
17
+ * `SUPPORTED_LOCALES` from the SDK. See `@juicesharp/rpiv-i18n` README →
18
+ * "Contributing translations" for the full convention.
19
+ */
20
+
21
+ import type { ExtensionAPI } from "@earendil-works/pi-coding-agent";
22
+ import { dirname } from "node:path"; // FEATURE-FORGE VENDOR PATCH
23
+ import { fileURLToPath } from "node:url"; // FEATURE-FORGE VENDOR PATCH
24
+ import { registerAskUserQuestionTool } from "./ask-user-question.js";
25
+ import { registerAskUserQuestionReconciler } from "./reconcile.js";
26
+ import { I18N_NAMESPACE } from "./state/i18n-bridge.js";
27
+
28
+ type I18nLoader = {
29
+ registerLocalesFromDir: (namespace: string, packageUrl: string, options?: { label?: string }) => void;
30
+ };
31
+
32
+ // Dynamic import keeps `@juicesharp/rpiv-i18n` a soft optional peer: when the
33
+ // SDK is installed alongside this package the strings register and
34
+ // `/languages` flips them live; when it isn't, the import rejects here, we
35
+ // no-op, and the bridge's English-fallback shim keeps the extension online.
36
+ //
37
+ // The `/loader` subpath is used instead of the SDK entry so the i18n-ui +
38
+ // pi-tui modules are not pulled into our load graph just to register strings.
39
+ try {
40
+ const sdk = (await import("@juicesharp/rpiv-i18n/loader")) as I18nLoader;
41
+ sdk.registerLocalesFromDir(I18N_NAMESPACE, import.meta.url, { label: "rpiv-ask-user-question" });
42
+ } catch {
43
+ // SDK absent — extension still loads with English-only UI.
44
+ }
45
+
46
+ export {
47
+ ASK_USER_BLOCKED_EVENT,
48
+ ASK_USER_PROMPT_EVENT,
49
+ type AskUserBlockedEventPayload,
50
+ type AskUserPromptEventPayload,
51
+ type AskUserPromptOption,
52
+ type AskUserPromptQuestion,
53
+ } from "./events.js";
54
+
55
+ export default function (pi: ExtensionAPI) {
56
+ // FEATURE-FORGE VENDOR PATCH: seed the bundle root so generated forge shell
57
+ // snippets prefer this active Pi adapter over unrelated local installs.
58
+ process.env.FEATURE_FORGE_ROOT ||= dirname(dirname(dirname(fileURLToPath(import.meta.url))));
59
+ registerAskUserQuestionTool(pi);
60
+ registerAskUserQuestionReconciler(pi);
61
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "_meta.notes": "Auto-translated draft. Native-speaker review welcome via PR. TUI symbols (↑/↓, ⚠) and key names (Enter, Esc, Tab, Space, n) are universal CLI conventions and stay untranslated.",
3
+
4
+ "sentinel.other": "Schreibe etwas.",
5
+ "sentinel.next": "Weiter",
6
+
7
+ "submit.label": "Antworten senden",
8
+ "submit.cancel": "Abbrechen",
9
+
10
+ "hint.enter": "Enter zum Auswählen",
11
+ "hint.navigate": "↑/↓ zur Navigation",
12
+ "hint.toggle": "Leertaste zum Umschalten",
13
+ "hint.notes": "n für Notizen",
14
+ "hint.tab": "Tab wechselt die Frage",
15
+ "hint.cancel": "Esc zum Abbrechen",
16
+
17
+ "review.heading": "Antworten überprüfen",
18
+ "review.ready": "Bereit, deine Antworten zu senden?",
19
+ "review.incomplete": "⚠ Beantworte die verbleibenden Fragen vor dem Senden:",
20
+
21
+ "preview.no_preview": "Keine Vorschau verfügbar",
22
+ "preview.notes_affordance": "Notizen: drücke n, um Notizen hinzuzufügen",
23
+ "notes.header": "Notizen:",
24
+
25
+ "rpc.multi_instructions": "Gib die Nummern aller zutreffenden Optionen durch Komma getrennt ein (z. B. \"1,3\") oder tippe eine eigene Antwort als Text.",
26
+ "rpc.custom_answer_title": "Gib deine Antwort ein:"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "sentinel.other": "Type something.",
3
+ "sentinel.next": "Next",
4
+
5
+ "submit.label": "Submit answers",
6
+ "submit.cancel": "Cancel",
7
+
8
+ "hint.enter": "Enter to select",
9
+ "hint.navigate": "↑/↓ to navigate",
10
+ "hint.toggle": "Space to toggle",
11
+ "hint.notes": "n to add notes",
12
+ "hint.tab": "Tab to switch questions",
13
+ "hint.collapse": "Ctrl+] to collapse",
14
+ "hint.expand_line": "Ctrl+] to expand · Esc to cancel",
15
+ "hint.cancel": "Esc to cancel",
16
+
17
+ "review.heading": "Review your answers",
18
+ "review.ready": "Ready to submit your answers?",
19
+ "review.incomplete": "⚠ Answer remaining questions before submitting:",
20
+
21
+ "preview.no_preview": "No preview available",
22
+ "preview.notes_affordance": "Notes: press n to add notes",
23
+ "notes.header": "Notes:",
24
+
25
+ "rpc.multi_instructions": "Enter the numbers of all that apply, comma-separated (e.g. \"1,3\"), or type a custom answer as plain text.",
26
+ "rpc.custom_answer_title": "Type your answer:"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "_meta.notes": "Auto-translated draft. Native-speaker review welcome via PR. TUI symbols (↑/↓, ⚠) and key names (Enter, Esc, Tab, Space, n) are universal CLI conventions and stay untranslated.",
3
+
4
+ "sentinel.other": "Escribe algo.",
5
+ "sentinel.next": "Siguiente",
6
+
7
+ "submit.label": "Enviar respuestas",
8
+ "submit.cancel": "Cancelar",
9
+
10
+ "hint.enter": "Enter para seleccionar",
11
+ "hint.navigate": "↑/↓ para navegar",
12
+ "hint.toggle": "Espacio para alternar",
13
+ "hint.notes": "n para añadir notas",
14
+ "hint.tab": "Tab para cambiar de pregunta",
15
+ "hint.cancel": "Esc para cancelar",
16
+
17
+ "review.heading": "Revisa tus respuestas",
18
+ "review.ready": "¿Listo para enviar tus respuestas?",
19
+ "review.incomplete": "⚠ Responde las preguntas restantes antes de enviar:",
20
+
21
+ "preview.no_preview": "Vista previa no disponible",
22
+ "preview.notes_affordance": "Notas: pulsa n para añadir notas",
23
+ "notes.header": "Notas:",
24
+
25
+ "rpc.multi_instructions": "Introduce los números de todas las opciones que apliquen, separados por comas (p. ej. \"1,3\"), o escribe una respuesta propia como texto.",
26
+ "rpc.custom_answer_title": "Escribe tu respuesta:"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "_meta.notes": "Auto-translated draft. Native-speaker review welcome via PR. TUI symbols (↑/↓, ⚠) and key names (Enter, Esc, Tab, Space, n) are universal CLI conventions and stay untranslated.",
3
+
4
+ "sentinel.other": "Écrivez quelque chose.",
5
+ "sentinel.next": "Suivant",
6
+
7
+ "submit.label": "Envoyer les réponses",
8
+ "submit.cancel": "Annuler",
9
+
10
+ "hint.enter": "Entrée pour sélectionner",
11
+ "hint.navigate": "↑/↓ pour naviguer",
12
+ "hint.toggle": "Espace pour basculer",
13
+ "hint.notes": "n pour ajouter des notes",
14
+ "hint.tab": "Tab pour changer de question",
15
+ "hint.cancel": "Échap pour annuler",
16
+
17
+ "review.heading": "Vérifiez vos réponses",
18
+ "review.ready": "Prêt à envoyer vos réponses ?",
19
+ "review.incomplete": "⚠ Répondez aux questions restantes avant d'envoyer :",
20
+
21
+ "preview.no_preview": "Aucun aperçu disponible",
22
+ "preview.notes_affordance": "Notes : appuyez sur n pour ajouter des notes",
23
+ "notes.header": "Notes :",
24
+
25
+ "rpc.multi_instructions": "Saisissez les numéros de toutes les options applicables, séparés par des virgules (p. ex. « 1,3 »), ou tapez une réponse libre en texte.",
26
+ "rpc.custom_answer_title": "Tapez votre réponse :"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "_meta.notes": "Auto-translated draft. Native-speaker review welcome via PR. TUI symbols (↑/↓, ⚠) and key names (Enter, Esc, Tab, Space, n) are universal CLI conventions and stay untranslated.",
3
+
4
+ "sentinel.other": "Digite algo.",
5
+ "sentinel.next": "Próximo",
6
+
7
+ "submit.label": "Enviar respostas",
8
+ "submit.cancel": "Cancelar",
9
+
10
+ "hint.enter": "Enter para selecionar",
11
+ "hint.navigate": "↑/↓ para navegar",
12
+ "hint.toggle": "Espaço para alternar",
13
+ "hint.notes": "n para adicionar notas",
14
+ "hint.tab": "Tab para trocar de pergunta",
15
+ "hint.cancel": "Esc para cancelar",
16
+
17
+ "review.heading": "Revise suas respostas",
18
+ "review.ready": "Pronto para enviar suas respostas?",
19
+ "review.incomplete": "⚠ Responda as perguntas restantes antes de enviar:",
20
+
21
+ "preview.no_preview": "Pré-visualização indisponível",
22
+ "preview.notes_affordance": "Notas: pressione n para adicionar notas",
23
+ "notes.header": "Notas:",
24
+
25
+ "rpc.multi_instructions": "Digite os números de todas as opções aplicáveis, separados por vírgula (ex.: \"1,3\") ou digite uma resposta própria em texto.",
26
+ "rpc.custom_answer_title": "Digite sua resposta:"
27
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "_meta.notes": "European Portuguese (Portugal). Auto-translated draft. Native-speaker review welcome via PR. Distinct from pt-BR (Brasil): differs in lexicon (utilizador / você), conjugation, and some terms. TUI symbols (↑/↓, ⚠) and key names (Enter, Esc, Tab, Space, n) are universal CLI conventions and stay untranslated.",
3
+
4
+ "sentinel.other": "Escreva algo.",
5
+ "sentinel.next": "Seguinte",
6
+
7
+ "submit.label": "Enviar respostas",
8
+ "submit.cancel": "Cancelar",
9
+
10
+ "hint.enter": "Enter para selecionar",
11
+ "hint.navigate": "↑/↓ para navegar",
12
+ "hint.toggle": "Espaço para alternar",
13
+ "hint.notes": "n para adicionar notas",
14
+ "hint.tab": "Tab para mudar de pergunta",
15
+ "hint.cancel": "Esc para cancelar",
16
+
17
+ "review.heading": "Reveja as suas respostas",
18
+ "review.ready": "Pronto para enviar as suas respostas?",
19
+ "review.incomplete": "⚠ Responda às perguntas restantes antes de enviar:",
20
+
21
+ "preview.no_preview": "Pré-visualização indisponível",
22
+ "preview.notes_affordance": "Notas: prima n para adicionar notas",
23
+ "notes.header": "Notas:",
24
+
25
+ "rpc.multi_instructions": "Introduza os números de todas as opções aplicáveis, separados por vírgulas (ex.: \"1,3\") ou escreva uma resposta própria em texto.",
26
+ "rpc.custom_answer_title": "Escreva a sua resposta:"
27
+ }