@sun-asterisk/sungen 3.2.2-beta.9 → 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.
- package/dist/capabilities/discover.d.ts.map +1 -1
- package/dist/capabilities/discover.js +26 -3
- package/dist/capabilities/discover.js.map +1 -1
- package/dist/cli/commands/add-flow.d.ts.map +1 -1
- package/dist/cli/commands/add-flow.js +2 -0
- package/dist/cli/commands/add-flow.js.map +1 -1
- package/dist/cli/commands/add.d.ts.map +1 -1
- package/dist/cli/commands/add.js +4 -0
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/capability.d.ts.map +1 -1
- package/dist/cli/commands/capability.js +61 -0
- package/dist/cli/commands/capability.js.map +1 -1
- package/dist/cli/commands/delivery.d.ts.map +1 -1
- package/dist/cli/commands/delivery.js +89 -2
- package/dist/cli/commands/delivery.js.map +1 -1
- package/dist/cli/commands/eval.js +3 -3
- package/dist/cli/commands/eval.js.map +1 -1
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/generate.js +2 -1
- package/dist/cli/commands/generate.js.map +1 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +32 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/journey.d.ts.map +1 -1
- package/dist/cli/commands/journey.js +24 -2
- package/dist/cli/commands/journey.js.map +1 -1
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +10 -3
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/dashboard/snapshot-builder.d.ts.map +1 -1
- package/dist/dashboard/snapshot-builder.js +10 -1
- package/dist/dashboard/snapshot-builder.js.map +1 -1
- package/dist/exporters/csv-exporter.d.ts.map +1 -1
- package/dist/exporters/csv-exporter.js +3 -1
- package/dist/exporters/csv-exporter.js.map +1 -1
- package/dist/exporters/json-exporter.js +3 -1
- package/dist/exporters/json-exporter.js.map +1 -1
- package/dist/exporters/mobile-app-id.d.ts +22 -0
- package/dist/exporters/mobile-app-id.d.ts.map +1 -0
- package/dist/exporters/mobile-app-id.js +37 -0
- package/dist/exporters/mobile-app-id.js.map +1 -0
- package/dist/exporters/spec-parser.d.ts.map +1 -1
- package/dist/exporters/spec-parser.js +6 -2
- package/dist/exporters/spec-parser.js.map +1 -1
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts +3 -0
- package/dist/generators/test-generator/adapters/adapter-interface.d.ts.map +1 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
- package/dist/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
- package/dist/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
- package/dist/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
- package/dist/generators/test-generator/code-generator.d.ts.map +1 -1
- package/dist/generators/test-generator/code-generator.js +48 -9
- package/dist/generators/test-generator/code-generator.js.map +1 -1
- package/dist/generators/test-generator/template-engine.d.ts +3 -0
- package/dist/generators/test-generator/template-engine.d.ts.map +1 -1
- package/dist/generators/test-generator/template-engine.js +11 -1
- package/dist/generators/test-generator/template-engine.js.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts +11 -1
- package/dist/generators/test-generator/utils/selector-resolver.d.ts.map +1 -1
- package/dist/generators/test-generator/utils/selector-resolver.js +33 -0
- package/dist/generators/test-generator/utils/selector-resolver.js.map +1 -1
- package/dist/harness/audit.d.ts.map +1 -1
- package/dist/harness/audit.js +8 -1
- package/dist/harness/audit.js.map +1 -1
- package/dist/harness/catalog/universal-viewpoints.yaml +15 -0
- package/dist/harness/eval/skill-lint.d.ts +3 -3
- package/dist/harness/eval/skill-lint.d.ts.map +1 -1
- package/dist/harness/eval/skill-lint.js +88 -68
- package/dist/harness/eval/skill-lint.js.map +1 -1
- package/dist/harness/journey.d.ts +37 -1
- package/dist/harness/journey.d.ts.map +1 -1
- package/dist/harness/journey.js +146 -19
- package/dist/harness/journey.js.map +1 -1
- package/dist/harness/quality-gates.d.ts +13 -0
- package/dist/harness/quality-gates.d.ts.map +1 -1
- package/dist/harness/quality-gates.js +23 -0
- package/dist/harness/quality-gates.js.map +1 -1
- package/dist/harness/sensors.d.ts +1 -1
- package/dist/harness/sensors.d.ts.map +1 -1
- package/dist/harness/sensors.js +32 -9
- package/dist/harness/sensors.js.map +1 -1
- package/dist/orchestrator/ai-rules-updater.d.ts +11 -3
- package/dist/orchestrator/ai-rules-updater.d.ts.map +1 -1
- package/dist/orchestrator/ai-rules-updater.js +44 -180
- package/dist/orchestrator/ai-rules-updater.js.map +1 -1
- package/dist/orchestrator/ai-skills/adapters.d.ts +28 -0
- package/dist/orchestrator/ai-skills/adapters.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/adapters.js +34 -0
- package/dist/orchestrator/ai-skills/adapters.js.map +1 -0
- package/dist/orchestrator/ai-skills/build.d.ts +10 -0
- package/dist/orchestrator/ai-skills/build.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/build.js +128 -0
- package/dist/orchestrator/ai-skills/build.js.map +1 -0
- package/dist/orchestrator/ai-skills/cap-stripper.d.ts +27 -0
- package/dist/orchestrator/ai-skills/cap-stripper.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/cap-stripper.js +78 -0
- package/dist/orchestrator/ai-skills/cap-stripper.js.map +1 -0
- package/dist/orchestrator/ai-skills/commands.d.ts +22 -0
- package/dist/orchestrator/ai-skills/commands.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/commands.js +109 -0
- package/dist/orchestrator/ai-skills/commands.js.map +1 -0
- package/dist/orchestrator/ai-skills/generator.d.ts +23 -0
- package/dist/orchestrator/ai-skills/generator.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/generator.js +79 -0
- package/dist/orchestrator/ai-skills/generator.js.map +1 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.d.ts +2 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.js +183 -0
- package/dist/orchestrator/ai-skills/golden-skills.test.js.map +1 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.d.ts +8 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.js +28 -0
- package/dist/orchestrator/ai-skills/resolve-assistants.js.map +1 -0
- package/dist/orchestrator/ai-skills/writer.d.ts +15 -0
- package/dist/orchestrator/ai-skills/writer.d.ts.map +1 -0
- package/dist/orchestrator/ai-skills/writer.js +129 -0
- package/dist/orchestrator/ai-skills/writer.js.map +1 -0
- package/dist/orchestrator/flow-manager.d.ts +11 -0
- package/dist/orchestrator/flow-manager.d.ts.map +1 -1
- package/dist/orchestrator/flow-manager.js +147 -29
- package/dist/orchestrator/flow-manager.js.map +1 -1
- package/dist/orchestrator/mobile-runtime-scaffolder.d.ts +59 -0
- package/dist/orchestrator/mobile-runtime-scaffolder.d.ts.map +1 -0
- package/dist/orchestrator/mobile-runtime-scaffolder.js +298 -0
- package/dist/orchestrator/mobile-runtime-scaffolder.js.map +1 -0
- package/dist/orchestrator/project-initializer.d.ts +44 -7
- package/dist/orchestrator/project-initializer.d.ts.map +1 -1
- package/dist/orchestrator/project-initializer.js +147 -79
- package/dist/orchestrator/project-initializer.js.map +1 -1
- package/dist/orchestrator/screen-manager.d.ts +30 -0
- package/dist/orchestrator/screen-manager.d.ts.map +1 -1
- package/dist/orchestrator/screen-manager.js +205 -22
- package/dist/orchestrator/screen-manager.js.map +1 -1
- package/dist/orchestrator/templates/ai-src/README.md +58 -0
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -5
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → dist/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → dist/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
- package/dist/orchestrator/templates/ai-src/commands/design.md +29 -0
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → dist/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
- package/{src/orchestrator/templates/ai-instructions/claude-cmd-review.md → dist/orchestrator/templates/ai-src/commands/review.md} +57 -2
- package/dist/orchestrator/templates/{ai-instructions/claude-cmd-run-test.md → ai-src/commands/run-test.md} +116 -8
- package/dist/orchestrator/templates/ai-src/config/codex.md +8 -0
- package/{src/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → dist/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
- package/dist/orchestrator/templates/{ai-instructions/github-skill-sungen-error-mapping.md → ai-src/skills/sungen-error-mapping/SKILL.md} +31 -10
- package/{src/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → dist/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
- package/{src/orchestrator/templates/ai-instructions/claude-skill-locale.md → dist/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
- 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
- package/{src/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md → dist/orchestrator/templates/ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
- package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
- package/dist/orchestrator/templates/playwright.config.ts +7 -4
- package/package.json +3 -3
- package/src/capabilities/discover.ts +29 -3
- package/src/cli/commands/add-flow.ts +2 -0
- package/src/cli/commands/add.ts +4 -0
- package/src/cli/commands/capability.ts +64 -1
- package/src/cli/commands/delivery.ts +89 -2
- package/src/cli/commands/eval.ts +3 -3
- package/src/cli/commands/generate.ts +2 -1
- package/src/cli/commands/init.ts +50 -3
- package/src/cli/commands/journey.ts +20 -3
- package/src/cli/commands/update.ts +14 -4
- package/src/dashboard/snapshot-builder.ts +10 -1
- package/src/exporters/csv-exporter.ts +3 -1
- package/src/exporters/json-exporter.ts +3 -1
- package/src/exporters/mobile-app-id.ts +34 -0
- package/src/exporters/spec-parser.ts +6 -2
- package/src/generators/test-generator/adapters/adapter-interface.ts +3 -0
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/scroll-action.hbs +7 -4
- package/src/generators/test-generator/adapters/appium/templates/steps/actions/toggle-action.hbs +20 -3
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/checked-assertion.hbs +4 -1
- package/src/generators/test-generator/adapters/appium/templates/steps/assertions/not-checked-assertion.hbs +4 -1
- package/src/generators/test-generator/adapters/appium/templates/test-file.hbs +3 -0
- package/src/generators/test-generator/code-generator.ts +49 -9
- package/src/generators/test-generator/template-engine.ts +14 -1
- package/src/generators/test-generator/utils/selector-resolver.ts +51 -1
- package/src/harness/audit.ts +9 -2
- package/src/harness/catalog/universal-viewpoints.yaml +15 -0
- package/src/harness/eval/skill-lint.ts +71 -60
- package/src/harness/journey.ts +167 -19
- package/src/harness/quality-gates.ts +20 -0
- package/src/harness/sensors.ts +25 -8
- package/src/orchestrator/ai-rules-updater.ts +35 -197
- package/src/orchestrator/ai-skills/adapters.ts +52 -0
- package/src/orchestrator/ai-skills/build.ts +103 -0
- package/src/orchestrator/ai-skills/cap-stripper.ts +85 -0
- package/src/orchestrator/ai-skills/commands.ts +112 -0
- package/src/orchestrator/ai-skills/generator.ts +47 -0
- package/src/orchestrator/ai-skills/golden-skills.test.ts +124 -0
- package/src/orchestrator/ai-skills/resolve-assistants.ts +18 -0
- package/src/orchestrator/ai-skills/writer.ts +92 -0
- package/src/orchestrator/flow-manager.ts +165 -29
- package/src/orchestrator/mobile-runtime-scaffolder.ts +277 -0
- package/src/orchestrator/project-initializer.ts +159 -86
- package/src/orchestrator/screen-manager.ts +237 -22
- package/src/orchestrator/templates/ai-src/README.md +58 -0
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-flow.md → ai-src/commands/add-flow.md} +63 -2
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-add-screen.md → ai-src/commands/add-screen.md} +171 -6
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-create-test.md → ai-src/commands/create-test.md} +118 -5
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-dashboard.md → src/orchestrator/templates/ai-src/commands/dashboard.md} +25 -3
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-delivery.md → src/orchestrator/templates/ai-src/commands/delivery.md} +67 -3
- package/src/orchestrator/templates/ai-src/commands/design.md +29 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-feedback.md → src/orchestrator/templates/ai-src/commands/feedback.md} +34 -3
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-locale.md → ai-src/commands/locale.md} +56 -4
- package/{dist/orchestrator/templates/ai-instructions/claude-cmd-review.md → src/orchestrator/templates/ai-src/commands/review.md} +57 -2
- package/src/orchestrator/templates/{ai-instructions/claude-cmd-run-test.md → ai-src/commands/run-test.md} +116 -8
- package/src/orchestrator/templates/ai-src/config/codex.md +8 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-capture-mobile.md → src/orchestrator/templates/ai-src/skills/sungen-capture-mobile/SKILL.md} +11 -0
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md → src/orchestrator/templates/ai-src/skills/sungen-error-mapping/SKILL.md} +31 -10
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-harness-audit.md → src/orchestrator/templates/ai-src/skills/sungen-harness-audit/SKILL.md} +5 -5
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-locale.md → src/orchestrator/templates/ai-src/skills/sungen-locale/SKILL.md} +275 -3
- 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
- package/{dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix-mobile.md → src/orchestrator/templates/ai-src/skills/sungen-selector-fix-mobile/SKILL.md} +5 -0
- package/src/orchestrator/templates/{ai-instructions/claude-skill-tc-generation.md → ai-src/skills/sungen-tc-generation/SKILL.md} +5 -0
- package/src/orchestrator/templates/playwright.config.ts +7 -4
- package/dist/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
- package/dist/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -94
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
- package/dist/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -158
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
- package/dist/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
- package/src/orchestrator/templates/ai-instructions/claude-cmd-design.md +0 -12
- package/src/orchestrator/templates/ai-instructions/claude-skill-api-design.md +0 -62
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-mcp.md +0 -82
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-figma-pat.md +0 -117
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-live.md +0 -60
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture-mode-local.md +0 -38
- package/src/orchestrator/templates/ai-instructions/claude-skill-capture.md +0 -35
- package/src/orchestrator/templates/ai-instructions/claude-skill-dashboard.md +0 -121
- package/src/orchestrator/templates/ai-instructions/claude-skill-delivery.md +0 -141
- package/src/orchestrator/templates/ai-instructions/claude-skill-error-mapping.md +0 -176
- package/src/orchestrator/templates/ai-instructions/claude-skill-gherkin-syntax.md +0 -446
- package/src/orchestrator/templates/ai-instructions/claude-skill-ingest-legacy.md +0 -79
- package/src/orchestrator/templates/ai-instructions/claude-skill-mobile-gestures.md +0 -109
- package/src/orchestrator/templates/ai-instructions/claude-skill-selector-fix.md +0 -347
- package/src/orchestrator/templates/ai-instructions/claude-skill-tc-review.md +0 -320
- package/src/orchestrator/templates/ai-instructions/claude-skill-test-design-techniques.md +0 -118
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-a-data-entry.md +0 -203
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-b-data-ops.md +0 -179
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-c-data-explore.md +0 -233
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-d-display.md +0 -226
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint-group-e-identity.md +0 -177
- package/src/orchestrator/templates/ai-instructions/claude-skill-viewpoint.md +0 -118
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-flow.md +0 -86
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-add-screen.md +0 -131
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-create-test.md +0 -94
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-dashboard.md +0 -65
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-delivery.md +0 -83
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-design.md +0 -13
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-feedback.md +0 -24
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-locale.md +0 -70
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-review.md +0 -38
- package/src/orchestrator/templates/ai-instructions/copilot-cmd-run-test.md +0 -158
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-api-design.md +0 -62
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mobile.md +0 -184
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-mcp.md +0 -82
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-figma-pat.md +0 -117
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-live.md +0 -60
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture-mode-local.md +0 -38
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md +0 -35
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md +0 -121
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md +0 -141
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-error-mapping.md +0 -176
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-gherkin-syntax.md +0 -446
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-harness-audit.md +0 -85
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-ingest-legacy.md +0 -79
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-locale.md +0 -291
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-mobile-gestures.md +0 -109
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-fix-mobile.md +0 -316
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-selector-keys.md +0 -221
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-generation.md +0 -617
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-tc-review.md +0 -320
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-test-design-techniques.md +0 -118
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-a-data-entry.md +0 -203
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-b-data-ops.md +0 -179
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-c-data-explore.md +0 -233
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-d-display.md +0 -226
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint-group-e-identity.md +0 -177
- package/src/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md +0 -118
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-api-design.md → ai-src/skills/sungen-api-design/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture.md → ai-src/skills/sungen-capture/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-mcp.md → ai-src/skills/sungen-capture/mode-figma-mcp.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-figma-pat.md → ai-src/skills/sungen-capture/mode-figma-pat.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-live.md → ai-src/skills/sungen-capture/mode-live.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-capture-mode-local.md → ai-src/skills/sungen-capture/mode-local.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-dashboard.md → ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-delivery.md → ai-src/skills/sungen-delivery/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-gherkin-syntax.md → ai-src/skills/sungen-gherkin-syntax/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-ingest-legacy.md → ai-src/skills/sungen-ingest-legacy/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-mobile-gestures.md → ai-src/skills/sungen-mobile-gestures/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-tc-review.md → ai-src/skills/sungen-tc-review/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-test-design-techniques.md → ai-src/skills/sungen-test-design-techniques/SKILL.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint.md → ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
- /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
- /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
- /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
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-d-display.md → ai-src/skills/sungen-viewpoint/group-d-display.md} +0 -0
- /package/dist/orchestrator/templates/{ai-instructions/claude-skill-viewpoint-group-e-identity.md → ai-src/skills/sungen-viewpoint/group-e-identity.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-challenge.md → ai-src/agents/challenge.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-discovery.md → ai-src/agents/discovery.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-generator.md → ai-src/agents/generator.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-agent-reviewer.md → ai-src/agents/reviewer.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/claude-config.md → ai-src/config/claude.md} +0 -0
- /package/src/orchestrator/templates/{ai-instructions/copilot-config.md → ai-src/config/copilot.md} +0 -0
- /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
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-capture.md → src/orchestrator/templates/ai-src/skills/sungen-capture/SKILL.md} +0 -0
- /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
- /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
- /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
- /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
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-dashboard.md → src/orchestrator/templates/ai-src/skills/sungen-dashboard/SKILL.md} +0 -0
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-delivery.md → src/orchestrator/templates/ai-src/skills/sungen-delivery/SKILL.md} +0 -0
- /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
- /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
- /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
- /package/src/orchestrator/templates/{ai-instructions/claude-skill-selector-keys.md → ai-src/skills/sungen-selector-keys/SKILL.md} +0 -0
- /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
- /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
- /package/{dist/orchestrator/templates/ai-instructions/github-skill-sungen-viewpoint.md → src/orchestrator/templates/ai-src/skills/sungen-viewpoint/SKILL.md} +0 -0
- /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
- /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
- /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
- /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
- /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,184 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sungen-capture-mobile
|
|
3
|
-
description: 'Capture a live mobile app screen via Appium MCP — locator tree + screenshot for visual context. Auto-loaded by create-test when the screen is @platform:mobile/android/ios.'
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Purpose
|
|
8
|
-
|
|
9
|
-
Launch a mobile app on a device/emulator, capture **one locator tree** (`generate_locators`) and **one screenshot**, and save them as visual context for test generation. The mobile analogue of `sungen-capture-live` — same job, Appium MCP instead of Playwright MCP.
|
|
10
|
-
|
|
11
|
-
Use when the target is a native/Flutter/React-Native app (`@platform:android` or `@platform:ios`) running on a connected device or emulator.
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## Prerequisites
|
|
16
|
-
|
|
17
|
-
- `appium-mcp` connected (see `/mcp`). It runs Appium **embedded** — no separate server needed.
|
|
18
|
-
- A device/emulator booted: `adb devices` shows one for Android; a Simulator for iOS.
|
|
19
|
-
- The app **installed** on the device (`adb install -r <app>.apk` for Android).
|
|
20
|
-
- The screen's `Path:` (in `<screen>/features/*.feature` or `spec.md`) gives the app entry as
|
|
21
|
-
`<appPackage>/<appActivity>` (Android) or bundleId (iOS), e.g. `com.kngroup.media.converter/.MainActivity`.
|
|
22
|
-
|
|
23
|
-
---
|
|
24
|
-
|
|
25
|
-
## Steps
|
|
26
|
-
|
|
27
|
-
### 1. Resolve target app + entry
|
|
28
|
-
|
|
29
|
-
Resolve in this order:
|
|
30
|
-
1. `Path:` line in the feature / `App ID` in `spec.md` → split into `appPackage` + `appActivity`.
|
|
31
|
-
A dual-id Path (`<pkg>/<activity> | <iosBundleId>`) → take the part for the OS you are exploring
|
|
32
|
-
(left of `|` = Android pkg/activity, right = iOS bundle id).
|
|
33
|
-
2. If missing → ask the user: *"What is the appPackage/appActivity (Android) or bundleId (iOS)?"*
|
|
34
|
-
3. **Navigation recipe** — read the feature's `Background:` (the in-app web-path analog). Line 1
|
|
35
|
-
`Given User is on [Home] screen` is the launcher/landing screen the app opens on; each following
|
|
36
|
-
`When/And User tap [...]` (or gesture) is one hop toward the target screen. You will **replay**
|
|
37
|
-
these in step 4.5 so you scan the screen this feature targets — not the launcher. An anchor-only
|
|
38
|
-
Background (no nav steps) ⇒ the target IS the launcher screen ⇒ no navigation needed.
|
|
39
|
-
|
|
40
|
-
### 2. Select device
|
|
41
|
-
|
|
42
|
-
`select_device` with `platform: android` (or `ios`). If exactly one device, it auto-selects.
|
|
43
|
-
If several, list them and ask the user which `deviceUdid`.
|
|
44
|
-
|
|
45
|
-
### 3. Create the session
|
|
46
|
-
|
|
47
|
-
`appium_session_management` `action=create`, `platform=android`, capabilities (JSON string):
|
|
48
|
-
```
|
|
49
|
-
appium:appPackage, appium:appActivity, appium:udid,
|
|
50
|
-
appium:noReset=true, appium:autoGrantPermissions=true, appium:newCommandTimeout=300
|
|
51
|
-
```
|
|
52
|
-
For iOS, call `prepare_ios_simulator` first, then create with `appium:bundleId`.
|
|
53
|
-
|
|
54
|
-
### 4. ⚠️ Wait for the screen to actually render
|
|
55
|
-
|
|
56
|
-
**This is the #1 gotcha for Flutter / RN apps.** Right after launch the app often shows a blank
|
|
57
|
-
splash — and the locator tree will contain **zero usable elements** (just an empty `FrameLayout`).
|
|
58
|
-
Do **not** capture yet. Take a quick `appium_screenshot`; if it's blank/splash, wait and re-check
|
|
59
|
-
until real content is drawn. Only then capture. (A Flutter app on a loading screen looks "invisible"
|
|
60
|
-
to Appium; the same app on a rendered screen exposes its full Semantics tree.)
|
|
61
|
-
|
|
62
|
-
### 4.5. ⚠️ Navigate to the target screen (replay the navigation recipe)
|
|
63
|
-
|
|
64
|
-
**This is what makes capture land on the RIGHT screen** — the mobile equivalent of `page.goto(url)`
|
|
65
|
-
on web. After the launcher screen has rendered, replay the `Background:` nav steps so Appium ends up
|
|
66
|
-
on the screen this feature targets, *then* capture there.
|
|
67
|
-
|
|
68
|
-
For each nav step **after** the `Given User is on [Home] screen` anchor, in order:
|
|
69
|
-
1. `generate_locators` (or `appium_get_page_source`) on the CURRENT screen.
|
|
70
|
-
2. Resolve the step's `[Label]` against the live tree — prefer `accessibility id`, then visible
|
|
71
|
-
`text`/`content-desc`, then an `xpath` on a distinctive substring. Gestures (`scroll to [X]`,
|
|
72
|
-
`swipe …`) follow `sungen-mobile-gestures`.
|
|
73
|
-
3. Perform the tap/gesture, then **wait for the next screen to render** (same blank-splash guard as
|
|
74
|
-
step 4) before the next step.
|
|
75
|
-
|
|
76
|
-
After the LAST step you are on the target screen — capture HERE (steps 5–6).
|
|
77
|
-
|
|
78
|
-
- **Anchor-only Background** (no nav steps) ⇒ the target IS the launcher screen ⇒ skip this step.
|
|
79
|
-
- **A step won't resolve** (its `[Label]` matches no element) ⇒ **STOP. Do not capture the wrong
|
|
80
|
-
screen.** Screenshot where you are and report: *"recipe step N: [Label] not found — fix the
|
|
81
|
-
Background nav path."* Fail loud (run-test would fail at the same step anyway).
|
|
82
|
-
- **No recipe yet** (guided-stub Background, but the target is NOT the launcher) ⇒ drive to the
|
|
83
|
-
screen interactively off the live tree (if unsure which control leads there, ask the user), then
|
|
84
|
-
**report the exact nav steps you took** so create-test/add-screen can write them into the
|
|
85
|
-
Background. Do **not** edit the `.feature` yourself — Gherkin authorship stays with those commands.
|
|
86
|
-
|
|
87
|
-
### 5. Capture the locator tree (primary AI context)
|
|
88
|
-
|
|
89
|
-
Call **`generate_locators`** — this is the mobile equivalent of the web accessibility snapshot. It
|
|
90
|
-
returns priority-ranked locators per interactable element: `accessibility id`, `id`, platform-native
|
|
91
|
-
(`-android uiautomator` / `-ios predicate string`), and `xpath`, plus `content-desc`/`text`,
|
|
92
|
-
`clickable`, `enabled`. This is what `sungen-tc-generation` and `sungen-selector-keys` consume.
|
|
93
|
-
|
|
94
|
-
If the tree is huge, also `appium_get_page_source` (saved to a file) and grep it — never dump the
|
|
95
|
-
full XML inline.
|
|
96
|
-
|
|
97
|
-
### 6. Screenshot
|
|
98
|
-
|
|
99
|
-
`appium_screenshot` → save to:
|
|
100
|
-
```
|
|
101
|
-
qa/screens/<screen>/requirements/ui/mobile-<timestamp>.png
|
|
102
|
-
```
|
|
103
|
-
`<timestamp>` = `YYYYMMDD-HHMM` local (e.g. `mobile-20260605-1645.png`).
|
|
104
|
-
|
|
105
|
-
### 7. Detect discrepancies vs spec
|
|
106
|
-
|
|
107
|
-
If `spec.md` exists, cross-check `generate_locators` labels against spec sections (fields in spec but
|
|
108
|
-
not on screen, and vice-versa). Report; do **not** auto-edit `spec.md`.
|
|
109
|
-
|
|
110
|
-
### 8. End the session
|
|
111
|
-
|
|
112
|
-
`appium_session_management` `action=delete` to free the device. Always clean up.
|
|
113
|
-
|
|
114
|
-
### 9. Report back
|
|
115
|
-
|
|
116
|
-
> Captured mobile screen `<appPackage>`:
|
|
117
|
-
> - Reached via: <N nav steps replayed from the Background recipe, or "launcher screen — no nav">
|
|
118
|
-
> - Locators: <N> interactable elements (M with accessibility-id)
|
|
119
|
-
> - Screenshot: `requirements/ui/mobile-<timestamp>.png`
|
|
120
|
-
> - Discrepancies vs spec: <count, or "none">
|
|
121
|
-
> - Discovered nav steps (only if the recipe was empty): <the taps you took, for create-test/add-screen to write into the Background>
|
|
122
|
-
|
|
123
|
-
Hand back to the calling command.
|
|
124
|
-
|
|
125
|
-
---
|
|
126
|
-
|
|
127
|
-
## Cross-platform discovery (`@platform:mobile` — explore one OS, layer the rest)
|
|
128
|
-
|
|
129
|
-
When the screen is **`@platform:mobile`** (write-once-run-both), discover the **shared** cases first,
|
|
130
|
-
then peel off only what is genuinely OS-specific. You do **not** need to explore both OSes up front —
|
|
131
|
-
Flutter/RN expose the same Semantics on each, so one exploration covers most of it.
|
|
132
|
-
|
|
133
|
-
1. **Explore whichever OS has a device up** (Android or iOS — symmetric for Flutter). Capture the tree.
|
|
134
|
-
2. **Classify each component** into THREE buckets (not two):
|
|
135
|
-
- **Shared-exact** → a stable `accessibility id` equal on both OSes (Flutter Semantics → same value on
|
|
136
|
-
Android `content-desc` AND iOS `name`) → flat `type: accessibility-id` key in `<screen>.feature`.
|
|
137
|
-
- **Shared-variant** → SAME step/assertion on both OSes but the LOCATOR differs (composite
|
|
138
|
-
`content-desc` vs `-ios predicate`; partial/dynamic text via `descriptionContains` vs predicate
|
|
139
|
-
`CONTAINS`; a different attribute) → STILL `<screen>.feature`, with `android:`/`ios:` variant keys in
|
|
140
|
-
selectors.yaml. **A native locator alone is NOT a reason to split** — default for composite/partial text.
|
|
141
|
-
- **Sub-feature** → ONLY for genuine SCENARIO divergence: an element on ONE OS only, divergent
|
|
142
|
-
steps/flow, an OS-exclusive gesture/permission/dialog flow, or a case needing a per-platform
|
|
143
|
-
`nth`/`scope` (a variant can't diverge those). → `<screen>-android.feature` / `<screen>-ios.feature`.
|
|
144
|
-
3. **Report the classification** so create-test/run-test scaffolds the right thing:
|
|
145
|
-
- `<screen>.feature` `@platform:mobile` ← shared-exact AND shared-variant (the vast majority)
|
|
146
|
-
- `<screen>-android.feature` `@platform:android` ← ONLY scenario-divergent Android cases
|
|
147
|
-
- `<screen>-ios.feature` `@platform:ios` ← ONLY scenario-divergent iOS cases
|
|
148
|
-
4. **Verifying the other OS needs no second exploration** — just running the shared spec there
|
|
149
|
-
(`MOBILE_PLATFORM=both`) IS the check. Re-capture on the 2nd OS only for components that fail, and
|
|
150
|
-
move those into that OS's sub-feature. (Asking devs to add a Semantics label to an unlabeled element
|
|
151
|
-
converts an OS-specific case back into a shared one — prefer that when feasible.)
|
|
152
|
-
|
|
153
|
-
## Selector-quality notes (carry into selectors.yaml)
|
|
154
|
-
|
|
155
|
-
- **Prefer `accessibility id`** (Android `content-desc` / iOS `accessibilityIdentifier`) — most stable.
|
|
156
|
-
- For **Flutter**, the Semantics label surfaces as `content-desc` ⇒ it usually equals the **visible
|
|
157
|
-
text**, so it is **locale-dependent** ("Good afternoon!", "English"). Keep such values in test-data
|
|
158
|
-
and use `{{variable}}` + locale overlays (see `sungen-locale`).
|
|
159
|
-
- **Composite nodes**: cards may concatenate child text into one `content-desc` with `\n` → prefer an
|
|
160
|
-
xpath `contains(@content-desc,'…')` on a distinctive substring.
|
|
161
|
-
- **Duplicate labels** → use `nth`. **Unlabelled controls** (search fields, icon buttons) → fall back
|
|
162
|
-
to `xpath` / class.
|
|
163
|
-
|
|
164
|
-
---
|
|
165
|
-
|
|
166
|
-
## What this skill does NOT do
|
|
167
|
-
|
|
168
|
-
- Does not run tests or generate `selectors.yaml` (that's `/sungen:run-test` + `sungen-selector-fix-mobile`)
|
|
169
|
-
- Does not generate Gherkin (that's `sungen-tc-generation`) — it may *report* discovered nav steps,
|
|
170
|
-
but writing them into the Background is create-test/add-screen's job
|
|
171
|
-
- Does not handle login/auth state (mobile auth is a separate concern — deep link / test build)
|
|
172
|
-
- Captures **the feature's target screen** per invocation — reached by replaying the Background
|
|
173
|
-
navigation recipe (step 4.5), not just the launcher. For a *different* screen, give it its own
|
|
174
|
-
feature + recipe and re-invoke.
|
|
175
|
-
|
|
176
|
-
---
|
|
177
|
-
|
|
178
|
-
## Relationship to other capture skills
|
|
179
|
-
|
|
180
|
-
- `sungen-capture-figma` / `sungen-capture-local` — design/image sources (platform-agnostic)
|
|
181
|
-
- `sungen-capture-live` — web (Playwright MCP)
|
|
182
|
-
- `sungen-capture-mobile` — this skill, mobile (Appium MCP)
|
|
183
|
-
|
|
184
|
-
All write to `requirements/ui/` and report back to the caller.
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sungen-harness-audit
|
|
3
|
-
description: 'How to read `sungen audit` output and repair test-design findings. Auto-loaded by the design orchestrator.'
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## What `sungen audit` measures
|
|
8
|
-
|
|
9
|
-
`sungen audit --screen <name>` runs deterministic sensors over `features/<name>.feature` + `requirements/test-viewpoint.md` and writes `.sungen/reports/<name>-audit.json`. It is the **gate** the orchestrator repairs against. Run with `--json` to parse it.
|
|
10
|
-
|
|
11
|
-
### Report shape (key fields)
|
|
12
|
-
```jsonc
|
|
13
|
-
{
|
|
14
|
-
"score": { "overall": 3.9, "coverage": 0.4, "businessDepth": 0.18, "balance": 0.5, "traceability": 0.7 },
|
|
15
|
-
"gateStatus": "PASS" | "FAIL",
|
|
16
|
-
"gate": { "pageType": "ecommerce-list", "themesCovered": 2, "themesTotal": 5,
|
|
17
|
-
"gaps": [ { "theme": "cart-correctness", "keywords": [...] } ] },
|
|
18
|
-
"depth": { "businessCriticalShallow": 9, "businessCriticalTotal": 11,
|
|
19
|
-
"shallowBusinessCritical": [ { "name": "...", "category": "PRODUCT" } ] },
|
|
20
|
-
"balance": { "imbalanced": true, "coreCount": 11, "secondaryCount": 22, "byBucket": {...} },
|
|
21
|
-
"duplicates": { "clusters": [ { "sameDataLikely": false, "scenarios": [...] } ] },
|
|
22
|
-
"trace": { "mappedRatio": 0.4, "note": "..." },
|
|
23
|
-
"findings": [ "GATE: ...", "DEPTH: ...", "BALANCE: ...", "TRACE: ..." ]
|
|
24
|
-
}
|
|
25
|
-
```
|
|
26
|
-
- **`overall` score is business-weighted** (coverage 0.4 + businessDepth 0.3 + balance 0.15 + traceability 0.15). It is intentionally strict on business value — a high count with shallow business coverage scores low. Don't optimize the count; optimize coverage + depth.
|
|
27
|
-
- Exit code **2** when `gateStatus == FAIL` (usable in CI / loop).
|
|
28
|
-
|
|
29
|
-
## Finding → repair mapping
|
|
30
|
-
|
|
31
|
-
| Finding prefix | Meaning | Repair action |
|
|
32
|
-
|---|---|---|
|
|
33
|
-
| **GATE** | a critical theme for the page-type has no covering scenario | Generate scenarios for that theme. **If cross-screen** (cart-correctness, product-detail-consistency, filter-result-correctness, multi-item cart) → do NOT fake it on a single screen; plan a **flow** (`/sungen:add-flow`) and record the deferral. |
|
|
34
|
-
| **DEPTH** | business-critical scenarios assert only visibility/navigation | Replace `Then User see [X] page/section` with **observable data assertions**: `Then User see [X] with {{value}}`, `Then User see [T] table match data:`. Capture real expected values into `test-data.yaml`. |
|
|
35
|
-
| **BALANCE** | secondary viewpoints (UI/validation/security) outweigh business-core | **Stop expanding** secondary viewpoints; generate the missing business-core scenarios first. Do not add more subscription/UI variants while core is thin. |
|
|
36
|
-
| **TRACE** | scenarios use ad-hoc `VP-<CAT>-NNN` codes not linked to the viewpoint-overview | Make each scenario map to a viewpoint-overview id (align category codes, or add a mapping comment). |
|
|
37
|
-
| **UNIVERSAL** | a universal theme (error/empty-state, accessibility) is absent | Low priority — add if in scope; otherwise note as out-of-scope with reason. |
|
|
38
|
-
|
|
39
|
-
## P5 steps for deep cross-screen / list coverage
|
|
40
|
-
|
|
41
|
-
Use these when repairing GATE/DEPTH findings for the hard viewpoints (cart/detail/filter correctness). They need **runtime data mode** (the default).
|
|
42
|
-
|
|
43
|
-
- **Capture a value to compare across screens** (product-detail-consistency, cart-correctness):
|
|
44
|
-
```gherkin
|
|
45
|
-
When User remember [Product Name] text as {{selected_product_name}}
|
|
46
|
-
And User remember [Product Price] text as {{selected_product_price}}
|
|
47
|
-
And User click [View Product] link
|
|
48
|
-
Then User see [Detail Product Name] header with {{selected_product_name}}
|
|
49
|
-
And User see [Detail Product Price] text with {{selected_product_price}}
|
|
50
|
-
```
|
|
51
|
-
`remember` stores the element's text/value at runtime; later `{{var}}` resolves to it. This proves the detail/cart shows the SAME product, not a random one.
|
|
52
|
-
|
|
53
|
-
- **Assert every item in a result matches** (category/brand-filter-correctness):
|
|
54
|
-
```gherkin
|
|
55
|
-
When User click [Women] link
|
|
56
|
-
And User click [Dress] link
|
|
57
|
-
Then User see all [Result Product Name] contain {{selected_category}}
|
|
58
|
-
```
|
|
59
|
-
`see all [X] contain {{v}}` asserts EVERY matching element contains the value → "all displayed products belong to the selected category/brand", not just one.
|
|
60
|
-
|
|
61
|
-
> Cross-screen flows (home → detail/cart): **automate the journey as a flow** (`/sungen:add-flow`) — it runs as one test, so it is automatable. Do **not** keep a full `@manual` duplicate of it on the screen (a non-running dead copy that `sungen audit` flags as `MANUAL-AUTOMATABLE` and that inflates nothing — deferred business-critical is reported as `DEPTH-DEFERRED`). The screen keeps its screen-contract; the flow owns the cross-screen depth. `@manual` is for genuine judgment / missing-capability only, tagged `@manual:Mx`.
|
|
62
|
-
|
|
63
|
-
## Repair loop rules
|
|
64
|
-
|
|
65
|
-
1. **Budget = 3 rounds.** Re-run `sungen audit` after each repair; track score delta.
|
|
66
|
-
2. **Stop when** `gateStatus == PASS` AND `findings` empty — or budget exhausted.
|
|
67
|
-
3. **Never fake a pass.** A shallow `see [Cart] page` does not satisfy `cart-correctness`. If a gap is genuinely cross-screen or needs capabilities the DSL lacks (e.g. capture an element value to compare elsewhere), **report it as a residual gap / flow item** instead of forcing a green gate.
|
|
68
|
-
4. **EP/data families are OK.** A `duplicates` cluster with `sameDataLikely=false` is an intentional equivalence-partition family (e.g. many invalid-email cases) — keep it; only collapse `sameDataLikely=true` exact duplicates.
|
|
69
|
-
5. **Advisory findings — surface, don't gate.** `MANUAL-REASON-MISMATCH` → fix the scenario's `@manual:Mx` code (so the planner recommends the right driver) during repair. `CAPABILITY-SUGGESTION` → **present it to the user as a next-step option** (e.g. "N @manual could be automated — `sungen capability add api db`?"), **recommend-only — never auto-install**. Neither fails the gate.
|
|
70
|
-
|
|
71
|
-
## Discovery / fallback tree (when input is limited)
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
spec.md đủ tốt? → YES: Spec-first
|
|
75
|
-
│ NO
|
|
76
|
-
source code có? → YES: Source-first (mine behavior từ code)
|
|
77
|
-
│ NO
|
|
78
|
-
testcase cũ tương tự?→ YES: History-first
|
|
79
|
-
│ NO
|
|
80
|
-
domain rủi ro+defect?→ YES: Defect-first
|
|
81
|
-
│ NO
|
|
82
|
-
→ hỏi QA; QA chưa phản hồi → OUTPUT kèm ASSUMPTION LIST rõ ràng (không stall)
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
See `docs/orchestration-spec.md` for the full flow and `docs/spec/sungen_refactor_spec.md` for the design rationale.
|
|
@@ -1,291 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: sungen-locale
|
|
3
|
-
description: 'Bootstrap i18n for a screen/flow — audit hardcoded selector text, detect locale-switch mechanism via live Playwright, generate test-data overlay file. Auto-loaded by /sungen:locale command.'
|
|
4
|
-
user-invocable: false
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
## Goal
|
|
8
|
-
|
|
9
|
-
Take a screen/flow whose `selectors/*.yaml` and `.feature` files were authored against the default locale (usually Vietnamese) and prepare it to run against a second locale. Output:
|
|
10
|
-
|
|
11
|
-
1. `selectors/<feature>.yaml` — hardcoded `name`/`value` replaced with `{{var}}`
|
|
12
|
-
2. `test-data/<feature>.yaml` — base locale, complete with all new keys
|
|
13
|
-
3. `test-data/<feature>.<locale>.yaml` — overlay with only the keys that change
|
|
14
|
-
4. (Optional) `selectors/<feature>.yaml` Pages block updated when locale uses URL prefix or query param
|
|
15
|
-
|
|
16
|
-
After this skill finishes, `sungen run-test <name> --env <locale>` Just Works.
|
|
17
|
-
|
|
18
|
-
## Run mode — Live (preferred) vs Offline (fallback)
|
|
19
|
-
|
|
20
|
-
Pick mode **once at start**, based on whether MCP Playwright can reach the page.
|
|
21
|
-
|
|
22
|
-
```
|
|
23
|
-
Try: browser_navigate(baseURL)
|
|
24
|
-
→ succeeds + page renders content → LIVE MODE (all 6 phases)
|
|
25
|
-
→ fails (auth blocked, network down, app broken) → OFFLINE MODE
|
|
26
|
-
(audit + scaffold template + ask user to fill, skip detection phases)
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
**Live mode is the value-add** — it auto-detects locale switch mechanism and auto-fills translations. Offline mode just makes the file structure right; user fills in text manually.
|
|
30
|
-
|
|
31
|
-
Announce which mode is being used before Phase 1.
|
|
32
|
-
|
|
33
|
-
## Phase 1 — Audit selectors (always, no MCP)
|
|
34
|
-
|
|
35
|
-
For each `.feature` file under the screen, read the matching `selectors/<feature>.yaml`. List every entry whose `name` or `value` field contains literal text WITHOUT `{{…}}` AND is not a CSS/href selector.
|
|
36
|
-
|
|
37
|
-
Classify each candidate:
|
|
38
|
-
- **`name` field of `role`-type selector** → very likely locale-dependent
|
|
39
|
-
- **`value` field of `text`-type selector** → very likely locale-dependent
|
|
40
|
-
- **`value` of `locator`-type selector** that contains `:has-text("…")` → check if text is in target language
|
|
41
|
-
- **`value` of `page`-type selector** → URL — handled in Phase 3
|
|
42
|
-
- **CSS / href / attribute selectors** (e.g. `a[href="/awards"]`) → skip, locale-invariant
|
|
43
|
-
|
|
44
|
-
Print the candidate list as a table:
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
selector key | field | hardcoded value | classification
|
|
48
|
-
-------------------+-------+---------------------------+------------------
|
|
49
|
-
nav about | name | Giới thiệu SAA 2025 | locale-dependent
|
|
50
|
-
nav awards | name | Thông tin giải thưởng | locale-dependent
|
|
51
|
-
event date | name | 26/12/2025 | maybe (date format)
|
|
52
|
-
nav kudos | name | Sun* Kudos | brand — skip
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
If zero candidates and zero `{{var}}` already in place → screen has no localizable text. Tell user, stop.
|
|
56
|
-
|
|
57
|
-
## Phase 2 — Capture base locale (LIVE only)
|
|
58
|
-
|
|
59
|
-
1. Read `playwright.config.ts` for `baseURL`. Read `Path:` from `.feature` for entry path.
|
|
60
|
-
2. If screen has `@auth:<role>` tags, load `specs/.auth/<role>.json` via `browser_set_storage_state` first.
|
|
61
|
-
3. `browser_navigate(baseURL + entryPath)` then `browser_wait_for` for something stable.
|
|
62
|
-
4. Capture:
|
|
63
|
-
- `browser_snapshot()` — DOM accessibility tree
|
|
64
|
-
- `browser_evaluate(() => location.href)` — full URL
|
|
65
|
-
- `browser_evaluate(() => ({ localStorage: {...localStorage}, cookies: document.cookie }))` — storage state hash
|
|
66
|
-
5. For each Phase-1 candidate: verify the hardcoded text actually appears on the page. Drop ones that don't (stale selectors / false positives).
|
|
67
|
-
|
|
68
|
-
Save state in memory as `baseLocale = { url, snapshot, storage }`.
|
|
69
|
-
|
|
70
|
-
If page redirects to `/login` (auth blocker) → stop. Print: *"Auth blocked — cannot capture live page. Re-run with `--offline` flag, or unblock auth first."*
|
|
71
|
-
|
|
72
|
-
## Phase 3 — Switch locale (LIVE only) — detect mechanism + storage delta
|
|
73
|
-
|
|
74
|
-
Goal: identify (a) HOW to switch the app to the target locale, and (b) WHAT app-side storage state ends up holding the locale preference so a fresh BrowserContext can be primed identically without driving the UI.
|
|
75
|
-
|
|
76
|
-
Before triggering the switch, capture full storage baseline:
|
|
77
|
-
|
|
78
|
-
```js
|
|
79
|
-
const before = await browser_evaluate(() => ({
|
|
80
|
-
sessionStorage: { ...sessionStorage },
|
|
81
|
-
localStorage: { ...localStorage },
|
|
82
|
-
cookies: document.cookie,
|
|
83
|
-
url: location.href,
|
|
84
|
-
}));
|
|
85
|
-
```
|
|
86
|
-
|
|
87
|
-
Then try mechanisms in order. First one that produces visibly different text wins. For EACH attempt, capture `after` state and diff against `before`.
|
|
88
|
-
|
|
89
|
-
**3a. URL prefix**
|
|
90
|
-
- `browser_navigate(baseURL + '/' + locale + entryPath)`
|
|
91
|
-
- Wait, snapshot
|
|
92
|
-
- Compare a known Phase-1 candidate's text vs baseLocale
|
|
93
|
-
- If text differs and page didn't 404 → **URL prefix mechanism**. Save `localePrefix = '/' + locale`.
|
|
94
|
-
|
|
95
|
-
**3b. Query param** (only if 3a failed)
|
|
96
|
-
- `browser_navigate(baseURL + entryPath + '?lang=' + locale)` (also try `?locale=`, `?lng=`, `?l=`, `?language=`)
|
|
97
|
-
- Same diff check
|
|
98
|
-
- If text differs → **Query param mechanism**. Save the variant that worked.
|
|
99
|
-
|
|
100
|
-
**3c. Language switcher UI** (only if 3a + 3b failed)
|
|
101
|
-
- Look in base-locale snapshot for buttons matching: `'Select language'`, `'Language'`, `'言語'`, `'Ngôn ngữ'`, role=combobox
|
|
102
|
-
- If found, ask user before clicking
|
|
103
|
-
- `browser_click` the switcher, then the locale option
|
|
104
|
-
- Verify text changed
|
|
105
|
-
- If yes → **UI switcher mechanism**.
|
|
106
|
-
|
|
107
|
-
**3d. None detected** — ask user how to proceed manually.
|
|
108
|
-
|
|
109
|
-
### Phase 3.5 — Storage diff (always run after Phase 3 succeeds)
|
|
110
|
-
|
|
111
|
-
After locale text confirmed switched, capture `after` state and diff per area:
|
|
112
|
-
|
|
113
|
-
```js
|
|
114
|
-
const after = await browser_evaluate(() => ({
|
|
115
|
-
sessionStorage: { ...sessionStorage },
|
|
116
|
-
localStorage: { ...localStorage },
|
|
117
|
-
cookies: document.cookie,
|
|
118
|
-
}));
|
|
119
|
-
const sessionDiff = diffEntries(before.sessionStorage, after.sessionStorage);
|
|
120
|
-
const localDiff = diffEntries(before.localStorage, after.localStorage);
|
|
121
|
-
const cookieDiff = diffCookies(before.cookies, after.cookies);
|
|
122
|
-
```
|
|
123
|
-
|
|
124
|
-
**Filter noise** — only keep entries where:
|
|
125
|
-
- Key name contains `lang|locale|language|i18n|intl` (case-insensitive), OR
|
|
126
|
-
- Value matches `^[a-z]{2}(-[A-Z]{2})?$` or equals the target locale code
|
|
127
|
-
|
|
128
|
-
Drop noise: auth tokens (`sb-*`, `*-token`, `*-jwt`), analytics (`_ga*`, `_gid`, `_fbp`), app state (`csrf*`, `last-*`).
|
|
129
|
-
|
|
130
|
-
**Auto-confidence per entry:**
|
|
131
|
-
- High: key name contains locale-related word AND value is a locale code → KEEP, no prompt
|
|
132
|
-
- Medium: only one signal matches → ask user
|
|
133
|
-
- Low: neither matches but key changed → ask user, default skip
|
|
134
|
-
|
|
135
|
-
### Phase 3.6 — Verification
|
|
136
|
-
|
|
137
|
-
For each high/medium-confidence storage entry, verify by setting it manually + reloading:
|
|
138
|
-
|
|
139
|
-
```js
|
|
140
|
-
await browser_evaluate(`() => sessionStorage.setItem('saa-language-preference', 'en')`);
|
|
141
|
-
await browser_navigate(baseURL); // reload triggers app to read storage on boot
|
|
142
|
-
await browser_snapshot();
|
|
143
|
-
// confirm a known target-locale string appears
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
Caveat: hard reload kills any in-memory JWT (auth blocker amplifies failure surface). Skip verification if the screen has `@auth:*` tags and JWT persistence is known broken in the app.
|
|
147
|
-
|
|
148
|
-
If verification fails → drop confidence one tier, ask user.
|
|
149
|
-
|
|
150
|
-
Save mechanism + verified storage delta to memory for Phase 6.
|
|
151
|
-
|
|
152
|
-
## Phase 4 — Diff base ↔ target (LIVE only)
|
|
153
|
-
|
|
154
|
-
For each candidate from Phase 1 that survived Phase 2:
|
|
155
|
-
- Find the SAME element in target-locale snapshot (match by `role`+position, by `aria-label`, by neighbor structure)
|
|
156
|
-
- Extract its text → `targetText`
|
|
157
|
-
- Pair: `(selectorKey, hardcoded baseText, observed targetText)`
|
|
158
|
-
|
|
159
|
-
If matching fails for a candidate → mark "needs manual" — flag for user input rather than skip silently.
|
|
160
|
-
|
|
161
|
-
Result: list of triples `{ selectorKey, baseText, targetText, confidence }`.
|
|
162
|
-
|
|
163
|
-
## Phase 5 — Confirm + edit (always)
|
|
164
|
-
|
|
165
|
-
Present the proposal table:
|
|
166
|
-
|
|
167
|
-
```
|
|
168
|
-
selector key | base text | target text | proposed var | apply?
|
|
169
|
-
-------------------+--------------------------+----------------------+------------------+-------
|
|
170
|
-
nav about | Giới thiệu SAA 2025 | About SAA 2025 | nav_about | [✓]
|
|
171
|
-
nav awards | Thông tin giải thưởng | Awards Info | nav_awards | [✓]
|
|
172
|
-
nav kudos | Sun* Kudos | Sun* Kudos | — | [skip — same]
|
|
173
|
-
event date | 26/12/2025 | 26/12/2025 | — | [skip — same]
|
|
174
|
-
```
|
|
175
|
-
|
|
176
|
-
Var names: snake_case the selector key. Avoid collisions with existing test-data keys.
|
|
177
|
-
|
|
178
|
-
Auto-skip rows where `baseText === targetText` (brand names, locale-invariant numbers).
|
|
179
|
-
|
|
180
|
-
Ask user: *"Review the table. Confirm to apply / edit individual rows / re-run capture / cancel."*
|
|
181
|
-
|
|
182
|
-
If user wants to edit a row → fall through to a per-row prompt for `var name` or `targetText` correction.
|
|
183
|
-
|
|
184
|
-
OFFLINE mode: same table but `target text` column blank — user fills via subsequent prompts or by editing the overlay file after the skill finishes.
|
|
185
|
-
|
|
186
|
-
## Phase 6 — Apply changes (always, after confirmation)
|
|
187
|
-
|
|
188
|
-
For each confirmed row:
|
|
189
|
-
|
|
190
|
-
**6a. Update `selectors/<feature>.yaml`**
|
|
191
|
-
|
|
192
|
-
Replace `name: '<baseText>'` with `name: '{{<varName>}}'`. Preserve quoting style.
|
|
193
|
-
|
|
194
|
-
**6b. Update `test-data/<feature>.yaml`** (base locale, complete dictionary)
|
|
195
|
-
|
|
196
|
-
Append new keys at the end, grouped under a `# === i18n: <screen> ===` comment:
|
|
197
|
-
|
|
198
|
-
```yaml
|
|
199
|
-
# === i18n: home ===
|
|
200
|
-
nav_about: 'Giới thiệu SAA 2025'
|
|
201
|
-
nav_awards: 'Thông tin giải thưởng'
|
|
202
|
-
```
|
|
203
|
-
|
|
204
|
-
**6c. Create `test-data/<feature>.<locale>.yaml`** (overlay, only diffs)
|
|
205
|
-
|
|
206
|
-
```yaml
|
|
207
|
-
# home — <locale> overlay. Only keys that change vs base.
|
|
208
|
-
# Run with: SUNGEN_ENV=<locale> npx playwright test ...
|
|
209
|
-
|
|
210
|
-
nav_about: 'About SAA 2025'
|
|
211
|
-
nav_awards: 'Awards Info'
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
**6d. (URL/query mechanism only) Update Pages selectors**
|
|
215
|
-
|
|
216
|
-
URL prefix:
|
|
217
|
-
|
|
218
|
-
```yaml
|
|
219
|
-
home:
|
|
220
|
-
type: 'page'
|
|
221
|
-
value: '{{base_path}}/'
|
|
222
|
-
awards:
|
|
223
|
-
type: 'page'
|
|
224
|
-
value: '{{base_path}}/awards'
|
|
225
|
-
```
|
|
226
|
-
|
|
227
|
-
Add to test-data:
|
|
228
|
-
```yaml
|
|
229
|
-
# base
|
|
230
|
-
base_path: ''
|
|
231
|
-
|
|
232
|
-
# overlay
|
|
233
|
-
base_path: '/en'
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
Query param mechanism: append `query_suffix` similarly.
|
|
237
|
-
|
|
238
|
-
UI switcher: do NOT modify Pages. Write storage delta into `specs/generated/locale-config.json` (sibling of generated `base.ts` + `locale-fixture.ts`) (6f).
|
|
239
|
-
|
|
240
|
-
**6f. Storage injection config — `specs/generated/locale-config.json` (sibling of generated `base.ts` + `locale-fixture.ts`)**
|
|
241
|
-
|
|
242
|
-
Always write `specs/generated/locale-config.json` (sibling of generated `base.ts` + `locale-fixture.ts`) with the verified storage delta from Phase 3.5/3.6. Consumed by `specs/locale-fixture.ts` (auto-generated alongside `specs/base.ts`), which wraps Playwright's context and calls `addInitScript` + `addCookies` BEFORE the first navigation.
|
|
243
|
-
|
|
244
|
-
Schema:
|
|
245
|
-
|
|
246
|
-
```json
|
|
247
|
-
{
|
|
248
|
-
"$schema": "sungen-locale-config-v1",
|
|
249
|
-
"sessionStorage": {
|
|
250
|
-
"saa-language-preference": "${SUNGEN_ENV}"
|
|
251
|
-
},
|
|
252
|
-
"localStorage": {},
|
|
253
|
-
"cookies": [],
|
|
254
|
-
"notes": "Detected by /sungen:locale on YYYY-MM-DD. ..."
|
|
255
|
-
}
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
Use `"${SUNGEN_ENV}"` (or `"{{SUNGEN_ENV}}"`) as placeholder for runtime substitution. Use hardcoded literals when the stored value is fixed regardless of locale. Drop auth tokens / session IDs even if the Phase 3.5 diff captured them.
|
|
259
|
-
|
|
260
|
-
Multi-locale projects use the same file — placeholder gets substituted at runtime per locale.
|
|
261
|
-
|
|
262
|
-
**6e. Compile**
|
|
263
|
-
|
|
264
|
-
Run `sungen generate --screen <name>` (or `--flow`) and report any compile errors. Selectors changed → compile MUST succeed before run-test.
|
|
265
|
-
|
|
266
|
-
## Phase 7 — Hand off
|
|
267
|
-
|
|
268
|
-
Print summary:
|
|
269
|
-
- N selectors converted to `{{var}}`
|
|
270
|
-
- M base keys added to `test-data/<feature>.yaml`
|
|
271
|
-
- K overlay keys written to `test-data/<feature>.<locale>.yaml`
|
|
272
|
-
- Pages selectors updated: yes/no
|
|
273
|
-
- Locale-switching mechanism: URL prefix `/en` / query `?lang=en` / UI switcher / manual
|
|
274
|
-
|
|
275
|
-
Suggest:
|
|
276
|
-
|
|
277
|
-
```
|
|
278
|
-
/sungen:run-test <name> --env <locale>
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
## Multi-feature screens
|
|
282
|
-
|
|
283
|
-
If the screen has multiple `.feature` files (e.g. `home.feature` + `home-modal.feature`), repeat Phase 1 → Phase 6 for each feature file with its own selectors + test-data pair. Phase 2 + 3 run **once per screen** — mechanism is the same. Phase 4 runs per feature because UI scope differs.
|
|
284
|
-
|
|
285
|
-
## What NOT to do
|
|
286
|
-
|
|
287
|
-
- Do not edit `.feature` files. The i18n shape is already correct there (`{{var}}` was the convention from the start). Only selectors + test-data need surgery.
|
|
288
|
-
- Do not write a separate selectors file per locale (`home.en.yaml`). One selectors file with `{{var}}` works across all locales.
|
|
289
|
-
- Do not delete keys from the base `test-data/<feature>.yaml`. Always append.
|
|
290
|
-
- Do not run tests in this skill. Hand off to `/sungen:run-test`.
|
|
291
|
-
- Do not commit. Hand off to user.
|