@sun-asterisk/sungen 3.2.2 → 3.2.3-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (355) hide show
  1. package/dist/capabilities/discover.d.ts.map +1 -1
  2. package/dist/capabilities/discover.js +26 -3
  3. package/dist/capabilities/discover.js.map +1 -1
  4. package/dist/cli/commands/add-flow.d.ts.map +1 -1
  5. package/dist/cli/commands/add-flow.js +2 -0
  6. package/dist/cli/commands/add-flow.js.map +1 -1
  7. package/dist/cli/commands/add.d.ts.map +1 -1
  8. package/dist/cli/commands/add.js +4 -0
  9. package/dist/cli/commands/add.js.map +1 -1
  10. package/dist/cli/commands/capability.d.ts.map +1 -1
  11. package/dist/cli/commands/capability.js +61 -0
  12. package/dist/cli/commands/capability.js.map +1 -1
  13. package/dist/cli/commands/delivery.d.ts.map +1 -1
  14. package/dist/cli/commands/delivery.js +89 -2
  15. package/dist/cli/commands/delivery.js.map +1 -1
  16. package/dist/cli/commands/eval.js +3 -3
  17. package/dist/cli/commands/eval.js.map +1 -1
  18. package/dist/cli/commands/gate.d.ts +3 -0
  19. package/dist/cli/commands/gate.d.ts.map +1 -0
  20. package/dist/cli/commands/gate.js +83 -0
  21. package/dist/cli/commands/gate.js.map +1 -0
  22. package/dist/cli/commands/generate.d.ts.map +1 -1
  23. package/dist/cli/commands/generate.js +2 -1
  24. package/dist/cli/commands/generate.js.map +1 -1
  25. package/dist/cli/commands/init.d.ts.map +1 -1
  26. package/dist/cli/commands/init.js +32 -2
  27. package/dist/cli/commands/init.js.map +1 -1
  28. package/dist/cli/commands/journey.d.ts +3 -0
  29. package/dist/cli/commands/journey.d.ts.map +1 -0
  30. package/dist/cli/commands/journey.js +114 -0
  31. package/dist/cli/commands/journey.js.map +1 -0
  32. package/dist/cli/commands/update.d.ts.map +1 -1
  33. package/dist/cli/commands/update.js +10 -3
  34. package/dist/cli/commands/update.js.map +1 -1
  35. package/dist/cli/index.js +4 -0
  36. package/dist/cli/index.js.map +1 -1
  37. package/dist/dashboard/snapshot-builder.d.ts.map +1 -1
  38. package/dist/dashboard/snapshot-builder.js +10 -1
  39. package/dist/dashboard/snapshot-builder.js.map +1 -1
  40. package/dist/exporters/csv-exporter.d.ts.map +1 -1
  41. package/dist/exporters/csv-exporter.js +3 -1
  42. package/dist/exporters/csv-exporter.js.map +1 -1
  43. package/dist/exporters/json-exporter.js +3 -1
  44. package/dist/exporters/json-exporter.js.map +1 -1
  45. package/dist/exporters/mobile-app-id.d.ts +22 -0
  46. package/dist/exporters/mobile-app-id.d.ts.map +1 -0
  47. package/dist/exporters/mobile-app-id.js +37 -0
  48. package/dist/exporters/mobile-app-id.js.map +1 -0
  49. package/dist/exporters/spec-parser.d.ts.map +1 -1
  50. package/dist/exporters/spec-parser.js +6 -2
  51. package/dist/exporters/spec-parser.js.map +1 -1
  52. package/dist/generators/test-generator/adapters/adapter-interface.d.ts +3 -0
  53. package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
  54. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
  55. package/dist/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
  56. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
  57. package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
  58. package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
  59. package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
  60. package/dist/generators/test-generator/code-generator.js +48 -9
  61. package/dist/generators/test-generator/code-generator.js.map +1 -1
  62. package/dist/generators/test-generator/template-engine.d.ts +3 -0
  63. package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
  64. package/dist/generators/test-generator/template-engine.js +11 -1
  65. package/dist/generators/test-generator/template-engine.js.map +1 -1
  66. package/dist/generators/test-generator/utils/selector-resolver.d.ts +11 -1
  67. package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
  68. package/dist/generators/test-generator/utils/selector-resolver.js +33 -0
  69. package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
  70. package/dist/harness/audit.d.ts.map +1 -1
  71. package/dist/harness/audit.js +8 -1
  72. package/dist/harness/audit.js.map +1 -1
  73. package/dist/harness/catalog/universal-viewpoints.yaml +15 -0
  74. package/dist/harness/eval/skill-lint.d.ts +3 -3
  75. package/dist/harness/eval/skill-lint.d.ts.map +1 -1
  76. package/dist/harness/eval/skill-lint.js +88 -68
  77. package/dist/harness/eval/skill-lint.js.map +1 -1
  78. package/dist/harness/journey.d.ts +88 -0
  79. package/dist/harness/journey.d.ts.map +1 -0
  80. package/dist/harness/journey.js +414 -0
  81. package/dist/harness/journey.js.map +1 -0
  82. package/dist/harness/quality-gates.d.ts +13 -0
  83. package/dist/harness/quality-gates.d.ts.map +1 -1
  84. package/dist/harness/quality-gates.js +23 -0
  85. package/dist/harness/quality-gates.js.map +1 -1
  86. package/dist/harness/sensors.d.ts +1 -1
  87. package/dist/harness/sensors.d.ts.map +1 -1
  88. package/dist/harness/sensors.js +32 -9
  89. package/dist/harness/sensors.js.map +1 -1
  90. package/dist/orchestrator/ai-rules-updater.d.ts +11 -3
  91. package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
  92. package/dist/orchestrator/ai-rules-updater.js +44 -180
  93. package/dist/orchestrator/ai-rules-updater.js.map +1 -1
  94. package/dist/orchestrator/ai-skills/adapters.d.ts +28 -0
  95. package/dist/orchestrator/ai-skills/adapters.d.ts.map +1 -0
  96. package/dist/orchestrator/ai-skills/adapters.js +34 -0
  97. package/dist/orchestrator/ai-skills/adapters.js.map +1 -0
  98. package/dist/orchestrator/ai-skills/build.d.ts +10 -0
  99. package/dist/orchestrator/ai-skills/build.d.ts.map +1 -0
  100. package/dist/orchestrator/ai-skills/build.js +128 -0
  101. package/dist/orchestrator/ai-skills/build.js.map +1 -0
  102. package/dist/orchestrator/ai-skills/cap-stripper.d.ts +27 -0
  103. package/dist/orchestrator/ai-skills/cap-stripper.d.ts.map +1 -0
  104. package/dist/orchestrator/ai-skills/cap-stripper.js +78 -0
  105. package/dist/orchestrator/ai-skills/cap-stripper.js.map +1 -0
  106. package/dist/orchestrator/ai-skills/commands.d.ts +22 -0
  107. package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -0
  108. package/dist/orchestrator/ai-skills/commands.js +109 -0
  109. package/dist/orchestrator/ai-skills/commands.js.map +1 -0
  110. package/dist/orchestrator/ai-skills/generator.d.ts +23 -0
  111. package/dist/orchestrator/ai-skills/generator.d.ts.map +1 -0
  112. package/dist/orchestrator/ai-skills/generator.js +79 -0
  113. package/dist/orchestrator/ai-skills/generator.js.map +1 -0
  114. package/dist/orchestrator/ai-skills/golden-skills.test.d.ts +2 -0
  115. package/dist/orchestrator/ai-skills/golden-skills.test.d.ts.map +1 -0
  116. package/dist/orchestrator/ai-skills/golden-skills.test.js +183 -0
  117. package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -0
  118. package/dist/orchestrator/ai-skills/resolve-assistants.d.ts +8 -0
  119. package/dist/orchestrator/ai-skills/resolve-assistants.d.ts.map +1 -0
  120. package/dist/orchestrator/ai-skills/resolve-assistants.js +28 -0
  121. package/dist/orchestrator/ai-skills/resolve-assistants.js.map +1 -0
  122. package/dist/orchestrator/ai-skills/writer.d.ts +15 -0
  123. package/dist/orchestrator/ai-skills/writer.d.ts.map +1 -0
  124. package/dist/orchestrator/ai-skills/writer.js +129 -0
  125. package/dist/orchestrator/ai-skills/writer.js.map +1 -0
  126. package/dist/orchestrator/flow-manager.d.ts +11 -0
  127. package/dist/orchestrator/flow-manager.d.ts.map +1 -1
  128. package/dist/orchestrator/flow-manager.js +147 -29
  129. package/dist/orchestrator/flow-manager.js.map +1 -1
  130. package/dist/orchestrator/mobile-runtime-scaffolder.d.ts +59 -0
  131. package/dist/orchestrator/mobile-runtime-scaffolder.d.ts.map +1 -0
  132. package/dist/orchestrator/mobile-runtime-scaffolder.js +298 -0
  133. package/dist/orchestrator/mobile-runtime-scaffolder.js.map +1 -0
  134. package/dist/orchestrator/project-initializer.d.ts +44 -7
  135. package/dist/orchestrator/project-initializer.d.ts.map +1 -1
  136. package/dist/orchestrator/project-initializer.js +147 -79
  137. package/dist/orchestrator/project-initializer.js.map +1 -1
  138. package/dist/orchestrator/screen-manager.d.ts +30 -0
  139. package/dist/orchestrator/screen-manager.d.ts.map +1 -1
  140. package/dist/orchestrator/screen-manager.js +205 -22
  141. package/dist/orchestrator/screen-manager.js.map +1 -1
  142. package/dist/orchestrator/templates/ai-src/README.md +58 -0
  143. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
  144. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
  145. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -4
  146. package/{src/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → dist/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
  147. package/{src/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → dist/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
  148. package/dist/orchestrator/templates/ai-src/commands/design.md +29 -0
  149. package/{src/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → dist/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
  150. package/dist/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
  151. package/{src/orchestrator/templates/ai-instructions/claude-cmd-review.md → dist/orchestrator/templates/ai-src/commands/review.md} +57 -2
  152. package/{src/orchestrator/templates/ai-instructions/claude-cmd-run-test.md → dist/orchestrator/templates/ai-src/commands/run-test.md} +116 -5
  153. package/dist/orchestrator/templates/ai-src/config/codex.md +8 -0
  154. package/{src/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
  155. package/dist/orchestrator/templates/{ai-instructions/github-skill-sungen-error-mapping.md → ai-src/skills/sungen-error-mapping/SKILL.md} +49 -9
  156. package/{src/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
  157. package/{src/orchestrator/templates/ai-instructions/claude-skill-locale.md → dist/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
  158. package/{src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md → dist/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md} +17 -0
  159. package/dist/orchestrator/templates/{ai-instructions/claude-skill-selector-fix-mobile.md → ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
  160. package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
  161. package/dist/orchestrator/templates/playwright.config.ts +7 -4
  162. package/package.json +3 -3
  163. package/src/capabilities/discover.ts +29 -3
  164. package/src/cli/commands/add-flow.ts +2 -0
  165. package/src/cli/commands/add.ts +4 -0
  166. package/src/cli/commands/capability.ts +64 -1
  167. package/src/cli/commands/delivery.ts +89 -2
  168. package/src/cli/commands/eval.ts +3 -3
  169. package/src/cli/commands/gate.ts +44 -0
  170. package/src/cli/commands/generate.ts +2 -1
  171. package/src/cli/commands/init.ts +50 -3
  172. package/src/cli/commands/journey.ts +72 -0
  173. package/src/cli/commands/update.ts +14 -4
  174. package/src/cli/index.ts +4 -0
  175. package/src/dashboard/snapshot-builder.ts +10 -1
  176. package/src/exporters/csv-exporter.ts +3 -1
  177. package/src/exporters/json-exporter.ts +3 -1
  178. package/src/exporters/mobile-app-id.ts +34 -0
  179. package/src/exporters/spec-parser.ts +6 -2
  180. package/src/generators/test-generator/adapters/adapter-interface.ts +3 -0
  181. package/src/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
  182. package/src/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
  183. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
  184. package/src/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
  185. package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
  186. package/src/generators/test-generator/code-generator.ts +49 -9
  187. package/src/generators/test-generator/template-engine.ts +14 -1
  188. package/src/generators/test-generator/utils/selector-resolver.ts +51 -1
  189. package/src/harness/audit.ts +9 -2
  190. package/src/harness/catalog/universal-viewpoints.yaml +15 -0
  191. package/src/harness/eval/skill-lint.ts +71 -60
  192. package/src/harness/journey.ts +434 -0
  193. package/src/harness/quality-gates.ts +20 -0
  194. package/src/harness/sensors.ts +25 -8
  195. package/src/orchestrator/ai-rules-updater.ts +35 -197
  196. package/src/orchestrator/ai-skills/adapters.ts +52 -0
  197. package/src/orchestrator/ai-skills/build.ts +103 -0
  198. package/src/orchestrator/ai-skills/cap-stripper.ts +85 -0
  199. package/src/orchestrator/ai-skills/commands.ts +112 -0
  200. package/src/orchestrator/ai-skills/generator.ts +47 -0
  201. package/src/orchestrator/ai-skills/golden-skills.test.ts +124 -0
  202. package/src/orchestrator/ai-skills/resolve-assistants.ts +18 -0
  203. package/src/orchestrator/ai-skills/writer.ts +92 -0
  204. package/src/orchestrator/flow-manager.ts +165 -29
  205. package/src/orchestrator/mobile-runtime-scaffolder.ts +277 -0
  206. package/src/orchestrator/project-initializer.ts +159 -86
  207. package/src/orchestrator/screen-manager.ts +237 -22
  208. package/src/orchestrator/templates/ai-src/README.md +58 -0
  209. package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
  210. package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
  211. package/src/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -4
  212. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → src/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
  213. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → src/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
  214. package/src/orchestrator/templates/ai-src/commands/design.md +29 -0
  215. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → src/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
  216. package/src/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
  217. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-review.md → src/orchestrator/templates/ai-src/commands/review.md} +57 -2
  218. package/{dist/orchestrator/templates/ai-instructions/claude-cmd-run-test.md → src/orchestrator/templates/ai-src/commands/run-test.md} +116 -5
  219. package/src/orchestrator/templates/ai-src/config/codex.md +8 -0
  220. package/{dist/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
  221. package/{dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md → src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md} +49 -9
  222. package/{dist/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
  223. package/{dist/orchestrator/templates/ai-instructions/claude-skill-locale.md → src/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
  224. package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix.md → src/orchestrator/templates/ai-src/skills/sungen-selector-fix/SKILL.md} +17 -0
  225. package/src/orchestrator/templates/{ai-instructions/claude-skill-selector-fix-mobile.md → ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
  226. package/src/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
  227. package/src/orchestrator/templates/playwright.config.ts +7 -4
  228. package/dist/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
  229. package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
  230. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
  231. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
  232. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -93
  233. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
  234. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
  235. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
  236. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
  237. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
  238. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
  239. package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -155
  240. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
  241. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
  242. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
  243. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
  244. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
  245. package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
  246. package/src/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
  247. package/src/orchestrator/templates/ai-instructions/claude-skill-api-design.md +0 -62
  248. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +0 -82
  249. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-pat.md +0 -117
  250. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +0 -60
  251. package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +0 -38
  252. package/src/orchestrator/templates/ai-instructions/claude-skill-capture.md +0 -35
  253. package/src/orchestrator/templates/ai-instructions/claude-skill-dashboard.md +0 -121
  254. package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +0 -141
  255. package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +0 -157
  256. package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +0 -446
  257. package/src/orchestrator/templates/ai-instructions/claude-skill-ingest-legacy.md +0 -79
  258. package/src/orchestrator/templates/ai-instructions/claude-skill-mobile-gestures.md +0 -109
  259. package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
  260. package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +0 -320
  261. package/src/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +0 -118
  262. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +0 -203
  263. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +0 -179
  264. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +0 -233
  265. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +0 -226
  266. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +0 -177
  267. package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +0 -118
  268. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
  269. package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
  270. package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -93
  271. package/src/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
  272. package/src/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
  273. package/src/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
  274. package/src/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
  275. package/src/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
  276. package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
  277. package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -155
  278. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +0 -62
  279. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
  280. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +0 -82
  281. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md +0 -117
  282. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +0 -60
  283. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +0 -38
  284. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +0 -35
  285. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md +0 -121
  286. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +0 -141
  287. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +0 -157
  288. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +0 -446
  289. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
  290. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-ingest-legacy.md +0 -79
  291. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
  292. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md +0 -109
  293. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
  294. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
  295. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
  296. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +0 -320
  297. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +0 -118
  298. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +0 -203
  299. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +0 -179
  300. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +0 -233
  301. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +0 -226
  302. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +0 -177
  303. package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +0 -118
  304. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
  305. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
  306. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
  307. /package/dist/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
  308. /package/dist/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
  309. /package/dist/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
  310. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-api-design.md → ai-src/skills/sungen-api-design/SKILL.md} +0 -0
  311. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture.md → ai-src/skills/sungen-capture/SKILL.md} +0 -0
  312. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-mcp.md → ai-src/skills/sungen-capture/mode-figma-mcp.md} +0 -0
  313. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-pat.md → ai-src/skills/sungen-capture/mode-figma-pat.md} +0 -0
  314. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-live.md → ai-src/skills/sungen-capture/mode-live.md} +0 -0
  315. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-local.md → ai-src/skills/sungen-capture/mode-local.md} +0 -0
  316. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-dashboard.md → ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
  317. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-delivery.md → ai-src/skills/sungen-delivery/SKILL.md} +0 -0
  318. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-gherkin-syntax.md → ai-src/skills/sungen-gherkin-syntax/SKILL.md} +0 -0
  319. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-ingest-legacy.md → ai-src/skills/sungen-ingest-legacy/SKILL.md} +0 -0
  320. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-mobile-gestures.md → ai-src/skills/sungen-mobile-gestures/SKILL.md} +0 -0
  321. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
  322. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-review.md → ai-src/skills/sungen-tc-review/SKILL.md} +0 -0
  323. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-test-design-techniques.md → ai-src/skills/sungen-test-design-techniques/SKILL.md} +0 -0
  324. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint.md → ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
  325. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-a-data-entry.md → ai-src/skills/sungen-viewpoint/group-a-data-entry.md} +0 -0
  326. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-b-data-ops.md → ai-src/skills/sungen-viewpoint/group-b-data-ops.md} +0 -0
  327. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-c-data-explore.md → ai-src/skills/sungen-viewpoint/group-c-data-explore.md} +0 -0
  328. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-d-display.md → ai-src/skills/sungen-viewpoint/group-d-display.md} +0 -0
  329. /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-e-identity.md → ai-src/skills/sungen-viewpoint/group-e-identity.md} +0 -0
  330. /package/src/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
  331. /package/src/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
  332. /package/src/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
  333. /package/src/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
  334. /package/src/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
  335. /package/src/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
  336. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md → src/orchestrator/templates/ai-src/skills/sungen-api-design/SKILL.md} +0 -0
  337. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md → src/orchestrator/templates/ai-src/skills/sungen-capture/SKILL.md} +0 -0
  338. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-figma-mcp.md} +0 -0
  339. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-figma-pat.md} +0 -0
  340. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-live.md} +0 -0
  341. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md → src/orchestrator/templates/ai-src/skills/sungen-capture/mode-local.md} +0 -0
  342. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md → src/orchestrator/templates/ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
  343. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md → src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md} +0 -0
  344. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md → src/orchestrator/templates/ai-src/skills/sungen-gherkin-syntax/SKILL.md} +0 -0
  345. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-ingest-legacy.md → src/orchestrator/templates/ai-src/skills/sungen-ingest-legacy/SKILL.md} +0 -0
  346. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md → src/orchestrator/templates/ai-src/skills/sungen-mobile-gestures/SKILL.md} +0 -0
  347. /package/src/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
  348. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md → src/orchestrator/templates/ai-src/skills/sungen-tc-review/SKILL.md} +0 -0
  349. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md → src/orchestrator/templates/ai-src/skills/sungen-test-design-techniques/SKILL.md} +0 -0
  350. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
  351. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-a-data-entry.md} +0 -0
  352. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-b-data-ops.md} +0 -0
  353. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-c-data-explore.md} +0 -0
  354. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-d-display.md} +0 -0
  355. /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/group-e-identity.md} +0 -0
