-
Your workflow generator prompt is ready
-
Copy it, then paste it into your agent from the repository you want to automate.
+
Your workflow generator prompt is ready
+
Copy it, then paste it into your agent from the repository you want to automate.
@@ -211,10 +211,10 @@
Your workflow generator prompt is ready
-
@@ -258,7 +258,7 @@
Your workflow generator prompt is ready
diff --git a/src/js/ui.js b/src/js/ui.js
index 3f06da4..773825c 100644
--- a/src/js/ui.js
+++ b/src/js/ui.js
@@ -792,9 +792,9 @@ function showCopyFailure() {
const status = document.getElementById('copy-status');
clearTimeout(copyFeedbackTimer);
button.dataset.defaultLabel ||= button.textContent;
- button.textContent = 'Copy failed — try again';
+ button.textContent = button.dataset.failureLabel || 'Copy failed — try again';
button.classList.add('copy-error');
- status.textContent = 'Prompt could not be copied. Please try again.';
+ status.textContent = status.dataset.failureMessage || 'Prompt could not be copied. Please try again.';
copyFeedbackTimer = setTimeout(resetCopyFeedback, 3000);
}
diff --git a/src/js/wizard-config.js b/src/js/wizard-config.js
index 0933e93..b16be19 100644
--- a/src/js/wizard-config.js
+++ b/src/js/wizard-config.js
@@ -40,6 +40,25 @@ const LANDING_ELEMENTS = {
outputs_label: 'landing-outputs-label'
};
+const FINISH_ELEMENTS = {
+ step_label: 'finish-step-label',
+ step_description: 'finish-step-description',
+ title: 'finish-title',
+ message: 'finish-message',
+ copy_button: 'btn-copy',
+ preview_label: 'finish-preview-label',
+ preview_hint: 'finish-preview-hint'
+};
+
+const COPY_SUCCESS_ELEMENTS = {
+ eyebrow: 'copy-modal-eyebrow',
+ title: 'copy-modal-title',
+ description: 'copy-modal-description',
+ next_step_title: 'copy-modal-next-step-title',
+ next_step_description: 'copy-modal-next-step-description',
+ action: 'copy-modal-action'
+};
+
const FOOTER_ELEMENTS = {
source: ['footer-source', 'footer-source-label'],
report_issue: ['footer-report-issue', 'footer-report-issue'],
@@ -68,6 +87,33 @@ export function applyPageContent(config, configUrl) {
const landing = config && config.landing ? config.landing : {};
Object.entries(LANDING_ELEMENTS).forEach(([key, id]) => setText(id, landing[key]));
+ const finish = config && config.finish ? config.finish : {};
+ Object.entries(FINISH_ELEMENTS).forEach(([key, id]) => setText(id, finish[key]));
+ const copyButton = document.getElementById('btn-copy');
+ if (copyButton) {
+ if (typeof finish.copy_button === 'string') {
+ copyButton.dataset.defaultLabel = finish.copy_button;
+ }
+ if (typeof finish.copy_failure_button === 'string') {
+ copyButton.dataset.failureLabel = finish.copy_failure_button;
+ }
+ }
+ const copyStatus = document.getElementById('copy-status');
+ if (copyStatus && typeof finish.copy_failure_status === 'string') {
+ copyStatus.dataset.failureMessage = finish.copy_failure_status;
+ }
+ const preview = document.getElementById('finish-preview');
+ if (preview && typeof finish.preview_aria_label === 'string') {
+ preview.setAttribute('aria-label', finish.preview_aria_label);
+ }
+
+ const copySuccess = config && config.copy_success ? config.copy_success : {};
+ Object.entries(COPY_SUCCESS_ELEMENTS).forEach(([key, id]) => setText(id, copySuccess[key]));
+ const closeButton = document.getElementById('copy-modal-close');
+ if (closeButton && typeof copySuccess.close_label === 'string') {
+ closeButton.setAttribute('aria-label', copySuccess.close_label);
+ }
+
const footer = config && config.footer ? config.footer : {};
Object.entries(FOOTER_ELEMENTS).forEach(([key, ids]) => {
const item = footer[key] || {};
diff --git a/src/wizard.json b/src/wizard.json
index 6884ee5..3055cfb 100644
--- a/src/wizard.json
+++ b/src/wizard.json
@@ -12,6 +12,27 @@
"agent_label": "Agent",
"outputs_label": "Safe outputs"
},
+ "finish": {
+ "step_label": "Finish",
+ "step_description": "copy your prompt and run it",
+ "title": "Your workflow generator prompt is ready",
+ "message": "Copy it, then paste it into your agent from the repository you want to automate.",
+ "copy_button": "Copy prompt",
+ "copy_failure_button": "Copy failed — try again",
+ "copy_failure_status": "Prompt could not be copied. Please try again.",
+ "preview_label": "Prompt preview",
+ "preview_hint": "Review before copying",
+ "preview_aria_label": "Generated prompt preview"
+ },
+ "copy_success": {
+ "close_label": "Close",
+ "eyebrow": "Prompt copied",
+ "title": "Your workflow is one prompt away",
+ "description": "Open your coding agent from the repository you want to automate, then paste the prompt to generate your agentic workflow.",
+ "next_step_title": "Run it in your repository",
+ "next_step_description": "Your agent will take it from there.",
+ "action": "Got it"
+ },
"footer": {
"source": {
"url": "https://github.com/githubnext/gh-aw-wizard",
diff --git a/test/a11y.test.js b/test/a11y.test.js
index 1367589..a802845 100644
--- a/test/a11y.test.js
+++ b/test/a11y.test.js
@@ -108,8 +108,12 @@ describe('Copy prompt success modal', () => {
});
it('tells users to run the copied prompt in their repository', () => {
- expect(html).toContain('Open your coding agent from the repository you want to automate');
- expect(html).toContain('
Run it in your repository');
+ expect(wizard.copy_success.description).toContain(
+ 'Open your coding agent from the repository you want to automate'
+ );
+ expect(wizard.copy_success.next_step_title).toBe('Run it in your repository');
+ expect(html).toContain('id="copy-modal-description"');
+ expect(html).toContain('id="copy-modal-next-step-title"');
});
it('announces clipboard failures without opening the success modal', () => {
diff --git a/test/wizard-config.test.js b/test/wizard-config.test.js
index 247d356..1628048 100644
--- a/test/wizard-config.test.js
+++ b/test/wizard-config.test.js
@@ -54,6 +54,12 @@ describe('wizard configuration', () => {
const elements = {
'landing-title': { textContent: '' },
'landing-button-label': { textContent: '' },
+ 'finish-title': { textContent: '' },
+ 'btn-copy': { textContent: '', dataset: {} },
+ 'copy-status': { textContent: '', dataset: {} },
+ 'finish-preview': { setAttribute: vi.fn() },
+ 'copy-modal-title': { textContent: '' },
+ 'copy-modal-close': { setAttribute: vi.fn() },
'footer-source': { href: '' },
'footer-source-label': { textContent: '' },
'footer-security': { href: '', textContent: '' }
@@ -70,6 +76,17 @@ describe('wizard configuration', () => {
title: 'Build an automation',
button: 'Start building'
},
+ finish: {
+ title: 'Your custom prompt is ready',
+ copy_button: 'Copy custom prompt',
+ copy_failure_button: 'Try copying again',
+ copy_failure_status: 'The custom prompt was not copied.',
+ preview_aria_label: 'Custom prompt preview'
+ },
+ copy_success: {
+ close_label: 'Dismiss',
+ title: 'Custom prompt copied'
+ },
footer: {
source: {
url: './source',
@@ -84,6 +101,21 @@ describe('wizard configuration', () => {
expect(elements['landing-title'].textContent).toBe('Build an automation');
expect(elements['landing-button-label'].textContent).toBe('Start building');
+ expect(elements['finish-title'].textContent).toBe('Your custom prompt is ready');
+ expect(elements['btn-copy']).toMatchObject({
+ textContent: 'Copy custom prompt',
+ dataset: {
+ defaultLabel: 'Copy custom prompt',
+ failureLabel: 'Try copying again'
+ }
+ });
+ expect(elements['copy-status'].dataset.failureMessage).toBe('The custom prompt was not copied.');
+ expect(elements['finish-preview'].setAttribute).toHaveBeenCalledWith(
+ 'aria-label',
+ 'Custom prompt preview'
+ );
+ expect(elements['copy-modal-title'].textContent).toBe('Custom prompt copied');
+ expect(elements['copy-modal-close'].setAttribute).toHaveBeenCalledWith('aria-label', 'Dismiss');
expect(elements['footer-source']).toMatchObject({
href: 'https://custom.example/config/source'
});