@@ -1,157 +0,0 @@
1
- ---
2
- name: sungen-error-mapping
3
- description: 'Error diagnosis and fix strategy — systematic debugging flow, error patterns, fix priorities. Auto-loaded during run-test.'
4
- user-invocable: false
5
- ---
6
-
7
- ## Diagnosis Flow (before fixing anything)
8
-
9
- **Step 1: Read the error** — extract: error type, element name, expected vs actual, file:line.
10
-
11
- **Step 2: Read error context** — check `test-results/` for the snapshot at failure time. This shows the exact page state when the test failed — more reliable than re-navigating with MCP.
12
-
13
- **Step 3: Compare** — match the failing selector against the snapshot. Ask:
14
- - Does the element exist on the page?
15
- - Does the accessible name match exactly?
16
- - Are there multiple matches (strict mode)?
17
- - Is the element inside an iframe or dialog?
18
- - Is the page in the expected state (correct URL, loaded)?
19
-
20
- Then choose the fix from the patterns below.
21
-
22
- ---
23
-
24
- ## Fix Priority (try in order)
25
-
26
- 1. **Auth issue** — page redirected to login? Fix auth first, everything else is noise
27
- 2. **Element not found** — wrong name/type/value in selectors.yaml. Re-snapshot, copy exact name
28
- 3. **Multiple matches** — add `nth`, `exact: true`, or `scope` to narrow down
29
- 4. **Wrong assertion** — `toHaveText` vs `toHaveValue` mismatch, wrong expected data
30
- 5. **Timing** — SPA not loaded, async content. Add `wait for` step in .feature
31
-
32
- ---
33
-
34
- ## Playwright Errors
35
-
36
- ### Selector errors → fix in `selectors.yaml`
37
-
38
- | Error | Diagnosis | Fix |
39
- |---|---|---|
40
- | strict mode violation | Multiple elements match | Add `nth: 0`, `exact: true`, or more specific `name` |
41
- | Timeout / not found | Element doesn't exist or name wrong | Re-snapshot → copy exact accessible name. Check iframe/dialog scope |
42
- | Element is not an input | Wrong element type targeted | Change `type` or `value` to match actual element |
43
- | not a select | Custom dropdown, not native `<select>` | Set `variant: 'custom'` |
44
- | Frame not found | iframe selector wrong or doesn't exist | Fix `frame` value, verify iframe in snapshot |
45
-
46
- ### Assertion errors → fix in `test-data.yaml` or `.feature`
47
-
48
- | Error | Diagnosis | Fix |
49
- |---|---|---|
50
- | toHaveText mismatch | Expected text differs from actual | Fix value in test-data. If element is input type → change Gherkin type to `field`/`textarea` (triggers `toHaveValue` instead) |
51
- | toHaveValue mismatch | Expected value differs from actual | Fix value in test-data |
52
- | toContainText mismatch | Partial text not found | Fix expected partial text in test-data |
53
- | toBeVisible timeout | Element exists but hidden, or name wrong | Check: is element conditionally visible? Wrong name? Inside dialog? |
54
- | toHaveCount mismatch | Row count differs | Fix expected count in test-data. Verify: is table loaded? Filtered? |
55
-
56
- ### Assertion type rule
57
-
58
- Sungen picks assertion based on element type:
59
- - **Input** (`field`, `textarea`, `search`, `dropdown`, `slider`) → `toHaveValue()`
60
- - **Text** (everything else: `message`, `heading`, `label`, `row`) → `toHaveText()`
61
- - **Partial** (`contains` keyword) → `toContainText()`
62
-
63
- If `toHaveText` fails on an input → the Gherkin step has wrong target type. Fix: change type in `.feature`.
64
-
65
- ---
66
-
67
- ## Table-Specific Errors
68
-
69
- | Error | Diagnosis | Fix |
70
- |---|---|---|
71
- | `tableRow is not defined` | Column assertion without preceding row scope step | Add `User see [Ref] row in [Table] table with {{v}}` before `User see [Col] column with {{v}}` |
72
- | `toHaveText` on cell fails (with columns) | Wrong column index in `columns` config | Re-count columns in snapshot (0-indexed). Fix `index` in selectors.yaml |
73
- | `toBeVisible` on cell fails (no columns) | `filter({ hasText })` didn't match | Check exact cell text in snapshot. Fix value in test-data |
74
- | Row filter matches 0 rows | Filter text doesn't match any row content | Re-snapshot → find actual row text. Fix filter value in test-data |
75
- | Row filter matches multiple rows | Filter text is too generic (matches multiple rows) | Use more specific filter text (unique identifier like email, ID) |
76
- | Table not found | Wrong table name or table not rendered | Re-snapshot → copy exact table accessible name |
77
-
78
- ---
79
-
80
- ## Auth Errors
81
-
82
- | Symptom | Fix |
83
- |---|---|
84
- | Redirect to login page | Auth expired. Ask user to log in manually via MCP browser |
85
- | `storageState` file not found | Ask user to log in manually via MCP browser, then save storage state |
86
- | Most tests timeout on first step | Auth expired — ask user to re-authenticate via MCP browser |
87
- | Page shows home instead of target | SPA + expired auth. Re-authenticate + add `wait for` step |
88
-
89
- **Never use `sungen makeauth`.** Always let the user log in manually via the MCP browser.
90
-
91
- ---
92
-
93
- ## Sungen Compile Errors
94
-
95
- | Error | Fix |
96
- |---|---|
97
- | Unknown step pattern | Rewrite step to match `sungen-gherkin-syntax` patterns |
98
- | Missing selector | Add key to `selectors.yaml` |
99
- | Missing variable | Add key to `test-data.yaml` |
100
- | Invalid selector type | Use: role/testid/placeholder/label/text/locator/page/upload/frame |
101
-
102
- ---
103
-
104
- ## Flow-Specific Errors
105
-
106
- | Error | Diagnosis | Fix |
107
- |---|---|---|
108
- | Navigation timeout between screens | Cross-screen transition takes too long or URL mismatch | Add explicit `wait for page` step between screen transitions in `.feature`. Verify target URL path |
109
- | Selector `"screen:element"` not found | Namespace key missing or wrong format | Ensure colon-namespaced key in `selectors.yaml` is **quoted**: `"login:submit":`. Check screen prefix matches `[Screen:Element]` ref in Gherkin |
110
- | Test data `screen.key` undefined | Phase namespace mismatch | Verify `test-data.yaml` uses dot-namespaced keys: `login.email`, `submission.nominee`. Keys must match `{{screen.key}}` refs in `.feature` |
111
- | State lost between screens | Auth/session expired during multi-screen flow | Ensure all screens in the flow share the same `@auth:role` tag. Check if the app invalidates sessions on navigation |
112
- | Duplicate selector key across screens | Two screens use same element name without namespace | Always use `[Screen:Element]` format in flow `.feature`. Selectors must use `"screen:element":` quoted keys |
113
-
114
- ---
115
-
116
- ## Performance & Infrastructure Errors → Fix in `specs/base.ts`
117
-
118
- All generated `.spec.ts` import from `specs/base.ts` — shared context caching, navigation, overlay cleanup. AI **can and should** tune `base.ts` to match the project.
119
-
120
- | Symptom | Root cause | Fix |
121
- |---|---|---|
122
- | Server 429 (rate limited) | Too many browser contexts | Fix `contextCache` to reuse sessions per `storageState` |
123
- | Tests slow with `--workers=1` | Redundant navigation | Fix goto patch: skip if `currentPath === url` |
124
- | Previous test's modal blocks next | Overlay not cleaned up | Add/improve Escape + backdrop click in cleanup hook |
125
- | All tests fail on first navigation | `page.url()` is `about:blank` | Add try/catch in goto patch |
126
- | Flaky timeouts on SPA pages | Default timeout too short for app | Increase `actionTimeout` / `navigationTimeout` |
127
- | Tests pass individually but fail in batch | Shared state leaking between tests | Isolate context per test or reset state in `beforeEach` |
128
-
129
- ### What AI CAN fix in `base.ts`
130
-
131
- - Timeout tuning (increase for slow APIs, decrease for fast apps)
132
- - Custom overlay/modal dismiss logic (project has unique close patterns)
133
- - Navigation wait strategy (`networkidle` vs `domcontentloaded` vs custom)
134
- - Context caching strategy (per-role, per-session)
135
- - Cookie/localStorage cleanup between tests
136
-
137
- ### What AI should NOT move into `base.ts`
138
-
139
- - Individual selector fixes → belong in `selectors.yaml`
140
- - Test data values → belong in `test-data.yaml`
141
- - Single-test workarounds → belong in the `.spec.ts` directly
142
-
143
- ---
144
-
145
- ## Smart Fix Strategy
146
-
147
- ### When multiple tests fail on the same element
148
- Fix the **root cause once** — don't fix each test individually. Group by selector key, fix selectors.yaml, recompile, re-run batch.
149
-
150
- ### When you're unsure about the fix
151
- **Re-snapshot** — `browser_navigate` to the failing page, take `browser_snapshot`, compare the live state against what the test expects. This is faster than guessing.
152
-
153
- ### When the fix might break other tests
154
- After fixing selectors.yaml, run ALL tests (not just the failing one) to catch regressions from renamed/changed selectors.
155
-
156
- ### When nothing works after 3 attempts
157
- Ask the user. The issue might be: dynamic content, race condition, environment-specific state, or a real application bug.
@@ -1,446 +0,0 @@
1
- ---
2
- name: sungen-gherkin-syntax
3
- description: 'Sungen Gherkin patterns, selector types, and YAML key rules. Auto-loaded when writing .feature, selectors.yaml, or test-data.yaml.'
4
- user-invocable: false
5
- ---
6
-
7
- ## Standard Syntax
8
-
9
- ```
10
- [Keyword] User <Action> [Target Name] <Target Type> <in [Parent Name] <Parent Type>> <with {{Value}}> <is State>
11
- ```
12
-
13
- - **Actor**: Always `User`, always active voice.
14
- - **Value**: `with {{snake_case}}` — never hardcode static data.
15
- - **State**: `is <keyword>` — never use `{{}}` for states.
16
- - **Parent scope**: `in [Parent] parentType` — optional, only when page has 2+ similar blocks needing disambiguation.
17
-
18
- ## Keyword → Action Rules
19
-
20
- ```
21
- GIVEN → is on
22
- WHEN → click · fill · select · press · clear · check · uncheck · hover
23
- [⚠️ wait for — only for Spinner/Modal, minimize usage]
24
- THEN → see
25
- AND → inherits from preceding keyword
26
- ```
27
-
28
- ## Step Patterns (70 patterns)
29
-
30
- ### Setup / Form / Interaction
31
-
32
- ```
33
- User is on [T] page | page with {{v}} | dialog
34
- User fill [T] field | textarea | search | slider | date-picker with {{v}}
35
- User fill [T] uploader with {{f}}
36
- User clear [T] field
37
- User check [T] checkbox | toggle | radio
38
- User uncheck [T] checkbox | toggle
39
- User select [T] dropdown with {{v}}
40
- User click [T] button | tab | column | breadcrumb
41
- User click [T] row with {{v}}
42
- User double click [T] element
43
- User hover [T] icon | row
44
- User drag [T] to [T2]
45
- User expand | collapse [T] row
46
- ```
47
-
48
- **click + with {{Value}} rule**: NO value for static (`button`, `link`, `icon`, `tab`). WITH value only for dynamic lists (`row`, `item`, `card`, `option`).
49
-
50
- ### Alert / Keyboard / Wait / Scroll
51
-
52
- ```
53
- User click [OK | Cancel] alert
54
- User fill [T] alert with {{v}}
55
- User see [message text] alert
56
- User press Escape key | Enter on [T] field
57
- User wait for N seconds | [T] dialog | [T] dialog is STATE | [T] page
58
- User scroll to [T] section
59
- User switch to [T] frame | [main] frame
60
- ```
61
-
62
- > Alert steps must appear BEFORE the action that triggers the dialog.
63
-
64
- ### Assertions (8 patterns → determines Playwright assertion)
65
-
66
- ```
67
- # 1. Visibility: User see [T] type (NEVER add "is visible") | is hidden
68
- # 2. Text (toHaveText): User see [T] message | header | label with {{v}}
69
- # 3. Partial (toContainText): User see [T] text contains {{v}}
70
- # 4. Input (toHaveValue): User see [T] field | dropdown | date-picker | search | slider with {{v}}
71
- # 5. State: User see [T] button is disabled | checkbox is checked | dialog with {{v}} is hidden
72
- # 6. Attribute (toHaveAttribute): User see [T] image | link with {{v}}
73
- # 7. Count: User see [T] row with {{count}}
74
- # 8. Page: User see [T] page
75
- ```
76
-
77
- ### Collection / all-card (P5)
78
-
79
- ```
80
- # Every element's TEXT matches a value (filter correctness, all items belong):
81
- User see all [Result Product Name] text contains {{category_term}}
82
- # Every CONTAINER holds a CHILD element (structural per-card proof — prove "each card has X"):
83
- User see all [Product Card] contain [Product Name]
84
- User see all [Product Card] contain [Add To Cart] button
85
- ```
86
-
87
- Use the all-card form whenever a title claims *every / each* card/row exposes something — a single `User see [Add To Cart] button` does NOT prove "each card" and the harness Claim-Proof gate will flag it.
88
-
89
- ### Table
90
-
91
- ```
92
- User see [Col] column in [Table] table
93
- User see [Ref] row in [Table] table with {{v}}
94
- User see [Ref] row in [Table] table with {{v}} is hidden
95
- User see [Table] table with {{count}} | is empty
96
- User see [Col] column with {{v}}
97
- User click [Act] button in [Table] table with {{v}}
98
- User see [Table] table match data:
99
- | Header1 | Header2 |
100
- | {{value1}} | {{value2}} |
101
- ```
102
-
103
- Row scope: `see [Ref] row in [Table] table with {{v}}` enters scope. Subsequent `see [Col] column with {{v}}` checks cell in that row. Use `table match data:` for multi-row verification.
104
-
105
- ### Database verification (optional Data Driver)
106
-
107
- Read-only DB-state checks. **Prefer named queries** — SQL lives in `qa/screens/<screen>/database/queries.yaml` (reviewed once, parameterized). Invoke with the `@query:<name>` annotation; it binds the result rows to `{{name}}`, then assert with `expect`:
108
-
109
- ```gherkin
110
- @query:active_user # precondition: run query, bind {{active_user}}
111
- @query:orders(buyer={{email}}) # …with explicit param override
112
- Scenario: ...
113
- Then expect {{active_user.count}} is at least {{one}} # ≥1 row
114
- And expect {{active_user.first.status}} is "active" # first row's column
115
- And expect {{orders.count}} is {{expected}} # exact count
116
- And User see [Total] text is {{orders.first.total}} # UI ↔ DB
117
- ```
118
-
119
- Path access on a bound result: `{{q.count}}`/`{{q.length}}`, `{{q.first.col}}`, `{{q.last.col}}`, `{{q[2].col}}`, `{{q.col}}` (= first row's col). `expect A is B` also supports `is at least` / `is at most` / `is not`. Tier-2 declarative (trivial inline, no catalog): `User see [<table>] row where [<col>] is {{v}} [has [<col2>] = "x"]`, `… no row where …`, `… count is {{n}}`. Full grammar + catalog/datasource/secret rules → **Advanced → Database** doc. Only emit DB steps when the project has a `database/` catalog / `datasources.yaml`.
120
-
121
- ### States
122
-
123
- `hidden` `visible` `disabled` `enabled` `checked` `unchecked` `focused` `empty` `loading` `selected` `sorted ascending` `sorted descending`
124
-
125
- ### Element Types
126
-
127
- | Group | Types |
128
- |---|---|
129
- | **Context** | `page` `dialog` `modal` `drawer` `tab` `alert` `overlay` `step` |
130
- | **Input** | `field` `textarea` `search` `dropdown` `option` `checkbox` `radio` `toggle` `uploader` `slider` `date-picker` |
131
- | **Trigger** | `button` `link` `icon` `menuitem` `tag` |
132
- | **Data** | `table` `row` `column` `cell` `list` `item` `card` `section` |
133
- | **Feedback** | `message` `header` `label` `text` `tooltip` `badge` `breadcrumb` `image` |
134
- | **System** | `key` `frame` `spinner` `progressbar` |
135
-
136
- ### Auto-infer (no YAML entry needed)
137
-
138
- Most elements auto-infer from `[Label] type` → `getByRole(type, { name: 'Label' })`. Only add YAML when the accessible name differs, needs `nth`, or needs `testid`. Full auto-infer table → see `sungen-selector-keys` skill.
139
-
140
- **Types requiring YAML entry:** `date-picker`, `uploader`, `overlay`, `frame`, `step` - these have no standard ARIA role and need explicit selectors.
141
-
142
- ## YAML Keys
143
-
144
- `[Reference]` → **lowercase, keep Unicode**: `[Search Content]` → `search content:`, `[Thời gian]` → `thời gian:`
145
-
146
- - Keys use **spaces** (not dots) as word separators
147
- - Same label, different element types → add `--type` suffix
148
- - Same label, nth occurrence → add `--N` suffix
149
- - Target Name > 30 chars → shorten to 1–3 meaningful words
150
-
151
- ## Dynamic Variables (test-data YAML)
152
-
153
- Use `{{$var}}` in test-data YAML for values that must be unique per test run. Resolved at **runtime** by `TestDataLoader` — the compiler passes them through unchanged.
154
-
155
- | Variable | Example | Output |
156
- |---|---|---|
157
- | `{{$timestamp}}` | `"User-{{$timestamp}}"` | `"User-1714000000"` |
158
- | `{{$uuid}}` | `"{{$uuid}}"` | `"a1b2c3d4-..."` |
159
- | `{{$random:min:max}}` | `"{{$random:1:100}}"` | `"42"` |
160
- | `{{$date}}` | `"{{$date}}"` | `"2026-04-24"` |
161
- | `{{$datetime}}` | `"{{$datetime}}"` | `"2026-04-24T10:30:00.000Z"` |
162
-
163
- **Rules:**
164
- - `$timestamp` and `$uuid` → same value across all keys in one `load()` call (stable within a test file)
165
- - `$random` → unique per occurrence (each key gets a different random)
166
- - Resolved once at load time → every `get()` returns the same resolved value
167
- - Use for CRUD flows to avoid data collision between parallel runs
168
-
169
- ```yaml
170
- # test-data/crud-award.yaml
171
- award:
172
- name: "Award-{{$timestamp}}"
173
- email: "test+{{$uuid}}@example.com"
174
- score: "{{$random:1:100}}"
175
- ```
176
-
177
- ## Selectors (priority order)
178
-
179
- | type | value | name | use |
180
- |---|---|---|---|
181
- | `testid` | data-testid | — | when exists |
182
- | `role` | button/heading/link… | accessible name | interactive elements |
183
- | `placeholder` | placeholder text | — | inputs |
184
- | `label` | label text | — | labeled inputs |
185
- | `text` | — | — | static text |
186
- | `locator` | CSS selector | — | last resort |
187
- | `page` | relative URL | — | navigation |
188
- | `upload` | — | — | file inputs |
189
- | `frame` | iframe selector | — | iframes |
190
-
191
- Options: `nth` `exact` `scope` `match` `variant` `frame` `contenteditable` `columns`
192
-
193
- ## Tags
194
-
195
- ### Functional tags (affect code generation)
196
-
197
- | Tag | Effect |
198
- |---|---|
199
- | `@manual` | Skip in generation |
200
- | `@auth:role` | Use auth storage state for role |
201
- | `@no-auth` | Disable inherited auth |
202
- | `@steps:name` | Define reusable step block (base scenario) |
203
- | `@extend:name` | Prepend Given→When from @steps block (skip Then) |
204
- | `@cleanup:overlay` | Auto-cleanup: dismiss dialogs/overlays after each test (cleanupPage) |
205
- | `@cleanup:forms` | Auto-cleanup: clear form fields after each test (cleanupPage) |
206
- | `@cleanup:scroll` | Auto-cleanup: scroll to top after each test (cleanupPage) |
207
- | `@cleanup:storage` | Auto-cleanup: clear sessionStorage after each test (cleanupPage) |
208
- | `@screenshot:on-failure` | Auto-capture screenshot when test fails (base.ts fixture) |
209
- | `@parallel` | Opt-out: fresh page per test instead of serial default (for independent scenarios) |
210
- | `@beforeAll` | Hook: runs once before all tests → `test.beforeAll()` |
211
- | `@afterEach` | Hook: runs after each test → `test.afterEach()` (custom cleanup) |
212
- | `@afterAll` | Hook: runs once after all tests → `test.afterAll()` |
213
- | `@flow` | Mark feature as E2E flow (cross-screen testing) |
214
- | `@cases:dataset` | Data-driven: run the scenario once per row of the `dataset` LIST in test-data → one `test()` per row |
215
- | `@query:name` | Database: run the named query from `database/queries.yaml` (precondition) and bind its rows to `{{name}}`; assert with `expect {{name.count}} …` + path access. Override params `@query:name(p={{v}})`. Repeatable. (Optional Data Driver — see Database verification above) |
216
- | `@api:name` | API: run the named request from `api/apis.yaml` (precondition) and bind the response to `{{name}}`; assert with `expect {{name.status}} …` + path access (`{{name.body.<path>}}`). Override params `@api:name(p={{v}})`. Repeatable. (Optional API Driver) |
217
- | `@concurrent:N` | API idempotency: fire the bound `@api` request N times in parallel, then bind aggregates on the `@api` name — `{{name.ok_count}}` (2xx count) and `{{name.status_counts}}` (status→count map). Assert the exactly-once invariant (`expect {{name.ok_count}} is 1`); pair with `@query` as a DB oracle. Tag order = run order: `@api` (mutate) before `@query` (verify). (Optional API Driver) |
218
- | `@hybrid` | One unit, two capabilities: a signed-in browser session (UI) authorizes the `@api` call — the API request reuses the UI `storageState`. (Optional API + UI Drivers) |
219
-
220
- ### Data-driven scenarios (`@cases`)
221
-
222
- For one test case × many inputs (email/format/boundary validation, decision tables), tag the
223
- scenario `@cases:<dataset>` and reference each row's columns as `{{col}}`. Put the rows as a LIST
224
- in test-data — NOT inline; data stays runtime + env-overlayable.
225
-
226
- ```gherkin
227
- @high @cases:email_validation
228
- Scenario: VP-VAL-001 The email field rejects invalid formats
229
- When User fill [Email] field with {{email}}
230
- Then User see [Login Error] message with {{expected_error}}
231
- ```
232
- ```yaml
233
- # test-data/<screen>.yaml
234
- email_validation:
235
- - { case: "no @", email: "plainaddress", expected_error: "Invalid email" }
236
- - { case: "valid", email: "ok@x.com", expected_error: "" }
237
- ```
238
- An optional `case`/`name`/`label` column labels each run. Each row → its own pass/fail. Prefer
239
- `@cases` over duplicating a scenario per value. (Gherkin `Scenario Outline`/`Examples` is NOT
240
- supported — use `@cases`.)
241
-
242
- ### Pass-through tags (filter at runtime via Playwright --grep)
243
-
244
- Any tag not listed above passes through to Playwright `{ tag: [...] }`. Feature-level tags inherit to all scenarios.
245
-
246
- | Tag | Purpose |
247
- |---|---|
248
- | `@smoke` | Quick sanity check — run after every deploy |
249
- | `@regression` | Full test suite — run nightly or before release |
250
- | `@high` | Priority: must pass — login, auth, core CRUD, primary business flow |
251
- | `@normal` | Priority: important — validation rules, secondary features, search/filter |
252
- | `@low` | Priority: minor/cosmetic — tooltips, hover states, element presence |
253
- | `@auto` | Standard scenario, ready for automation |
254
- | Any custom | e.g., `@sprint-42`, `@team-payment` — any tag works |
255
-
256
- **Assign priority by user impact** (canonical mapping — override only when context differs):
257
-
258
- | Scenario type | Tag |
259
- |---|---|
260
- | Auth redirect / unauthenticated access | `@high` |
261
- | CRUD happy path (create / update / delete — success) | `@high` |
262
- | Core business rule, state transition | `@high` |
263
- | XSS, SQL injection, permission blocked | `@high` |
264
- | Required field error, unique/duplicate constraint | `@high` |
265
- | Format validation (email, phone, date…) | `@normal` |
266
- | Boundary value — inclusive (`<=`, `>=`) → `@high`; standard range → `@normal` | `@normal` |
267
- | Secondary features (search, filter, sort, pagination) | `@normal` |
268
- | Element presence, label, placeholder, tooltip | `@low` |
269
-
270
- **Run filtered:**
271
- ```bash
272
- npx playwright test --grep "@smoke" # only smoke tests
273
- npx playwright test --grep "@high" # only high priority
274
- npx playwright test --grep "@smoke|@high" # smoke OR high
275
- ```
276
-
277
- ### Serial vs Parallel (test execution mode)
278
-
279
- **Default: serial** — `test.describe.serial()` with shared page. Background runs once in `beforeAll`. Fail → skip remaining.
280
-
281
- **`@parallel` opt-out** — `test.describe()` with fresh page per test. Background runs as `beforeEach`. Use when scenarios are truly independent (validation rules, permission tests).
282
-
283
- | Mode | Generated | Page | Background | On fail |
284
- |---|---|---|---|---|
285
- | Serial (default) | `test.describe.serial()` | Shared | `beforeAll` (1 goto) | Skip remaining |
286
- | `@parallel` | `test.describe()` | Fresh per test | `beforeEach` (N goto) | Continue |
287
-
288
- **`@parallel` is required** when a feature has multiple auth groups (e.g., `@auth:user` + `@no-auth` scenarios). Serial mode uses one shared browser context and cannot mix auth roles. The compiler will error if `@parallel` is missing in this case.
289
-
290
- ### `@flow` tag (E2E cross-screen testing)
291
-
292
- `@flow` marks a feature as a **flow** — an E2E journey spanning multiple screens. Flows live in `qa/flows/<name>/` with their own selectors, test-data, and requirements.
293
-
294
- **Key differences from screen tests:**
295
-
296
- | Aspect | Screen (`qa/screens/`) | Flow (`qa/flows/`) |
297
- |---|---|---|
298
- | Scope | Single page | Multiple pages |
299
- | Selectors | `[Element]` → own YAML | `[Screen:Element]` → own YAML (namespaced) |
300
- | Test data | `{{variable}}` | `{{phase.variable}}` (namespaced by phase) |
301
- | Tag | `@auto` / `@smoke` etc. | `@flow` (required at feature level) |
302
- | Multi-domain | N/A | Absolute URL in selector `path:` skips baseURL |
303
-
304
- **Selector namespace format:** `[Screen:Element]` where colon separates screen prefix from element name. The YAML key is `"screen:element"` (quoted, lowercase).
305
-
306
- ```gherkin
307
- # Feature file
308
- When User fill [Login:Email] field with {{login.email}}
309
- And User click [Login:Submit] button
310
- Then User see [Dashboard] page
311
- When User click [Dashboard:Awards] link
312
- ```
313
-
314
- ```yaml
315
- # selectors.yaml — keys are namespaced, quoted due to colon
316
- "login:email":
317
- type: 'testid'
318
- value: 'email-input'
319
-
320
- "login:submit":
321
- type: 'role'
322
- value: 'button'
323
- name: 'Login'
324
-
325
- dashboard:
326
- type: 'page'
327
- value: '/dashboard'
328
-
329
- "dashboard:awards":
330
- type: 'role'
331
- value: 'link'
332
- name: 'Awards'
333
- ```
334
-
335
- **Flow structure:**
336
- - `Background:` — set starting page only (e.g., `Given User is on [Login] page`)
337
- - Each `Scenario:` — one phase/step of the flow (login, navigate, submit, etc.)
338
- - Page navigation between scenarios uses `[Screen] page` references
339
-
340
- **CLI:** `sungen add-flow --flow <name>`, `sungen generate --flow <name>`, `sungen generate --all` (includes flows)
341
-
342
- ### @extend behavior
343
-
344
- - Tool executes **only Given→When** of `@steps` scenario (skips Then)
345
- - The `Given` in `@extend` scenario is the **entry assertion** (confirms state after base steps)
346
- - **Entry assertion MUST use `Given User is on [X] type`** — NEVER `Given User see [X] type`
347
- - `Given` keyword ONLY allows `is on` action. `see` = `Then` only.
348
- - If `@steps` scenario fails, `@extend` scenario is **skipped**
349
- - Name format: `snake_case` or `kebab-case` with module prefix: `@steps:kudos__open_modal`
350
-
351
- ## Common Syntax Errors
352
-
353
- | Error | Wrong | Correct |
354
- |---|---|---|
355
- | Wrong keyword | `Given User click [T] button` | `When User click [T] button` |
356
- | `see` after Given | `Given User see [T] heading with {{v}}` | `Then User see [T] heading with {{v}}` (or `Given User is on [T] page` for entry assertion) |
357
- | Name ≠ step type | Scenario name says "modal" but step uses `dialog` | Use the **same element type** in both: "...dialog opens" + `[X] dialog` |
358
- | Wrong action for type | `When User click [T] checkbox` | `When User check [T] checkbox` |
359
- | press wrong target | `When User press [Submit] button` | `When User press Enter key` |
360
- | uncheck radio | `When User uncheck [Male] radio` | `When User check [Female] radio` |
361
- | Hardcode data | `with {{admin@mail.com}}` | `with {{invalid_email}}` |
362
- | Missing `is` for state | `with {{text}} hidden` | `with {{text}} is hidden` |
363
- | State as value | `with {{disabled}}` | `is disabled` |
364
- | Missing target type | `fill [email] with {{v}}` | `fill [email] field with {{v}}` |
365
- | Background with scope | `Background: ... And User is on [X] dialog` | Use `@steps` + `@extend` for scope-dependent flows |
366
- | `is on` after When | `When ... And User is on [X] dialog` | `And User see [X] dialog` or separate Given |
367
- | Literal URL navigate | `User navigate to "/dashboard"` | `User is on [Dashboard] page` (add page selector in `selectors.yaml`) |
368
-
369
- ## Background vs @steps/@extend
370
-
371
- Both `Background` and `@steps`/`@extend` are valid — they serve different purposes.
372
-
373
- | Pattern | Use when | Generates |
374
- |---|---|---|
375
- | `Background` | Simple shared setup (navigate to page) | `test.beforeEach()` |
376
- | `@steps`/`@extend` | Complex reusable flows with scope (dialog, frame) | Inline merged steps in `test()` |
377
-
378
- **Use `Background` for simple navigation:**
379
- ```gherkin
380
- Background:
381
- Given User is on [Dashboard] page
382
-
383
- Scenario: View stats
384
- Then User see [Revenue Chart] section
385
- ```
386
-
387
- **Use `@steps`/`@extend` when scope matters (dialog, frame):**
388
- ```gherkin
389
- @steps:open_modal
390
- Scenario: Open modal
391
- Given User is on [Kudos] page
392
- When User click [Open] button
393
- Then User see [Modal] dialog
394
-
395
- @extend:open_modal
396
- Scenario: VP-UI-001 Title visible
397
- Given User is on [Modal] dialog
398
- Then User see [Title] heading
399
- ```
400
-
401
- **Avoid `Background` with scope-dependent steps** — `When` + `And User is on [X] dialog` creates keyword mismatch (`is on` = Given, not When). Use `@steps`/`@extend` instead.
402
-
403
- ## Hooks & Cleanup
404
-
405
- Two layers for test lifecycle management. Prefer `@cleanup:*` tags (Layer 1) — they work with base.ts automatically. Use hook scenarios (Layer 2) only for custom logic.
406
-
407
- ### Layer 1: `@cleanup:*` tags (automatic via base.ts)
408
-
409
- Feature-level tags that activate cleanup fixtures in base.ts. No Gherkin steps needed.
410
-
411
- ```gherkin
412
- @auth:admin
413
- @cleanup:overlay
414
- @cleanup:forms
415
- Feature: User Management
416
- Path: /users
417
-
418
- Background:
419
- Given User is on [User Management] page
420
-
421
- Scenario: Create user shows form
422
- When User click [Add User] button
423
- Then User see [Create User] dialog
424
-
425
- Scenario: Search user by name
426
- When User fill [Search] field with {{search_name}}
427
- Then User see [User Row] row
428
- ```
429
-
430
- | Tag | What base.ts does after each test |
431
- |---|---|
432
- | `@cleanup:overlay` | Press Escape, click body, dismiss fixed overlays |
433
- | `@cleanup:forms` | Clear all input/textarea fields, reset selects |
434
- | `@cleanup:scroll` | Scroll to top of page |
435
- | `@cleanup:storage` | Clear sessionStorage |
436
-
437
- ### Layer 2: `@afterEach` scenario (custom cleanup)
438
-
439
- Only when `@cleanup:*` tags aren't enough — feature-specific logic.
440
-
441
- ### Layer 3: `@beforeAll` / `@afterAll` (optional)
442
-
443
- For one-time setup/teardown.
444
-
445
- **Rendering order in `.spec.ts`:**
446
- `test.describe` → `test.use(storageState)` → `test.use(autoCleanup)` → `test.beforeAll` → `test.beforeEach` → `test.afterEach` → `test.afterAll` → `test()` blocks
@@ -1,79 +0,0 @@
1
- ---
2
- name: sungen-ingest-legacy
3
- description: 'Import a legacy manual testcase suite from Google Sheets (multi-tab) or a local file into Sungen — fetch via MCP, then sungen ingest. Use when the user wants to convert/evaluate an existing manual testcase spreadsheet.'
4
- user-invocable: true
5
- ---
6
-
7
- # sungen-ingest-legacy
8
-
9
- Bring an existing **manual testcase workbook** into Sungen for evaluation + conversion. The
10
- fetch (Google login + pick file) is done here via MCP; the parsing/audit is deterministic
11
- (`sungen ingest`). **Security:** the workbook is the user's project data — read it on
12
- consent, keep the output in their project, never upload or commit the content.
13
-
14
- ## Flow
15
-
16
- 1. **Locate the source.**
17
- - **Google Sheets (recommended):** use the Google Drive MCP. Authenticate if needed, then
18
- `search_files` / list to find the workbook; confirm the file with the user.
19
- - **Local:** if the user points to a `.xlsx`/`.csv`, skip to step 4.
20
-
21
- 2. **List the tabs.** Read the workbook's sheet/tab names (Drive MCP file metadata or a values
22
- read). A legacy workbook usually has **many** tabs — some are testcases, some are
23
- viewpoint/UI matrices.
24
-
25
- 3. **Assemble a JSON sheet-bundle.** For each tab, read its cell values (a 2-D array of
26
- strings) and write a local bundle in the user project (e.g.
27
- `qa/screens/<screen>/requirements/legacy/bundle.json`):
28
- ```json
29
- { "source": "<workbook name>", "sheets": [ { "name": "<tab>", "rows": [["TC ID","Page",…],["TC-01",…]] } ] }
30
- ```
31
- Record only the **source link** in `requirements/legacy/source.yaml` — never the content.
32
-
33
- 4. **Classify the tabs.** Run:
34
- ```bash
35
- sungen ingest --legacy <bundle.json|file.xlsx|file.csv> --list-sheets
36
- ```
37
- It prints each tab + detected type (`testcase` / `viewpoint-matrix` / `ui-checklist`).
38
-
39
- 5. **Confirm which tabs to ingest.** Use `AskUserQuestion` to let the user pick the
40
- **testcase** tabs (matrix/UI tabs feed the viewpoint layer later, not the inventory).
41
-
42
- 6. **Ingest + reconcile.**
43
- ```bash
44
- sungen ingest --legacy <source> --screen <screen> --sheets "<Tab A>,<Tab B>" --emit-gherkin
45
- ```
46
- Produces: `inventory.json` (+ baseline audit), `*.legacy-draft.feature` + `legacy-trace.json`
47
- (parity: `@legacy:<id>` per scenario), and `test-viewpoint.draft.md` with **blind-spots**
48
- (catalog-expected viewpoints the legacy suite lacks).
49
-
50
- 7. **Hand off to quality.** Tell the user the next step is `/sungen:create-test <screen>` —
51
- it discovers + refines the draft into real `[Reference]` steps and fills the blind-spots;
52
- then `sungen audit <screen>` gates quality. A 1:1 convert is NOT the deliverable; the
53
- harness raises the legacy floor to catalog quality.
54
-
55
- ## Governance block (important)
56
-
57
- Many orgs mark confidential files as **"ineligible for generative AI contexts"** — the
58
- Google Drive MCP will then **refuse** to read the file (metadata + download both error).
59
- This is the org's DLP policy, not a bug, and it is the *expected* outcome for a
60
- confidential testcase suite. When you hit it, **do not retry** — fall back:
61
-
62
- > "This sheet is restricted by your org's data policy, so I can't read it through the
63
- > AI connector. Two ways to proceed, both running as **you**, not AI:
64
- > (1) `sungen ingest --gsheet <url>` — fetches under your own Google identity
65
- > (read-only; Viewer/Commenter is enough). It offers to install `googleapis`
66
- > and to open the Google login in your browser (pick your account), then
67
- > retries automatically. Needs the gcloud SDK for the browser login.
68
- > (2) Export it manually (**File → Download → Microsoft Excel `.xlsx`**) and I'll run
69
- > `sungen ingest --legacy <file>.xlsx`."
70
-
71
- The local-file path is deterministic and **never sends the content through AI** — the
72
- correct, governance-compliant channel for confidential data. The MCP auto-pick is only
73
- for files the org does *not* restrict.
74
-
75
- ## Notes
76
- - Multiple local CSVs (one per tab) also work: `--legacy tab1.csv tab2.csv …`.
77
- - Re-run only re-fetches when the user asks; otherwise reuse the saved bundle.
78
- - Do not invent testcases. Only ingest what the workbook contains; the *augmentation*
79
- (blind-spots) happens in `/sungen:create-test`, flagged for human review.