diff --git a/.github/workflows/ci_check.yml b/.github/workflows/ci_check.yml index 24f18b2d1..4d98d0db1 100644 --- a/.github/workflows/ci_check.yml +++ b/.github/workflows/ci_check.yml @@ -13,6 +13,10 @@ concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true +defaults: + run: + shell: bash + jobs: ci-check: name: CI Check @@ -100,5 +104,8 @@ jobs: - name: Validate product specification catalog run: pnpm run validate:specifications + - name: Validate setup acceptance ledger + run: pnpm run validate:setup-acceptance + - name: Validate Git diff run: git diff --check diff --git a/.github/workflows/copilot_commit.yml b/.github/workflows/copilot_commit.yml index 8378228d0..bb96ccb52 100644 --- a/.github/workflows/copilot_commit.yml +++ b/.github/workflows/copilot_commit.yml @@ -7,6 +7,10 @@ on: - '!master' - '!develop' +defaults: + run: + shell: bash + jobs: copilot-commits: if: ${{ vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN }} diff --git a/.github/workflows/copilot_pull_request.yml b/.github/workflows/copilot_pull_request.yml index befe15aba..cb7aed263 100644 --- a/.github/workflows/copilot_pull_request.yml +++ b/.github/workflows/copilot_pull_request.yml @@ -5,6 +5,10 @@ on: pull_request: types: [opened, reopened, closed, synchronize] +defaults: + run: + shell: bash + jobs: copilot-pull-requests: if: ${{ (vars.COPILOT_BOT_LOGIN == '' || github.actor != vars.COPILOT_BOT_LOGIN) && github.event.pull_request.head.repo.full_name == github.repository }} diff --git a/.github/workflows/copilot_pull_request_merge_queue.yml b/.github/workflows/copilot_pull_request_merge_queue.yml index 810fcf431..e0c684849 100644 --- a/.github/workflows/copilot_pull_request_merge_queue.yml +++ b/.github/workflows/copilot_pull_request_merge_queue.yml @@ -1,4 +1,8 @@ name: Copilot - Pull Request Merge Queue + +defaults: + run: + shell: bash run-name: Copilot PR · ${{ github.event_name }}:${{ github.event.action }} on: diff --git a/.github/workflows/hotfix_workflow.yml b/.github/workflows/hotfix_workflow.yml index 0160b2682..0494172d1 100644 --- a/.github/workflows/hotfix_workflow.yml +++ b/.github/workflows/hotfix_workflow.yml @@ -1,5 +1,9 @@ name: Task - Hotfix +defaults: + run: + shell: bash + on: workflow_dispatch: inputs: diff --git a/.github/workflows/release_workflow.yml b/.github/workflows/release_workflow.yml index b0e8b7f93..bbf3e5902 100644 --- a/.github/workflows/release_workflow.yml +++ b/.github/workflows/release_workflow.yml @@ -1,5 +1,9 @@ name: Task - Release +defaults: + run: + shell: bash + on: workflow_dispatch: inputs: diff --git a/.github/workflows/setup_platform_smoke.yml b/.github/workflows/setup_platform_smoke.yml new file mode 100644 index 000000000..c65099c0b --- /dev/null +++ b/.github/workflows/setup_platform_smoke.yml @@ -0,0 +1,43 @@ +name: Setup Platform Smoke + +on: + pull_request: + types: [opened, synchronize] + workflow_dispatch: + +permissions: + contents: read + +defaults: + run: + shell: bash + +jobs: + setup-platform-smoke: + name: Setup package and local session (${{ matrix.os }}) + runs-on: ${{ matrix.os }} + timeout-minutes: 20 + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + steps: + - uses: actions/checkout@v5 + with: + persist-credentials: false + - uses: pnpm/action-setup@v5 + with: + version: 10.12.4 + standalone: false + - uses: actions/setup-node@v7 + with: + node-version: '24.x' + cache: pnpm + - run: pnpm install --frozen-lockfile + - run: pnpm run build + - run: pnpm run validate:build + - run: pnpm run typecheck + - name: Local setup fixtures only + run: pnpm exec jest src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts src/cli/__tests__/web_setup_server.test.ts src/cli/__tests__/setup_session_guard.test.ts src/cli/__tests__/setup_apply_snapshot.test.ts src/tooling/__tests__/setup_acceptance_path.test.ts --runInBand --silent + - name: Isolated npm package checks + run: pnpm run validate:npm-package && pnpm run smoke:npm-package diff --git a/build/cli/index.js b/build/cli/index.js index 154091691..21f85edd1 100755 --- a/build/cli/index.js +++ b/build/cli/index.js @@ -37603,7 +37603,7 @@ const main_run_lifecycle_1 = __nccwpck_require__(916); const issue_workflow_runtime_policy_1 = __nccwpck_require__(77734); const application_error_1 = __nccwpck_require__(75999); const issue_start_policy_1 = __nccwpck_require__(90332); -async function mainRun(execution, projectBoardCommandPort, latestTagQueryPort, compositionSurface, lifecycleStateUseCase, agentActivityUseCase, prepareRuntime) { +async function mainRun(execution, projectBoardCommandPort, latestTagQueryPort, compositionSurface, lifecycleStateUseCase, agentActivityUseCase, prepareRuntime, setupProgress) { (0, logging_ports_1.configureApplicationLogger)((0, logger_adapter_1.createLoggerAdapter)()); (0, logging_ports_1.setGlobalLoggerDebug)(execution.debug, execution.inputs === undefined); const repository = (0, repository_context_1.requireRepositoryCoordinates)({ @@ -37640,7 +37640,7 @@ async function mainRun(execution, projectBoardCommandPort, latestTagQueryPort, c return [issueWorkflowAdmissionResult(runtimeDecision.mode, runtimeDecision.message)]; } await prepareRuntime?.(execution); - const routeHandlers = (0, main_run_route_composition_root_1.createMainRunRouteCompositionRoot)(projectBoardCommandPort, compositionSurface); + const routeHandlers = (0, main_run_route_composition_root_1.createMainRunRouteCompositionRoot)(projectBoardCommandPort, compositionSurface, setupProgress); if (execution.runnedByToken) { return runTrackedRoute(execution, 'single-action', () => (0, main_run_lifecycle_1.runTokenExecution)(execution, routeHandlers), undefined, agentActivityUseCase); } @@ -37998,7 +37998,7 @@ async function runLocalAction(additionalParams, options = {}) { owner: execution.owner, repository: execution.repo, token: execution.tokens.token, - })); + }), undefined, options.onSetupProgress); if (options.render !== false) { const catalog = await (0, publication_message_catalog_1.resolvePublicationCatalog)(execution.locale.repository, execution.ai.getAgentConfiguration('planner'), composition.catalogResolver); (0, local_action_output_1.renderLocalActionResults)(results, catalog); @@ -49953,6 +49953,12 @@ function reconcileSetupTokenPermissionEvidence(requirements, evidence) { } /** Limits positive usability without promoting publicly readable evidence to verified PAT access. */ function isOperationallyAvailableSetupRead(requirement, evidence) { + if (requirement.level === 'read' + && requirement.scope === 'organization' + && requirement.permission === 'Projects' + && requirement.probe === 'projects') { + return evidence === 'public-organization-projects'; + } return requirement.level === 'read' && requirement.scope === 'repository' && evidence === 'public-repository' @@ -49976,7 +49982,8 @@ function isMatchingEvidence(requirement, value) { && value.message.trim().length > 0 && (value.operationallyAvailable === undefined || value.operationallyAvailable === true) && (value.publicReadEvidence === undefined - || value.publicReadEvidence === 'public-repository'); + || value.publicReadEvidence === 'public-repository' + || value.publicReadEvidence === 'public-organization-projects'); } function isPermissionStatus(value) { return value === 'verified' || value === 'missing' || value === 'unverifiable'; @@ -52160,7 +52167,7 @@ exports.InitialSetupUseCase = void 0; const initial_setup_workflow_1 = __nccwpck_require__(18079); /** Application boundary for provisioning a repository for Copilot automation. */ class InitialSetupUseCase { - constructor(authenticatedUserPort, initialLabelProvisioningPort, issueTypeProvisioningPort, latestTagQueryPort, repositoryDefaultBranchPort, repositoryTagPort, setupWorkspacePort, setupRepositoryVariablesPort, setupRepositorySecretsPort, setupRemoteConfigurationReadPort) { + constructor(authenticatedUserPort, initialLabelProvisioningPort, issueTypeProvisioningPort, latestTagQueryPort, repositoryDefaultBranchPort, repositoryTagPort, setupWorkspacePort, setupRepositoryVariablesPort, setupRepositorySecretsPort, setupRemoteConfigurationReadPort, progress) { this.authenticatedUserPort = authenticatedUserPort; this.initialLabelProvisioningPort = initialLabelProvisioningPort; this.issueTypeProvisioningPort = issueTypeProvisioningPort; @@ -52171,6 +52178,7 @@ class InitialSetupUseCase { this.setupRepositoryVariablesPort = setupRepositoryVariablesPort; this.setupRepositorySecretsPort = setupRepositorySecretsPort; this.setupRemoteConfigurationReadPort = setupRemoteConfigurationReadPort; + this.progress = progress; this.taskId = 'InitialSetupUseCase'; } async invoke(param) { @@ -52185,6 +52193,7 @@ class InitialSetupUseCase { setupRepositoryVariablesPort: this.setupRepositoryVariablesPort, setupRepositorySecretsPort: this.setupRepositorySecretsPort, setupRemoteConfigurationReadPort: this.setupRemoteConfigurationReadPort, + progress: this.progress, }); } } @@ -52226,8 +52235,13 @@ async function runInitialSetupWorkflow(request, dependencies) { const mark = (id, state) => { const index = effects.findIndex(effect => effect.id === id); effects[index] = { ...effects[index], state }; + try { + dependencies.progress?.(Object.freeze({ ...effects[index] })); + } + catch { /* Presentation observers cannot abort provisioning. */ } }; - const receipt = () => buildResult(errors, steps, effects); + const receipt = () => buildResult(errors, steps, effects.map(effect => effect.state === 'in-progress' + ? { ...effect, state: 'needs-inspection' } : effect)); try { const setupConfiguration = request.setupConfiguration; if (!dependencies.setupWorkspacePort.hasValidToken()) { @@ -52285,12 +52299,12 @@ async function runInitialSetupWorkflow(request, dependencies) { approvedWorkflowFiles: request.workflowUpdates, } : {}), }; - mark('files', 'needs-inspection'); + mark('files', 'in-progress'); const filesResult = dependencies.setupWorkspacePort.prepare(workspaceSelection); mark('files', filesResult.copied > 0 ? 'completed' : 'skipped'); steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); if (setupConfiguration?.manageRepositorySecrets && secretValues > 0) - mark('secrets', 'needs-inspection'); + mark('secrets', 'in-progress'); const secrets = await (0, setup_resource_provisioning_1.ensureRepositorySecrets)(request, dependencies, setupConfiguration, remoteConfiguration); mark('secrets', secrets.errors.length ? 'needs-inspection' : secrets.writes > 0 ? 'completed' : 'skipped'); if (secrets.step) @@ -52298,7 +52312,7 @@ async function runInitialSetupWorkflow(request, dependencies) { if (secrets.errors.length > 0) errors.push(...fromMessages(secrets.errors, 'authorization.credential-invalid')); (0, logging_ports_1.logInfo)('🏷️ Checking configured and progress labels...'); - mark('labels', 'needs-inspection'); + mark('labels', 'in-progress'); const labels = await ensureInitialLabels(request, dependencies.initialLabelProvisioningPort, setupConfiguration); mark('labels', !labels.completed || labels.configured.errors.length || labels.progress.errors.length ? 'needs-inspection' : labels.configured.created + labels.progress.created > 0 ? 'completed' : 'skipped'); @@ -52310,7 +52324,7 @@ async function runInitialSetupWorkflow(request, dependencies) { appendLabelSummary(steps, errors, labels.progress, 'Progress labels'); } (0, logging_ports_1.logInfo)('📋 Checking issue types...'); - mark('issue-types', 'needs-inspection'); + mark('issue-types', 'in-progress'); const issueTypes = await ensureIssueTypes(request, dependencies.issueTypeProvisioningPort, setupConfiguration); mark('issue-types', !issueTypes.success ? 'needs-inspection' : issueTypes.created > 0 ? 'completed' : 'skipped'); if (!issueTypes.success) { @@ -52320,7 +52334,7 @@ async function runInitialSetupWorkflow(request, dependencies) { steps.push(`✅ Issue types checked: ${issueTypes.created} created, ${issueTypes.existing} already existed`); } if (setupConfiguration?.manageRepositoryVariables) - mark('variables', 'needs-inspection'); + mark('variables', 'in-progress'); const variables = await (0, setup_resource_provisioning_1.ensureRepositoryVariables)(request, dependencies, setupConfiguration, remoteConfiguration); mark('variables', variables.errors.length ? 'needs-inspection' : variables.writes > 0 ? 'completed' : 'skipped'); if (variables.step) @@ -52328,7 +52342,7 @@ async function runInitialSetupWorkflow(request, dependencies) { if (variables.errors.length > 0) errors.push(...fromMessages(variables.errors, 'provider.unavailable')); if (setupConfiguration?.createInitialTag !== false) - mark('initial-tag', 'needs-inspection'); + mark('initial-tag', 'in-progress'); const defaultVersion = await ensureDefaultVersion(request, dependencies, setupConfiguration); mark('initial-tag', defaultVersion.error ? 'needs-inspection' : defaultVersion.step?.includes('created on branch') ? 'completed' : 'skipped'); @@ -57564,6 +57578,106 @@ function toEvent(input) { } +/***/ }), + +/***/ 70102: +/***/ ((__unused_webpack_module, exports) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.SetupSessionCoordinator = void 0; +/** Owns cross-frontend stage order, the write boundary and conservative outcomes. */ +class SetupSessionCoordinator { + constructor(ports) { + this.ports = ports; + this.running = false; + this.finished = false; + this.mutationStarted = false; + this.stage = 'repository'; + this.effects = new Map(); + } + async execute() { + if (this.running || this.finished) + throw new Error('Setup session can run only once.'); + this.running = true; + try { + const stages = [ + ['repository', this.ports.repository], + ['choices', this.ports.choices], + ['setup-pat', this.ports.setupPat], + ['plan', this.ports.plan], + ['credentials', () => this.ports.credentials(() => this.markPossibleMutation())], + ['apply', this.ports.authorizeApply], + ]; + for (const [stage, operation] of stages) { + this.stage = stage; + this.ports.present(stage, this.mutationStarted); + const before = this.liveOutcome(); + if (before) + return this.finish(before); + const decision = await operation(); + const after = this.liveOutcome(); + if (after) + return this.finish(after); + if (decision !== 'continue') + return this.finish(decision === 'dry-run' ? 'dry-run' : decision); + } + // The authorization operation must finish while the live session is active. + // The mutation marker is set before entering the provider boundary: a + // rejected/unknown request can already have reached GitHub. + this.markPossibleMutation(); + const receipt = await this.ports.apply(effect => this.record(effect)); + for (const effect of receipt.effects) + this.record(effect); + return this.finish(receipt.success && !this.hasUncertainEffect() ? 'complete' : 'partial'); + } + catch (error) { + const cancelled = this.ports.isCancellationError(error) || this.ports.liveness() === 'cancelled'; + return this.finish(this.mutationStarted ? 'partial' : cancelled ? 'cancelled' : 'blocked', error); + } + finally { + this.running = false; + this.finished = true; + } + } + liveOutcome() { + const state = this.ports.liveness(); + if (state === 'active') + return undefined; + return this.mutationStarted ? 'partial' : state === 'cancelled' ? 'cancelled' : 'blocked'; + } + markPossibleMutation() { + if (this.mutationStarted) + return; + this.mutationStarted = true; + this.ports.present(this.stage, true); + } + record(effect) { + const previous = this.effects.get(effect.id); + if (previous?.state === 'completed' && effect.state !== 'completed') + return; + this.effects.set(effect.id, Object.freeze({ ...effect })); + } + hasUncertainEffect() { + return [...this.effects.values()].some(effect => effect.state === 'needs-inspection' || effect.state === 'in-progress'); + } + finish(outcome, error) { + // An interrupted in-flight write must not be reported as no change. + const finalOutcome = this.mutationStarted && (outcome === 'cancelled' || outcome === 'blocked' + || (outcome === 'complete' && this.hasUncertainEffect())) ? 'partial' : outcome; + for (const [id, effect] of this.effects) { + if (effect.state === 'in-progress') + this.effects.set(id, Object.freeze({ ...effect, state: 'needs-inspection' })); + } + this.ports.present(this.stage, this.mutationStarted, finalOutcome); + return { outcome: finalOutcome, mutationStarted: this.mutationStarted, + effects: [...this.effects.values()], ...(error === undefined ? {} : { error }) }; + } +} +exports.SetupSessionCoordinator = SetupSessionCoordinator; + + /***/ }), /***/ 11797: @@ -57984,7 +58098,7 @@ class VerifySetupPatBootstrapUseCase { role: 'setup', owner: request.owner, repository: request.repository, expiresIn: 1, requirements: request.requirements, })); - throw new application_error_1.ApplicationError('authorization.credential-invalid', 'The setup PAT has missing or unconfirmed required access. Grant or explicitly confirm the permissions shown above and retry.'); + throw new application_error_1.ApplicationError('authorization.credential-invalid', 'The setup PAT has missing or unconfirmed required access. Review the permission report, correct or explicitly confirm the required grants, and retry.'); } if (!await this.ports.confirmAccount(report.account)) { throw new application_error_1.ApplicationError('authorization.credential-invalid', 'The setup PAT belongs to an unintended account. Revoke it in GitHub and retry with the correct account.'); @@ -67455,21 +67569,69 @@ function runReconcileCommand(options, workspace = new setup_workspace_adapter_1. Object.defineProperty(exports, "__esModule", ({ value: true })); exports.registerSetupCommand = registerSetupCommand; -const local_action_1 = __nccwpck_require__(76102); const product_identity_1 = __nccwpck_require__(18739); +const setup_command_options_1 = __nccwpck_require__(99254); +const setup_execution_1 = __nccwpck_require__(51293); +function registerSetupCommand(program) { + program + .command('setup') + .description(`${product_identity_1.TITLE} - Interactive repository setup: select workflows, agents, Variables, labels, and issue types`) + .option('-d, --debug', 'Debug mode', false) + .option('-t, --token ', 'Personal access token (or PERSONAL_ACCESS_TOKEN from the environment)') + .option('--agent ', 'Use one agent runtime for every setup task (codex|opencode|cursor)') + .option('--features ', 'Comma-separated setup features, or "all" (for non-interactive setup)') + .option('--issue-workflows ', 'Comma-separated issue workflow types, or "all" (for non-interactive setup)') + .option('--agent-guidance ', 'Generated agent guidance mode (prompt|create-if-missing|disabled)') + .option('--config ', 'YAML or JSON file with setup overrides') + .option('--pr-approval-mode ', 'PR bot approval: recommend (new setup default), guarded, or off') + .option('--pr-approval-check ', 'Exact test producer name|source-App-ID|workflow-name; repeat for multiple checks', setup_command_options_1.collectApprovalCheck, []) + .option('--pr-approval-coverage-check ', 'Exact selected check that enforces the coverage budget') + .option('--pr-approval-attest-producer', 'Confirm exact check/App/workflow identity and a coverage-enforcing CI step', false) + .option('--non-interactive', 'Use defaults and config-file values without prompting', false) + .option('--web', 'Run the optional local browser setup assistant (127.0.0.1 only)', false) + .option('--yes', 'Apply the plan without the final confirmation prompt', false) + .option('--confirm-unverifiable-write-permissions', 'Confirm that required PAT write permissions shown as Unverifiable were configured exactly as displayed', false) + .option('--dry-run', 'Show the setup plan without changing files or GitHub', false) + .option('--skip-variables', 'Do not create or update GitHub Repository Variables', false) + .option('--skip-secrets', 'Do not validate or create/update GitHub Repository Secrets', false) + .option('--variables-scope ', 'Default Variable scope (repository|organization)') + .option('--secrets-scope ', 'Default Secret scope (repository|organization)') + .option('--variables-visibility ', 'Organization Variable visibility (selected|private|all)') + .option('--secrets-visibility ', 'Organization Secret visibility (selected|private|all)') + .option('--variable-scope ', 'Per-variable scope override; repeat as needed', setup_command_options_1.collectScope, {}) + .option('--secret-scope ', 'Per-secret scope override; repeat as needed', setup_command_options_1.collectScope, {}) + .option('--update-workflows', 'Allow setup-managed workflows already in the repository to be updated', false) + .option('--workflow-pat ', 'Workflow PAT for the bot account (prefer the hidden interactive prompt)') + .option('--secret ', 'Secret value for non-interactive setup; repeat for each API key', setup_command_options_1.collectSecret, {}) + .action(setup_execution_1.executeSetupCommand); +} + + +/***/ }), + +/***/ 51293: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.executeSetupCommand = executeSetupCommand; +const local_action_1 = __nccwpck_require__(76102); const setup_files_1 = __nccwpck_require__(59126); const logger_1 = __nccwpck_require__(91151); const cli_context_1 = __nccwpck_require__(21307); const setup_policy_1 = __nccwpck_require__(28732); const setup_command_options_1 = __nccwpck_require__(99254); const setup_1 = __nccwpck_require__(36888); +const setup_session_coordinator_1 = __nccwpck_require__(70102); const setup_configuration_plan_1 = __nccwpck_require__(87770); -const prepare_setup_pat_intent_use_case_1 = __nccwpck_require__(69277); +const setup_pat_intent_adapter_1 = __nccwpck_require__(67610); const audit_configured_setup_pat_use_case_1 = __nccwpck_require__(60830); const verify_setup_pat_bootstrap_use_case_1 = __nccwpck_require__(23388); const setup_configuration_policy_1 = __nccwpck_require__(56637); const setup_token_permission_policy_1 = __nccwpck_require__(99590); const setup_credentials_composition_root_1 = __nccwpck_require__(69084); +const setup_credential_collection_1 = __nccwpck_require__(19469); const setup_doctor_composition_root_1 = __nccwpck_require__(56360); const setup_workspace_adapter_1 = __nccwpck_require__(5729); const setup_approval_readiness_adapter_1 = __nccwpck_require__(78572); @@ -67484,10 +67646,7 @@ const setup_credential_prompt_adapter_1 = __nccwpck_require__(93232); const setup_workflow_update_prompt_adapter_1 = __nccwpck_require__(84473); const setup_token_permission_presenter_1 = __nccwpck_require__(63206); const setup_token_permissions_composition_root_1 = __nccwpck_require__(64132); -const setup_pat_creation_url_policy_1 = __nccwpck_require__(54718); -const setup_github_identity_query_adapter_1 = __nccwpck_require__(56098); -const verify_guided_workflow_pat_identity_use_case_1 = __nccwpck_require__(35697); -const verify_web_setup_apply_use_case_1 = __nccwpck_require__(5303); +const setup_apply_authorization_1 = __nccwpck_require__(75885); const setup_journey_use_case_1 = __nccwpck_require__(8419); const setup_journey_policy_1 = __nccwpck_require__(53289); const setup_journey_presenter_1 = __nccwpck_require__(20462); @@ -67497,447 +67656,319 @@ const setup_session_guard_1 = __nccwpck_require__(53104); const web_setup_server_1 = __nccwpck_require__(63080); const web_setup_adapters_1 = __nccwpck_require__(60574); const setup_result_receipt_1 = __nccwpck_require__(44132); -function registerSetupCommand(program) { - program - .command('setup') - .description(`${product_identity_1.TITLE} - Interactive repository setup: select workflows, agents, Variables, labels, and issue types`) - .option('-d, --debug', 'Debug mode', false) - .option('-t, --token ', 'Personal access token (or PERSONAL_ACCESS_TOKEN from the environment)') - .option('--agent ', 'Use one agent runtime for every setup task (codex|opencode|cursor)') - .option('--features ', 'Comma-separated setup features, or "all" (for non-interactive setup)') - .option('--issue-workflows ', 'Comma-separated issue workflow types, or "all" (for non-interactive setup)') - .option('--agent-guidance ', 'Generated agent guidance mode (prompt|create-if-missing|disabled)') - .option('--config ', 'YAML or JSON file with setup overrides') - .option('--pr-approval-mode ', 'PR bot approval: recommend (new setup default), guarded, or off') - .option('--pr-approval-check ', 'Exact test producer name|source-App-ID|workflow-name; repeat for multiple checks', setup_command_options_1.collectApprovalCheck, []) - .option('--pr-approval-coverage-check ', 'Exact selected check that enforces the coverage budget') - .option('--pr-approval-attest-producer', 'Confirm exact check/App/workflow identity and a coverage-enforcing CI step', false) - .option('--non-interactive', 'Use defaults and config-file values without prompting', false) - .option('--web', 'Run the optional local browser setup assistant (127.0.0.1 only)', false) - .option('--yes', 'Apply the plan without the final confirmation prompt', false) - .option('--confirm-unverifiable-write-permissions', 'Confirm that required PAT write permissions shown as Unverifiable were configured exactly as displayed', false) - .option('--dry-run', 'Show the setup plan without changing files or GitHub', false) - .option('--skip-variables', 'Do not create or update GitHub Repository Variables', false) - .option('--skip-secrets', 'Do not validate or create/update GitHub Repository Secrets', false) - .option('--variables-scope ', 'Default Variable scope (repository|organization)') - .option('--secrets-scope ', 'Default Secret scope (repository|organization)') - .option('--variables-visibility ', 'Organization Variable visibility (selected|private|all)') - .option('--secrets-visibility ', 'Organization Secret visibility (selected|private|all)') - .option('--variable-scope ', 'Per-variable scope override; repeat as needed', setup_command_options_1.collectScope, {}) - .option('--secret-scope ', 'Per-secret scope override; repeat as needed', setup_command_options_1.collectScope, {}) - .option('--update-workflows', 'Allow setup-managed workflows already in the repository to be updated', false) - .option('--workflow-pat ', 'Workflow PAT for the bot account (prefer the hidden interactive prompt)') - .option('--secret ', 'Secret value for non-interactive setup; repeat for each API key', setup_command_options_1.collectSecret, {}) - .action(async (options) => { - const terminal = options.nonInteractive || options.web ? undefined : (0, setup_terminal_driver_1.createInteractiveTerminalDriver)(); - const webBridge = options.web ? new web_setup_bridge_1.WebSetupBridge('Resolving repository…') : undefined; - let webServer; - const credentialPrompt = webBridge ? new web_setup_adapters_1.WebSetupCredentialPrompt(webBridge) : new setup_credential_prompt_adapter_1.SetupCredentialPromptAdapter(terminal, { - ...(options.workflowPat ? { PAT: options.workflowPat } : {}), - ...options.secret, - }, Boolean(options.confirmUnverifiableWritePermissions)); - const permissionPresenter = webBridge ? new web_setup_adapters_1.WebSetupPermissionPresenter(webBridge) - : new setup_token_permission_presenter_1.ConsoleSetupTokenPermissionPresenter(options.nonInteractive ? 'full' : 'summary'); - const tokenPermissions = (0, setup_token_permissions_composition_root_1.createSetupTokenPermissionsUseCase)(); - const workflowPrompt = webBridge ? new web_setup_adapters_1.WebSetupWorkflowUpdatePrompt(webBridge) : new setup_workflow_update_prompt_adapter_1.SetupWorkflowUpdatePromptAdapter(terminal); - const cwd = process.cwd(); - let setupMutationStarted = false; - let setupApplyStarted = false; - let releaseSetupGuard; - let journey; - try { - if (options.web && (options.nonInteractive || options.yes || options.token || options.workflowPat - || Object.keys(options.secret ?? {}).length || options.confirmUnverifiableWritePermissions)) { - throw new application_error_1.ApplicationError('configuration.invalid', '--web cannot be combined with --non-interactive, --yes, --token, --workflow-pat, --secret, or --confirm-unverifiable-write-permissions. Use the browser for these decisions or run copilot setup in the terminal.'); - } - (0, logger_1.logInfo)('🔍 Checking we are inside a git repository...'); - if (!(0, cli_context_1.isInsideGitRepo)(cwd)) { - (0, logger_1.logError)('❌ Not a git repository. Run "copilot setup" from the root of a git repo.'); - process.exitCode = 1; - return; - } - (0, logger_1.logInfo)('✅ Git repository detected.'); - (0, logger_1.logInfo)('🔗 Resolving repository (owner/repo)...'); - const gitInfo = (0, cli_context_1.getGitInfo)(); - if ('error' in gitInfo) { - (0, logger_1.logError)(gitInfo.error); - process.exitCode = 1; - return; - } - (0, logger_1.logInfo)(`📦 Repository: ${gitInfo.owner}/${gitInfo.repo}`); - const checkoutRoot = webBridge ? (0, cli_context_1.getGitRepositoryRoot)(cwd) : cwd; - if (webBridge && !(0, cli_context_1.isGitRepositoryRoot)(cwd)) { - throw new application_error_1.ApplicationError('configuration.invalid', `Web setup must start from the repository root (${checkoutRoot}). Change to that directory and rerun before creating PATs. No local setup session started.`); - } - releaseSetupGuard = (0, setup_session_guard_1.acquireSetupSessionGuard)(cwd); - const initialBranch = webBridge ? (0, cli_context_1.getCurrentAttachedBranch)(cwd) : undefined; - const initialHead = webBridge ? (0, cli_context_1.getCurrentHeadSha)() : undefined; - if (webBridge && (!initialBranch || !initialHead)) { - throw new application_error_1.ApplicationError('configuration.invalid', 'An attached Git branch and revision are required for web setup. Check out a branch before creating PATs. No local setup session started.'); - } - if (webBridge) { - webBridge.setRepository(`${gitInfo.owner}/${gitInfo.repo}`); - webBridge.setJourney((0, setup_journey_policy_1.buildSetupJourneyView)(`${gitInfo.owner}/${gitInfo.repo}`, 'repository', false)); - webServer = await (0, web_setup_server_1.startWebSetupServer)(webBridge); - (0, logger_1.logInfo)(`🌐 Local setup assistant: ${webServer.url}`); - (0, logger_1.logInfo)(`🔑 Browser pairing code: ${webServer.pairingCode}`, false, undefined, true); - (0, logger_1.logInfo)('If the browser does not open, copy this URL into a browser on this computer, then enter the pairing code shown above. The terminal setup remains available with copilot setup.'); - (0, web_setup_server_1.openWebSetupBrowser)(webServer.url); - } - if (!options.nonInteractive) { - journey = new setup_journey_use_case_1.SetupJourneyUseCase(`${gitInfo.owner}/${gitInfo.repo}`, webBridge ? new web_setup_adapters_1.WebSetupJourneyPresenter(webBridge) : new setup_journey_presenter_1.ConsoleSetupJourneyPresenter()); +const setup_outcome_adapter_1 = __nccwpck_require__(9961); +async function executeSetupCommand(options) { + const terminal = options.nonInteractive || options.web ? undefined : (0, setup_terminal_driver_1.createInteractiveTerminalDriver)(); + const webBridge = options.web ? new web_setup_bridge_1.WebSetupBridge('Resolving repository…') : undefined; + let webServer; + const credentialPrompt = webBridge ? new web_setup_adapters_1.WebSetupCredentialPrompt(webBridge) : new setup_credential_prompt_adapter_1.SetupCredentialPromptAdapter(terminal, { + ...(options.workflowPat ? { PAT: options.workflowPat } : {}), + ...options.secret, + }, Boolean(options.confirmUnverifiableWritePermissions)); + const permissionPresenter = webBridge ? new web_setup_adapters_1.WebSetupPermissionPresenter(webBridge) + : new setup_token_permission_presenter_1.ConsoleSetupTokenPermissionPresenter(options.nonInteractive ? 'full' : 'summary'); + const tokenPermissions = (0, setup_token_permissions_composition_root_1.createSetupTokenPermissionsUseCase)(); + const workflowPrompt = webBridge ? new web_setup_adapters_1.WebSetupWorkflowUpdatePrompt(webBridge) : new setup_workflow_update_prompt_adapter_1.SetupWorkflowUpdatePromptAdapter(terminal); + const cwd = process.cwd(); + let setupMutationStarted = false; + let setupApplyStarted = false; + let releaseSetupGuard; + let journey; + let gitInfo; + let checkoutRoot = cwd; + let initialBranch; + let initialHead; + let overrides; + let presentationMode = 'custom'; + let setupPatPermissions = (0, setup_token_permission_policy_1.buildSetupPatPermissionRequirements)(); + let token; + let setupPatAccount; + let permissionIntent; + let assertedOwnerKind; + let auditConfiguredSetupPat; + let remoteConfigurationReader; + let configuration; + let remoteConfiguration; + let guardedFiles; + let webApplySnapshot; + let approvedWorkflowFiles = []; + let credentialsCollection; + try { + const session = new setup_session_coordinator_1.SetupSessionCoordinator({ + repository: async () => { + if (options.web && (options.nonInteractive || options.yes || options.token || options.workflowPat + || Object.keys(options.secret ?? {}).length || options.confirmUnverifiableWritePermissions)) { + throw new application_error_1.ApplicationError('configuration.invalid', '--web cannot be combined with --non-interactive, --yes, --token, --workflow-pat, --secret, or --confirm-unverifiable-write-permissions. Use the browser for these decisions or run copilot setup in the terminal.'); + } + (0, logger_1.logInfo)('🔍 Checking we are inside a git repository...'); + if (!(0, cli_context_1.isInsideGitRepo)(cwd)) { + (0, logger_1.logError)('❌ Not a git repository. Run "copilot setup" from the root of a git repo.'); + process.exitCode = 1; + return 'blocked'; + } + (0, logger_1.logInfo)('✅ Git repository detected.'); + (0, logger_1.logInfo)('🔗 Resolving repository (owner/repo)...'); + const resolvedGitInfo = (0, cli_context_1.getGitInfo)(); + if ('error' in resolvedGitInfo) { + (0, logger_1.logError)(resolvedGitInfo.error); + process.exitCode = 1; + return 'blocked'; + } + gitInfo = resolvedGitInfo; + (0, logger_1.logInfo)(`📦 Repository: ${gitInfo.owner}/${gitInfo.repo}`); + checkoutRoot = webBridge ? (0, cli_context_1.getGitRepositoryRoot)(cwd) : cwd; + if (webBridge && !(0, cli_context_1.isGitRepositoryRoot)(cwd)) { + throw new application_error_1.ApplicationError('configuration.invalid', `Web setup must start from the repository root (${checkoutRoot}). Change to that directory and rerun before creating PATs. No local setup session started.`); + } + releaseSetupGuard = (0, setup_session_guard_1.acquireSetupSessionGuard)(cwd); + initialBranch = webBridge ? (0, cli_context_1.getCurrentAttachedBranch)(cwd) : undefined; + initialHead = webBridge ? (0, cli_context_1.getCurrentHeadSha)() : undefined; + if (webBridge && (!initialBranch || !initialHead)) { + throw new application_error_1.ApplicationError('configuration.invalid', 'An attached Git branch and revision are required for web setup. Check out a branch before creating PATs. No local setup session started.'); + } if (webBridge) { - const target = await webBridge.ask({ kind: 'confirm', title: 'Confirm this repository', copyId: 'repository.confirm', copyValues: { repository: `${gitInfo.owner}/${gitInfo.repo}`, branch: initialBranch ?? '' }, - description: `This local checkout resolves to ${gitInfo.owner}/${gitInfo.repo} on branch ${initialBranch}. Confirm the target before configuring PAT access or files.`, - choices: ['Yes, this is my repository', 'Stop and choose another checkout'] }); - if (target === undefined) - throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); - if (target !== 'Yes, this is my repository') { - journey.finish('cancelled'); - return; + webBridge.setRepository(`${gitInfo.owner}/${gitInfo.repo}`); + webBridge.setJourney((0, setup_journey_policy_1.buildSetupJourneyView)(`${gitInfo.owner}/${gitInfo.repo}`, 'repository', false)); + webServer = await (0, web_setup_server_1.startWebSetupServer)(webBridge); + (0, logger_1.logInfo)(`🌐 Local setup assistant: ${webServer.url}`); + (0, logger_1.logInfo)(`🔑 Browser pairing code: ${webServer.pairingCode}`, false, undefined, true); + (0, logger_1.logInfo)('If the browser does not open, copy this URL into a browser on this computer, then enter the pairing code shown above. The terminal setup remains available with copilot setup.'); + (0, web_setup_server_1.openWebSetupBrowser)(webServer.url); + } + if (!options.nonInteractive) { + journey = new setup_journey_use_case_1.SetupJourneyUseCase(`${gitInfo.owner}/${gitInfo.repo}`, webBridge ? new web_setup_adapters_1.WebSetupJourneyPresenter(webBridge) : new setup_journey_presenter_1.ConsoleSetupJourneyPresenter()); + if (webBridge) { + const target = await webBridge.ask({ kind: 'confirm', title: 'Confirm this repository', copyId: 'repository.confirm', copyValues: { repository: `${gitInfo.owner}/${gitInfo.repo}`, branch: initialBranch ?? '' }, + description: `This local checkout resolves to ${gitInfo.owner}/${gitInfo.repo} on branch ${initialBranch}. Confirm the target before configuring PAT access or files.`, + choices: ['Yes, this is my repository', 'Stop and choose another checkout'] }); + if (target === undefined) + throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); + if (target !== 'Yes, this is my repository') + return 'cancelled'; } } - journey.advance('choices'); - } - const overrides = (0, setup_command_options_1.loadSetupOverrides)(options); - let presentationMode = 'custom'; - if (!options.nonInteractive && !options.dryRun) { - if (webBridge) { - const depth = await webBridge.ask({ kind: 'choice', title: 'Choose setup detail', copyId: 'setup.depth', - choices: ['Basic guided setup', 'Customize every setting'], defaultValue: 'Basic guided setup' }); - if (depth === undefined) - throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); - presentationMode = depth === 'Basic guided setup' ? 'basic' : 'custom'; + return 'continue'; + }, + choices: async () => { + overrides = (0, setup_command_options_1.loadSetupOverrides)(options); + if (!options.nonInteractive && !options.dryRun) { + if (webBridge) { + const depth = await webBridge.ask({ kind: 'choice', title: 'Choose setup detail', copyId: 'setup.depth', + choices: ['Basic guided setup', 'Customize every setting'], defaultValue: 'Basic guided setup' }); + if (depth === undefined) + throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); + presentationMode = depth === 'Basic guided setup' ? 'basic' : 'custom'; + } + else if (credentialPrompt instanceof setup_credential_prompt_adapter_1.SetupCredentialPromptAdapter) { + presentationMode = await credentialPrompt.chooseSetupPresentationMode(); + } } - else if (credentialPrompt instanceof setup_credential_prompt_adapter_1.SetupCredentialPromptAdapter) { - presentationMode = await credentialPrompt.chooseSetupPresentationMode(); + token = (0, setup_files_1.getSetupToken)(cwd, options.token); + if (webBridge && token) { + const choice = await webBridge.ask({ kind: 'choice', title: 'An environment setup PAT is available', copyId: 'setup.environmentPat', + description: 'Its value stays in the CLI process and is never sent to this page. Exiting Copilot cannot unset your parent shell variable.', + choices: ['Use the environment PAT', 'Create or enter a different PAT'] }); + if (choice === undefined) + throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); + if (choice !== 'Use the environment PAT') + token = undefined; } - } - let setupPatPermissions = (0, setup_token_permission_policy_1.buildSetupPatPermissionRequirements)(); - let token = (0, setup_files_1.getSetupToken)(cwd, options.token); - if (webBridge && token) { - const choice = await webBridge.ask({ kind: 'choice', title: 'An environment setup PAT is available', copyId: 'setup.environmentPat', - description: 'Its value stays in the CLI process and is never sent to this page. Exiting Copilot cannot unset your parent shell variable.', - choices: ['Use the environment PAT', 'Create or enter a different PAT'] }); - if (choice === undefined) - throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); - if (choice !== 'Use the environment PAT') - token = undefined; - } - if (token || options.nonInteractive) - permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); - else - permissionPresenter.showRequirements('setup', setupPatPermissions); - let setupPatAccount; - let permissionIntent; - let assertedOwnerKind; - if (!token && !options.nonInteractive && !options.dryRun) { - if (await credentialPrompt.chooseSetupPatMethod() === 'guided') { - const prepared = await new prepare_setup_pat_intent_use_case_1.PrepareSetupPatIntentUseCase({ - collect: (initial, context, pass) => (webBridge - ? new web_setup_adapters_1.WebSetupQuestionnaireCollector(webBridge, pass) - : new setup_1.SetupQuestionnaireController(terminal, new setup_question_renderer_1.ConsoleSetupQuestionRenderer('permission-intent', pass))) - .collect(initial, context), - chooseOwnerKind: () => credentialPrompt.chooseSetupOwnerKind(), - review: () => credentialPrompt.reviewSetupPatIntent(), - showPreview: ({ draft, requirements, uncertain, ownerConflict, errors, pass, projectsWanted }) => { - if (ownerConflict) - (0, logger_1.logInfo)('This plan selects organization storage or Projects, but the owner was declared a personal account. Revise the choices or use the manual PAT path.'); - if (errors.length) - (0, logger_1.logInfo)(`The selected local configuration needs correction before a guided link can be generated:\n${errors.map(item => ` - ${item}`).join('\n')}`); - if (pass > 1) - (0, logger_1.logInfo)('Choice review complete. Returning to setup PAT permission review.'); - (0, logger_1.logInfo)('Permission intent:'); - (0, logger_1.logInfo)(` Initial tag: ${draft.createInitialTag ? 'yes' : 'no'}; issue workflows: ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval: ${draft.pullRequestApproval.mode}`); - (0, logger_1.logInfo)(` Secrets: ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables: ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects: ${projectsWanted ? 'yes (choose exact Projects after PAT)' : 'none'}`); - webBridge?.message(`Permission preview: issue workflows ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval ${draft.pullRequestApproval.mode}; Secrets ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects ${projectsWanted ? 'yes (choose after PAT)' : 'none'}.`, 'info', undefined, 'permission.preview', { - issues: draft.features.issues ? draft.issueWorkflows.enabled.join('|') || 'none' : 'disabled', - approval: draft.pullRequestApproval.mode, - secrets: draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off', - variables: draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off', - projects: projectsWanted ? 'yes' : 'none', - }); - permissionPresenter.showRequirements('setup', requirements); - if (uncertain.length) - (0, logger_1.logInfo)(`May need after GitHub inspection:\n${uncertain.map(item => ` - ${item}`).join('\n')}`); - }, - showDetails: requirements => permissionPresenter.showDetailedRequirements('setup', requirements), - onManual: reason => { - if (reason === 'owner-unknown') - (0, logger_1.logInfo)('Owner type was not confirmed. Use the manual PAT table, or check whether the GitHub owner is an organization before retrying guided setup.'); - if (reason === 'unsupported') - (0, logger_1.logInfo)('A guided setup PAT link is unavailable for this owner or permission set. Enter a manually created PAT using the table above.'); - credentialPrompt.useManualSetupPat(); - permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); - }, - advanceToSetupPat: () => { journey?.advance('setup-pat'); }, - revisitChoices: () => journey.revisitChoices(), - }).execute({ + if (token || options.nonInteractive) + permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); + else + permissionPresenter.showRequirements('setup', setupPatPermissions); + if (!token && !options.nonInteractive && !options.dryRun) { + const intent = await (0, setup_pat_intent_adapter_1.collectSetupPatIntent)({ owner: gitInfo.owner, repository: gitInfo.repo, overrides, skipRepositoryVariables: Boolean(options.skipVariables), skipRepositorySecrets: Boolean(options.skipSecrets), + terminal, bridge: webBridge, journey, credentialPrompt, permissionPresenter, + initialRequirements: setupPatPermissions, }); - if (prepared.kind === 'guided') { - credentialPrompt.configureSetupPatGuide(prepared.url); - setupPatPermissions = [...prepared.requirements]; - assertedOwnerKind = prepared.ownerKind; - permissionIntent = prepared.permissionIntent; - } + setupPatPermissions = [...intent.requirements]; + assertedOwnerKind = intent.assertedOwnerKind; + permissionIntent = intent.permissionIntent; } - else { - journey?.advance('setup-pat'); - permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); + return 'continue'; + }, + setupPat: async () => { + if (!token && !options.nonInteractive && !options.dryRun) + token = await credentialPrompt.requestSetupPat(); + if (!token && !options.dryRun) { + (0, logger_1.logError)('🛑 Setup requires PERSONAL_ACCESS_TOKEN with a valid token.'); + (0, logger_1.logInfo)(' You can:'); + (0, logger_1.logInfo)(' • Pass it on the command line: copilot setup --token '); + (0, logger_1.logInfo)(' • Add it to your environment: export PERSONAL_ACCESS_TOKEN=your_github_token'); + process.exitCode = 1; + return 'blocked'; } - } - if (options.dryRun && !token && !webBridge) - journey?.advance('plan'); - if (!token && !options.dryRun) - journey?.advance('setup-pat'); - if (!token && !options.nonInteractive && !options.dryRun) - token = await credentialPrompt.requestSetupPat(); - if (!token && !options.dryRun) { - (0, logger_1.logError)('🛑 Setup requires PERSONAL_ACCESS_TOKEN with a valid token.'); - (0, logger_1.logInfo)(' You can:'); - (0, logger_1.logInfo)(' • Pass it on the command line: copilot setup --token '); - (0, logger_1.logInfo)(' • Add it to your environment: export PERSONAL_ACCESS_TOKEN=your_github_token'); - process.exitCode = 1; - return; - } - if (token) { - journey?.advance('setup-pat'); - setupPatAccount = await new verify_setup_pat_bootstrap_use_case_1.VerifySetupPatBootstrapUseCase({ + if (token) { + setupPatAccount = await new verify_setup_pat_bootstrap_use_case_1.VerifySetupPatBootstrapUseCase({ + permissions: tokenPermissions, + presenter: permissionPresenter, + confirmUnverifiable: report => credentialPrompt.confirmUnverifiableTokenPermissions(report), + confirmAccount: account => credentialPrompt.confirmGuidedSetupAccount(account), + showCorrectedLink: url => credentialPrompt.showUpdatedSetupPatLink(url, 'bootstrap'), + }).execute({ owner: gitInfo.owner, repository: gitInfo.repo, token, + requirements: setupPatPermissions, guided: credentialPrompt.usedGuidedSetupPat }); + } + return 'continue'; + }, + plan: async () => { + (0, logger_1.logInfo)(options.dryRun ? '🧭 Building a dry-run setup plan...' : '🧭 Building your setup plan...'); + auditConfiguredSetupPat = new audit_configured_setup_pat_use_case_1.AuditConfiguredSetupPatUseCase({ + owner: gitInfo.owner, repository: gitInfo.repo, token, + provisionalRequirements: setupPatPermissions, assertedOwnerKind, + guided: credentialPrompt.usedGuidedSetupPat, + }, { permissions: tokenPermissions, presenter: permissionPresenter, confirmUnverifiable: report => credentialPrompt.confirmUnverifiableTokenPermissions(report), - confirmAccount: account => credentialPrompt.confirmGuidedSetupAccount(account), - showCorrectedLink: url => credentialPrompt.showUpdatedSetupPatLink(url, 'bootstrap'), - }).execute({ owner: gitInfo.owner, repository: gitInfo.repo, token, - requirements: setupPatPermissions, guided: credentialPrompt.usedGuidedSetupPat }); - journey?.advance('plan'); - } - (0, logger_1.logInfo)(options.dryRun ? '🧭 Building a dry-run setup plan...' : '🧭 Building your setup plan...'); - const auditConfiguredSetupPat = new audit_configured_setup_pat_use_case_1.AuditConfiguredSetupPatUseCase({ - owner: gitInfo.owner, repository: gitInfo.repo, token, - provisionalRequirements: setupPatPermissions, assertedOwnerKind, - guided: credentialPrompt.usedGuidedSetupPat, - }, { - permissions: tokenPermissions, - presenter: permissionPresenter, - confirmUnverifiable: report => credentialPrompt.confirmUnverifiableTokenPermissions(report), - showOwnerMismatch: (asserted, actual) => (0, logger_1.logInfo)(`The owner was declared ${asserted}, but GitHub reports ${actual}. The guided link is no longer valid for this plan.`), - showExcessGrants: grants => (0, logger_1.logInfo)(`The final plan no longer requires grants suggested earlier: ${grants.join(', ')}. Your PAT may have excess access; replace it in GitHub if least privilege is required.`), - showUpdatedLink: (url, grants) => credentialPrompt.showUpdatedSetupPatLink(url, 'final', grants), - }); - const remoteConfigurationReader = (0, setup_credentials_composition_root_1.createSetupRemoteConfigurationReadPort)(); - const wizard = new setup_1.SetupWizardUseCase({ - ...(terminal || webBridge ? { - collector: webBridge ? new web_setup_adapters_1.WebSetupQuestionnaireCollector(webBridge) - : new setup_1.SetupQuestionnaireController(terminal, new setup_question_renderer_1.ConsoleSetupQuestionRenderer()), - } : {}), - planPresenter: webBridge ? new web_setup_adapters_1.WebSetupPlanPresenter(webBridge) : new setup_plan_presenter_1.ConsoleSetupPlanPresenter(), - confirmation: options.dryRun - ? new setup_confirmation_adapter_1.DryRunSetupPlanConfirmation() - : webBridge ? new web_setup_adapters_1.WebSetupPlanConfirmation(webBridge) - : new setup_confirmation_adapter_1.SetupPlanConfirmationAdapter(terminal, Boolean(options.yes)), - finalPermissionAudit: auditConfiguredSetupPat, - remoteConfiguration: remoteConfigurationReader, - mergeQueueReadiness: (0, setup_doctor_composition_root_1.createSetupMergeQueueReadinessUseCase)(), - approvalReadiness: new setup_approval_readiness_adapter_1.GithubSetupApprovalReadinessAdapter(), - approvalCheckDiscovery: new github_setup_approval_check_discovery_adapter_1.GithubSetupApprovalCheckDiscoveryAdapter(), - projectDiscovery: new github_setup_project_discovery_adapter_1.GithubSetupProjectDiscoveryAdapter(), - }); - const result = await wizard.execute({ - mode: options.nonInteractive ? 'non-interactive' : 'interactive', - overrides, - ...(permissionIntent ? { permissionIntent } : {}), - skipRepositoryVariables: Boolean(options.skipVariables), - skipRepositorySecrets: Boolean(options.skipSecrets), - previewOnly: Boolean(options.dryRun), - presentationMode, - developmentBranchObservedLocally: (0, cli_context_1.hasLocalOrTrackedGitBranch)(cwd, overrides.repository?.developmentBranch ?? 'develop'), - ...(token ? { remoteTarget: { owner: gitInfo.owner, repository: gitInfo.repo, token } } : {}), - }); - if (result.status === 'cancelled') { - journey?.finish('cancelled'); - if (result.reason !== 'questionnaire-cancelled') { - (0, logger_1.logInfo)('⏭️ Setup cancelled. No changes were applied.'); + showOwnerMismatch: (asserted, actual) => (0, logger_1.logInfo)(`The owner was declared ${asserted}, but GitHub reports ${actual}. The guided link is no longer valid for this plan.`), + showExcessGrants: grants => (0, logger_1.logInfo)(`The final plan no longer requires grants suggested earlier: ${grants.join(', ')}. Your PAT may have excess access; replace it in GitHub if least privilege is required.`), + showUpdatedLink: (url, grants) => credentialPrompt.showUpdatedSetupPatLink(url, 'final', grants), + }); + remoteConfigurationReader = (0, setup_credentials_composition_root_1.createSetupRemoteConfigurationReadPort)(); + const wizard = new setup_1.SetupWizardUseCase({ + ...(terminal || webBridge ? { + collector: webBridge ? new web_setup_adapters_1.WebSetupQuestionnaireCollector(webBridge) + : new setup_1.SetupQuestionnaireController(terminal, new setup_question_renderer_1.ConsoleSetupQuestionRenderer()), + } : {}), + planPresenter: webBridge ? new web_setup_adapters_1.WebSetupPlanPresenter(webBridge) : new setup_plan_presenter_1.ConsoleSetupPlanPresenter(), + confirmation: options.dryRun + ? new setup_confirmation_adapter_1.DryRunSetupPlanConfirmation() + : webBridge ? new web_setup_adapters_1.WebSetupPlanConfirmation(webBridge) + : new setup_confirmation_adapter_1.SetupPlanConfirmationAdapter(terminal, Boolean(options.yes)), + finalPermissionAudit: auditConfiguredSetupPat, + remoteConfiguration: remoteConfigurationReader, + mergeQueueReadiness: (0, setup_doctor_composition_root_1.createSetupMergeQueueReadinessUseCase)(), + approvalReadiness: new setup_approval_readiness_adapter_1.GithubSetupApprovalReadinessAdapter(), + approvalCheckDiscovery: new github_setup_approval_check_discovery_adapter_1.GithubSetupApprovalCheckDiscoveryAdapter(), + projectDiscovery: new github_setup_project_discovery_adapter_1.GithubSetupProjectDiscoveryAdapter(), + }); + const result = await wizard.execute({ + mode: options.nonInteractive ? 'non-interactive' : 'interactive', + overrides, + ...(permissionIntent ? { permissionIntent } : {}), + skipRepositoryVariables: Boolean(options.skipVariables), + skipRepositorySecrets: Boolean(options.skipSecrets), + previewOnly: Boolean(options.dryRun), + presentationMode, + developmentBranchObservedLocally: (0, cli_context_1.hasLocalOrTrackedGitBranch)(cwd, overrides.repository?.developmentBranch ?? 'develop'), + ...(token ? { remoteTarget: { owner: gitInfo.owner, repository: gitInfo.repo, token } } : {}), + }); + if (result.status === 'cancelled') { + if (result.reason !== 'questionnaire-cancelled') { + (0, logger_1.logInfo)('⏭️ Setup cancelled. No changes were applied.'); + } + if (result.exitCode !== 0) + process.exitCode = result.exitCode; + return 'cancelled'; } - if (result.exitCode !== 0) + if (result.status === 'blocked') { + webBridge?.resultReason(result.reason === 'setup-permissions-unavailable' ? 'permissions' : 'storage'); + (0, logger_1.logError)(new application_error_1.ApplicationError(result.reason === 'setup-permissions-unavailable' ? 'authorization.credential-invalid' : 'provider.unavailable', `${result.reason === 'setup-permissions-unavailable' + ? 'Setup is blocked by missing or unconfirmed PAT permissions:' + : 'Setup is blocked by unavailable remote storage:'}\n${result.errors.map(error => `- ${error}`).join('\n')}`)); process.exitCode = result.exitCode; - return; - } - if (result.status === 'blocked') { - journey?.finish('blocked'); - webBridge?.resultReason(result.reason === 'setup-permissions-unavailable' ? 'permissions' : 'storage'); - (0, logger_1.logError)(new application_error_1.ApplicationError(result.reason === 'setup-permissions-unavailable' ? 'authorization.credential-invalid' : 'provider.unavailable', `${result.reason === 'setup-permissions-unavailable' - ? 'Setup is blocked by missing or unconfirmed PAT permissions:' - : 'Setup is blocked by unavailable remote storage:'}\n${result.errors.map(error => `- ${error}`).join('\n')}`)); - process.exitCode = result.exitCode; - return; - } - const { configuration, remoteConfiguration } = result; - const guardedFiles = webBridge ? (0, setup_configuration_plan_1.setupPlanGuardPaths)(result.plan) : undefined; - const webApplySnapshot = guardedFiles ? (0, setup_apply_snapshot_1.captureSetupApplySnapshot)(checkoutRoot, guardedFiles) : undefined; - const credentialRequirements = (0, setup_configuration_policy_1.buildSetupCredentialRequirements)(configuration); - const workflowComparisons = new setup_workspace_adapter_1.SetupDoctorWorkspaceQueryAdapter().compareWorkflows((0, setup_configuration_policy_1.effectiveIssueWorkflowFeatures)(configuration), configuration); - const updateWorkflows = await workflowPrompt.confirmWorkflowUpdates(workflowComparisons, Boolean(options.updateWorkflows)); - const approvedWorkflowFiles = updateWorkflows - ? workflowComparisons.filter(comparison => comparison.status === 'changed').map(comparison => comparison.file) - : []; - if (options.dryRun) { - if (webBridge) - journey?.advance('plan'); - journey?.finish('dry-run'); - (0, logger_1.logInfo)('✅ Dry run complete. No files or GitHub resources were changed.'); - return; - } - journey?.advance('credentials'); - const workflowTokenPermissions = (0, setup_token_permission_policy_1.buildWorkflowPatPermissionRequirements)(configuration, remoteConfiguration); - const githubIdentities = new setup_github_identity_query_adapter_1.SetupGithubIdentityQueryAdapter(); - if (!options.nonInteractive && !options.workflowPat && !options.secret?.PAT) { - try { - const workflowPatGuide = (0, setup_pat_creation_url_policy_1.buildSetupPatCreationUrl)({ - role: 'workflow', owner: gitInfo.owner, repository: gitInfo.repo, expiresIn: 90, - requirements: workflowTokenPermissions, - }); - credentialPrompt.configureWorkflowPatGuide(workflowPatGuide, login => githubIdentities.resolve(login, token), workflowTokenPermissions); - } - catch (error) { - if (!(error instanceof setup_pat_creation_url_policy_1.UnsupportedSetupPatLinkError)) - throw error; - (0, logger_1.logInfo)('A guided fine-grained bot PAT link is unavailable for one or more required permissions. Use the permission table and manual path; review whether a classic PAT is required for this plan.'); - permissionPresenter.showDetailedRequirements('workflow', workflowTokenPermissions); + return 'blocked'; } - } - const credentials = await (0, setup_credentials_composition_root_1.createSetupCredentialsUseCase)(credentialPrompt, permissionPresenter, webBridge ? { allowPreApplyHealthWorkflow: false } : { - onTemporaryWorkflowMutationAttempt: () => { - setupMutationStarted = true; - journey?.markMutationStarted(); - }, - }).collect({ - owner: gitInfo.owner, - repository: gitInfo.repo, - setupToken: token ?? '', - requirements: credentialRequirements, - manageSecrets: !options.skipSecrets && configuration.manageRepositorySecrets, - secretStoragePolicy: configuration.storage.secrets, - ref: configuration.repository.mainBranch, - remoteConfiguration, - workflowTokenPermissions, - }); - const guidedBotIdentity = credentialPrompt.guidedWorkflowBotIdentity; - if (guidedBotIdentity && credentials.collection.workflowPat) { - const verifiedBot = await new verify_guided_workflow_pat_identity_use_case_1.VerifyGuidedWorkflowPatIdentityUseCase(githubIdentities) - .execute(guidedBotIdentity, credentials.collection.workflowPat.value); - (0, logger_1.logInfo)(`✅ Workflow PAT owner verified as @${verifiedBot.login} (GitHub account ID ${verifiedBot.id}).`); - if (setupPatAccount?.toLowerCase() === verifiedBot.login.toLowerCase()) { - (0, logger_1.logInfo)('The workflow PAT and setup PAT use the same GitHub account. If this account authors PRs, bot-generated events and guarded self-approval may not behave as intended; use a dedicated bot account where required.'); - } - } - if (webBridge) { - if (!remoteConfiguration || !guardedFiles || !webApplySnapshot || !initialBranch || !initialHead || !token) { - throw new application_error_1.ApplicationError('configuration.invalid', 'The approved setup evidence is incomplete. No mutation started; restart and review a new plan.'); + configuration = result.configuration; + remoteConfiguration = result.remoteConfiguration; + guardedFiles = webBridge ? (0, setup_configuration_plan_1.setupPlanGuardPaths)(result.plan) : undefined; + webApplySnapshot = guardedFiles ? (0, setup_apply_snapshot_1.captureSetupApplySnapshot)(checkoutRoot, guardedFiles) : undefined; + const workflowComparisons = new setup_workspace_adapter_1.SetupDoctorWorkspaceQueryAdapter().compareWorkflows((0, setup_configuration_policy_1.effectiveIssueWorkflowFeatures)(configuration), configuration); + const updateWorkflows = await workflowPrompt.confirmWorkflowUpdates(workflowComparisons, Boolean(options.updateWorkflows)); + approvedWorkflowFiles = updateWorkflows + ? workflowComparisons.filter(comparison => comparison.status === 'changed').map(comparison => comparison.file) + : []; + if (options.dryRun) { + (0, logger_1.logInfo)('✅ Dry run complete. No files or GitHub resources were changed.'); + return 'dry-run'; } - const authorization = await new verify_web_setup_apply_use_case_1.VerifyWebSetupApplyUseCase({ - confirm: async () => { - const answer = await webBridge.ask({ kind: 'confirm', title: 'Apply this setup now?', copyId: 'apply.confirm', - description: 'This is the final approval. Local files and selected GitHub resources may change. A partial result may require inspection before retrying.', - choices: ['Apply setup', 'Stop without applying'] }); - return answer === undefined ? undefined : answer === 'Apply setup' ? 'apply' : 'stop'; - }, - readRepositoryFacts: () => { - const current = (0, cli_context_1.getGitInfo)(); - return 'error' in current ? undefined : { - owner: current.owner, repository: current.repo, checkoutRoot: (0, cli_context_1.getGitRepositoryRoot)(cwd), - branch: (0, cli_context_1.getCurrentAttachedBranch)(cwd) ?? '', head: (0, cli_context_1.getCurrentHeadSha)() ?? '', - }; - }, - fileSnapshotMatches: setup_apply_snapshot_1.setupApplySnapshotMatches, - remote: remoteConfigurationReader, - permissionAudit: auditConfiguredSetupPat, - sessionState: () => webBridge.snapshot().outcome === 'cancelled' ? 'cancelled' - : webBridge.snapshot().outcome ? 'ended' : 'active', - }).execute({ - repository: { owner: gitInfo.owner, repository: gitInfo.repo, checkoutRoot, - branch: initialBranch, head: initialHead }, - selectedFiles: guardedFiles, fileSnapshot: webApplySnapshot, approvedRemote: remoteConfiguration, - configuration, setupToken: token, + return 'continue'; + }, + credentials: async (possibleMutation) => { + credentialsCollection = await (0, setup_credential_collection_1.collectSetupCredentials)({ + owner: gitInfo.owner, repository: gitInfo.repo, setupToken: token ?? '', + setupPatAccount, configuration, remoteConfiguration, + skipSecrets: Boolean(options.skipSecrets), nonInteractive: Boolean(options.nonInteractive), + workflowPat: options.workflowPat, secret: options.secret, bridge: webBridge, + prompt: credentialPrompt, permissionPresenter, + possibleMutation: () => { setupMutationStarted = true; possibleMutation(); }, }); - if (authorization === 'cancelled') - throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); - if (authorization === 'declined') { - journey?.finish('cancelled'); - return; - } - } - (0, logger_1.logInfo)('⚙️ Applying the approved setup plan...'); - journey?.advance('apply'); - const params = (0, setup_policy_1.buildSetupParams)(options, gitInfo, token ?? '', configuration, credentials.collection, approvedWorkflowFiles, remoteConfiguration); - setupMutationStarted = true; - journey?.markMutationStarted(); - setupApplyStarted = true; - const actionResults = await (0, local_action_1.runLocalAction)(params); - webBridge?.effects((0, setup_result_receipt_1.setupResultEffects)(actionResults)); - if (actionResults.some(actionResult => !actionResult.success || actionResult.errors.length > 0)) { - const failure = (0, setup_result_receipt_1.setupActionResultFailure)(actionResults); - if (failure) - webBridge?.resultReason(failure.reasonCode, failure.diagnosticRef); - journey?.finish('partial'); - (0, logger_1.logInfo)('Setup reported failures or partial completion. If a bot PAT was supplied, its Secret may already have been written; inspect the result and GitHub Secret name/scope before retrying or revoking it.'); - process.exitCode = 1; - } - else { - if (webBridge && token) { - const doctorToken = token; - webBridge.configureReadOnlyDoctor(async () => { - const diagnosis = await (0, setup_doctor_composition_root_1.createSetupDoctorUseCase)().execute({ owner: gitInfo.owner, - repository: gitInfo.repo, setupToken: doctorToken, configuration, readOnly: true }); - return { healthy: diagnosis.report.healthy, ...diagnosis.report.totals }; + return 'continue'; + }, + authorizeApply: async () => { + if (webBridge) + return (0, setup_apply_authorization_1.authorizeWebSetupApply)({ + bridge: webBridge, cwd, owner: gitInfo.owner, repository: gitInfo.repo, + checkoutRoot, initialBranch, initialHead, selectedFiles: guardedFiles, + fileSnapshot: webApplySnapshot, approvedRemote: remoteConfiguration, + configuration, setupToken: token, remoteReader: remoteConfigurationReader, + permissionAudit: auditConfiguredSetupPat, }); + return 'continue'; + }, + apply: async (report) => { + (0, logger_1.logInfo)('⚙️ Applying the approved setup plan...'); + const params = (0, setup_policy_1.buildSetupParams)(options, gitInfo, token ?? '', configuration, credentialsCollection, approvedWorkflowFiles, remoteConfiguration); + setupMutationStarted = true; + setupApplyStarted = true; + const actionResults = await (0, local_action_1.runLocalAction)(params, { + onSetupProgress: effect => { report(effect); webBridge?.progress(effect); }, + }); + webBridge?.effects((0, setup_result_receipt_1.setupResultEffects)(actionResults)); + if (actionResults.length === 0 || actionResults.some(actionResult => !actionResult.success || actionResult.errors.length > 0)) { + const failure = (0, setup_result_receipt_1.setupActionResultFailure)(actionResults); + if (failure) + webBridge?.resultReason(failure.reasonCode, failure.diagnosticRef); + (0, logger_1.logInfo)('Setup reported failures or partial completion. If a bot PAT was supplied, its Secret may already have been written; inspect the result and GitHub Secret name/scope before retrying or revoking it.'); + process.exitCode = 1; } - journey?.finish('complete'); - } - } - catch (error) { - journey?.finish(setupMutationStarted ? 'partial' : error instanceof setup_credential_prompt_adapter_1.SetupTerminalCancelledError ? 'cancelled' : 'blocked'); - const normalizedError = error instanceof setup_credential_prompt_adapter_1.SetupTerminalCancelledError ? undefined - : (0, application_error_1.toApplicationError)(error, 'workflow.failed', 'Setup failed.'); - webBridge?.resultReason(error instanceof setup_credential_prompt_adapter_1.SetupTerminalCancelledError ? 'cancelled' - : (0, setup_result_receipt_1.setupResultReason)(normalizedError.code), normalizedError?.correlationId); - if (setupMutationStarted && !setupApplyStarted) { - (0, logger_1.logInfo)('A temporary credential-health workflow create was attempted before Apply. Inspect the selected branch and GitHub workflow history before retrying; a failed request may still have reached GitHub.'); - } - if (credentialPrompt.guidedWorkflowBotIdentity) { - (0, logger_1.logInfo)(setupApplyStarted - ? 'Setup may be partially applied. Inspect the GitHub Secret before deleting or replacing the bot PAT.' - : 'No bot Secret write started. If you generated an unused bot PAT in GitHub, delete it there; Copilot cannot revoke it.'); - } - if (error instanceof setup_credential_prompt_adapter_1.SetupTerminalCancelledError) { - (0, logger_1.logInfo)(setupMutationStarted - ? 'Setup stopped after a possible credential-health workflow change. Inspect the selected branch and GitHub workflow history before retrying.' - : 'Setup cancelled. No changes were applied.'); - process.exitCode = 130; - return; - } - (0, logger_1.logError)((0, application_error_1.toApplicationError)(error, 'workflow.failed', 'Setup failed.')); + else { + if (webBridge && token) { + const doctorToken = token; + webBridge.configureReadOnlyDoctor(async () => { + const diagnosis = await (0, setup_doctor_composition_root_1.createSetupDoctorUseCase)().execute({ owner: gitInfo.owner, + repository: gitInfo.repo, setupToken: doctorToken, configuration, readOnly: true }); + return { healthy: diagnosis.report.healthy, ...diagnosis.report.totals }; + }); + } + } + return { success: actionResults.length > 0 && actionResults.every(actionResult => actionResult.success && actionResult.errors.length === 0), effects: [] }; + }, + liveness: () => webBridge?.snapshot().outcome === 'cancelled' ? 'cancelled' + : webBridge?.snapshot().outcome ? 'expired' : 'active', + present: (stage, mutationStarted, outcome) => { + if (!journey) + return; + journey.advance(stage); + if (mutationStarted) + journey.markMutationStarted(); + if (outcome) + journey.finish(outcome); + }, + isCancellationError: error => error instanceof setup_credential_prompt_adapter_1.SetupTerminalCancelledError, + }); + const run = await session.execute(); + setupMutationStarted = run.mutationStarted; + if (run.error !== undefined) + throw run.error; + if (run.outcome === 'blocked' || run.outcome === 'partial') process.exitCode = 1; - } - finally { - credentialPrompt.showSetupPatCleanupReminder(); - terminal?.close(); - if (webBridge && webServer) { - const outcome = webBridge.snapshot().journey?.outcome ?? (process.exitCode ? 'blocked' : 'cancelled'); - webBridge.finish(outcome, outcome === 'complete' - ? 'Setup completed. Delete the temporary setup PAT in GitHub; keep the bot PAT while its Secret is in use.' - : outcome === 'dry-run' ? 'Dry run complete. No files or GitHub resources changed.' - : outcome === 'partial' ? 'Setup may be partial. Inspect GitHub resources and run copilot doctor --read-only before retrying.' - : 'No further setup changes will be applied. Any PAT already created in GitHub still exists until you delete it there.'); - (0, logger_1.logInfo)('The local browser page shows the result. Choose “Close local session” there, or stop this command with Ctrl+C.'); - await webServer.closed; - } - releaseSetupGuard?.(); - } - }); + } + catch (error) { + process.exitCode = (0, setup_outcome_adapter_1.reportSetupFailure)(error, { journey, bridge: webBridge, + mutationStarted: setupMutationStarted, applyStarted: setupApplyStarted, + guidedBotIdentity: Boolean(credentialPrompt.guidedWorkflowBotIdentity) }); + } + finally { + credentialPrompt.showSetupPatCleanupReminder(); + terminal?.close(); + await (0, setup_outcome_adapter_1.finishWebSetupSession)(webBridge, webServer, process.exitCode); + releaseSetupGuard?.(); + } } @@ -68094,6 +68125,57 @@ function registerUpgradeCommand(program) { } +/***/ }), + +/***/ 75885: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.authorizeWebSetupApply = authorizeWebSetupApply; +const cli_context_1 = __nccwpck_require__(21307); +const verify_web_setup_apply_use_case_1 = __nccwpck_require__(5303); +const application_error_1 = __nccwpck_require__(75999); +const setup_credential_prompt_adapter_1 = __nccwpck_require__(93232); +const setup_apply_snapshot_1 = __nccwpck_require__(84136); +/** Web transport and Git facts for the application-owned final approval. */ +async function authorizeWebSetupApply(input) { + const { bridge } = input; + if (!input.approvedRemote || !input.selectedFiles || !input.fileSnapshot || !input.initialBranch || !input.initialHead || !input.setupToken) { + throw new application_error_1.ApplicationError('configuration.invalid', 'The approved setup evidence is incomplete. No mutation started; restart and review a new plan.'); + } + const authorization = await new verify_web_setup_apply_use_case_1.VerifyWebSetupApplyUseCase({ + confirm: async () => { + const answer = await bridge.ask({ kind: 'confirm', title: 'Apply this setup now?', copyId: 'apply.confirm', + description: 'This is the final approval. Local files and selected GitHub resources may change. A partial result may require inspection before retrying.', + choices: ['Apply setup', 'Stop without applying'] }); + return answer === undefined ? undefined : answer === 'Apply setup' ? 'apply' : 'stop'; + }, + readRepositoryFacts: () => { + const current = (0, cli_context_1.getGitInfo)(); + return 'error' in current ? undefined : { + owner: current.owner, repository: current.repo, checkoutRoot: (0, cli_context_1.getGitRepositoryRoot)(input.cwd), + branch: (0, cli_context_1.getCurrentAttachedBranch)(input.cwd) ?? '', head: (0, cli_context_1.getCurrentHeadSha)() ?? '', + }; + }, + fileSnapshotMatches: setup_apply_snapshot_1.setupApplySnapshotMatches, + remote: input.remoteReader, + permissionAudit: input.permissionAudit, + sessionState: () => bridge.snapshot().outcome === 'cancelled' ? 'cancelled' + : bridge.snapshot().outcome ? 'ended' : 'active', + }).execute({ + repository: { owner: input.owner, repository: input.repository, checkoutRoot: input.checkoutRoot, + branch: input.initialBranch, head: input.initialHead }, + selectedFiles: input.selectedFiles, fileSnapshot: input.fileSnapshot, approvedRemote: input.approvedRemote, + configuration: input.configuration, setupToken: input.setupToken, + }); + if (authorization === 'cancelled') + throw new setup_credential_prompt_adapter_1.SetupTerminalCancelledError(); + return authorization === 'declined' ? 'cancelled' : 'continue'; +} + + /***/ }), /***/ 84136: @@ -68649,6 +68731,64 @@ class DryRunSetupPlanConfirmation { exports.DryRunSetupPlanConfirmation = DryRunSetupPlanConfirmation; +/***/ }), + +/***/ 19469: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.collectSetupCredentials = collectSetupCredentials; +const setup_configuration_policy_1 = __nccwpck_require__(56637); +const setup_token_permission_policy_1 = __nccwpck_require__(99590); +const setup_pat_creation_url_policy_1 = __nccwpck_require__(54718); +const verify_guided_workflow_pat_identity_use_case_1 = __nccwpck_require__(35697); +const setup_credentials_composition_root_1 = __nccwpck_require__(69084); +const setup_github_identity_query_adapter_1 = __nccwpck_require__(56098); +const logger_1 = __nccwpck_require__(91151); +/** Wires bot-PAT guidance and credential ports for both setup presentations. */ +async function collectSetupCredentials(input) { + const requirements = (0, setup_configuration_policy_1.buildSetupCredentialRequirements)(input.configuration); + const workflowTokenPermissions = (0, setup_token_permission_policy_1.buildWorkflowPatPermissionRequirements)(input.configuration, input.remoteConfiguration); + const githubIdentities = new setup_github_identity_query_adapter_1.SetupGithubIdentityQueryAdapter(); + if (!input.nonInteractive && !input.workflowPat && !input.secret?.PAT) { + try { + const guide = (0, setup_pat_creation_url_policy_1.buildSetupPatCreationUrl)({ + role: 'workflow', owner: input.owner, repository: input.repository, expiresIn: 90, + requirements: workflowTokenPermissions, + }); + input.prompt.configureWorkflowPatGuide(guide, login => githubIdentities.resolve(login, input.setupToken), workflowTokenPermissions); + } + catch (error) { + if (!(error instanceof setup_pat_creation_url_policy_1.UnsupportedSetupPatLinkError)) + throw error; + (0, logger_1.logInfo)('A guided fine-grained bot PAT link is unavailable for one or more required permissions. Use the permission table and manual path; review whether a classic PAT is required for this plan.'); + input.permissionPresenter.showDetailedRequirements('workflow', workflowTokenPermissions); + } + } + const credentials = await (0, setup_credentials_composition_root_1.createSetupCredentialsUseCase)(input.prompt, input.permissionPresenter, input.bridge ? { allowPreApplyHealthWorkflow: false } : { + onTemporaryWorkflowMutationAttempt: input.possibleMutation, + }).collect({ + owner: input.owner, repository: input.repository, setupToken: input.setupToken, + requirements, manageSecrets: !input.skipSecrets && input.configuration.manageRepositorySecrets, + secretStoragePolicy: input.configuration.storage.secrets, + ref: input.configuration.repository.mainBranch, remoteConfiguration: input.remoteConfiguration, + workflowTokenPermissions, + }); + const guidedBotIdentity = input.prompt.guidedWorkflowBotIdentity; + if (guidedBotIdentity && credentials.collection.workflowPat) { + const verifiedBot = await new verify_guided_workflow_pat_identity_use_case_1.VerifyGuidedWorkflowPatIdentityUseCase(githubIdentities) + .execute(guidedBotIdentity, credentials.collection.workflowPat.value); + (0, logger_1.logInfo)(`✅ Workflow PAT owner verified as @${verifiedBot.login} (GitHub account ID ${verifiedBot.id}).`); + if (input.setupPatAccount?.toLowerCase() === verifiedBot.login.toLowerCase()) { + (0, logger_1.logInfo)('The workflow PAT and setup PAT use the same GitHub account. If this account authors PRs, bot-generated events and guarded self-approval may not behave as intended; use a dedicated bot account where required.'); + } + } + return credentials.collection; +} + + /***/ }), /***/ 93232: @@ -69018,6 +69158,127 @@ function renderSetupJourney(view, maximumWidth) { } +/***/ }), + +/***/ 9961: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.reportSetupFailure = reportSetupFailure; +exports.finishWebSetupSession = finishWebSetupSession; +const application_error_1 = __nccwpck_require__(75999); +const logger_1 = __nccwpck_require__(91151); +const setup_credential_prompt_adapter_1 = __nccwpck_require__(93232); +const setup_result_receipt_1 = __nccwpck_require__(44132); +/** Terminal diagnostics are separate from the redacted browser result. */ +function reportSetupFailure(error, context) { + const cancelled = error instanceof setup_credential_prompt_adapter_1.SetupTerminalCancelledError; + context.journey?.finish(context.mutationStarted ? 'partial' : cancelled ? 'cancelled' : 'blocked'); + const normalized = cancelled ? undefined : (0, application_error_1.toApplicationError)(error, 'workflow.failed', 'Setup failed.'); + context.bridge?.resultReason(cancelled ? 'cancelled' : (0, setup_result_receipt_1.setupResultReason)(normalized.code), normalized?.correlationId); + if (context.mutationStarted && !context.applyStarted) { + (0, logger_1.logInfo)('A temporary credential-health workflow create was attempted before Apply. Inspect the selected branch and GitHub workflow history before retrying; a failed request may still have reached GitHub.'); + } + if (context.guidedBotIdentity) { + (0, logger_1.logInfo)(context.applyStarted + ? 'Setup may be partially applied. Inspect the GitHub Secret before deleting or replacing the bot PAT.' + : 'No bot Secret write started. If you generated an unused bot PAT in GitHub, delete it there; Copilot cannot revoke it.'); + } + if (cancelled) { + (0, logger_1.logInfo)(context.mutationStarted + ? 'Setup stopped after a possible credential-health workflow change. Inspect the selected branch and GitHub workflow history before retrying.' + : 'Setup cancelled. No changes were applied.'); + return 130; + } + (0, logger_1.logError)(normalized); + return 1; +} +async function finishWebSetupSession(bridge, server, exitCode) { + if (!bridge || !server) + return; + const outcome = bridge.snapshot().journey?.outcome ?? (exitCode ? 'blocked' : 'cancelled'); + bridge.finish(outcome, outcome === 'complete' + ? 'Setup completed. Delete the temporary setup PAT in GitHub; keep the bot PAT while its Secret is in use.' + : outcome === 'dry-run' ? 'Dry run complete. No files or GitHub resources changed.' + : outcome === 'partial' ? 'Setup may be partial. Inspect GitHub resources and run copilot doctor --read-only before retrying.' + : 'No further setup changes will be applied. Any PAT already created in GitHub still exists until you delete it there.'); + (0, logger_1.logInfo)('The local browser page shows the result. Choose “Close local session” there, or stop this command with Ctrl+C.'); + await server.closed; +} + + +/***/ }), + +/***/ 67610: +/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { + +"use strict"; + +Object.defineProperty(exports, "__esModule", ({ value: true })); +exports.collectSetupPatIntent = collectSetupPatIntent; +const prepare_setup_pat_intent_use_case_1 = __nccwpck_require__(69277); +const setup_questionnaire_controller_1 = __nccwpck_require__(41644); +const logger_1 = __nccwpck_require__(91151); +const setup_question_renderer_1 = __nccwpck_require__(89481); +const web_setup_adapters_1 = __nccwpck_require__(60574); +/** Presentation wiring for the shared application permission-intent decision. */ +async function collectSetupPatIntent(input) { + const { bridge, credentialPrompt, permissionPresenter } = input; + if (await credentialPrompt.chooseSetupPatMethod() !== 'guided') { + permissionPresenter.showDetailedRequirements('setup', input.initialRequirements); + return { requirements: input.initialRequirements }; + } + const prepared = await new prepare_setup_pat_intent_use_case_1.PrepareSetupPatIntentUseCase({ + collect: (initial, context, pass) => (bridge + ? new web_setup_adapters_1.WebSetupQuestionnaireCollector(bridge, pass) + : new setup_questionnaire_controller_1.SetupQuestionnaireController(input.terminal, new setup_question_renderer_1.ConsoleSetupQuestionRenderer('permission-intent', pass))) + .collect(initial, context), + chooseOwnerKind: () => credentialPrompt.chooseSetupOwnerKind(), + review: () => credentialPrompt.reviewSetupPatIntent(), + showPreview: ({ draft, requirements, uncertain, ownerConflict, errors, pass, projectsWanted }) => { + if (ownerConflict) + (0, logger_1.logInfo)('This plan selects organization storage or Projects, but the owner was declared a personal account. Revise the choices or use the manual PAT path.'); + if (errors.length) + (0, logger_1.logInfo)(`The selected local configuration needs correction before a guided link can be generated:\n${errors.map(item => ` - ${item}`).join('\n')}`); + if (pass > 1) + (0, logger_1.logInfo)('Choice review complete. Returning to setup PAT permission review.'); + (0, logger_1.logInfo)('Permission intent:'); + (0, logger_1.logInfo)(` Initial tag: ${draft.createInitialTag ? 'yes' : 'no'}; issue workflows: ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval: ${draft.pullRequestApproval.mode}`); + (0, logger_1.logInfo)(` Secrets: ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables: ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects: ${projectsWanted ? 'yes (choose exact Projects after PAT)' : 'none'}`); + bridge?.message(`Permission preview: issue workflows ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval ${draft.pullRequestApproval.mode}; Secrets ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects ${projectsWanted ? 'yes (choose after PAT)' : 'none'}.`, 'info', undefined, 'permission.preview', { + issues: draft.features.issues ? draft.issueWorkflows.enabled.join('|') || 'none' : 'disabled', + approval: draft.pullRequestApproval.mode, + secrets: draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off', + variables: draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off', + projects: projectsWanted ? 'yes' : 'none', + }); + permissionPresenter.showRequirements('setup', requirements); + if (uncertain.length) + (0, logger_1.logInfo)(`May need after GitHub inspection:\n${uncertain.map(item => ` - ${item}`).join('\n')}`); + }, + showDetails: requirements => permissionPresenter.showDetailedRequirements('setup', requirements), + onManual: reason => { + if (reason === 'owner-unknown') + (0, logger_1.logInfo)('Owner type was not confirmed. Use the manual PAT table, or check whether the GitHub owner is an organization before retrying guided setup.'); + if (reason === 'unsupported') + (0, logger_1.logInfo)('A guided setup PAT link is unavailable for this owner or permission set. Enter a manually created PAT using the table above.'); + credentialPrompt.useManualSetupPat(); + permissionPresenter.showDetailedRequirements('setup', input.initialRequirements); + }, + advanceToSetupPat: () => { input.journey?.advance('setup-pat'); }, + revisitChoices: () => input.journey.revisitChoices(), + }).execute({ owner: input.owner, repository: input.repository, overrides: input.overrides, + skipRepositoryVariables: input.skipRepositoryVariables, skipRepositorySecrets: input.skipRepositorySecrets }); + if (prepared.kind !== 'guided') + return { requirements: input.initialRequirements }; + credentialPrompt.configureSetupPatGuide(prepared.url); + return { requirements: [...prepared.requirements], assertedOwnerKind: prepared.ownerKind, + permissionIntent: prepared.permissionIntent }; +} + + /***/ }), /***/ 33441: @@ -69430,7 +69691,7 @@ function setupResultEffects(results) { })); } const EFFECT_IDS = ['files', 'secrets', 'labels', 'issue-types', 'variables', 'initial-tag']; -const EFFECT_STATES = ['completed', 'skipped', 'needs-inspection', 'not-started']; +const EFFECT_STATES = ['completed', 'skipped', 'needs-inspection', 'not-started', 'in-progress']; const EFFECT_SCOPES = ['local', 'repository', 'organization', 'mixed']; function parseEffect(value) { const effect = (0, result_1.getResultPayload)(value); @@ -70385,12 +70646,24 @@ class WebSetupBridge { mutationStarted: this.view.journey?.mutationStarted === true, effects, ...(this.view.resultDetail?.diagnosticRef ? { diagnosticRef: this.view.resultDetail.diagnosticRef } : {}) } }); } + progress(effect) { + if (this.view.outcome) + return; + const previous = this.view.resultDetail?.effects ?? []; + const effects = previous.some(item => item.id === effect.id) + ? previous.map(item => item.id === effect.id ? { ...effect } : item) + : [...previous, { ...effect }]; + this.effects(effects); + } finish(outcome, text) { if (this.view.outcome) return; this.pending?.resolve(undefined); this.pending = undefined; + const effects = this.view.resultDetail?.effects?.map(effect => effect.state === 'in-progress' + ? { ...effect, state: 'needs-inspection' } : effect); this.publish({ prompt: undefined, promptRevision: undefined, outcome, message: { tone: outcome === 'complete' || outcome === 'dry-run' ? 'success' : 'warning', text }, + ...(this.view.resultDetail && effects ? { resultDetail: { ...this.view.resultDetail, effects } } : {}), ...(this.view.resultDetail ? {} : { resultDetail: { reasonCode: outcome === 'cancelled' ? 'cancelled' : outcome === 'blocked' ? 'unknown' : 'unknown', stoppedStage: this.view.journey?.current ?? 'Preparation', @@ -84207,10 +84480,10 @@ const setup_workspace_adapter_1 = __nccwpck_require__(5729); const repository_variables_repository_1 = __nccwpck_require__(28493); const github_identity_client_factory_2 = __nccwpck_require__(93081); const push_single_action_capability_port_binding_1 = __nccwpck_require__(49417); -function createInitialSetupCompositionRoot(binding) { +function createInitialSetupCompositionRoot(binding, progress) { const labelProvisioning = new issue_label_provisioning_repository_1.IssueLabelProvisioningRepository((0, github_issue_client_factory_1.createIssueLabelProvisioningClient)()); const githubResourceClient = (0, github_identity_client_factory_2.createRepositoryVariablesClient)(); - return (0, initial_setup_use_case_composition_1.composeInitialSetupUseCase)((0, push_single_action_capability_port_binding_1.bindAuthenticatedUser)(new authenticated_user_repository_1.AuthenticatedUserRepository((0, github_identity_client_factory_1.createAuthenticatedUserClient)()), binding), (0, push_single_action_capability_port_binding_1.bindInitialLabels)(labelProvisioning, binding), (0, push_single_action_capability_port_binding_1.bindIssueTypes)(new issue_type_repository_1.IssueTypeRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), new git_cli_repository_1.GitCliRepository(), (0, push_single_action_capability_port_binding_1.bindRepositoryDefaultBranch)(new repository_default_branch_repository_1.RepositoryDefaultBranchRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindRepositoryTag)(new repository_tag_repository_1.RepositoryTagRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindSetupWorkspace)(new setup_workspace_adapter_1.SetupWorkspaceMutationAdapter(), binding), (0, push_single_action_capability_port_binding_1.bindSetupVariables)(new repository_variables_repository_1.RepositoryVariablesCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupSecrets)(new repository_variables_repository_1.RepositorySecretsCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupRemoteConfiguration)(new repository_variables_repository_1.SetupRemoteConfigurationQueryRepository(githubResourceClient), binding)); + return (0, initial_setup_use_case_composition_1.composeInitialSetupUseCase)((0, push_single_action_capability_port_binding_1.bindAuthenticatedUser)(new authenticated_user_repository_1.AuthenticatedUserRepository((0, github_identity_client_factory_1.createAuthenticatedUserClient)()), binding), (0, push_single_action_capability_port_binding_1.bindInitialLabels)(labelProvisioning, binding), (0, push_single_action_capability_port_binding_1.bindIssueTypes)(new issue_type_repository_1.IssueTypeRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), new git_cli_repository_1.GitCliRepository(), (0, push_single_action_capability_port_binding_1.bindRepositoryDefaultBranch)(new repository_default_branch_repository_1.RepositoryDefaultBranchRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindRepositoryTag)(new repository_tag_repository_1.RepositoryTagRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindSetupWorkspace)(new setup_workspace_adapter_1.SetupWorkspaceMutationAdapter(), binding), (0, push_single_action_capability_port_binding_1.bindSetupVariables)(new repository_variables_repository_1.RepositoryVariablesCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupSecrets)(new repository_variables_repository_1.RepositorySecretsCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupRemoteConfiguration)(new repository_variables_repository_1.SetupRemoteConfigurationQueryRepository(githubResourceClient), binding), progress); } @@ -84650,7 +84923,7 @@ function createDetectPotentialProblemsUseCase(binding) { const bugbot = (0, bugbot_composition_root_1.createBugbotCompositionRoot)(binding); return new detect_potential_problems_use_case_1.DetectPotentialProblemsUseCase((0, agent_capability_composition_root_1.createFindingsQueryPort)(), bugbot.scm, bugbot.telemetry, new resolve_message_catalog_use_case_1.ResolveMessageCatalogUseCase((0, agent_capability_composition_root_1.createLanguageQueryPort)())); } -function createSingleActionUseCaseCompositionRoot(surface, binding) { +function createSingleActionUseCaseCompositionRoot(surface, binding, setupProgress) { const catalogResolver = new resolve_message_catalog_use_case_1.ResolveMessageCatalogUseCase((0, agent_capability_composition_root_1.createLanguageQueryPort)()); const issueDescriptionQueryPort = (0, issue_content_composition_root_1.createIssueContentCompositionRoot)(); const repositoryTagPort = surface === "github-workflow" @@ -84664,7 +84937,7 @@ function createSingleActionUseCaseCompositionRoot(surface, binding) { : undefined; return new single_action_use_case_1.SingleActionUseCase(repositoryTagPort && repositoryReleasePort ? new publish_github_action_use_case_1.PublishGithubActionUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryTag)(repositoryTagPort, binding), (0, push_single_action_capability_port_binding_1.bindRepositoryRelease)(repositoryReleasePort, binding)) - : undefined, repositoryReleasePort ? new create_release_use_case_1.CreateReleaseUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryRelease)(repositoryReleasePort, binding)) : undefined, repositoryTagPort ? new create_tag_use_case_1.CreateTagUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryTag)(repositoryTagPort, binding)) : undefined, new think_use_case_1.ThinkUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, initial_setup_composition_root_1.createInitialSetupCompositionRoot)(binding), (0, check_progress_composition_root_1.createCheckProgressCompositionRoot)(binding), createDetectPotentialProblemsUseCase(binding), new recommend_steps_use_case_1.RecommendStepsUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, issue_inactivity_composition_root_1.createCloseInactiveIssuesUseCase)(binding, catalogResolver), (0, actor_authorization_composition_root_1.createActorAuthorizationRepository)(), new publish_issue_comment_use_case_1.PublishIssueCommentUseCase((0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding)), new observe_branch_sync_use_case_1.ObserveBranchSyncUseCase((0, push_single_action_capability_port_binding_1.bindBranchDependencies)(new branch_dependency_repository_1.BranchDependencyRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), (0, push_single_action_capability_port_binding_1.bindBranchComparison)(new branch_compare_repository_1.BranchCompareRepository((0, github_branch_client_factory_1.createBranchComparisonClient)()), binding), (0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding), catalogResolver), deploymentOrchestration); + : undefined, repositoryReleasePort ? new create_release_use_case_1.CreateReleaseUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryRelease)(repositoryReleasePort, binding)) : undefined, repositoryTagPort ? new create_tag_use_case_1.CreateTagUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryTag)(repositoryTagPort, binding)) : undefined, new think_use_case_1.ThinkUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, initial_setup_composition_root_1.createInitialSetupCompositionRoot)(binding, setupProgress), (0, check_progress_composition_root_1.createCheckProgressCompositionRoot)(binding), createDetectPotentialProblemsUseCase(binding), new recommend_steps_use_case_1.RecommendStepsUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, issue_inactivity_composition_root_1.createCloseInactiveIssuesUseCase)(binding, catalogResolver), (0, actor_authorization_composition_root_1.createActorAuthorizationRepository)(), new publish_issue_comment_use_case_1.PublishIssueCommentUseCase((0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding)), new observe_branch_sync_use_case_1.ObserveBranchSyncUseCase((0, push_single_action_capability_port_binding_1.bindBranchDependencies)(new branch_dependency_repository_1.BranchDependencyRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), (0, push_single_action_capability_port_binding_1.bindBranchComparison)(new branch_compare_repository_1.BranchCompareRepository((0, github_branch_client_factory_1.createBranchComparisonClient)()), binding), (0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding), catalogResolver), deploymentOrchestration); } function createDeploymentOrchestrationUseCase(issueDescriptionQueryPort, publication, binding, catalogResolver) { const deploymentClient = new octokit_deployment_adapter_1.OctokitDeploymentClientAdapter(); @@ -84717,7 +84990,7 @@ function createPullRequestReviewCommentUseCaseCompositionRoot(binding) { function createCommitUseCaseCompositionRoot(projectBoardCommandPort, binding) { return new commit_use_case_1.CommitUseCase(new notify_new_commit_on_issue_use_case_1.NotifyNewCommitOnIssueUseCase((0, push_single_action_capability_port_binding_1.bindIssueReopen)((0, issue_interaction_composition_root_1.createIssueNotificationRepository)(), binding)), new check_changes_issue_size_use_case_1.CheckChangesIssueSizeUseCase((0, lifecycle_capability_port_binding_2.bindProjectBoardCommands)(projectBoardCommandPort, binding), (0, lifecycle_capability_port_binding_2.bindIssueLabels)((0, issue_labels_composition_root_1.createIssueLabelRepository)(), binding), (0, push_single_action_capability_port_binding_1.bindPullRequestBranchQuery)(new pull_request_lifecycle_repository_1.PullRequestLifecycleRepository((0, github_pull_request_client_factory_1.createPullRequestLifecycleClient)()), binding), (0, push_single_action_capability_port_binding_1.bindBranchChangeSize)(new branch_compare_repository_1.BranchCompareRepository((0, github_branch_client_factory_1.createBranchComparisonClient)()), binding)), createDetectPotentialProblemsUseCase(binding), (0, check_progress_composition_root_1.createCheckProgressCompositionRoot)(binding), (0, actor_authorization_composition_root_1.createActorAuthorizationRepository)()); } -function createMainRunRouteCompositionRoot(projectBoardCommandPort, surface) { +function createMainRunRouteCompositionRoot(projectBoardCommandPort, surface, setupProgress) { let singleAction; let issueComment; let issue; @@ -84726,7 +84999,7 @@ function createMainRunRouteCompositionRoot(projectBoardCommandPort, surface) { let push; return { "single-action": async (execution) => { - singleAction ?? (singleAction = createSingleActionUseCaseCompositionRoot(surface, bugbotBinding(execution))); + singleAction ?? (singleAction = createSingleActionUseCaseCompositionRoot(surface, bugbotBinding(execution), setupProgress)); return singleAction.invoke(execution); }, "issue-comment": async (execution) => { @@ -87326,7 +87599,7 @@ class SetupTokenPermissionQueryAdapter { try { const request = (url) => this.fetcher(url, { method: 'GET', - headers: permissionProbeHeaders(token), + headers: permissionProbeHeaders(token, requirement), signal: controller.signal, }); const target = await resolveProbeTarget(owner, repository, requirement, request); @@ -87343,11 +87616,12 @@ class SetupTokenPermissionQueryAdapter { } } exports.SetupTokenPermissionQueryAdapter = SetupTokenPermissionQueryAdapter; -function permissionProbeHeaders(token) { +function permissionProbeHeaders(token, requirement) { return { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json', - 'X-GitHub-Api-Version': '2022-11-28', + 'X-GitHub-Api-Version': requirement.scope === 'organization' && requirement.probe === 'projects' + ? '2026-03-10' : '2022-11-28', }; } async function resolveProbeTarget(owner, repository, requirement, request) { @@ -87366,6 +87640,9 @@ async function resolveProbeTarget(owner, repository, requirement, request) { if (requirement.scope === 'organization' && requirement.probe === 'members') { return { status: 'ready', url, readEvidence: 'organization-membership' }; } + if (requirement.scope === 'organization' && requirement.probe === 'projects') { + return { status: 'ready', url, readEvidence: 'organization-projects' }; + } if (requiresRepositoryVisibilityProof(requirement)) { const metadataResponse = await request(repositoryRoot(owner, repository)); if (!metadataResponse.ok) { @@ -87466,6 +87743,9 @@ function containsAsciiControl(value) { } async function mapProbeResponse(requirement, response, readEvidence, owner) { if (response.ok) { + if (readEvidence === 'organization-projects' && requirement.level === 'read') { + return inspectOrganizationProjectsRead(requirement, response); + } if (readEvidence === 'organization-membership') { return response.status === 200 && await isActiveOrganizationMembership(response, owner) ? outcome(requirement, 'verified', 'GitHub confirmed active organization membership through a permission-bound Members-read probe.') @@ -87512,6 +87792,29 @@ async function mapProbeResponse(requirement, response, readEvidence, owner) { } return outcome(requirement, 'unverifiable', `GitHub could not verify this permission safely (HTTP ${response.status}).`); } +async function inspectOrganizationProjectsRead(requirement, response) { + try { + const payload = await response.json(); + if (!Array.isArray(payload)) { + return outcome(requirement, 'unverifiable', 'GitHub returned an unrecognized organization Projects list.'); + } + if (payload.some(project => typeof project !== 'object' || project === null + || Array.isArray(project) || typeof project.public !== 'boolean')) { + return outcome(requirement, 'unverifiable', 'GitHub returned an unrecognized organization Projects list.'); + } + if (payload.some(project => project.public === false)) { + return outcome(requirement, 'verified', 'GitHub returned a non-public organization Project through a read-only Projects probe.'); + } + return { + ...outcome(requirement, 'unverifiable', 'Only public or no organization Projects were returned; listing is available, but the PAT grant is not proven.'), + operationallyAvailable: true, + publicReadEvidence: 'public-organization-projects', + }; + } + catch { + return outcome(requirement, 'unverifiable', 'GitHub organization Projects response could not be inspected safely.'); + } +} async function isActiveOrganizationMembership(response, owner) { try { const payload = await response.json(); @@ -87577,6 +87880,8 @@ function probeUrl(owner, repository, requirement) { return `https://api.github.com/user/memberships/orgs/${encodedOwner}`; if (requirement.probe === 'issue-types') return `${organizationRoot}/issue-types?per_page=1`; + if (requirement.probe === 'projects') + return `${organizationRoot}/projectsV2?per_page=1`; return undefined; } if (requirement.probe === 'metadata') diff --git a/build/github_action/index.js b/build/github_action/index.js index da21e04f3..2ed2aa0cb 100644 --- a/build/github_action/index.js +++ b/build/github_action/index.js @@ -38898,7 +38898,7 @@ const main_run_lifecycle_1 = __nccwpck_require__(916); const issue_workflow_runtime_policy_1 = __nccwpck_require__(77734); const application_error_1 = __nccwpck_require__(75999); const issue_start_policy_1 = __nccwpck_require__(90332); -async function mainRun(execution, projectBoardCommandPort, latestTagQueryPort, compositionSurface, lifecycleStateUseCase, agentActivityUseCase, prepareRuntime) { +async function mainRun(execution, projectBoardCommandPort, latestTagQueryPort, compositionSurface, lifecycleStateUseCase, agentActivityUseCase, prepareRuntime, setupProgress) { (0, logging_ports_1.configureApplicationLogger)((0, logger_adapter_1.createLoggerAdapter)()); (0, logging_ports_1.setGlobalLoggerDebug)(execution.debug, execution.inputs === undefined); const repository = (0, repository_context_1.requireRepositoryCoordinates)({ @@ -38935,7 +38935,7 @@ async function mainRun(execution, projectBoardCommandPort, latestTagQueryPort, c return [issueWorkflowAdmissionResult(runtimeDecision.mode, runtimeDecision.message)]; } await prepareRuntime?.(execution); - const routeHandlers = (0, main_run_route_composition_root_1.createMainRunRouteCompositionRoot)(projectBoardCommandPort, compositionSurface); + const routeHandlers = (0, main_run_route_composition_root_1.createMainRunRouteCompositionRoot)(projectBoardCommandPort, compositionSurface, setupProgress); if (execution.runnedByToken) { return runTrackedRoute(execution, 'single-action', () => (0, main_run_lifecycle_1.runTokenExecution)(execution, routeHandlers), undefined, agentActivityUseCase); } @@ -52068,7 +52068,7 @@ exports.InitialSetupUseCase = void 0; const initial_setup_workflow_1 = __nccwpck_require__(18079); /** Application boundary for provisioning a repository for Copilot automation. */ class InitialSetupUseCase { - constructor(authenticatedUserPort, initialLabelProvisioningPort, issueTypeProvisioningPort, latestTagQueryPort, repositoryDefaultBranchPort, repositoryTagPort, setupWorkspacePort, setupRepositoryVariablesPort, setupRepositorySecretsPort, setupRemoteConfigurationReadPort) { + constructor(authenticatedUserPort, initialLabelProvisioningPort, issueTypeProvisioningPort, latestTagQueryPort, repositoryDefaultBranchPort, repositoryTagPort, setupWorkspacePort, setupRepositoryVariablesPort, setupRepositorySecretsPort, setupRemoteConfigurationReadPort, progress) { this.authenticatedUserPort = authenticatedUserPort; this.initialLabelProvisioningPort = initialLabelProvisioningPort; this.issueTypeProvisioningPort = issueTypeProvisioningPort; @@ -52079,6 +52079,7 @@ class InitialSetupUseCase { this.setupRepositoryVariablesPort = setupRepositoryVariablesPort; this.setupRepositorySecretsPort = setupRepositorySecretsPort; this.setupRemoteConfigurationReadPort = setupRemoteConfigurationReadPort; + this.progress = progress; this.taskId = 'InitialSetupUseCase'; } async invoke(param) { @@ -52093,6 +52094,7 @@ class InitialSetupUseCase { setupRepositoryVariablesPort: this.setupRepositoryVariablesPort, setupRepositorySecretsPort: this.setupRepositorySecretsPort, setupRemoteConfigurationReadPort: this.setupRemoteConfigurationReadPort, + progress: this.progress, }); } } @@ -52134,8 +52136,13 @@ async function runInitialSetupWorkflow(request, dependencies) { const mark = (id, state) => { const index = effects.findIndex(effect => effect.id === id); effects[index] = { ...effects[index], state }; + try { + dependencies.progress?.(Object.freeze({ ...effects[index] })); + } + catch { /* Presentation observers cannot abort provisioning. */ } }; - const receipt = () => buildResult(errors, steps, effects); + const receipt = () => buildResult(errors, steps, effects.map(effect => effect.state === 'in-progress' + ? { ...effect, state: 'needs-inspection' } : effect)); try { const setupConfiguration = request.setupConfiguration; if (!dependencies.setupWorkspacePort.hasValidToken()) { @@ -52193,12 +52200,12 @@ async function runInitialSetupWorkflow(request, dependencies) { approvedWorkflowFiles: request.workflowUpdates, } : {}), }; - mark('files', 'needs-inspection'); + mark('files', 'in-progress'); const filesResult = dependencies.setupWorkspacePort.prepare(workspaceSelection); mark('files', filesResult.copied > 0 ? 'completed' : 'skipped'); steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); if (setupConfiguration?.manageRepositorySecrets && secretValues > 0) - mark('secrets', 'needs-inspection'); + mark('secrets', 'in-progress'); const secrets = await (0, setup_resource_provisioning_1.ensureRepositorySecrets)(request, dependencies, setupConfiguration, remoteConfiguration); mark('secrets', secrets.errors.length ? 'needs-inspection' : secrets.writes > 0 ? 'completed' : 'skipped'); if (secrets.step) @@ -52206,7 +52213,7 @@ async function runInitialSetupWorkflow(request, dependencies) { if (secrets.errors.length > 0) errors.push(...fromMessages(secrets.errors, 'authorization.credential-invalid')); (0, logging_ports_1.logInfo)('🏷️ Checking configured and progress labels...'); - mark('labels', 'needs-inspection'); + mark('labels', 'in-progress'); const labels = await ensureInitialLabels(request, dependencies.initialLabelProvisioningPort, setupConfiguration); mark('labels', !labels.completed || labels.configured.errors.length || labels.progress.errors.length ? 'needs-inspection' : labels.configured.created + labels.progress.created > 0 ? 'completed' : 'skipped'); @@ -52218,7 +52225,7 @@ async function runInitialSetupWorkflow(request, dependencies) { appendLabelSummary(steps, errors, labels.progress, 'Progress labels'); } (0, logging_ports_1.logInfo)('📋 Checking issue types...'); - mark('issue-types', 'needs-inspection'); + mark('issue-types', 'in-progress'); const issueTypes = await ensureIssueTypes(request, dependencies.issueTypeProvisioningPort, setupConfiguration); mark('issue-types', !issueTypes.success ? 'needs-inspection' : issueTypes.created > 0 ? 'completed' : 'skipped'); if (!issueTypes.success) { @@ -52228,7 +52235,7 @@ async function runInitialSetupWorkflow(request, dependencies) { steps.push(`✅ Issue types checked: ${issueTypes.created} created, ${issueTypes.existing} already existed`); } if (setupConfiguration?.manageRepositoryVariables) - mark('variables', 'needs-inspection'); + mark('variables', 'in-progress'); const variables = await (0, setup_resource_provisioning_1.ensureRepositoryVariables)(request, dependencies, setupConfiguration, remoteConfiguration); mark('variables', variables.errors.length ? 'needs-inspection' : variables.writes > 0 ? 'completed' : 'skipped'); if (variables.step) @@ -52236,7 +52243,7 @@ async function runInitialSetupWorkflow(request, dependencies) { if (variables.errors.length > 0) errors.push(...fromMessages(variables.errors, 'provider.unavailable')); if (setupConfiguration?.createInitialTag !== false) - mark('initial-tag', 'needs-inspection'); + mark('initial-tag', 'in-progress'); const defaultVersion = await ensureDefaultVersion(request, dependencies, setupConfiguration); mark('initial-tag', defaultVersion.error ? 'needs-inspection' : defaultVersion.step?.includes('created on branch') ? 'completed' : 'skipped'); @@ -79261,10 +79268,10 @@ const setup_workspace_adapter_1 = __nccwpck_require__(5729); const repository_variables_repository_1 = __nccwpck_require__(28493); const github_identity_client_factory_2 = __nccwpck_require__(93081); const push_single_action_capability_port_binding_1 = __nccwpck_require__(49417); -function createInitialSetupCompositionRoot(binding) { +function createInitialSetupCompositionRoot(binding, progress) { const labelProvisioning = new issue_label_provisioning_repository_1.IssueLabelProvisioningRepository((0, github_issue_client_factory_1.createIssueLabelProvisioningClient)()); const githubResourceClient = (0, github_identity_client_factory_2.createRepositoryVariablesClient)(); - return (0, initial_setup_use_case_composition_1.composeInitialSetupUseCase)((0, push_single_action_capability_port_binding_1.bindAuthenticatedUser)(new authenticated_user_repository_1.AuthenticatedUserRepository((0, github_identity_client_factory_1.createAuthenticatedUserClient)()), binding), (0, push_single_action_capability_port_binding_1.bindInitialLabels)(labelProvisioning, binding), (0, push_single_action_capability_port_binding_1.bindIssueTypes)(new issue_type_repository_1.IssueTypeRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), new git_cli_repository_1.GitCliRepository(), (0, push_single_action_capability_port_binding_1.bindRepositoryDefaultBranch)(new repository_default_branch_repository_1.RepositoryDefaultBranchRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindRepositoryTag)(new repository_tag_repository_1.RepositoryTagRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindSetupWorkspace)(new setup_workspace_adapter_1.SetupWorkspaceMutationAdapter(), binding), (0, push_single_action_capability_port_binding_1.bindSetupVariables)(new repository_variables_repository_1.RepositoryVariablesCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupSecrets)(new repository_variables_repository_1.RepositorySecretsCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupRemoteConfiguration)(new repository_variables_repository_1.SetupRemoteConfigurationQueryRepository(githubResourceClient), binding)); + return (0, initial_setup_use_case_composition_1.composeInitialSetupUseCase)((0, push_single_action_capability_port_binding_1.bindAuthenticatedUser)(new authenticated_user_repository_1.AuthenticatedUserRepository((0, github_identity_client_factory_1.createAuthenticatedUserClient)()), binding), (0, push_single_action_capability_port_binding_1.bindInitialLabels)(labelProvisioning, binding), (0, push_single_action_capability_port_binding_1.bindIssueTypes)(new issue_type_repository_1.IssueTypeRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), new git_cli_repository_1.GitCliRepository(), (0, push_single_action_capability_port_binding_1.bindRepositoryDefaultBranch)(new repository_default_branch_repository_1.RepositoryDefaultBranchRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindRepositoryTag)(new repository_tag_repository_1.RepositoryTagRepository((0, github_release_client_factory_1.createReleaseClient)()), binding), (0, push_single_action_capability_port_binding_1.bindSetupWorkspace)(new setup_workspace_adapter_1.SetupWorkspaceMutationAdapter(), binding), (0, push_single_action_capability_port_binding_1.bindSetupVariables)(new repository_variables_repository_1.RepositoryVariablesCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupSecrets)(new repository_variables_repository_1.RepositorySecretsCommandRepository(githubResourceClient), binding), (0, push_single_action_capability_port_binding_1.bindSetupRemoteConfiguration)(new repository_variables_repository_1.SetupRemoteConfigurationQueryRepository(githubResourceClient), binding), progress); } @@ -79695,7 +79702,7 @@ function createDetectPotentialProblemsUseCase(binding) { const bugbot = (0, bugbot_composition_root_1.createBugbotCompositionRoot)(binding); return new detect_potential_problems_use_case_1.DetectPotentialProblemsUseCase((0, agent_capability_composition_root_1.createFindingsQueryPort)(), bugbot.scm, bugbot.telemetry, new resolve_message_catalog_use_case_1.ResolveMessageCatalogUseCase((0, agent_capability_composition_root_1.createLanguageQueryPort)())); } -function createSingleActionUseCaseCompositionRoot(surface, binding) { +function createSingleActionUseCaseCompositionRoot(surface, binding, setupProgress) { const catalogResolver = new resolve_message_catalog_use_case_1.ResolveMessageCatalogUseCase((0, agent_capability_composition_root_1.createLanguageQueryPort)()); const issueDescriptionQueryPort = (0, issue_content_composition_root_1.createIssueContentCompositionRoot)(); const repositoryTagPort = surface === "github-workflow" @@ -79709,7 +79716,7 @@ function createSingleActionUseCaseCompositionRoot(surface, binding) { : undefined; return new single_action_use_case_1.SingleActionUseCase(repositoryTagPort && repositoryReleasePort ? new publish_github_action_use_case_1.PublishGithubActionUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryTag)(repositoryTagPort, binding), (0, push_single_action_capability_port_binding_1.bindRepositoryRelease)(repositoryReleasePort, binding)) - : undefined, repositoryReleasePort ? new create_release_use_case_1.CreateReleaseUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryRelease)(repositoryReleasePort, binding)) : undefined, repositoryTagPort ? new create_tag_use_case_1.CreateTagUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryTag)(repositoryTagPort, binding)) : undefined, new think_use_case_1.ThinkUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, initial_setup_composition_root_1.createInitialSetupCompositionRoot)(binding), (0, check_progress_composition_root_1.createCheckProgressCompositionRoot)(binding), createDetectPotentialProblemsUseCase(binding), new recommend_steps_use_case_1.RecommendStepsUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, issue_inactivity_composition_root_1.createCloseInactiveIssuesUseCase)(binding, catalogResolver), (0, actor_authorization_composition_root_1.createActorAuthorizationRepository)(), new publish_issue_comment_use_case_1.PublishIssueCommentUseCase((0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding)), new observe_branch_sync_use_case_1.ObserveBranchSyncUseCase((0, push_single_action_capability_port_binding_1.bindBranchDependencies)(new branch_dependency_repository_1.BranchDependencyRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), (0, push_single_action_capability_port_binding_1.bindBranchComparison)(new branch_compare_repository_1.BranchCompareRepository((0, github_branch_client_factory_1.createBranchComparisonClient)()), binding), (0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding), catalogResolver), deploymentOrchestration); + : undefined, repositoryReleasePort ? new create_release_use_case_1.CreateReleaseUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryRelease)(repositoryReleasePort, binding)) : undefined, repositoryTagPort ? new create_tag_use_case_1.CreateTagUseCase((0, push_single_action_capability_port_binding_1.bindRepositoryTag)(repositoryTagPort, binding)) : undefined, new think_use_case_1.ThinkUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, initial_setup_composition_root_1.createInitialSetupCompositionRoot)(binding, setupProgress), (0, check_progress_composition_root_1.createCheckProgressCompositionRoot)(binding), createDetectPotentialProblemsUseCase(binding), new recommend_steps_use_case_1.RecommendStepsUseCase((0, shared_capability_port_binding_1.bindIssueDescriptionQuery)(issueDescriptionQueryPort, binding), (0, agent_capability_composition_root_1.createFindingsQueryPort)()), (0, issue_inactivity_composition_root_1.createCloseInactiveIssuesUseCase)(binding, catalogResolver), (0, actor_authorization_composition_root_1.createActorAuthorizationRepository)(), new publish_issue_comment_use_case_1.PublishIssueCommentUseCase((0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding)), new observe_branch_sync_use_case_1.ObserveBranchSyncUseCase((0, push_single_action_capability_port_binding_1.bindBranchDependencies)(new branch_dependency_repository_1.BranchDependencyRepository((0, github_project_client_factory_1.createGraphqlTransportClient)()), binding), (0, push_single_action_capability_port_binding_1.bindBranchComparison)(new branch_compare_repository_1.BranchCompareRepository((0, github_branch_client_factory_1.createBranchComparisonClient)()), binding), (0, push_single_action_capability_port_binding_1.bindIssueCommentPublication)(issueDescriptionQueryPort, binding), catalogResolver), deploymentOrchestration); } function createDeploymentOrchestrationUseCase(issueDescriptionQueryPort, publication, binding, catalogResolver) { const deploymentClient = new octokit_deployment_adapter_1.OctokitDeploymentClientAdapter(); @@ -79762,7 +79769,7 @@ function createPullRequestReviewCommentUseCaseCompositionRoot(binding) { function createCommitUseCaseCompositionRoot(projectBoardCommandPort, binding) { return new commit_use_case_1.CommitUseCase(new notify_new_commit_on_issue_use_case_1.NotifyNewCommitOnIssueUseCase((0, push_single_action_capability_port_binding_1.bindIssueReopen)((0, issue_interaction_composition_root_1.createIssueNotificationRepository)(), binding)), new check_changes_issue_size_use_case_1.CheckChangesIssueSizeUseCase((0, lifecycle_capability_port_binding_2.bindProjectBoardCommands)(projectBoardCommandPort, binding), (0, lifecycle_capability_port_binding_2.bindIssueLabels)((0, issue_labels_composition_root_1.createIssueLabelRepository)(), binding), (0, push_single_action_capability_port_binding_1.bindPullRequestBranchQuery)(new pull_request_lifecycle_repository_1.PullRequestLifecycleRepository((0, github_pull_request_client_factory_1.createPullRequestLifecycleClient)()), binding), (0, push_single_action_capability_port_binding_1.bindBranchChangeSize)(new branch_compare_repository_1.BranchCompareRepository((0, github_branch_client_factory_1.createBranchComparisonClient)()), binding)), createDetectPotentialProblemsUseCase(binding), (0, check_progress_composition_root_1.createCheckProgressCompositionRoot)(binding), (0, actor_authorization_composition_root_1.createActorAuthorizationRepository)()); } -function createMainRunRouteCompositionRoot(projectBoardCommandPort, surface) { +function createMainRunRouteCompositionRoot(projectBoardCommandPort, surface, setupProgress) { let singleAction; let issueComment; let issue; @@ -79771,7 +79778,7 @@ function createMainRunRouteCompositionRoot(projectBoardCommandPort, surface) { let push; return { "single-action": async (execution) => { - singleAction ?? (singleAction = createSingleActionUseCaseCompositionRoot(surface, bugbotBinding(execution))); + singleAction ?? (singleAction = createSingleActionUseCaseCompositionRoot(surface, bugbotBinding(execution), setupProgress)); return singleAction.invoke(execution); }, "issue-comment": async (execution) => { diff --git a/build/web/assets/index-CaPMoT2_.js b/build/web/assets/index-CaPMoT2_.js new file mode 100644 index 000000000..a1e07e662 --- /dev/null +++ b/build/web/assets/index-CaPMoT2_.js @@ -0,0 +1,3 @@ +(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})(),typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var e=!1;function t(){e=!0}t();var n={},r=Symbol(`uninitialized`),i=`http://www.w3.org/1999/xhtml`,a=Array.isArray,o=Array.prototype.indexOf,s=Array.prototype.includes,c=Array.from,l=Object.defineProperty,u=Object.getOwnPropertyDescriptor,d=Object.getOwnPropertyDescriptors,f=Object.prototype,p=Array.prototype,m=Object.getPrototypeOf,h=Object.isExtensible,g=()=>{};function _(e){return e()}function v(e){for(var t=0;t{e=n,t=r}),resolve:e,reject:t}}function b(e,t){if(Array.isArray(e))return e;if(t===void 0||!(Symbol.iterator in e))return Array.from(e);let n=[];for(let r of e)if(n.push(r),n.length===t)break;return n}var x=1024,S=2048,C=4096,ee=8192,te=16384,ne=32768,re=1<<25,ie=65536,ae=1<<19,oe=1<<20,se=1<<25,ce=1<<21,le=1<<22,ue=1<<23,de=Symbol(`$state`),fe=Symbol(`component`),pe=Symbol(`legacy props`),me=Symbol(``),he=Symbol(`attributes`),ge=Symbol(`class`),_e=Symbol(`style`),ve=Symbol(`text`),ye=Symbol(`form reset`),be=new class extends Error{name=`StaleReactionError`;message="The reaction that called `getAbortSignal()` was re-run or destroyed"},xe=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`);function Se(){console.warn(`https://svelte.dev/e/derived_inert`)}function Ce(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function we(){console.warn(`https://svelte.dev/e/select_multiple_invalid_value`)}function Te(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var w=!1;function Ee(e){w=e}var T;function De(e){if(e===null)throw Ce(),n;return T=e}function Oe(){return De(cn(T))}function E(e){if(w){if(cn(T)!==null)throw Ce(),n;T=e}}function ke(e=1){if(w){for(var t=e,n=T;t--;)n=cn(n);T=n}}function Ae(e=!0){for(var t=0,n=T;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else(r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=cn(n);e&&n.remove(),n=i}}function je(e){if(!e||e.nodeType!==8)throw Ce(),n;return e.data}function Me(e){return e===this.v}function Ne(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function Pe(e){return!Ne(e,this.v)}function Fe(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function Ie(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function Le(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Re(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function ze(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Be(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function Ve(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function He(e){throw Error(`https://svelte.dev/e/props_invalid_value`)}function Ue(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function We(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function Ge(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function Ke(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var D=null;function qe(e){D=e}function O(t,n=!1,r){D={p:D,i:!1,c:null,e:null,s:t,x:null,r:B,l:e&&!n?{s:null,u:null,$:[]}:null}}function k(e){var t=D,n=t.e;if(n!==null){t.e=null;for(var r of n)xn(r)}return e!==void 0&&(t.x=e),t.i=!0,D=t.p,Je(e)}function Je(e={}){return l(e,fe,{value:!0}),e}function Ye(){return!e||D!==null&&D.l===null}var Xe=[];function Ze(){var e=Xe;Xe=[],v(e)}function Qe(e){if(Xe.length===0&&!Et){var t=Xe;queueMicrotask(()=>{t===Xe&&Ze()})}Xe.push(e)}function $e(){for(;Xe.length>0;)Ze()}var et=~(S|C|x);function tt(e,t){e.f=e.f&et|t}function nt(e){e.f&512||e.deps===null?tt(e,x):tt(e,C)}function rt(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),tt(e,x)}function it(e){w&&sn(e)!==null&&ln(e)}var at=!1;function ot(){at||(at=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[ye]?.()})},{capture:!0}))}function st(e){var t=z,n=B;qn(null),Jn(null);try{return e()}finally{qn(t),Jn(n)}}function ct(e,t,n,r=n){e.addEventListener(t,()=>st(n));let i=e[ye];e[ye]=i?()=>{i(),r(!0)}:()=>r(!0),ot()}function lt(e,t,n,r){let i=Ye()?pt:A;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=B,c=ut(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){mn(e,s)}dt()}}var d=ft();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>ht(e))).then(u).catch(e=>mn(e,s)).finally(d)}l?l.then(()=>{c(),f(),dt()}):f()}function ut(){var e=B,t=z,n=D,r=j;return function(i=!0){Jn(e),qn(t),qe(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function dt(e=!0){Jn(null),qn(null),qe(null),e&&j?.deactivate()}function ft(){var e=B,t=e.b,n=j,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function pt(e){var t=2|S;return B!==null&&(B.f|=ae),{ctx:D,deps:null,effects:null,equals:Me,f:t,fn:e,reactions:null,rv:0,v:r,wv:0,parent:B,ac:null}}var mt=Symbol(`obsolete`);function ht(e,t,n){let i=B;i===null&&Ie();var a=void 0,o=Ut(r),s=!z,c=new Set;return Dn(()=>{var t=B,n=y();a=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==be&&n.reject(e)}).finally(dt)}catch(e){n.reject(e),dt()}var r=j;if(s){if(t.f&32768)var l=ft();if(i.b?.is_rendered())r.async_deriveds.get(t)?.reject(mt);else for(let e of c.values())e.reject(mt);c.add(n),r.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),c.delete(n),t!==mt&&(r.activate(),t?(o.f|=ue,qt(o,t)):(o.f&8388608&&(o.f^=ue),qt(o,e)),r.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),yn(()=>{for(let e of c)e.reject(mt)}),new Promise(e=>{function t(n){function r(){n===a?e(o):t(a)}n.then(r,r)}t(a)})}function gt(e){let t=pt(e);return Xn(t),t}function A(e){let t=pt(e);return t.equals=Pe,t}function _t(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n{t.ac.abort(be),t.ac=null}),t.fn!==null&&(t.teardown=g),dr(t,0),Mn(t))}function xt(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&fr(t)}var St=null,j=null,Ct=null,wt=null,Tt=null,Et=!1,Dt=!1,Ot=null,kt=null,At=0,jt=1,Mt=class e{id=jt++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){St===null?St=this:(St.#n=this,this.#t=St),St=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)tt(r,S),t(r);for(r of n.m)tt(r,C),t(r)}this.#p.add(e)}#g(){var e=[];for(let i of this.#c)if(!(i.f&16384||!(i.f&6144))){for(var t=i,n=!1;t.parent!==null;){t=t.parent;var r=t.f;if(r&96){if(!(r&1024)){n=!0;break}t.f^=x}}n||e.push(t)}return this.#c=[],e}#_(){this.#e=!0;for(let e of this.#u)this.#d.delete(e),tt(e,S),this.schedule(e);for(let e of this.#d)tt(e,C),this.schedule(e);this.apply();for(var t=Ot=[],n=[],r=kt=[];this.#c.length>0;){At++>1e3&&(this.#S(),Pt());for(let e of this.#g())try{this.#v(e,t,n)}catch(t){throw zt(e),this.#h()||this.discard(),t}}if(j=null,r.length>0){var i=e.ensure();for(let e of r)i.schedule(e)}if(Ot=null,kt=null,this.#h()){this.#x(n),this.#x(t);for(let[e,t]of this.#f)Rt(e,t);r.length>0&&j.#_();return}let a=this.#y();if(a){this.#x(n),this.#x(t),a.#b(this);return}this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),Ct=this,It(n),It(t),Ct=null,this.#s?.resolve();var o=j;if(this.#a===0&&(this.#c.length===0||o!==null)&&this.#S(),this.#c.length>0){if(o!==null){for(let e of this.#c)o.#c.push(e);this.#c=[]}else o=this}o!==null&&(Vt.clear(),o.#_())}#v(e,t,n){e.f^=x;for(var r=e.first;r!==null;){var i=r.f,a=!!(i&96);if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=x:i&4?t.push(r):or(r)&&(i&16&&this.#d.add(r),fr(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#y(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#b(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null&&!(e.f&2&&!(e.f&6144)))for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),tt(i,S),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),j=this,this.#_()}#x(e){for(var t=0;t{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=y()).promise}static ensure(){if(j===null){let t=j=new e;!Dt&&!Et&&Qe(()=>{t.#e||t.flush()})}return j}apply(){wt=null}schedule(e){if(Tt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)){e.b.defer_effect(e);return}this.#c.push(e)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null||(e.#n=t),t===null?St=e:t.#t=e,this.linked=!1}}};function Nt(e){var t=Et;Et=!0;try{var n;for(e&&(j!==null&&!j.is_fork&&j.flush(),n=e());;){if($e(),j===null)return n;j.flush()}}finally{Et=t}}function Pt(){try{Ve()}catch(e){mn(e,Tt)}}var Ft=null;function It(e){var t=e.length;if(t!==0){for(var n=0;n0)){Vt.clear();for(let e of Ft){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)Ft.has(n)&&(Ft.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||fr(n)}}Ft.clear()}}Ft=null}}function Lt(e){j.schedule(e)}function Rt(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),tt(e,x);for(var n=e.first;n!==null;)Rt(n,t),n=n.next}}function zt(e){tt(e,x);for(var t=e.first;t!==null;)zt(t),t=t.next}var Bt=new Set,Vt=new Map,Ht=!1;function Ut(e,t){return{f:0,v:e,reactions:null,equals:Me,rv:0,wv:0}}function Wt(e,t){let n=Ut(e,t);return Xn(n),n}function M(t,n=!1,r=!0){let i=Ut(t);return n||(i.equals=Pe),e&&r&&D!==null&&D.l!==null&&(D.l.s??=[]).push(i),i}function N(e,t,n=!1){return z!==null&&(!Kn||z.f&131072)&&Ye()&&z.f&4325394&&(Yn===null||!Yn.has(e))&&Ge(),qt(e,n?Zt(t):t,kt)}var Gt=null,Kt=0;function qt(e,t,n=null){if(!e.equals(t)){Wn?Vt.set(e,t):Vt.has(e)||Vt.set(e,e.v);var r=Mt.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&&vt(t),wt===null&&nt(t)}e.wv=ar(),Gt=null,Kt=0,Xt(e,S,n),Gt=null,Ye()&&B!==null&&B.f&1024&&!(B.f&96)&&($n===null?er([e]):$n.push(e)),!r.is_fork&&Bt.size>0&&!Ht&&Jt()}return t}function Jt(){Ht=!1;for(let e of Bt){e.f&1024&&tt(e,C);let t;try{t=or(e)}catch{t=!0}t&&fr(e)}Bt.clear()}function Yt(e){N(e,e.v+1)}function Xt(e,t,n){var r=e.reactions;if(r!==null){var i=Ye(),a=r.length;if(Kt+=a,Kt>1e5&&Gt===null&&(Gt=new Set),Gt!==null){if(Gt.has(e))return;Gt.add(e)}for(var o=0;o{if(rr===c)return e();var t=z,n=rr;qn(null),ir(c);var r=e();return qn(t),ir(n),r};return i&&n.set(`length`,Wt(e.length,s)),new Proxy(e,{defineProperty(e,t,r){(!(`value`in r)||r.configurable===!1||r.enumerable===!1||r.writable===!1)&&Ue();var i=n.get(t);return i===void 0?l(()=>{var e=Wt(r.value,s);return n.set(t,e),e}):N(i,r.value,!0),!0},deleteProperty(e,t){var i=n.get(t);if(i===void 0){if(t in e){let e=l(()=>Wt(r,s));n.set(t,e),Yt(o)}}else N(i,r),Yt(o);return!0},get(t,i,a){if(i===de)return e;var o=n.get(i),c=i in t;if(o===void 0&&(!c||u(t,i)?.writable)&&(o=l(()=>Wt(Zt(c?t[i]:r),s)),n.set(i,o)),o!==void 0){var d=V(o);return d===r?void 0:d}return Reflect.get(t,i,a)},getOwnPropertyDescriptor(e,t){this.has?.(e,t);var i=Reflect.getOwnPropertyDescriptor(e,t),a=n.get(t);if(a!==void 0){var o=V(a);if(o===r)return;if(i&&`value`in i)i.value=o;else return{enumerable:!0,configurable:!0,value:o,writable:!0}}return i},has(e,t){if(t===de)return!0;var i=n.get(t),a=i!==void 0&&i.v!==r||Reflect.has(e,t);return(i!==void 0||B!==null&&(!a||u(e,t)?.writable))&&(i===void 0&&(i=l(()=>Wt(a?Zt(e[t]):r,s)),n.set(t,i)),V(i)===r)?!1:a},set(e,t,a,c){var d=n.get(t),f=t in e;if(i&&t===`length`)for(var p=a;pWt(r,s)),n.set(p+``,m)):N(m,r)}if(d===void 0)(!f||u(e,t)?.writable)&&(d=l(()=>Wt(void 0,s)),N(d,Zt(a)),n.set(t,d));else{f=d.v!==r;var h=l(()=>Zt(a));N(d,h)}var g=Reflect.getOwnPropertyDescriptor(e,t);if(g?.set&&g.set.call(c,a),!f){if(i&&typeof t==`string`){var _=n.get(`length`),v=Number(t);Number.isInteger(v)&&v>=_.v&&N(_,v+1)}Yt(o)}return!0},ownKeys(e){V(o);var t=Reflect.ownKeys(e).filter(e=>{var t=n.get(e);return t===void 0||t.v!==r});for(var[i,a]of n)a.v!==r&&!(i in e)&&t.push(i);return t},setPrototypeOf(){We()}})}function Qt(e){try{if(typeof e==`object`&&e&&de in e)return e[de]}catch{}return e}function $t(e,t){return Object.is(Qt(e),Qt(t))}var en,tn,nn,rn;function an(){if(en===void 0){en=window,tn=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;nn=u(t,`firstChild`).get,rn=u(t,`nextSibling`).get,h(e)&&(e[ge]=void 0,e[he]=null,e[_e]=void 0,e.__e=void 0),h(n)&&(n[ve]=void 0)}}function on(e=``){return document.createTextNode(e)}function sn(e){return nn.call(e)}function cn(e){return rn.call(e)}function P(e,t){if(!w)return sn(e);var n=sn(T);if(n===null)n=T.appendChild(on());else if(t&&n.nodeType!==3){var r=on();return n?.before(r),De(r),r}return t&&fn(n),De(n),n}function F(e,t=!1){if(!w){var n=sn(e);return n instanceof Comment&&n.data===``?cn(n):n}if(t){if(T?.nodeType!==3){var r=on();return T?.before(r),De(r),r}fn(T)}return T}function I(e,t=!1){if(!w)return sn(e);var n=P(e,t);return E(e),n}function L(e,t=1,n=!1){let r=w?T:e;for(var i;t--;)i=r,r=cn(r);if(!w)return r;if(n){if(r?.nodeType!==3){var a=on();return r===null?i?.after(a):r.before(a),De(a),a}fn(r)}return De(r),r}function ln(e){e.textContent=``}function un(){return!1}function dn(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function fn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function pn(e){var t=B;if(t===null)return z.f|=ue,e;if(!(t.f&32768)&&!(t.f&4))throw e;mn(e,t)}function mn(e,t){if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128&&!(t.f&33570816)){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}function hn(e){B===null&&(z===null&&Be(e),ze()),Wn&&Re(e)}function gn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function _n(e,t){var n=B;n!==null&&n.f&8192&&(e|=ee);var r={ctx:D,deps:null,nodes:null,f:e|S|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};j?.register_created_effect(r);var i=r;if(e&4)Ot===null?Mt.ensure().schedule(r):Ot.push(r);else if(t!==null){try{fr(r)}catch(e){throw Pn(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=ie))}if(i!==null&&(i.parent=n,n!==null&&gn(i,n),z!==null&&z.f&2&&!(e&64))){var a=z;(a.effects??=[]).push(i)}return r}function vn(){return z!==null&&!Kn}function yn(e){let t=_n(8,null);return tt(t,x),t.teardown=e,t}function bn(e){hn(`$effect`);var t=B.f;if(!z&&t&32&&D!==null&&!D.i){var n=D;(n.e??=[]).push(e)}else return xn(e)}function xn(e){return _n(4|oe,e)}function Sn(e){return hn(`$effect.pre`),_n(8|oe,e)}function Cn(e){Mt.ensure();let t=_n(64|ae,e);return(e={})=>new Promise(n=>{e.outro?Ln(t,()=>{Pn(t),n(void 0)}):(Pn(t),n(void 0))})}function wn(e){return _n(4,e)}function Tn(e,t){var n=D,r={effect:null,ran:!1,deps:e};n.l.$.push(r),r.effect=On(()=>{if(e(),!r.ran){r.ran=!0;var n=B;try{Jn(n.parent),H(t)}finally{Jn(n)}}})}function En(){var e=D;On(()=>{for(var t of e.l.$){t.deps();var n=t.effect;n.f&1024&&n.deps!==null&&tt(n,C),or(n)&&fr(n),t.ran=!1}})}function Dn(e){return _n(le|ae,e)}function On(e,t=0){return _n(8|t,e)}function R(e,t=[],n=[],r=[]){lt(r,t,n,t=>{_n(8,()=>{e(...t.map(V))})})}function kn(e,t=0){return _n(16|t,e)}function An(e){return _n(32|ae,e)}function jn(e){var t=e.teardown;if(t!==null){let n=Wn,r=z;Gn(!0),qn(null);try{t.call(null)}catch(t){mn(t,e.parent)}finally{Gn(n),qn(r)}}}function Mn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&st(()=>{e.abort(be)});var r=n.next;n.f&64?n.parent=null:Pn(n,t),n=r}}function Nn(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||Pn(t),t=n}}function Pn(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(Fn(e.nodes.start,e.nodes.end),n=!0),e.f|=re,Mn(e,t&&!n),dr(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();jn(e),e.f^=re,e.f|=te;var i=e.parent;i!==null&&i.first!==null&&In(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Fn(e,t){for(;e!==null;){var n=e===t?null:cn(e);e.remove(),e=n}}function In(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function Ln(e,t,n=!0){var r=[];e.f|=256,Rn(e,r,!0);var i=()=>{n&&Pn(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function Rn(e,t,n){if(!(e.f&8192)){e.f^=ee;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=!!(i.f&65536)||!!(i.f&32)&&!!(e.f&16);Rn(i,t,o?n:!1)}i=a}}}function zn(e){e.f&=-257,Bn(e,!0)}function Bn(e,t){if(!(e.f&256)&&e.f&8192){e.f^=ee,e.f&1024||(tt(e,S),Mt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=!!(n.f&65536)||!!(n.f&32);Bn(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function Vn(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:cn(n);t.append(n),n=i}}var Hn=null,Un=!1,Wn=!1;function Gn(e){Wn=e}var z=null,Kn=!1;function qn(e){z=e}var B=null;function Jn(e){B=e}var Yn=null;function Xn(e){z!==null&&(z.f&2097152||z.f&2)&&(Yn??=new Set).add(e)}var Zn=null,Qn=0,$n=null;function er(e){$n=e}var tr=1,nr=0,rr=nr;function ir(e){rr=e}function ar(){return++tr}function or(e){var t=e.f;if(t&2048)return!0;if(t&4096){for(var n=e.deps,r=n.length,i=0;ie.wv)return!0}t&512&&wt===null&&tt(e,x)}return!1}function sr(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Yn!==null&&Yn.has(e)))for(var i=0;i{e.ac.abort(be)}),e.ac=null);try{e.f|=ce;var u=e.fn,d=u();e.f|=ne;var f=lr(e);if(Ye()&&$n!==null&&!Kn&&f!==null&&!(e.f&6146))for(var p=0;p<$n.length;p++)sr($n[p],e);if(i!==null&&i!==e){if(nr++,i.deps!==null)for(let e=0;e0)for(t.length=Qn+Zn.length,r=0;r{c.ac.abort(be),c.ac=null,tt(c,S)}),bt(c),dr(c,0)}}function dr(e,t){var n=e.deps;if(n!==null)for(var r=t;rn?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?(i.__removed=!1,Qe(()=>{i.__removed||t.addEventListener(e,i,r)})):t.addEventListener(e,i,r),i}function xr(e,t,n,r,i){var a={capture:r,passive:i},o=br(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&yn(()=>{o.__removed=!0,t.removeEventListener(e,o,a)})}function Sr(e,t,n){(t[_r]??={})[e]=n}function Cr(e){for(var t=0;t{Tr=!1,wr=null}));var o=0,s=wr===e&&e[_r];if(s){var c=i.indexOf(s);if(c!==-1&&(t===document||t===window)){e[_r]=t;return}var u=i.indexOf(t);if(u===-1)return;c<=u&&(o=c)}if(a=i[o]||e.target,a!==t){l(e,`currentTarget`,{configurable:!0,get(){return a||n}});var d=z,f=B;qn(null),Jn(null);try{for(var p,m=[];a!==null&&a!==t;){try{var h=a[_r]?.[r];h!=null&&(!a.disabled||e.target===a)&&h.call(a,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;o++,a=o{throw e});throw p}}finally{e[_r]=t,delete e.currentTarget,qn(d),Jn(f)}}}var Dr=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function Or(e){return Dr?.createHTML(e)??e}function kr(e){var t=dn(`template`);return t.innerHTML=Or(e.replaceAll(``,``)),t.content}function Ar(e,t){var n=B;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function W(e,t){var n=!!(t&1),r=!!(t&2),i,a=!e.startsWith(``);return()=>{if(w)return Ar(T,null),T;i===void 0&&(i=kr(a?e:``+e),n||(i=sn(i)));var t=r||tn?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=sn(t),s=t.lastChild;Ar(o,s)}else Ar(t,t);return t}}function jr(e=``){if(!w){var t=on(e+``);return Ar(t,t),t}var n=T;return n.nodeType===3?fn(n):(n.before(n=on()),De(n)),Ar(n,n),n}function Mr(){if(w)return Ar(T,null),T;var e=document.createDocumentFragment(),t=document.createComment(``),n=on();return e.append(t,n),Ar(t,n),e}function G(e,t){if(w){var n=B;(!(n.f&32768)||n.nodes.end===null)&&(n.nodes.end=T),Oe();return}e!==null&&e.before(t)}[...`allowfullscreen.async.autofocus.autoplay.checked.controls.default.disabled.formnovalidate.indeterminate.inert.ismap.loop.multiple.muted.nomodule.novalidate.open.playsinline.readonly.required.reversed.seamless.selected.webkitdirectory.defer.disablepictureinpicture.disableremoteplayback`.split(`.`)];var Nr=[`touchstart`,`touchmove`];function Pr(e){return Nr.includes(e)}function Fr(e){let t=0,n=Ut(0),r;return()=>{vn()&&(V(n),On(()=>(t===0&&(r=H(()=>e(()=>Yt(n)))),t+=1,()=>{Qe(()=>{--t,t===0&&(r?.(),r=void 0,Yt(n))})})))}}var Ir=ie|ae;function Lr(e,t,n,r){new Rr(e,t,n,r)}var Rr=class{parent;is_pending=!1;transform_error;#e;#t=w?T:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=Fr(()=>(this.#m=Ut(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=B;t.b=this,t.f|=128,n(e)},this.parent=B.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=kn(()=>{if(w){let e=this.#t;Oe();let t=e.data===`[!`;if(e.data.startsWith(`[?`)){let t=JSON.parse(e.data.slice(2));this.#_(t)}else t?this.#y():this.#g()}else this.#b()},Ir),w&&(this.#e=T)}#g(){try{this.#a=An(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed,{reset:n,invoke_onerror:r}=this.#v(e);Qe(r),t&&(this.#s=An(()=>{t(this.#e,()=>e,()=>n)}))}#v(e){var t=!1,n=!1;let r=()=>{if(t){Te();return}t=!0,n&&Ke(),this.#s!==null&&Ln(this.#s,()=>{this.#s=null}),this.#S(()=>{this.#b()})};return{reset:r,invoke_onerror:()=>{try{n=!0,this.#n.onerror?.(e,r),n=!1}catch(e){mn(e,this.#i&&this.#i.parent)}}}}#y(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=An(()=>e(this.#e)),Qe(()=>{var e=this.#c=document.createDocumentFragment(),t=on(),n=!1;if(e.append(t),this.#a=this.#S(()=>{try{return An(()=>this.#r(t))}catch(e){try{this.error(e),n=!0}catch(e){mn(e,this.#i.parent)}return null}}),this.#a===null){this.#c=null,n&&this.#x(j);return}this.#u===0&&(this.#e.before(e),this.#c=null,Ln(this.#o,()=>{this.#o=null}),this.#x(j))}))}#b(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=An(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();Vn(this.#a,e);let t=this.#n.pending;this.#o=An(()=>t(this.#e))}else this.#x(j)}catch(e){this.error(e)}}#x(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){rt(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#S(e){var t=B,n=z,r=D;Jn(this.#i),qn(this.#i),qe(this.#i.ctx);try{return Mt.ensure(),e()}finally{Jn(t),qn(n),qe(r)}}#C(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#C(e,t);return}this.#u+=e,this.#u===0&&(this.#x(t),this.#o&&Ln(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))}update_pending_count(e,t){this.#C(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,Qe(()=>{this.#d=!1,this.#m&&qt(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),V(this.#m)}error(e){if(!this.#n.onerror&&!this.#n.failed)throw e;j?.is_fork?(this.#a&&j.skip_effect(this.#a),this.#o&&j.skip_effect(this.#o),this.#s&&j.skip_effect(this.#s),j.oncommit(()=>{this.#w(e)})):this.#w(e)}#w(e){this.#a&&=(Pn(this.#a),null),this.#o&&=(Pn(this.#o),null),this.#s&&=(Pn(this.#s),null),w&&(De(this.#t),ke(),De(Ae()));let t=this.#n.failed,n=e=>{let{reset:n,invoke_onerror:r}=this.#v(e);r(),t&&(this.#s=this.#S(()=>{try{return An(()=>{var r=B;r.b=this,r.f|=128,t(this.#e,()=>e,()=>n)})}catch(e){return mn(e,this.#i.parent),null}}))};Qe(()=>{var t;try{t=this.transform_error(e)}catch(e){mn(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(n,e=>mn(e,this.#i&&this.#i.parent)):n(t)})}};function K(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[ve]??=e.nodeValue)&&(e[ve]=n,e.nodeValue=`${n}`)}function zr(e,t){return Vr(e,t)}var Br=new Map;function Vr(e,{target:t,anchor:r,props:i={},events:a,context:o,intro:s=!0,transformError:l}){an();var u=void 0,d=Cn(()=>{var s=r??t.appendChild(on());Lr(s,{pending:()=>{}},t=>{O({});var r=D;if(o&&(r.c=o),a&&(i.$$events=a),w&&Ar(t,null),u=e(t,i)||Je(),w&&(B.nodes.end=T,T===null||T.nodeType!==8||T.data!==`]`))throw Ce(),n;k()},l);var d=new Set,f=e=>{for(var n=0;n{for(var e of d)for(let r of[t,document]){var n=Br.get(r),i=n.get(e);--i==0?(r.removeEventListener(e,Er),n.delete(e),n.size===0&&Br.delete(r)):n.set(e,i)}yr.delete(f),s!==r&&s.parentNode?.removeChild(s)}});return Hr.set(u,d),u}var Hr=new WeakMap,Ur=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)zn(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(zn(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(Pn(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();Vn(r,t),t.append(on()),this.#n.set(e,{effect:r,fragment:t})}else Pn(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),Ln(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(Pn(n.effect),this.#n.delete(e))};ensure(e,t){var n=j,r=un();if(t&&!this.#t.has(e)&&!this.#n.has(e)){if(r){var i=document.createDocumentFragment(),a=on();i.append(a),this.#n.set(e,{effect:An(()=>t(a)),fragment:i})}else this.#t.set(e,An(()=>t(this.anchor)))}if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else w&&(this.anchor=T),this.#a(n)}};function Wr(t){D===null&&Fe(`onMount`),e&&D.l!==null?Gr(D).m.push(t):bn(()=>{let e=H(t);if(typeof e==`function`)return e})}function Gr(e){var t=e.l;return t.u??={a:[],b:[],m:[]}}function q(e,t,n=!1){var r;w&&(r=T,Oe());var i=new Ur(e),a=n?ie:0;function o(e,t){if(w){var n=je(r);if(e!==parseInt(n.substring(1))){var a=Ae();De(a),i.anchor=a,Ee(!1),i.ensure(e,t),Ee(!0);return}}i.ensure(e,t)}kn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}var Kr=Symbol(`NaN`);function qr(e,t,n){w&&Oe();var r=new Ur(e),i=!Ye();kn(()=>{var e=t();e!==e&&(e=Kr),i&&typeof e==`object`&&e&&(e={}),r.ensure(e,n)})}function Jr(e,t){return t}function Yr(e,t,n){for(var r=[],i=t.length,a,o=t.length,s=0;s{if(a){if(a.pending.delete(n),a.done.add(n),a.pending.size===0){var t=e.outrogroups;Xr(e,c(a.done)),t.delete(a),t.size===0&&(e.outrogroups=null)}}else--o},!1)}if(o===0){var l=r.length===0&&n!==null&&e.pending.size===0;if(l){var u=n,d=u.parentNode;ln(d),d.append(u),e.items.clear()}Xr(e,t,!l)}else a={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(a)}function Xr(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i{var e=n();return a(e)?e:e==null?[]:c(e)}),p,m=new Map,h=!0;function g(e){v.effect.f&16384||(v.pending.delete(e),v.fallback=d,ei(v,p,s,t,r),d!==null&&(p.length===0?d.f&33554432?(d.f^=se,ni(d,null,s)):zn(d):Ln(d,()=>{d=null})))}function _(e){v.pending.delete(e)}var v={effect:kn(()=>{p=V(f);var e=p.length;let a=!1;w&&je(s)===`[!`!=(e===0)&&(s=Ae(),De(s),Ee(!1),a=!0);for(var c=new Set,u=j,v=un(),y=0;yo(s)):(d=An(()=>o(Zr??=on())),d.f|=se)),e>c.size&&Le(``,``,``),w&&e>0&&De(Ae()),!h){if(m.set(u,c),v){for(let[e,t]of l)c.has(e)||u.skip_effect(t.e);u.oncommit(g),u.ondiscard(_)}else g(u)}a&&Ee(!0),V(f)}),flags:t,items:l,pending:m,outrogroups:null,fallback:d};h=!1,w&&(s=T)}function $r(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function ei(e,t,n,r,i){var a=!!(r&8),o=t.length,s=e.items,l=$r(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(a)for(v=0;v0){var ne=r&4&&o===0?n:null;if(a){for(v=0;v{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function ti(e,t,n,r,i,a,o,s){var c=o&1?o&16?Ut(n):M(n,!1,!1):null,l=o&2?Ut(i):null;return{v:c,i:l,e:An(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function ni(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=cn(r);if(a.before(r),r===i)return;r=o}}function ri(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function ii(e,t,n){wn(()=>{var r=H(()=>t(e,n?.())||{});if(n&&r?.update){var i=!1,a={};On(()=>{var e=n();U(e),i&&Ne(a,e)&&(a=e,r.update(e))}),i=!0}if(r?.destroy)return()=>r.destroy()})}function ai(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`){if(Array.isArray(e)){var i=e.length;for(t=0;t=0;){var s=o+a;(o===0||ci.includes(r[o-1]))&&(s===r.length||ci.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function ui(e,t,n,r,i,a){var o=e[ge];if(w||o!==n||o===void 0){var s=li(n,r,a);(!w||s!==e.getAttribute(`class`))&&(s==null?e.removeAttribute(`class`):t?e.className=s:e.setAttribute(`class`,s)),e[ge]=n}else if(a&&i!==a)for(var c in a){var l=!!a[c];(i==null||l!==!!i[c])&&e.classList.toggle(c,l)}return a}function di(e,t){t?e.hasAttribute(`selected`)||e.setAttribute(`selected`,``):e.removeAttribute(`selected`)}function fi(e,t){var n=e.__defaultValue,r=e.multiple,i=r?n??[]:null;if(!r||a(i)){var o=e.selectedIndex,s=t&&r?new Set(e.selectedOptions):null;for(var c of e.options){var l=gi(c);di(c,r?i.includes(l):$t(l,n))}if(t){if(s!==null)for(c of e.options){var u=s.has(c);c.selected!==u&&(c.selected=u)}else e.selectedIndex!==o&&(e.selectedIndex=o)}}}function pi(e,t,n=!1){if(e.multiple){if(t==null)return;if(!a(t))return we();for(var r of e.options)r.selected=t.includes(gi(r));return}for(r of e.options)if($t(gi(r),t)){r.selected=!0;return}(!n||t!==void 0)&&(e.selectedIndex=-1)}function mi(e){var t=new MutationObserver(t=>{t.every(_i)||(`__defaultValue`in e&&fi(e,!1),`__value`in e&&pi(e,e.__value))});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`value`]}),yn(()=>{t.disconnect()})}function hi(e,t,n=t){var r=new WeakSet,i=!0;ct(e,`change`,t=>{var i=t?`[selected]`:`:checked`,a;if(e.multiple)a=[].map.call(e.querySelectorAll(i),gi);else{var o=e.querySelector(i)??e.querySelector(`option:not([disabled])`);a=o&&gi(o)}n(a),e.__value=a,j!==null&&r.add(j)}),wn(()=>{var a=t();if(e===document.activeElement){var o=j;if(r.has(o))return}if(pi(e,a,i),i&&a===void 0){var s=e.querySelector(`:checked`);s!==null&&(a=gi(s),n(a))}e.__value=a,i=!1})}function gi(e){return`__value`in e?e.__value:e.value}function _i(e){if(e.target.closest(`selectedcontent`)!==null)return!0;if(e.type===`childList`){var t=[...e.addedNodes,...e.removedNodes];return t.length>0&&t.every(e=>e.nodeName===`SELECTEDCONTENT`)}return!1}var vi=Symbol(`is custom element`),yi=Symbol(`is html`),bi=xe?`link`:`LINK`;function xi(e){if(w){var t=!1,n=()=>{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;J(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;J(e,`checked`,null),e.checked=r}}};e[ye]=n,Qe(n),ot()}}function Si(e,t){var n=Ci(e);n.checked!==(n.checked=t??void 0)&&(e.checked=t)}function J(e,t,n,r){var i=Ci(e);w&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===bi)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[me]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&Ti(e).has(t)?e[t]=n:e.setAttribute(t,n))}function Ci(e){return e[he]??={[vi]:e.nodeName.includes(`-`),[yi]:e.namespaceURI===i}}var wi=new Map;function Ti(e){var t=e.getAttribute(`is`)||e.nodeName,n=wi.get(t);if(n)return n;wi.set(t,n=new Set);for(var r,i=e,a=Element.prototype;a!==i;){for(var o in r=d(i),r)r[o].set&&o!==`innerHTML`&&o!==`textContent`&&o!==`innerText`&&n.add(o);i=m(i)}return n}function Ei(e,t,n=t){var r=new WeakSet;ct(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=Di(e)?Oi(a):a,n(a),j!==null&&r.add(j),await pr(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(w&&e.defaultValue!==e.value||H(t)==null&&e.value)&&(n(Di(e)?Oi(e.value):e.value),j!==null&&r.add(j)),On(()=>{var n=t();if(e===document.activeElement){var i=j;if(r.has(i))return}Di(e)&&n===Oi(e.value)||(e.type!==`date`||n||e.value)&&n!==e.value&&(e.value=n??``)})}function Di(e){var t=e.type;return t===`number`||t===`range`}function Oi(e){return e===``?null:+e}function Y(e=!1){let t=D,n=t.l.u;if(!n)return;let r=()=>U(t.s);if(e){let e=0,n={},i=pt(()=>{let r=!1,i=t.s;for(let e in i)i[e]!==n[e]&&(n[e]=i[e],r=!0);return r&&e++,e});r=()=>V(i)}n.b.length&&Sn(()=>{ki(t,r),v(n.b)}),bn(()=>{let e=H(()=>n.m.map(_));return()=>{for(let t of e)typeof t==`function`&&t()}}),n.a.length&&bn(()=>{ki(t,r),v(n.a)})}function ki(e,t){if(e.l.s)for(let t of e.l.s)V(t);t()}function Ai(e,t,n){if(e==null)return t(void 0),n&&n(void 0),g;let r=H(()=>e.subscribe(t,n));return r.unsubscribe?()=>r.unsubscribe():r}var ji=[];function Mi(e,t=g){let n=null,r=new Set;function i(t){if(Ne(e,t)&&(e=t,n)){let t=!ji.length;for(let t of r)t[1](),ji.push(t,e);if(t){for(let e=0;e{r.delete(c),r.size===0&&n&&(n(),n=null)}}return{set:i,update:a,subscribe:o}}function Ni(e){let t;return Ai(e,e=>t=e)(),t}var Pi=!1,Fi=Symbol(`unmounted`);function X(e,t,n){let r=n[t]??={store:null,source:M(void 0),unsubscribe:g};if(r.store!==e&&!(Fi in n)){if(r.unsubscribe(),r.store=e??null,e==null)r.source.v=void 0,r.unsubscribe=g;else{var i=!0;r.unsubscribe=Ai(e,e=>{i?r.source.v=e:N(r.source,e)}),i=!1}}return e&&Fi in n?Ni(e):V(r.source)}function Ii(){let e={};function t(){yn(()=>{for(var t in e)e[t].unsubscribe();l(e,Fi,{enumerable:!1,value:!0})})}return[e,t]}function Li(e){var t=Pi;try{return Pi=!1,[e(),Pi]}finally{Pi=t}}function Z(t,n,r,i){var a=!e||!!(r&2),o=!!(r&8),s=!!(r&16),c=i,l=!0,d=void 0,f=()=>s&&a?(d??=pt(i),V(d)):(l&&(l=!1,c=s?H(i):i),c);let p;if(o){var m=de in t||pe in t;p=u(t,n)?.set??(m&&n in t?e=>t[n]=e:void 0)}var h,g=!1;o?[h,g]=Li(()=>t[n]):h=t[n],h===void 0&&i!==void 0&&(h=f(),p&&(a&&He(n),p(h)));var _=a?()=>{var e=t[n];return e===void 0?f():(l=!0,e)}:()=>{var e=t[n];return e!==void 0&&(c=void 0),e===void 0?c:e};if(a&&!(r&4))return _;if(p){var v=t.$$legacy;return(function(e,t){return arguments.length>0?((!a||!t||v||g)&&p(t?_():e),e):_()})}var y=!1,b=(r&1?pt:A)(()=>(y=!1,_()));o&&V(b);var x=B;return(function(e,t){if(arguments.length>0){let n=t?V(b):a&&o?Zt(e):e;return N(b,n),y=!0,c!==void 0&&(c=n),e}return Wn&&y||x.f&16384?b.v:V(b)})}function Ri(e){let t=Mi({paired:!!e,controller:!1,busy:!1,error:``}),n=e,r,i={paired:!!e,controller:!1,busy:!1,error:``},a=!1;function o(e){i={...i,...e},t.set(i)}async function s(e=!1){if(!a&&n){a=!0;try{let t=await fetch(`/api/state`,{cache:`no-store`,headers:{"X-Setup-Session-Key":n}});if(!t.ok)throw Error(`The local setup session is unavailable.`);o({view:await t.json(),...e?{}:{error:``}})}catch{o({view:void 0,error:`Connection lost. The CLI may have stopped. Check the terminal before trying again.`})}finally{a=!1}}}let c=()=>s(!0);async function l(){if(n)try{let e=await fetch(`/api/bootstrap`,{cache:`no-store`,headers:{"X-Setup-Session-Key":n}});if(!e.ok)throw Error(`Could not join this local session.`);let t=await e.json();r=t.capability,o({controller:t.controller,error:``}),await s()}catch{n=void 0,r=void 0,o({view:void 0,paired:!1,controller:!1,error:`Could not connect to the local setup session. Check the terminal and pair again.`})}}async function u(e){if(!(i.busy||i.paired)){o({busy:!0,error:``});try{let t=await fetch(`/api/pair`,{method:`POST`,cache:`no-store`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:e.trim().toLowerCase()})}),r=await t.json();if(!t.ok)throw Error(String(r.error??`Pairing was rejected.`));if(typeof r.sessionKey!=`string`||!/^[a-f0-9]{64}$/.test(r.sessionKey))throw Error(`Invalid local pairing response.`);n=r.sessionKey,o({paired:!0,error:``}),await l()}catch(e){o({error:e instanceof Error?e.message:`Could not pair this browser.`})}finally{o({busy:!1})}}}async function d(e,t,i=!0){let a=await fetch(e,{method:`POST`,cache:`no-store`,headers:{"Content-Type":`application/json`,"X-Setup-Session-Key":n,...i&&r?{"X-Setup-Capability":r}:{}},body:JSON.stringify(t)}),o=await a.json();if(!a.ok)throw Error(String(o.error??`The request was rejected.`));return o}async function f(e,t){let n=e instanceof Error?e.message:t;o({error:n}),/read-only|Control moved/.test(n)?await l():await s(!0)}async function p(e,t){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/answer`,{revision:e,value:t}),await s()}catch(e){await f(e,`Could not submit this answer.`)}finally{o({busy:!1})}}}async function m(e){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/retry-discovery`,{revision:e}),await s()}catch(e){await f(e,`Could not retry discovery.`)}finally{o({busy:!1})}}}async function h(e){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/back`,{revision:e}),await s()}catch(e){await f(e,`Could not return to the previous question.`)}finally{o({busy:!1})}}}async function g(){if(i.controller&&!i.busy){o({busy:!0,error:``});try{await d(`/api/cancel`,{}),await s()}catch(e){let t=e instanceof Error?e.message:`Cancellation failed.`;o({error:t}),/read-only|Control moved/.test(t)&&await l()}finally{o({busy:!1})}}}async function _(e){if(!(i.busy||!i.paired||i.controller)){o({busy:!0,error:``});try{let t=await d(`/api/takeover`,{code:e.trim().toLowerCase()},!1);r=String(t.capability),o({controller:!0,error:``}),await s()}catch(e){o({error:e instanceof Error?e.message:`Takeover failed.`}),await s(!0)}finally{o({busy:!1})}}}async function v(){try{await d(`/api/close`,{})}catch{}}async function y(){if(!i.busy&&i.controller&&i.view?.outcome===`complete`){o({busy:!0,error:``,view:{...i.view,doctor:{status:`running`}}});try{await d(`/api/doctor`,{})}catch(e){o({error:e instanceof Error?e.message:`Read-only verification failed.`})}finally{await s(!0),o({busy:!1})}}}return{subscribe:t.subscribe,pair:u,connect:l,refresh:s,poll:c,submit:p,retryDiscovery:m,back:h,cancel:g,takeOver:_,close:v,runDoctor:y}}var zi={language:`Language`,english:`English`,spanish:`Español`,setup:`SETUP`,connecting:`Connecting…`,localSession:`LOCAL SESSION`,progress:`Setup progress`,studio:`SETUP STUDIO`,journey:`YOUR SETUP JOURNEY`,repository:`Repository`,choices:`Setup choices`,setupPat:`Setup PAT`,plan:`Plan`,botPat:`Bot PAT & credentials`,apply:`Apply`,localDesign:`Local by design`,localDesignBody:`This page runs on your computer. GitHub creates both PATs in its own browser tabs.`,preparing:`Preparing your setup…`,completeTitle:`Setup complete.`,previewTitle:`Preview complete.`,cancelledTitle:`Setup cancelled.`,blockedTitle:`Setup needs attention.`,gettingReady:`GETTING READY`,activeLede:`One decision at a time. Your choices shape the permissions, plan and credentials needed for this repository.`,resultLede:`Review the result and next action below. The terminal has additional technical detail.`,readOnly:`Read-only tab`,readOnlyBody:`Another tab controls this session. You can review progress here or explicitly take over.`,takeOver:`Take control in this tab`,attention:`Needs attention`,checked:`Checked`,pleaseNote:`Please note`,progressUpdate:`Progress update`,reviewPass:`Reviewing saved choices — pass {pass}. This is the same setup run, not a restart.`,cancelSetup:`Cancel setup`,cancelConfirm:`Cancel this local setup session? PATs already created in GitHub will still exist.`,footerLocal:`LOCALHOST ONLY`,footerCloud:`NO CLOUD SETUP ACCOUNT`,footerGithub:`GITHUB OWNS PAT ISSUANCE`,currentDecision:`CURRENT DECISION`,session:`SESSION`,continue:`Continue`,previousQuestion:`Previous question`,questionProgress:`Question {current} of {total} in this group · {overall} of {all} overall`,yes:`Yes`,no:`No`,permissionPreview:`PERMISSION PREVIEW`,changeAnswersTitle:`Change your answers`,changeAnswersHelp:`Return to a section without losing other answers. The plan and required PAT grants will be checked again.`,changeSection:`Change {section}`,editCapabilities:`Capabilities`,editRuntimes:`Agent runtimes`,editModels:`Agent models`,editRoleModels:`Per-role models`,editRepository:`Repository behavior`,editDeployment:`Release and hotfix`,editBugbot:`Bugbot`,editApproval:`PR approval`,editProjects:`Projects`,editProvisioning:`Provisioning`,editStorage:`Secrets and Variables`,suggested:`Suggested answer: {answer}. You can review choices again before creating your setup PAT.`,none:`none`,sourceGithub:`Observed from authenticated GitHub repository metadata.`,sourceConfig:`Provided by your configuration; GitHub has not replaced it.`,sourceDefault:`Product default; not verified against this repository.`,sourceLocal:`Observed in this local checkout; confirm this branch exists on GitHub before applying.`,whyMatters:`Why this matters`,whenApplies:`When it applies`,whereConfigured:`Where it is configured`,howToChoose:`How to choose`,whyRecommendation:`Why this matters`,example:`Example`,effect:`What changes`,verify:`How to check`,learnMore:`Read documentation about this setting`,resultApplied:`Your configuration was applied`,resultNoChanges:`No changes were made`,resultStopped:`No setup changes started`,resultPartial:`Check partial changes before retrying`,resultCompleteBody:`The temporary setup PAT is not revoked automatically. Delete it in GitHub after confirming your setup. Keep the bot PAT until you rotate the installed Secret.`,resultPartialBody:`A bot Secret write or another change may have succeeded. Inspect GitHub and run copilot doctor --read-only before replacing or deleting its PAT.`,resultNoChangesBody:`Copilot did not begin applying setup changes. PATs you created in GitHub still exist until you delete them there.`,whatHappened:`What happened`,alreadyChanged:`Already changed`,noChanges:`No repository or GitHub setup changes were started in this session.`,nextAction:`Next action`,reasonPermissions:`The setup PAT lacked or could not confirm required permissions.`,nextPermissions:`Check the displayed grants, correct the PAT in GitHub, then start a fresh setup run.`,permissionReportTitle:`PAT permission evidence`,permissionReportLead:`Any required grants that could not be confirmed are listed below. Unverifiable does not mean missing.`,permissionIdentity:`GitHub identity and repository access`,permissionIdentityValid:`Verified`,permissionIdentityInvalid:`Rejected`,permissionIdentityUnknown:`Could not be confirmed`,permissionReportNoFailedGrant:`No required grant failed this check. Review the intended PAT account and the terminal error before retrying.`,reasonStorage:`The selected GitHub Actions storage could not be used safely.`,nextStorage:`Inspect the Variables/Secrets scope and existing resources, then retry.`,reasonConfiguration:`The chosen configuration could not be validated.`,nextConfiguration:`Review the terminal validation details, correct the choices, and retry.`,reasonExpired:`The local setup session expired.`,nextExpired:`Start a new setup session; the old approval cannot be replayed.`,reasonCancelled:`This setup was cancelled.`,nextCancelled:`Start a new run if you still want to configure this repository.`,reasonUnknown:`Setup stopped. The browser could not determine the exact cause or which changes completed.`,nextUnknown:`Check the final terminal error before retrying; do not assume a PAT was revoked.`,reasonProvider:`GitHub or another provider did not complete the requested operation.`,nextProvider:`Use the diagnostic reference to inspect the terminal result, check provider availability and access, then retry only after reviewing possible partial changes.`,reasonRateLimit:`GitHub temporarily limited the requests needed for setup.`,nextRateLimit:`Wait for the limit to reset. Inspect any completed changes before starting another setup run.`,diagnosticReference:`Diagnostic reference`,resourceReceipt:`Setup operation receipt`,effectCompleted:`Reported completed`,effectSkipped:`Reported skipped`,effectInspect:`Outcome needs inspection`,effectNotStarted:`Not started`,effectInProgress:`In progress; outcome not yet confirmed`,scopeLocal:`Local checkout`,scopeMixed:`Repository and organization`,receiptFiles:`Setup files`,receiptSecrets:`GitHub Actions Secrets`,receiptLabels:`Issue labels`,receiptIssueTypes:`Issue types`,receiptVariables:`GitHub Actions Variables`,receiptInitialTag:`Initial version tag`,inspectPartial:`Some setup changes may already be active. Inspect GitHub and the terminal result before retrying.`,patSettings:`Open GitHub PAT settings ↗`,closeSession:`Close local session`,doctorHelp:`After success, you can verify installed resources here without dispatching Actions. Or run copilot doctor --read-only from the repository root with the temporary setup PAT and the same non-secret --config file, if used.`,doctorRun:`Verify installed setup (read-only)`,doctorRunning:`Checking installed resources without dispatching Actions…`,doctorPassed:`Read-only verification found no failing checks.`,doctorWarnings:`Read-only verification needs attention.`,doctorFailed:`Read-only verification did not finish. Check the terminal or run the command below.`,doctorCounts:`{pass} passed · {warn} warnings · {fail} failed · {skipped} skipped.`,doctorSecretLimit:`Secret values cannot be verified in this mode.`,botRenewal:`The bot PAT stays in the selected GitHub Actions Secret for future runs. Its actual expiry is not verified here; record it in GitHub and rotate the Secret before expiry.`,working:`Working on the next step`,workingBody:`The local process is checking your answers and preparing the next decision. Keep this page open.`,repoFocus:`Repository in focus`,repoFocusBody:`All decisions in this session target only:`,access:`access`,readOnlyCheck:`Read-only access check`,provisionalGrants:`Provisional least-privilege grants`,conditionalGrants:`Conditional grants depend on the choices and GitHub facts. A final audit runs before setup changes.`,permissionUnknown:`This permission needs review. Check its exact grant and technical explanation in the terminal before continuing.`,permissionsFollow:`Permissions follow your choices`,permissionsFollowBody:`We’ll show the exact grants before you create each PAT. Nothing is created just by opening this page.`,files:`Files`,workflows:`Workflows`,variables:`Variables`,secretNames:`Secret names`,planBody:`Review exactly what this run may change. The bot PAT and any additional credentials are collected next.`,planChoices:`Your key decisions`,planEnabledCapabilities:`Enabled capabilities`,planBranchRoles:`Production / development branch`,planApprovalMode:`Pull-request approval`,planVariableScope:`Variables scope`,planSecretScope:`Secrets scope`,planInitialTag:`Create initial tag`,planAgentRouting:`Agent and model for each task`,planIssueWorkflows:`Issue workflows`,planTrustedChecks:`Trusted CI producers`,planCoverage:`Coverage evidence`,planProjectStatuses:`Project Status transitions`,planIssueResources:`Issue labels and issue types`,planIssueResourcesValue:`Checked or provisioned during Apply`,planProducerAttested:`CI identity and enforcing step verified by you`,planCoverageThreshold:`Minimum changed-line coverage`,planCoverageReporter:`Artifact-publishing workflow`,planReporterAttested:`Coverage reporter verified by you`,planAdvancedDefaults:`The plan also includes defaults for settings you did not change. Use Change below to inspect any section before approving.`,planUnknownWarning:`An additional plan warning could not be displayed here. Read the terminal warning before approving.`,planBasicDefaultsIntro:`Basic setup retained these advanced defaults. Open a section below to review or change them:`,scopeRepository:`Repository`,scopeOrganization:`Organization`,scopeDisabled:`Not provisioned`,approvalOff:`Off`,approvalRecommend:`Recommendation only`,approvalGuarded:`Guarded approval`,beforeContinue:`Before you continue`,stopHere:`Stop here`,approvePlan:`Approve this plan`,githubLink:`Open GitHub link ↗`,githubForm:`Open the official GitHub PAT form`,githubFormHelp:`Check the signed-in account, select Only select repositories, then select this repository. GitHub handles 2FA and creates the PAT.`,pasteHere:`Paste the value here`,yourAnswer:`Your answer`,hiddenAfter:`Hidden after submission`,typeAnswer:`Type your answer`,secretHelp:`Sent only to this local process. It will not be shown again or saved in browser storage.`,pairTitle:`Pair this browser`,pairLabel:`Pairing code from terminal`,pairPlaceholder:`16 hexadecimal characters`,pairBody:`Find the 16-character pairing code in the terminal that started copilot setup --web. Enter it here to view or control this setup. The code is never placed in the browser URL or stored after this page closes.`,pairHelp:`Keep the code private. After refreshing this page, enter it again to reconnect.`,pairButton:`Connect to local setup`,privateSession:`PRIVATE LOCAL SESSION`,theme:`Color theme`,themeAuto:`Auto`,themeSystem:`Follow system theme`,themeLight:`Light theme`,themeDark:`Dark theme`,selectOne:`Select one`,ciRun:`Open CI run on GitHub ↗`,manualCheck:`Check not listed? Enter exact name|App ID|workflow, separated by semicolons.`,checksObserved:`Recent CI jobs were found. Open each run and verify the exact job, App and enforcing coverage step before trusting it.`,checksNoRecent:`No recent pull-request workflow runs were found. Run your normal CI on a real pull request, or enter an exact producer manually.`,checksNoVerifiable:`Recent runs exist, but no job could be linked to an exact Check Run and App identity. Inspect GitHub or enter an exact producer manually.`,checksDenied:`GitHub did not allow CI discovery. Give the setup PAT Actions: read and Checks: read, or enter an exact producer manually.`,checksUnavailable:`GitHub CI discovery could not complete. This is not evidence that the repository has no checks. Retry setup or enter an exact producer manually.`,projectsObserved:`These existing Projects belong to the repository owner. Select only Projects this automation should update.`,projectsEmpty:`This bounded GitHub query returned no open, accessible organization Projects; it does not prove none exist. Check access or enter a verified Project number.`,projectsDenied:`GitHub did not allow Project discovery. Check organization Projects: read on the setup PAT, or enter Project numbers manually.`,projectsUnavailable:`GitHub Project discovery could not complete. This is not evidence that no Projects exist. Enter a verified Project number manually or retry.`,projectsUnsupported:`GitHub does not support listing personal Projects with a fine-grained PAT through this endpoint. Enter an existing Project number from its URL.`,discoveryTruncated:`Only a bounded sample of accessible Projects or recent checks was inspected. Use manual entry for an item not shown.`,checksDiscoveryScope:`Search scope: up to 20 recent pull-request workflow runs; at most 15 runs and 100 checks per commit are inspected.`,projectsDiscoveryScope:`Search scope: at most 30 open, accessible organization Projects from two pages; up to 100 fields are inspected per Project. Closed Projects are excluded.`,retryDiscovery:`Retry GitHub discovery`,retryRemaining:`{count} read-only retries left. Your answers stay here.`,retryExhausted:`No discovery retries remain. Inspect GitHub and use the manual option if the item is missing.`,observationTimeUnknown:`observation time unavailable`,branchRequirementUnknown:`Required by branch rule: not checked`,branchRequirementObserved:`Required on {branch} by an active ruleset for this exact check and App.`,ciRule:`Open required-check ruleset ↗`,projectSharedStatus:`All selected Projects must share each chosen Status value. This setup cannot assign a different Status vocabulary per Project.`,fixedWorkflowEnabled:`Your configuration fixes features.{kind}=true. Keep {kind} selected; edit --config or flags to change this.`,fixedWorkflowDisabled:`Your configuration fixes features.{kind}=false. Leave {kind} unselected; edit --config or flags to change this.`,fixedIssuesRequired:`Your configuration explicitly enables release or hotfix automation. Keep Issues enabled, or change --config or flags first.`,projectSelectionNotObserved:`Previously selected Project numbers are retained, but no longer appear in this GitHub result. Verify each in GitHub or remove it.`,removeSelection:`Remove selection`,projectTransitionIssueCreated:`New issue`,projectTransitionPullRequestCreated:`New pull request`,projectTransitionIssueInProgress:`Issue in progress`,projectTransitionPullRequestInProgress:`Pull request in progress`,projectUrl:`Open Project on GitHub ↗`,projectManual:`Project not listed? Enter its positive number or exact GitHub URL. PVT_ IDs are not accepted.`,projectStatusUnavailable:`Status options could not be verified for every selected Project. Enter the exact existing Status value after checking each Project in GitHub.`,projectStatusIncompatible:`Selected Projects have no shared Status values. Choose compatible Projects before continuing.`,producerName:`Check/job name`,producerAppId:`Source GitHub App ID`,producerWorkflow:`Workflow name`,producerAdd:`Add exact check`,producerRemove:`Remove check`,producerManualHelp:`Use the exact identity shown on GitHub. Adding it does not attest that it enforces coverage.`,producerManualInvalid:`Enter a check name, positive numeric App ID and workflow name. Do not use | or ; in names.`,translationPreviewTitle:`Translation review in progress`,translationPreviewBody:`First-party setup questions are translated. Some dynamic GitHub or provider diagnostics may still appear in English while localization review finishes. Changing language does not change your answers.`,unknownLocalError:`An unexpected local setup error occurred. Check the terminal for details, then refresh or restart setup.`},Bi={language:`Idioma`,english:`English`,spanish:`Español`,setup:`CONFIGURACIÓN`,connecting:`Conectando…`,localSession:`SESIÓN LOCAL`,progress:`Progreso de la configuración`,studio:`ASISTENTE DE CONFIGURACIÓN`,journey:`TU RECORRIDO`,repository:`Repositorio`,choices:`Opciones de configuración`,setupPat:`PAT de configuración`,plan:`Plan`,botPat:`PAT del bot y credenciales`,apply:`Aplicar`,localDesign:`Local por diseño`,localDesignBody:`Esta página se ejecuta en tu ordenador. GitHub crea ambos PAT en sus propias pestañas.`,preparing:`Preparando la configuración…`,completeTitle:`Configuración completada.`,previewTitle:`Vista previa completada.`,cancelledTitle:`Configuración cancelada.`,blockedTitle:`La configuración necesita atención.`,gettingReady:`PREPARANDO`,activeLede:`Una decisión cada vez. Tus elecciones determinan los permisos, el plan y las credenciales que necesita este repositorio.`,resultLede:`Revisa abajo el resultado y el siguiente paso. La terminal contiene más detalles técnicos.`,readOnly:`Pestaña de solo lectura`,readOnlyBody:`Otra pestaña controla esta sesión. Puedes ver el progreso aquí o tomar el control explícitamente.`,takeOver:`Tomar el control en esta pestaña`,attention:`Necesita atención`,checked:`Comprobado`,pleaseNote:`Ten en cuenta`,progressUpdate:`Actualización de progreso`,reviewPass:`Revisando las opciones guardadas — pasada {pass}. Es la misma ejecución, no un reinicio.`,cancelSetup:`Cancelar configuración`,cancelConfirm:`¿Cancelar esta sesión local? Los PAT ya creados en GitHub seguirán existiendo.`,footerLocal:`SOLO LOCALHOST`,footerCloud:`SIN CUENTA DE CONFIGURACIÓN EN LA NUBE`,footerGithub:`GITHUB EMITE LOS PAT`,currentDecision:`DECISIÓN ACTUAL`,session:`SESIÓN`,continue:`Continuar`,previousQuestion:`Pregunta anterior`,questionProgress:`Pregunta {current} de {total} en este grupo · {overall} de {all} en total`,yes:`Sí`,no:`No`,permissionPreview:`VISTA PREVIA DE PERMISOS`,changeAnswersTitle:`Cambiar respuestas`,changeAnswersHelp:`Vuelve a una sección sin perder las demás respuestas. Se comprobarán de nuevo el plan y los permisos necesarios del PAT.`,changeSection:`Cambiar {section}`,editCapabilities:`Funciones`,editRuntimes:`Agentes`,editModels:`Modelos de agentes`,editRoleModels:`Modelos por tarea`,editRepository:`Comportamiento del repositorio`,editDeployment:`Releases y hotfixes`,editBugbot:`Bugbot`,editApproval:`Aprobación de PR`,editProjects:`Projects`,editProvisioning:`Aprovisionamiento`,editStorage:`Secrets y Variables`,suggested:`Respuesta sugerida: {answer}. Podrás revisar las opciones antes de crear el PAT de configuración.`,none:`ninguna`,sourceGithub:`Consultado en los metadatos autenticados de este repositorio en GitHub.`,sourceConfig:`Valor de tu configuración; GitHub no lo ha sustituido.`,sourceDefault:`Valor predeterminado del producto; no verificado en este repositorio.`,sourceLocal:`Observado en este checkout local; confirma que la rama existe en GitHub antes de aplicar cambios.`,whyMatters:`Por qué importa`,whenApplies:`Cuándo se aplica`,whereConfigured:`Dónde se configura`,howToChoose:`Cómo elegir`,whyRecommendation:`Por qué importa`,example:`Ejemplo`,effect:`Qué cambia`,verify:`Cómo comprobarlo`,learnMore:`Leer documentación de esta opción`,resultApplied:`Tu configuración se ha aplicado`,resultNoChanges:`No se hicieron cambios`,resultStopped:`No se empezó a aplicar la configuración`,resultPartial:`Revisa los cambios parciales antes de reintentar`,resultCompleteBody:`El PAT temporal de configuración no se revoca automáticamente. Elimínalo en GitHub tras comprobar el resultado. Conserva el PAT del bot hasta que rotes el Secret instalado.`,resultPartialBody:`Puede haberse escrito el Secret del bot u otro recurso. Revisa GitHub y ejecuta copilot doctor --read-only antes de reemplazar o eliminar ese PAT.`,resultNoChangesBody:`Copilot no empezó a aplicar cambios de configuración. Los PAT creados en GitHub siguen existiendo hasta que los elimines allí.`,whatHappened:`Qué ha pasado`,alreadyChanged:`Qué ha cambiado`,noChanges:`No se iniciaron cambios de configuración en el repositorio ni en GitHub durante esta sesión.`,nextAction:`Siguiente paso`,reasonPermissions:`Faltan permisos del PAT de configuración o no pudieron confirmarse.`,nextPermissions:`Comprueba los permisos mostrados, corrige el PAT en GitHub e inicia una nueva sesión.`,permissionReportTitle:`Comprobación de permisos del PAT`,permissionReportLead:`Se muestran los permisos obligatorios que no pudieron confirmarse. «No verificable» no significa «ausente».`,permissionIdentity:`Identidad de GitHub y acceso al repositorio`,permissionIdentityValid:`Verificados`,permissionIdentityInvalid:`Rechazados`,permissionIdentityUnknown:`No se pudieron confirmar`,permissionReportNoFailedGrant:`La comprobación no detectó un permiso obligatorio fallido. Revisa la cuenta prevista para el PAT y el error de la terminal antes de reintentarlo.`,reasonStorage:`No se pudo usar de forma segura el almacenamiento elegido de GitHub Actions.`,nextStorage:`Revisa el ámbito de Variables/Secrets y los recursos existentes; después, reinténtalo.`,reasonConfiguration:`No se pudo validar la configuración elegida.`,nextConfiguration:`Revisa el detalle de validación en la terminal, corrige las opciones y reinténtalo.`,reasonExpired:`La sesión local caducó.`,nextExpired:`Inicia una sesión nueva; la aprobación anterior no puede reutilizarse.`,reasonCancelled:`La sesión se canceló.`,nextCancelled:`Inicia una nueva ejecución si todavía quieres configurar este repositorio.`,reasonUnknown:`La configuración se detuvo. La web no pudo determinar la causa exacta ni qué cambios se completaron.`,nextUnknown:`Consulta el último error de la terminal antes de reintentar; no supongas que se revocó ningún PAT.`,reasonProvider:`GitHub u otro proveedor no completó la operación solicitada.`,nextProvider:`Usa la referencia de diagnóstico para consultar la terminal, comprueba la disponibilidad y el acceso al proveedor y revisa posibles cambios parciales antes de reintentar.`,reasonRateLimit:`GitHub ha limitado temporalmente las solicitudes necesarias para la configuración.`,nextRateLimit:`Espera a que se restablezca el límite. Inspecciona los cambios completados antes de iniciar otra configuración.`,diagnosticReference:`Referencia de diagnóstico`,resourceReceipt:`Registro de operaciones de configuración`,effectCompleted:`Marcada como completada`,effectSkipped:`Marcada como omitida`,effectInspect:`Resultado pendiente de inspección`,effectNotStarted:`No iniciada`,effectInProgress:`En curso; resultado aún sin confirmar`,scopeLocal:`Checkout local`,scopeMixed:`Repositorio y organización`,receiptFiles:`Archivos de configuración`,receiptSecrets:`Secrets de GitHub Actions`,receiptLabels:`Etiquetas de issues`,receiptIssueTypes:`Tipos de issue`,receiptVariables:`Variables de GitHub Actions`,receiptInitialTag:`Etiqueta de versión inicial`,inspectPartial:`Algunos cambios podrían estar activos. Revisa GitHub y el resultado de la terminal antes de reintentar.`,patSettings:`Abrir ajustes de PAT en GitHub ↗`,closeSession:`Cerrar sesión local`,doctorHelp:`Tras completar el setup, puedes comprobar aquí los recursos instalados sin lanzar Actions. También puedes ejecutar copilot doctor --read-only desde la raíz del repositorio con el PAT temporal y el mismo archivo --config no secreto, si lo usaste.`,doctorRun:`Comprobar instalación (solo lectura)`,doctorRunning:`Comprobando los recursos instalados sin lanzar Actions…`,doctorPassed:`La comprobación de solo lectura no encontró fallos.`,doctorWarnings:`La comprobación de solo lectura requiere atención.`,doctorFailed:`La comprobación de solo lectura no terminó. Revisa la terminal o ejecuta el comando indicado abajo.`,doctorCounts:`{pass} correctas · {warn} avisos · {fail} fallos · {skipped} omitidas.`,doctorSecretLimit:`Este modo no puede verificar los valores de Secrets.`,botRenewal:`El PAT del bot permanece en el Secret de GitHub Actions seleccionado para futuras ejecuciones. Su fecha real de caducidad no se verifica aquí; anótala en GitHub y rota el Secret antes de que venza.`,working:`Preparando el siguiente paso`,workingBody:`El proceso local comprueba tus respuestas y prepara la siguiente decisión. Mantén esta página abierta.`,repoFocus:`Repositorio seleccionado`,repoFocusBody:`Todas las decisiones de esta sesión afectan solo a:`,access:`acceso`,readOnlyCheck:`Comprobación de acceso de solo lectura`,provisionalGrants:`Permisos provisionales de mínimo privilegio`,conditionalGrants:`Los permisos condicionales dependen de tus elecciones y de GitHub. Se hará una auditoría final antes de cualquier cambio.`,permissionUnknown:`Este permiso requiere revisión. Comprueba en la terminal el permiso exacto y su explicación técnica antes de continuar.`,permissionsFollow:`Los permisos dependen de tus elecciones`,permissionsFollowBody:`Mostraremos los permisos exactos antes de crear cada PAT. Abrir esta página no crea nada.`,files:`Archivos`,workflows:`Workflows`,variables:`Variables`,secretNames:`Nombres de Secrets`,planBody:`Revisa exactamente lo que podría cambiar. Después se pedirán el PAT del bot y las demás credenciales.`,planChoices:`Tus decisiones principales`,planEnabledCapabilities:`Funciones activadas`,planBranchRoles:`Rama de producción / desarrollo`,planApprovalMode:`Aprobación de pull requests`,planVariableScope:`Ámbito de Variables`,planSecretScope:`Ámbito de Secrets`,planInitialTag:`Crear etiqueta inicial`,planAgentRouting:`Agente y modelo por tarea`,planIssueWorkflows:`Flujos de issues`,planTrustedChecks:`Productores de CI fiables`,planCoverage:`Prueba de cobertura`,planProjectStatuses:`Transiciones de Status en Projects`,planIssueResources:`Etiquetas y tipos de issue`,planIssueResourcesValue:`Se comprobarán o crearán al aplicar`,planProducerAttested:`Identidad de CI y paso obligatorio comprobados por ti`,planCoverageThreshold:`Cobertura mínima de líneas modificadas`,planCoverageReporter:`Workflow que publica el artefacto`,planReporterAttested:`Generador de cobertura comprobado por ti`,planAdvancedDefaults:`El plan también incluye valores predeterminados de ajustes que no cambiaste. Usa Cambiar más abajo para revisar cualquier sección antes de aprobar.`,planUnknownWarning:`Hay un aviso adicional del plan que no se puede mostrar aquí. Léelo en la terminal antes de aprobar.`,planBasicDefaultsIntro:`El modo básico conservó estos ajustes avanzados. Abre una sección más abajo para revisarlos o cambiarlos:`,scopeRepository:`Repositorio`,scopeOrganization:`Organización`,scopeDisabled:`Sin aprovisionar`,approvalOff:`Desactivada`,approvalRecommend:`Solo recomendaciones`,approvalGuarded:`Aprobación protegida`,beforeContinue:`Antes de continuar`,stopHere:`Detener aquí`,approvePlan:`Aprobar este plan`,githubLink:`Abrir enlace de GitHub ↗`,githubForm:`Abrir el formulario oficial de PAT de GitHub`,githubFormHelp:`Comprueba la cuenta activa, elige Only select repositories y selecciona este repositorio. GitHub gestiona el 2FA y crea el PAT.`,pasteHere:`Pega aquí el valor`,yourAnswer:`Tu respuesta`,hiddenAfter:`Oculto tras enviarlo`,typeAnswer:`Escribe tu respuesta`,secretHelp:`Se envía solo a este proceso local. No volverá a mostrarse ni se guardará en el almacenamiento del navegador.`,pairTitle:`Vincula este navegador`,pairLabel:`Código de vinculación de la terminal`,pairPlaceholder:`16 caracteres hexadecimales`,pairBody:`Busca el código de 16 caracteres en la terminal donde ejecutaste copilot setup --web. Introdúcelo para ver o controlar la sesión. No aparece en la URL ni se almacena al cerrar la página.`,pairHelp:`Mantén el código en privado. Tras actualizar la página, introdúcelo de nuevo para reconectar.`,pairButton:`Conectar a la configuración local`,privateSession:`SESIÓN LOCAL PRIVADA`,theme:`Tema de color`,themeAuto:`Sistema`,themeSystem:`Seguir tema del sistema`,themeLight:`Tema claro`,themeDark:`Tema oscuro`,selectOne:`Selecciona una opción`,ciRun:`Abrir ejecución de CI en GitHub ↗`,manualCheck:`¿No aparece el check? Introduce nombre|ID de App|workflow exactos, separados por punto y coma.`,checksObserved:`Se encontraron jobs recientes de CI. Abre cada ejecución y comprueba el job, la App y el paso obligatorio de cobertura antes de confiar en él.`,checksNoRecent:`No hay ejecuciones recientes de workflows de pull request. Ejecuta tu CI habitual en un PR real o introduce manualmente un productor exacto.`,checksNoVerifiable:`Hay ejecuciones recientes, pero ningún job pudo vincularse a un Check Run y una App concretos. Revisa GitHub o introduce el productor manualmente.`,checksDenied:`GitHub no permitió consultar los checks. Concede Actions: read y Checks: read al PAT de configuración, o introduce el productor manualmente.`,checksUnavailable:`No se pudo completar la consulta de CI. Esto no significa que el repositorio no tenga checks. Reintenta o introduce el productor manualmente.`,projectsObserved:`Estos Projects existentes pertenecen al dueño del repositorio. Selecciona solo los que deba actualizar la automatización.`,projectsEmpty:`Esta consulta limitada no devolvió Projects abiertos y accesibles; eso no demuestra que no existan. Comprueba el acceso o introduce un número verificado.`,projectsDenied:`GitHub no permitió consultar Projects. Comprueba Projects: read de la organización en el PAT o introduce los números manualmente.`,projectsUnavailable:`No se pudo consultar Projects. Eso no demuestra que no existan. Introduce un número verificado o reintenta.`,projectsUnsupported:`GitHub no permite listar Projects personales con un PAT de permisos precisos mediante esta API. Introduce el número de la URL de un Project existente.`,discoveryTruncated:`Solo se inspeccionó una muestra limitada de Projects accesibles o checks recientes. Usa la entrada manual si falta uno.`,checksDiscoveryScope:`Alcance: hasta 20 ejecuciones recientes de workflows de PR; se inspeccionan como máximo 15 ejecuciones y 100 checks por commit.`,projectsDiscoveryScope:`Alcance: hasta 30 Projects abiertos y accesibles de la organización en dos páginas; se inspeccionan hasta 100 campos por Project. Se excluyen los Projects cerrados.`,retryDiscovery:`Reintentar búsqueda en GitHub`,retryRemaining:`Quedan {count} reintentos de solo lectura. Tus respuestas se conservan.`,retryExhausted:`No quedan reintentos. Consulta GitHub e introduce manualmente lo que falte.`,observationTimeUnknown:`fecha de observación no disponible`,branchRequirementUnknown:`Obligatorio según la regla de rama: no comprobado`,branchRequirementObserved:`Obligatorio en {branch} por un ruleset activo para este check y esta App exactos.`,ciRule:`Abrir ruleset del check obligatorio ↗`,projectSharedStatus:`Todos los Projects elegidos deben compartir cada valor Status. Este setup no asigna valores diferentes por Project.`,fixedWorkflowEnabled:`Tu configuración fija features.{kind}=true. Mantén {kind} seleccionado; cambia --config o los flags si quieres modificarlo.`,fixedWorkflowDisabled:`Tu configuración fija features.{kind}=false. Deja {kind} sin seleccionar; cambia --config o los flags si quieres modificarlo.`,fixedIssuesRequired:`Tu configuración activa expresamente release o hotfix. Mantén Issues activado o cambia antes --config o los flags.`,projectSelectionNotObserved:`Se conservan los números de Project elegidos antes, aunque ya no figuren en esta consulta. Compruébalos en GitHub o quítalos.`,removeSelection:`Quitar selección`,projectTransitionIssueCreated:`Issue nuevo`,projectTransitionPullRequestCreated:`Pull request nuevo`,projectTransitionIssueInProgress:`Issue en curso`,projectTransitionPullRequestInProgress:`Pull request en curso`,projectUrl:`Abrir Project en GitHub ↗`,projectManual:`¿Falta un Project? Introduce su número positivo o URL exacta de GitHub. No se aceptan IDs PVT_.`,projectStatusUnavailable:`No se pudieron verificar las opciones Status de todos los Projects elegidos. Comprueba cada Project en GitHub e introduce el valor exacto.`,projectStatusIncompatible:`Los Projects elegidos no comparten valores Status. Elige Projects compatibles antes de continuar.`,producerName:`Nombre del check/job`,producerAppId:`ID de la App de GitHub`,producerWorkflow:`Nombre del workflow`,producerAdd:`Añadir check exacto`,producerRemove:`Quitar check`,producerManualHelp:`Usa la identidad exacta de GitHub. Añadirla no acredita que exija la cobertura.`,producerManualInvalid:`Indica nombre, ID numérico positivo de App y workflow. No uses | ni ; en los nombres.`,translationPreviewTitle:`Revisión de la traducción en curso`,translationPreviewBody:`Las preguntas propias de la configuración ya están traducidas. Algunos diagnósticos dinámicos de GitHub o del proveedor aún pueden aparecer en inglés mientras termina la revisión. Cambiar de idioma no modifica tus respuestas.`,unknownLocalError:`Se ha producido un error inesperado en la configuración local. Consulta la terminal y actualiza la página o reinicia la configuración.`},Vi={language:`Langue`,english:`Anglais`,spanish:`Espagnol`,setup:`CONFIGURATION`,connecting:`Connexion…`,localSession:`SESSION LOCALE`,progress:`Progression`,studio:`ASSISTANT DE CONFIGURATION`,journey:`VOTRE PARCOURS`,repository:`Dépôt`,choices:`Choix`,setupPat:`PAT de configuration`,plan:`Plan`,botPat:`PAT du bot et identifiants`,apply:`Appliquer`,localDesign:`Local par conception`,localDesignBody:`Cette page fonctionne sur votre ordinateur. GitHub crée les deux PAT dans ses propres onglets.`,preparing:`Préparation…`,completeTitle:`Configuration terminée.`,previewTitle:`Aperçu terminé.`,cancelledTitle:`Configuration annulée.`,blockedTitle:`Une intervention est nécessaire.`,gettingReady:`PRÉPARATION`,activeLede:`Une décision à la fois. Vos choix déterminent les droits, le plan et les identifiants nécessaires.`,resultLede:`Consultez le résultat et la prochaine étape ci-dessous. Le terminal fournit les détails techniques.`,readOnly:`Onglet en lecture seule`,readOnlyBody:`Un autre onglet contrôle cette session. Vous pouvez suivre la progression ou prendre le contrôle.`,takeOver:`Prendre le contrôle`,attention:`Action nécessaire`,checked:`Vérifié`,pleaseNote:`À noter`,progressUpdate:`Mise à jour`,reviewPass:`Révision des choix enregistrés — passage {pass}. C’est la même session, pas un redémarrage.`,cancelSetup:`Annuler`,cancelConfirm:`Annuler cette session locale ? Les PAT créés sur GitHub continueront d’exister.`,footerLocal:`LOCALHOST UNIQUEMENT`,footerCloud:`AUCUN COMPTE CLOUD`,footerGithub:`GITHUB ÉMET LES PAT`,currentDecision:`DÉCISION ACTUELLE`,session:`SESSION`,continue:`Continuer`,previousQuestion:`Question précédente`,questionProgress:`Question {current} sur {total} dans ce groupe · {overall} sur {all} au total`,yes:`Oui`,no:`Non`,permissionPreview:`APERÇU DES DROITS`,changeAnswersTitle:`Modifier vos réponses`,changeAnswersHelp:`Revenez à une section sans perdre les autres réponses. Le plan et les droits PAT requis seront vérifiés à nouveau.`,changeSection:`Modifier {section}`,editCapabilities:`Fonctionnalités`,editRuntimes:`Agents`,editModels:`Modèles des agents`,editRoleModels:`Modèles par tâche`,editRepository:`Comportement du dépôt`,editDeployment:`Releases et correctifs`,editBugbot:`Bugbot`,editApproval:`Approbation des PR`,editProjects:`Projects`,editProvisioning:`Provisionnement`,editStorage:`Secrets et Variables`,suggested:`Réponse suggérée : {answer}. Vous pourrez revoir vos choix avant de créer le PAT.`,none:`aucune`,sourceGithub:`Observé dans les métadonnées authentifiées de ce dépôt GitHub.`,sourceConfig:`Fourni par votre configuration ; GitHub ne l’a pas remplacé.`,sourceDefault:`Valeur par défaut du produit ; non vérifiée dans ce dépôt.`,sourceLocal:`Observé dans ce dossier local ; vérifiez que cette branche existe sur GitHub avant d’appliquer les changements.`,whyMatters:`Pourquoi c’est important`,whenApplies:`Quand cela s’applique`,whereConfigured:`Où se fait le réglage`,howToChoose:`Comment choisir`,whyRecommendation:`Pourquoi c’est important`,example:`Exemple`,effect:`Ce qui change`,verify:`Comment vérifier`,learnMore:`Lire la documentation de ce réglage`,resultApplied:`Configuration appliquée`,resultNoChanges:`Aucun changement effectué`,resultStopped:`Aucun changement commencé`,resultPartial:`Vérifiez les changements partiels`,resultCompleteBody:`Le PAT temporaire n’est pas révoqué automatiquement. Supprimez-le sur GitHub après vérification. Gardez le PAT du bot jusqu’à rotation du Secret.`,resultPartialBody:`Un Secret ou une autre ressource a peut-être été modifié. Vérifiez GitHub et exécutez copilot doctor --read-only avant de remplacer ou supprimer un PAT.`,resultNoChangesBody:`Copilot n’a pas commencé à appliquer la configuration. Les PAT créés sur GitHub restent actifs jusqu’à leur suppression là-bas.`,whatHappened:`Ce qui s’est passé`,alreadyChanged:`Déjà modifié`,noChanges:`Aucun changement du dépôt ou de GitHub n’a commencé pendant cette session.`,nextAction:`Prochaine étape`,reasonPermissions:`Les droits nécessaires du PAT de configuration manquent ou n’ont pas pu être confirmés.`,nextPermissions:`Vérifiez les droits affichés, corrigez le PAT sur GitHub, puis recommencez.`,permissionReportTitle:`Vérification des droits du PAT`,permissionReportLead:`Les droits requis qui n’ont pas pu être confirmés sont indiqués ci-dessous. « Non vérifiable » ne signifie pas « absent ».`,permissionIdentity:`Identité GitHub et accès au dépôt`,permissionIdentityValid:`Vérifiés`,permissionIdentityInvalid:`Refusés`,permissionIdentityUnknown:`Non confirmés`,permissionReportNoFailedGrant:`Cette vérification n’a trouvé aucun droit requis en échec. Vérifiez le compte prévu pour le PAT et l’erreur du terminal avant de réessayer.`,reasonStorage:`Le stockage GitHub Actions choisi ne peut pas être utilisé en sécurité.`,nextStorage:`Vérifiez la portée des Variables/Secrets et les ressources existantes, puis réessayez.`,reasonConfiguration:`La configuration choisie n’a pas pu être validée.`,nextConfiguration:`Lisez les détails du terminal, corrigez les choix et réessayez.`,reasonExpired:`La session locale a expiré.`,nextExpired:`Démarrez une nouvelle session ; l’ancienne approbation ne peut pas être réutilisée.`,reasonCancelled:`La configuration a été annulée.`,nextCancelled:`Démarrez une nouvelle session si vous souhaitez encore configurer ce dépôt.`,reasonUnknown:`La configuration s’est arrêtée. Le navigateur ne peut déterminer ni la cause exacte ni les modifications effectuées.`,nextUnknown:`Consultez la dernière erreur du terminal avant de réessayer. Ne supposez pas qu’un PAT a été révoqué.`,reasonProvider:`GitHub ou un autre fournisseur n’a pas terminé l’opération demandée.`,nextProvider:`Utilisez la référence de diagnostic pour consulter le terminal, vérifiez la disponibilité et les accès, puis examinez tout changement partiel avant de réessayer.`,reasonRateLimit:`GitHub a temporairement limité les requêtes nécessaires à la configuration.`,nextRateLimit:`Attendez la réinitialisation de la limite. Examinez les changements effectués avant de recommencer.`,diagnosticReference:`Référence de diagnostic`,resourceReceipt:`Reçu des opérations de configuration`,effectCompleted:`Signalée comme terminée`,effectSkipped:`Signalée comme ignorée`,effectInspect:`Résultat à vérifier`,effectNotStarted:`Non commencée`,effectInProgress:`En cours ; résultat non encore confirmé`,scopeLocal:`Dossier local`,scopeMixed:`Dépôt et organisation`,receiptFiles:`Fichiers de configuration`,receiptSecrets:`Secrets GitHub Actions`,receiptLabels:`Étiquettes des tickets`,receiptIssueTypes:`Types de ticket`,receiptVariables:`Variables GitHub Actions`,receiptInitialTag:`Première étiquette de version`,inspectPartial:`Des changements peuvent déjà être actifs. Vérifiez GitHub et le terminal avant de réessayer.`,patSettings:`Ouvrir les paramètres PAT GitHub ↗`,closeSession:`Fermer la session locale`,doctorHelp:`Après la configuration, vérifiez ici les ressources installées sans déclencher d’Actions. Vous pouvez aussi exécuter copilot doctor --read-only à la racine du dépôt avec le PAT temporaire et le même fichier --config non secret, le cas échéant.`,doctorRun:`Vérifier l’installation (lecture seule)`,doctorRunning:`Vérification des ressources installées sans déclencher d’Actions…`,doctorPassed:`La vérification en lecture seule n’a trouvé aucun échec.`,doctorWarnings:`La vérification en lecture seule demande une attention particulière.`,doctorFailed:`La vérification en lecture seule ne s’est pas terminée. Consultez le terminal ou exécutez la commande ci-dessous.`,doctorCounts:`{pass} réussis · {warn} avertissements · {fail} échecs · {skipped} ignorés.`,doctorSecretLimit:`Ce mode ne peut pas vérifier les valeurs des Secrets.`,botRenewal:`Le PAT du bot reste dans le secret GitHub Actions choisi pour les futures exécutions. Sa date d’expiration réelle n’est pas vérifiée ici ; notez-la sur GitHub et remplacez le secret avant cette date.`,working:`Préparation de l’étape suivante`,workingBody:`Le processus local vérifie vos réponses. Gardez cette page ouverte.`,repoFocus:`Dépôt concerné`,repoFocusBody:`Toutes les décisions de cette session concernent uniquement :`,access:`accès`,readOnlyCheck:`Vérification en lecture seule`,provisionalGrants:`Droits provisoires minimaux`,conditionalGrants:`Les droits conditionnels dépendent de vos choix et de GitHub. Un contrôle final précède toute modification.`,permissionUnknown:`Ce droit exige une vérification. Consultez le droit exact et son explication technique dans le terminal avant de continuer.`,permissionsFollow:`Les droits suivent vos choix`,permissionsFollowBody:`Les droits exacts sont affichés avant chaque PAT. Ouvrir cette page ne crée rien.`,files:`Fichiers`,workflows:`Workflows`,variables:`Variables`,secretNames:`Noms des Secrets`,planBody:`Vérifiez précisément ce qui pourrait changer. Le PAT du bot et les autres identifiants seront demandés ensuite.`,planChoices:`Vos décisions principales`,planEnabledCapabilities:`Fonctionnalités activées`,planBranchRoles:`Branche de production / développement`,planApprovalMode:`Approbation des pull requests`,planVariableScope:`Portée des variables`,planSecretScope:`Portée des secrets`,planInitialTag:`Créer la première étiquette`,planAgentRouting:`Agent et modèle par tâche`,planIssueWorkflows:`Workflows de tickets`,planTrustedChecks:`Producteurs CI de confiance`,planCoverage:`Preuve de couverture`,planProjectStatuses:`Transitions Status des Projects`,planIssueResources:`Étiquettes et types de ticket`,planIssueResourcesValue:`Vérifiés ou créés lors de l’application`,planProducerAttested:`Identité CI et étape obligatoire vérifiées par vous`,planCoverageThreshold:`Couverture minimale des lignes modifiées`,planCoverageReporter:`Workflow publiant l’artefact`,planReporterAttested:`Producteur du rapport de couverture vérifié par vous`,planAdvancedDefaults:`Le plan comprend aussi les valeurs par défaut des réglages non modifiés. Utilisez Modifier ci-dessous pour examiner une section avant de valider.`,planUnknownWarning:`Un avertissement supplémentaire du plan ne peut pas être affiché ici. Lisez-le dans le terminal avant de valider.`,planBasicDefaultsIntro:`Le parcours de base a conservé ces réglages avancés. Ouvrez une section ci-dessous pour les vérifier ou les modifier :`,scopeRepository:`Dépôt`,scopeOrganization:`Organisation`,scopeDisabled:`Non provisionné`,approvalOff:`Désactivée`,approvalRecommend:`Recommandation uniquement`,approvalGuarded:`Approbation protégée`,beforeContinue:`Avant de continuer`,stopHere:`Arrêter ici`,approvePlan:`Approuver ce plan`,githubLink:`Ouvrir le lien GitHub ↗`,githubForm:`Ouvrir le formulaire PAT officiel de GitHub`,githubFormHelp:`Vérifiez le compte connecté, choisissez Only select repositories et ce dépôt. GitHub gère la 2FA et crée le PAT.`,pasteHere:`Collez la valeur ici`,yourAnswer:`Votre réponse`,hiddenAfter:`Masquée après envoi`,typeAnswer:`Saisissez votre réponse`,secretHelp:`Envoyé uniquement au processus local. Ni réaffiché ni enregistré dans le navigateur.`,pairTitle:`Associer ce navigateur`,pairLabel:`Code du terminal`,pairPlaceholder:`16 caractères hexadécimaux`,pairBody:`Trouvez le code à 16 caractères dans le terminal qui a lancé copilot setup --web. Il ne figure pas dans l’URL et n’est pas conservé après fermeture.`,pairHelp:`Gardez ce code secret. Après actualisation, saisissez-le de nouveau.`,pairButton:`Se connecter à la configuration locale`,privateSession:`SESSION LOCALE PRIVÉE`,theme:`Thème`,themeAuto:`Auto`,themeSystem:`Suivre le système`,themeLight:`Thème clair`,themeDark:`Thème sombre`,selectOne:`Choisissez une option`,ciRun:`Voir l’exécution CI sur GitHub ↗`,manualCheck:`Check absent ? Saisissez nom|ID App|workflow exacts, séparés par des points-virgules.`,checksObserved:`Des jobs CI récents ont été trouvés. Ouvrez chaque exécution et vérifiez le job, l’App et l’étape obligatoire de couverture avant de lui faire confiance.`,checksNoRecent:`Aucune exécution récente de workflow de pull request. Lancez le CI habituel sur une vraie PR ou saisissez un producteur exact.`,checksNoVerifiable:`Des exécutions récentes existent, mais aucun job ne correspond à une identité exacte de Check Run et d’App. Vérifiez GitHub ou saisissez-la.`,checksDenied:`GitHub a refusé la découverte CI. Accordez Actions: read et Checks: read au PAT de configuration, ou saisissez un producteur exact.`,checksUnavailable:`La découverte CI a échoué. Cela ne prouve pas l’absence de checks. Réessayez ou saisissez un producteur exact.`,projectsObserved:`Ces Projects existants appartiennent au propriétaire du dépôt. Ne choisissez que ceux que l’automatisation doit modifier.`,projectsEmpty:`Cette requête GitHub limitée n’a renvoyé aucun Project ouvert et accessible ; elle ne prouve pas leur absence. Vérifiez l’accès ou saisissez un numéro vérifié.`,projectsDenied:`GitHub a refusé la découverte des Projects. Vérifiez Projects: read au niveau organisation sur le PAT, ou saisissez les numéros.`,projectsUnavailable:`La découverte des Projects a échoué. Cela ne prouve pas leur absence. Saisissez un numéro vérifié ou réessayez.`,projectsUnsupported:`Cette API GitHub ne liste pas les Projects personnels avec un PAT à permissions fines. Saisissez le numéro figurant dans l’URL.`,discoveryTruncated:`Seul un échantillon limité de Projects accessibles ou checks récents a été inspecté. Saisissez manuellement un élément absent.`,checksDiscoveryScope:`Périmètre : jusqu’à 20 exécutions récentes de workflows de PR ; au plus 15 exécutions et 100 checks par commit sont inspectés.`,projectsDiscoveryScope:`Périmètre : au plus 30 Projects ouverts et accessibles de l’organisation sur deux pages ; jusqu’à 100 champs sont inspectés par Project. Les Projects fermés sont exclus.`,retryDiscovery:`Relancer la recherche GitHub`,retryRemaining:`Il reste {count} essais en lecture seule. Vos réponses sont conservées.`,retryExhausted:`Plus aucun essai disponible. Vérifiez GitHub et saisissez manuellement tout élément manquant.`,observationTimeUnknown:`date d’observation indisponible`,branchRequirementUnknown:`Exigé par la règle de branche : non vérifié`,branchRequirementObserved:`Exigé sur {branch} par un ruleset actif pour ce contrôle et cette application précis.`,ciRule:`Ouvrir le ruleset du contrôle obligatoire ↗`,projectSharedStatus:`Tous les Projects choisis doivent partager chaque valeur Status. Cette configuration ne définit pas de valeurs différentes par Project.`,fixedWorkflowEnabled:`Votre configuration fixe features.{kind}=true. Gardez {kind} sélectionné ; modifiez --config ou les options pour changer ce choix.`,fixedWorkflowDisabled:`Votre configuration fixe features.{kind}=false. Ne sélectionnez pas {kind} ; modifiez --config ou les options pour changer ce choix.`,fixedIssuesRequired:`Votre configuration active explicitement release ou hotfix. Gardez Issues activé ou modifiez d’abord --config ou les options.`,projectSelectionNotObserved:`Les numéros de Projects choisis auparavant sont conservés, mais n’apparaissent plus dans ce résultat GitHub. Vérifiez-les sur GitHub ou retirez-les.`,removeSelection:`Retirer la sélection`,projectTransitionIssueCreated:`Nouveau ticket`,projectTransitionPullRequestCreated:`Nouvelle pull request`,projectTransitionIssueInProgress:`Ticket en cours`,projectTransitionPullRequestInProgress:`Pull request en cours`,projectUrl:`Ouvrir le Project sur GitHub ↗`,projectManual:`Project absent ? Saisissez son numéro positif ou son URL GitHub exacte. Les ID PVT_ sont refusés.`,projectStatusUnavailable:`Les options Status n’ont pas pu être vérifiées pour tous les Projects. Vérifiez-les sur GitHub et saisissez la valeur exacte.`,projectStatusIncompatible:`Les Projects choisis ne partagent aucun Status. Choisissez des Projects compatibles avant de continuer.`,producerName:`Nom du check/job`,producerAppId:`ID de l’App GitHub source`,producerWorkflow:`Nom du workflow`,producerAdd:`Ajouter le check exact`,producerRemove:`Retirer le check`,producerManualHelp:`Utilisez l’identité exacte affichée sur GitHub. L’ajouter ne prouve pas que la couverture est imposée.`,producerManualInvalid:`Indiquez le nom, un ID numérique positif d’App et le workflow. N’utilisez ni | ni ; dans les noms.`,translationPreviewTitle:`Révision de la traduction en cours`,translationPreviewBody:`Les questions propres à la configuration sont traduites. Certains diagnostics dynamiques de GitHub ou du fournisseur peuvent encore apparaître en anglais pendant la révision. Changer de langue ne modifie pas vos réponses.`,unknownLocalError:`Une erreur inattendue est survenue pendant la configuration locale. Consultez le terminal, puis actualisez la page ou relancez la configuration.`},Hi={language:`Idioma`,english:`Inglês`,spanish:`Espanhol`,setup:`CONFIGURAÇÃO`,connecting:`A ligar…`,localSession:`SESSÃO LOCAL`,progress:`Progresso`,studio:`ASSISTENTE DE CONFIGURAÇÃO`,journey:`O SEU PERCURSO`,repository:`Repositório`,choices:`Opções`,setupPat:`PAT de configuração`,plan:`Plano`,botPat:`PAT do bot e credenciais`,apply:`Aplicar`,localDesign:`Local por conceção`,localDesignBody:`Esta página funciona no seu computador. O GitHub cria ambos os PAT nos seus próprios separadores.`,preparing:`A preparar a configuração…`,completeTitle:`Configuração concluída.`,previewTitle:`Pré-visualização concluída.`,cancelledTitle:`Configuração cancelada.`,blockedTitle:`A configuração requer atenção.`,gettingReady:`A PREPARAR`,activeLede:`Uma decisão de cada vez. As suas escolhas determinam permissões, plano e credenciais.`,resultLede:`Consulte abaixo o resultado e o próximo passo. O terminal contém mais detalhes técnicos.`,readOnly:`Separador só de leitura`,readOnlyBody:`Outro separador controla esta sessão. Pode acompanhar o progresso ou assumir o controlo.`,takeOver:`Assumir o controlo`,attention:`Requer atenção`,checked:`Verificado`,pleaseNote:`Atenção`,progressUpdate:`Atualização de progresso`,reviewPass:`A rever as escolhas guardadas — passagem {pass}. É a mesma execução, não um reinício.`,cancelSetup:`Cancelar configuração`,cancelConfirm:`Cancelar esta sessão local? Os PAT já criados no GitHub continuarão a existir.`,footerLocal:`APENAS LOCALHOST`,footerCloud:`SEM CONTA DE CONFIGURAÇÃO NA NUVEM`,footerGithub:`O GITHUB EMITE OS PAT`,currentDecision:`DECISÃO ATUAL`,session:`SESSÃO`,continue:`Continuar`,previousQuestion:`Pergunta anterior`,questionProgress:`Pergunta {current} de {total} neste grupo · {overall} de {all} no total`,yes:`Sim`,no:`Não`,permissionPreview:`PRÉ-VISUALIZAÇÃO DAS PERMISSÕES`,changeAnswersTitle:`Alterar respostas`,changeAnswersHelp:`Volte a uma secção sem perder as outras respostas. O plano e as permissões PAT necessárias serão verificados de novo.`,changeSection:`Alterar {section}`,editCapabilities:`Funcionalidades`,editRuntimes:`Agentes`,editModels:`Modelos dos agentes`,editRoleModels:`Modelos por tarefa`,editRepository:`Comportamento do repositório`,editDeployment:`Releases e correções`,editBugbot:`Bugbot`,editApproval:`Aprovação de PR`,editProjects:`Projects`,editProvisioning:`Provisionamento`,editStorage:`Secrets e Variables`,suggested:`Resposta sugerida: {answer}. Pode rever as opções antes de criar o PAT.`,none:`nenhuma`,sourceGithub:`Observado nos metadados autenticados deste repositório no GitHub.`,sourceConfig:`Fornecido pela sua configuração; o GitHub não o substituiu.`,sourceDefault:`Valor predefinido do produto; não verificado neste repositório.`,sourceLocal:`Observado neste checkout local; confirme que o ramo existe no GitHub antes de aplicar alterações.`,whyMatters:`Porque importa`,whenApplies:`Quando se aplica`,whereConfigured:`Onde se configura`,howToChoose:`Como escolher`,whyRecommendation:`Porque importa`,example:`Exemplo`,effect:`O que muda`,verify:`Como verificar`,learnMore:`Ler a documentação desta opção`,resultApplied:`A configuração foi aplicada`,resultNoChanges:`Nenhuma alteração efetuada`,resultStopped:`Nenhuma alteração iniciada`,resultPartial:`Verifique as alterações parciais`,resultCompleteBody:`O PAT temporário não é revogado automaticamente. Elimine-o no GitHub após verificar. Guarde o PAT do bot até rodar o Secret.`,resultPartialBody:`Um Secret ou outro recurso pode ter sido alterado. Verifique o GitHub e execute copilot doctor --read-only antes de substituir ou eliminar o PAT.`,resultNoChangesBody:`O Copilot não começou a aplicar alterações. Os PAT criados no GitHub permanecem até serem eliminados lá.`,whatHappened:`O que aconteceu`,alreadyChanged:`O que mudou`,noChanges:`Não foram iniciadas alterações no repositório nem no GitHub nesta sessão.`,nextAction:`Próximo passo`,reasonPermissions:`Faltam permissões do PAT de configuração ou não foi possível confirmá-las.`,nextPermissions:`Verifique as permissões, corrija o PAT no GitHub e inicie uma nova sessão.`,permissionReportTitle:`Verificação das permissões do PAT`,permissionReportLead:`As permissões obrigatórias que não puderam ser confirmadas aparecem abaixo. «Não verificável» não significa «ausente».`,permissionIdentity:`Identidade GitHub e acesso ao repositório`,permissionIdentityValid:`Verificados`,permissionIdentityInvalid:`Recusados`,permissionIdentityUnknown:`Não confirmados`,permissionReportNoFailedGrant:`Esta verificação não encontrou uma permissão obrigatória em falta. Confirme a conta prevista para o PAT e o erro no terminal antes de tentar novamente.`,reasonStorage:`O armazenamento GitHub Actions escolhido não pôde ser usado com segurança.`,nextStorage:`Verifique o âmbito das Variables/Secrets e os recursos existentes; depois tente novamente.`,reasonConfiguration:`Não foi possível validar a configuração escolhida.`,nextConfiguration:`Leia os detalhes no terminal, corrija as opções e tente novamente.`,reasonExpired:`A sessão local expirou.`,nextExpired:`Inicie uma nova sessão; a aprovação anterior não pode ser reutilizada.`,reasonCancelled:`A configuração foi cancelada.`,nextCancelled:`Inicie outra execução se ainda quiser configurar o repositório.`,reasonUnknown:`A configuração parou. O navegador não conseguiu determinar a causa exata nem quais alterações foram concluídas.`,nextUnknown:`Leia o último erro no terminal antes de tentar novamente. Não presuma que um PAT foi revogado.`,reasonProvider:`O GitHub ou outro fornecedor não concluiu a operação solicitada.`,nextProvider:`Use a referência de diagnóstico para consultar o terminal, verifique a disponibilidade e o acesso e reveja possíveis alterações parciais antes de tentar novamente.`,reasonRateLimit:`O GitHub limitou temporariamente os pedidos necessários para a configuração.`,nextRateLimit:`Aguarde a reposição do limite. Inspecione as alterações concluídas antes de iniciar outra configuração.`,diagnosticReference:`Referência de diagnóstico`,resourceReceipt:`Registo das operações de configuração`,effectCompleted:`Indicada como concluída`,effectSkipped:`Indicada como ignorada`,effectInspect:`Resultado por inspecionar`,effectNotStarted:`Não iniciada`,effectInProgress:`Em curso; resultado ainda por confirmar`,scopeLocal:`Checkout local`,scopeMixed:`Repositório e organização`,receiptFiles:`Ficheiros de configuração`,receiptSecrets:`Secrets do GitHub Actions`,receiptLabels:`Etiquetas das questões`,receiptIssueTypes:`Tipos de questão`,receiptVariables:`Variables do GitHub Actions`,receiptInitialTag:`Etiqueta de versão inicial`,inspectPartial:`Algumas alterações podem estar ativas. Verifique o GitHub e o terminal antes de tentar novamente.`,patSettings:`Abrir definições de PAT no GitHub ↗`,closeSession:`Fechar sessão local`,doctorHelp:`Depois de concluir a configuração, pode verificar aqui os recursos instalados sem iniciar Actions. Também pode executar copilot doctor --read-only na raiz do repositório com o PAT temporário e o mesmo ficheiro --config não secreto, caso o tenha usado.`,doctorRun:`Verificar instalação (só de leitura)`,doctorRunning:`A verificar os recursos instalados sem iniciar Actions…`,doctorPassed:`A verificação só de leitura não encontrou falhas.`,doctorWarnings:`A verificação só de leitura requer atenção.`,doctorFailed:`A verificação só de leitura não terminou. Consulte o terminal ou execute o comando abaixo.`,doctorCounts:`{pass} aprovados · {warn} avisos · {fail} falhas · {skipped} ignorados.`,doctorSecretLimit:`Este modo não consegue verificar os valores dos Secrets.`,botRenewal:`O PAT do bot permanece no Secret do GitHub Actions escolhido para execuções futuras. A data de validade real não é verificada aqui; registe-a no GitHub e substitua o Secret antes de expirar.`,working:`A preparar o próximo passo`,workingBody:`O processo local está a verificar as respostas. Mantenha esta página aberta.`,repoFocus:`Repositório em foco`,repoFocusBody:`Todas as decisões desta sessão afetam apenas:`,access:`acesso`,readOnlyCheck:`Verificação de acesso só de leitura`,provisionalGrants:`Permissões provisórias mínimas`,conditionalGrants:`As permissões condicionais dependem das escolhas e do GitHub. Haverá uma auditoria final antes das alterações.`,permissionUnknown:`Esta permissão exige revisão. Consulte a permissão exata e a explicação técnica no terminal antes de continuar.`,permissionsFollow:`As permissões seguem as suas escolhas`,permissionsFollowBody:`Mostramos as permissões exatas antes de criar cada PAT. Abrir esta página não cria nada.`,files:`Ficheiros`,workflows:`Workflows`,variables:`Variables`,secretNames:`Nomes dos Secrets`,planBody:`Reveja exatamente o que pode mudar. O PAT do bot e outras credenciais serão pedidos a seguir.`,planChoices:`As suas decisões principais`,planEnabledCapabilities:`Funcionalidades ativadas`,planBranchRoles:`Ramo de produção / desenvolvimento`,planApprovalMode:`Aprovação de pull requests`,planVariableScope:`Âmbito das Variables`,planSecretScope:`Âmbito dos Secrets`,planInitialTag:`Criar etiqueta inicial`,planAgentRouting:`Agente e modelo por tarefa`,planIssueWorkflows:`Fluxos de questões`,planTrustedChecks:`Produtores CI de confiança`,planCoverage:`Evidência de cobertura`,planProjectStatuses:`Transições Status dos Projects`,planIssueResources:`Etiquetas e tipos de questão`,planIssueResourcesValue:`Verificados ou criados ao aplicar`,planProducerAttested:`Identidade CI e passo obrigatório verificados por si`,planCoverageThreshold:`Cobertura mínima das linhas alteradas`,planCoverageReporter:`Workflow que publica o artefacto`,planReporterAttested:`Produtor do relatório de cobertura verificado por si`,planAdvancedDefaults:`O plano também inclui valores predefinidos para definições que não alterou. Use Alterar abaixo para rever qualquer secção antes de aprovar.`,planUnknownWarning:`Um aviso adicional do plano não pode ser apresentado aqui. Leia-o no terminal antes de aprovar.`,planBasicDefaultsIntro:`O percurso básico manteve estas definições avançadas. Abra uma secção abaixo para as rever ou alterar:`,scopeRepository:`Repositório`,scopeOrganization:`Organização`,scopeDisabled:`Sem aprovisionamento`,approvalOff:`Desativada`,approvalRecommend:`Apenas recomendações`,approvalGuarded:`Aprovação protegida`,beforeContinue:`Antes de continuar`,stopHere:`Parar aqui`,approvePlan:`Aprovar este plano`,githubLink:`Abrir ligação do GitHub ↗`,githubForm:`Abrir formulário oficial de PAT no GitHub`,githubFormHelp:`Confirme a conta ligada, escolha Only select repositories e este repositório. O GitHub gere 2FA e cria o PAT.`,pasteHere:`Cole o valor aqui`,yourAnswer:`A sua resposta`,hiddenAfter:`Oculto após envio`,typeAnswer:`Escreva a sua resposta`,secretHelp:`Enviado apenas ao processo local. Não será mostrado de novo nem guardado no navegador.`,pairTitle:`Emparelhar este navegador`,pairLabel:`Código do terminal`,pairPlaceholder:`16 caracteres hexadecimais`,pairBody:`Encontre o código de 16 caracteres no terminal onde iniciou copilot setup --web. Não aparece no URL nem fica guardado após fechar a página.`,pairHelp:`Mantenha o código privado. Após atualizar a página, introduza-o novamente.`,pairButton:`Ligar à configuração local`,privateSession:`SESSÃO LOCAL PRIVADA`,theme:`Tema`,themeAuto:`Automático`,themeSystem:`Seguir sistema`,themeLight:`Tema claro`,themeDark:`Tema escuro`,selectOne:`Selecione uma opção`,ciRun:`Abrir execução de CI no GitHub ↗`,manualCheck:`Check não listado? Indique nome|ID da App|workflow exatos, separados por ponto e vírgula.`,checksObserved:`Foram encontrados jobs recentes de CI. Abra cada execução e confirme o job, a App e o passo obrigatório de cobertura antes de confiar nele.`,checksNoRecent:`Não há execuções recentes de workflows de pull request. Execute o CI habitual numa PR real ou introduza um produtor exato.`,checksNoVerifiable:`Há execuções recentes, mas nenhum job foi ligado a um Check Run e App exatos. Consulte o GitHub ou introduza o produtor manualmente.`,checksDenied:`O GitHub recusou a consulta do CI. Conceda Actions: read e Checks: read ao PAT de configuração ou introduza um produtor exato.`,checksUnavailable:`A consulta do CI falhou. Isto não prova que o repositório não tenha checks. Tente novamente ou introduza um produtor exato.`,projectsObserved:`Estes Projects existentes pertencem ao proprietário do repositório. Selecione só os que a automatização deve atualizar.`,projectsEmpty:`Esta consulta limitada ao GitHub não devolveu Projects abertos e acessíveis; isso não prova que não existam. Verifique o acesso ou introduza um número confirmado.`,projectsDenied:`O GitHub recusou a consulta de Projects. Verifique Projects: read da organização no PAT ou introduza os números.`,projectsUnavailable:`Não foi possível consultar Projects. Isto não prova que não existam. Introduza um número verificado ou tente novamente.`,projectsUnsupported:`Esta API do GitHub não lista Projects pessoais com um PAT de permissões precisas. Introduza o número do URL de um Project existente.`,discoveryTruncated:`Só foi inspecionada uma amostra limitada de Projects acessíveis ou checks recentes. Introduza manualmente um elemento em falta.`,checksDiscoveryScope:`Âmbito: até 20 execuções recentes de workflows de PR; são inspecionadas no máximo 15 execuções e 100 checks por commit.`,projectsDiscoveryScope:`Âmbito: no máximo 30 Projects abertos e acessíveis da organização em duas páginas; são inspecionados até 100 campos por Project. Os Projects fechados são excluídos.`,retryDiscovery:`Repetir pesquisa no GitHub`,retryRemaining:`Restam {count} tentativas só de leitura. As suas respostas são mantidas.`,retryExhausted:`Não restam tentativas. Verifique o GitHub e introduza manualmente os itens em falta.`,observationTimeUnknown:`data de observação indisponível`,branchRequirementUnknown:`Exigido pela regra do ramo: não verificado`,branchRequirementObserved:`Exigido em {branch} por um ruleset ativo para esta verificação e esta App específicas.`,ciRule:`Abrir ruleset da verificação obrigatória ↗`,projectSharedStatus:`Todos os Projects escolhidos devem partilhar cada valor Status. Esta configuração não atribui valores diferentes por Project.`,fixedWorkflowEnabled:`A sua configuração fixa features.{kind}=true. Mantenha {kind} selecionado; altere --config ou as opções para mudar esta escolha.`,fixedWorkflowDisabled:`A sua configuração fixa features.{kind}=false. Não selecione {kind}; altere --config ou as opções para mudar esta escolha.`,fixedIssuesRequired:`A sua configuração ativa explicitamente release ou hotfix. Mantenha Issues ativo ou altere primeiro --config ou as opções.`,projectSelectionNotObserved:`Os números de Projects escolhidos anteriormente são mantidos, mas já não aparecem neste resultado do GitHub. Confirme-os no GitHub ou remova-os.`,removeSelection:`Remover seleção`,projectTransitionIssueCreated:`Nova questão`,projectTransitionPullRequestCreated:`Novo pull request`,projectTransitionIssueInProgress:`Questão em curso`,projectTransitionPullRequestInProgress:`Pull request em curso`,projectUrl:`Abrir Project no GitHub ↗`,projectManual:`Project em falta? Introduza o número positivo ou o URL exato do GitHub. IDs PVT_ não são aceites.`,projectStatusUnavailable:`Não foi possível verificar as opções Status de todos os Projects. Consulte cada um no GitHub e introduza o valor exato.`,projectStatusIncompatible:`Os Projects escolhidos não partilham valores Status. Selecione Projects compatíveis antes de continuar.`,producerName:`Nome do check/job`,producerAppId:`ID da App GitHub de origem`,producerWorkflow:`Nome do workflow`,producerAdd:`Adicionar check exato`,producerRemove:`Remover check`,producerManualHelp:`Use a identidade exata apresentada no GitHub. Adicioná-la não prova que exige cobertura.`,producerManualInvalid:`Indique nome, ID numérico positivo da App e workflow. Não use | ou ; nos nomes.`,translationPreviewTitle:`Revisão da tradução em curso`,translationPreviewBody:`As perguntas próprias da configuração já estão traduzidas. Alguns diagnósticos dinâmicos do GitHub ou do fornecedor ainda podem aparecer em inglês durante a revisão. Mudar de idioma não altera as suas respostas.`,unknownLocalError:`Ocorreu um erro inesperado na configuração local. Consulte o terminal e atualize a página ou reinicie a configuração.`},Ui=[`en`,`es`,`fr`,`pt`],Wi={en:`English`,es:`Español`,fr:`Français`,pt:`Português`},Gi={en:zi,es:Bi,fr:Vi,pt:Hi};function Q(e,t,n={}){return(Gi[t]??Gi.en)[e].replace(/\{(\w+)\}/gu,(e,t)=>n[t]??``)}var Ki={Repository:`repository`,"Setup choices":`choices`,"Setup PAT":`setupPat`,Plan:`plan`,"Bot PAT & credentials":`botPat`,Apply:`apply`,Preparation:`gettingReady`};function qi(e,t){return Q(Ki[e??``]??`gettingReady`,t)}var $=Mi(`en`),Ji=W(`
  • `),Yi=W(``);function Xi(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`journey`,8),o=[`repository`,`choices`,`setupPat`,`plan`,`botPat`,`apply`];Y();var s=Yi(),c=P(s),l=L(P(c)),u=I(L(P(l)),!0);E(l),E(c);var d=L(c,2),f=I(d,!0),p=L(d,2);Qr(p,5,()=>o,Jr,(e,t,r)=>{var i=Ji();let o;var s=P(i),c=I(s,!0),l=I(L(s,2),!0);E(i),R((e,t)=>{J(i,`aria-current`,(U(a()),H(()=>a()?.position===r+1?`step`:void 0))),o=ui(i,1,``,null,o,{current:a()?.position===r+1,completed:(a()?.position??0)>r+1}),K(c,e),K(l,t)},[()=>(U(a()),H(()=>(a()?.position??0)>r+1?`✓`:String(r+1).padStart(2,`0`))),()=>(U(Q),V(t),n(),H(()=>Q(V(t),n())))]),G(e,i)}),E(p);var m=L(p,2),h=L(P(m)),g=P(h),_=I(g,!0),v=I(L(g),!0);E(h),E(m),E(s),R((e,t,n,r,i)=>{J(s,`aria-label`,e),K(u,t),K(f,n),K(_,r),K(v,i)},[()=>(U(Q),n(),H(()=>Q(`progress`,n()))),()=>(U(Q),n(),H(()=>Q(`studio`,n()))),()=>(U(Q),n(),H(()=>Q(`journey`,n()))),()=>(U(Q),n(),H(()=>Q(`localDesign`,n()))),()=>(U(Q),n(),H(()=>Q(`localDesignBody`,n())))]),G(e,s),k(),i()}var Zi=W(`
    `);function Qi(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(`system`);Tn(()=>V(a),()=>{document.documentElement.dataset.theme=V(a)}),En(),Y();var o=Zi(),s=P(o);let c;var l=I(s,!0),u=L(s,2);let d;var f=L(u,2);let p;E(o),R((e,t,n,r,i,m,h,g)=>{J(o,`aria-label`,e),J(s,`aria-pressed`,V(a)===`system`),J(s,`aria-label`,t),J(s,`title`,n),c=ui(s,1,``,null,c,{active:V(a)===`system`}),K(l,r),J(u,`aria-pressed`,V(a)===`light`),J(u,`aria-label`,i),J(u,`title`,m),d=ui(u,1,``,null,d,{active:V(a)===`light`}),J(f,`aria-pressed`,V(a)===`dark`),J(f,`aria-label`,h),J(f,`title`,g),p=ui(f,1,``,null,p,{active:V(a)===`dark`})},[()=>(U(Q),n(),H(()=>Q(`theme`,n()))),()=>(U(Q),n(),H(()=>Q(`themeSystem`,n()))),()=>(U(Q),n(),H(()=>Q(`themeSystem`,n()))),()=>(U(Q),n(),H(()=>Q(`themeAuto`,n()))),()=>(U(Q),n(),H(()=>Q(`themeLight`,n()))),()=>(U(Q),n(),H(()=>Q(`themeLight`,n()))),()=>(U(Q),n(),H(()=>Q(`themeDark`,n()))),()=>(U(Q),n(),H(()=>Q(`themeDark`,n())))]),Sr(`click`,s,()=>N(a,`system`)),Sr(`click`,u,()=>N(a,`light`)),Sr(`click`,f,()=>N(a,`dark`)),G(e,o),k(),i()}Cr([`click`]);var $i=W(``),ea=W(` `,1);function ta(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii();function a(e){let t=e.currentTarget.value;Ui.includes(t)&&$.set(t)}Y();var o=ea(),s=F(o),c=P(s),l=L(c);Qr(l,5,()=>Ui,Jr,(e,t)=>{var n=$i(),r=I(n,!0),i={};R(()=>{K(r,Wi[V(t)]),i!==(i=V(t))&&(n.value=(n.__value=i)??``)}),G(e,n)}),E(l);var u;mi(l),E(s);var d=I(L(s,2),!0);R((e,t)=>{K(c,`${e??``} `),J(l,`aria-label`,t),u!==(u=n())&&(l.value=(l.__value=u)??``,pi(l,u)),K(d,Wi[n()])},[()=>Q(`language`,n()),()=>Q(`language`,n())]),Sr(`change`,l,a),G(e,o),k(),i()}Cr([`change`]);var na=W(`
    `);function ra(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`repository`,8);Y();var o=na(),s=P(o),c=P(s),l=I(c,!0),u=L(c,2),d=I(P(u),!0);E(u),E(s);var f=L(s,2),p=P(f),m=L(P(p));E(p);var h=L(p);ta(h,{}),Qi(L(h),{}),E(f),E(o),R((e,t,n)=>{K(l,e),K(d,t),K(m,` ${n??``}`)},[()=>(U(Q),n(),H(()=>Q(`setup`,n()))),()=>(U(a()),U(Q),n(),H(()=>a()??Q(`connecting`,n()))),()=>(U(Q),n(),H(()=>Q(`localSession`,n())))]),G(e,o),k(),i()}var ia={"repository.confirm":{title:`Confirm this repository`,description:`This checkout points to {repository} on branch {branch}. Confirm the target before configuring PAT access or files.`,choices:[`Yes, this is my repository`,`Stop and choose another checkout`]},"setup.depth":{title:`Choose how much detail to review`,description:`Basic still asks about permissions, security, branch roles, Projects, approval and storage. Selected advanced agent, branch-prefix and Bugbot settings keep their defaults; inspect and edit them in the final plan. Custom asks every applicable question. Neither path applies changes now.`,choices:[`Basic guided setup (recommended)`,`Customize every setting`]},"setup.environmentPat":{title:`An environment setup PAT is available`,description:`Its value stays in the CLI process and is never sent to this page. Exiting Copilot cannot unset your parent shell variable.`,choices:[`Use the environment PAT`,`Create or enter a different PAT`]},"plan.review":{title:`Review your setup plan`,description:`Inspect the affected files, workflows, Variables and Secret names before approving. No setup changes start by opening this plan.`},"workflow.update":{title:`Update existing workflows?`,description:`These existing workflow files differ from the setup plan: {files}. Keeping them may leave some new settings inactive.`,choices:[`Keep existing`,`Update setup-managed workflows`]},"setupPat.method":{title:`How will you provide your setup PAT?`,description:`This temporary PAT authorizes this one setup run. GitHub creates it under your operator account; Copilot cannot revoke it for you.`,choices:[`Guided GitHub link`,`Manual PAT`]},"setupPat.ownerKind":{title:`Who owns this repository on GitHub?`,description:`The owner determines which organization permissions may be needed. Check the repository header on GitHub if unsure.`,choices:[`Organization`,`Personal account`,`Not sure`]},"setupPat.review":{title:`Review provisional setup PAT permissions`,description:`These grants follow your choices so far. GitHub inspection may add a requirement; you will review any change before setup starts.`,choices:[`Continue to GitHub`,`Review setup choices again`,`View full permission table`,`Enter a PAT manually`]},"setupPat.entry":{title:`Temporary setup PAT`,description:`Open GitHub as your operator account, complete 2FA, choose “Only select repositories”, select this repository and copy the generated PAT here. This PAT is for this run only; delete it on GitHub afterwards.`},"setupPat.confirmAccount":{title:`GitHub authenticated the setup PAT as @{account}`,description:`Is this the operator account that should configure this repository? A wrong account must stop before any setup change.`,choices:[`Yes, continue`,`No, stop`]},"setupPat.confirmWrites":{title:`Confirm write permissions that GitHub cannot safely test`,description:`Some required write grants cannot be proven without a mutation. Check them in GitHub against the displayed permission table before confirming.`,choices:[`No, stop`,`Yes, I checked them`]},"botPat.method":{title:`How will you provide the bot PAT?`,description:`The bot PAT is separate from the setup PAT. It belongs to the account that will run future GitHub Actions and is stored as a Secret after approval.`,choices:[`Guided GitHub link`,`Manual PAT`]},"botPat.login":{title:`Expected GitHub bot login`,description:`Enter the bot account login without @. Copilot resolves its numeric GitHub ID and compares it with the PAT owner.`},"botPat.entry.guided":{title:`{name} — bot account PAT`,description:`Open GitHub as @{account} (account ID {accountId}), not as the setup operator. Select only this repository, review all grants and paste the PAT here. Suggested expiry: 90 days. An existing Secret value cannot be read back.`},"botPat.entry.manual":{title:`{name} — bot account PAT`,description:`Use the bot account, select only the intended repository and review all grants before pasting its PAT. Suggested expiry: 90 days. An existing Secret value cannot be read back.`},"credential.apiKey":{title:`{name} — {provider} API key`,description:`Paste the API key for {provider}. It is sent only to this local setup process and, if approved, installed as a GitHub Actions Secret. Existing Secret values cannot be read back.`},"credential.existing":{title:`Existing {name}: {status}`,description:`GitHub cannot reveal the current Secret value. Keep it only if you deliberately accept that its health cannot be verified here; replace or skip it otherwise.`,choices:[`Keep existing`,`Replace it`,`Skip this credential`]},"apply.confirm":{title:`Apply this setup now?`,description:`This is the final approval. Local files and selected GitHub resources may change. A partial result may require inspection before retrying.`,choices:[`Apply setup`,`Stop without applying`]}},aa={"repository.confirm":{title:`Confirma el repositorio`,description:`Este checkout apunta a {repository} en la rama {branch}. Comprueba el destino antes de configurar permisos del PAT o archivos.`,choices:[`Sí, es mi repositorio`,`Detener y elegir otro checkout`]},"setup.depth":{title:`Elige cuánto detalle quieres revisar`,description:`El modo básico sigue preguntando por permisos, seguridad, ramas, Projects, aprobación y almacenamiento. Algunos ajustes avanzados de agentes, prefijos de rama y Bugbot conservan sus valores predeterminados; podrás revisarlos y editarlos en el plan final. El modo personalizado pregunta por todos los ajustes aplicables. Ninguno aplica cambios todavía.`,choices:[`Configuración básica guiada (recomendada)`,`Personalizar todos los ajustes`]},"setup.environmentPat":{title:`Hay un PAT de configuración en el entorno`,description:`Su valor permanece en el proceso CLI y no se envía a esta página. Cerrar Copilot no elimina la variable de la terminal original.`,choices:[`Usar el PAT del entorno`,`Crear o introducir otro PAT`]},"plan.review":{title:`Revisa el plan de configuración`,description:`Comprueba los archivos, workflows, Variables y nombres de Secrets antes de aprobar. Abrir el plan no inicia ningún cambio.`},"workflow.update":{title:`¿Actualizar los workflows existentes?`,description:`Estos archivos difieren del plan: {files}. Si los conservas, algunos ajustes nuevos podrían no activarse.`,choices:[`Conservar los existentes`,`Actualizar los workflows gestionados`]},"setupPat.method":{title:`¿Cómo proporcionarás el PAT de configuración?`,description:`Este PAT temporal autoriza una sola ejecución. GitHub lo crea con tu cuenta de operador; Copilot no puede revocarlo por ti.`,choices:[`Enlace guiado de GitHub`,`Introducir PAT manualmente`]},"setupPat.ownerKind":{title:`¿Quién es propietario de este repositorio en GitHub?`,description:`El propietario determina qué permisos de organización pueden hacer falta. Consulta la cabecera del repositorio en GitHub si dudas.`,choices:[`Organización`,`Cuenta personal`,`No lo sé`]},"setupPat.review":{title:`Revisa los permisos provisionales del PAT de configuración`,description:`Estos permisos dependen de las opciones elegidas. Al inspeccionar GitHub podría aparecer otro requisito; lo revisarás antes de aplicar cambios.`,choices:[`Continuar en GitHub`,`Revisar de nuevo las opciones`,`Ver la tabla completa de permisos`,`Introducir un PAT manualmente`]},"setupPat.entry":{title:`PAT temporal de configuración`,description:`Abre GitHub con tu cuenta de operador, completa el 2FA, elige «Only select repositories», selecciona este repositorio y pega aquí el PAT generado. Es solo para esta ejecución; elimínalo en GitHub después.`},"setupPat.confirmAccount":{title:`GitHub autenticó el PAT de configuración como @{account}`,description:`¿Es la cuenta de operador que debe configurar este repositorio? Una cuenta incorrecta debe detener el proceso antes de cualquier cambio.`,choices:[`Sí, continuar`,`No, detener`]},"setupPat.confirmWrites":{title:`Confirma permisos de escritura que GitHub no puede probar sin cambios`,description:`Algunos permisos de escritura no pueden verificarse sin modificar recursos. Compruébalos en GitHub frente a la tabla mostrada antes de confirmar.`,choices:[`No, detener`,`Sí, los he comprobado`]},"botPat.method":{title:`¿Cómo proporcionarás el PAT del bot?`,description:`Es distinto del PAT de configuración. Pertenece a la cuenta que ejecutará las futuras GitHub Actions y se instalará como Secret tras la aprobación.`,choices:[`Enlace guiado de GitHub`,`Introducir PAT manualmente`]},"botPat.login":{title:`Usuario previsto del bot en GitHub`,description:`Introduce el nombre de usuario del bot sin @. Copilot consultará su ID numérico de GitHub y lo comparará con el propietario del PAT.`},"botPat.entry.guided":{title:`{name} — PAT de la cuenta bot`,description:`Abre GitHub como @{account} (ID {accountId}), no como operador de setup. Selecciona solo este repositorio, revisa todos los permisos y pega aquí el PAT. Caducidad sugerida: 90 días. El valor de un Secret existente no puede leerse.`},"botPat.entry.manual":{title:`{name} — PAT de la cuenta bot`,description:`Usa la cuenta bot, selecciona solo el repositorio previsto y revisa todos los permisos antes de pegar el PAT. Caducidad sugerida: 90 días. El valor de un Secret existente no puede leerse.`},"credential.apiKey":{title:`{name} — clave API de {provider}`,description:`Pega la clave API de {provider}. Solo se envía a este proceso local y, si apruebas el plan, se instala como Secret de GitHub Actions. Los valores existentes no pueden leerse.`},"credential.existing":{title:`{name} existente: {status}`,description:`GitHub no muestra el valor actual del Secret. Consérvalo solo si aceptas expresamente que aquí no se puede comprobar su estado; de lo contrario, sustitúyelo u omítelo.`,choices:[`Conservar`,`Sustituir`,`Omitir esta credencial`]},"apply.confirm":{title:`¿Aplicar la configuración ahora?`,description:`Esta es la aprobación final. Pueden cambiar archivos locales y recursos de GitHub seleccionados. Si el resultado es parcial, revísalo antes de reintentar.`,choices:[`Aplicar configuración`,`Detener sin aplicar`]}},oa={"repository.confirm":{title:`Confirmez ce dépôt`,description:`Ce dossier pointe vers {repository}, branche {branch}. Vérifiez la cible avant de configurer les accès PAT ou les fichiers.`,choices:[`Oui, c’est mon dépôt`,`Arrêter et choisir un autre dossier`]},"setup.depth":{title:`Choisissez le niveau de détail`,description:`Le parcours de base demande toujours les autorisations, la sécurité, les branches, Projects, l’approbation et le stockage. Certains réglages avancés des agents, préfixes de branche et Bugbot conservent leurs valeurs par défaut ; vous pourrez les examiner et les modifier dans le plan final. Le parcours personnalisé pose toutes les questions applicables. Aucun changement n’est appliqué à ce stade.`,choices:[`Configuration de base guidée (recommandée)`,`Personnaliser tous les réglages`]},"setup.environmentPat":{title:`Un PAT de configuration est disponible dans l’environnement`,description:`Sa valeur reste dans le processus CLI et n’est jamais envoyée à cette page. Quitter Copilot ne supprime pas la variable du shell parent.`,choices:[`Utiliser le PAT de l’environnement`,`Créer ou saisir un autre PAT`]},"plan.review":{title:`Examinez le plan de configuration`,description:`Vérifiez les fichiers, workflows, Variables et noms de Secrets avant d’approuver. Ouvrir le plan ne lance aucun changement.`},"workflow.update":{title:`Mettre à jour les workflows existants ?`,description:`Ces fichiers diffèrent du plan : {files}. Les conserver peut laisser certains nouveaux réglages inactifs.`,choices:[`Conserver les fichiers existants`,`Mettre à jour les workflows gérés`]},"setupPat.method":{title:`Comment fournirez-vous le PAT de configuration ?`,description:`Ce PAT temporaire autorise une seule exécution. GitHub le crée avec votre compte opérateur ; Copilot ne peut pas le révoquer à votre place.`,choices:[`Lien GitHub guidé`,`Saisir un PAT manuellement`]},"setupPat.ownerKind":{title:`À qui appartient ce dépôt sur GitHub ?`,description:`Le propriétaire détermine les éventuelles autorisations d’organisation. Consultez l’en-tête du dépôt sur GitHub en cas de doute.`,choices:[`Organisation`,`Compte personnel`,`Je ne sais pas`]},"setupPat.review":{title:`Examinez les autorisations provisoires du PAT de configuration`,description:`Ces autorisations suivent vos choix. L’inspection de GitHub peut révéler un besoin supplémentaire ; vous le reverrez avant tout changement.`,choices:[`Continuer sur GitHub`,`Revoir les choix de configuration`,`Voir toutes les autorisations`,`Saisir un PAT manuellement`]},"setupPat.entry":{title:`PAT temporaire de configuration`,description:`Ouvrez GitHub avec votre compte opérateur, effectuez la 2FA, choisissez « Only select repositories », sélectionnez ce dépôt puis collez ici le PAT généré. Il ne sert qu’à cette exécution ; supprimez-le sur GitHub ensuite.`},"setupPat.confirmAccount":{title:`GitHub a authentifié le PAT de configuration comme @{account}`,description:`Est-ce bien le compte opérateur autorisé à configurer ce dépôt ? Un autre compte doit arrêter le processus avant tout changement.`,choices:[`Oui, continuer`,`Non, arrêter`]},"setupPat.confirmWrites":{title:`Confirmez les droits d’écriture que GitHub ne peut pas vérifier sans changement`,description:`Certains droits d’écriture ne peuvent être prouvés sans modifier des ressources. Comparez-les au tableau affiché sur GitHub avant de confirmer.`,choices:[`Non, arrêter`,`Oui, je les ai vérifiés`]},"botPat.method":{title:`Comment fournirez-vous le PAT du bot ?`,description:`Il est distinct du PAT de configuration. Il appartient au compte qui exécutera les futures GitHub Actions et sera installé comme Secret après approbation.`,choices:[`Lien GitHub guidé`,`Saisir un PAT manuellement`]},"botPat.login":{title:`Identifiant GitHub attendu pour le bot`,description:`Saisissez l’identifiant du bot sans @. Copilot récupère son ID numérique GitHub et le compare au propriétaire du PAT.`},"botPat.entry.guided":{title:`{name} — PAT du compte bot`,description:`Ouvrez GitHub en tant que @{account} (ID {accountId}), pas en tant qu’opérateur. Sélectionnez uniquement ce dépôt, vérifiez tous les droits et collez le PAT ici. Expiration suggérée : 90 jours. La valeur d’un Secret existant ne peut pas être relue.`},"botPat.entry.manual":{title:`{name} — PAT du compte bot`,description:`Utilisez le compte bot, sélectionnez uniquement le dépôt voulu et vérifiez tous les droits avant de coller le PAT. Expiration suggérée : 90 jours. La valeur d’un Secret existant ne peut pas être relue.`},"credential.apiKey":{title:`{name} — clé API de {provider}`,description:`Collez la clé API de {provider}. Elle est envoyée uniquement au processus local puis, si vous approuvez le plan, installée comme Secret GitHub Actions. Les valeurs existantes ne peuvent pas être relues.`},"credential.existing":{title:`{name} existant : {status}`,description:`GitHub ne révèle pas la valeur actuelle du Secret. Ne la conservez que si vous acceptez explicitement de ne pas pouvoir vérifier son état ici ; sinon, remplacez-la ou ignorez-la.`,choices:[`Conserver`,`Remplacer`,`Ignorer cet identifiant`]},"apply.confirm":{title:`Appliquer la configuration maintenant ?`,description:`C’est l’approbation finale. Des fichiers locaux et ressources GitHub choisis peuvent changer. Un résultat partiel doit être inspecté avant une nouvelle tentative.`,choices:[`Appliquer la configuration`,`Arrêter sans appliquer`]}},sa={"repository.confirm":{title:`Confirme este repositório`,description:`Esta pasta aponta para {repository}, no ramo {branch}. Confirme o destino antes de configurar acessos PAT ou ficheiros.`,choices:[`Sim, é o meu repositório`,`Parar e escolher outra pasta`]},"setup.depth":{title:`Escolha o nível de detalhe`,description:`O percurso básico continua a perguntar sobre permissões, segurança, ramos, Projects, aprovação e armazenamento. Algumas definições avançadas de agentes, prefixos de ramos e Bugbot mantêm os valores predefinidos; poderá revê-las e editá-las no plano final. O percurso personalizado pergunta por todas as definições aplicáveis. Nenhum dos percursos aplica alterações nesta fase.`,choices:[`Configuração básica guiada (recomendada)`,`Personalizar todas as definições`]},"setup.environmentPat":{title:`Existe um PAT de configuração no ambiente`,description:`O valor permanece no processo CLI e nunca é enviado para esta página. Sair do Copilot não remove a variável da shell original.`,choices:[`Usar o PAT do ambiente`,`Criar ou introduzir outro PAT`]},"plan.review":{title:`Reveja o plano de configuração`,description:`Confirme ficheiros, fluxos, Variables e nomes de Secrets antes de aprovar. Abrir o plano não inicia alterações.`,choices:void 0},"workflow.update":{title:`Atualizar os fluxos existentes?`,description:`Estes ficheiros diferem do plano: {files}. Conservá-los pode deixar algumas definições novas inativas.`,choices:[`Conservar os existentes`,`Atualizar os fluxos geridos`]},"setupPat.method":{title:`Como irá fornecer o PAT de configuração?`,description:`Este PAT temporário autoriza uma única execução. O GitHub cria-o na sua conta de operador; o Copilot não pode revogá-lo por si.`,choices:[`Ligação guiada do GitHub`,`Introduzir PAT manualmente`]},"setupPat.ownerKind":{title:`Quem é o proprietário deste repositório no GitHub?`,description:`O proprietário determina as permissões de organização necessárias. Consulte o cabeçalho do repositório no GitHub se tiver dúvidas.`,choices:[`Organização`,`Conta pessoal`,`Não tenho a certeza`]},"setupPat.review":{title:`Reveja as permissões provisórias do PAT de configuração`,description:`Estas permissões seguem as suas escolhas. A inspeção do GitHub pode revelar outro requisito; irá revê-lo antes de qualquer alteração.`,choices:[`Continuar no GitHub`,`Rever as escolhas`,`Ver a tabela completa de permissões`,`Introduzir um PAT manualmente`]},"setupPat.entry":{title:`PAT temporário de configuração`,description:`Abra o GitHub com a sua conta de operador, conclua a 2FA, escolha «Only select repositories», selecione este repositório e cole aqui o PAT gerado. É apenas para esta execução; elimine-o no GitHub depois.`},"setupPat.confirmAccount":{title:`O GitHub autenticou o PAT de configuração como @{account}`,description:`É esta a conta de operador que deve configurar o repositório? Uma conta errada tem de parar o processo antes de qualquer alteração.`,choices:[`Sim, continuar`,`Não, parar`]},"setupPat.confirmWrites":{title:`Confirme permissões de escrita que o GitHub não pode testar sem alterações`,description:`Algumas permissões de escrita não podem ser provadas sem alterar recursos. Compare-as com a tabela no GitHub antes de confirmar.`,choices:[`Não, parar`,`Sim, já as verifiquei`]},"botPat.method":{title:`Como irá fornecer o PAT do bot?`,description:`É diferente do PAT de configuração. Pertence à conta que executará as futuras GitHub Actions e será instalado como Secret após aprovação.`,choices:[`Ligação guiada do GitHub`,`Introduzir PAT manualmente`]},"botPat.login":{title:`Utilizador GitHub esperado para o bot`,description:`Introduza o nome de utilizador do bot sem @. O Copilot consulta o ID numérico do GitHub e compara-o com o proprietário do PAT.`},"botPat.entry.guided":{title:`{name} — PAT da conta bot`,description:`Abra o GitHub como @{account} (ID {accountId}), não como operador. Selecione apenas este repositório, reveja todas as permissões e cole aqui o PAT. Validade sugerida: 90 dias. Não é possível voltar a ler o valor de um Secret existente.`},"botPat.entry.manual":{title:`{name} — PAT da conta bot`,description:`Use a conta bot, selecione apenas o repositório pretendido e reveja todas as permissões antes de colar o PAT. Validade sugerida: 90 dias. Não é possível voltar a ler o valor de um Secret existente.`},"credential.apiKey":{title:`{name} — chave API de {provider}`,description:`Cole a chave API de {provider}. Só é enviada para este processo local e, se aprovar o plano, instalada como Secret do GitHub Actions. Os valores existentes não podem voltar a ser lidos.`},"credential.existing":{title:`{name} existente: {status}`,description:`O GitHub não revela o valor atual do Secret. Conserve-o apenas se aceitar expressamente que aqui não se pode verificar o seu estado; caso contrário, substitua-o ou ignore-o.`,choices:[`Conservar`,`Substituir`,`Ignorar esta credencial`]},"apply.confirm":{title:`Aplicar a configuração agora?`,description:`Esta é a aprovação final. Ficheiros locais e recursos GitHub selecionados podem mudar. Um resultado parcial exige inspeção antes de tentar novamente.`,choices:[`Aplicar configuração`,`Parar sem aplicar`]}},ca={"session.controlMoved":`Control moved to this tab. The previous tab is now read-only.`,"session.cancelled":`Setup stopped before applying further changes. Any PAT created on GitHub still exists until you delete it there.`,"plan.ready":`Plan ready: {files} files, {variables} Variables and {secrets} Secret names. Review it before continuing.`,"permission.preview":`Permission preview: issue workflows {issues}; PR approval {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Review the exact grants before creating the setup PAT.`,"setupPat.corrected.bootstrap":`The setup PAT could not access the repository. No setup changes started. Required grants: {grants}. Create a corrected PAT using the updated GitHub link.`,"setupPat.corrected.final":`Required setup PAT permissions changed after inspection. No setup changes started. New grants: {grants}. Create a corrected PAT using the updated GitHub link.`,"setupPat.cleanup":`Delete the temporary setup PAT in GitHub Settings after this run. Closing Copilot does not revoke it.`,"botPat.separation":`The bot PAT is separate from your setup PAT. These credentials become GitHub Actions Secrets: {names}. Existing Secret values cannot be read back. Re-enter an existing bot PAT so its grants can be checked. No credential-health workflow runs before Apply.`,"credential.checks":`Credential checks finished for {count} items. Each result is shown below. The terminal has technical details; an existing Secret value cannot be read back.`,"credential.status.valid":`Valid`,"credential.status.invalid":`Invalid`,"credential.status.missing":`Missing`,"credential.status.unverifiable":`Cannot be verified without a new value`,"credential.status.not_required":`Not required`,"validation.producers":`Select 1–8 observed checks or enter exact name|App ID|workflow tuples.`,"validation.duplicateNames":`Two trusted producers use the same check name. Coverage stores only the name: choose one producer or rename the CI jobs.`,"validation.projectStatusVerified":`Open every selected Project in GitHub and confirm that all four exact Status values exist. Answer Yes after checking, or No to choose Projects again.`,"validation.projectStatusRedo":`Status values were not confirmed. Choose compatible Projects, then review their Status options again.`,"validation.number":`Enter a non-negative whole number.`,"validation.boolean":`Enter yes or no.`,"validation.choice":`Select one of the listed options.`,"validation.unknownResource":`Unknown inherited resource names: {names}. Choose only names shown in the inherited list.`,"validation.unknownWorkflow":`Unknown issue workflows: {names}. Choose only the listed workflow types.`,"validation.firstQuestion":`This is the first question in this pass. Review it or cancel setup.`,"validation.duplicateProducer":`This trusted check was selected twice. Remove the duplicate selection.`,"validation.savedStatus":`The saved Status value is not available in every selected Project. Choose a listed option.`,"validation.projectIncompatible":`The selected Projects have no common Status option. Choose compatible Projects or configure them separately.`,"validation.projectLimit":`Choose at most 10 Projects; separate their numbers or URLs with commas.`,"validation.projectOwnerNeeded":`A Project URL needs a known repository owner; enter its positive number instead.`,"validation.projectOwnerMismatch":`Use a GitHub Project URL belonging to {owner}, without query parameters.`,"validation.projectUrl":`Enter a valid GitHub Project URL or positive Project number.`,"validation.projectNumber":`Enter the positive Project number from its GitHub URL, not a PVT_ GraphQL ID.`,"validation.projectNumberRange":`Project numbers must be positive integers at most 2147483647.`,"validation.projectDuplicate":`Project {number} was selected more than once.`,"validation.fixedIssues":`Your configuration explicitly enables release or hotfix automation. Keep Issues enabled or edit that configuration first.`,"validation.fixedWorkflowEnabled":`Your configuration enables {kind}. Keep that workflow selected or edit the configuration first.`,"validation.fixedWorkflowDisabled":`Your configuration disables {kind}. Deselect that workflow or edit the configuration first.`,"validation.unknown":`This answer could not be accepted. Review the question and its help; the terminal has the technical detail.`},la={"session.controlMoved":`El control ha pasado a esta pestaña. La anterior ahora es de solo lectura.`,"session.cancelled":`La configuración se detuvo antes de aplicar más cambios. Los PAT creados en GitHub siguen existiendo hasta que los elimines allí.`,"plan.ready":`Plan listo: {files} archivos, {variables} Variables y {secrets} nombres de Secrets. Revísalo antes de continuar.`,"permission.preview":`Vista previa de permisos: flujos de incidencias {issues}; aprobación de PR {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Revisa los permisos exactos antes de crear el PAT de configuración.`,"setupPat.corrected.bootstrap":`El PAT de configuración no pudo acceder al repositorio. No se iniciaron cambios. Permisos necesarios: {grants}. Crea un PAT corregido desde el enlace actualizado de GitHub.`,"setupPat.corrected.final":`Los permisos necesarios del PAT cambiaron tras la inspección. No se iniciaron cambios. Permisos nuevos: {grants}. Crea un PAT corregido desde el enlace actualizado.`,"setupPat.cleanup":`Elimina el PAT temporal de configuración en los ajustes de GitHub después de esta ejecución. Cerrar Copilot no lo revoca.`,"botPat.separation":`El PAT del bot es distinto del de configuración. Estas credenciales se instalarán como Secrets de GitHub Actions: {names}. Los valores existentes no pueden leerse. Vuelve a introducir un PAT del bot para comprobar sus permisos. Antes de Aplicar no se ejecuta ningún workflow de comprobación.`,"credential.checks":`Se han comprobado {count} credenciales. Abajo aparece el resultado de cada una. La terminal contiene los detalles técnicos; el valor de un Secret existente no puede leerse.`,"credential.status.valid":`Válida`,"credential.status.invalid":`No válida`,"credential.status.missing":`Falta`,"credential.status.unverifiable":`No verificable sin un valor nuevo`,"credential.status.not_required":`No necesaria`,"validation.producers":`Selecciona entre 1 y 8 checks observados o introduce las tuplas exactas nombre|ID de App|workflow.`,"validation.duplicateNames":`Dos productores fiables tienen el mismo nombre de check. La cobertura solo guarda el nombre: elige uno o cambia el nombre de los jobs de CI.`,"validation.projectStatusVerified":`Abre cada Project elegido en GitHub y confirma los cuatro valores Status exactos. Responde Sí tras comprobarlo, o No para elegir Projects de nuevo.`,"validation.projectStatusRedo":`No se confirmaron los valores Status. Elige Projects compatibles y vuelve a revisar sus opciones Status.`,"validation.number":`Introduce un número entero no negativo.`,"validation.boolean":`Elige Sí o No.`,"validation.choice":`Elige una de las opciones mostradas.`,"validation.unknownResource":`Nombres de recursos heredados desconocidos: {names}. Elige solo nombres de la lista heredada.`,"validation.unknownWorkflow":`Flujos de issues desconocidos: {names}. Elige solo los tipos indicados.`,"validation.firstQuestion":`Esta es la primera pregunta de esta pasada. Revísala o cancela la configuración.`,"validation.duplicateProducer":`Has seleccionado dos veces el mismo check fiable. Quita la selección duplicada.`,"validation.savedStatus":`El valor Status guardado no existe en todos los Projects seleccionados. Elige una opción de la lista.`,"validation.projectIncompatible":`Los Projects elegidos no comparten ningún valor Status. Elige Projects compatibles o configúralos por separado.`,"validation.projectLimit":`Elige como máximo 10 Projects; separa sus números o URL con comas.`,"validation.projectOwnerNeeded":`Para usar la URL de un Project hay que conocer el propietario del repositorio; introduce su número positivo.`,"validation.projectOwnerMismatch":`Usa la URL de un Project de GitHub que pertenezca a {owner}, sin parámetros.`,"validation.projectUrl":`Introduce una URL válida de un Project de GitHub o su número positivo.`,"validation.projectNumber":`Introduce el número positivo del Project que aparece en su URL, no un ID GraphQL PVT_.`,"validation.projectNumberRange":`El número del Project debe ser un entero positivo no mayor de 2147483647.`,"validation.projectDuplicate":`Has seleccionado el Project {number} más de una vez.`,"validation.fixedIssues":`Tu configuración activa expresamente release o hotfix. Mantén Issues activado o cambia antes la configuración.`,"validation.fixedWorkflowEnabled":`Tu configuración activa {kind}. Mantén ese flujo seleccionado o cambia antes la configuración.`,"validation.fixedWorkflowDisabled":`Tu configuración desactiva {kind}. Desmarca ese flujo o cambia antes la configuración.`,"validation.unknown":`No se pudo aceptar esta respuesta. Revisa la pregunta y su ayuda; la terminal contiene el detalle técnico.`},ua={"session.controlMoved":`Le contrôle est passé à cet onglet. L’onglet précédent est maintenant en lecture seule.`,"session.cancelled":`La configuration s’est arrêtée avant de nouveaux changements. Tout PAT créé sur GitHub existe encore jusqu’à sa suppression là-bas.`,"plan.ready":`Plan prêt : {files} fichiers, {variables} Variables et {secrets} noms de Secrets. Examinez-le avant de continuer.`,"permission.preview":`Aperçu des droits : flux de tickets {issues} ; approbation des PR {approval} ; Secrets {secrets} ; Variables {variables} ; Projects {projects}. Vérifiez les droits exacts avant de créer le PAT de configuration.`,"setupPat.corrected.bootstrap":`Le PAT de configuration n’a pas pu accéder au dépôt. Aucun changement n’a commencé. Droits requis : {grants}. Créez un PAT corrigé avec le lien GitHub mis à jour.`,"setupPat.corrected.final":`Les droits requis du PAT ont changé après inspection. Aucun changement n’a commencé. Nouveaux droits : {grants}. Créez un PAT corrigé avec le lien mis à jour.`,"setupPat.cleanup":`Supprimez le PAT temporaire de configuration dans les paramètres GitHub après cette exécution. Fermer Copilot ne le révoque pas.`,"botPat.separation":`Le PAT du bot est distinct du PAT de configuration. Ces identifiants deviendront des Secrets GitHub Actions : {names}. Les valeurs existantes ne peuvent pas être relues. Saisissez à nouveau un PAT du bot pour vérifier ses droits. Aucun workflow de vérification ne démarre avant Appliquer.`,"credential.checks":`Vérification terminée pour {count} identifiants. Le résultat de chacun figure ci-dessous. Le terminal contient les détails techniques ; la valeur d’un Secret existant ne peut pas être relue.`,"credential.status.valid":`Valide`,"credential.status.invalid":`Invalide`,"credential.status.missing":`Manquant`,"credential.status.unverifiable":`Invérifiable sans nouvelle valeur`,"credential.status.not_required":`Non requis`,"validation.producers":`Choisissez 1 à 8 vérifications observées ou saisissez les triplets exacts nom|ID d’App|workflow.`,"validation.duplicateNames":`Deux producteurs fiables portent le même nom de vérification. La couverture ne stocke que ce nom : choisissez-en un ou renommez les jobs CI.`,"validation.projectStatusVerified":`Ouvrez chaque Project choisi sur GitHub et confirmez les quatre valeurs Status exactes. Répondez Oui après vérification, ou Non pour choisir à nouveau les Projects.`,"validation.projectStatusRedo":`Les valeurs Status n’ont pas été confirmées. Choisissez des Projects compatibles, puis revérifiez leurs options Status.`,"validation.number":`Saisissez un entier positif ou nul.`,"validation.boolean":`Choisissez Oui ou Non.`,"validation.choice":`Choisissez une des options affichées.`,"validation.unknownResource":`Noms de ressources héritées inconnus : {names}. Choisissez seulement les noms de la liste héritée.`,"validation.unknownWorkflow":`Workflows de ticket inconnus : {names}. Choisissez seulement les types proposés.`,"validation.firstQuestion":`C’est la première question de cette passe. Vérifiez-la ou annulez la configuration.`,"validation.duplicateProducer":`Cette vérification fiable a été choisie deux fois. Retirez le doublon.`,"validation.savedStatus":`La valeur Status enregistrée n’existe pas dans tous les Projects choisis. Sélectionnez une option proposée.`,"validation.projectIncompatible":`Les Projects choisis ne partagent aucune valeur Status. Choisissez des Projects compatibles ou configurez-les séparément.`,"validation.projectLimit":`Choisissez au plus 10 Projects ; séparez leurs numéros ou URL par des virgules.`,"validation.projectOwnerNeeded":`Une URL de Project exige de connaître le propriétaire du dépôt ; saisissez plutôt son numéro positif.`,"validation.projectOwnerMismatch":`Utilisez une URL de Project GitHub appartenant à {owner}, sans paramètres.`,"validation.projectUrl":`Saisissez une URL valide de Project GitHub ou son numéro positif.`,"validation.projectNumber":`Saisissez le numéro positif figurant dans l’URL du Project, pas un ID GraphQL PVT_.`,"validation.projectNumberRange":`Le numéro du Project doit être un entier positif inférieur ou égal à 2147483647.`,"validation.projectDuplicate":`Le Project {number} a été choisi plusieurs fois.`,"validation.fixedIssues":`Votre configuration active explicitement release ou hotfix. Gardez Issues activé ou modifiez d’abord la configuration.`,"validation.fixedWorkflowEnabled":`Votre configuration active {kind}. Gardez ce flux sélectionné ou modifiez d’abord la configuration.`,"validation.fixedWorkflowDisabled":`Votre configuration désactive {kind}. Désélectionnez ce flux ou modifiez d’abord la configuration.`,"validation.unknown":`Cette réponse n’a pas été acceptée. Vérifiez la question et son aide ; le terminal contient le détail technique.`},da={"session.controlMoved":`O controlo passou para este separador. O separador anterior é agora apenas de leitura.`,"session.cancelled":`A configuração parou antes de novas alterações. Os PAT criados no GitHub continuam a existir até os eliminar lá.`,"plan.ready":`Plano pronto: {files} ficheiros, {variables} Variables e {secrets} nomes de Secrets. Reveja-o antes de continuar.`,"permission.preview":`Pré-visualização das permissões: fluxos de issues {issues}; aprovação de PR {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Reveja as permissões exatas antes de criar o PAT de configuração.`,"setupPat.corrected.bootstrap":`O PAT de configuração não conseguiu aceder ao repositório. Não começaram alterações. Permissões necessárias: {grants}. Crie um PAT corrigido com a ligação GitHub atualizada.`,"setupPat.corrected.final":`As permissões necessárias do PAT mudaram após inspeção. Não começaram alterações. Novas permissões: {grants}. Crie um PAT corrigido com a ligação atualizada.`,"setupPat.cleanup":`Elimine o PAT temporário de configuração nas definições do GitHub após esta execução. Fechar o Copilot não o revoga.`,"botPat.separation":`O PAT do bot é distinto do PAT de configuração. Estas credenciais serão Secrets do GitHub Actions: {names}. Os valores existentes não podem voltar a ser lidos. Reintroduza um PAT do bot para verificar as permissões. Nenhum fluxo de verificação é executado antes de Aplicar.`,"credential.checks":`Verificação concluída para {count} credenciais. O resultado de cada uma aparece abaixo. O terminal contém os detalhes técnicos; o valor de um Secret existente não pode voltar a ser lido.`,"credential.status.valid":`Válida`,"credential.status.invalid":`Inválida`,"credential.status.missing":`Em falta`,"credential.status.unverifiable":`Não verificável sem um novo valor`,"credential.status.not_required":`Não necessária`,"validation.producers":`Selecione 1 a 8 verificações observadas ou introduza os triplos exatos nome|ID da App|workflow.`,"validation.duplicateNames":`Dois produtores fiáveis têm o mesmo nome de check. A cobertura guarda apenas o nome: escolha um ou altere o nome dos jobs de CI.`,"validation.projectStatusVerified":`Abra cada Project escolhido no GitHub e confirme os quatro valores Status exatos. Responda Sim após verificar, ou Não para voltar a escolher Projects.`,"validation.projectStatusRedo":`Os valores Status não foram confirmados. Escolha Projects compatíveis e volte a verificar as opções Status.`,"validation.number":`Introduza um número inteiro não negativo.`,"validation.boolean":`Escolha Sim ou Não.`,"validation.choice":`Escolha uma das opções apresentadas.`,"validation.unknownResource":`Nomes de recursos herdados desconhecidos: {names}. Escolha apenas nomes da lista herdada.`,"validation.unknownWorkflow":`Fluxos de questões desconhecidos: {names}. Escolha apenas os tipos indicados.`,"validation.firstQuestion":`Esta é a primeira pergunta desta ronda. Reveja-a ou cancele a configuração.`,"validation.duplicateProducer":`Esta verificação de confiança foi selecionada duas vezes. Remova a seleção duplicada.`,"validation.savedStatus":`O valor Status guardado não existe em todos os Projects escolhidos. Selecione uma opção da lista.`,"validation.projectIncompatible":`Os Projects escolhidos não partilham qualquer valor Status. Escolha Projects compatíveis ou configure-os separadamente.`,"validation.projectLimit":`Escolha no máximo 10 Projects; separe os números ou URL por vírgulas.`,"validation.projectOwnerNeeded":`Uma URL de Project exige que se conheça o proprietário do repositório; introduza antes o número positivo.`,"validation.projectOwnerMismatch":`Use uma URL de Project do GitHub pertencente a {owner}, sem parâmetros.`,"validation.projectUrl":`Introduza uma URL válida de Project do GitHub ou o respetivo número positivo.`,"validation.projectNumber":`Introduza o número positivo apresentado na URL do Project, não um ID GraphQL PVT_.`,"validation.projectNumberRange":`O número do Project tem de ser um inteiro positivo até 2147483647.`,"validation.projectDuplicate":`O Project {number} foi selecionado mais do que uma vez.`,"validation.fixedIssues":`A sua configuração ativa explicitamente release ou hotfix. Mantenha Issues ativo ou altere primeiro a configuração.`,"validation.fixedWorkflowEnabled":`A sua configuração ativa {kind}. Mantenha esse fluxo selecionado ou altere primeiro a configuração.`,"validation.fixedWorkflowDisabled":`A sua configuração desativa {kind}. Desmarque esse fluxo ou altere primeiro a configuração.`,"validation.unknown":`Esta resposta não foi aceite. Reveja a pergunta e a ajuda; o terminal contém o detalhe técnico.`},fa={es:{All:`Todos`,prompt:`Preguntar antes de crear el enlace`,"create-if-missing":`Crear el enlace si falta`,disabled:`Desactivado`,replace:`Sustituir`,append:`Añadir`,preserve:`Conservar`,info:`Informativa`,low:`Baja`,medium:`Media`,high:`Alta`,smart:`Adaptativa`,default:`Predeterminado`,auto:`Automático`,always:`Reinstalar siempre`,recommend:`Recomendar aprobación`,guarded:`Aprobar solo con garantías`,off:`Desactivado`,check:`Check de CI que exige la cobertura`,numeric:`Informe numérico verificable`,repository:`Repositorio`,organization:`Organización`,selected:`Repositorios seleccionados`,private:`Repositorios privados`,all:`Todos los repositorios`,"production-lineage":`Conservar el linaje de producción`,"canonical-gitflow":`Git-Flow canónico`,manual:`Manual`,"auto-merge":`Fusionar automáticamente`,"merge-queue":`Cola de integración`,"create-only":`Solo crear PR`,direct:`Integración directa`,"sync-branch":`Mediante rama de sincronización`,"prefer-release":`Priorizar la release`,development:`Desarrollo`,both:`Ambos destinos`,"source-only":`Solo rama de origen`,"sync-only":`Solo rama de sincronización`,none:`Ninguna`,close:`Cerrar el issue`,"keep-open":`Mantener abierto`,guided:`Guiado`,compact:`Compacto`,quiet:`Mínimo`,update:`Actualizar el comentario`,milestones:`Publicar en hitos`,feature:`Funcionalidad`,bugfix:`Corrección`,documentation:`Documentación`,chore:`Mantenimiento`,help:`Ayuda o pregunta`,hotfix:`Arreglo urgente`,release:`Release`},fr:{All:`Tous`,prompt:`Demander avant de créer le renvoi`,"create-if-missing":`Créer le renvoi s’il manque`,disabled:`Désactivé`,replace:`Remplacer`,append:`Ajouter`,preserve:`Conserver`,info:`Information`,low:`Faible`,medium:`Moyenne`,high:`Élevée`,smart:`Adaptatif`,default:`Par défaut`,auto:`Automatique`,always:`Toujours réinstaller`,recommend:`Recommander une approbation`,guarded:`Approuver sous garde`,off:`Désactivé`,check:`Vérification CI imposant la couverture`,numeric:`Rapport numérique vérifiable`,repository:`Dépôt`,organization:`Organisation`,selected:`Dépôts sélectionnés`,private:`Dépôts privés`,all:`Tous les dépôts`,"production-lineage":`Préserver la filiation de production`,"canonical-gitflow":`Git-Flow canonique`,manual:`Manuel`,"auto-merge":`Fusionner automatiquement`,"merge-queue":`File de fusion`,"create-only":`Créer la PR uniquement`,direct:`Fusion directe`,"sync-branch":`Par branche de synchronisation`,"prefer-release":`Privilégier la version`,development:`Développement`,both:`Les deux destinations`,"source-only":`Branche source seulement`,"sync-only":`Branche de synchronisation seulement`,none:`Aucune`,close:`Fermer le ticket`,"keep-open":`Garder ouvert`,guided:`Guidé`,compact:`Compact`,quiet:`Minimal`,update:`Mettre le commentaire à jour`,milestones:`Publier aux étapes clés`,feature:`Fonctionnalité`,bugfix:`Correction`,documentation:`Documentation`,chore:`Maintenance`,help:`Aide ou question`,hotfix:`Correctif urgent`,release:`Version`},pt:{All:`Todos`,prompt:`Perguntar antes de criar o apontador`,"create-if-missing":`Criar o apontador se faltar`,disabled:`Desativado`,replace:`Substituir`,append:`Acrescentar`,preserve:`Conservar`,info:`Informação`,low:`Baixa`,medium:`Média`,high:`Alta`,smart:`Adaptativo`,default:`Predefinido`,auto:`Automático`,always:`Reinstalar sempre`,recommend:`Recomendar aprovação`,guarded:`Aprovar sob condições`,off:`Desativado`,check:`Verificação CI que exige cobertura`,numeric:`Relatório numérico verificável`,repository:`Repositório`,organization:`Organização`,selected:`Repositórios selecionados`,private:`Repositórios privados`,all:`Todos os repositórios`,"production-lineage":`Preservar a linhagem de produção`,"canonical-gitflow":`Git-Flow canónico`,manual:`Manual`,"auto-merge":`Integrar automaticamente`,"merge-queue":`Fila de integração`,"create-only":`Criar apenas a PR`,direct:`Integração direta`,"sync-branch":`Através de ramo de sincronização`,"prefer-release":`Priorizar a release`,development:`Desenvolvimento`,both:`Ambos os destinos`,"source-only":`Apenas ramo de origem`,"sync-only":`Apenas ramo de sincronização`,none:`Nenhum`,close:`Fechar a questão`,"keep-open":`Manter aberta`,guided:`Guiado`,compact:`Compacto`,quiet:`Mínimo`,update:`Atualizar o comentário`,milestones:`Publicar nos marcos`,feature:`Funcionalidade`,bugfix:`Correção`,documentation:`Documentação`,chore:`Manutenção`,help:`Ajuda ou pergunta`,hotfix:`Hotfix`,release:`Release`}},pa=new Set([`codex`,`opencode`,`cursor`,`openai`,`anthropic`,`google`,`openrouter`,`local`]);function ma(e,t,n){if(n===`en`||pa.has(t))return t;let r=fa[n];if(e===`issueWorkflows.enabled`&&t.includes(` — `)){let e=t.split(` — `,1)[0];if(r[e])return`${e} — ${r[e]}`}return e===`repository.reconciliationCleanup`&&t===`all`?{es:`Todas las ramas temporales`,fr:`Toutes les branches temporaires`,pt:`Todos os ramos temporários`}[n]:r[t]??t}var ha={en:ca,es:la,fr:ua,pt:da};function ga(e,t){if(!e.copyId)return t===`en`?e.text:Q(`unknownLocalError`,t);let n=ha[t][e.copyId],r=e.copyValues??{},i=e.copyId===`permission.preview`?{...r,issues:(r.issues??``).split(`|`).map(e=>ma(`issueWorkflows.enabled`,e,t)).join(`, `),approval:ma(`pullRequestApproval.mode`,r.approval??``,t),secrets:ma(`storage.secrets.defaultScope`,r.secrets??``,t),variables:ma(`storage.variables.defaultScope`,r.variables??``,t),projects:ma(`projects.ids`,r.projects??``,t)}:r,a=n.replace(/\{([a-zA-Z]\w*)\}/gu,(e,t)=>i[t]??``);return e.copyId!==`credential.checks`||!e.credentialChecks?.length?a:`${a}\n${e.credentialChecks.map(e=>{let n=`credential.status.${e.status}`;return`${e.name}: ${ha[t][n]}`}).join(` +`)}`}var _a={en:ia,es:aa,fr:oa,pt:sa};function va(e,t){return e.replace(/\{([a-zA-Z]\w*)\}/gu,(e,n)=>t[n]??``)}function ya(e,t){if(!e.copyId)return;let n=_a[t][e.copyId],r={...e.copyValues??{}};if(e.copyId===`credential.existing`&&r.status&&[`valid`,`invalid`,`missing`,`unverifiable`,`not_required`].includes(r.status)){let e=`credential.status.${r.status}`;r.status=ha[t][e]}return{title:va(n.title,r),description:va(n.description,r),...n.choices?{choices:n.choices}:{}}}function ba(e,t,n){return ya(e,t)?.choices?.[n]??e.choices[n]}var xa=W(`

    `,1);function Sa(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`view`,8);Tn(()=>(U(o()),n(),ya),()=>{N(a,o()?.outcome===`complete`?Q(`completeTitle`,n()):o()?.outcome===`dry-run`?Q(`previewTitle`,n()):o()?.outcome===`cancelled`?Q(`cancelledTitle`,n()):o()?.outcome?Q(`blockedTitle`,n()):o()?.prompt?.kind===`question`?Q(`choices`,n()):o()?.prompt?.kind===`plan`?Q(`plan`,n()):o()?.prompt?ya(o().prompt,n())?.title??o().prompt.title:Q(`preparing`,n()))}),En(),Y();var s=xa(),c=F(s),l=L(P(c)),u=I(L(l));E(c);var d=L(c,2),f=I(d,!0),p=I(L(d,2),!0);R((e,t,n)=>{K(l,` ${e??``} `),K(u,`${t??``} / 06`),K(f,V(a)),K(p,n)},[()=>(U(qi),U(o()),n(),H(()=>qi(o()?.journey?.current,n()).toUpperCase())),()=>(U(o()),H(()=>String(o()?.journey?.position??1).padStart(2,`0`))),()=>(U(o()),U(Q),n(),H(()=>o()?.outcome?Q(`resultLede`,n()):Q(`activeLede`,n())))]),G(e,s),k(),i()}function Ca(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&(t.pathname===`/settings/personal-access-tokens`||t.pathname.startsWith(`/settings/personal-access-tokens/`))?t.toString():void 0}catch{return}}function wa(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/actions\/runs\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function Ta(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/rules\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function Ea(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/(?:orgs|users)\/[A-Za-z0-9-]{1,39}\/projects\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}var Da=W(``),Oa=W(``);function ka(e,t){let n=Z(t,`label`,8),r=Z(t,`variant`,8,`primary`),i=Z(t,`disabled`,8,!1),a=Z(t,`arrow`,8,!1),o=Z(t,`onClick`,8);var s=Oa(),c=P(s,!0),l=L(c),u=e=>{G(e,Da())};q(l,e=>{a()&&e(u)}),E(s),R(()=>{ui(s,1,si(r())),s.disabled=i(),K(c,n())}),Sr(`click`,s,function(...e){o()?.apply(this,e)}),G(e,s)}Cr([`click`]);var Aa=W(` `),ja=W(`

    `);function Ma(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`tone`,8,`info`),s=Z(t,`title`,8),c=Z(t,`message`,8),l=Z(t,`link`,8,void 0),u=Z(t,`actionLabel`,8,void 0),d=Z(t,`onAction`,8,void 0);Tn(()=>U(l()),()=>{N(a,Ca(l()))}),En(),Y();var f=ja(),p=P(f),m=I(p,!0),h=L(p),g=I(h,!0),_=L(h,2),v=e=>{var t=Aa(),r=I(t,!0);R(e=>{J(t,`href`,V(a)),K(r,e)},[()=>(U(Q),n(),H(()=>Q(`githubLink`,n())))]),G(e,t)};q(_,e=>{V(a)&&e(v)});var y=L(_,2),b=e=>{ka(e,{get label(){return u()},variant:`secondary`,get onClick(){return d()}})};q(y,e=>{u()&&d()&&e(b)}),E(f),R(()=>{ui(f,1,`banner ${o()??``}`),J(f,`role`,o()===`error`?`alert`:`status`),K(m,s()),K(g,c())}),G(e,f),k(),i()}function Na(e){let t=String(e.question.defaultValue),n=t.split(`,`).map(e=>e.trim()).filter(Boolean),r=e.question.kind===`multi-select`?n.includes(`All`)&&e.question.choices?.includes(`All`)?[`All`]:(e.question.choices??[]).filter(e=>e!==`All`&&n.includes(e.split(` — `)[0])):e.question.kind===`scope-overrides`?n:e.question.kind===`producer-select`?t.split(`;`).map(e=>e.trim()).filter(Boolean):e.question.kind===`project-select`?n.filter(t=>e.question.projectCandidates?.some(e=>String(e.number)===t)):[],i=e.question.kind===`project-select`?n.filter(e=>!r.includes(e)).join(`,`):t;return{value:e.question.kind===`producer-select`?``:i,selected:r}}function Pa(e,t){return t===`All`?e.includes(`All`)?[]:[`All`]:e.includes(t)?e.filter(e=>e!==t):[...e.filter(e=>e!==`All`),t]}function Fa(e,t,n){return e.question.kind===`scope-overrides`||e.question.kind===`multi-select`?n.length?n.join(`,`):`none`:e.question.kind===`producer-select`?[...n,...t.split(`;`).map(e=>e.trim()).filter(Boolean)].join(`;`):e.question.kind===`project-select`?[...n,...t.split(`,`).map(e=>e.trim()).filter(Boolean)].join(`,`)||`none`:t}var Ia={issueCreated:`projectTransitionIssueCreated`,pullRequestCreated:`projectTransitionPullRequestCreated`,issueInProgress:`projectTransitionIssueInProgress`,pullRequestInProgress:`projectTransitionPullRequestInProgress`};function La(e){if(e)try{let t=new URL(e);if(t.protocol!==`https:`||t.username||t.password||t.search)return;if(t.hostname===`docs.page`&&t.port===``&&t.pathname.startsWith(`/vypdev/copilot/`)||t.hostname===`docs.github.com`&&t.port===``&&t.pathname.startsWith(`/en/`))return t.href}catch{return}}var Ra=W(`

    `),za=W(`

    `),Ba=W(` `,1);function Va(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`kind`,8),s=Z(t,`status`,8),c=Z(t,`truncated`,8,!1),l={observed:`checksObserved`,"no-recent-runs":`checksNoRecent`,"no-verifiable-checks":`checksNoVerifiable`,"permission-denied":`checksDenied`,unavailable:`checksUnavailable`},u={observed:`projectsObserved`,empty:`projectsEmpty`,"permission-denied":`projectsDenied`,unavailable:`projectsUnavailable`,unsupported:`projectsUnsupported`};Tn(()=>(U(s()),U(o())),()=>{N(a,s()?o()===`checks`?l[s()]:u[s()]:void 0)}),En(),Y();var d=Ba(),f=F(d),p=e=>{var t=Ra(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),V(a),n(),H(()=>Q(V(a),n())))]),G(e,t)};q(f,e=>{V(a)&&e(p)});var m=L(f,2),h=e=>{var t=za(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),U(o()),n(),H(()=>Q(o()===`checks`?`checksDiscoveryScope`:`projectsDiscoveryScope`,n())))]),G(e,t)};q(m,e=>{(s()===`observed`||s()===`empty`||s()===`no-recent-runs`||s()===`no-verifiable-checks`)&&e(h)});var g=L(m,2),_=e=>{var t=za(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`discoveryTruncated`,n())))]),G(e,t)};q(g,e=>{c()&&e(_)}),G(e,d),k(),i()}var Ha={en:{success:`Passed`,failure:`Failed`,cancelled:`Cancelled`,neutral:`Neutral`,skipped:`Skipped`,timed_out:`Timed out`,action_required:`Action required`,stale:`Stale`,startup_failure:`Failed to start`,unknown:`Unknown outcome`},es:{success:`Correcto`,failure:`Falló`,cancelled:`Cancelado`,neutral:`Neutral`,skipped:`Omitido`,timed_out:`Agotó el tiempo`,action_required:`Requiere intervención`,stale:`Obsoleto`,startup_failure:`Falló al iniciar`,unknown:`Resultado desconocido`},fr:{success:`Réussi`,failure:`Échoué`,cancelled:`Annulé`,neutral:`Neutre`,skipped:`Ignoré`,timed_out:`Délai dépassé`,action_required:`Action nécessaire`,stale:`Obsolète`,startup_failure:`Échec au démarrage`,unknown:`Résultat inconnu`},pt:{success:`Concluído`,failure:`Falhou`,cancelled:`Cancelado`,neutral:`Neutro`,skipped:`Ignorado`,timed_out:`Tempo esgotado`,action_required:`Ação necessária`,stale:`Obsoleto`,startup_failure:`Falha ao iniciar`,unknown:`Resultado desconhecido`}};function Ua(e,t){return Ha[t][e]??Ha[t].unknown}function Wa(e,t,n){let r=e.trim(),i=n.trim(),a=String(t??``).trim(),o=Number(a);if(!(!r||!i||r.length>100||i.length>100||/[|;\r\n]/u.test(r+i)||!/^[1-9]\d*$/u.test(a)||!Number.isSafeInteger(o)))return`${r}|${o}|${i}`}var Ga=W(` `),Ka=W(`
    `),qa=W(`
  • `),Ja=W(`
      `),Ya=W(``),Xa=W(`

      `,1);function Za(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=Z(t,`candidates`,8),c=Z(t,`selected`,12),l=Z(t,`controller`,8),u=M(``),d=M(``),f=M(``),p=M(!1);function m(){let e=Wa(V(u),V(d),V(f));if(!e||c().length>=8){N(p,!0);return}N(p,!1),c().includes(e)||c([...c(),e]),N(u,``),N(d,``),N(f,``)}Tn(()=>U(s()),()=>{N(a,new Set(s().map(e=>`${e.name}|${e.sourceAppId}|${e.workflowName}`)))}),Tn(()=>(U(c()),V(a)),()=>{N(o,c().filter(e=>!V(a).has(e)))}),En(),Y();var h=Xa(),g=F(h);Qr(g,5,s,Jr,(e,t)=>{let r=A(()=>(V(t),H(()=>`${V(t).name}|${V(t).sourceAppId}|${V(t).workflowName}`)));var i=Ka(),a=P(i),o=P(a);xi(o);var s=L(o,2),u=P(s),d=I(P(u),!0);E(u);var f=L(u),p=I(P(f));E(f);var m=I(L(f),!0);E(s),E(a);var h=L(a,2),g=e=>{var r=Ga(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(wa),V(t),H(()=>wa(V(t).runUrl))),()=>(U(Q),n(),H(()=>Q(`ciRun`,n())))]),G(e,r)},_=gt(()=>(U(wa),V(t),H(()=>wa(V(t).runUrl))));q(h,e=>{V(_)&&e(g)});var v=L(h,2),y=e=>{var r=Ga(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(Ta),V(t),H(()=>Ta(V(t).requiredByRuleset?.sourceUrl))),()=>(U(Q),n(),H(()=>Q(`ciRule`,n())))]),G(e,r)},b=gt(()=>(U(Ta),V(t),H(()=>Ta(V(t).requiredByRuleset?.sourceUrl))));q(v,e=>{V(b)&&e(y)}),E(i),R((e,n,r,i,a,s)=>{Si(o,e),o.disabled=n,K(d,(V(t),H(()=>V(t).name))),K(p,`${V(t),H(()=>V(t).workflowName)??``} · ${V(t),H(()=>V(t).sourceAppName??`GitHub App`)??``} ${V(t),H(()=>V(t).sourceAppId)??``} · ${r??``} · ${i??``} · ${a??``}`),K(m,s)},[()=>(U(c()),U(V(r)),H(()=>c().includes(V(r)))),()=>(U(l()),U(c()),U(V(r)),H(()=>!l()||c().length>=8&&!c().includes(V(r)))),()=>(U(Ua),V(t),n(),H(()=>Ua(V(t).conclusion,n()))),()=>(V(t),H(()=>V(t).headSha.slice(0,7))),()=>(V(t),U(Q),n(),H(()=>V(t).observedAt??Q(`observationTimeUnknown`,n()))),()=>(V(t),U(Q),n(),H(()=>V(t).requiredByRuleset?Q(`branchRequirementObserved`,n(),{branch:V(t).requiredByRuleset.branch}):Q(`branchRequirementUnknown`,n())))]),Sr(`change`,o,()=>c(Pa(c(),V(r)))),G(e,i)}),E(g);var _=L(g,2),v=e=>{var t=Ja();Qr(t,5,()=>V(o),Jr,(e,t)=>{var r=qa(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0);E(r),R(e=>{K(a,V(t)),o.disabled=!l(),K(s,e)},[()=>(U(Q),n(),H(()=>Q(`producerRemove`,n())))]),Sr(`click`,o,()=>c(Pa(c(),V(t)))),G(e,r)}),E(t),G(e,t)};q(_,e=>{V(o),H(()=>V(o).length)&&e(v)});var y=L(_,2),b=I(y,!0),x=L(y,2),S=P(x),C=P(S,!0),ee=L(C);xi(ee),E(S);var te=L(S,2),ne=P(te,!0),re=L(ne);xi(re),E(te);var ie=L(te,2),ae=P(ie,!0),oe=L(ae);xi(oe),E(ie),E(x);var se=L(x,2),ce=I(se,!0),le=L(se,2),ue=e=>{var t=Ya(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`producerManualInvalid`,n())))]),G(e,t)};q(le,e=>{V(p)&&e(ue)}),R((e,t,n,r,i,a)=>{J(g,`aria-label`,e),K(b,t),K(C,n),ee.disabled=!l(),K(ne,r),re.disabled=!l(),K(ae,i),oe.disabled=!l(),se.disabled=!l(),K(ce,a)},[()=>(U(Q),n(),H(()=>Q(`checksObserved`,n()))),()=>(U(Q),n(),H(()=>Q(`producerManualHelp`,n()))),()=>(U(Q),n(),H(()=>Q(`producerName`,n()))),()=>(U(Q),n(),H(()=>Q(`producerAppId`,n()))),()=>(U(Q),n(),H(()=>Q(`producerWorkflow`,n()))),()=>(U(Q),n(),H(()=>Q(`producerAdd`,n())))]),Ei(ee,()=>V(u),e=>N(u,e)),Ei(re,()=>V(d),e=>N(d,e)),Ei(oe,()=>V(f),e=>N(f,e)),Sr(`click`,se,m),G(e,h),k(),i()}Cr([`change`,`click`]);var Qa=W(` `),$a=W(`
      `),eo=W(`
    • `),to=W(`

        `,1),no=W(`
        `,1);function ro(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=Z(t,`candidates`,8),c=Z(t,`selected`,12),l=Z(t,`value`,12),u=Z(t,`controller`,8);Tn(()=>U(s()),()=>{N(a,new Set(s().map(e=>String(e.number))))}),Tn(()=>(U(c()),V(a)),()=>{N(o,c().filter(e=>!V(a).has(e)))}),En(),Y();var d=no(),f=F(d);Qr(f,5,s,Jr,(e,t)=>{var r=$a(),i=P(r),a=P(i);xi(a);var o=L(a,2),s=P(o),l=I(P(s),!0);E(s);var d=L(s),f=I(P(d));E(d),E(o),E(i);var p=L(i,2),m=e=>{var r=Qa(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(Ea),V(t),H(()=>Ea(V(t).url))),()=>(U(Q),n(),H(()=>Q(`projectUrl`,n())))]),G(e,r)},h=gt(()=>(U(Ea),V(t),H(()=>Ea(V(t).url))));q(p,e=>{V(h)&&e(m)}),E(r),R((e,n)=>{Si(a,e),a.disabled=n,K(l,(V(t),H(()=>V(t).title))),K(f,`${V(t),H(()=>V(t).owner)??``} · #${V(t),H(()=>V(t).number)??``}`)},[()=>(U(c()),V(t),H(()=>c().includes(String(V(t).number)))),()=>(U(u()),U(c()),V(t),H(()=>!u()||c().length>=10&&!c().includes(String(V(t).number))))]),Sr(`change`,a,()=>c(Pa(c(),String(V(t).number)))),G(e,r)}),E(f);var p=L(f,2),m=e=>{var t=to(),r=F(t),i=I(r,!0),a=L(r,2);Qr(a,5,()=>V(o),Jr,(e,t)=>{var r=eo(),i=P(r),a=I(i),o=L(i,2),s=I(o,!0);E(r),R(e=>{K(a,`#${V(t)??``}`),o.disabled=!u(),K(s,e)},[()=>(U(Q),n(),H(()=>Q(`removeSelection`,n())))]),Sr(`click`,o,()=>c(Pa(c(),V(t)))),G(e,r)}),E(a),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`projectSelectionNotObserved`,n())))]),G(e,t)};q(p,e=>{V(o),H(()=>V(o).length)&&e(m)});var h=L(p,2),g=I(h,!0),_=L(h,2);xi(_),R((e,t)=>{J(f,`aria-label`,e),K(g,t),_.disabled=!u()},[()=>(U(Q),n(),H(()=>Q(`projectsObserved`,n()))),()=>(U(Q),n(),H(()=>Q(`projectManual`,n())))]),Ei(_,l),G(e,d),k(),i()}Cr([`change`,`click`]);var io=W(``),ao=W(`
        `),oo=W(` `,1);function so(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`explanation`,8),o=Z(t,`helpUrl`,8);Y();var s=oo(),c=F(s),l=e=>{var t=io(),r=P(t),i=I(r);E(t),R(e=>{J(r,`href`,o()),K(i,`${e??``} ↗`)},[()=>(U(Q),n(),H(()=>Q(`learnMore`,n())))]),G(e,t)};q(c,e=>{o()&&e(l)});var u=L(c,2),d=e=>{var t=ao(),r=P(t),i=I(r,!0),o=L(r),s=P(o),c=I(s,!0),l=L(s),u=I(l,!0),d=L(l,2),f=I(d,!0),p=L(d),m=I(p,!0),h=L(p,2),g=I(h,!0),_=L(h),v=I(_,!0),y=L(_,2),b=I(y,!0),x=L(y),S=I(x,!0),C=L(x,2),ee=I(C,!0),te=L(C),ne=I(te,!0),re=L(te,2),ie=I(re,!0),ae=L(re),oe=I(ae,!0),se=L(ae,2),ce=I(se,!0),le=I(L(se),!0);E(o),E(t),R((e,t,n,r,o,s,l,d)=>{K(i,e),K(c,t),K(u,(U(a()),H(()=>a().when))),K(f,n),K(m,(U(a()),H(()=>a().where))),K(g,r),K(v,(U(a()),H(()=>a().how))),K(b,o),K(S,(U(a()),H(()=>a().why))),K(ee,s),K(ne,(U(a()),H(()=>a().example))),K(ie,l),K(oe,(U(a()),H(()=>a().effect))),K(ce,d),K(le,(U(a()),H(()=>a().verify)))},[()=>(U(Q),n(),H(()=>Q(`whyMatters`,n()))),()=>(U(Q),n(),H(()=>Q(`whenApplies`,n()))),()=>(U(Q),n(),H(()=>Q(`whereConfigured`,n()))),()=>(U(Q),n(),H(()=>Q(`howToChoose`,n()))),()=>(U(Q),n(),H(()=>Q(`whyRecommendation`,n()))),()=>(U(Q),n(),H(()=>Q(`example`,n()))),()=>(U(Q),n(),H(()=>Q(`effect`,n()))),()=>(U(Q),n(),H(()=>Q(`verify`,n())))]),G(e,t)};q(u,e=>{a()&&e(d)}),G(e,s),k(),i()}var co=W(`· `,1),lo=W(`

        `,1);function uo(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`candidate`,8);Y();var o=lo(),s=F(o),c=P(s),l=I(c),u=L(c,2),d=e=>{var t=co(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(wa),U(a()),H(()=>wa(a().runUrl))),()=>(U(Q),n(),H(()=>Q(`ciRun`,n())))]),G(e,t)},f=gt(()=>(U(wa),U(a()),H(()=>wa(a().runUrl))));q(u,e=>{V(f)&&e(d)}),E(s);var p=L(s,2),m=P(p),h=I(m),g=L(m),_=L(g),v=e=>{var t=co(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(Ta),U(a()),H(()=>Ta(a().requiredByRuleset?.sourceUrl))),()=>(U(Q),n(),H(()=>Q(`ciRule`,n())))]),G(e,t)},y=gt(()=>(U(Ta),U(a()),H(()=>Ta(a().requiredByRuleset?.sourceUrl))));q(_,e=>{V(y)&&e(v)}),E(p),R((e,t,n,r)=>{K(l,`${U(a()),H(()=>a().workflowName)??``} · GitHub App ${U(a()),H(()=>a().sourceAppId)??``}`),K(h,`${e??``} · ${t??``} · ${n??``}`),K(g,` · ${r??``} `)},[()=>(U(Ua),U(a()),n(),H(()=>Ua(a().conclusion,n()))),()=>(U(a()),H(()=>a().headSha.slice(0,7))),()=>(U(a()),U(Q),n(),H(()=>a().observedAt??Q(`observationTimeUnknown`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().requiredByRuleset?Q(`branchRequirementObserved`,n(),{branch:a().requiredByRuleset.branch}):Q(`branchRequirementUnknown`,n())))]),G(e,o),k(),i()}var fo=W(`

        `);function po(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`question`,8);Y();var o=Mr(),s=F(o),c=e=>{var t=fo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`fixedIssuesRequired`,n())))]),G(e,t)},l=e=>{var t=Mr();Qr(F(t),1,()=>(U(a()),H(()=>Object.entries(a().fixedWorkflowFeatures).filter(([,e])=>e!==void 0))),Jr,(e,t)=>{var r=gt(()=>b(V(t),2));let i=()=>V(r)[0],a=()=>V(r)[1];var o=fo(),s=I(o,!0);R(e=>K(s,e),[()=>(U(Q),a(),n(),i(),H(()=>Q(a()?`fixedWorkflowEnabled`:`fixedWorkflowDisabled`,n(),{kind:i()})))]),G(e,o)}),G(e,t)};q(s,e=>{U(a()),H(()=>a().id===`features.issues`&&(a().fixedWorkflowFeatures?.release||a().fixedWorkflowFeatures?.hotfix))?e(c):(U(a()),H(()=>a().fixedWorkflowFeatures)&&e(l,1))}),G(e,o),k(),i()}var mo=W(` `),ho=W(`

        `),go=W(`

        `),_o=W(` `,1),vo=W(`

        `),yo=W(`
        `),bo=W(`

        `),xo=W(``),So=W(`
      • `),Co=W(`
          `),wo=W(`
          `),To=W(``),Eo=W(``),Do=W(` `,1),Oo=W(``),ko=W(`
          `),Ao=W(``),jo=W(``),Mo=W(`

          `,1);function No(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=M(),c=Z(t,`prompt`,8),l=Z(t,`controller`,8),u=Z(t,`busy`,8),d=Z(t,`onSubmit`,8),f=Z(t,`onRetryDiscovery`,8),p=Z(t,`onBack`,8),m=Na(c()),h=M(m.value),g=M(m.selected);Tn(()=>(U(c()),n()),()=>{N(a,c().presentation?.[n()])}),Tn(()=>V(a),()=>{N(o,La(V(a)?.documentation?.url))}),Tn(()=>(U(c()),n(),ma),()=>{N(s,typeof c().question.defaultValue==`boolean`?Q(c().question.defaultValue?`yes`:`no`,n()):c().question.defaultValue===``?Q(`none`,n()):c().question.kind===`choice`||c().question.kind===`multi-select`?ma(c().question.id,String(c().question.defaultValue),n()):String(c().question.defaultValue))}),En(),Y();var _=Mo(),v=F(_),y=P(v),b=I(y,!0),x=L(y),S=e=>{var t=mo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`permissionPreview`,n())))]),G(e,t)};q(x,e=>{U(c()),H(()=>c().phase===`permission-intent`)&&e(S)}),E(v);var C=L(v,2),ee=e=>{var t=ho(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),U(c()),H(()=>Q(`questionProgress`,n(),{current:String(c().progress.groupPosition),total:String(c().progress.groupTotal),overall:String(c().progress.position),all:String(c().progress.total)})))]),G(e,t)};q(C,e=>{U(c()),H(()=>c().progress)&&e(ee)});var te=L(C,2),ne=e=>{var t=go(),n=I(t,!0);R(()=>K(n,(V(a),H(()=>V(a).summary)))),G(e,t)};q(te,e=>{V(a)&&e(ne)});var re=L(te,2),ie=e=>{Va(e,{kind:`checks`,get status(){return U(c()),H(()=>c().question.discoveryStatus)},get truncated(){return U(c()),H(()=>c().question.discoveryTruncated)}})};q(re,e=>{U(c()),H(()=>c().question.id===`pullRequestApproval.testChecks`)&&e(ie)});var ae=L(re,2),oe=e=>{Va(e,{kind:`projects`,get status(){return U(c()),H(()=>c().question.discoveryStatus)},get truncated(){return U(c()),H(()=>c().question.discoveryTruncated)}})};q(ae,e=>{U(c()),H(()=>c().question.id===`projects.ids`)&&e(oe)});var se=L(ae,2),ce=e=>{var t=yo(),r=P(t),i=e=>{var t=_o(),r=F(t),i=I(r,!0),a=I(L(r,2),!0);R((e,t)=>{r.disabled=!l()||u(),K(i,e),K(a,t)},[()=>(U(Q),n(),H(()=>Q(`retryDiscovery`,n()))),()=>(U(Q),n(),U(c()),H(()=>Q(`retryRemaining`,n(),{count:String(c().question.discoveryRetryRemaining)})))]),Sr(`click`,r,function(...e){f()?.apply(this,e)}),G(e,t)},a=e=>{var t=vo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`retryExhausted`,n())))]),G(e,t)};q(r,e=>{U(c()),H(()=>c().question.discoveryRetryRemaining>0)?e(i):e(a,-1)}),E(t),G(e,t)};q(se,e=>{U(c()),H(()=>c().question.discoveryRetryRemaining!==void 0)&&e(ce)});var le=L(se,2),ue=e=>{var t=bo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`projectStatusUnavailable`,n())))]),G(e,t)};q(le,e=>{U(c()),H(()=>c().question.statusOptionState===`unavailable`)&&e(ue)});var de=L(le,2),fe=e=>{var t=xo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`projectStatusIncompatible`,n())))]),G(e,t)};q(de,e=>{U(c()),H(()=>c().question.statusOptionState===`incompatible`)&&e(fe)});var pe=L(de,2),me=e=>{var t=vo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`projectSharedStatus`,n())))]),G(e,t)};q(pe,e=>{U(c()),H(()=>c().question.id===`projects.ids`)&&e(me)});var he=L(pe,2);po(he,{get question(){return U(c()),H(()=>c().question)}});var ge=L(he,2),_e=e=>{var t=Co();Qr(t,5,()=>(U(c()),H(()=>c().question.projectStatusValues)),Jr,(e,t)=>{var r=So(),i=P(r),a=L(i),o=I(P(a),!0);E(a),E(r),R(e=>{K(i,`${e??``}: `),K(o,(V(t),H(()=>V(t).value)))},[()=>(U(Q),U(Ia),V(t),n(),H(()=>Q(Ia[V(t).transition],n())))]),G(e,r)}),E(t),G(e,t)};q(ge,e=>{U(c()),H(()=>c().question.projectStatusValues)&&e(_e)});var ve=L(ge,2),ye=e=>{var t=wo(),r=P(t);let i;var o=I(r,!0),s=L(r);let u;var d=I(s,!0);E(t),R((e,n)=>{J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),J(r,`aria-pressed`,V(h)===`yes`||V(h)===`true`),r.disabled=!l(),i=ui(r,1,``,null,i,{selected:V(h)===`yes`||V(h)===`true`}),K(o,e),J(s,`aria-pressed`,V(h)===`no`||V(h)===`false`),s.disabled=!l(),u=ui(s,1,``,null,u,{selected:V(h)===`no`||V(h)===`false`}),K(d,n)},[()=>(U(Q),n(),H(()=>Q(`yes`,n()))),()=>(U(Q),n(),H(()=>Q(`no`,n())))]),Sr(`click`,r,()=>N(h,`yes`)),Sr(`click`,s,()=>N(h,`no`)),G(e,t)},be=e=>{var t=Do(),r=F(t),i=P(r),o=e=>{var t=To(),r=I(t,!0);t.value=t.__value=``,R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`selectOne`,n())))]),G(e,t)};q(i,e=>{U(c()),H(()=>!c().question.defaultValue)&&e(o)}),Qr(L(i),1,()=>(U(c()),H(()=>c().question.choices??[])),Jr,(e,t)=>{let r=A(()=>(U(c()),V(t),H(()=>c().question.id===`pullRequestApproval.coverage.checkName`?c().question.trustedProducers?.find(e=>e.name===V(t)):void 0)));var i=Eo(),a=I(i,!0),o={};R(e=>{K(a,e),o!==(o=V(t))&&(i.value=(i.__value=o)??``)},[()=>(U(V(r)),V(t),U(ma),U(c()),n(),H(()=>V(r)?`${V(t)} — ${V(r).workflowName} · App ${V(r).sourceAppId}`:ma(c().question.id,V(t),n())))]),G(e,i)}),E(r),mi(r);var s=L(r,2),u=e=>{var t=Mr();Qr(F(t),1,()=>(U(c()),V(h),H(()=>(c().question.producerCandidates??[]).filter(e=>e.name===V(h)))),Jr,(e,t)=>{uo(e,{get candidate(){return V(t)}})}),G(e,t)};q(s,e=>{U(c()),H(()=>c().question.id===`pullRequestApproval.coverage.checkName`)&&e(u)}),R(()=>{J(r,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),r.disabled=!l()}),hi(r,()=>V(h),e=>N(h,e)),G(e,t)},xe=e=>{{let t=A(()=>(U(c()),H(()=>c().question.producerCandidates??[])));Za(e,{get candidates(){return V(t)},get controller(){return l()},get selected(){return V(g)},set selected(e){N(g,e)},$$legacy:!0})}},Se=e=>{{let t=A(()=>(U(c()),H(()=>c().question.projectCandidates??[])));ro(e,{get candidates(){return V(t)},get controller(){return l()},get selected(){return V(g)},set selected(e){N(g,e)},get value(){return V(h)},set value(e){N(h,e)},$$legacy:!0})}},Ce=e=>{var t=ko();Qr(t,5,()=>(U(c()),H(()=>c().question.kind===`multi-select`?c().question.choices??[]:c().question.allowedNames??[])),Jr,(e,t)=>{var r=Oo(),i=P(r);xi(i);var a=I(L(i),!0);E(r),R((e,t)=>{Si(i,e),i.disabled=!l(),K(a,t)},[()=>(V(g),V(t),H(()=>V(g).includes(V(t)))),()=>(U(c()),U(ma),V(t),n(),H(()=>c().question.kind===`multi-select`?ma(c().question.id,V(t),n()):V(t)))]),Sr(`change`,i,()=>N(g,Pa(V(g),V(t)))),G(e,r)}),E(t),R(()=>J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label)))),G(e,t)},we=e=>{var t=Mr(),n=F(t),r=e=>{var t=Ao();it(t),R(()=>{J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),t.disabled=!l()}),Ei(t,()=>V(h),e=>N(h,e)),G(e,t)},i=e=>{var t=jo();xi(t),R(()=>{J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),J(t,`type`,(U(c()),H(()=>c().question.kind===`number`?`number`:`text`))),J(t,`min`,(U(c()),H(()=>c().question.kind===`number`?0:void 0))),t.disabled=!l()}),Ei(t,()=>V(h),e=>N(h,e)),G(e,t)};q(n,e=>{U(c()),H(()=>c().question.id===`ai.bugbotOrganizationRules`)?e(r):e(i,-1)}),G(e,t)};q(ve,e=>{U(c()),H(()=>c().question.kind===`boolean`)?e(ye):(U(c()),H(()=>c().question.kind===`choice`)?e(be,1):(U(c()),H(()=>c().question.kind===`producer-select`)?e(xe,2):(U(c()),H(()=>c().question.kind===`project-select`)?e(Se,3):(U(c()),H(()=>c().question.kind===`multi-select`||c().question.kind===`scope-overrides`)?e(Ce,4):e(we,-1)))))});var Te=L(ve,2),w=I(Te,!0),Ee=L(Te,2),T=e=>{var t=ho(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),U(c()),n(),H(()=>Q(c().question.suggestionSource===`github`?`sourceGithub`:c().question.suggestionSource===`local`?`sourceLocal`:c().question.suggestionSource===`configuration`?`sourceConfig`:`sourceDefault`,n())))]),G(e,t)};q(Ee,e=>{U(c()),H(()=>c().question.suggestionSource)&&e(T)});var De=L(Ee,2);so(De,{get explanation(){return V(a)},get helpUrl(){return V(o)}});var Oe=L(De,2),ke=P(Oe),Ae=e=>{{let t=A(()=>(U(Q),n(),H(()=>Q(`previousQuestion`,n())))),r=A(()=>!l()||u());ka(e,{get label(){return V(t)},variant:`secondary`,get onClick(){return p()},get disabled(){return V(r)}})}};q(ke,e=>{U(c()),H(()=>c().canGoBack)&&e(Ae)});var je=L(ke,2);{let e=A(()=>(U(Q),n(),H(()=>Q(`continue`,n())))),t=A(()=>!l()||u());ka(je,{get label(){return V(e)},arrow:!0,onClick:()=>d()(Fa(c(),V(h),V(g))),get disabled(){return V(t)}})}E(Oe),R((e,t)=>{K(b,e),K(w,t)},[()=>(V(a),U(c()),H(()=>V(a)?.label??c().question.label.replace(` (Space toggles, Enter confirms)`,``))),()=>(U(Q),n(),V(s),H(()=>Q(`suggested`,n(),{answer:V(s)})))]),G(e,_),k(),i()}Cr([`click`,`change`]);var Po=W(``),Fo=W(`
          `);function Io(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`prompt`,8),o=Z(t,`controller`,8),s=Z(t,`busy`,8),c=Z(t,`onSubmit`,8);Y();var l=Fo();Qr(l,5,()=>(U(a()),H(()=>a().choices)),Jr,(e,t,r)=>{var i=Po(),l=I(P(i),!0);ke(),E(i),R(e=>{i.disabled=!o()||s(),K(l,e)},[()=>(U(ba),U(a()),n(),H(()=>ba(a(),n(),r)))]),Sr(`click`,i,()=>c()(V(t))),G(e,i)}),E(l),G(e,l),k(),i()}Cr([`click`]);var Lo=W(`

          `,1),Ro=W(`

          `),zo=W(` `,1);function Bo(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`prompt`,8),s=Z(t,`controller`,8),c=Z(t,`busy`,8),l=Z(t,`onSubmit`,8),u=M(``);function d(){let e=V(u);o().kind===`secret`&&N(u,``),l()(e)}Tn(()=>U(o()),()=>{N(a,Ca(o().link))}),En(),Y();var f=zo(),p=F(f),m=e=>{var t=Lo(),r=F(t),i=P(r);ke(),E(r);var o=I(L(r),!0);R((e,t)=>{J(r,`href`,V(a)),K(i,`${e??``} `),K(o,t)},[()=>(U(Q),n(),H(()=>Q(`githubForm`,n()))),()=>(U(Q),n(),H(()=>Q(`githubFormHelp`,n())))]),G(e,t)};q(p,e=>{V(a)&&e(m)});var h=L(p,2),g=I(h,!0),_=L(h,2);xi(_);var v=L(_,2),y=e=>{var t=Ro(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`secretHelp`,n())))]),G(e,t)};q(v,e=>{U(o()),H(()=>o().kind===`secret`)&&e(y)});var b=L(v,2);{let e=A(()=>(U(Q),n(),H(()=>Q(`continue`,n())))),t=A(()=>(U(s()),U(c()),U(o()),V(u),H(()=>!s()||c()||!o().optional&&!V(u).trim())));ka(b,{get label(){return V(e)},arrow:!0,onClick:d,get disabled(){return V(t)}})}R((e,t)=>{K(g,e),J(_,`type`,(U(o()),H(()=>o().kind===`secret`?`password`:`text`))),_.disabled=!s(),J(_,`placeholder`,t)},[()=>(U(Q),U(o()),n(),H(()=>Q(o().kind===`secret`?`pasteHere`:`yourAnswer`,n()))),()=>(U(Q),U(o()),n(),H(()=>Q(o().kind===`secret`?`hiddenAfter`:`typeAnswer`,n())))]),Ei(_,()=>V(u),e=>N(u,e)),G(e,f),k(),i()}var Vo={"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Help / question issues remain branchless even when issue-managed-branches is enabled.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`Release automation is installed, but release issue events are disabled by the selected issue workflow profile.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Release and hotfix workflows require the workflow PAT Secret and a writable token.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.`},Ho={en:Vo,es:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No has activado ningún tipo de flujo de incidencias. Sus eventos no se gestionarán hasta que actives un formulario de incidencia y su entrada en el perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Las incidencias de ayuda y consulta no crean ramas, aunque actives las ramas gestionadas por incidencias.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`La automatización de versiones ya está instalada, pero el perfil elegido desactiva los eventos de incidencias de versiones.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`La automatización de correcciones urgentes ya está instalada, pero el perfil elegido desactiva los eventos de sus incidencias.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Has desactivado la generación de instrucciones para agentes del repositorio. Los colaboradores no recibirán el perfil ni la guía del flujo de trabajo generados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Los flujos de versiones y correcciones urgentes requieren el Secret con el PAT de la Action y un token con permisos de escritura.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La cola de merge bloqueará la operación si cada productor obligatorio no se verifica automáticamente o no dispone de una certificación exacta revisada.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`El modo de provisión permanente solo reinstala los entornos predeterminados de Codex y OpenCode desde paquetes fijados en el manifiesto. No sustituye ejecutables explícitos; Cursor debe estar instalado previamente.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Está activado el cierre de incidencias inactivas. Las que estén en espera se cerrarán tras el plazo configurado y podrán reabrirse con un comentario.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`El PAT del bot debe tener acceso a los Projects seleccionados, y los cuatro valores de Status configurados deben existir en cada uno de ellos.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`Cursor es un entorno experimental en Copilot. Requiere una CLI compatible ya instalada y CURSOR_API_KEY; Copilot no instala Cursor automáticamente.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Los Secrets y Variables de organización requieren permisos en ella. Limitar el acceso a los repositorios elegidos es la opción más segura; los valores del repositorio tienen prioridad.`},fr:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Aucun type de flux de travail pour les tickets n’est activé. Leurs événements ne seront pas gérés tant qu’un formulaire de ticket pris en charge et son entrée de profil ne seront pas activés.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Les tickets d’aide ou de question ne créent pas de branche, même lorsque les branches gérées par les tickets sont activées.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`L’automatisation des versions est déjà installée, mais le profil choisi désactive les événements des tickets de version.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`L’automatisation des correctifs urgents est déjà installée, mais le profil choisi désactive les événements des tickets correspondants.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`La génération des consignes pour les agents du dépôt est désactivée. Les collaborateurs ne recevront ni le profil ni le guide de flux de travail générés.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Les flux de version et de correctif urgent nécessitent le Secret contenant le PAT de l’Action et un jeton autorisé à écrire.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La file de fusion bloque l’opération si chaque producteur requis n’est pas vérifié automatiquement ou couvert par une attestation exacte et examinée.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`Le mode de provisionnement permanent ne réinstalle que les environnements Codex et OpenCode par défaut depuis les paquets verrouillés du manifeste. Il ne remplace jamais les exécutables indiqués explicitement ; Cursor doit être préinstallé.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`La fermeture des tickets inactifs est activée. Les tickets en attente seront fermés après le délai configuré et pourront être rouverts par un nouveau commentaire.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Le PAT du bot doit avoir accès aux Projects sélectionnés, et les quatre valeurs Status configurées doivent exister dans chacun de ces Projects.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`Cursor est un environnement expérimental dans Copilot. Il nécessite une CLI compatible déjà installée et CURSOR_API_KEY ; Copilot ne l’installe pas automatiquement.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Les Secrets et Variables d’organisation nécessitent des droits sur celle-ci. Limiter l’accès aux dépôts sélectionnés est le choix le plus sûr ; les valeurs du dépôt prévalent.`},pt:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Não está ativo nenhum tipo de fluxo de trabalho para issues. Os respetivos eventos não serão geridos até ativar um formulário de issue suportado e a entrada correspondente no perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`As issues de ajuda ou perguntas não criam ramos, mesmo com os ramos geridos por issues ativados.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`A automação de versões já está instalada, mas o perfil escolhido desativa os eventos das issues de versão.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`A automação de correções urgentes já está instalada, mas o perfil escolhido desativa os eventos das respetivas issues.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`A criação de orientações para agentes do repositório está desativada. Os colaboradores não receberão o perfil nem o guia do fluxo de trabalho gerados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Os fluxos de versão e correção urgente exigem o Secret com o PAT da Action e um token com permissão de escrita.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`A fila de integração bloqueia a operação se cada produtor obrigatório não for verificado automaticamente ou coberto por uma declaração exata e revista.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`O modo de aprovisionamento permanente reinstala apenas os ambientes padrão de Codex e OpenCode a partir de pacotes fixados no manifesto. Nunca substitui executáveis indicados explicitamente; o Cursor tem de estar pré-instalado.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`O fecho de issues inativas está ativado. As que aguardam resposta serão fechadas após o prazo configurado e poderão ser reabertas com um novo comentário.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`O PAT do bot tem de ter acesso aos Projects selecionados, e os quatro valores de Status configurados têm de existir em cada Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`O Cursor é um ambiente experimental no Copilot. Exige uma CLI compatível já instalada e CURSOR_API_KEY; o Copilot não instala o Cursor automaticamente.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Os Secrets e Variables da organização exigem permissões nessa organização. Restringir o acesso aos repositórios selecionados é a opção mais segura; os valores do repositório prevalecem.`}};function Uo(e,t){let n=Ho[t]??Vo;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:t===`en`?e:Q(`planUnknownWarning`,t)}var Wo={en:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Issue comments`,pullRequestComments:`Pull-request comments`,release:`Releases`,hotfix:`Hotfixes`,agentProvisioning:`Agent provisioning`,credentialHealth:`Credential health`,inactiveIssueClosure:`Inactive issue closure`,issueTemplates:`Issue templates`,pullRequestTemplate:`Pull-request template`},es:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentarios en issues`,pullRequestComments:`Comentarios en pull requests`,release:`Releases`,hotfix:`Correcciones urgentes`,agentProvisioning:`Instalación de agentes`,credentialHealth:`Estado de credenciales`,inactiveIssueClosure:`Cierre de issues inactivos`,issueTemplates:`Plantillas de issues`,pullRequestTemplate:`Plantilla de pull requests`},fr:{issues:`Tickets`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Commentaires des tickets`,pullRequestComments:`Commentaires des pull requests`,release:`Versions`,hotfix:`Correctifs urgents`,agentProvisioning:`Installation des agents`,credentialHealth:`État des identifiants`,inactiveIssueClosure:`Fermeture des tickets inactifs`,issueTemplates:`Modèles de tickets`,pullRequestTemplate:`Modèle de pull request`},pt:{issues:`Questões`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentários nas questões`,pullRequestComments:`Comentários nas pull requests`,release:`Versões`,hotfix:`Correções urgentes`,agentProvisioning:`Instalação de agentes`,credentialHealth:`Estado das credenciais`,inactiveIssueClosure:`Fecho de questões inativas`,issueTemplates:`Modelos de questões`,pullRequestTemplate:`Modelo de pull request`}};function Go(e,t){return Wo[t][e]??e}var Ko={en:{planner:`Planner`,findings:`Findings analyst`,reviewer:`Reviewer`,fixer:`Fixer`,tester:`Tester`},es:{planner:`Planificador`,findings:`Analista de hallazgos`,reviewer:`Revisor`,fixer:`Corrector`,tester:`Probador`},fr:{planner:`Planificateur`,findings:`Analyste des problèmes`,reviewer:`Réviseur`,fixer:`Correcteur`,tester:`Testeur`},pt:{planner:`Planeador`,findings:`Analista de problemas`,reviewer:`Revisor`,fixer:`Corretor`,tester:`Testador`}};function qo(e,t){return Ko[t][e]??e}var Jo=W(`
        • `),Yo=W(`
        • `),Xo=W(`
            `),Zo=W(`· `,1),Qo=W(`
            `,1),$o=W(`
            `,1),es=W(`
              `),ts=W(`

                /

                `);function ns(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`decisions`,8);function o(e){return Q(e===`repository`?`scopeRepository`:e===`organization`?`scopeOrganization`:`scopeDisabled`,n())}function s(e){return Q(e===`guarded`?`approvalGuarded`:e===`recommend`?`approvalRecommend`:`approvalOff`,n())}Y();var c=ts(),l=P(c),u=I(l,!0),d=L(l,2),f=P(d),p=P(f),m=I(p,!0),h=I(L(p),!0);E(f);var g=L(f,2),_=P(g),v=I(_,!0),y=I(L(_),!0);E(g);var b=L(g,2),x=P(b),S=I(x,!0),C=L(x),ee=P(C);Qr(ee,5,()=>(U(a()),H(()=>a().agentRouting)),Jr,(e,t)=>{var r=Jo(),i=P(r),a=I(L(i));E(r),R(e=>{K(i,`${e??``}: `),K(a,`${V(t),H(()=>V(t).provider)??``} · ${V(t),H(()=>V(t).modelProvider)??``}/${V(t),H(()=>V(t).model)??``}`)},[()=>(U(qo),V(t),n(),H(()=>qo(V(t).role,n())))]),G(e,r)}),E(ee),E(C),E(b);var te=L(b,2),ne=P(te),re=I(ne,!0),ie=L(ne),ae=P(ie),oe=I(ae,!0),se=I(L(ae,2),!0);E(ie),E(te);var ce=L(te,2),le=P(ce),ue=I(le,!0),de=I(L(le),!0);E(ce);var fe=L(ce,2),pe=e=>{var t=$o(),r=F(t),i=P(r),o=I(i,!0),s=L(i),c=P(s),l=e=>{var t=Xo();Qr(t,5,()=>(U(a()),H(()=>a().trustedChecks)),Jr,(e,t)=>{var r=Yo(),i=P(r),a=I(i,!0),o=L(i),s=I(L(o),!0);E(r),R(e=>{K(a,(V(t),H(()=>V(t).name))),K(o,` · ${e??``} ${V(t),H(()=>V(t).sourceAppId)??``} · `),K(s,(V(t),H(()=>V(t).workflowName)))},[()=>(U(Q),n(),H(()=>Q(`producerAppId`,n())))]),G(e,r)}),E(t),G(e,t)},u=e=>{var t=jr();R(e=>K(t,e),[()=>(U(Q),n(),H(()=>Q(`none`,n())))]),G(e,t)};q(c,e=>{U(a()),H(()=>a().trustedChecks.length)?e(l):e(u,-1)}),E(s),E(r);var d=L(r,2),f=P(d),p=I(f,!0),m=I(L(f),!0);E(d);var h=L(d,2),g=P(h),_=I(g,!0),v=L(g),y=P(v,!0),b=L(y),x=e=>{var t=Zo(),n=I(L(F(t)),!0);R(()=>K(n,(U(a()),H(()=>a().coverageCheck)))),G(e,t)};q(b,e=>{U(a()),H(()=>a().coverageCheck)&&e(x)}),E(v),E(h);var S=L(h,2),C=e=>{var t=Qo(),r=F(t),i=P(r),o=I(i,!0),s=I(L(i),!0);E(r);var c=L(r,2),l=P(c),u=I(l,!0),d=L(l),f=I(P(d),!0);E(d),E(c);var p=L(c,2),m=P(p),h=I(m,!0),g=I(L(m),!0);E(p),R((e,t,n,r,i,a)=>{K(o,e),K(s,t),K(u,n),K(f,r),K(h,i),K(g,a)},[()=>(U(Q),n(),H(()=>Q(`planCoverageThreshold`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().coverageMinimum===void 0?Q(`none`,n()):`${a().coverageMinimum}%`)),()=>(U(Q),n(),H(()=>Q(`planCoverageReporter`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().coverageArtifactWorkflow||Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planReporterAttested`,n()))),()=>(U(Q),U(a()),n(),H(()=>Q(a().coverageReporterAttested?`yes`:`no`,n())))]),G(e,t)};q(S,e=>{U(a()),H(()=>a().coverageMode===`numeric`)&&e(C)}),R((e,t,n,r,i)=>{K(o,e),K(p,t),K(m,n),K(_,r),K(y,i)},[()=>(U(Q),n(),H(()=>Q(`planTrustedChecks`,n()))),()=>(U(Q),n(),H(()=>Q(`planProducerAttested`,n()))),()=>(U(Q),U(a()),n(),H(()=>Q(a().producerAttested?`yes`:`no`,n()))),()=>(U(Q),n(),H(()=>Q(`planCoverage`,n()))),()=>(U(ma),U(a()),n(),H(()=>ma(`pullRequestApproval.coverage.mode`,a().coverageMode,n())))]),G(e,t)};q(fe,e=>{U(a()),H(()=>a().approvalMode!==`off`)&&e(pe)});var me=L(fe,2),he=P(me),ge=I(he,!0),_e=I(L(he),!0);E(me);var ve=L(me,2),ye=e=>{var t=es(),r=P(t),i=I(r,!0),o=L(r),s=P(o);Qr(s,5,()=>(U(a()),H(()=>a().projectStatuses)),Jr,(e,t)=>{var r=Jo(),i=P(r),a=I(L(i),!0);E(r),R(e=>{K(i,`${e??``}: `),K(a,(V(t),H(()=>V(t).value)))},[()=>(U(Q),U(Ia),V(t),n(),H(()=>Q(Ia[V(t).transition],n())))]),G(e,r)}),E(s),E(o),E(t),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`planProjectStatuses`,n())))]),G(e,t)};q(ve,e=>{U(a()),H(()=>a().projectNumbers.length)&&e(ye)});var be=L(ve,2),xe=P(be),Se=I(xe,!0),Ce=I(L(xe),!0);E(be);var we=L(be,2),Te=P(we),w=I(Te,!0),Ee=I(L(Te),!0);E(we);var T=L(we,2),De=P(T),Oe=I(De,!0),ke=I(L(De),!0);E(T);var Ae=L(T,2),je=P(Ae),Me=I(je,!0),Ne=I(L(je),!0);E(Ae),E(d);var Pe=I(L(d,2),!0);E(c),R((e,t,n,r,i,o,s,c,l,d,f,p,g,_,b,x,C,ee,te,ne)=>{K(u,e),K(m,t),K(h,n),K(v,r),K(y,i),K(S,o),K(re,s),K(oe,(U(a()),H(()=>a().productionBranch))),K(se,(U(a()),H(()=>a().developmentBranch))),K(ue,c),K(de,l),K(ge,d),K(_e,f),K(Se,p),K(Ce,g),K(w,_),K(Ee,b),K(Oe,x),K(ke,C),K(Me,ee),K(Ne,te),K(Pe,ne)},[()=>(U(Q),n(),H(()=>Q(`planChoices`,n()))),()=>(U(Q),n(),H(()=>Q(`planEnabledCapabilities`,n()))),()=>(U(a()),U(Go),n(),U(Q),H(()=>a().enabledCapabilities.length?a().enabledCapabilities.map(e=>Go(e,n())).join(`, `):Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planIssueWorkflows`,n()))),()=>(U(a()),U(ma),n(),U(Q),H(()=>a().issueWorkflows.length?a().issueWorkflows.map(e=>ma(`issueWorkflows.enabled`,e,n())).join(`, `):Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planAgentRouting`,n()))),()=>(U(Q),n(),H(()=>Q(`planBranchRoles`,n()))),()=>(U(Q),n(),H(()=>Q(`planApprovalMode`,n()))),()=>(U(a()),H(()=>s(a().approvalMode))),()=>(U(Q),n(),H(()=>Q(`editProjects`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().projectNumbers.length?a().projectNumbers.map(e=>`#${e}`).join(`, `):Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planVariableScope`,n()))),()=>(U(a()),H(()=>o(a().variableScope))),()=>(U(Q),n(),H(()=>Q(`planSecretScope`,n()))),()=>(U(a()),H(()=>o(a().secretScope))),()=>(U(Q),n(),H(()=>Q(`planIssueResources`,n()))),()=>(U(Q),n(),H(()=>Q(`planIssueResourcesValue`,n()))),()=>(U(Q),n(),H(()=>Q(`planInitialTag`,n()))),()=>(U(Q),U(a()),n(),H(()=>Q(a().initialTag?`yes`:`no`,n()))),()=>(U(Q),n(),H(()=>Q(`planAdvancedDefaults`,n())))]),G(e,c),k(),i()}var rs=W(`
              • `),is=W(`

                  `),as=W(`
                • `),os=W(`

                    `),ss=W(`

                      `),cs=W(``),ls=W(`

                      `),us=W(`

                      `,1);function ds(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`prompt`,8),s=Z(t,`controller`,8),c=Z(t,`busy`,8),l=Z(t,`onSubmit`,8),u={capabilities:`editCapabilities`,"agent-runtime":`editRuntimes`,"agent-model-defaults":`editModels`,"agent-role-overrides":`editRoleModels`,repository:`editRepository`,deployment:`editDeployment`,bugbot:`editBugbot`,"pull-request-approval":`editApproval`,projects:`editProjects`,provisioning:`editProvisioning`,storage:`editStorage`};Tn(()=>(n(),U(o())),()=>{N(a,[{title:Q(`files`,n()),items:o().plan.files},{title:Q(`workflows`,n()),items:o().plan.workflows},{title:Q(`variables`,n()),items:o().plan.variables},{title:Q(`secretNames`,n()),items:o().plan.secrets}])}),En(),Y();var d=us(),f=F(d),p=I(f,!0),m=L(f,2);ns(m,{get decisions(){return U(o()),H(()=>o().plan.decisions)}});var h=L(m,2),g=e=>{var t=is(),r=P(t),i=I(r,!0),a=L(r,2);Qr(a,5,()=>(U(o()),H(()=>o().plan.presentationDefaults)),Jr,(e,t)=>{var r=rs(),i=I(r);R(e=>K(i,`${e??``}: ${V(t),H(()=>V(t).count)??``}`),[()=>(V(t),U(Q),n(),H(()=>u[V(t).group]?Q(u[V(t).group],n()):V(t).group))]),G(e,r)}),E(a),E(t),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`planBasicDefaultsIntro`,n())))]),G(e,t)};q(h,e=>{U(o()),H(()=>o().plan.presentationDefaults.length)&&e(g)});var _=L(h,2);Qr(_,5,()=>V(a),Jr,(e,t)=>{var n=os(),r=P(n),i=P(r),a=I(L(i),!0);E(r);var o=L(r);Qr(o,5,()=>(V(t),H(()=>V(t).items)),Jr,(e,t)=>{var n=as(),r=I(P(n),!0);E(n),R(()=>K(r,V(t))),G(e,n)}),E(o),E(n),R(()=>{K(i,`${V(t),H(()=>V(t).title)??``} `),K(a,(V(t),H(()=>V(t).items.length)))}),G(e,n)}),E(_);var v=L(_,2),y=e=>{var t=ss(),r=P(t),i=I(r,!0),a=L(r);Qr(a,5,()=>(U(o()),H(()=>o().plan.warnings)),Jr,(e,t)=>{var r=rs(),i=I(r,!0);R(e=>K(i,e),[()=>(U(Uo),V(t),n(),H(()=>Uo(V(t),n())))]),G(e,r)}),E(a),E(t),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`beforeContinue`,n())))]),G(e,t)};q(v,e=>{U(o()),H(()=>o().plan.warnings.length)&&e(y)});var b=L(v,2),x=e=>{var t=ls(),r=P(t),i=I(r,!0),a=L(r),d=I(a,!0),f=L(a,2);Qr(f,5,()=>(U(o()),H(()=>o().editGroups)),Jr,(e,t)=>{var r=cs(),i=I(r,!0);R(e=>{r.disabled=!s()||c(),K(i,e)},[()=>(U(Q),n(),V(t),H(()=>Q(`changeSection`,n(),{section:Q(u[V(t)],n())})))]),Sr(`click`,r,()=>l()(`revise:${V(t)}`)),G(e,r)}),E(f),E(t),R((e,t)=>{K(i,e),K(d,t)},[()=>(U(Q),n(),H(()=>Q(`changeAnswersTitle`,n()))),()=>(U(Q),n(),H(()=>Q(`changeAnswersHelp`,n())))]),G(e,t)};q(b,e=>{U(o()),H(()=>o().editGroups?.length)&&e(x)});var S=L(b,2),C=P(S);{let e=A(()=>(U(Q),n(),H(()=>Q(`stopHere`,n())))),t=A(()=>!s()||c());ka(C,{get label(){return V(e)},variant:`secondary`,onClick:()=>l()(`decline`),get disabled(){return V(t)}})}var ee=L(C);{let e=A(()=>(U(Q),n(),H(()=>Q(`approvePlan`,n())))),t=A(()=>!s()||c());ka(ee,{get label(){return V(e)},arrow:!0,onClick:()=>l()(`approve`),get disabled(){return V(t)}})}E(S),R(e=>K(p,e),[()=>(U(Q),n(),H(()=>Q(`planBody`,n())))]),G(e,d),k(),i()}Cr([`click`]);function fs(e,t){let n=t,r=!0,i=()=>queueMicrotask(()=>{r&&e.isConnected&&e.focus({preventScroll:!0})});return i(),{update(e){e!==n&&(n=e,i())},destroy(){r=!1}}}var ps=W(`

                      `),ms=W(`

                      `),hs=W(`
                      `);function gs(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`prompt`,8),s=Z(t,`revision`,8),c=Z(t,`promptRevision`,8),l=Z(t,`controller`,8),u=Z(t,`busy`,8),d=Z(t,`onSubmit`,8),f=Z(t,`onRetryDiscovery`,8),p=Z(t,`onBack`,8);Tn(()=>(U(o()),n()),()=>{N(a,ya(o(),n()))}),En(),Y();var m=hs(),h=P(m),g=P(h),_=I(g,!0),v=I(L(g));E(h);var y=L(h,2),b=e=>{var t=ps(),n=I(t,!0);R(()=>K(n,(V(a),U(o()),H(()=>V(a)?.title??o().title)))),G(e,t)};q(y,e=>{U(o()),H(()=>o().kind!==`question`)&&e(b)});var x=L(y,2),S=e=>{var t=ms(),n=I(t,!0);R(()=>K(n,(V(a),U(o()),H(()=>V(a)?.description??(`description`in o()?o().description:``))))),G(e,t)};q(x,e=>{V(a),U(o()),H(()=>V(a)?.description||`description`in o()&&o().description)&&e(S)}),qr(L(x,2),c,e=>{var t=Mr(),n=F(t),r=e=>{No(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()},get onRetryDiscovery(){return f()},get onBack(){return p()}})},i=e=>{Io(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},a=e=>{Bo(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},s=e=>{ds(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})};q(n,e=>{U(o()),H(()=>o().kind===`question`)?e(r):(U(o()),H(()=>o().kind===`choice`||o().kind===`confirm`)?e(i,1):(U(o()),H(()=>o().kind===`text`||o().kind===`secret`)?e(a,2):(U(o()),H(()=>o().kind===`plan`)&&e(s,3))))}),G(e,t)}),E(m),ii(m,(e,t)=>fs?.(e,t),c),R((e,t,n)=>{J(m,`aria-label`,e),K(_,t),K(v,`${n??``} ${s()??``}`)},[()=>(U(Q),n(),H(()=>Q(`currentDecision`,n()))),()=>(U(Q),n(),H(()=>Q(`currentDecision`,n()))),()=>(U(Q),n(),H(()=>Q(`session`,n())))]),G(e,m),k(),i()}var _s={Metadata:`Metadata`,Contents:`Contents`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Issues`,Actions:`Actions`,Checks:`Checks`,Administration:`Administration`,Workflows:`Workflows`,"Issue Types":`Issue Types`,Projects:`Projects`,"Pull requests":`Pull requests`,Members:`Members`},vs={repository:`repository`,organization:`organization`,read:`Read`,write:`Write`,required:`Required`,conditional:`Conditional`,verified:`Verified`,missing:`Missing`,unverifiable:`Unverifiable`},ys={Metadata:`Metadatos`,Contents:`Contenido`,Secrets:`Secretos`,Variables:`Variables`,Issues:`Incidencias`,Actions:`Acciones`,Checks:`Comprobaciones`,Administration:`Administración`,Workflows:`Flujos de trabajo`,"Issue Types":`Tipos de incidencia`,Projects:`Proyectos`,"Pull requests":`Solicitudes de cambio`,Members:`Miembros`},bs={repository:`repositorio`,organization:`organización`,read:`Lectura`,write:`Escritura`,required:`Obligatorio`,conditional:`Condicional`,verified:`Verificado`,missing:`Faltante`,unverifiable:`No verificable`},xs={Metadata:`Métadonnées`,Contents:`Contenu`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Tickets`,Actions:`Actions`,Checks:`Vérifications`,Administration:`Administration`,Workflows:`Flux de travail`,"Issue Types":`Types de ticket`,Projects:`Projets`,"Pull requests":`Demandes de tirage`,Members:`Membres`},Ss={repository:`dépôt`,organization:`organisation`,read:`Lecture`,write:`Écriture`,required:`Obligatoire`,conditional:`Conditionnel`,verified:`Vérifié`,missing:`Manquant`,unverifiable:`Non vérifiable`},Cs={Metadata:`Metadados`,Contents:`Conteúdo`,Secrets:`Segredos`,Variables:`Variáveis`,Issues:`Questões`,Actions:`Ações`,Checks:`Verificações`,Administration:`Administração`,Workflows:`Fluxos de trabalho`,"Issue Types":`Tipos de questão`,Projects:`Projetos`,"Pull requests":`Pedidos de alteração`,Members:`Membros`},ws={repository:`repositório`,organization:`organização`,read:`Leitura`,write:`Escrita`,required:`Obrigatório`,conditional:`Condicional`,verified:`Verificado`,missing:`Em falta`,unverifiable:`Não verificável`},Ts={en:_s,es:ys,fr:xs,pt:Cs},Es={en:vs,es:bs,fr:Ss,pt:ws};function Ds(e,t){return Es[e][t]}function Os(e,t){return Object.prototype.hasOwnProperty.call(Ts[e],t)?Ts[e][t]:t}function ks(e,t){if(t===`verified`||t===`missing`||t===`unverifiable`)return Es[e][t]}var As=`Resolve repository identity and visibility.(Inspect installed workflows and repository files.(Inspect and provision selected GitHub Actions Secrets.(Inspect and provision selected GitHub Actions Variables.(Provision labels and issue resources.(Inspect and dispatch credential-health workflows.(Inspect CI workflow runs and jobs for exact producer identities.(Discover exact CI check and producer identities.(Inspect branch protection and rulesets.(Bootstrap a missing credential-health workflow.(Inspect and provision organization Actions Secrets.(Inspect and provision organization Actions Variables.(Provision and assign configured issue types.(Inspect selected Projects and their Status options; setup does not edit Project items.(Create the initial repository tag when no version tag exists.(Inspect and provision selected repository Actions Secrets.(Inspect and provision selected repository Actions Variables.(Provision labels for the selected issue workflows.(Dispatch credential-health checks for existing Secrets.(Inspect CI workflow runs and jobs for approval evidence.(Temporarily install credential health when its workflow is not confirmed installed.(Inspect branch protection and effective rulesets.(Inspect and provision selected organization Actions Secrets.(Inspect and provision selected organization Actions Variables.(Provision native issue types for the selected workflows.(Resolve repository and collaborator metadata.(Dispatch selected release or hotfix workflows and check previous runs.(Check previous workflow runs before executing an enabled route.(Create managed branches, edit files, or merge selected release/hotfix changes.(Manage selected issue lifecycles, comments, and progress.(Manage selected pull request workflows, reviews, or autofix.(Verify current-head required checks and producer identities.(Load the guarded approval policy.(Select or authorize organization members for enabled workflows.(Assign configured organization issue types.(Update selected organization Projects.(Load the organization-scoped approval policy.(Secret provisioning enabled(Variable provisioning enabled(Issue workflows enabled(Credential health enabled(Pull-request approval enabled(Release, hotfix, or guarded approval enabled(Temporary health workflow required(Organization Secret storage selected(Organization Variable storage selected(Issue type automation enabled(Organization Projects selected`.split(`(`),js={"Resolve repository identity and visibility.":`Comprobar la identidad y visibilidad del repositorio.`,"Inspect installed workflows and repository files.":`Examinar los workflows instalados y los archivos del repositorio.`,"Inspect and provision selected GitHub Actions Secrets.":`Examinar y configurar los Secrets de GitHub Actions seleccionados.`,"Inspect and provision selected GitHub Actions Variables.":`Examinar y configurar las Variables de GitHub Actions seleccionadas.`,"Provision labels and issue resources.":`Crear etiquetas y recursos de issues.`,"Inspect and dispatch credential-health workflows.":`Examinar y ejecutar los workflows de comprobación de credenciales.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examinar ejecuciones y jobs de CI para identificar sus productores exactos.`,"Discover exact CI check and producer identities.":`Identificar los checks de CI y sus productores exactos.`,"Inspect branch protection and rulesets.":`Examinar la protección de ramas y sus reglas.`,"Bootstrap a missing credential-health workflow.":`Instalar provisionalmente el workflow de comprobación de credenciales que falta.`,"Inspect and provision organization Actions Secrets.":`Examinar y configurar Secrets de Actions en la organización.`,"Inspect and provision organization Actions Variables.":`Examinar y configurar Variables de Actions en la organización.`,"Provision and assign configured issue types.":`Crear y asignar los tipos de issue configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar los Projects seleccionados y sus opciones de Status; el setup no modifica los elementos de los Projects.`,"Create the initial repository tag when no version tag exists.":`Crear el tag inicial si el repositorio aún no tiene ninguno de versión.`,"Inspect and provision selected repository Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en el repositorio.`,"Inspect and provision selected repository Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en el repositorio.`,"Provision labels for the selected issue workflows.":`Crear las etiquetas de los flujos de issues seleccionados.`,"Dispatch credential-health checks for existing Secrets.":`Ejecutar comprobaciones de credenciales para los Secrets existentes.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examinar ejecuciones y jobs de CI como prueba para la aprobación.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporalmente la comprobación de credenciales si su workflow no está confirmado.`,"Inspect branch protection and effective rulesets.":`Examinar la protección de ramas y las reglas efectivas.`,"Inspect and provision selected organization Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en la organización.`,"Inspect and provision selected organization Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en la organización.`,"Provision native issue types for the selected workflows.":`Crear tipos de issue nativos para los flujos seleccionados.`,"Resolve repository and collaborator metadata.":`Consultar los metadatos del repositorio y sus colaboradores.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Ejecutar los flujos de release o hotfix seleccionados y comprobar ejecuciones anteriores.`,"Check previous workflow runs before executing an enabled route.":`Comprobar ejecuciones anteriores antes de iniciar un flujo habilitado.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Crear ramas gestionadas, editar archivos o integrar cambios de release y hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gestionar el ciclo de vida, los comentarios y el progreso de los issues seleccionados.`,"Manage selected pull request workflows, reviews, or autofix.":`Gestionar flujos de pull requests, revisiones o correcciones automáticas.`,"Verify current-head required checks and producer identities.":`Verificar los checks obligatorios y productores del commit actual.`,"Load the guarded approval policy.":`Leer la política de aprobación protegida.`,"Select or authorize organization members for enabled workflows.":`Seleccionar o autorizar miembros de la organización para los flujos activos.`,"Assign configured organization issue types.":`Asignar los tipos de issue configurados en la organización.`,"Update selected organization Projects.":`Actualizar los Projects seleccionados de la organización.`,"Load the organization-scoped approval policy.":`Leer la política de aprobación guardada en la organización.`,"Secret provisioning enabled":`Configuración de Secrets activada`,"Variable provisioning enabled":`Configuración de Variables activada`,"Issue workflows enabled":`Flujos de issues activados`,"Credential health enabled":`Comprobación de credenciales activada`,"Pull-request approval enabled":`Aprobación de pull requests activada`,"Release, hotfix, or guarded approval enabled":`Release, hotfix o aprobación protegida activados`,"Temporary health workflow required":`Hace falta un workflow temporal de comprobación`,"Organization Secret storage selected":`Se eligió guardar Secrets en la organización`,"Organization Variable storage selected":`Se eligió guardar Variables en la organización`,"Issue type automation enabled":`Automatización de tipos de issue activada`,"Organization Projects selected":`Se seleccionaron Projects de la organización`},Ms={"Resolve repository identity and visibility.":`Vérifier l’identité et la visibilité du dépôt.`,"Inspect installed workflows and repository files.":`Examiner les workflows installés et les fichiers du dépôt.`,"Inspect and provision selected GitHub Actions Secrets.":`Examiner et configurer les Secrets GitHub Actions choisis.`,"Inspect and provision selected GitHub Actions Variables.":`Examiner et configurer les Variables GitHub Actions choisies.`,"Provision labels and issue resources.":`Créer des étiquettes et des ressources pour les tickets.`,"Inspect and dispatch credential-health workflows.":`Examiner et lancer les workflows de vérification des identifiants.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examiner les exécutions et jobs CI pour identifier exactement leurs producteurs.`,"Discover exact CI check and producer identities.":`Identifier précisément les vérifications CI et leurs producteurs.`,"Inspect branch protection and rulesets.":`Examiner la protection des branches et les ensembles de règles.`,"Bootstrap a missing credential-health workflow.":`Installer provisoirement le workflow de vérification des identifiants manquant.`,"Inspect and provision organization Actions Secrets.":`Examiner et configurer les Secrets Actions de l’organisation.`,"Inspect and provision organization Actions Variables.":`Examiner et configurer les Variables Actions de l’organisation.`,"Provision and assign configured issue types.":`Créer et attribuer les types de ticket configurés.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consulter les Projects sélectionnés et leurs options Status ; la configuration ne modifie aucun élément de Project.`,"Create the initial repository tag when no version tag exists.":`Créer le tag initial si le dépôt ne possède encore aucun tag de version.`,"Inspect and provision selected repository Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans le dépôt.`,"Inspect and provision selected repository Actions Variables.":`Examiner et configurer les Variables Actions choisies dans le dépôt.`,"Provision labels for the selected issue workflows.":`Créer les étiquettes des workflows de ticket choisis.`,"Dispatch credential-health checks for existing Secrets.":`Lancer des vérifications d’identifiants pour les Secrets existants.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examiner les exécutions et jobs CI comme preuve pour l’approbation.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Installer provisoirement la vérification des identifiants si son workflow n’est pas confirmé.`,"Inspect branch protection and effective rulesets.":`Examiner la protection des branches et les règles applicables.`,"Inspect and provision selected organization Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans l’organisation.`,"Inspect and provision selected organization Actions Variables.":`Examiner et configurer les Variables Actions choisies dans l’organisation.`,"Provision native issue types for the selected workflows.":`Créer des types de ticket natifs pour les workflows choisis.`,"Resolve repository and collaborator metadata.":`Consulter les métadonnées du dépôt et de ses collaborateurs.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Lancer les workflows de version ou correctif urgent choisis et vérifier les exécutions précédentes.`,"Check previous workflow runs before executing an enabled route.":`Vérifier les exécutions précédentes avant de lancer un parcours activé.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Créer des branches gérées, modifier des fichiers ou fusionner les changements de version et correctif.`,"Manage selected issue lifecycles, comments, and progress.":`Gérer le cycle de vie, les commentaires et la progression des tickets choisis.`,"Manage selected pull request workflows, reviews, or autofix.":`Gérer les workflows de pull request, les revues ou les corrections automatiques.`,"Verify current-head required checks and producer identities.":`Vérifier les contrôles requis et leurs producteurs pour le commit courant.`,"Load the guarded approval policy.":`Lire la politique d’approbation encadrée.`,"Select or authorize organization members for enabled workflows.":`Sélectionner ou autoriser des membres de l’organisation pour les workflows activés.`,"Assign configured organization issue types.":`Attribuer les types de ticket configurés dans l’organisation.`,"Update selected organization Projects.":`Mettre à jour les projets de l’organisation choisis.`,"Load the organization-scoped approval policy.":`Lire la politique d’approbation stockée dans l’organisation.`,"Secret provisioning enabled":`Configuration des Secrets activée`,"Variable provisioning enabled":`Configuration des Variables activée`,"Issue workflows enabled":`Workflows de ticket activés`,"Credential health enabled":`Vérification des identifiants activée`,"Pull-request approval enabled":`Approbation des pull requests activée`,"Release, hotfix, or guarded approval enabled":`Version, correctif urgent ou approbation encadrée activés`,"Temporary health workflow required":`Workflow temporaire de vérification requis`,"Organization Secret storage selected":`Stockage des Secrets dans l’organisation choisi`,"Organization Variable storage selected":`Stockage des Variables dans l’organisation choisi`,"Issue type automation enabled":`Automatisation des types de ticket activée`,"Organization Projects selected":`Projets de l’organisation choisis`},Ns={"Resolve repository identity and visibility.":`Verificar a identidade e visibilidade do repositório.`,"Inspect installed workflows and repository files.":`Inspecionar os fluxos instalados e os ficheiros do repositório.`,"Inspect and provision selected GitHub Actions Secrets.":`Inspecionar e configurar os Secrets do GitHub Actions selecionados.`,"Inspect and provision selected GitHub Actions Variables.":`Inspecionar e configurar as Variables do GitHub Actions selecionadas.`,"Provision labels and issue resources.":`Criar etiquetas e recursos para questões.`,"Inspect and dispatch credential-health workflows.":`Inspecionar e executar os fluxos de verificação de credenciais.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Inspecionar execuções e jobs CI para identificar exatamente os seus produtores.`,"Discover exact CI check and producer identities.":`Identificar as verificações CI e os seus produtores exatos.`,"Inspect branch protection and rulesets.":`Inspecionar a proteção de ramos e os conjuntos de regras.`,"Bootstrap a missing credential-health workflow.":`Instalar temporariamente o fluxo de verificação de credenciais em falta.`,"Inspect and provision organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions da organização.`,"Inspect and provision organization Actions Variables.":`Inspecionar e configurar as Variables de Actions da organização.`,"Provision and assign configured issue types.":`Criar e atribuir os tipos de questão configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar os Projects selecionados e as suas opções de Status; a configuração não altera os itens dos Projects.`,"Create the initial repository tag when no version tag exists.":`Criar a etiqueta inicial se o repositório ainda não tiver etiquetas de versão.`,"Inspect and provision selected repository Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados no repositório.`,"Inspect and provision selected repository Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas no repositório.`,"Provision labels for the selected issue workflows.":`Criar etiquetas para os fluxos de questões selecionados.`,"Dispatch credential-health checks for existing Secrets.":`Executar verificações de credenciais para os Secrets existentes.`,"Inspect CI workflow runs and jobs for approval evidence.":`Inspecionar execuções e jobs CI como prova para aprovação.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporariamente a verificação de credenciais se o fluxo não estiver confirmado.`,"Inspect branch protection and effective rulesets.":`Inspecionar a proteção de ramos e as regras aplicáveis.`,"Inspect and provision selected organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados na organização.`,"Inspect and provision selected organization Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas na organização.`,"Provision native issue types for the selected workflows.":`Criar tipos de questão nativos para os fluxos selecionados.`,"Resolve repository and collaborator metadata.":`Consultar os metadados do repositório e dos colaboradores.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Executar os fluxos de release ou hotfix selecionados e verificar execuções anteriores.`,"Check previous workflow runs before executing an enabled route.":`Verificar execuções anteriores antes de iniciar um percurso ativo.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Criar ramos geridos, editar ficheiros ou integrar alterações de release e hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gerir o ciclo de vida, os comentários e o progresso das questões selecionadas.`,"Manage selected pull request workflows, reviews, or autofix.":`Gerir fluxos de pull requests, revisões ou correções automáticas.`,"Verify current-head required checks and producer identities.":`Verificar as verificações obrigatórias e os produtores do commit atual.`,"Load the guarded approval policy.":`Ler a política de aprovação protegida.`,"Select or authorize organization members for enabled workflows.":`Selecionar ou autorizar membros da organização para os fluxos ativos.`,"Assign configured organization issue types.":`Atribuir os tipos de questão configurados na organização.`,"Update selected organization Projects.":`Atualizar os Projetos selecionados da organização.`,"Load the organization-scoped approval policy.":`Ler a política de aprovação guardada na organização.`,"Secret provisioning enabled":`Configuração de Secrets ativa`,"Variable provisioning enabled":`Configuração de Variables ativa`,"Issue workflows enabled":`Fluxos de questões ativos`,"Credential health enabled":`Verificação de credenciais ativa`,"Pull-request approval enabled":`Aprovação de pull requests ativa`,"Release, hotfix, or guarded approval enabled":`Release, hotfix ou aprovação protegida ativos`,"Temporary health workflow required":`É necessário um fluxo temporário de verificação`,"Organization Secret storage selected":`Armazenamento dos Secrets na organização selecionado`,"Organization Variable storage selected":`Armazenamento das Variables na organização selecionado`,"Issue type automation enabled":`Automatização de tipos de questão ativa`,"Organization Projects selected":`Projetos da organização selecionados`},Ps=new Set(As),Fs={es:js,fr:Ms,pt:Ns};function Is(e,t){return e===`en`?t:Ps.has(t)?Fs[e][t]:Q(`permissionUnknown`,e)}var Ls=W(` `),Rs=W(` `),zs=W(`
                    • `),Bs=W(`

                        `),Vs=W(`

                        `),Hs=W(``);function Us(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`view`,8);Y();var o=Hs(),s=P(o),c=L(P(s)),l=I(c,!0),u=L(c),d=I(u,!0),f=L(u),p=I(P(f),!0);E(f),E(s);var m=L(s,2),h=e=>{var t=Bs(),r=L(P(t)),i=I(r),o=L(r),s=I(o,!0),c=L(o,2);Qr(c,5,()=>(U(a()),H(()=>a().permissions.report?.checks??a().permissions.requirements??[])),Jr,(e,t)=>{var r=zs(),i=P(r),a=P(i,!0),o=L(a),s=e=>{var n=Ls(),r=I(P(n));E(n),R(()=>K(r,`GitHub · ${V(t),H(()=>V(t).permission)??``}`)),G(e,n)},c=gt(()=>(n(),U(Os),V(t),H(()=>n()!==`en`&&Os(n(),V(t).permission)!==V(t).permission)));q(o,e=>{V(c)&&e(s)});var l=L(o),u=I(l),d=L(l),f=I(d,!0),p=L(d),m=e=>{var r=Rs(),i=I(r,!0);R(e=>K(i,e),[()=>(U(Is),n(),V(t),H(()=>Is(n(),V(t).condition)))]),G(e,r)};q(p,e=>{V(t),H(()=>V(t).condition)&&e(m)}),E(i);var h=L(i),g=P(h,!0),_=L(g),v=e=>{var r=Rs(),i=I(r,!0);R(e=>K(i,e),[()=>(U(ks),n(),V(t),H(()=>ks(n(),V(t).status)))]),G(e,r)},y=gt(()=>(V(t),U(ks),n(),H(()=>`status`in V(t)&&ks(n(),V(t).status))));q(_,e=>{V(y)&&e(v)}),E(h),E(r),R((e,t,n,r,i)=>{K(a,e),K(u,`${t??``} · ${n??``}`),K(f,r),K(g,i)},[()=>(U(Os),n(),V(t),H(()=>Os(n(),V(t).permission))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).scope))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).applicability))),()=>(U(Is),n(),V(t),H(()=>Is(n(),V(t).reason))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).level)))]),G(e,r)}),E(c);var l=I(L(c,2),!0);E(t),R((e,t,n,r)=>{K(i,`${e??``} ${t??``}`),K(s,n),K(l,r)},[()=>(U(a()),U(Q),n(),H(()=>a().permissions.role===`setup`?Q(`setupPat`,n()):Q(`botPat`,n()))),()=>(U(Q),n(),H(()=>Q(`access`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().permissions.report?Q(`readOnlyCheck`,n()):Q(`provisionalGrants`,n()))),()=>(U(Q),n(),H(()=>Q(`conditionalGrants`,n())))]),G(e,t)},g=e=>{var t=Vs(),r=L(P(t)),i=I(r,!0),a=I(L(r),!0);E(t),R((e,t)=>{K(i,e),K(a,t)},[()=>(U(Q),n(),H(()=>Q(`permissionsFollow`,n()))),()=>(U(Q),n(),H(()=>Q(`permissionsFollowBody`,n())))]),G(e,t)};q(m,e=>{U(a()),H(()=>a().permissions)?e(h):e(g,-1)}),E(o),R((e,t,n)=>{J(o,`aria-label`,e),K(l,t),K(d,n),K(p,(U(a()),H(()=>a().repository)))},[()=>(U(Q),n(),H(()=>Q(`setup`,n()))),()=>(U(Q),n(),H(()=>Q(`repoFocus`,n()))),()=>(U(Q),n(),H(()=>Q(`repoFocusBody`,n())))]),G(e,o),k(),i()}var Ws=W(`
                      • `),Gs=W(`

                          `);function Ks(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`effects`,8),o={files:`receiptFiles`,secrets:`receiptSecrets`,labels:`receiptLabels`,"issue-types":`receiptIssueTypes`,variables:`receiptVariables`,"initial-tag":`receiptInitialTag`},s={completed:`effectCompleted`,skipped:`effectSkipped`,"needs-inspection":`effectInspect`,"not-started":`effectNotStarted`,"in-progress":`effectInProgress`},c={local:`scopeLocal`,repository:`scopeRepository`,organization:`scopeOrganization`,mixed:`scopeMixed`};Y();var l=Gs(),u=P(l),d=I(u,!0),f=L(u,2);Qr(f,5,a,e=>e.id,(e,t)=>{var r=Ws(),i=P(r),a=I(i,!0),l=L(i),u=L(l),d=e=>{var r=jr();R(e=>K(r,`· ${e??``}`),[()=>(U(Q),V(t),n(),H(()=>Q(c[V(t).scope],n())))]),G(e,r)};q(u,e=>{V(t),H(()=>V(t).scope)&&e(d)}),E(r),R((e,t)=>{K(a,e),K(l,` — ${t??``}`)},[()=>(V(t),U(Q),n(),H(()=>o[V(t).id]?Q(o[V(t).id],n()):V(t).id)),()=>(U(Q),V(t),n(),H(()=>Q(s[V(t).state],n())))]),G(e,r)}),E(f),E(l),R(e=>K(d,e),[()=>(U(Q),n(),H(()=>Q(`resourceReceipt`,n())))]),G(e,l),k(),i()}var qs=W(`

                          `),Js=W(`

                          `),Ys=W(`

                          `),Xs=W(` `),Zs=W(`
                        • `),Qs=W(`
                            `),$s=W(`

                            `),ec=W(`

                            `),tc=W(`
                            `),nc=W(`

                            `);function rc(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=M(),c=M(),l=Z(t,`outcome`,8),u=Z(t,`controller`,8),d=Z(t,`onClose`,8),f=Z(t,`onDoctor`,8,async()=>void 0),p=Z(t,`doctor`,8,void 0),m=Z(t,`detail`,8,void 0),h=Z(t,`permissionReport`,8,void 0),g={permissions:[`reasonPermissions`,`nextPermissions`],storage:[`reasonStorage`,`nextStorage`],configuration:[`reasonConfiguration`,`nextConfiguration`],"session-expired":[`reasonExpired`,`nextExpired`],cancelled:[`reasonCancelled`,`nextCancelled`],provider:[`reasonProvider`,`nextProvider`],"rate-limit":[`reasonRateLimit`,`nextRateLimit`],unknown:[`reasonUnknown`,`nextUnknown`]};Tn(()=>(U(l()),n()),()=>{N(a,l()===`complete`?Q(`resultApplied`,n()):l()===`dry-run`?Q(`resultNoChanges`,n()):l()===`cancelled`||l()===`blocked`?Q(`resultStopped`,n()):Q(`resultPartial`,n()))}),Tn(()=>(U(l()),n()),()=>{N(o,l()===`complete`?Q(`resultCompleteBody`,n()):l()===`partial`?Q(`resultPartialBody`,n()):Q(`resultNoChangesBody`,n()))}),Tn(()=>(U(l()),U(m()),U(h())),()=>{N(s,l()===`blocked`&&m()?.reasonCode===`permissions`?h():void 0)}),Tn(()=>V(s),()=>{N(c,V(s)?.identityStatus===`valid`?V(s).checks.filter(e=>e.applicability===`required`&&e.status!==`verified`&&e.operationallyAvailable!==!0):[])}),En(),Y();var _=nc(),v=P(_),y=I(v,!0),b=L(v),x=I(b,!0),S=L(b,2),C=e=>{var t=Ys(),r=P(t),i=P(r),a=I(i),o=L(i);E(r);var s=L(r,2),c=e=>{var t=qs(),r=P(t),i=I(r),a=L(r);E(t),R((e,t)=>{K(i,`${e??``}:`),K(a,` ${t??``}`)},[()=>(U(Q),n(),H(()=>Q(`progress`,n()))),()=>(U(qi),U(m()),n(),H(()=>qi(m().stoppedStage,n())))]),G(e,t)};q(s,e=>{U(m()),H(()=>m()?.stoppedStage)&&e(c)});var u=L(s,2),d=P(u),f=I(d),p=L(d);E(u);var h=L(u,2),_=P(h),v=I(_),y=L(_);E(h);var b=L(h,2),x=e=>{var t=Js(),r=P(t),i=I(r),a=I(L(r,2),!0);E(t),R(e=>{K(i,`${e??``}:`),K(a,(U(m()),H(()=>m().diagnosticRef)))},[()=>(U(Q),n(),H(()=>Q(`diagnosticReference`,n())))]),G(e,t)};q(b,e=>{U(m()),H(()=>m()?.diagnosticRef)&&e(x)}),E(t),R((e,t,n,r,i,s)=>{K(a,`${e??``}:`),K(o,` ${t??``}`),K(f,`${n??``}:`),K(p,` ${r??``}`),K(v,`${i??``}:`),K(y,` ${s??``}`)},[()=>(U(Q),n(),H(()=>Q(`whatHappened`,n()))),()=>(U(Q),U(m()),n(),H(()=>Q(g[m()?.reasonCode??`unknown`][0],n()))),()=>(U(Q),n(),H(()=>Q(`alreadyChanged`,n()))),()=>(U(m()),U(l()),U(Q),n(),H(()=>m()?.mutationStarted||l()===`partial`?Q(`inspectPartial`,n()):Q(`noChanges`,n()))),()=>(U(Q),n(),H(()=>Q(`nextAction`,n()))),()=>(U(l()),U(Q),n(),U(m()),H(()=>l()===`partial`?`${Q(`inspectPartial`,n())} ${Q(g[m()?.reasonCode??`unknown`][1],n())}`:Q(g[m()?.reasonCode??`unknown`][1],n())))]),G(e,t)};q(S,e=>{(l()===`blocked`||l()===`cancelled`||l()===`partial`)&&e(C)});var ee=L(S,2),te=e=>{var t=ec(),r=P(t),i=I(r,!0),a=L(r,2),o=I(a,!0),l=L(a,2),u=P(l),d=I(u),f=L(u);E(l);var p=L(l,2),m=e=>{var t=Qs();Qr(t,5,()=>V(c),Jr,(e,t)=>{var r=Zs(),i=P(r),a=I(i,!0),o=L(i),s=e=>{var n=Xs(),r=I(P(n));E(n),R(()=>K(r,`GitHub · ${V(t),H(()=>V(t).permission)??``}`)),G(e,n)},c=gt(()=>(n(),U(Os),V(t),H(()=>n()!==`en`&&Os(n(),V(t).permission)!==V(t).permission)));q(o,e=>{V(c)&&e(s)});var l=L(o),u=I(L(l),!0);E(r),R((e,t,n,r)=>{K(a,e),K(l,` — ${t??``} · ${n??``} · `),K(u,r)},[()=>(U(Os),n(),V(t),H(()=>Os(n(),V(t).permission))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).scope))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).level))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).status)))]),G(e,r)}),E(t),G(e,t)},h=e=>{var t=$s(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`permissionReportNoFailedGrant`,n())))]),G(e,t)};q(p,e=>{V(c),H(()=>V(c).length)?e(m):(V(s),H(()=>V(s).identityStatus===`valid`)&&e(h,1))}),E(t),R((e,n,r,a,s)=>{J(t,`aria-label`,e),K(i,n),K(o,r),K(d,`${a??``}:`),K(f,` ${s??``}`)},[()=>(U(Q),n(),H(()=>Q(`permissionReportTitle`,n()))),()=>(U(Q),n(),H(()=>Q(`permissionReportTitle`,n()))),()=>(U(Q),n(),H(()=>Q(`permissionReportLead`,n()))),()=>(U(Q),n(),H(()=>Q(`permissionIdentity`,n()))),()=>(U(Q),V(s),n(),H(()=>Q(V(s).identityStatus===`valid`?`permissionIdentityValid`:V(s).identityStatus===`invalid`?`permissionIdentityInvalid`:`permissionIdentityUnknown`,n())))]),G(e,t)};q(ee,e=>{V(s)&&e(te)});var ne=L(ee,2),re=e=>{Ks(e,{get effects(){return U(m()),H(()=>m().effects)}})};q(ne,e=>{U(m()),H(()=>m()?.effects?.length)&&e(re)});var ie=L(ne,2),ae=I(ie,!0),oe=L(ie,2),se=e=>{var t=$s(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`botRenewal`,n())))]),G(e,t)};q(oe,e=>{l()===`complete`&&e(se)});var ce=L(oe,2),le=I(ce,!0),ue=L(ce,2),de=e=>{var t=tc(),r=P(t),i=e=>{var t=$s(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`doctorRunning`,n())))]),G(e,t)},a=e=>{var t=$s(),r=I(t);R((e,t,n)=>K(r,`${e??``} ${t??``} ${n??``}`),[()=>(U(Q),U(p()),n(),H(()=>Q(p().healthy?`doctorPassed`:`doctorWarnings`,n()))),()=>(U(Q),n(),U(p()),H(()=>Q(`doctorCounts`,n(),{pass:String(p().pass??0),warn:String(p().warn??0),fail:String(p().fail??0),skipped:String(p().skipped??0)}))),()=>(U(Q),n(),H(()=>Q(`doctorSecretLimit`,n())))]),G(e,t)},o=e=>{var t=$s(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`doctorFailed`,n())))]),G(e,t)};q(r,e=>{U(p()),H(()=>p()?.status===`running`)?e(i):(U(p()),H(()=>p()?.status===`complete`)?e(a,1):(U(p()),H(()=>p()?.status===`failed`)&&e(o,2)))});var s=L(r,2),c=e=>{{let t=A(()=>(U(Q),n(),H(()=>Q(`doctorRun`,n()))));ka(e,{get label(){return V(t)},variant:`secondary`,get onClick(){return f()}})}};q(s,e=>{U(u()),U(p()),H(()=>u()&&p()?.status!==`running`&&p()?.status!==`complete`)&&e(c)}),E(t),G(e,t)};q(ue,e=>{l()===`complete`&&e(de)});var fe=L(ue,2),pe=I(P(fe),!0);ke(),E(fe);var me=L(fe),he=e=>{{let t=A(()=>(U(Q),n(),H(()=>Q(`closeSession`,n()))));ka(e,{get label(){return V(t)},get onClick(){return d()}})}};q(me,e=>{u()&&e(he)}),E(_),ii(_,(e,t)=>fs?.(e,t),()=>1),R((e,t)=>{K(y,l()===`complete`?`✓`:`!`),K(x,V(a)),K(ae,V(o)),K(le,e),K(pe,t)},[()=>(U(Q),n(),H(()=>Q(`doctorHelp`,n()))),()=>(U(Q),n(),H(()=>Q(`patSettings`,n())))]),G(e,_),k(),i()}var ic=W(`

                            `);function ac(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`effects`,8,void 0);Y();var o=ic(),s=L(P(o)),c=I(s,!0),l=L(s),u=I(l,!0),d=L(l),f=e=>{Ks(e,{get effects(){return a()}})};q(d,e=>{U(a()),H(()=>a()?.length)&&e(f)}),E(o),R((e,t)=>{K(c,e),K(u,t)},[()=>(U(Q),n(),H(()=>Q(`working`,n()))),()=>(U(Q),n(),H(()=>Q(`workingBody`,n())))]),G(e,o),k(),i()}function oc(e,t){return!t&&/^[A-Fa-f0-9]{16}$/u.test(e.trim())}var sc=W(`

                            `);function cc(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`busy`,8),o=Z(t,`onPair`,8),s=Z(t,`mode`,8,`pair`),c=M(``);function l(){if(!oc(V(c),a()))return;let e=V(c).trim();N(c,``),o()(e)}Y();var u=sc(),d=P(u),f=I(P(d),!0);E(d);var p=L(d,2),m=I(P(p),!0);E(p);var h=L(p,2),g=I(h,!0),_=L(h,2),v=P(_),y=I(v,!0),b=L(v,2);xi(b);var x=L(b,2),S=I(x,!0),C=L(x,2);{let e=A(()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairButton`:`takeOver`,n())))),t=A(()=>(U(oc),V(c),U(a()),H(()=>!oc(V(c),a()))));ka(C,{get label(){return V(e)},arrow:!0,onClick:l,get disabled(){return V(t)}})}E(_),E(u),R((e,t,n,r,i,o,s)=>{J(u,`aria-label`,e),K(f,t),K(m,n),K(g,r),K(y,i),b.disabled=a(),J(b,`placeholder`,o),K(S,s)},[()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(U(Q),n(),H(()=>Q(`privateSession`,n()))),()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairBody`:`readOnlyBody`,n()))),()=>(U(Q),n(),H(()=>Q(`pairLabel`,n()))),()=>(U(Q),n(),H(()=>Q(`pairPlaceholder`,n()))),()=>(U(Q),n(),H(()=>Q(`pairHelp`,n())))]),xr(`submit`,_,e=>{e.preventDefault(),l()}),Ei(b,()=>V(c),e=>N(c,e)),G(e,u),k(),i()}var lc={"The local setup session is unavailable.":`The local setup session is unavailable. Check the terminal; you may need to restart setup.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connection lost. The CLI may have stopped. Check the terminal before trying again.`,"Could not join this local session.":`Could not join this local session. Check the terminal and pair again.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Could not connect to the local setup session. Check the terminal and pair again.`,"Pairing was rejected.":`Pairing was rejected. Check the code in the launching terminal.`,"Invalid local pairing response.":`The local pairing response was invalid. Restart setup from the terminal.`,"Could not pair this browser.":`Could not pair this browser. Check the terminal and try again.`,"The request was rejected.":`The local request was rejected. Refresh the page and check the terminal.`,"Could not submit this answer.":`Could not submit this answer. Refresh the page and try again.`,"Cancellation failed.":`Cancellation failed. Check whether setup has already started applying before closing.`,"Takeover failed.":`Could not take control. Re-enter the pairing code from the launching terminal.`,"Invalid local host or request context.":`The local request context was rejected. Open the exact URL printed in the terminal.`,"Invalid request origin.":`The request came from another origin. Open the exact local URL printed in the terminal.`,"JSON required.":`The local request format was invalid. Refresh the page and try again.`,"Too many pairing attempts. Restart setup.":`Too many incorrect pairing attempts. Restart setup from the terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Too many incorrect pairing attempts. Wait 30 seconds and try the code again; terminal setup remains available.`,"Incorrect pairing code. Check the terminal.":`Incorrect pairing code. Check the launching terminal.`,"Incorrect pairing code. Check the launching output.":`Incorrect pairing code. Check the launching output.`,"Pair this browser using the code printed by the CLI.":`Pair this browser using the code printed by the CLI.`,"This tab is read-only.":`This tab is read-only. Enter the pairing code again to take control.`,"Invalid answer.":`The answer was invalid. Review the current question and try again.`,"Control moved to another tab.":`Control moved to another tab. This tab is now read-only.`,"This question changed. Refresh the current state.":`This question changed. Refresh the page before answering again.`,"This setup has already started applying or ended.":`Setup has already started applying or ended. Inspect the current result before retrying.`,"Only the controller can close a finished session.":`Only the controlling tab can close this finished session.`,"Method not allowed.":`This local request is not allowed. Refresh the page.`,"Not found.":`The requested local page was not found. Open the URL printed in the terminal.`,"Invalid local request.":`The local request was invalid. Refresh the page and try again.`,"Body too large.":`The submitted answer is too large. Shorten it and try again.`,"JSON object required.":`The local request format was invalid. Refresh the page and try again.`,"Could not retry discovery.":`Could not refresh the GitHub suggestions. Retry or use verified manual entry.`,"Could not return to the previous question.":`Could not return to the previous question. Refresh the page and try again.`,"Invalid question revision.":`The question changed. Refresh the page before going back.`,"No earlier question is available here.":`There is no earlier question in this stage. Continue or return to the plan review.`,"Read-only verification failed.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification failed. Check the terminal.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification is unavailable or already running.":`Read-only verification is unavailable or already running. Check the current result before retrying.`},uc={en:lc,es:{"The local setup session is unavailable.":`La sesión local no está disponible. Revisa la terminal; quizá debas reiniciar la configuración.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Se perdió la conexión. Es posible que el CLI se haya detenido. Revisa la terminal antes de reintentar.`,"Could not join this local session.":`No se pudo acceder a esta sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`No se pudo conectar con la sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Pairing was rejected.":`Se rechazó la vinculación. Comprueba el código en la terminal que inició el proceso.`,"Invalid local pairing response.":`La respuesta de vinculación local no es válida. Reinicia la configuración desde la terminal.`,"Could not pair this browser.":`No se pudo vincular este navegador. Revisa la terminal y vuelve a intentarlo.`,"The request was rejected.":`Se rechazó la petición local. Actualiza la página y revisa la terminal.`,"Could not submit this answer.":`No se pudo enviar la respuesta. Actualiza la página y vuelve a intentarlo.`,"Cancellation failed.":`No se pudo cancelar. Comprueba si ya se han empezado a aplicar cambios antes de cerrar.`,"Takeover failed.":`No se pudo tomar el control. Vuelve a introducir el código de la terminal inicial.`,"Invalid local host or request context.":`Se rechazó el contexto de la petición local. Abre la URL exacta que aparece en la terminal.`,"Invalid request origin.":`La petición llegó desde otro origen. Abre la URL local exacta de la terminal.`,"JSON required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Too many pairing attempts. Restart setup.":`Demasiados intentos de vinculación fallidos. Reinicia la configuración desde la terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiados intentos de vinculación fallidos. Espera 30 segundos y vuelve a probar el código; puedes seguir con el setup en la terminal.`,"Incorrect pairing code. Check the terminal.":`Código de vinculación incorrecto. Comprueba la terminal inicial.`,"Incorrect pairing code. Check the launching output.":`Código de vinculación incorrecto. Comprueba la salida de inicio.`,"Pair this browser using the code printed by the CLI.":`Vincula este navegador con el código mostrado por el CLI.`,"This tab is read-only.":`Esta pestaña es de solo lectura. Introduce otra vez el código para tomar el control.`,"Invalid answer.":`La respuesta no es válida. Revisa la pregunta actual e inténtalo de nuevo.`,"Control moved to another tab.":`El control pasó a otra pestaña. Esta ahora es de solo lectura.`,"This question changed. Refresh the current state.":`La pregunta cambió. Actualiza la página antes de volver a responder.`,"This setup has already started applying or ended.":`La configuración ya empezó a aplicarse o terminó. Revisa el resultado antes de reintentar.`,"Only the controller can close a finished session.":`Solo la pestaña que tiene el control puede cerrar esta sesión finalizada.`,"Method not allowed.":`Esta petición local no está permitida. Actualiza la página.`,"Not found.":`No se encontró la página local solicitada. Abre la URL de la terminal.`,"Invalid local request.":`La petición local no es válida. Actualiza la página y reinténtalo.`,"Body too large.":`La respuesta enviada es demasiado larga. Acórtala y reinténtalo.`,"JSON object required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Could not retry discovery.":`No se pudieron actualizar las sugerencias de GitHub. Reinténtalo o introduce datos verificados manualmente.`,"Could not return to the previous question.":`No se pudo volver a la pregunta anterior. Actualiza la página y reinténtalo.`,"Invalid question revision.":`La pregunta cambió. Actualiza la página antes de volver atrás.`,"No earlier question is available here.":`No hay una pregunta anterior en esta etapa. Continúa o vuelve a revisar el plan.`,"Read-only verification failed.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification failed. Check the terminal.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification is unavailable or already running.":`La comprobación de solo lectura no está disponible o ya se está ejecutando. Revisa el resultado antes de reintentar.`},fr:{"The local setup session is unavailable.":`La session locale est indisponible. Vérifiez le terminal ; vous devrez peut-être relancer la configuration.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connexion perdue. Le CLI s’est peut-être arrêté. Vérifiez le terminal avant de réessayer.`,"Could not join this local session.":`Impossible de rejoindre cette session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Impossible de se connecter à la session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Pairing was rejected.":`L’association a été refusée. Vérifiez le code dans le terminal de lancement.`,"Invalid local pairing response.":`La réponse d’association locale est invalide. Relancez la configuration depuis le terminal.`,"Could not pair this browser.":`Impossible d’associer ce navigateur. Vérifiez le terminal et réessayez.`,"The request was rejected.":`La demande locale a été refusée. Actualisez la page et vérifiez le terminal.`,"Could not submit this answer.":`Impossible d’envoyer cette réponse. Actualisez la page et réessayez.`,"Cancellation failed.":`Annulation impossible. Vérifiez si des changements ont déjà commencé avant de fermer.`,"Takeover failed.":`Impossible de prendre le contrôle. Ressaisissez le code du terminal de lancement.`,"Invalid local host or request context.":`Le contexte de la demande locale a été refusé. Ouvrez l’URL exacte affichée dans le terminal.`,"Invalid request origin.":`La demande vient d’une autre origine. Ouvrez l’URL locale exacte du terminal.`,"JSON required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Too many pairing attempts. Restart setup.":`Trop de tentatives d’association incorrectes. Relancez la configuration depuis le terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Trop de tentatives d’association incorrectes. Attendez 30 secondes puis ressaisissez le code ; la configuration par terminal reste disponible.`,"Incorrect pairing code. Check the terminal.":`Code d’association incorrect. Vérifiez le terminal de lancement.`,"Incorrect pairing code. Check the launching output.":`Code d’association incorrect. Vérifiez la sortie de lancement.`,"Pair this browser using the code printed by the CLI.":`Associez ce navigateur avec le code affiché par le CLI.`,"This tab is read-only.":`Cet onglet est en lecture seule. Ressaisissez le code pour prendre le contrôle.`,"Invalid answer.":`La réponse est invalide. Revoyez la question actuelle et réessayez.`,"Control moved to another tab.":`Le contrôle est passé à un autre onglet. Celui-ci est maintenant en lecture seule.`,"This question changed. Refresh the current state.":`La question a changé. Actualisez la page avant de répondre de nouveau.`,"This setup has already started applying or ended.":`La configuration est déjà en cours d’application ou terminée. Inspectez le résultat avant de réessayer.`,"Only the controller can close a finished session.":`Seul l’onglet qui détient le contrôle peut fermer cette session terminée.`,"Method not allowed.":`Cette demande locale n’est pas autorisée. Actualisez la page.`,"Not found.":`La page locale demandée est introuvable. Ouvrez l’URL affichée dans le terminal.`,"Invalid local request.":`La demande locale est invalide. Actualisez la page et réessayez.`,"Body too large.":`La réponse envoyée est trop longue. Raccourcissez-la et réessayez.`,"JSON object required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Could not retry discovery.":`Impossible d’actualiser les suggestions GitHub. Réessayez ou saisissez des données vérifiées manuellement.`,"Could not return to the previous question.":`Impossible de revenir à la question précédente. Actualisez la page et réessayez.`,"Invalid question revision.":`La question a changé. Actualisez la page avant de revenir en arrière.`,"No earlier question is available here.":`Il n’y a pas de question précédente à cette étape. Continuez ou revenez à la révision du plan.`,"Read-only verification failed.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification failed. Check the terminal.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification is unavailable or already running.":`La vérification en lecture seule est indisponible ou déjà en cours. Consultez le résultat avant de réessayer.`},pt:{"The local setup session is unavailable.":`A sessão local não está disponível. Verifique o terminal; poderá ter de reiniciar a configuração.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Ligação perdida. O CLI pode ter parado. Verifique o terminal antes de tentar novamente.`,"Could not join this local session.":`Não foi possível entrar nesta sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Não foi possível ligar à sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Pairing was rejected.":`O emparelhamento foi recusado. Confirme o código no terminal de lançamento.`,"Invalid local pairing response.":`A resposta de emparelhamento local é inválida. Reinicie a configuração a partir do terminal.`,"Could not pair this browser.":`Não foi possível emparelhar este navegador. Verifique o terminal e tente novamente.`,"The request was rejected.":`O pedido local foi recusado. Atualize a página e verifique o terminal.`,"Could not submit this answer.":`Não foi possível enviar a resposta. Atualize a página e tente novamente.`,"Cancellation failed.":`Não foi possível cancelar. Confirme se a aplicação das alterações já começou antes de fechar.`,"Takeover failed.":`Não foi possível assumir o controlo. Volte a introduzir o código do terminal de lançamento.`,"Invalid local host or request context.":`O contexto do pedido local foi recusado. Abra o URL exato apresentado no terminal.`,"Invalid request origin.":`O pedido veio de outra origem. Abra o URL local exato do terminal.`,"JSON required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Too many pairing attempts. Restart setup.":`Demasiadas tentativas incorretas de emparelhamento. Reinicie a configuração no terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiadas tentativas incorretas de emparelhamento. Aguarde 30 segundos e volte a introduzir o código; a configuração no terminal continua disponível.`,"Incorrect pairing code. Check the terminal.":`Código de emparelhamento incorreto. Verifique o terminal de lançamento.`,"Incorrect pairing code. Check the launching output.":`Código de emparelhamento incorreto. Verifique a saída de lançamento.`,"Pair this browser using the code printed by the CLI.":`Emparelhe este navegador com o código apresentado pelo CLI.`,"This tab is read-only.":`Este separador é apenas de leitura. Reintroduza o código para assumir o controlo.`,"Invalid answer.":`A resposta é inválida. Reveja a pergunta atual e tente novamente.`,"Control moved to another tab.":`O controlo passou para outro separador. Este é agora apenas de leitura.`,"This question changed. Refresh the current state.":`A pergunta mudou. Atualize a página antes de voltar a responder.`,"This setup has already started applying or ended.":`A configuração já começou a ser aplicada ou terminou. Inspecione o resultado antes de tentar novamente.`,"Only the controller can close a finished session.":`Só o separador que detém o controlo pode fechar esta sessão terminada.`,"Method not allowed.":`Este pedido local não é permitido. Atualize a página.`,"Not found.":`A página local pedida não foi encontrada. Abra o URL apresentado no terminal.`,"Invalid local request.":`O pedido local é inválido. Atualize a página e tente novamente.`,"Body too large.":`A resposta enviada é demasiado longa. Encurte-a e tente novamente.`,"JSON object required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Could not retry discovery.":`Não foi possível atualizar as sugestões do GitHub. Tente novamente ou introduza dados verificados manualmente.`,"Could not return to the previous question.":`Não foi possível voltar à pergunta anterior. Atualize a página e tente novamente.`,"Invalid question revision.":`A pergunta mudou. Atualize a página antes de voltar atrás.`,"No earlier question is available here.":`Não há uma pergunta anterior nesta etapa. Continue ou volte à revisão do plano.`,"Read-only verification failed.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification failed. Check the terminal.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification is unavailable or already running.":`A verificação só de leitura não está disponível ou já está em curso. Consulte o resultado antes de tentar novamente.`}};function dc(e,t){let n=uc[t]??lc;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:Q(`unknownLocalError`,t)}var fc=W(`
                            `),pc=W(` `,1),mc=W(``),hc=W(`
                            `,1),gc=W(`
                            `);function _c(e,t){O(t,!1);let n=()=>X(o,`$session`,i),r=()=>X($,`$setupLocale`,i),[i,a]=Ii(),o=Ri();Wr(()=>{let e=$.subscribe(e=>{document.documentElement.lang=e,document.documentElement.dir=`ltr`,document.title=`Copilot · ${Q(`studio`,e)}`}),t=window.setInterval(()=>{n().paired&&!n().view?.outcome&&o.poll()},900);return()=>{window.clearInterval(t),e()}});async function s(){window.confirm(Q(`cancelConfirm`,r()))&&await o.cancel()}async function c(e){let t=n().view?.promptRevision;t!==void 0&&await o.submit(t,e)}async function l(){let e=n().view?.promptRevision;e!==void 0&&await o.retryDiscovery(e)}async function u(){let e=n().view?.promptRevision;e!==void 0&&await o.back(e)}Y();var d=gc(),f=P(d);{let e=A(()=>n().view?.journey);Xi(f,{get journey(){return V(e)}})}var p=L(f,2),m=P(p);{let e=A(()=>n().view?.repository);ra(m,{get repository(){return V(e)}})}var h=L(m,2),g=P(h),_=e=>{{let t=A(()=>Q(`translationPreviewTitle`,r())),n=A(()=>Q(`translationPreviewBody`,r()));Ma(e,{tone:`warning`,get title(){return V(t)},get message(){return V(n)}})}};q(g,e=>{r()!==`en`&&e(_)});var v=L(g,2),y=e=>{Sa(e,{get view(){return n().view}})};q(v,e=>{n().paired&&e(y)});var b=L(v,2),x=e=>{var t=fc(),i=L(P(t));E(t),R(e=>K(i,` ${e??``}`),[()=>Q(`reviewPass`,r(),{pass:String(n().view.journey.choiceReviewPass)})]),G(e,t)};q(b,e=>{n().view?.journey?.choiceReviewPass&&n().view.journey.choiceReviewPass>1&&!n().view.outcome&&e(x)});var S=L(b,2),C=e=>{var t=pc(),i=F(t);{let e=A(()=>Q(`readOnly`,r())),t=A(()=>Q(`readOnlyBody`,r()));Ma(i,{tone:`warning`,get title(){return V(e)},get message(){return V(t)}})}cc(L(i,2),{mode:`takeover`,get busy(){return n().busy},get onPair(){return o.takeOver}}),G(e,t)};q(S,e=>{!n().controller&&n().view&&e(C)});var ee=L(S,2),te=e=>{{let t=A(()=>Q(`attention`,r())),i=A(()=>dc(n().error,r()));Ma(e,{tone:`error`,get title(){return V(t)},get message(){return V(i)}})}};q(ee,e=>{n().error&&e(te)});var ne=L(ee,2),re=e=>{{let t=A(()=>Q(n().view.message.tone===`success`?`checked`:n().view.message.tone===`warning`?`pleaseNote`:n().view.message.tone===`error`?`attention`:`progressUpdate`,r())),i=A(()=>ga(n().view.message,r()));Ma(e,{get tone(){return n().view.message.tone},get title(){return V(t)},get message(){return V(i)},get link(){return n().view.message.link}})}};q(ne,e=>{n().view?.message&&!n().view.outcome&&e(re)});var ie=L(ne,2),ae=e=>{cc(e,{get busy(){return n().busy},get onPair(){return o.pair}})},oe=e=>{{let t=A(()=>n().view.permissions?.report);rc(e,{get outcome(){return n().view.outcome},get detail(){return n().view.resultDetail},get permissionReport(){return V(t)},get doctor(){return n().view.doctor},get controller(){return n().controller},get onDoctor(){return o.runDoctor},get onClose(){return o.close}})}},se=e=>{var t=hc(),i=F(t),a=P(i);gs(a,{get prompt(){return n().view.prompt},get revision(){return n().view.revision},get promptRevision(){return n().view.promptRevision},get controller(){return n().controller},get busy(){return n().busy},onSubmit:c,onRetryDiscovery:l,onBack:u}),Us(L(a,2),{get view(){return n().view}}),E(i);var o=L(i,2),d=e=>{var t=mc(),i=I(t,!0);R(e=>{t.disabled=n().busy,K(i,e)},[()=>Q(`cancelSetup`,r())]),Sr(`click`,t,s),G(e,t)};q(o,e=>{n().controller&&n().view.journey?.current!==`Apply`&&e(d)}),G(e,t)},ce=e=>{{let t=A(()=>n().view?.resultDetail?.effects);ac(e,{get effects(){return V(t)}})}};q(ie,e=>{n().paired?n().view?.outcome?e(oe,1):n().view?.prompt?e(se,2):e(ce,-1):e(ae)});var le=L(ie,2),ue=P(le),de=L(ue,2),fe=L(de,2);E(le),E(h),E(p),E(d),R((e,t,n)=>{K(ue,`${e??``} `),K(de,` ${t??``} `),K(fe,` ${n??``}`)},[()=>Q(`footerLocal`,r()),()=>Q(`footerCloud`,r()),()=>Q(`footerGithub`,r())]),G(e,d),k(),a()}Cr([`click`]),zr(_c,{target:document.getElementById(`app`)}); \ No newline at end of file diff --git a/build/web/assets/index-CcOfHgj1.js b/build/web/assets/index-CcOfHgj1.js deleted file mode 100644 index 1476328a1..000000000 --- a/build/web/assets/index-CcOfHgj1.js +++ /dev/null @@ -1,3 +0,0 @@ -(function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})(),typeof window<`u`&&((window.__svelte??={}).v??=new Set).add(`5`);var e=!1;function t(){e=!0}t();var n={},r=Symbol(`uninitialized`),i=`http://www.w3.org/1999/xhtml`,a=Array.isArray,o=Array.prototype.indexOf,s=Array.prototype.includes,c=Array.from,l=Object.defineProperty,u=Object.getOwnPropertyDescriptor,d=Object.getOwnPropertyDescriptors,f=Object.prototype,p=Array.prototype,m=Object.getPrototypeOf,h=Object.isExtensible,g=()=>{};function _(e){return e()}function v(e){for(var t=0;t{e=n,t=r}),resolve:e,reject:t}}function b(e,t){if(Array.isArray(e))return e;if(t===void 0||!(Symbol.iterator in e))return Array.from(e);let n=[];for(let r of e)if(n.push(r),n.length===t)break;return n}var x=1024,S=2048,C=4096,ee=8192,te=16384,ne=32768,re=1<<25,ie=65536,ae=1<<19,oe=1<<20,se=1<<25,ce=1<<21,le=1<<22,ue=1<<23,de=Symbol(`$state`),fe=Symbol(`component`),pe=Symbol(`legacy props`),me=Symbol(``),he=Symbol(`attributes`),ge=Symbol(`class`),_e=Symbol(`style`),ve=Symbol(`text`),ye=Symbol(`form reset`),be=new class extends Error{name=`StaleReactionError`;message="The reaction that called `getAbortSignal()` was re-run or destroyed"},xe=!!globalThis.document?.contentType&&globalThis.document.contentType.includes(`xml`);function Se(){console.warn(`https://svelte.dev/e/derived_inert`)}function Ce(e){console.warn(`https://svelte.dev/e/hydration_mismatch`)}function we(){console.warn(`https://svelte.dev/e/select_multiple_invalid_value`)}function Te(){console.warn(`https://svelte.dev/e/svelte_boundary_reset_noop`)}var w=!1;function Ee(e){w=e}var T;function De(e){if(e===null)throw Ce(),n;return T=e}function Oe(){return De(cn(T))}function E(e){if(w){if(cn(T)!==null)throw Ce(),n;T=e}}function ke(e=1){if(w){for(var t=e,n=T;t--;)n=cn(n);T=n}}function Ae(e=!0){for(var t=0,n=T;;){if(n.nodeType===8){var r=n.data;if(r===`]`){if(t===0)return n;--t}else(r===`[`||r===`[!`||r[0]===`[`&&!isNaN(Number(r.slice(1))))&&(t+=1)}var i=cn(n);e&&n.remove(),n=i}}function je(e){if(!e||e.nodeType!==8)throw Ce(),n;return e.data}function Me(e){return e===this.v}function Ne(e,t){return e==e?e!==t||typeof e==`object`&&!!e||typeof e==`function`:t==t}function Pe(e){return!Ne(e,this.v)}function Fe(e){throw Error(`https://svelte.dev/e/lifecycle_outside_component`)}function Ie(){throw Error(`https://svelte.dev/e/async_derived_orphan`)}function Le(e,t,n){throw Error(`https://svelte.dev/e/each_key_duplicate`)}function Re(e){throw Error(`https://svelte.dev/e/effect_in_teardown`)}function ze(){throw Error(`https://svelte.dev/e/effect_in_unowned_derived`)}function Be(e){throw Error(`https://svelte.dev/e/effect_orphan`)}function Ve(){throw Error(`https://svelte.dev/e/effect_update_depth_exceeded`)}function He(e){throw Error(`https://svelte.dev/e/props_invalid_value`)}function Ue(){throw Error(`https://svelte.dev/e/state_descriptors_fixed`)}function We(){throw Error(`https://svelte.dev/e/state_prototype_fixed`)}function Ge(){throw Error(`https://svelte.dev/e/state_unsafe_mutation`)}function Ke(){throw Error(`https://svelte.dev/e/svelte_boundary_reset_onerror`)}var D=null;function qe(e){D=e}function O(t,n=!1,r){D={p:D,i:!1,c:null,e:null,s:t,x:null,r:B,l:e&&!n?{s:null,u:null,$:[]}:null}}function k(e){var t=D,n=t.e;if(n!==null){t.e=null;for(var r of n)xn(r)}return e!==void 0&&(t.x=e),t.i=!0,D=t.p,Je(e)}function Je(e={}){return l(e,fe,{value:!0}),e}function Ye(){return!e||D!==null&&D.l===null}var Xe=[];function Ze(){var e=Xe;Xe=[],v(e)}function Qe(e){if(Xe.length===0&&!Et){var t=Xe;queueMicrotask(()=>{t===Xe&&Ze()})}Xe.push(e)}function $e(){for(;Xe.length>0;)Ze()}var et=~(S|C|x);function tt(e,t){e.f=e.f&et|t}function nt(e){e.f&512||e.deps===null?tt(e,x):tt(e,C)}function rt(e,t,n){e.f&2048?t.add(e):e.f&4096&&n.add(e),tt(e,x)}function it(e){w&&sn(e)!==null&&ln(e)}var at=!1;function ot(){at||(at=!0,document.addEventListener(`reset`,e=>{Promise.resolve().then(()=>{if(!e.defaultPrevented)for(let t of e.target.elements)t[ye]?.()})},{capture:!0}))}function st(e){var t=z,n=B;qn(null),Jn(null);try{return e()}finally{qn(t),Jn(n)}}function ct(e,t,n,r=n){e.addEventListener(t,()=>st(n));let i=e[ye];e[ye]=i?()=>{i(),r(!0)}:()=>r(!0),ot()}function lt(e,t,n,r){let i=Ye()?pt:A;var a=e.filter(e=>!e.settled),o=t.map(i);if(n.length===0&&a.length===0){r(o);return}var s=B,c=ut(),l=a.length===1?a[0].promise:a.length>1?Promise.all(a.map(e=>e.promise)):null;function u(e){if(!(s.f&16384)){c();try{r([...o,...e])}catch(e){mn(e,s)}dt()}}var d=ft();if(n.length===0){l.then(()=>u([])).finally(d);return}function f(){Promise.all(n.map(e=>ht(e))).then(u).catch(e=>mn(e,s)).finally(d)}l?l.then(()=>{c(),f(),dt()}):f()}function ut(){var e=B,t=z,n=D,r=j;return function(i=!0){Jn(e),qn(t),qe(n),i&&!(e.f&16384)&&(r?.activate(),r?.apply())}}function dt(e=!0){Jn(null),qn(null),qe(null),e&&j?.deactivate()}function ft(){var e=B,t=e.b,n=j,r=!!t?.is_rendered();return t?.update_pending_count(1,n),n.increment(r,e),()=>{t?.update_pending_count(-1,n),n.decrement(r,e)}}function pt(e){var t=2|S;return B!==null&&(B.f|=ae),{ctx:D,deps:null,effects:null,equals:Me,f:t,fn:e,reactions:null,rv:0,v:r,wv:0,parent:B,ac:null}}var mt=Symbol(`obsolete`);function ht(e,t,n){let i=B;i===null&&Ie();var a=void 0,o=Ut(r),s=!z,c=new Set;return Dn(()=>{var t=B,n=y();a=n.promise;try{Promise.resolve(e()).then(n.resolve,e=>{e!==be&&n.reject(e)}).finally(dt)}catch(e){n.reject(e),dt()}var r=j;if(s){if(t.f&32768)var l=ft();if(i.b?.is_rendered())r.async_deriveds.get(t)?.reject(mt);else for(let e of c.values())e.reject(mt);c.add(n),r.async_deriveds.set(t,n)}let u=(e,t=void 0)=>{l?.(),c.delete(n),t!==mt&&(r.activate(),t?(o.f|=ue,qt(o,t)):(o.f&8388608&&(o.f^=ue),qt(o,e)),r.deactivate())};n.promise.then(u,e=>u(null,e||`unknown`))}),yn(()=>{for(let e of c)e.reject(mt)}),new Promise(e=>{function t(n){function r(){n===a?e(o):t(a)}n.then(r,r)}t(a)})}function gt(e){let t=pt(e);return Xn(t),t}function A(e){let t=pt(e);return t.equals=Pe,t}function _t(e){var t=e.effects;if(t!==null){e.effects=null;for(var n=0;n{t.ac.abort(be),t.ac=null}),t.fn!==null&&(t.teardown=g),dr(t,0),Mn(t))}function xt(e){if(e.effects!==null)for(let t of e.effects)t.teardown&&t.fn!==null&&fr(t)}var St=null,j=null,Ct=null,wt=null,Tt=null,Et=!1,Dt=!1,Ot=null,kt=null,At=0,jt=1,Mt=class e{id=jt++;#e=!1;linked=!0;#t=null;#n=null;async_deriveds=new Map;current=new Map;previous=new Map;#r=new Set;#i=new Set;#a=0;#o=new Map;#s=null;#c=[];#l=[];#u=new Set;#d=new Set;#f=new Map;#p=new Set;is_fork=!1;#m=!1;constructor(){St===null?St=this:(St.#n=this,this.#t=St),St=this}#h(){if(this.is_fork)return!0;for(let n of this.#o.keys()){for(var e=n,t=!1;e.parent!==null;){if(this.#f.has(e)){t=!0;break}e=e.parent}if(!t)return!0}return!1}skip_effect(e){this.#f.has(e)||this.#f.set(e,{d:[],m:[]}),this.#p.delete(e)}unskip_effect(e,t=e=>this.schedule(e)){var n=this.#f.get(e);if(n){this.#f.delete(e);for(var r of n.d)tt(r,S),t(r);for(r of n.m)tt(r,C),t(r)}this.#p.add(e)}#g(){var e=[];for(let i of this.#c)if(!(i.f&16384||!(i.f&6144))){for(var t=i,n=!1;t.parent!==null;){t=t.parent;var r=t.f;if(r&96){if(!(r&1024)){n=!0;break}t.f^=x}}n||e.push(t)}return this.#c=[],e}#_(){this.#e=!0;for(let e of this.#u)this.#d.delete(e),tt(e,S),this.schedule(e);for(let e of this.#d)tt(e,C),this.schedule(e);this.apply();for(var t=Ot=[],n=[],r=kt=[];this.#c.length>0;){At++>1e3&&(this.#S(),Pt());for(let e of this.#g())try{this.#v(e,t,n)}catch(t){throw zt(e),this.#h()||this.discard(),t}}if(j=null,r.length>0){var i=e.ensure();for(let e of r)i.schedule(e)}if(Ot=null,kt=null,this.#h()){this.#x(n),this.#x(t);for(let[e,t]of this.#f)Rt(e,t);r.length>0&&j.#_();return}let a=this.#y();if(a){this.#x(n),this.#x(t),a.#b(this);return}this.#u.clear(),this.#d.clear();for(let e of this.#r)e(this);this.#r.clear(),Ct=this,It(n),It(t),Ct=null,this.#s?.resolve();var o=j;if(this.#a===0&&(this.#c.length===0||o!==null)&&this.#S(),this.#c.length>0){if(o!==null){for(let e of this.#c)o.#c.push(e);this.#c=[]}else o=this}o!==null&&(Vt.clear(),o.#_())}#v(e,t,n){e.f^=x;for(var r=e.first;r!==null;){var i=r.f,a=!!(i&96);if(!(a&&i&1024||i&8192||this.#f.has(r))&&r.fn!==null){a?r.f^=x:i&4?t.push(r):or(r)&&(i&16&&this.#d.add(r),fr(r));var o=r.first;if(o!==null){r=o;continue}}for(;r!==null;){var s=r.next;if(s!==null){r=s;break}r=r.parent}}}#y(){for(var e=this.#t;e!==null;){if(!e.is_fork){for(let[t,[,n]]of this.current)if(e.current.has(t)&&!n)return e}e=e.#t}return null}#b(e){for(let[t,n]of e.current)!this.previous.has(t)&&e.previous.has(t)&&this.previous.set(t,e.previous.get(t)),this.current.set(t,n);for(let[t,n]of e.async_deriveds){let e=this.async_deriveds.get(t);e&&n.promise.then(e.resolve).catch(e.reject)}e.async_deriveds.clear(),this.transfer_effects(e.#u,e.#d);let t=e=>{var n=e.reactions;if(n!==null&&!(e.f&2&&!(e.f&6144)))for(let e of n){var r=e.f;if(r&2)t(e);else{var i=e;r&4194320&&!this.async_deriveds.has(i)&&(this.#d.delete(i),tt(i,S),this.schedule(i))}}};for(let e of this.current.keys())t(e);this.oncommit(()=>e.discard()),e.#S(),j=this,this.#_()}#x(e){for(var t=0;t{this.#m=!1,this.linked&&this.flush()}))}transfer_effects(e,t){for(let t of e)this.#u.add(t);for(let e of t)this.#d.add(e);e.clear(),t.clear()}oncommit(e){this.#r.add(e)}ondiscard(e){this.#i.add(e)}settled(){return(this.#s??=y()).promise}static ensure(){if(j===null){let t=j=new e;!Dt&&!Et&&Qe(()=>{t.#e||t.flush()})}return j}apply(){wt=null}schedule(e){if(Tt=e,e.b?.is_pending&&e.f&16777228&&!(e.f&32768)){e.b.defer_effect(e);return}this.#c.push(e)}#S(){if(this.linked){var e=this.#t,t=this.#n;e===null||(e.#n=t),t===null?St=e:t.#t=e,this.linked=!1}}};function Nt(e){var t=Et;Et=!0;try{var n;for(e&&(j!==null&&!j.is_fork&&j.flush(),n=e());;){if($e(),j===null)return n;j.flush()}}finally{Et=t}}function Pt(){try{Ve()}catch(e){mn(e,Tt)}}var Ft=null;function It(e){var t=e.length;if(t!==0){for(var n=0;n0)){Vt.clear();for(let e of Ft){if(e.f&24576)continue;let t=[e],n=e.parent;for(;n!==null;)Ft.has(n)&&(Ft.delete(n),t.push(n)),n=n.parent;for(let e=t.length-1;e>=0;e--){let n=t[e];n.f&24576||fr(n)}}Ft.clear()}}Ft=null}}function Lt(e){j.schedule(e)}function Rt(e,t){if(!(e.f&32&&e.f&1024)){e.f&2048?t.d.push(e):e.f&4096&&t.m.push(e),tt(e,x);for(var n=e.first;n!==null;)Rt(n,t),n=n.next}}function zt(e){tt(e,x);for(var t=e.first;t!==null;)zt(t),t=t.next}var Bt=new Set,Vt=new Map,Ht=!1;function Ut(e,t){return{f:0,v:e,reactions:null,equals:Me,rv:0,wv:0}}function Wt(e,t){let n=Ut(e,t);return Xn(n),n}function M(t,n=!1,r=!0){let i=Ut(t);return n||(i.equals=Pe),e&&r&&D!==null&&D.l!==null&&(D.l.s??=[]).push(i),i}function N(e,t,n=!1){return z!==null&&(!Kn||z.f&131072)&&Ye()&&z.f&4325394&&(Yn===null||!Yn.has(e))&&Ge(),qt(e,n?Zt(t):t,kt)}var Gt=null,Kt=0;function qt(e,t,n=null){if(!e.equals(t)){Wn?Vt.set(e,t):Vt.has(e)||Vt.set(e,e.v);var r=Mt.ensure();if(r.capture(e,t),e.f&2){let t=e;e.f&2048&&vt(t),wt===null&&nt(t)}e.wv=ar(),Gt=null,Kt=0,Xt(e,S,n),Gt=null,Ye()&&B!==null&&B.f&1024&&!(B.f&96)&&($n===null?er([e]):$n.push(e)),!r.is_fork&&Bt.size>0&&!Ht&&Jt()}return t}function Jt(){Ht=!1;for(let e of Bt){e.f&1024&&tt(e,C);let t;try{t=or(e)}catch{t=!0}t&&fr(e)}Bt.clear()}function Yt(e){N(e,e.v+1)}function Xt(e,t,n){var r=e.reactions;if(r!==null){var i=Ye(),a=r.length;if(Kt+=a,Kt>1e5&&Gt===null&&(Gt=new Set),Gt!==null){if(Gt.has(e))return;Gt.add(e)}for(var o=0;o{if(rr===c)return e();var t=z,n=rr;qn(null),ir(c);var r=e();return qn(t),ir(n),r};return i&&n.set(`length`,Wt(e.length,s)),new Proxy(e,{defineProperty(e,t,r){(!(`value`in r)||r.configurable===!1||r.enumerable===!1||r.writable===!1)&&Ue();var i=n.get(t);return i===void 0?l(()=>{var e=Wt(r.value,s);return n.set(t,e),e}):N(i,r.value,!0),!0},deleteProperty(e,t){var i=n.get(t);if(i===void 0){if(t in e){let e=l(()=>Wt(r,s));n.set(t,e),Yt(o)}}else N(i,r),Yt(o);return!0},get(t,i,a){if(i===de)return e;var o=n.get(i),c=i in t;if(o===void 0&&(!c||u(t,i)?.writable)&&(o=l(()=>Wt(Zt(c?t[i]:r),s)),n.set(i,o)),o!==void 0){var d=V(o);return d===r?void 0:d}return Reflect.get(t,i,a)},getOwnPropertyDescriptor(e,t){this.has?.(e,t);var i=Reflect.getOwnPropertyDescriptor(e,t),a=n.get(t);if(a!==void 0){var o=V(a);if(o===r)return;if(i&&`value`in i)i.value=o;else return{enumerable:!0,configurable:!0,value:o,writable:!0}}return i},has(e,t){if(t===de)return!0;var i=n.get(t),a=i!==void 0&&i.v!==r||Reflect.has(e,t);return(i!==void 0||B!==null&&(!a||u(e,t)?.writable))&&(i===void 0&&(i=l(()=>Wt(a?Zt(e[t]):r,s)),n.set(t,i)),V(i)===r)?!1:a},set(e,t,a,c){var d=n.get(t),f=t in e;if(i&&t===`length`)for(var p=a;pWt(r,s)),n.set(p+``,m)):N(m,r)}if(d===void 0)(!f||u(e,t)?.writable)&&(d=l(()=>Wt(void 0,s)),N(d,Zt(a)),n.set(t,d));else{f=d.v!==r;var h=l(()=>Zt(a));N(d,h)}var g=Reflect.getOwnPropertyDescriptor(e,t);if(g?.set&&g.set.call(c,a),!f){if(i&&typeof t==`string`){var _=n.get(`length`),v=Number(t);Number.isInteger(v)&&v>=_.v&&N(_,v+1)}Yt(o)}return!0},ownKeys(e){V(o);var t=Reflect.ownKeys(e).filter(e=>{var t=n.get(e);return t===void 0||t.v!==r});for(var[i,a]of n)a.v!==r&&!(i in e)&&t.push(i);return t},setPrototypeOf(){We()}})}function Qt(e){try{if(typeof e==`object`&&e&&de in e)return e[de]}catch{}return e}function $t(e,t){return Object.is(Qt(e),Qt(t))}var en,tn,nn,rn;function an(){if(en===void 0){en=window,tn=/Firefox/.test(navigator.userAgent);var e=Element.prototype,t=Node.prototype,n=Text.prototype;nn=u(t,`firstChild`).get,rn=u(t,`nextSibling`).get,h(e)&&(e[ge]=void 0,e[he]=null,e[_e]=void 0,e.__e=void 0),h(n)&&(n[ve]=void 0)}}function on(e=``){return document.createTextNode(e)}function sn(e){return nn.call(e)}function cn(e){return rn.call(e)}function P(e,t){if(!w)return sn(e);var n=sn(T);if(n===null)n=T.appendChild(on());else if(t&&n.nodeType!==3){var r=on();return n?.before(r),De(r),r}return t&&fn(n),De(n),n}function F(e,t=!1){if(!w){var n=sn(e);return n instanceof Comment&&n.data===``?cn(n):n}if(t){if(T?.nodeType!==3){var r=on();return T?.before(r),De(r),r}fn(T)}return T}function I(e,t=!1){if(!w)return sn(e);var n=P(e,t);return E(e),n}function L(e,t=1,n=!1){let r=w?T:e;for(var i;t--;)i=r,r=cn(r);if(!w)return r;if(n){if(r?.nodeType!==3){var a=on();return r===null?i?.after(a):r.before(a),De(a),a}fn(r)}return De(r),r}function ln(e){e.textContent=``}function un(){return!1}function dn(e,t,n){return t==null||t===`http://www.w3.org/1999/xhtml`?n?document.createElement(e,{is:n}):document.createElement(e):n?document.createElementNS(t,e,{is:n}):document.createElementNS(t,e)}function fn(e){if(e.nodeValue.length<65536)return;let t=e.nextSibling;for(;t!==null&&t.nodeType===3;)t.remove(),e.nodeValue+=t.nodeValue,t=e.nextSibling}function pn(e){var t=B;if(t===null)return z.f|=ue,e;if(!(t.f&32768)&&!(t.f&4))throw e;mn(e,t)}function mn(e,t){if(!(t!==null&&t.f&16384)){for(;t!==null;){if(t.f&128&&!(t.f&33570816)){if(!(t.f&32768))throw e;try{t.b.error(e);return}catch(t){e=t}}t=t.parent}throw e}}function hn(e){B===null&&(z===null&&Be(e),ze()),Wn&&Re(e)}function gn(e,t){var n=t.last;n===null?t.last=t.first=e:(n.next=e,e.prev=n,t.last=e)}function _n(e,t){var n=B;n!==null&&n.f&8192&&(e|=ee);var r={ctx:D,deps:null,nodes:null,f:e|S|512,first:null,fn:t,last:null,next:null,parent:n,b:n&&n.b,prev:null,teardown:null,wv:0,ac:null};j?.register_created_effect(r);var i=r;if(e&4)Ot===null?Mt.ensure().schedule(r):Ot.push(r);else if(t!==null){try{fr(r)}catch(e){throw Pn(r),e}i.deps===null&&i.teardown===null&&i.nodes===null&&i.first===i.last&&!(i.f&524288)&&(i=i.first,e&16&&e&65536&&i!==null&&(i.f|=ie))}if(i!==null&&(i.parent=n,n!==null&&gn(i,n),z!==null&&z.f&2&&!(e&64))){var a=z;(a.effects??=[]).push(i)}return r}function vn(){return z!==null&&!Kn}function yn(e){let t=_n(8,null);return tt(t,x),t.teardown=e,t}function bn(e){hn(`$effect`);var t=B.f;if(!z&&t&32&&D!==null&&!D.i){var n=D;(n.e??=[]).push(e)}else return xn(e)}function xn(e){return _n(4|oe,e)}function Sn(e){return hn(`$effect.pre`),_n(8|oe,e)}function Cn(e){Mt.ensure();let t=_n(64|ae,e);return(e={})=>new Promise(n=>{e.outro?Ln(t,()=>{Pn(t),n(void 0)}):(Pn(t),n(void 0))})}function wn(e){return _n(4,e)}function Tn(e,t){var n=D,r={effect:null,ran:!1,deps:e};n.l.$.push(r),r.effect=On(()=>{if(e(),!r.ran){r.ran=!0;var n=B;try{Jn(n.parent),H(t)}finally{Jn(n)}}})}function En(){var e=D;On(()=>{for(var t of e.l.$){t.deps();var n=t.effect;n.f&1024&&n.deps!==null&&tt(n,C),or(n)&&fr(n),t.ran=!1}})}function Dn(e){return _n(le|ae,e)}function On(e,t=0){return _n(8|t,e)}function R(e,t=[],n=[],r=[]){lt(r,t,n,t=>{_n(8,()=>{e(...t.map(V))})})}function kn(e,t=0){return _n(16|t,e)}function An(e){return _n(32|ae,e)}function jn(e){var t=e.teardown;if(t!==null){let n=Wn,r=z;Gn(!0),qn(null);try{t.call(null)}catch(t){mn(t,e.parent)}finally{Gn(n),qn(r)}}}function Mn(e,t=!1){var n=e.first;for(e.first=e.last=null;n!==null;){let e=n.ac;e!==null&&st(()=>{e.abort(be)});var r=n.next;n.f&64?n.parent=null:Pn(n,t),n=r}}function Nn(e){for(var t=e.first;t!==null;){var n=t.next;t.f&32||Pn(t),t=n}}function Pn(e,t=!0){var n=!1;(t||e.f&262144)&&e.nodes!==null&&e.nodes.end!==null&&(Fn(e.nodes.start,e.nodes.end),n=!0),e.f|=re,Mn(e,t&&!n),dr(e,0);var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)e.stop();jn(e),e.f^=re,e.f|=te;var i=e.parent;i!==null&&i.first!==null&&In(e),e.next=e.prev=e.teardown=e.ctx=e.deps=e.fn=e.nodes=e.ac=e.b=null}function Fn(e,t){for(;e!==null;){var n=e===t?null:cn(e);e.remove(),e=n}}function In(e){var t=e.parent,n=e.prev,r=e.next;n!==null&&(n.next=r),r!==null&&(r.prev=n),t!==null&&(t.first===e&&(t.first=r),t.last===e&&(t.last=n))}function Ln(e,t,n=!0){var r=[];e.f|=256,Rn(e,r,!0);var i=()=>{n&&Pn(e),t&&t()},a=r.length;if(a>0){var o=()=>--a||i();for(var s of r)s.out(o)}else i()}function Rn(e,t,n){if(!(e.f&8192)){e.f^=ee;var r=e.nodes&&e.nodes.t;if(r!==null)for(let e of r)(e.is_global||n)&&t.push(e);for(var i=e.first;i!==null;){var a=i.next;if(!(i.f&64)){var o=!!(i.f&65536)||!!(i.f&32)&&!!(e.f&16);Rn(i,t,o?n:!1)}i=a}}}function zn(e){e.f&=-257,Bn(e,!0)}function Bn(e,t){if(!(e.f&256)&&e.f&8192){e.f^=ee,e.f&1024||(tt(e,S),Mt.ensure().schedule(e));for(var n=e.first;n!==null;){var r=n.next,i=!!(n.f&65536)||!!(n.f&32);Bn(n,i?t:!1),n=r}var a=e.nodes&&e.nodes.t;if(a!==null)for(let e of a)(e.is_global||t)&&e.in()}}function Vn(e,t){if(e.nodes)for(var n=e.nodes.start,r=e.nodes.end;n!==null;){var i=n===r?null:cn(n);t.append(n),n=i}}var Hn=null,Un=!1,Wn=!1;function Gn(e){Wn=e}var z=null,Kn=!1;function qn(e){z=e}var B=null;function Jn(e){B=e}var Yn=null;function Xn(e){z!==null&&(z.f&2097152||z.f&2)&&(Yn??=new Set).add(e)}var Zn=null,Qn=0,$n=null;function er(e){$n=e}var tr=1,nr=0,rr=nr;function ir(e){rr=e}function ar(){return++tr}function or(e){var t=e.f;if(t&2048)return!0;if(t&4096){for(var n=e.deps,r=n.length,i=0;ie.wv)return!0}t&512&&wt===null&&tt(e,x)}return!1}function sr(e,t,n=!0){var r=e.reactions;if(r!==null&&!(Yn!==null&&Yn.has(e)))for(var i=0;i{e.ac.abort(be)}),e.ac=null);try{e.f|=ce;var u=e.fn,d=u();e.f|=ne;var f=lr(e);if(Ye()&&$n!==null&&!Kn&&f!==null&&!(e.f&6146))for(var p=0;p<$n.length;p++)sr($n[p],e);if(i!==null&&i!==e){if(nr++,i.deps!==null)for(let e=0;e0)for(t.length=Qn+Zn.length,r=0;r{c.ac.abort(be),c.ac=null,tt(c,S)}),bt(c),dr(c,0)}}function dr(e,t){var n=e.deps;if(n!==null)for(var r=t;rn?.call(this,e))}return e.startsWith(`pointer`)||e.startsWith(`touch`)||e===`wheel`?(i.__removed=!1,Qe(()=>{i.__removed||t.addEventListener(e,i,r)})):t.addEventListener(e,i,r),i}function xr(e,t,n,r,i){var a={capture:r,passive:i},o=br(e,t,n,a);(t===document.body||t===window||t===document||t instanceof HTMLMediaElement)&&yn(()=>{o.__removed=!0,t.removeEventListener(e,o,a)})}function Sr(e,t,n){(t[_r]??={})[e]=n}function Cr(e){for(var t=0;t{Tr=!1,wr=null}));var o=0,s=wr===e&&e[_r];if(s){var c=i.indexOf(s);if(c!==-1&&(t===document||t===window)){e[_r]=t;return}var u=i.indexOf(t);if(u===-1)return;c<=u&&(o=c)}if(a=i[o]||e.target,a!==t){l(e,`currentTarget`,{configurable:!0,get(){return a||n}});var d=z,f=B;qn(null),Jn(null);try{for(var p,m=[];a!==null&&a!==t;){try{var h=a[_r]?.[r];h!=null&&(!a.disabled||e.target===a)&&h.call(a,e)}catch(e){p?m.push(e):p=e}if(e.cancelBubble)break;o++,a=o{throw e});throw p}}finally{e[_r]=t,delete e.currentTarget,qn(d),Jn(f)}}}var Dr=globalThis?.window?.trustedTypes&&globalThis.window.trustedTypes.createPolicy(`svelte-trusted-html`,{createHTML:e=>e});function Or(e){return Dr?.createHTML(e)??e}function kr(e){var t=dn(`template`);return t.innerHTML=Or(e.replaceAll(``,``)),t.content}function Ar(e,t){var n=B;n.nodes===null&&(n.nodes={start:e,end:t,a:null,t:null})}function W(e,t){var n=!!(t&1),r=!!(t&2),i,a=!e.startsWith(``);return()=>{if(w)return Ar(T,null),T;i===void 0&&(i=kr(a?e:``+e),n||(i=sn(i)));var t=r||tn?document.importNode(i,!0):i.cloneNode(!0);if(n){var o=sn(t),s=t.lastChild;Ar(o,s)}else Ar(t,t);return t}}function jr(e=``){if(!w){var t=on(e+``);return Ar(t,t),t}var n=T;return n.nodeType===3?fn(n):(n.before(n=on()),De(n)),Ar(n,n),n}function Mr(){if(w)return Ar(T,null),T;var e=document.createDocumentFragment(),t=document.createComment(``),n=on();return e.append(t,n),Ar(t,n),e}function G(e,t){if(w){var n=B;(!(n.f&32768)||n.nodes.end===null)&&(n.nodes.end=T),Oe();return}e!==null&&e.before(t)}[...`allowfullscreen.async.autofocus.autoplay.checked.controls.default.disabled.formnovalidate.indeterminate.inert.ismap.loop.multiple.muted.nomodule.novalidate.open.playsinline.readonly.required.reversed.seamless.selected.webkitdirectory.defer.disablepictureinpicture.disableremoteplayback`.split(`.`)];var Nr=[`touchstart`,`touchmove`];function Pr(e){return Nr.includes(e)}function Fr(e){let t=0,n=Ut(0),r;return()=>{vn()&&(V(n),On(()=>(t===0&&(r=H(()=>e(()=>Yt(n)))),t+=1,()=>{Qe(()=>{--t,t===0&&(r?.(),r=void 0,Yt(n))})})))}}var Ir=ie|ae;function Lr(e,t,n,r){new Rr(e,t,n,r)}var Rr=class{parent;is_pending=!1;transform_error;#e;#t=w?T:null;#n;#r;#i;#a=null;#o=null;#s=null;#c=null;#l=0;#u=0;#d=!1;#f=new Set;#p=new Set;#m=null;#h=Fr(()=>(this.#m=Ut(this.#l),()=>{this.#m=null}));constructor(e,t,n,r){this.#e=e,this.#n=t,this.#r=e=>{var t=B;t.b=this,t.f|=128,n(e)},this.parent=B.b,this.transform_error=r??this.parent?.transform_error??(e=>e),this.#i=kn(()=>{if(w){let e=this.#t;Oe();let t=e.data===`[!`;if(e.data.startsWith(`[?`)){let t=JSON.parse(e.data.slice(2));this.#_(t)}else t?this.#y():this.#g()}else this.#b()},Ir),w&&(this.#e=T)}#g(){try{this.#a=An(()=>this.#r(this.#e))}catch(e){this.error(e)}}#_(e){let t=this.#n.failed,{reset:n,invoke_onerror:r}=this.#v(e);Qe(r),t&&(this.#s=An(()=>{t(this.#e,()=>e,()=>n)}))}#v(e){var t=!1,n=!1;let r=()=>{if(t){Te();return}t=!0,n&&Ke(),this.#s!==null&&Ln(this.#s,()=>{this.#s=null}),this.#S(()=>{this.#b()})};return{reset:r,invoke_onerror:()=>{try{n=!0,this.#n.onerror?.(e,r),n=!1}catch(e){mn(e,this.#i&&this.#i.parent)}}}}#y(){let e=this.#n.pending;e&&(this.is_pending=!0,this.#o=An(()=>e(this.#e)),Qe(()=>{var e=this.#c=document.createDocumentFragment(),t=on(),n=!1;if(e.append(t),this.#a=this.#S(()=>{try{return An(()=>this.#r(t))}catch(e){try{this.error(e),n=!0}catch(e){mn(e,this.#i.parent)}return null}}),this.#a===null){this.#c=null,n&&this.#x(j);return}this.#u===0&&(this.#e.before(e),this.#c=null,Ln(this.#o,()=>{this.#o=null}),this.#x(j))}))}#b(){try{if(this.is_pending=this.has_pending_snippet(),this.#u=0,this.#l=0,this.#a=An(()=>{this.#r(this.#e)}),this.#u>0){var e=this.#c=document.createDocumentFragment();Vn(this.#a,e);let t=this.#n.pending;this.#o=An(()=>t(this.#e))}else this.#x(j)}catch(e){this.error(e)}}#x(e){this.is_pending=!1,e.transfer_effects(this.#f,this.#p)}defer_effect(e){rt(e,this.#f,this.#p)}is_rendered(){return!this.is_pending&&(!this.parent||this.parent.is_rendered())}has_pending_snippet(){return!!this.#n.pending}#S(e){var t=B,n=z,r=D;Jn(this.#i),qn(this.#i),qe(this.#i.ctx);try{return Mt.ensure(),e()}finally{Jn(t),qn(n),qe(r)}}#C(e,t){if(!this.has_pending_snippet()){this.parent&&this.parent.#C(e,t);return}this.#u+=e,this.#u===0&&(this.#x(t),this.#o&&Ln(this.#o,()=>{this.#o=null}),this.#c&&=(this.#e.before(this.#c),null))}update_pending_count(e,t){this.#C(e,t),this.#l+=e,!(!this.#m||this.#d)&&(this.#d=!0,Qe(()=>{this.#d=!1,this.#m&&qt(this.#m,this.#l)}))}get_effect_pending(){return this.#h(),V(this.#m)}error(e){if(!this.#n.onerror&&!this.#n.failed)throw e;j?.is_fork?(this.#a&&j.skip_effect(this.#a),this.#o&&j.skip_effect(this.#o),this.#s&&j.skip_effect(this.#s),j.oncommit(()=>{this.#w(e)})):this.#w(e)}#w(e){this.#a&&=(Pn(this.#a),null),this.#o&&=(Pn(this.#o),null),this.#s&&=(Pn(this.#s),null),w&&(De(this.#t),ke(),De(Ae()));let t=this.#n.failed,n=e=>{let{reset:n,invoke_onerror:r}=this.#v(e);r(),t&&(this.#s=this.#S(()=>{try{return An(()=>{var r=B;r.b=this,r.f|=128,t(this.#e,()=>e,()=>n)})}catch(e){return mn(e,this.#i.parent),null}}))};Qe(()=>{var t;try{t=this.transform_error(e)}catch(e){mn(e,this.#i&&this.#i.parent);return}typeof t==`object`&&t&&typeof t.then==`function`?t.then(n,e=>mn(e,this.#i&&this.#i.parent)):n(t)})}};function K(e,t){var n=t==null?``:typeof t==`object`?`${t}`:t;n!==(e[ve]??=e.nodeValue)&&(e[ve]=n,e.nodeValue=`${n}`)}function zr(e,t){return Vr(e,t)}var Br=new Map;function Vr(e,{target:t,anchor:r,props:i={},events:a,context:o,intro:s=!0,transformError:l}){an();var u=void 0,d=Cn(()=>{var s=r??t.appendChild(on());Lr(s,{pending:()=>{}},t=>{O({});var r=D;if(o&&(r.c=o),a&&(i.$$events=a),w&&Ar(t,null),u=e(t,i)||Je(),w&&(B.nodes.end=T,T===null||T.nodeType!==8||T.data!==`]`))throw Ce(),n;k()},l);var d=new Set,f=e=>{for(var n=0;n{for(var e of d)for(let r of[t,document]){var n=Br.get(r),i=n.get(e);--i==0?(r.removeEventListener(e,Er),n.delete(e),n.size===0&&Br.delete(r)):n.set(e,i)}yr.delete(f),s!==r&&s.parentNode?.removeChild(s)}});return Hr.set(u,d),u}var Hr=new WeakMap,Ur=class{anchor;#e=new Map;#t=new Map;#n=new Map;#r=new Set;#i=!0;constructor(e,t=!0){this.anchor=e,this.#i=t}#a=e=>{if(this.#e.has(e)){var t=this.#e.get(e),n=this.#t.get(t);if(n)zn(n),this.#r.delete(t);else{var r=this.#n.get(t);r&&(zn(r.effect),this.#t.set(t,r.effect),this.#n.delete(t),r.fragment.lastChild.remove(),this.anchor.before(r.fragment),n=r.effect)}for(let[t,n]of this.#e){if(this.#e.delete(t),t===e)break;let r=this.#n.get(n);r&&(Pn(r.effect),this.#n.delete(n))}for(let[e,r]of this.#t){if(e===t||this.#r.has(e))continue;let i=()=>{if(Array.from(this.#e.values()).includes(e)){var t=document.createDocumentFragment();Vn(r,t),t.append(on()),this.#n.set(e,{effect:r,fragment:t})}else Pn(r);this.#r.delete(e),this.#t.delete(e)};this.#i||!n?(this.#r.add(e),Ln(r,i,!1)):i()}}};#o=e=>{this.#e.delete(e);let t=Array.from(this.#e.values());for(let[e,n]of this.#n)t.includes(e)||(Pn(n.effect),this.#n.delete(e))};ensure(e,t){var n=j,r=un();if(t&&!this.#t.has(e)&&!this.#n.has(e)){if(r){var i=document.createDocumentFragment(),a=on();i.append(a),this.#n.set(e,{effect:An(()=>t(a)),fragment:i})}else this.#t.set(e,An(()=>t(this.anchor)))}if(this.#e.set(n,e),r){for(let[t,r]of this.#t)t===e?n.unskip_effect(r):n.skip_effect(r);for(let[t,r]of this.#n)t===e?n.unskip_effect(r.effect):n.skip_effect(r.effect);n.oncommit(this.#a),n.ondiscard(this.#o)}else w&&(this.anchor=T),this.#a(n)}};function Wr(t){D===null&&Fe(`onMount`),e&&D.l!==null?Gr(D).m.push(t):bn(()=>{let e=H(t);if(typeof e==`function`)return e})}function Gr(e){var t=e.l;return t.u??={a:[],b:[],m:[]}}function q(e,t,n=!1){var r;w&&(r=T,Oe());var i=new Ur(e),a=n?ie:0;function o(e,t){if(w){var n=je(r);if(e!==parseInt(n.substring(1))){var a=Ae();De(a),i.anchor=a,Ee(!1),i.ensure(e,t),Ee(!0);return}}i.ensure(e,t)}kn(()=>{var e=!1;t((t,n=0)=>{e=!0,o(n,t)}),e||o(-1,null)},a)}var Kr=Symbol(`NaN`);function qr(e,t,n){w&&Oe();var r=new Ur(e),i=!Ye();kn(()=>{var e=t();e!==e&&(e=Kr),i&&typeof e==`object`&&e&&(e={}),r.ensure(e,n)})}function Jr(e,t){return t}function Yr(e,t,n){for(var r=[],i=t.length,a,o=t.length,s=0;s{if(a){if(a.pending.delete(n),a.done.add(n),a.pending.size===0){var t=e.outrogroups;Xr(e,c(a.done)),t.delete(a),t.size===0&&(e.outrogroups=null)}}else--o},!1)}if(o===0){var l=r.length===0&&n!==null&&e.pending.size===0;if(l){var u=n,d=u.parentNode;ln(d),d.append(u),e.items.clear()}Xr(e,t,!l)}else a={pending:new Set(t),done:new Set},(e.outrogroups??=new Set).add(a)}function Xr(e,t,n=!0){var r;if(e.pending.size>0){r=new Set;for(let t of e.pending.values())for(let n of t)r.add(e.items.get(n).e)}for(var i=0;i{var e=n();return a(e)?e:e==null?[]:c(e)}),p,m=new Map,h=!0;function g(e){v.effect.f&16384||(v.pending.delete(e),v.fallback=d,ei(v,p,s,t,r),d!==null&&(p.length===0?d.f&33554432?(d.f^=se,ni(d,null,s)):zn(d):Ln(d,()=>{d=null})))}function _(e){v.pending.delete(e)}var v={effect:kn(()=>{p=V(f);var e=p.length;let a=!1;w&&je(s)===`[!`!=(e===0)&&(s=Ae(),De(s),Ee(!1),a=!0);for(var c=new Set,u=j,v=un(),y=0;yo(s)):(d=An(()=>o(Zr??=on())),d.f|=se)),e>c.size&&Le(``,``,``),w&&e>0&&De(Ae()),!h){if(m.set(u,c),v){for(let[e,t]of l)c.has(e)||u.skip_effect(t.e);u.oncommit(g),u.ondiscard(_)}else g(u)}a&&Ee(!0),V(f)}),flags:t,items:l,pending:m,outrogroups:null,fallback:d};h=!1,w&&(s=T)}function $r(e){for(;e!==null&&!(e.f&32);)e=e.next;return e}function ei(e,t,n,r,i){var a=!!(r&8),o=t.length,s=e.items,l=$r(e.effect.first),u,d=null,f,p=[],m=[],h,g,_,v;if(a)for(v=0;v0){var ne=r&4&&o===0?n:null;if(a){for(v=0;v{if(f!==void 0)for(_ of f)_.nodes?.a?.apply()})}function ti(e,t,n,r,i,a,o,s){var c=o&1?o&16?Ut(n):M(n,!1,!1):null,l=o&2?Ut(i):null;return{v:c,i:l,e:An(()=>(a(t,c??n,l??i,s),()=>{e.delete(r)}))}}function ni(e,t,n){if(e.nodes)for(var r=e.nodes.start,i=e.nodes.end,a=t&&!(t.f&33554432)?t.nodes.start:n;r!==null;){var o=cn(r);if(a.before(r),r===i)return;r=o}}function ri(e,t,n){t===null?e.effect.first=n:t.next=n,n===null?e.effect.last=t:n.prev=t}function ii(e,t,n){wn(()=>{var r=H(()=>t(e,n?.())||{});if(n&&r?.update){var i=!1,a={};On(()=>{var e=n();U(e),i&&Ne(a,e)&&(a=e,r.update(e))}),i=!0}if(r?.destroy)return()=>r.destroy()})}function ai(e){var t,n,r=``;if(typeof e==`string`||typeof e==`number`)r+=e;else if(typeof e==`object`){if(Array.isArray(e)){var i=e.length;for(t=0;t=0;){var s=o+a;(o===0||ci.includes(r[o-1]))&&(s===r.length||ci.includes(r[s]))?r=(o===0?``:r.substring(0,o))+r.substring(s+1):o=s}}return r===``?null:r}function ui(e,t,n,r,i,a){var o=e[ge];if(w||o!==n||o===void 0){var s=li(n,r,a);(!w||s!==e.getAttribute(`class`))&&(s==null?e.removeAttribute(`class`):t?e.className=s:e.setAttribute(`class`,s)),e[ge]=n}else if(a&&i!==a)for(var c in a){var l=!!a[c];(i==null||l!==!!i[c])&&e.classList.toggle(c,l)}return a}function di(e,t){t?e.hasAttribute(`selected`)||e.setAttribute(`selected`,``):e.removeAttribute(`selected`)}function fi(e,t){var n=e.__defaultValue,r=e.multiple,i=r?n??[]:null;if(!r||a(i)){var o=e.selectedIndex,s=t&&r?new Set(e.selectedOptions):null;for(var c of e.options){var l=gi(c);di(c,r?i.includes(l):$t(l,n))}if(t){if(s!==null)for(c of e.options){var u=s.has(c);c.selected!==u&&(c.selected=u)}else e.selectedIndex!==o&&(e.selectedIndex=o)}}}function pi(e,t,n=!1){if(e.multiple){if(t==null)return;if(!a(t))return we();for(var r of e.options)r.selected=t.includes(gi(r));return}for(r of e.options)if($t(gi(r),t)){r.selected=!0;return}(!n||t!==void 0)&&(e.selectedIndex=-1)}function mi(e){var t=new MutationObserver(t=>{t.every(_i)||(`__defaultValue`in e&&fi(e,!1),`__value`in e&&pi(e,e.__value))});t.observe(e,{childList:!0,subtree:!0,attributes:!0,attributeFilter:[`value`]}),yn(()=>{t.disconnect()})}function hi(e,t,n=t){var r=new WeakSet,i=!0;ct(e,`change`,t=>{var i=t?`[selected]`:`:checked`,a;if(e.multiple)a=[].map.call(e.querySelectorAll(i),gi);else{var o=e.querySelector(i)??e.querySelector(`option:not([disabled])`);a=o&&gi(o)}n(a),e.__value=a,j!==null&&r.add(j)}),wn(()=>{var a=t();if(e===document.activeElement){var o=j;if(r.has(o))return}if(pi(e,a,i),i&&a===void 0){var s=e.querySelector(`:checked`);s!==null&&(a=gi(s),n(a))}e.__value=a,i=!1})}function gi(e){return`__value`in e?e.__value:e.value}function _i(e){if(e.target.closest(`selectedcontent`)!==null)return!0;if(e.type===`childList`){var t=[...e.addedNodes,...e.removedNodes];return t.length>0&&t.every(e=>e.nodeName===`SELECTEDCONTENT`)}return!1}var vi=Symbol(`is custom element`),yi=Symbol(`is html`),bi=xe?`link`:`LINK`;function xi(e){if(w){var t=!1,n=()=>{if(!t){if(t=!0,e.hasAttribute(`value`)){var n=e.value;J(e,`value`,null),e.value=n}if(e.hasAttribute(`checked`)){var r=e.checked;J(e,`checked`,null),e.checked=r}}};e[ye]=n,Qe(n),ot()}}function Si(e,t){var n=Ci(e);n.checked!==(n.checked=t??void 0)&&(e.checked=t)}function J(e,t,n,r){var i=Ci(e);w&&(i[t]=e.getAttribute(t),t===`src`||t===`srcset`||t===`href`&&e.nodeName===bi)||i[t]!==(i[t]=n)&&(t===`loading`&&(e[me]=n),n==null?e.removeAttribute(t):typeof n!=`string`&&Ti(e).has(t)?e[t]=n:e.setAttribute(t,n))}function Ci(e){return e[he]??={[vi]:e.nodeName.includes(`-`),[yi]:e.namespaceURI===i}}var wi=new Map;function Ti(e){var t=e.getAttribute(`is`)||e.nodeName,n=wi.get(t);if(n)return n;wi.set(t,n=new Set);for(var r,i=e,a=Element.prototype;a!==i;){for(var o in r=d(i),r)r[o].set&&o!==`innerHTML`&&o!==`textContent`&&o!==`innerText`&&n.add(o);i=m(i)}return n}function Ei(e,t,n=t){var r=new WeakSet;ct(e,`input`,async i=>{var a=i?e.defaultValue:e.value;if(a=Di(e)?Oi(a):a,n(a),j!==null&&r.add(j),await pr(),a!==(a=t())){var o=e.selectionStart,s=e.selectionEnd,c=e.value.length;if(e.value=a??``,s!==null){var l=e.value.length;o===s&&s===c&&l>c?(e.selectionStart=l,e.selectionEnd=l):(e.selectionStart=o,e.selectionEnd=Math.min(s,l))}}}),(w&&e.defaultValue!==e.value||H(t)==null&&e.value)&&(n(Di(e)?Oi(e.value):e.value),j!==null&&r.add(j)),On(()=>{var n=t();if(e===document.activeElement){var i=j;if(r.has(i))return}Di(e)&&n===Oi(e.value)||(e.type!==`date`||n||e.value)&&n!==e.value&&(e.value=n??``)})}function Di(e){var t=e.type;return t===`number`||t===`range`}function Oi(e){return e===``?null:+e}function Y(e=!1){let t=D,n=t.l.u;if(!n)return;let r=()=>U(t.s);if(e){let e=0,n={},i=pt(()=>{let r=!1,i=t.s;for(let e in i)i[e]!==n[e]&&(n[e]=i[e],r=!0);return r&&e++,e});r=()=>V(i)}n.b.length&&Sn(()=>{ki(t,r),v(n.b)}),bn(()=>{let e=H(()=>n.m.map(_));return()=>{for(let t of e)typeof t==`function`&&t()}}),n.a.length&&bn(()=>{ki(t,r),v(n.a)})}function ki(e,t){if(e.l.s)for(let t of e.l.s)V(t);t()}function Ai(e,t,n){if(e==null)return t(void 0),n&&n(void 0),g;let r=H(()=>e.subscribe(t,n));return r.unsubscribe?()=>r.unsubscribe():r}var ji=[];function Mi(e,t=g){let n=null,r=new Set;function i(t){if(Ne(e,t)&&(e=t,n)){let t=!ji.length;for(let t of r)t[1](),ji.push(t,e);if(t){for(let e=0;e{r.delete(c),r.size===0&&n&&(n(),n=null)}}return{set:i,update:a,subscribe:o}}function Ni(e){let t;return Ai(e,e=>t=e)(),t}var Pi=!1,Fi=Symbol(`unmounted`);function X(e,t,n){let r=n[t]??={store:null,source:M(void 0),unsubscribe:g};if(r.store!==e&&!(Fi in n)){if(r.unsubscribe(),r.store=e??null,e==null)r.source.v=void 0,r.unsubscribe=g;else{var i=!0;r.unsubscribe=Ai(e,e=>{i?r.source.v=e:N(r.source,e)}),i=!1}}return e&&Fi in n?Ni(e):V(r.source)}function Ii(){let e={};function t(){yn(()=>{for(var t in e)e[t].unsubscribe();l(e,Fi,{enumerable:!1,value:!0})})}return[e,t]}function Li(e){var t=Pi;try{return Pi=!1,[e(),Pi]}finally{Pi=t}}function Z(t,n,r,i){var a=!e||!!(r&2),o=!!(r&8),s=!!(r&16),c=i,l=!0,d=void 0,f=()=>s&&a?(d??=pt(i),V(d)):(l&&(l=!1,c=s?H(i):i),c);let p;if(o){var m=de in t||pe in t;p=u(t,n)?.set??(m&&n in t?e=>t[n]=e:void 0)}var h,g=!1;o?[h,g]=Li(()=>t[n]):h=t[n],h===void 0&&i!==void 0&&(h=f(),p&&(a&&He(n),p(h)));var _=a?()=>{var e=t[n];return e===void 0?f():(l=!0,e)}:()=>{var e=t[n];return e!==void 0&&(c=void 0),e===void 0?c:e};if(a&&!(r&4))return _;if(p){var v=t.$$legacy;return(function(e,t){return arguments.length>0?((!a||!t||v||g)&&p(t?_():e),e):_()})}var y=!1,b=(r&1?pt:A)(()=>(y=!1,_()));o&&V(b);var x=B;return(function(e,t){if(arguments.length>0){let n=t?V(b):a&&o?Zt(e):e;return N(b,n),y=!0,c!==void 0&&(c=n),e}return Wn&&y||x.f&16384?b.v:V(b)})}function Ri(e){let t=Mi({paired:!!e,controller:!1,busy:!1,error:``}),n=e,r,i={paired:!!e,controller:!1,busy:!1,error:``},a=!1;function o(e){i={...i,...e},t.set(i)}async function s(e=!1){if(!a&&n){a=!0;try{let t=await fetch(`/api/state`,{cache:`no-store`,headers:{"X-Setup-Session-Key":n}});if(!t.ok)throw Error(`The local setup session is unavailable.`);o({view:await t.json(),...e?{}:{error:``}})}catch{o({view:void 0,error:`Connection lost. The CLI may have stopped. Check the terminal before trying again.`})}finally{a=!1}}}let c=()=>s(!0);async function l(){if(n)try{let e=await fetch(`/api/bootstrap`,{cache:`no-store`,headers:{"X-Setup-Session-Key":n}});if(!e.ok)throw Error(`Could not join this local session.`);let t=await e.json();r=t.capability,o({controller:t.controller,error:``}),await s()}catch{n=void 0,r=void 0,o({view:void 0,paired:!1,controller:!1,error:`Could not connect to the local setup session. Check the terminal and pair again.`})}}async function u(e){if(!(i.busy||i.paired)){o({busy:!0,error:``});try{let t=await fetch(`/api/pair`,{method:`POST`,cache:`no-store`,headers:{"Content-Type":`application/json`},body:JSON.stringify({code:e.trim().toLowerCase()})}),r=await t.json();if(!t.ok)throw Error(String(r.error??`Pairing was rejected.`));if(typeof r.sessionKey!=`string`||!/^[a-f0-9]{64}$/.test(r.sessionKey))throw Error(`Invalid local pairing response.`);n=r.sessionKey,o({paired:!0,error:``}),await l()}catch(e){o({error:e instanceof Error?e.message:`Could not pair this browser.`})}finally{o({busy:!1})}}}async function d(e,t,i=!0){let a=await fetch(e,{method:`POST`,cache:`no-store`,headers:{"Content-Type":`application/json`,"X-Setup-Session-Key":n,...i&&r?{"X-Setup-Capability":r}:{}},body:JSON.stringify(t)}),o=await a.json();if(!a.ok)throw Error(String(o.error??`The request was rejected.`));return o}async function f(e,t){let n=e instanceof Error?e.message:t;o({error:n}),/read-only|Control moved/.test(n)?await l():await s(!0)}async function p(e,t){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/answer`,{revision:e,value:t}),await s()}catch(e){await f(e,`Could not submit this answer.`)}finally{o({busy:!1})}}}async function m(e){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/retry-discovery`,{revision:e}),await s()}catch(e){await f(e,`Could not retry discovery.`)}finally{o({busy:!1})}}}async function h(e){if(!i.busy&&i.controller&&i.view?.promptRevision===e){o({busy:!0,error:``});try{await d(`/api/back`,{revision:e}),await s()}catch(e){await f(e,`Could not return to the previous question.`)}finally{o({busy:!1})}}}async function g(){if(i.controller&&!i.busy){o({busy:!0,error:``});try{await d(`/api/cancel`,{}),await s()}catch(e){let t=e instanceof Error?e.message:`Cancellation failed.`;o({error:t}),/read-only|Control moved/.test(t)&&await l()}finally{o({busy:!1})}}}async function _(e){if(!(i.busy||!i.paired||i.controller)){o({busy:!0,error:``});try{let t=await d(`/api/takeover`,{code:e.trim().toLowerCase()},!1);r=String(t.capability),o({controller:!0,error:``}),await s()}catch(e){o({error:e instanceof Error?e.message:`Takeover failed.`}),await s(!0)}finally{o({busy:!1})}}}async function v(){try{await d(`/api/close`,{})}catch{}}async function y(){if(!i.busy&&i.controller&&i.view?.outcome===`complete`){o({busy:!0,error:``,view:{...i.view,doctor:{status:`running`}}});try{await d(`/api/doctor`,{})}catch(e){o({error:e instanceof Error?e.message:`Read-only verification failed.`})}finally{await s(!0),o({busy:!1})}}}return{subscribe:t.subscribe,pair:u,connect:l,refresh:s,poll:c,submit:p,retryDiscovery:m,back:h,cancel:g,takeOver:_,close:v,runDoctor:y}}var zi={language:`Language`,english:`English`,spanish:`Español`,setup:`SETUP`,connecting:`Connecting…`,localSession:`LOCAL SESSION`,progress:`Setup progress`,studio:`SETUP STUDIO`,journey:`YOUR SETUP JOURNEY`,repository:`Repository`,choices:`Setup choices`,setupPat:`Setup PAT`,plan:`Plan`,botPat:`Bot PAT & credentials`,apply:`Apply`,localDesign:`Local by design`,localDesignBody:`This page runs on your computer. GitHub creates both PATs in its own browser tabs.`,preparing:`Preparing your setup…`,completeTitle:`Setup complete.`,previewTitle:`Preview complete.`,cancelledTitle:`Setup cancelled.`,blockedTitle:`Setup needs attention.`,gettingReady:`GETTING READY`,activeLede:`One decision at a time. Your choices shape the permissions, plan and credentials needed for this repository.`,resultLede:`Review the result and next action below. The terminal has additional technical detail.`,readOnly:`Read-only tab`,readOnlyBody:`Another tab controls this session. You can review progress here or explicitly take over.`,takeOver:`Take control in this tab`,attention:`Needs attention`,checked:`Checked`,pleaseNote:`Please note`,progressUpdate:`Progress update`,reviewPass:`Reviewing saved choices — pass {pass}. This is the same setup run, not a restart.`,cancelSetup:`Cancel setup`,cancelConfirm:`Cancel this local setup session? PATs already created in GitHub will still exist.`,footerLocal:`LOCALHOST ONLY`,footerCloud:`NO CLOUD SETUP ACCOUNT`,footerGithub:`GITHUB OWNS PAT ISSUANCE`,currentDecision:`CURRENT DECISION`,session:`SESSION`,continue:`Continue`,previousQuestion:`Previous question`,questionProgress:`Question {current} of {total} in this group · {overall} of {all} overall`,yes:`Yes`,no:`No`,permissionPreview:`PERMISSION PREVIEW`,changeAnswersTitle:`Change your answers`,changeAnswersHelp:`Return to a section without losing other answers. The plan and required PAT grants will be checked again.`,changeSection:`Change {section}`,editCapabilities:`Capabilities`,editRuntimes:`Agent runtimes`,editModels:`Agent models`,editRoleModels:`Per-role models`,editRepository:`Repository behavior`,editDeployment:`Release and hotfix`,editBugbot:`Bugbot`,editApproval:`PR approval`,editProjects:`Projects`,editProvisioning:`Provisioning`,editStorage:`Secrets and Variables`,suggested:`Suggested answer: {answer}. You can review choices again before creating your setup PAT.`,none:`none`,sourceGithub:`Observed from authenticated GitHub repository metadata.`,sourceConfig:`Provided by your configuration; GitHub has not replaced it.`,sourceDefault:`Product default; not verified against this repository.`,sourceLocal:`Observed in this local checkout; confirm this branch exists on GitHub before applying.`,whyMatters:`Why this matters`,whenApplies:`When it applies`,whereConfigured:`Where it is configured`,howToChoose:`How to choose`,whyRecommendation:`Why this matters`,example:`Example`,effect:`What changes`,verify:`How to check`,learnMore:`Read documentation about this setting`,resultApplied:`Your configuration was applied`,resultNoChanges:`No changes were made`,resultStopped:`No setup changes started`,resultPartial:`Check partial changes before retrying`,resultCompleteBody:`The temporary setup PAT is not revoked automatically. Delete it in GitHub after confirming your setup. Keep the bot PAT until you rotate the installed Secret.`,resultPartialBody:`A bot Secret write or another change may have succeeded. Inspect GitHub and run copilot doctor --read-only before replacing or deleting its PAT.`,resultNoChangesBody:`Copilot did not begin applying setup changes. PATs you created in GitHub still exist until you delete them there.`,whatHappened:`What happened`,alreadyChanged:`Already changed`,noChanges:`No repository or GitHub setup changes were started in this session.`,nextAction:`Next action`,reasonPermissions:`The setup PAT lacked or could not confirm required permissions.`,nextPermissions:`Check the displayed grants, correct the PAT in GitHub, then start a fresh setup run.`,reasonStorage:`The selected GitHub Actions storage could not be used safely.`,nextStorage:`Inspect the Variables/Secrets scope and existing resources, then retry.`,reasonConfiguration:`The chosen configuration could not be validated.`,nextConfiguration:`Review the terminal validation details, correct the choices, and retry.`,reasonExpired:`The local setup session expired before applying changes.`,nextExpired:`Start a new setup session; the old approval cannot be replayed.`,reasonCancelled:`This setup was cancelled before applying changes.`,nextCancelled:`Start a new run if you still want to configure this repository.`,reasonUnknown:`Setup stopped before Apply. The browser could not determine the exact cause.`,nextUnknown:`Check the final terminal error before retrying; do not assume a PAT was revoked.`,reasonProvider:`GitHub or another provider did not complete the requested operation.`,nextProvider:`Use the diagnostic reference to inspect the terminal result, check provider availability and access, then retry only after reviewing possible partial changes.`,reasonRateLimit:`GitHub temporarily limited the requests needed for setup.`,nextRateLimit:`Wait for the limit to reset. Inspect any completed changes before starting another setup run.`,diagnosticReference:`Diagnostic reference`,resourceReceipt:`Setup operation receipt`,effectCompleted:`Reported completed`,effectSkipped:`Reported skipped`,effectInspect:`Outcome needs inspection`,effectNotStarted:`Not started`,scopeLocal:`Local checkout`,scopeMixed:`Repository and organization`,receiptFiles:`Setup files`,receiptSecrets:`GitHub Actions Secrets`,receiptLabels:`Issue labels`,receiptIssueTypes:`Issue types`,receiptVariables:`GitHub Actions Variables`,receiptInitialTag:`Initial version tag`,inspectPartial:`Some setup changes may already be active. Inspect GitHub and the terminal result before retrying.`,patSettings:`Open GitHub PAT settings ↗`,closeSession:`Close local session`,doctorHelp:`After success, you can verify installed resources here without dispatching Actions. Or run copilot doctor --read-only from the repository root with the temporary setup PAT and the same non-secret --config file, if used.`,doctorRun:`Verify installed setup (read-only)`,doctorRunning:`Checking installed resources without dispatching Actions…`,doctorPassed:`Read-only verification found no failing checks.`,doctorWarnings:`Read-only verification needs attention.`,doctorFailed:`Read-only verification did not finish. Check the terminal or run the command below.`,doctorCounts:`{pass} passed · {warn} warnings · {fail} failed · {skipped} skipped.`,doctorSecretLimit:`Secret values cannot be verified in this mode.`,botRenewal:`The bot PAT stays in the selected GitHub Actions Secret for future runs. Its actual expiry is not verified here; record it in GitHub and rotate the Secret before expiry.`,working:`Working on the next step`,workingBody:`The local process is checking your answers and preparing the next decision. Keep this page open.`,repoFocus:`Repository in focus`,repoFocusBody:`All decisions in this session target only:`,access:`access`,readOnlyCheck:`Read-only access check`,provisionalGrants:`Provisional least-privilege grants`,conditionalGrants:`Conditional grants depend on the choices and GitHub facts. A final audit runs before setup changes.`,permissionUnknown:`This permission needs review. Check its exact grant and technical explanation in the terminal before continuing.`,permissionsFollow:`Permissions follow your choices`,permissionsFollowBody:`We’ll show the exact grants before you create each PAT. Nothing is created just by opening this page.`,files:`Files`,workflows:`Workflows`,variables:`Variables`,secretNames:`Secret names`,planBody:`Review exactly what this run may change. The bot PAT and any additional credentials are collected next.`,planChoices:`Your key decisions`,planEnabledCapabilities:`Enabled capabilities`,planBranchRoles:`Production / development branch`,planApprovalMode:`Pull-request approval`,planVariableScope:`Variables scope`,planSecretScope:`Secrets scope`,planInitialTag:`Create initial tag`,planAgentRouting:`Agent and model for each task`,planIssueWorkflows:`Issue workflows`,planTrustedChecks:`Trusted CI producers`,planCoverage:`Coverage evidence`,planProjectStatuses:`Project Status transitions`,planIssueResources:`Issue labels and issue types`,planIssueResourcesValue:`Checked or provisioned during Apply`,planProducerAttested:`CI identity and enforcing step verified by you`,planCoverageThreshold:`Minimum changed-line coverage`,planCoverageReporter:`Artifact-publishing workflow`,planReporterAttested:`Coverage reporter verified by you`,planAdvancedDefaults:`The plan also includes defaults for settings you did not change. Use Change below to inspect any section before approving.`,planUnknownWarning:`An additional plan warning could not be displayed here. Read the terminal warning before approving.`,planBasicDefaultsIntro:`Basic setup retained these advanced defaults. Open a section below to review or change them:`,scopeRepository:`Repository`,scopeOrganization:`Organization`,scopeDisabled:`Not provisioned`,approvalOff:`Off`,approvalRecommend:`Recommendation only`,approvalGuarded:`Guarded approval`,beforeContinue:`Before you continue`,stopHere:`Stop here`,approvePlan:`Approve this plan`,githubLink:`Open GitHub link ↗`,githubForm:`Open the official GitHub PAT form`,githubFormHelp:`Check the signed-in account, select Only select repositories, then select this repository. GitHub handles 2FA and creates the PAT.`,pasteHere:`Paste the value here`,yourAnswer:`Your answer`,hiddenAfter:`Hidden after submission`,typeAnswer:`Type your answer`,secretHelp:`Sent only to this local process. It will not be shown again or saved in browser storage.`,pairTitle:`Pair this browser`,pairLabel:`Pairing code from terminal`,pairPlaceholder:`16 hexadecimal characters`,pairBody:`Find the 16-character pairing code in the terminal that started copilot setup --web. Enter it here to view or control this setup. The code is never placed in the browser URL or stored after this page closes.`,pairHelp:`Keep the code private. After refreshing this page, enter it again to reconnect.`,pairButton:`Connect to local setup`,privateSession:`PRIVATE LOCAL SESSION`,theme:`Color theme`,themeAuto:`Auto`,themeSystem:`Follow system theme`,themeLight:`Light theme`,themeDark:`Dark theme`,selectOne:`Select one`,ciRun:`Open CI run on GitHub ↗`,manualCheck:`Check not listed? Enter exact name|App ID|workflow, separated by semicolons.`,checksObserved:`Recent CI jobs were found. Open each run and verify the exact job, App and enforcing coverage step before trusting it.`,checksNoRecent:`No recent pull-request workflow runs were found. Run your normal CI on a real pull request, or enter an exact producer manually.`,checksNoVerifiable:`Recent runs exist, but no job could be linked to an exact Check Run and App identity. Inspect GitHub or enter an exact producer manually.`,checksDenied:`GitHub did not allow CI discovery. Give the setup PAT Actions: read and Checks: read, or enter an exact producer manually.`,checksUnavailable:`GitHub CI discovery could not complete. This is not evidence that the repository has no checks. Retry setup or enter an exact producer manually.`,projectsObserved:`These existing Projects belong to the repository owner. Select only Projects this automation should update.`,projectsEmpty:`This bounded GitHub query returned no open, accessible organization Projects; it does not prove none exist. Check access or enter a verified Project number.`,projectsDenied:`GitHub did not allow Project discovery. Check organization Projects: read on the setup PAT, or enter Project numbers manually.`,projectsUnavailable:`GitHub Project discovery could not complete. This is not evidence that no Projects exist. Enter a verified Project number manually or retry.`,projectsUnsupported:`GitHub does not support listing personal Projects with a fine-grained PAT through this endpoint. Enter an existing Project number from its URL.`,discoveryTruncated:`Only a bounded sample of accessible Projects or recent checks was inspected. Use manual entry for an item not shown.`,checksDiscoveryScope:`Search scope: up to 20 recent pull-request workflow runs; at most 15 runs and 100 checks per commit are inspected.`,projectsDiscoveryScope:`Search scope: at most 30 open, accessible organization Projects from two pages; up to 100 fields are inspected per Project. Closed Projects are excluded.`,retryDiscovery:`Retry GitHub discovery`,retryRemaining:`{count} read-only retries left. Your answers stay here.`,retryExhausted:`No discovery retries remain. Inspect GitHub and use the manual option if the item is missing.`,observationTimeUnknown:`observation time unavailable`,branchRequirementUnknown:`Required by branch rule: not checked`,branchRequirementObserved:`Required on {branch} by an active ruleset for this exact check and App.`,ciRule:`Open required-check ruleset ↗`,projectSharedStatus:`All selected Projects must share each chosen Status value. This setup cannot assign a different Status vocabulary per Project.`,fixedWorkflowEnabled:`Your configuration fixes features.{kind}=true. Keep {kind} selected; edit --config or flags to change this.`,fixedWorkflowDisabled:`Your configuration fixes features.{kind}=false. Leave {kind} unselected; edit --config or flags to change this.`,fixedIssuesRequired:`Your configuration explicitly enables release or hotfix automation. Keep Issues enabled, or change --config or flags first.`,projectSelectionNotObserved:`Previously selected Project numbers are retained, but no longer appear in this GitHub result. Verify each in GitHub or remove it.`,removeSelection:`Remove selection`,projectTransitionIssueCreated:`New issue`,projectTransitionPullRequestCreated:`New pull request`,projectTransitionIssueInProgress:`Issue in progress`,projectTransitionPullRequestInProgress:`Pull request in progress`,projectUrl:`Open Project on GitHub ↗`,projectManual:`Project not listed? Enter its positive number or exact GitHub URL. PVT_ IDs are not accepted.`,projectStatusUnavailable:`Status options could not be verified for every selected Project. Enter the exact existing Status value after checking each Project in GitHub.`,projectStatusIncompatible:`Selected Projects have no shared Status values. Choose compatible Projects before continuing.`,producerName:`Check/job name`,producerAppId:`Source GitHub App ID`,producerWorkflow:`Workflow name`,producerAdd:`Add exact check`,producerRemove:`Remove check`,producerManualHelp:`Use the exact identity shown on GitHub. Adding it does not attest that it enforces coverage.`,producerManualInvalid:`Enter a check name, positive numeric App ID and workflow name. Do not use | or ; in names.`,translationPreviewTitle:`Translation review in progress`,translationPreviewBody:`First-party setup questions are translated. Some dynamic GitHub or provider diagnostics may still appear in English while localization review finishes. Changing language does not change your answers.`,unknownLocalError:`An unexpected local setup error occurred. Check the terminal for details, then refresh or restart setup.`},Bi={language:`Idioma`,english:`English`,spanish:`Español`,setup:`CONFIGURACIÓN`,connecting:`Conectando…`,localSession:`SESIÓN LOCAL`,progress:`Progreso de la configuración`,studio:`ASISTENTE DE CONFIGURACIÓN`,journey:`TU RECORRIDO`,repository:`Repositorio`,choices:`Opciones de configuración`,setupPat:`PAT de configuración`,plan:`Plan`,botPat:`PAT del bot y credenciales`,apply:`Aplicar`,localDesign:`Local por diseño`,localDesignBody:`Esta página se ejecuta en tu ordenador. GitHub crea ambos PAT en sus propias pestañas.`,preparing:`Preparando la configuración…`,completeTitle:`Configuración completada.`,previewTitle:`Vista previa completada.`,cancelledTitle:`Configuración cancelada.`,blockedTitle:`La configuración necesita atención.`,gettingReady:`PREPARANDO`,activeLede:`Una decisión cada vez. Tus elecciones determinan los permisos, el plan y las credenciales que necesita este repositorio.`,resultLede:`Revisa abajo el resultado y el siguiente paso. La terminal contiene más detalles técnicos.`,readOnly:`Pestaña de solo lectura`,readOnlyBody:`Otra pestaña controla esta sesión. Puedes ver el progreso aquí o tomar el control explícitamente.`,takeOver:`Tomar el control en esta pestaña`,attention:`Necesita atención`,checked:`Comprobado`,pleaseNote:`Ten en cuenta`,progressUpdate:`Actualización de progreso`,reviewPass:`Revisando las opciones guardadas — pasada {pass}. Es la misma ejecución, no un reinicio.`,cancelSetup:`Cancelar configuración`,cancelConfirm:`¿Cancelar esta sesión local? Los PAT ya creados en GitHub seguirán existiendo.`,footerLocal:`SOLO LOCALHOST`,footerCloud:`SIN CUENTA DE CONFIGURACIÓN EN LA NUBE`,footerGithub:`GITHUB EMITE LOS PAT`,currentDecision:`DECISIÓN ACTUAL`,session:`SESIÓN`,continue:`Continuar`,previousQuestion:`Pregunta anterior`,questionProgress:`Pregunta {current} de {total} en este grupo · {overall} de {all} en total`,yes:`Sí`,no:`No`,permissionPreview:`VISTA PREVIA DE PERMISOS`,changeAnswersTitle:`Cambiar respuestas`,changeAnswersHelp:`Vuelve a una sección sin perder las demás respuestas. Se comprobarán de nuevo el plan y los permisos necesarios del PAT.`,changeSection:`Cambiar {section}`,editCapabilities:`Funciones`,editRuntimes:`Agentes`,editModels:`Modelos de agentes`,editRoleModels:`Modelos por tarea`,editRepository:`Comportamiento del repositorio`,editDeployment:`Releases y hotfixes`,editBugbot:`Bugbot`,editApproval:`Aprobación de PR`,editProjects:`Projects`,editProvisioning:`Aprovisionamiento`,editStorage:`Secrets y Variables`,suggested:`Respuesta sugerida: {answer}. Podrás revisar las opciones antes de crear el PAT de configuración.`,none:`ninguna`,sourceGithub:`Consultado en los metadatos autenticados de este repositorio en GitHub.`,sourceConfig:`Valor de tu configuración; GitHub no lo ha sustituido.`,sourceDefault:`Valor predeterminado del producto; no verificado en este repositorio.`,sourceLocal:`Observado en este checkout local; confirma que la rama existe en GitHub antes de aplicar cambios.`,whyMatters:`Por qué importa`,whenApplies:`Cuándo se aplica`,whereConfigured:`Dónde se configura`,howToChoose:`Cómo elegir`,whyRecommendation:`Por qué importa`,example:`Ejemplo`,effect:`Qué cambia`,verify:`Cómo comprobarlo`,learnMore:`Leer documentación de esta opción`,resultApplied:`Tu configuración se ha aplicado`,resultNoChanges:`No se hicieron cambios`,resultStopped:`No se empezó a aplicar la configuración`,resultPartial:`Revisa los cambios parciales antes de reintentar`,resultCompleteBody:`El PAT temporal de configuración no se revoca automáticamente. Elimínalo en GitHub tras comprobar el resultado. Conserva el PAT del bot hasta que rotes el Secret instalado.`,resultPartialBody:`Puede haberse escrito el Secret del bot u otro recurso. Revisa GitHub y ejecuta copilot doctor --read-only antes de reemplazar o eliminar ese PAT.`,resultNoChangesBody:`Copilot no empezó a aplicar cambios de configuración. Los PAT creados en GitHub siguen existiendo hasta que los elimines allí.`,whatHappened:`Qué ha pasado`,alreadyChanged:`Qué ha cambiado`,noChanges:`No se iniciaron cambios de configuración en el repositorio ni en GitHub durante esta sesión.`,nextAction:`Siguiente paso`,reasonPermissions:`Faltan permisos del PAT de configuración o no pudieron confirmarse.`,nextPermissions:`Comprueba los permisos mostrados, corrige el PAT en GitHub e inicia una nueva sesión.`,reasonStorage:`No se pudo usar de forma segura el almacenamiento elegido de GitHub Actions.`,nextStorage:`Revisa el ámbito de Variables/Secrets y los recursos existentes; después, reinténtalo.`,reasonConfiguration:`No se pudo validar la configuración elegida.`,nextConfiguration:`Revisa el detalle de validación en la terminal, corrige las opciones y reinténtalo.`,reasonExpired:`La sesión local caducó antes de aplicar cambios.`,nextExpired:`Inicia una sesión nueva; la aprobación anterior no puede reutilizarse.`,reasonCancelled:`La sesión se canceló antes de aplicar cambios.`,nextCancelled:`Inicia una nueva ejecución si todavía quieres configurar este repositorio.`,reasonUnknown:`La configuración se detuvo antes de aplicar cambios. La web no pudo determinar la causa exacta.`,nextUnknown:`Consulta el último error de la terminal antes de reintentar; no supongas que se revocó ningún PAT.`,reasonProvider:`GitHub u otro proveedor no completó la operación solicitada.`,nextProvider:`Usa la referencia de diagnóstico para consultar la terminal, comprueba la disponibilidad y el acceso al proveedor y revisa posibles cambios parciales antes de reintentar.`,reasonRateLimit:`GitHub ha limitado temporalmente las solicitudes necesarias para la configuración.`,nextRateLimit:`Espera a que se restablezca el límite. Inspecciona los cambios completados antes de iniciar otra configuración.`,diagnosticReference:`Referencia de diagnóstico`,resourceReceipt:`Registro de operaciones de configuración`,effectCompleted:`Marcada como completada`,effectSkipped:`Marcada como omitida`,effectInspect:`Resultado pendiente de inspección`,effectNotStarted:`No iniciada`,scopeLocal:`Checkout local`,scopeMixed:`Repositorio y organización`,receiptFiles:`Archivos de configuración`,receiptSecrets:`Secrets de GitHub Actions`,receiptLabels:`Etiquetas de issues`,receiptIssueTypes:`Tipos de issue`,receiptVariables:`Variables de GitHub Actions`,receiptInitialTag:`Etiqueta de versión inicial`,inspectPartial:`Algunos cambios podrían estar activos. Revisa GitHub y el resultado de la terminal antes de reintentar.`,patSettings:`Abrir ajustes de PAT en GitHub ↗`,closeSession:`Cerrar sesión local`,doctorHelp:`Tras completar el setup, puedes comprobar aquí los recursos instalados sin lanzar Actions. También puedes ejecutar copilot doctor --read-only desde la raíz del repositorio con el PAT temporal y el mismo archivo --config no secreto, si lo usaste.`,doctorRun:`Comprobar instalación (solo lectura)`,doctorRunning:`Comprobando los recursos instalados sin lanzar Actions…`,doctorPassed:`La comprobación de solo lectura no encontró fallos.`,doctorWarnings:`La comprobación de solo lectura requiere atención.`,doctorFailed:`La comprobación de solo lectura no terminó. Revisa la terminal o ejecuta el comando indicado abajo.`,doctorCounts:`{pass} correctas · {warn} avisos · {fail} fallos · {skipped} omitidas.`,doctorSecretLimit:`Este modo no puede verificar los valores de Secrets.`,botRenewal:`El PAT del bot permanece en el Secret de GitHub Actions seleccionado para futuras ejecuciones. Su fecha real de caducidad no se verifica aquí; anótala en GitHub y rota el Secret antes de que venza.`,working:`Preparando el siguiente paso`,workingBody:`El proceso local comprueba tus respuestas y prepara la siguiente decisión. Mantén esta página abierta.`,repoFocus:`Repositorio seleccionado`,repoFocusBody:`Todas las decisiones de esta sesión afectan solo a:`,access:`acceso`,readOnlyCheck:`Comprobación de acceso de solo lectura`,provisionalGrants:`Permisos provisionales de mínimo privilegio`,conditionalGrants:`Los permisos condicionales dependen de tus elecciones y de GitHub. Se hará una auditoría final antes de cualquier cambio.`,permissionUnknown:`Este permiso requiere revisión. Comprueba en la terminal el permiso exacto y su explicación técnica antes de continuar.`,permissionsFollow:`Los permisos dependen de tus elecciones`,permissionsFollowBody:`Mostraremos los permisos exactos antes de crear cada PAT. Abrir esta página no crea nada.`,files:`Archivos`,workflows:`Workflows`,variables:`Variables`,secretNames:`Nombres de Secrets`,planBody:`Revisa exactamente lo que podría cambiar. Después se pedirán el PAT del bot y las demás credenciales.`,planChoices:`Tus decisiones principales`,planEnabledCapabilities:`Funciones activadas`,planBranchRoles:`Rama de producción / desarrollo`,planApprovalMode:`Aprobación de pull requests`,planVariableScope:`Ámbito de Variables`,planSecretScope:`Ámbito de Secrets`,planInitialTag:`Crear etiqueta inicial`,planAgentRouting:`Agente y modelo por tarea`,planIssueWorkflows:`Flujos de issues`,planTrustedChecks:`Productores de CI fiables`,planCoverage:`Prueba de cobertura`,planProjectStatuses:`Transiciones de Status en Projects`,planIssueResources:`Etiquetas y tipos de issue`,planIssueResourcesValue:`Se comprobarán o crearán al aplicar`,planProducerAttested:`Identidad de CI y paso obligatorio comprobados por ti`,planCoverageThreshold:`Cobertura mínima de líneas modificadas`,planCoverageReporter:`Workflow que publica el artefacto`,planReporterAttested:`Generador de cobertura comprobado por ti`,planAdvancedDefaults:`El plan también incluye valores predeterminados de ajustes que no cambiaste. Usa Cambiar más abajo para revisar cualquier sección antes de aprobar.`,planUnknownWarning:`Hay un aviso adicional del plan que no se puede mostrar aquí. Léelo en la terminal antes de aprobar.`,planBasicDefaultsIntro:`El modo básico conservó estos ajustes avanzados. Abre una sección más abajo para revisarlos o cambiarlos:`,scopeRepository:`Repositorio`,scopeOrganization:`Organización`,scopeDisabled:`Sin aprovisionar`,approvalOff:`Desactivada`,approvalRecommend:`Solo recomendaciones`,approvalGuarded:`Aprobación protegida`,beforeContinue:`Antes de continuar`,stopHere:`Detener aquí`,approvePlan:`Aprobar este plan`,githubLink:`Abrir enlace de GitHub ↗`,githubForm:`Abrir el formulario oficial de PAT de GitHub`,githubFormHelp:`Comprueba la cuenta activa, elige Only select repositories y selecciona este repositorio. GitHub gestiona el 2FA y crea el PAT.`,pasteHere:`Pega aquí el valor`,yourAnswer:`Tu respuesta`,hiddenAfter:`Oculto tras enviarlo`,typeAnswer:`Escribe tu respuesta`,secretHelp:`Se envía solo a este proceso local. No volverá a mostrarse ni se guardará en el almacenamiento del navegador.`,pairTitle:`Vincula este navegador`,pairLabel:`Código de vinculación de la terminal`,pairPlaceholder:`16 caracteres hexadecimales`,pairBody:`Busca el código de 16 caracteres en la terminal donde ejecutaste copilot setup --web. Introdúcelo para ver o controlar la sesión. No aparece en la URL ni se almacena al cerrar la página.`,pairHelp:`Mantén el código en privado. Tras actualizar la página, introdúcelo de nuevo para reconectar.`,pairButton:`Conectar a la configuración local`,privateSession:`SESIÓN LOCAL PRIVADA`,theme:`Tema de color`,themeAuto:`Sistema`,themeSystem:`Seguir tema del sistema`,themeLight:`Tema claro`,themeDark:`Tema oscuro`,selectOne:`Selecciona una opción`,ciRun:`Abrir ejecución de CI en GitHub ↗`,manualCheck:`¿No aparece el check? Introduce nombre|ID de App|workflow exactos, separados por punto y coma.`,checksObserved:`Se encontraron jobs recientes de CI. Abre cada ejecución y comprueba el job, la App y el paso obligatorio de cobertura antes de confiar en él.`,checksNoRecent:`No hay ejecuciones recientes de workflows de pull request. Ejecuta tu CI habitual en un PR real o introduce manualmente un productor exacto.`,checksNoVerifiable:`Hay ejecuciones recientes, pero ningún job pudo vincularse a un Check Run y una App concretos. Revisa GitHub o introduce el productor manualmente.`,checksDenied:`GitHub no permitió consultar los checks. Concede Actions: read y Checks: read al PAT de configuración, o introduce el productor manualmente.`,checksUnavailable:`No se pudo completar la consulta de CI. Esto no significa que el repositorio no tenga checks. Reintenta o introduce el productor manualmente.`,projectsObserved:`Estos Projects existentes pertenecen al dueño del repositorio. Selecciona solo los que deba actualizar la automatización.`,projectsEmpty:`Esta consulta limitada no devolvió Projects abiertos y accesibles; eso no demuestra que no existan. Comprueba el acceso o introduce un número verificado.`,projectsDenied:`GitHub no permitió consultar Projects. Comprueba Projects: read de la organización en el PAT o introduce los números manualmente.`,projectsUnavailable:`No se pudo consultar Projects. Eso no demuestra que no existan. Introduce un número verificado o reintenta.`,projectsUnsupported:`GitHub no permite listar Projects personales con un PAT de permisos precisos mediante esta API. Introduce el número de la URL de un Project existente.`,discoveryTruncated:`Solo se inspeccionó una muestra limitada de Projects accesibles o checks recientes. Usa la entrada manual si falta uno.`,checksDiscoveryScope:`Alcance: hasta 20 ejecuciones recientes de workflows de PR; se inspeccionan como máximo 15 ejecuciones y 100 checks por commit.`,projectsDiscoveryScope:`Alcance: hasta 30 Projects abiertos y accesibles de la organización en dos páginas; se inspeccionan hasta 100 campos por Project. Se excluyen los Projects cerrados.`,retryDiscovery:`Reintentar búsqueda en GitHub`,retryRemaining:`Quedan {count} reintentos de solo lectura. Tus respuestas se conservan.`,retryExhausted:`No quedan reintentos. Consulta GitHub e introduce manualmente lo que falte.`,observationTimeUnknown:`fecha de observación no disponible`,branchRequirementUnknown:`Obligatorio según la regla de rama: no comprobado`,branchRequirementObserved:`Obligatorio en {branch} por un ruleset activo para este check y esta App exactos.`,ciRule:`Abrir ruleset del check obligatorio ↗`,projectSharedStatus:`Todos los Projects elegidos deben compartir cada valor Status. Este setup no asigna valores diferentes por Project.`,fixedWorkflowEnabled:`Tu configuración fija features.{kind}=true. Mantén {kind} seleccionado; cambia --config o los flags si quieres modificarlo.`,fixedWorkflowDisabled:`Tu configuración fija features.{kind}=false. Deja {kind} sin seleccionar; cambia --config o los flags si quieres modificarlo.`,fixedIssuesRequired:`Tu configuración activa expresamente release o hotfix. Mantén Issues activado o cambia antes --config o los flags.`,projectSelectionNotObserved:`Se conservan los números de Project elegidos antes, aunque ya no figuren en esta consulta. Compruébalos en GitHub o quítalos.`,removeSelection:`Quitar selección`,projectTransitionIssueCreated:`Issue nuevo`,projectTransitionPullRequestCreated:`Pull request nuevo`,projectTransitionIssueInProgress:`Issue en curso`,projectTransitionPullRequestInProgress:`Pull request en curso`,projectUrl:`Abrir Project en GitHub ↗`,projectManual:`¿Falta un Project? Introduce su número positivo o URL exacta de GitHub. No se aceptan IDs PVT_.`,projectStatusUnavailable:`No se pudieron verificar las opciones Status de todos los Projects elegidos. Comprueba cada Project en GitHub e introduce el valor exacto.`,projectStatusIncompatible:`Los Projects elegidos no comparten valores Status. Elige Projects compatibles antes de continuar.`,producerName:`Nombre del check/job`,producerAppId:`ID de la App de GitHub`,producerWorkflow:`Nombre del workflow`,producerAdd:`Añadir check exacto`,producerRemove:`Quitar check`,producerManualHelp:`Usa la identidad exacta de GitHub. Añadirla no acredita que exija la cobertura.`,producerManualInvalid:`Indica nombre, ID numérico positivo de App y workflow. No uses | ni ; en los nombres.`,translationPreviewTitle:`Revisión de la traducción en curso`,translationPreviewBody:`Las preguntas propias de la configuración ya están traducidas. Algunos diagnósticos dinámicos de GitHub o del proveedor aún pueden aparecer en inglés mientras termina la revisión. Cambiar de idioma no modifica tus respuestas.`,unknownLocalError:`Se ha producido un error inesperado en la configuración local. Consulta la terminal y actualiza la página o reinicia la configuración.`},Vi={language:`Langue`,english:`Anglais`,spanish:`Espagnol`,setup:`CONFIGURATION`,connecting:`Connexion…`,localSession:`SESSION LOCALE`,progress:`Progression`,studio:`ASSISTANT DE CONFIGURATION`,journey:`VOTRE PARCOURS`,repository:`Dépôt`,choices:`Choix`,setupPat:`PAT de configuration`,plan:`Plan`,botPat:`PAT du bot et identifiants`,apply:`Appliquer`,localDesign:`Local par conception`,localDesignBody:`Cette page fonctionne sur votre ordinateur. GitHub crée les deux PAT dans ses propres onglets.`,preparing:`Préparation…`,completeTitle:`Configuration terminée.`,previewTitle:`Aperçu terminé.`,cancelledTitle:`Configuration annulée.`,blockedTitle:`Une intervention est nécessaire.`,gettingReady:`PRÉPARATION`,activeLede:`Une décision à la fois. Vos choix déterminent les droits, le plan et les identifiants nécessaires.`,resultLede:`Consultez le résultat et la prochaine étape ci-dessous. Le terminal fournit les détails techniques.`,readOnly:`Onglet en lecture seule`,readOnlyBody:`Un autre onglet contrôle cette session. Vous pouvez suivre la progression ou prendre le contrôle.`,takeOver:`Prendre le contrôle`,attention:`Action nécessaire`,checked:`Vérifié`,pleaseNote:`À noter`,progressUpdate:`Mise à jour`,reviewPass:`Révision des choix enregistrés — passage {pass}. C’est la même session, pas un redémarrage.`,cancelSetup:`Annuler`,cancelConfirm:`Annuler cette session locale ? Les PAT créés sur GitHub continueront d’exister.`,footerLocal:`LOCALHOST UNIQUEMENT`,footerCloud:`AUCUN COMPTE CLOUD`,footerGithub:`GITHUB ÉMET LES PAT`,currentDecision:`DÉCISION ACTUELLE`,session:`SESSION`,continue:`Continuer`,previousQuestion:`Question précédente`,questionProgress:`Question {current} sur {total} dans ce groupe · {overall} sur {all} au total`,yes:`Oui`,no:`Non`,permissionPreview:`APERÇU DES DROITS`,changeAnswersTitle:`Modifier vos réponses`,changeAnswersHelp:`Revenez à une section sans perdre les autres réponses. Le plan et les droits PAT requis seront vérifiés à nouveau.`,changeSection:`Modifier {section}`,editCapabilities:`Fonctionnalités`,editRuntimes:`Agents`,editModels:`Modèles des agents`,editRoleModels:`Modèles par tâche`,editRepository:`Comportement du dépôt`,editDeployment:`Releases et correctifs`,editBugbot:`Bugbot`,editApproval:`Approbation des PR`,editProjects:`Projects`,editProvisioning:`Provisionnement`,editStorage:`Secrets et Variables`,suggested:`Réponse suggérée : {answer}. Vous pourrez revoir vos choix avant de créer le PAT.`,none:`aucune`,sourceGithub:`Observé dans les métadonnées authentifiées de ce dépôt GitHub.`,sourceConfig:`Fourni par votre configuration ; GitHub ne l’a pas remplacé.`,sourceDefault:`Valeur par défaut du produit ; non vérifiée dans ce dépôt.`,sourceLocal:`Observé dans ce dossier local ; vérifiez que cette branche existe sur GitHub avant d’appliquer les changements.`,whyMatters:`Pourquoi c’est important`,whenApplies:`Quand cela s’applique`,whereConfigured:`Où se fait le réglage`,howToChoose:`Comment choisir`,whyRecommendation:`Pourquoi c’est important`,example:`Exemple`,effect:`Ce qui change`,verify:`Comment vérifier`,learnMore:`Lire la documentation de ce réglage`,resultApplied:`Configuration appliquée`,resultNoChanges:`Aucun changement effectué`,resultStopped:`Aucun changement commencé`,resultPartial:`Vérifiez les changements partiels`,resultCompleteBody:`Le PAT temporaire n’est pas révoqué automatiquement. Supprimez-le sur GitHub après vérification. Gardez le PAT du bot jusqu’à rotation du Secret.`,resultPartialBody:`Un Secret ou une autre ressource a peut-être été modifié. Vérifiez GitHub et exécutez copilot doctor --read-only avant de remplacer ou supprimer un PAT.`,resultNoChangesBody:`Copilot n’a pas commencé à appliquer la configuration. Les PAT créés sur GitHub restent actifs jusqu’à leur suppression là-bas.`,whatHappened:`Ce qui s’est passé`,alreadyChanged:`Déjà modifié`,noChanges:`Aucun changement du dépôt ou de GitHub n’a commencé pendant cette session.`,nextAction:`Prochaine étape`,reasonPermissions:`Les droits nécessaires du PAT de configuration manquent ou n’ont pas pu être confirmés.`,nextPermissions:`Vérifiez les droits affichés, corrigez le PAT sur GitHub, puis recommencez.`,reasonStorage:`Le stockage GitHub Actions choisi ne peut pas être utilisé en sécurité.`,nextStorage:`Vérifiez la portée des Variables/Secrets et les ressources existantes, puis réessayez.`,reasonConfiguration:`La configuration choisie n’a pas pu être validée.`,nextConfiguration:`Lisez les détails du terminal, corrigez les choix et réessayez.`,reasonExpired:`La session locale a expiré avant toute modification.`,nextExpired:`Démarrez une nouvelle session ; l’ancienne approbation ne peut pas être réutilisée.`,reasonCancelled:`La configuration a été annulée avant toute modification.`,nextCancelled:`Démarrez une nouvelle session si vous souhaitez encore configurer ce dépôt.`,reasonUnknown:`La configuration s’est arrêtée avant l’application ; la cause exacte est inconnue.`,nextUnknown:`Consultez la dernière erreur du terminal avant de réessayer. Ne supposez pas qu’un PAT a été révoqué.`,reasonProvider:`GitHub ou un autre fournisseur n’a pas terminé l’opération demandée.`,nextProvider:`Utilisez la référence de diagnostic pour consulter le terminal, vérifiez la disponibilité et les accès, puis examinez tout changement partiel avant de réessayer.`,reasonRateLimit:`GitHub a temporairement limité les requêtes nécessaires à la configuration.`,nextRateLimit:`Attendez la réinitialisation de la limite. Examinez les changements effectués avant de recommencer.`,diagnosticReference:`Référence de diagnostic`,resourceReceipt:`Reçu des opérations de configuration`,effectCompleted:`Signalée comme terminée`,effectSkipped:`Signalée comme ignorée`,effectInspect:`Résultat à vérifier`,effectNotStarted:`Non commencée`,scopeLocal:`Dossier local`,scopeMixed:`Dépôt et organisation`,receiptFiles:`Fichiers de configuration`,receiptSecrets:`Secrets GitHub Actions`,receiptLabels:`Étiquettes des tickets`,receiptIssueTypes:`Types de ticket`,receiptVariables:`Variables GitHub Actions`,receiptInitialTag:`Première étiquette de version`,inspectPartial:`Des changements peuvent déjà être actifs. Vérifiez GitHub et le terminal avant de réessayer.`,patSettings:`Ouvrir les paramètres PAT GitHub ↗`,closeSession:`Fermer la session locale`,doctorHelp:`Après la configuration, vérifiez ici les ressources installées sans déclencher d’Actions. Vous pouvez aussi exécuter copilot doctor --read-only à la racine du dépôt avec le PAT temporaire et le même fichier --config non secret, le cas échéant.`,doctorRun:`Vérifier l’installation (lecture seule)`,doctorRunning:`Vérification des ressources installées sans déclencher d’Actions…`,doctorPassed:`La vérification en lecture seule n’a trouvé aucun échec.`,doctorWarnings:`La vérification en lecture seule demande une attention particulière.`,doctorFailed:`La vérification en lecture seule ne s’est pas terminée. Consultez le terminal ou exécutez la commande ci-dessous.`,doctorCounts:`{pass} réussis · {warn} avertissements · {fail} échecs · {skipped} ignorés.`,doctorSecretLimit:`Ce mode ne peut pas vérifier les valeurs des Secrets.`,botRenewal:`Le PAT du bot reste dans le secret GitHub Actions choisi pour les futures exécutions. Sa date d’expiration réelle n’est pas vérifiée ici ; notez-la sur GitHub et remplacez le secret avant cette date.`,working:`Préparation de l’étape suivante`,workingBody:`Le processus local vérifie vos réponses. Gardez cette page ouverte.`,repoFocus:`Dépôt concerné`,repoFocusBody:`Toutes les décisions de cette session concernent uniquement :`,access:`accès`,readOnlyCheck:`Vérification en lecture seule`,provisionalGrants:`Droits provisoires minimaux`,conditionalGrants:`Les droits conditionnels dépendent de vos choix et de GitHub. Un contrôle final précède toute modification.`,permissionUnknown:`Ce droit exige une vérification. Consultez le droit exact et son explication technique dans le terminal avant de continuer.`,permissionsFollow:`Les droits suivent vos choix`,permissionsFollowBody:`Les droits exacts sont affichés avant chaque PAT. Ouvrir cette page ne crée rien.`,files:`Fichiers`,workflows:`Workflows`,variables:`Variables`,secretNames:`Noms des Secrets`,planBody:`Vérifiez précisément ce qui pourrait changer. Le PAT du bot et les autres identifiants seront demandés ensuite.`,planChoices:`Vos décisions principales`,planEnabledCapabilities:`Fonctionnalités activées`,planBranchRoles:`Branche de production / développement`,planApprovalMode:`Approbation des pull requests`,planVariableScope:`Portée des variables`,planSecretScope:`Portée des secrets`,planInitialTag:`Créer la première étiquette`,planAgentRouting:`Agent et modèle par tâche`,planIssueWorkflows:`Workflows de tickets`,planTrustedChecks:`Producteurs CI de confiance`,planCoverage:`Preuve de couverture`,planProjectStatuses:`Transitions Status des Projects`,planIssueResources:`Étiquettes et types de ticket`,planIssueResourcesValue:`Vérifiés ou créés lors de l’application`,planProducerAttested:`Identité CI et étape obligatoire vérifiées par vous`,planCoverageThreshold:`Couverture minimale des lignes modifiées`,planCoverageReporter:`Workflow publiant l’artefact`,planReporterAttested:`Producteur du rapport de couverture vérifié par vous`,planAdvancedDefaults:`Le plan comprend aussi les valeurs par défaut des réglages non modifiés. Utilisez Modifier ci-dessous pour examiner une section avant de valider.`,planUnknownWarning:`Un avertissement supplémentaire du plan ne peut pas être affiché ici. Lisez-le dans le terminal avant de valider.`,planBasicDefaultsIntro:`Le parcours de base a conservé ces réglages avancés. Ouvrez une section ci-dessous pour les vérifier ou les modifier :`,scopeRepository:`Dépôt`,scopeOrganization:`Organisation`,scopeDisabled:`Non provisionné`,approvalOff:`Désactivée`,approvalRecommend:`Recommandation uniquement`,approvalGuarded:`Approbation protégée`,beforeContinue:`Avant de continuer`,stopHere:`Arrêter ici`,approvePlan:`Approuver ce plan`,githubLink:`Ouvrir le lien GitHub ↗`,githubForm:`Ouvrir le formulaire PAT officiel de GitHub`,githubFormHelp:`Vérifiez le compte connecté, choisissez Only select repositories et ce dépôt. GitHub gère la 2FA et crée le PAT.`,pasteHere:`Collez la valeur ici`,yourAnswer:`Votre réponse`,hiddenAfter:`Masquée après envoi`,typeAnswer:`Saisissez votre réponse`,secretHelp:`Envoyé uniquement au processus local. Ni réaffiché ni enregistré dans le navigateur.`,pairTitle:`Associer ce navigateur`,pairLabel:`Code du terminal`,pairPlaceholder:`16 caractères hexadécimaux`,pairBody:`Trouvez le code à 16 caractères dans le terminal qui a lancé copilot setup --web. Il ne figure pas dans l’URL et n’est pas conservé après fermeture.`,pairHelp:`Gardez ce code secret. Après actualisation, saisissez-le de nouveau.`,pairButton:`Se connecter à la configuration locale`,privateSession:`SESSION LOCALE PRIVÉE`,theme:`Thème`,themeAuto:`Auto`,themeSystem:`Suivre le système`,themeLight:`Thème clair`,themeDark:`Thème sombre`,selectOne:`Choisissez une option`,ciRun:`Voir l’exécution CI sur GitHub ↗`,manualCheck:`Check absent ? Saisissez nom|ID App|workflow exacts, séparés par des points-virgules.`,checksObserved:`Des jobs CI récents ont été trouvés. Ouvrez chaque exécution et vérifiez le job, l’App et l’étape obligatoire de couverture avant de lui faire confiance.`,checksNoRecent:`Aucune exécution récente de workflow de pull request. Lancez le CI habituel sur une vraie PR ou saisissez un producteur exact.`,checksNoVerifiable:`Des exécutions récentes existent, mais aucun job ne correspond à une identité exacte de Check Run et d’App. Vérifiez GitHub ou saisissez-la.`,checksDenied:`GitHub a refusé la découverte CI. Accordez Actions: read et Checks: read au PAT de configuration, ou saisissez un producteur exact.`,checksUnavailable:`La découverte CI a échoué. Cela ne prouve pas l’absence de checks. Réessayez ou saisissez un producteur exact.`,projectsObserved:`Ces Projects existants appartiennent au propriétaire du dépôt. Ne choisissez que ceux que l’automatisation doit modifier.`,projectsEmpty:`Cette requête GitHub limitée n’a renvoyé aucun Project ouvert et accessible ; elle ne prouve pas leur absence. Vérifiez l’accès ou saisissez un numéro vérifié.`,projectsDenied:`GitHub a refusé la découverte des Projects. Vérifiez Projects: read au niveau organisation sur le PAT, ou saisissez les numéros.`,projectsUnavailable:`La découverte des Projects a échoué. Cela ne prouve pas leur absence. Saisissez un numéro vérifié ou réessayez.`,projectsUnsupported:`Cette API GitHub ne liste pas les Projects personnels avec un PAT à permissions fines. Saisissez le numéro figurant dans l’URL.`,discoveryTruncated:`Seul un échantillon limité de Projects accessibles ou checks récents a été inspecté. Saisissez manuellement un élément absent.`,checksDiscoveryScope:`Périmètre : jusqu’à 20 exécutions récentes de workflows de PR ; au plus 15 exécutions et 100 checks par commit sont inspectés.`,projectsDiscoveryScope:`Périmètre : au plus 30 Projects ouverts et accessibles de l’organisation sur deux pages ; jusqu’à 100 champs sont inspectés par Project. Les Projects fermés sont exclus.`,retryDiscovery:`Relancer la recherche GitHub`,retryRemaining:`Il reste {count} essais en lecture seule. Vos réponses sont conservées.`,retryExhausted:`Plus aucun essai disponible. Vérifiez GitHub et saisissez manuellement tout élément manquant.`,observationTimeUnknown:`date d’observation indisponible`,branchRequirementUnknown:`Exigé par la règle de branche : non vérifié`,branchRequirementObserved:`Exigé sur {branch} par un ruleset actif pour ce contrôle et cette application précis.`,ciRule:`Ouvrir le ruleset du contrôle obligatoire ↗`,projectSharedStatus:`Tous les Projects choisis doivent partager chaque valeur Status. Cette configuration ne définit pas de valeurs différentes par Project.`,fixedWorkflowEnabled:`Votre configuration fixe features.{kind}=true. Gardez {kind} sélectionné ; modifiez --config ou les options pour changer ce choix.`,fixedWorkflowDisabled:`Votre configuration fixe features.{kind}=false. Ne sélectionnez pas {kind} ; modifiez --config ou les options pour changer ce choix.`,fixedIssuesRequired:`Votre configuration active explicitement release ou hotfix. Gardez Issues activé ou modifiez d’abord --config ou les options.`,projectSelectionNotObserved:`Les numéros de Projects choisis auparavant sont conservés, mais n’apparaissent plus dans ce résultat GitHub. Vérifiez-les sur GitHub ou retirez-les.`,removeSelection:`Retirer la sélection`,projectTransitionIssueCreated:`Nouveau ticket`,projectTransitionPullRequestCreated:`Nouvelle pull request`,projectTransitionIssueInProgress:`Ticket en cours`,projectTransitionPullRequestInProgress:`Pull request en cours`,projectUrl:`Ouvrir le Project sur GitHub ↗`,projectManual:`Project absent ? Saisissez son numéro positif ou son URL GitHub exacte. Les ID PVT_ sont refusés.`,projectStatusUnavailable:`Les options Status n’ont pas pu être vérifiées pour tous les Projects. Vérifiez-les sur GitHub et saisissez la valeur exacte.`,projectStatusIncompatible:`Les Projects choisis ne partagent aucun Status. Choisissez des Projects compatibles avant de continuer.`,producerName:`Nom du check/job`,producerAppId:`ID de l’App GitHub source`,producerWorkflow:`Nom du workflow`,producerAdd:`Ajouter le check exact`,producerRemove:`Retirer le check`,producerManualHelp:`Utilisez l’identité exacte affichée sur GitHub. L’ajouter ne prouve pas que la couverture est imposée.`,producerManualInvalid:`Indiquez le nom, un ID numérique positif d’App et le workflow. N’utilisez ni | ni ; dans les noms.`,translationPreviewTitle:`Révision de la traduction en cours`,translationPreviewBody:`Les questions propres à la configuration sont traduites. Certains diagnostics dynamiques de GitHub ou du fournisseur peuvent encore apparaître en anglais pendant la révision. Changer de langue ne modifie pas vos réponses.`,unknownLocalError:`Une erreur inattendue est survenue pendant la configuration locale. Consultez le terminal, puis actualisez la page ou relancez la configuration.`},Hi={language:`Idioma`,english:`Inglês`,spanish:`Espanhol`,setup:`CONFIGURAÇÃO`,connecting:`A ligar…`,localSession:`SESSÃO LOCAL`,progress:`Progresso`,studio:`ASSISTENTE DE CONFIGURAÇÃO`,journey:`O SEU PERCURSO`,repository:`Repositório`,choices:`Opções`,setupPat:`PAT de configuração`,plan:`Plano`,botPat:`PAT do bot e credenciais`,apply:`Aplicar`,localDesign:`Local por conceção`,localDesignBody:`Esta página funciona no seu computador. O GitHub cria ambos os PAT nos seus próprios separadores.`,preparing:`A preparar a configuração…`,completeTitle:`Configuração concluída.`,previewTitle:`Pré-visualização concluída.`,cancelledTitle:`Configuração cancelada.`,blockedTitle:`A configuração requer atenção.`,gettingReady:`A PREPARAR`,activeLede:`Uma decisão de cada vez. As suas escolhas determinam permissões, plano e credenciais.`,resultLede:`Consulte abaixo o resultado e o próximo passo. O terminal contém mais detalhes técnicos.`,readOnly:`Separador só de leitura`,readOnlyBody:`Outro separador controla esta sessão. Pode acompanhar o progresso ou assumir o controlo.`,takeOver:`Assumir o controlo`,attention:`Requer atenção`,checked:`Verificado`,pleaseNote:`Atenção`,progressUpdate:`Atualização de progresso`,reviewPass:`A rever as escolhas guardadas — passagem {pass}. É a mesma execução, não um reinício.`,cancelSetup:`Cancelar configuração`,cancelConfirm:`Cancelar esta sessão local? Os PAT já criados no GitHub continuarão a existir.`,footerLocal:`APENAS LOCALHOST`,footerCloud:`SEM CONTA DE CONFIGURAÇÃO NA NUVEM`,footerGithub:`O GITHUB EMITE OS PAT`,currentDecision:`DECISÃO ATUAL`,session:`SESSÃO`,continue:`Continuar`,previousQuestion:`Pergunta anterior`,questionProgress:`Pergunta {current} de {total} neste grupo · {overall} de {all} no total`,yes:`Sim`,no:`Não`,permissionPreview:`PRÉ-VISUALIZAÇÃO DAS PERMISSÕES`,changeAnswersTitle:`Alterar respostas`,changeAnswersHelp:`Volte a uma secção sem perder as outras respostas. O plano e as permissões PAT necessárias serão verificados de novo.`,changeSection:`Alterar {section}`,editCapabilities:`Funcionalidades`,editRuntimes:`Agentes`,editModels:`Modelos dos agentes`,editRoleModels:`Modelos por tarefa`,editRepository:`Comportamento do repositório`,editDeployment:`Releases e correções`,editBugbot:`Bugbot`,editApproval:`Aprovação de PR`,editProjects:`Projects`,editProvisioning:`Provisionamento`,editStorage:`Secrets e Variables`,suggested:`Resposta sugerida: {answer}. Pode rever as opções antes de criar o PAT.`,none:`nenhuma`,sourceGithub:`Observado nos metadados autenticados deste repositório no GitHub.`,sourceConfig:`Fornecido pela sua configuração; o GitHub não o substituiu.`,sourceDefault:`Valor predefinido do produto; não verificado neste repositório.`,sourceLocal:`Observado neste checkout local; confirme que o ramo existe no GitHub antes de aplicar alterações.`,whyMatters:`Porque importa`,whenApplies:`Quando se aplica`,whereConfigured:`Onde se configura`,howToChoose:`Como escolher`,whyRecommendation:`Porque importa`,example:`Exemplo`,effect:`O que muda`,verify:`Como verificar`,learnMore:`Ler a documentação desta opção`,resultApplied:`A configuração foi aplicada`,resultNoChanges:`Nenhuma alteração efetuada`,resultStopped:`Nenhuma alteração iniciada`,resultPartial:`Verifique as alterações parciais`,resultCompleteBody:`O PAT temporário não é revogado automaticamente. Elimine-o no GitHub após verificar. Guarde o PAT do bot até rodar o Secret.`,resultPartialBody:`Um Secret ou outro recurso pode ter sido alterado. Verifique o GitHub e execute copilot doctor --read-only antes de substituir ou eliminar o PAT.`,resultNoChangesBody:`O Copilot não começou a aplicar alterações. Os PAT criados no GitHub permanecem até serem eliminados lá.`,whatHappened:`O que aconteceu`,alreadyChanged:`O que mudou`,noChanges:`Não foram iniciadas alterações no repositório nem no GitHub nesta sessão.`,nextAction:`Próximo passo`,reasonPermissions:`Faltam permissões do PAT de configuração ou não foi possível confirmá-las.`,nextPermissions:`Verifique as permissões, corrija o PAT no GitHub e inicie uma nova sessão.`,reasonStorage:`O armazenamento GitHub Actions escolhido não pôde ser usado com segurança.`,nextStorage:`Verifique o âmbito das Variables/Secrets e os recursos existentes; depois tente novamente.`,reasonConfiguration:`Não foi possível validar a configuração escolhida.`,nextConfiguration:`Leia os detalhes no terminal, corrija as opções e tente novamente.`,reasonExpired:`A sessão local expirou antes de aplicar alterações.`,nextExpired:`Inicie uma nova sessão; a aprovação anterior não pode ser reutilizada.`,reasonCancelled:`A configuração foi cancelada antes de aplicar alterações.`,nextCancelled:`Inicie outra execução se ainda quiser configurar o repositório.`,reasonUnknown:`A configuração parou antes de aplicar; a causa exata é desconhecida.`,nextUnknown:`Leia o último erro no terminal antes de tentar novamente. Não presuma que um PAT foi revogado.`,reasonProvider:`O GitHub ou outro fornecedor não concluiu a operação solicitada.`,nextProvider:`Use a referência de diagnóstico para consultar o terminal, verifique a disponibilidade e o acesso e reveja possíveis alterações parciais antes de tentar novamente.`,reasonRateLimit:`O GitHub limitou temporariamente os pedidos necessários para a configuração.`,nextRateLimit:`Aguarde a reposição do limite. Inspecione as alterações concluídas antes de iniciar outra configuração.`,diagnosticReference:`Referência de diagnóstico`,resourceReceipt:`Registo das operações de configuração`,effectCompleted:`Indicada como concluída`,effectSkipped:`Indicada como ignorada`,effectInspect:`Resultado por inspecionar`,effectNotStarted:`Não iniciada`,scopeLocal:`Checkout local`,scopeMixed:`Repositório e organização`,receiptFiles:`Ficheiros de configuração`,receiptSecrets:`Secrets do GitHub Actions`,receiptLabels:`Etiquetas das questões`,receiptIssueTypes:`Tipos de questão`,receiptVariables:`Variables do GitHub Actions`,receiptInitialTag:`Etiqueta de versão inicial`,inspectPartial:`Algumas alterações podem estar ativas. Verifique o GitHub e o terminal antes de tentar novamente.`,patSettings:`Abrir definições de PAT no GitHub ↗`,closeSession:`Fechar sessão local`,doctorHelp:`Depois de concluir a configuração, pode verificar aqui os recursos instalados sem iniciar Actions. Também pode executar copilot doctor --read-only na raiz do repositório com o PAT temporário e o mesmo ficheiro --config não secreto, caso o tenha usado.`,doctorRun:`Verificar instalação (só de leitura)`,doctorRunning:`A verificar os recursos instalados sem iniciar Actions…`,doctorPassed:`A verificação só de leitura não encontrou falhas.`,doctorWarnings:`A verificação só de leitura requer atenção.`,doctorFailed:`A verificação só de leitura não terminou. Consulte o terminal ou execute o comando abaixo.`,doctorCounts:`{pass} aprovados · {warn} avisos · {fail} falhas · {skipped} ignorados.`,doctorSecretLimit:`Este modo não consegue verificar os valores dos Secrets.`,botRenewal:`O PAT do bot permanece no Secret do GitHub Actions escolhido para execuções futuras. A data de validade real não é verificada aqui; registe-a no GitHub e substitua o Secret antes de expirar.`,working:`A preparar o próximo passo`,workingBody:`O processo local está a verificar as respostas. Mantenha esta página aberta.`,repoFocus:`Repositório em foco`,repoFocusBody:`Todas as decisões desta sessão afetam apenas:`,access:`acesso`,readOnlyCheck:`Verificação de acesso só de leitura`,provisionalGrants:`Permissões provisórias mínimas`,conditionalGrants:`As permissões condicionais dependem das escolhas e do GitHub. Haverá uma auditoria final antes das alterações.`,permissionUnknown:`Esta permissão exige revisão. Consulte a permissão exata e a explicação técnica no terminal antes de continuar.`,permissionsFollow:`As permissões seguem as suas escolhas`,permissionsFollowBody:`Mostramos as permissões exatas antes de criar cada PAT. Abrir esta página não cria nada.`,files:`Ficheiros`,workflows:`Workflows`,variables:`Variables`,secretNames:`Nomes dos Secrets`,planBody:`Reveja exatamente o que pode mudar. O PAT do bot e outras credenciais serão pedidos a seguir.`,planChoices:`As suas decisões principais`,planEnabledCapabilities:`Funcionalidades ativadas`,planBranchRoles:`Ramo de produção / desenvolvimento`,planApprovalMode:`Aprovação de pull requests`,planVariableScope:`Âmbito das Variables`,planSecretScope:`Âmbito dos Secrets`,planInitialTag:`Criar etiqueta inicial`,planAgentRouting:`Agente e modelo por tarefa`,planIssueWorkflows:`Fluxos de questões`,planTrustedChecks:`Produtores CI de confiança`,planCoverage:`Evidência de cobertura`,planProjectStatuses:`Transições Status dos Projects`,planIssueResources:`Etiquetas e tipos de questão`,planIssueResourcesValue:`Verificados ou criados ao aplicar`,planProducerAttested:`Identidade CI e passo obrigatório verificados por si`,planCoverageThreshold:`Cobertura mínima das linhas alteradas`,planCoverageReporter:`Workflow que publica o artefacto`,planReporterAttested:`Produtor do relatório de cobertura verificado por si`,planAdvancedDefaults:`O plano também inclui valores predefinidos para definições que não alterou. Use Alterar abaixo para rever qualquer secção antes de aprovar.`,planUnknownWarning:`Um aviso adicional do plano não pode ser apresentado aqui. Leia-o no terminal antes de aprovar.`,planBasicDefaultsIntro:`O percurso básico manteve estas definições avançadas. Abra uma secção abaixo para as rever ou alterar:`,scopeRepository:`Repositório`,scopeOrganization:`Organização`,scopeDisabled:`Sem aprovisionamento`,approvalOff:`Desativada`,approvalRecommend:`Apenas recomendações`,approvalGuarded:`Aprovação protegida`,beforeContinue:`Antes de continuar`,stopHere:`Parar aqui`,approvePlan:`Aprovar este plano`,githubLink:`Abrir ligação do GitHub ↗`,githubForm:`Abrir formulário oficial de PAT no GitHub`,githubFormHelp:`Confirme a conta ligada, escolha Only select repositories e este repositório. O GitHub gere 2FA e cria o PAT.`,pasteHere:`Cole o valor aqui`,yourAnswer:`A sua resposta`,hiddenAfter:`Oculto após envio`,typeAnswer:`Escreva a sua resposta`,secretHelp:`Enviado apenas ao processo local. Não será mostrado de novo nem guardado no navegador.`,pairTitle:`Emparelhar este navegador`,pairLabel:`Código do terminal`,pairPlaceholder:`16 caracteres hexadecimais`,pairBody:`Encontre o código de 16 caracteres no terminal onde iniciou copilot setup --web. Não aparece no URL nem fica guardado após fechar a página.`,pairHelp:`Mantenha o código privado. Após atualizar a página, introduza-o novamente.`,pairButton:`Ligar à configuração local`,privateSession:`SESSÃO LOCAL PRIVADA`,theme:`Tema`,themeAuto:`Automático`,themeSystem:`Seguir sistema`,themeLight:`Tema claro`,themeDark:`Tema escuro`,selectOne:`Selecione uma opção`,ciRun:`Abrir execução de CI no GitHub ↗`,manualCheck:`Check não listado? Indique nome|ID da App|workflow exatos, separados por ponto e vírgula.`,checksObserved:`Foram encontrados jobs recentes de CI. Abra cada execução e confirme o job, a App e o passo obrigatório de cobertura antes de confiar nele.`,checksNoRecent:`Não há execuções recentes de workflows de pull request. Execute o CI habitual numa PR real ou introduza um produtor exato.`,checksNoVerifiable:`Há execuções recentes, mas nenhum job foi ligado a um Check Run e App exatos. Consulte o GitHub ou introduza o produtor manualmente.`,checksDenied:`O GitHub recusou a consulta do CI. Conceda Actions: read e Checks: read ao PAT de configuração ou introduza um produtor exato.`,checksUnavailable:`A consulta do CI falhou. Isto não prova que o repositório não tenha checks. Tente novamente ou introduza um produtor exato.`,projectsObserved:`Estes Projects existentes pertencem ao proprietário do repositório. Selecione só os que a automatização deve atualizar.`,projectsEmpty:`Esta consulta limitada ao GitHub não devolveu Projects abertos e acessíveis; isso não prova que não existam. Verifique o acesso ou introduza um número confirmado.`,projectsDenied:`O GitHub recusou a consulta de Projects. Verifique Projects: read da organização no PAT ou introduza os números.`,projectsUnavailable:`Não foi possível consultar Projects. Isto não prova que não existam. Introduza um número verificado ou tente novamente.`,projectsUnsupported:`Esta API do GitHub não lista Projects pessoais com um PAT de permissões precisas. Introduza o número do URL de um Project existente.`,discoveryTruncated:`Só foi inspecionada uma amostra limitada de Projects acessíveis ou checks recentes. Introduza manualmente um elemento em falta.`,checksDiscoveryScope:`Âmbito: até 20 execuções recentes de workflows de PR; são inspecionadas no máximo 15 execuções e 100 checks por commit.`,projectsDiscoveryScope:`Âmbito: no máximo 30 Projects abertos e acessíveis da organização em duas páginas; são inspecionados até 100 campos por Project. Os Projects fechados são excluídos.`,retryDiscovery:`Repetir pesquisa no GitHub`,retryRemaining:`Restam {count} tentativas só de leitura. As suas respostas são mantidas.`,retryExhausted:`Não restam tentativas. Verifique o GitHub e introduza manualmente os itens em falta.`,observationTimeUnknown:`data de observação indisponível`,branchRequirementUnknown:`Exigido pela regra do ramo: não verificado`,branchRequirementObserved:`Exigido em {branch} por um ruleset ativo para esta verificação e esta App específicas.`,ciRule:`Abrir ruleset da verificação obrigatória ↗`,projectSharedStatus:`Todos os Projects escolhidos devem partilhar cada valor Status. Esta configuração não atribui valores diferentes por Project.`,fixedWorkflowEnabled:`A sua configuração fixa features.{kind}=true. Mantenha {kind} selecionado; altere --config ou as opções para mudar esta escolha.`,fixedWorkflowDisabled:`A sua configuração fixa features.{kind}=false. Não selecione {kind}; altere --config ou as opções para mudar esta escolha.`,fixedIssuesRequired:`A sua configuração ativa explicitamente release ou hotfix. Mantenha Issues ativo ou altere primeiro --config ou as opções.`,projectSelectionNotObserved:`Os números de Projects escolhidos anteriormente são mantidos, mas já não aparecem neste resultado do GitHub. Confirme-os no GitHub ou remova-os.`,removeSelection:`Remover seleção`,projectTransitionIssueCreated:`Nova questão`,projectTransitionPullRequestCreated:`Novo pull request`,projectTransitionIssueInProgress:`Questão em curso`,projectTransitionPullRequestInProgress:`Pull request em curso`,projectUrl:`Abrir Project no GitHub ↗`,projectManual:`Project em falta? Introduza o número positivo ou o URL exato do GitHub. IDs PVT_ não são aceites.`,projectStatusUnavailable:`Não foi possível verificar as opções Status de todos os Projects. Consulte cada um no GitHub e introduza o valor exato.`,projectStatusIncompatible:`Os Projects escolhidos não partilham valores Status. Selecione Projects compatíveis antes de continuar.`,producerName:`Nome do check/job`,producerAppId:`ID da App GitHub de origem`,producerWorkflow:`Nome do workflow`,producerAdd:`Adicionar check exato`,producerRemove:`Remover check`,producerManualHelp:`Use a identidade exata apresentada no GitHub. Adicioná-la não prova que exige cobertura.`,producerManualInvalid:`Indique nome, ID numérico positivo da App e workflow. Não use | ou ; nos nomes.`,translationPreviewTitle:`Revisão da tradução em curso`,translationPreviewBody:`As perguntas próprias da configuração já estão traduzidas. Alguns diagnósticos dinâmicos do GitHub ou do fornecedor ainda podem aparecer em inglês durante a revisão. Mudar de idioma não altera as suas respostas.`,unknownLocalError:`Ocorreu um erro inesperado na configuração local. Consulte o terminal e atualize a página ou reinicie a configuração.`},Ui=[`en`,`es`,`fr`,`pt`],Wi={en:`English`,es:`Español`,fr:`Français`,pt:`Português`},Gi={en:zi,es:Bi,fr:Vi,pt:Hi};function Q(e,t,n={}){return(Gi[t]??Gi.en)[e].replace(/\{(\w+)\}/gu,(e,t)=>n[t]??``)}var Ki={Repository:`repository`,"Setup choices":`choices`,"Setup PAT":`setupPat`,Plan:`plan`,"Bot PAT & credentials":`botPat`,Apply:`apply`,Preparation:`gettingReady`};function qi(e,t){return Q(Ki[e??``]??`gettingReady`,t)}var $=Mi(`en`),Ji=W(`
                          • `),Yi=W(``);function Xi(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`journey`,8),o=[`repository`,`choices`,`setupPat`,`plan`,`botPat`,`apply`];Y();var s=Yi(),c=P(s),l=L(P(c)),u=I(L(P(l)),!0);E(l),E(c);var d=L(c,2),f=I(d,!0),p=L(d,2);Qr(p,5,()=>o,Jr,(e,t,r)=>{var i=Ji();let o;var s=P(i),c=I(s,!0),l=I(L(s,2),!0);E(i),R((e,t)=>{J(i,`aria-current`,(U(a()),H(()=>a()?.position===r+1?`step`:void 0))),o=ui(i,1,``,null,o,{current:a()?.position===r+1,completed:(a()?.position??0)>r+1}),K(c,e),K(l,t)},[()=>(U(a()),H(()=>(a()?.position??0)>r+1?`✓`:String(r+1).padStart(2,`0`))),()=>(U(Q),V(t),n(),H(()=>Q(V(t),n())))]),G(e,i)}),E(p);var m=L(p,2),h=L(P(m)),g=P(h),_=I(g,!0),v=I(L(g),!0);E(h),E(m),E(s),R((e,t,n,r,i)=>{J(s,`aria-label`,e),K(u,t),K(f,n),K(_,r),K(v,i)},[()=>(U(Q),n(),H(()=>Q(`progress`,n()))),()=>(U(Q),n(),H(()=>Q(`studio`,n()))),()=>(U(Q),n(),H(()=>Q(`journey`,n()))),()=>(U(Q),n(),H(()=>Q(`localDesign`,n()))),()=>(U(Q),n(),H(()=>Q(`localDesignBody`,n())))]),G(e,s),k(),i()}var Zi=W(`
                            `);function Qi(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(`system`);Tn(()=>V(a),()=>{document.documentElement.dataset.theme=V(a)}),En(),Y();var o=Zi(),s=P(o);let c;var l=I(s,!0),u=L(s,2);let d;var f=L(u,2);let p;E(o),R((e,t,n,r,i,m,h,g)=>{J(o,`aria-label`,e),J(s,`aria-pressed`,V(a)===`system`),J(s,`aria-label`,t),J(s,`title`,n),c=ui(s,1,``,null,c,{active:V(a)===`system`}),K(l,r),J(u,`aria-pressed`,V(a)===`light`),J(u,`aria-label`,i),J(u,`title`,m),d=ui(u,1,``,null,d,{active:V(a)===`light`}),J(f,`aria-pressed`,V(a)===`dark`),J(f,`aria-label`,h),J(f,`title`,g),p=ui(f,1,``,null,p,{active:V(a)===`dark`})},[()=>(U(Q),n(),H(()=>Q(`theme`,n()))),()=>(U(Q),n(),H(()=>Q(`themeSystem`,n()))),()=>(U(Q),n(),H(()=>Q(`themeSystem`,n()))),()=>(U(Q),n(),H(()=>Q(`themeAuto`,n()))),()=>(U(Q),n(),H(()=>Q(`themeLight`,n()))),()=>(U(Q),n(),H(()=>Q(`themeLight`,n()))),()=>(U(Q),n(),H(()=>Q(`themeDark`,n()))),()=>(U(Q),n(),H(()=>Q(`themeDark`,n())))]),Sr(`click`,s,()=>N(a,`system`)),Sr(`click`,u,()=>N(a,`light`)),Sr(`click`,f,()=>N(a,`dark`)),G(e,o),k(),i()}Cr([`click`]);var $i=W(``),ea=W(` `,1);function ta(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii();function a(e){let t=e.currentTarget.value;Ui.includes(t)&&$.set(t)}Y();var o=ea(),s=F(o),c=P(s),l=L(c);Qr(l,5,()=>Ui,Jr,(e,t)=>{var n=$i(),r=I(n,!0),i={};R(()=>{K(r,Wi[V(t)]),i!==(i=V(t))&&(n.value=(n.__value=i)??``)}),G(e,n)}),E(l);var u;mi(l),E(s);var d=I(L(s,2),!0);R((e,t)=>{K(c,`${e??``} `),J(l,`aria-label`,t),u!==(u=n())&&(l.value=(l.__value=u)??``,pi(l,u)),K(d,Wi[n()])},[()=>Q(`language`,n()),()=>Q(`language`,n())]),Sr(`change`,l,a),G(e,o),k(),i()}Cr([`change`]);var na=W(`
                            `);function ra(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`repository`,8);Y();var o=na(),s=P(o),c=P(s),l=I(c,!0),u=L(c,2),d=I(P(u),!0);E(u),E(s);var f=L(s,2),p=P(f),m=L(P(p));E(p);var h=L(p);ta(h,{}),Qi(L(h),{}),E(f),E(o),R((e,t,n)=>{K(l,e),K(d,t),K(m,` ${n??``}`)},[()=>(U(Q),n(),H(()=>Q(`setup`,n()))),()=>(U(a()),U(Q),n(),H(()=>a()??Q(`connecting`,n()))),()=>(U(Q),n(),H(()=>Q(`localSession`,n())))]),G(e,o),k(),i()}var ia={"repository.confirm":{title:`Confirm this repository`,description:`This checkout points to {repository} on branch {branch}. Confirm the target before configuring PAT access or files.`,choices:[`Yes, this is my repository`,`Stop and choose another checkout`]},"setup.depth":{title:`Choose how much detail to review`,description:`Basic still asks about permissions, security, branch roles, Projects, approval and storage. Selected advanced agent, branch-prefix and Bugbot settings keep their defaults; inspect and edit them in the final plan. Custom asks every applicable question. Neither path applies changes now.`,choices:[`Basic guided setup (recommended)`,`Customize every setting`]},"setup.environmentPat":{title:`An environment setup PAT is available`,description:`Its value stays in the CLI process and is never sent to this page. Exiting Copilot cannot unset your parent shell variable.`,choices:[`Use the environment PAT`,`Create or enter a different PAT`]},"plan.review":{title:`Review your setup plan`,description:`Inspect the affected files, workflows, Variables and Secret names before approving. No setup changes start by opening this plan.`},"workflow.update":{title:`Update existing workflows?`,description:`These existing workflow files differ from the setup plan: {files}. Keeping them may leave some new settings inactive.`,choices:[`Keep existing`,`Update setup-managed workflows`]},"setupPat.method":{title:`How will you provide your setup PAT?`,description:`This temporary PAT authorizes this one setup run. GitHub creates it under your operator account; Copilot cannot revoke it for you.`,choices:[`Guided GitHub link`,`Manual PAT`]},"setupPat.ownerKind":{title:`Who owns this repository on GitHub?`,description:`The owner determines which organization permissions may be needed. Check the repository header on GitHub if unsure.`,choices:[`Organization`,`Personal account`,`Not sure`]},"setupPat.review":{title:`Review provisional setup PAT permissions`,description:`These grants follow your choices so far. GitHub inspection may add a requirement; you will review any change before setup starts.`,choices:[`Continue to GitHub`,`Review setup choices again`,`View full permission table`,`Enter a PAT manually`]},"setupPat.entry":{title:`Temporary setup PAT`,description:`Open GitHub as your operator account, complete 2FA, choose “Only select repositories”, select this repository and copy the generated PAT here. This PAT is for this run only; delete it on GitHub afterwards.`},"setupPat.confirmAccount":{title:`GitHub authenticated the setup PAT as @{account}`,description:`Is this the operator account that should configure this repository? A wrong account must stop before any setup change.`,choices:[`Yes, continue`,`No, stop`]},"setupPat.confirmWrites":{title:`Confirm write permissions that GitHub cannot safely test`,description:`Some required write grants cannot be proven without a mutation. Check them in GitHub against the displayed permission table before confirming.`,choices:[`No, stop`,`Yes, I checked them`]},"botPat.method":{title:`How will you provide the bot PAT?`,description:`The bot PAT is separate from the setup PAT. It belongs to the account that will run future GitHub Actions and is stored as a Secret after approval.`,choices:[`Guided GitHub link`,`Manual PAT`]},"botPat.login":{title:`Expected GitHub bot login`,description:`Enter the bot account login without @. Copilot resolves its numeric GitHub ID and compares it with the PAT owner.`},"botPat.entry.guided":{title:`{name} — bot account PAT`,description:`Open GitHub as @{account} (account ID {accountId}), not as the setup operator. Select only this repository, review all grants and paste the PAT here. Suggested expiry: 90 days. An existing Secret value cannot be read back.`},"botPat.entry.manual":{title:`{name} — bot account PAT`,description:`Use the bot account, select only the intended repository and review all grants before pasting its PAT. Suggested expiry: 90 days. An existing Secret value cannot be read back.`},"credential.apiKey":{title:`{name} — {provider} API key`,description:`Paste the API key for {provider}. It is sent only to this local setup process and, if approved, installed as a GitHub Actions Secret. Existing Secret values cannot be read back.`},"credential.existing":{title:`Existing {name}: {status}`,description:`GitHub cannot reveal the current Secret value. Keep it only if you deliberately accept that its health cannot be verified here; replace or skip it otherwise.`,choices:[`Keep existing`,`Replace it`,`Skip this credential`]},"apply.confirm":{title:`Apply this setup now?`,description:`This is the final approval. Local files and selected GitHub resources may change. A partial result may require inspection before retrying.`,choices:[`Apply setup`,`Stop without applying`]}},aa={"repository.confirm":{title:`Confirma el repositorio`,description:`Este checkout apunta a {repository} en la rama {branch}. Comprueba el destino antes de configurar permisos del PAT o archivos.`,choices:[`Sí, es mi repositorio`,`Detener y elegir otro checkout`]},"setup.depth":{title:`Elige cuánto detalle quieres revisar`,description:`El modo básico sigue preguntando por permisos, seguridad, ramas, Projects, aprobación y almacenamiento. Algunos ajustes avanzados de agentes, prefijos de rama y Bugbot conservan sus valores predeterminados; podrás revisarlos y editarlos en el plan final. El modo personalizado pregunta por todos los ajustes aplicables. Ninguno aplica cambios todavía.`,choices:[`Configuración básica guiada (recomendada)`,`Personalizar todos los ajustes`]},"setup.environmentPat":{title:`Hay un PAT de configuración en el entorno`,description:`Su valor permanece en el proceso CLI y no se envía a esta página. Cerrar Copilot no elimina la variable de la terminal original.`,choices:[`Usar el PAT del entorno`,`Crear o introducir otro PAT`]},"plan.review":{title:`Revisa el plan de configuración`,description:`Comprueba los archivos, workflows, Variables y nombres de Secrets antes de aprobar. Abrir el plan no inicia ningún cambio.`},"workflow.update":{title:`¿Actualizar los workflows existentes?`,description:`Estos archivos difieren del plan: {files}. Si los conservas, algunos ajustes nuevos podrían no activarse.`,choices:[`Conservar los existentes`,`Actualizar los workflows gestionados`]},"setupPat.method":{title:`¿Cómo proporcionarás el PAT de configuración?`,description:`Este PAT temporal autoriza una sola ejecución. GitHub lo crea con tu cuenta de operador; Copilot no puede revocarlo por ti.`,choices:[`Enlace guiado de GitHub`,`Introducir PAT manualmente`]},"setupPat.ownerKind":{title:`¿Quién es propietario de este repositorio en GitHub?`,description:`El propietario determina qué permisos de organización pueden hacer falta. Consulta la cabecera del repositorio en GitHub si dudas.`,choices:[`Organización`,`Cuenta personal`,`No lo sé`]},"setupPat.review":{title:`Revisa los permisos provisionales del PAT de configuración`,description:`Estos permisos dependen de las opciones elegidas. Al inspeccionar GitHub podría aparecer otro requisito; lo revisarás antes de aplicar cambios.`,choices:[`Continuar en GitHub`,`Revisar de nuevo las opciones`,`Ver la tabla completa de permisos`,`Introducir un PAT manualmente`]},"setupPat.entry":{title:`PAT temporal de configuración`,description:`Abre GitHub con tu cuenta de operador, completa el 2FA, elige «Only select repositories», selecciona este repositorio y pega aquí el PAT generado. Es solo para esta ejecución; elimínalo en GitHub después.`},"setupPat.confirmAccount":{title:`GitHub autenticó el PAT de configuración como @{account}`,description:`¿Es la cuenta de operador que debe configurar este repositorio? Una cuenta incorrecta debe detener el proceso antes de cualquier cambio.`,choices:[`Sí, continuar`,`No, detener`]},"setupPat.confirmWrites":{title:`Confirma permisos de escritura que GitHub no puede probar sin cambios`,description:`Algunos permisos de escritura no pueden verificarse sin modificar recursos. Compruébalos en GitHub frente a la tabla mostrada antes de confirmar.`,choices:[`No, detener`,`Sí, los he comprobado`]},"botPat.method":{title:`¿Cómo proporcionarás el PAT del bot?`,description:`Es distinto del PAT de configuración. Pertenece a la cuenta que ejecutará las futuras GitHub Actions y se instalará como Secret tras la aprobación.`,choices:[`Enlace guiado de GitHub`,`Introducir PAT manualmente`]},"botPat.login":{title:`Usuario previsto del bot en GitHub`,description:`Introduce el nombre de usuario del bot sin @. Copilot consultará su ID numérico de GitHub y lo comparará con el propietario del PAT.`},"botPat.entry.guided":{title:`{name} — PAT de la cuenta bot`,description:`Abre GitHub como @{account} (ID {accountId}), no como operador de setup. Selecciona solo este repositorio, revisa todos los permisos y pega aquí el PAT. Caducidad sugerida: 90 días. El valor de un Secret existente no puede leerse.`},"botPat.entry.manual":{title:`{name} — PAT de la cuenta bot`,description:`Usa la cuenta bot, selecciona solo el repositorio previsto y revisa todos los permisos antes de pegar el PAT. Caducidad sugerida: 90 días. El valor de un Secret existente no puede leerse.`},"credential.apiKey":{title:`{name} — clave API de {provider}`,description:`Pega la clave API de {provider}. Solo se envía a este proceso local y, si apruebas el plan, se instala como Secret de GitHub Actions. Los valores existentes no pueden leerse.`},"credential.existing":{title:`{name} existente: {status}`,description:`GitHub no muestra el valor actual del Secret. Consérvalo solo si aceptas expresamente que aquí no se puede comprobar su estado; de lo contrario, sustitúyelo u omítelo.`,choices:[`Conservar`,`Sustituir`,`Omitir esta credencial`]},"apply.confirm":{title:`¿Aplicar la configuración ahora?`,description:`Esta es la aprobación final. Pueden cambiar archivos locales y recursos de GitHub seleccionados. Si el resultado es parcial, revísalo antes de reintentar.`,choices:[`Aplicar configuración`,`Detener sin aplicar`]}},oa={"repository.confirm":{title:`Confirmez ce dépôt`,description:`Ce dossier pointe vers {repository}, branche {branch}. Vérifiez la cible avant de configurer les accès PAT ou les fichiers.`,choices:[`Oui, c’est mon dépôt`,`Arrêter et choisir un autre dossier`]},"setup.depth":{title:`Choisissez le niveau de détail`,description:`Le parcours de base demande toujours les autorisations, la sécurité, les branches, Projects, l’approbation et le stockage. Certains réglages avancés des agents, préfixes de branche et Bugbot conservent leurs valeurs par défaut ; vous pourrez les examiner et les modifier dans le plan final. Le parcours personnalisé pose toutes les questions applicables. Aucun changement n’est appliqué à ce stade.`,choices:[`Configuration de base guidée (recommandée)`,`Personnaliser tous les réglages`]},"setup.environmentPat":{title:`Un PAT de configuration est disponible dans l’environnement`,description:`Sa valeur reste dans le processus CLI et n’est jamais envoyée à cette page. Quitter Copilot ne supprime pas la variable du shell parent.`,choices:[`Utiliser le PAT de l’environnement`,`Créer ou saisir un autre PAT`]},"plan.review":{title:`Examinez le plan de configuration`,description:`Vérifiez les fichiers, workflows, Variables et noms de Secrets avant d’approuver. Ouvrir le plan ne lance aucun changement.`},"workflow.update":{title:`Mettre à jour les workflows existants ?`,description:`Ces fichiers diffèrent du plan : {files}. Les conserver peut laisser certains nouveaux réglages inactifs.`,choices:[`Conserver les fichiers existants`,`Mettre à jour les workflows gérés`]},"setupPat.method":{title:`Comment fournirez-vous le PAT de configuration ?`,description:`Ce PAT temporaire autorise une seule exécution. GitHub le crée avec votre compte opérateur ; Copilot ne peut pas le révoquer à votre place.`,choices:[`Lien GitHub guidé`,`Saisir un PAT manuellement`]},"setupPat.ownerKind":{title:`À qui appartient ce dépôt sur GitHub ?`,description:`Le propriétaire détermine les éventuelles autorisations d’organisation. Consultez l’en-tête du dépôt sur GitHub en cas de doute.`,choices:[`Organisation`,`Compte personnel`,`Je ne sais pas`]},"setupPat.review":{title:`Examinez les autorisations provisoires du PAT de configuration`,description:`Ces autorisations suivent vos choix. L’inspection de GitHub peut révéler un besoin supplémentaire ; vous le reverrez avant tout changement.`,choices:[`Continuer sur GitHub`,`Revoir les choix de configuration`,`Voir toutes les autorisations`,`Saisir un PAT manuellement`]},"setupPat.entry":{title:`PAT temporaire de configuration`,description:`Ouvrez GitHub avec votre compte opérateur, effectuez la 2FA, choisissez « Only select repositories », sélectionnez ce dépôt puis collez ici le PAT généré. Il ne sert qu’à cette exécution ; supprimez-le sur GitHub ensuite.`},"setupPat.confirmAccount":{title:`GitHub a authentifié le PAT de configuration comme @{account}`,description:`Est-ce bien le compte opérateur autorisé à configurer ce dépôt ? Un autre compte doit arrêter le processus avant tout changement.`,choices:[`Oui, continuer`,`Non, arrêter`]},"setupPat.confirmWrites":{title:`Confirmez les droits d’écriture que GitHub ne peut pas vérifier sans changement`,description:`Certains droits d’écriture ne peuvent être prouvés sans modifier des ressources. Comparez-les au tableau affiché sur GitHub avant de confirmer.`,choices:[`Non, arrêter`,`Oui, je les ai vérifiés`]},"botPat.method":{title:`Comment fournirez-vous le PAT du bot ?`,description:`Il est distinct du PAT de configuration. Il appartient au compte qui exécutera les futures GitHub Actions et sera installé comme Secret après approbation.`,choices:[`Lien GitHub guidé`,`Saisir un PAT manuellement`]},"botPat.login":{title:`Identifiant GitHub attendu pour le bot`,description:`Saisissez l’identifiant du bot sans @. Copilot récupère son ID numérique GitHub et le compare au propriétaire du PAT.`},"botPat.entry.guided":{title:`{name} — PAT du compte bot`,description:`Ouvrez GitHub en tant que @{account} (ID {accountId}), pas en tant qu’opérateur. Sélectionnez uniquement ce dépôt, vérifiez tous les droits et collez le PAT ici. Expiration suggérée : 90 jours. La valeur d’un Secret existant ne peut pas être relue.`},"botPat.entry.manual":{title:`{name} — PAT du compte bot`,description:`Utilisez le compte bot, sélectionnez uniquement le dépôt voulu et vérifiez tous les droits avant de coller le PAT. Expiration suggérée : 90 jours. La valeur d’un Secret existant ne peut pas être relue.`},"credential.apiKey":{title:`{name} — clé API de {provider}`,description:`Collez la clé API de {provider}. Elle est envoyée uniquement au processus local puis, si vous approuvez le plan, installée comme Secret GitHub Actions. Les valeurs existantes ne peuvent pas être relues.`},"credential.existing":{title:`{name} existant : {status}`,description:`GitHub ne révèle pas la valeur actuelle du Secret. Ne la conservez que si vous acceptez explicitement de ne pas pouvoir vérifier son état ici ; sinon, remplacez-la ou ignorez-la.`,choices:[`Conserver`,`Remplacer`,`Ignorer cet identifiant`]},"apply.confirm":{title:`Appliquer la configuration maintenant ?`,description:`C’est l’approbation finale. Des fichiers locaux et ressources GitHub choisis peuvent changer. Un résultat partiel doit être inspecté avant une nouvelle tentative.`,choices:[`Appliquer la configuration`,`Arrêter sans appliquer`]}},sa={"repository.confirm":{title:`Confirme este repositório`,description:`Esta pasta aponta para {repository}, no ramo {branch}. Confirme o destino antes de configurar acessos PAT ou ficheiros.`,choices:[`Sim, é o meu repositório`,`Parar e escolher outra pasta`]},"setup.depth":{title:`Escolha o nível de detalhe`,description:`O percurso básico continua a perguntar sobre permissões, segurança, ramos, Projects, aprovação e armazenamento. Algumas definições avançadas de agentes, prefixos de ramos e Bugbot mantêm os valores predefinidos; poderá revê-las e editá-las no plano final. O percurso personalizado pergunta por todas as definições aplicáveis. Nenhum dos percursos aplica alterações nesta fase.`,choices:[`Configuração básica guiada (recomendada)`,`Personalizar todas as definições`]},"setup.environmentPat":{title:`Existe um PAT de configuração no ambiente`,description:`O valor permanece no processo CLI e nunca é enviado para esta página. Sair do Copilot não remove a variável da shell original.`,choices:[`Usar o PAT do ambiente`,`Criar ou introduzir outro PAT`]},"plan.review":{title:`Reveja o plano de configuração`,description:`Confirme ficheiros, fluxos, Variables e nomes de Secrets antes de aprovar. Abrir o plano não inicia alterações.`,choices:void 0},"workflow.update":{title:`Atualizar os fluxos existentes?`,description:`Estes ficheiros diferem do plano: {files}. Conservá-los pode deixar algumas definições novas inativas.`,choices:[`Conservar os existentes`,`Atualizar os fluxos geridos`]},"setupPat.method":{title:`Como irá fornecer o PAT de configuração?`,description:`Este PAT temporário autoriza uma única execução. O GitHub cria-o na sua conta de operador; o Copilot não pode revogá-lo por si.`,choices:[`Ligação guiada do GitHub`,`Introduzir PAT manualmente`]},"setupPat.ownerKind":{title:`Quem é o proprietário deste repositório no GitHub?`,description:`O proprietário determina as permissões de organização necessárias. Consulte o cabeçalho do repositório no GitHub se tiver dúvidas.`,choices:[`Organização`,`Conta pessoal`,`Não tenho a certeza`]},"setupPat.review":{title:`Reveja as permissões provisórias do PAT de configuração`,description:`Estas permissões seguem as suas escolhas. A inspeção do GitHub pode revelar outro requisito; irá revê-lo antes de qualquer alteração.`,choices:[`Continuar no GitHub`,`Rever as escolhas`,`Ver a tabela completa de permissões`,`Introduzir um PAT manualmente`]},"setupPat.entry":{title:`PAT temporário de configuração`,description:`Abra o GitHub com a sua conta de operador, conclua a 2FA, escolha «Only select repositories», selecione este repositório e cole aqui o PAT gerado. É apenas para esta execução; elimine-o no GitHub depois.`},"setupPat.confirmAccount":{title:`O GitHub autenticou o PAT de configuração como @{account}`,description:`É esta a conta de operador que deve configurar o repositório? Uma conta errada tem de parar o processo antes de qualquer alteração.`,choices:[`Sim, continuar`,`Não, parar`]},"setupPat.confirmWrites":{title:`Confirme permissões de escrita que o GitHub não pode testar sem alterações`,description:`Algumas permissões de escrita não podem ser provadas sem alterar recursos. Compare-as com a tabela no GitHub antes de confirmar.`,choices:[`Não, parar`,`Sim, já as verifiquei`]},"botPat.method":{title:`Como irá fornecer o PAT do bot?`,description:`É diferente do PAT de configuração. Pertence à conta que executará as futuras GitHub Actions e será instalado como Secret após aprovação.`,choices:[`Ligação guiada do GitHub`,`Introduzir PAT manualmente`]},"botPat.login":{title:`Utilizador GitHub esperado para o bot`,description:`Introduza o nome de utilizador do bot sem @. O Copilot consulta o ID numérico do GitHub e compara-o com o proprietário do PAT.`},"botPat.entry.guided":{title:`{name} — PAT da conta bot`,description:`Abra o GitHub como @{account} (ID {accountId}), não como operador. Selecione apenas este repositório, reveja todas as permissões e cole aqui o PAT. Validade sugerida: 90 dias. Não é possível voltar a ler o valor de um Secret existente.`},"botPat.entry.manual":{title:`{name} — PAT da conta bot`,description:`Use a conta bot, selecione apenas o repositório pretendido e reveja todas as permissões antes de colar o PAT. Validade sugerida: 90 dias. Não é possível voltar a ler o valor de um Secret existente.`},"credential.apiKey":{title:`{name} — chave API de {provider}`,description:`Cole a chave API de {provider}. Só é enviada para este processo local e, se aprovar o plano, instalada como Secret do GitHub Actions. Os valores existentes não podem voltar a ser lidos.`},"credential.existing":{title:`{name} existente: {status}`,description:`O GitHub não revela o valor atual do Secret. Conserve-o apenas se aceitar expressamente que aqui não se pode verificar o seu estado; caso contrário, substitua-o ou ignore-o.`,choices:[`Conservar`,`Substituir`,`Ignorar esta credencial`]},"apply.confirm":{title:`Aplicar a configuração agora?`,description:`Esta é a aprovação final. Ficheiros locais e recursos GitHub selecionados podem mudar. Um resultado parcial exige inspeção antes de tentar novamente.`,choices:[`Aplicar configuração`,`Parar sem aplicar`]}},ca={"session.controlMoved":`Control moved to this tab. The previous tab is now read-only.`,"session.cancelled":`Setup stopped before applying further changes. Any PAT created on GitHub still exists until you delete it there.`,"plan.ready":`Plan ready: {files} files, {variables} Variables and {secrets} Secret names. Review it before continuing.`,"permission.preview":`Permission preview: issue workflows {issues}; PR approval {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Review the exact grants before creating the setup PAT.`,"setupPat.corrected.bootstrap":`The setup PAT could not access the repository. No setup changes started. Required grants: {grants}. Create a corrected PAT using the updated GitHub link.`,"setupPat.corrected.final":`Required setup PAT permissions changed after inspection. No setup changes started. New grants: {grants}. Create a corrected PAT using the updated GitHub link.`,"setupPat.cleanup":`Delete the temporary setup PAT in GitHub Settings after this run. Closing Copilot does not revoke it.`,"botPat.separation":`The bot PAT is separate from your setup PAT. These credentials become GitHub Actions Secrets: {names}. Existing Secret values cannot be read back. Re-enter an existing bot PAT so its grants can be checked. No credential-health workflow runs before Apply.`,"credential.checks":`Credential checks finished for {count} items. Each result is shown below. The terminal has technical details; an existing Secret value cannot be read back.`,"credential.status.valid":`Valid`,"credential.status.invalid":`Invalid`,"credential.status.missing":`Missing`,"credential.status.unverifiable":`Cannot be verified without a new value`,"credential.status.not_required":`Not required`,"validation.producers":`Select 1–8 observed checks or enter exact name|App ID|workflow tuples.`,"validation.duplicateNames":`Two trusted producers use the same check name. Coverage stores only the name: choose one producer or rename the CI jobs.`,"validation.projectStatusVerified":`Open every selected Project in GitHub and confirm that all four exact Status values exist. Answer Yes after checking, or No to choose Projects again.`,"validation.projectStatusRedo":`Status values were not confirmed. Choose compatible Projects, then review their Status options again.`,"validation.number":`Enter a non-negative whole number.`,"validation.boolean":`Enter yes or no.`,"validation.choice":`Select one of the listed options.`,"validation.unknownResource":`Unknown inherited resource names: {names}. Choose only names shown in the inherited list.`,"validation.unknownWorkflow":`Unknown issue workflows: {names}. Choose only the listed workflow types.`,"validation.firstQuestion":`This is the first question in this pass. Review it or cancel setup.`,"validation.duplicateProducer":`This trusted check was selected twice. Remove the duplicate selection.`,"validation.savedStatus":`The saved Status value is not available in every selected Project. Choose a listed option.`,"validation.projectIncompatible":`The selected Projects have no common Status option. Choose compatible Projects or configure them separately.`,"validation.projectLimit":`Choose at most 10 Projects; separate their numbers or URLs with commas.`,"validation.projectOwnerNeeded":`A Project URL needs a known repository owner; enter its positive number instead.`,"validation.projectOwnerMismatch":`Use a GitHub Project URL belonging to {owner}, without query parameters.`,"validation.projectUrl":`Enter a valid GitHub Project URL or positive Project number.`,"validation.projectNumber":`Enter the positive Project number from its GitHub URL, not a PVT_ GraphQL ID.`,"validation.projectNumberRange":`Project numbers must be positive integers at most 2147483647.`,"validation.projectDuplicate":`Project {number} was selected more than once.`,"validation.fixedIssues":`Your configuration explicitly enables release or hotfix automation. Keep Issues enabled or edit that configuration first.`,"validation.fixedWorkflowEnabled":`Your configuration enables {kind}. Keep that workflow selected or edit the configuration first.`,"validation.fixedWorkflowDisabled":`Your configuration disables {kind}. Deselect that workflow or edit the configuration first.`,"validation.unknown":`This answer could not be accepted. Review the question and its help; the terminal has the technical detail.`},la={"session.controlMoved":`El control ha pasado a esta pestaña. La anterior ahora es de solo lectura.`,"session.cancelled":`La configuración se detuvo antes de aplicar más cambios. Los PAT creados en GitHub siguen existiendo hasta que los elimines allí.`,"plan.ready":`Plan listo: {files} archivos, {variables} Variables y {secrets} nombres de Secrets. Revísalo antes de continuar.`,"permission.preview":`Vista previa de permisos: flujos de incidencias {issues}; aprobación de PR {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Revisa los permisos exactos antes de crear el PAT de configuración.`,"setupPat.corrected.bootstrap":`El PAT de configuración no pudo acceder al repositorio. No se iniciaron cambios. Permisos necesarios: {grants}. Crea un PAT corregido desde el enlace actualizado de GitHub.`,"setupPat.corrected.final":`Los permisos necesarios del PAT cambiaron tras la inspección. No se iniciaron cambios. Permisos nuevos: {grants}. Crea un PAT corregido desde el enlace actualizado.`,"setupPat.cleanup":`Elimina el PAT temporal de configuración en los ajustes de GitHub después de esta ejecución. Cerrar Copilot no lo revoca.`,"botPat.separation":`El PAT del bot es distinto del de configuración. Estas credenciales se instalarán como Secrets de GitHub Actions: {names}. Los valores existentes no pueden leerse. Vuelve a introducir un PAT del bot para comprobar sus permisos. Antes de Aplicar no se ejecuta ningún workflow de comprobación.`,"credential.checks":`Se han comprobado {count} credenciales. Abajo aparece el resultado de cada una. La terminal contiene los detalles técnicos; el valor de un Secret existente no puede leerse.`,"credential.status.valid":`Válida`,"credential.status.invalid":`No válida`,"credential.status.missing":`Falta`,"credential.status.unverifiable":`No verificable sin un valor nuevo`,"credential.status.not_required":`No necesaria`,"validation.producers":`Selecciona entre 1 y 8 checks observados o introduce las tuplas exactas nombre|ID de App|workflow.`,"validation.duplicateNames":`Dos productores fiables tienen el mismo nombre de check. La cobertura solo guarda el nombre: elige uno o cambia el nombre de los jobs de CI.`,"validation.projectStatusVerified":`Abre cada Project elegido en GitHub y confirma los cuatro valores Status exactos. Responde Sí tras comprobarlo, o No para elegir Projects de nuevo.`,"validation.projectStatusRedo":`No se confirmaron los valores Status. Elige Projects compatibles y vuelve a revisar sus opciones Status.`,"validation.number":`Introduce un número entero no negativo.`,"validation.boolean":`Elige Sí o No.`,"validation.choice":`Elige una de las opciones mostradas.`,"validation.unknownResource":`Nombres de recursos heredados desconocidos: {names}. Elige solo nombres de la lista heredada.`,"validation.unknownWorkflow":`Flujos de issues desconocidos: {names}. Elige solo los tipos indicados.`,"validation.firstQuestion":`Esta es la primera pregunta de esta pasada. Revísala o cancela la configuración.`,"validation.duplicateProducer":`Has seleccionado dos veces el mismo check fiable. Quita la selección duplicada.`,"validation.savedStatus":`El valor Status guardado no existe en todos los Projects seleccionados. Elige una opción de la lista.`,"validation.projectIncompatible":`Los Projects elegidos no comparten ningún valor Status. Elige Projects compatibles o configúralos por separado.`,"validation.projectLimit":`Elige como máximo 10 Projects; separa sus números o URL con comas.`,"validation.projectOwnerNeeded":`Para usar la URL de un Project hay que conocer el propietario del repositorio; introduce su número positivo.`,"validation.projectOwnerMismatch":`Usa la URL de un Project de GitHub que pertenezca a {owner}, sin parámetros.`,"validation.projectUrl":`Introduce una URL válida de un Project de GitHub o su número positivo.`,"validation.projectNumber":`Introduce el número positivo del Project que aparece en su URL, no un ID GraphQL PVT_.`,"validation.projectNumberRange":`El número del Project debe ser un entero positivo no mayor de 2147483647.`,"validation.projectDuplicate":`Has seleccionado el Project {number} más de una vez.`,"validation.fixedIssues":`Tu configuración activa expresamente release o hotfix. Mantén Issues activado o cambia antes la configuración.`,"validation.fixedWorkflowEnabled":`Tu configuración activa {kind}. Mantén ese flujo seleccionado o cambia antes la configuración.`,"validation.fixedWorkflowDisabled":`Tu configuración desactiva {kind}. Desmarca ese flujo o cambia antes la configuración.`,"validation.unknown":`No se pudo aceptar esta respuesta. Revisa la pregunta y su ayuda; la terminal contiene el detalle técnico.`},ua={"session.controlMoved":`Le contrôle est passé à cet onglet. L’onglet précédent est maintenant en lecture seule.`,"session.cancelled":`La configuration s’est arrêtée avant de nouveaux changements. Tout PAT créé sur GitHub existe encore jusqu’à sa suppression là-bas.`,"plan.ready":`Plan prêt : {files} fichiers, {variables} Variables et {secrets} noms de Secrets. Examinez-le avant de continuer.`,"permission.preview":`Aperçu des droits : flux de tickets {issues} ; approbation des PR {approval} ; Secrets {secrets} ; Variables {variables} ; Projects {projects}. Vérifiez les droits exacts avant de créer le PAT de configuration.`,"setupPat.corrected.bootstrap":`Le PAT de configuration n’a pas pu accéder au dépôt. Aucun changement n’a commencé. Droits requis : {grants}. Créez un PAT corrigé avec le lien GitHub mis à jour.`,"setupPat.corrected.final":`Les droits requis du PAT ont changé après inspection. Aucun changement n’a commencé. Nouveaux droits : {grants}. Créez un PAT corrigé avec le lien mis à jour.`,"setupPat.cleanup":`Supprimez le PAT temporaire de configuration dans les paramètres GitHub après cette exécution. Fermer Copilot ne le révoque pas.`,"botPat.separation":`Le PAT du bot est distinct du PAT de configuration. Ces identifiants deviendront des Secrets GitHub Actions : {names}. Les valeurs existantes ne peuvent pas être relues. Saisissez à nouveau un PAT du bot pour vérifier ses droits. Aucun workflow de vérification ne démarre avant Appliquer.`,"credential.checks":`Vérification terminée pour {count} identifiants. Le résultat de chacun figure ci-dessous. Le terminal contient les détails techniques ; la valeur d’un Secret existant ne peut pas être relue.`,"credential.status.valid":`Valide`,"credential.status.invalid":`Invalide`,"credential.status.missing":`Manquant`,"credential.status.unverifiable":`Invérifiable sans nouvelle valeur`,"credential.status.not_required":`Non requis`,"validation.producers":`Choisissez 1 à 8 vérifications observées ou saisissez les triplets exacts nom|ID d’App|workflow.`,"validation.duplicateNames":`Deux producteurs fiables portent le même nom de vérification. La couverture ne stocke que ce nom : choisissez-en un ou renommez les jobs CI.`,"validation.projectStatusVerified":`Ouvrez chaque Project choisi sur GitHub et confirmez les quatre valeurs Status exactes. Répondez Oui après vérification, ou Non pour choisir à nouveau les Projects.`,"validation.projectStatusRedo":`Les valeurs Status n’ont pas été confirmées. Choisissez des Projects compatibles, puis revérifiez leurs options Status.`,"validation.number":`Saisissez un entier positif ou nul.`,"validation.boolean":`Choisissez Oui ou Non.`,"validation.choice":`Choisissez une des options affichées.`,"validation.unknownResource":`Noms de ressources héritées inconnus : {names}. Choisissez seulement les noms de la liste héritée.`,"validation.unknownWorkflow":`Workflows de ticket inconnus : {names}. Choisissez seulement les types proposés.`,"validation.firstQuestion":`C’est la première question de cette passe. Vérifiez-la ou annulez la configuration.`,"validation.duplicateProducer":`Cette vérification fiable a été choisie deux fois. Retirez le doublon.`,"validation.savedStatus":`La valeur Status enregistrée n’existe pas dans tous les Projects choisis. Sélectionnez une option proposée.`,"validation.projectIncompatible":`Les Projects choisis ne partagent aucune valeur Status. Choisissez des Projects compatibles ou configurez-les séparément.`,"validation.projectLimit":`Choisissez au plus 10 Projects ; séparez leurs numéros ou URL par des virgules.`,"validation.projectOwnerNeeded":`Une URL de Project exige de connaître le propriétaire du dépôt ; saisissez plutôt son numéro positif.`,"validation.projectOwnerMismatch":`Utilisez une URL de Project GitHub appartenant à {owner}, sans paramètres.`,"validation.projectUrl":`Saisissez une URL valide de Project GitHub ou son numéro positif.`,"validation.projectNumber":`Saisissez le numéro positif figurant dans l’URL du Project, pas un ID GraphQL PVT_.`,"validation.projectNumberRange":`Le numéro du Project doit être un entier positif inférieur ou égal à 2147483647.`,"validation.projectDuplicate":`Le Project {number} a été choisi plusieurs fois.`,"validation.fixedIssues":`Votre configuration active explicitement release ou hotfix. Gardez Issues activé ou modifiez d’abord la configuration.`,"validation.fixedWorkflowEnabled":`Votre configuration active {kind}. Gardez ce flux sélectionné ou modifiez d’abord la configuration.`,"validation.fixedWorkflowDisabled":`Votre configuration désactive {kind}. Désélectionnez ce flux ou modifiez d’abord la configuration.`,"validation.unknown":`Cette réponse n’a pas été acceptée. Vérifiez la question et son aide ; le terminal contient le détail technique.`},da={"session.controlMoved":`O controlo passou para este separador. O separador anterior é agora apenas de leitura.`,"session.cancelled":`A configuração parou antes de novas alterações. Os PAT criados no GitHub continuam a existir até os eliminar lá.`,"plan.ready":`Plano pronto: {files} ficheiros, {variables} Variables e {secrets} nomes de Secrets. Reveja-o antes de continuar.`,"permission.preview":`Pré-visualização das permissões: fluxos de issues {issues}; aprovação de PR {approval}; Secrets {secrets}; Variables {variables}; Projects {projects}. Reveja as permissões exatas antes de criar o PAT de configuração.`,"setupPat.corrected.bootstrap":`O PAT de configuração não conseguiu aceder ao repositório. Não começaram alterações. Permissões necessárias: {grants}. Crie um PAT corrigido com a ligação GitHub atualizada.`,"setupPat.corrected.final":`As permissões necessárias do PAT mudaram após inspeção. Não começaram alterações. Novas permissões: {grants}. Crie um PAT corrigido com a ligação atualizada.`,"setupPat.cleanup":`Elimine o PAT temporário de configuração nas definições do GitHub após esta execução. Fechar o Copilot não o revoga.`,"botPat.separation":`O PAT do bot é distinto do PAT de configuração. Estas credenciais serão Secrets do GitHub Actions: {names}. Os valores existentes não podem voltar a ser lidos. Reintroduza um PAT do bot para verificar as permissões. Nenhum fluxo de verificação é executado antes de Aplicar.`,"credential.checks":`Verificação concluída para {count} credenciais. O resultado de cada uma aparece abaixo. O terminal contém os detalhes técnicos; o valor de um Secret existente não pode voltar a ser lido.`,"credential.status.valid":`Válida`,"credential.status.invalid":`Inválida`,"credential.status.missing":`Em falta`,"credential.status.unverifiable":`Não verificável sem um novo valor`,"credential.status.not_required":`Não necessária`,"validation.producers":`Selecione 1 a 8 verificações observadas ou introduza os triplos exatos nome|ID da App|workflow.`,"validation.duplicateNames":`Dois produtores fiáveis têm o mesmo nome de check. A cobertura guarda apenas o nome: escolha um ou altere o nome dos jobs de CI.`,"validation.projectStatusVerified":`Abra cada Project escolhido no GitHub e confirme os quatro valores Status exatos. Responda Sim após verificar, ou Não para voltar a escolher Projects.`,"validation.projectStatusRedo":`Os valores Status não foram confirmados. Escolha Projects compatíveis e volte a verificar as opções Status.`,"validation.number":`Introduza um número inteiro não negativo.`,"validation.boolean":`Escolha Sim ou Não.`,"validation.choice":`Escolha uma das opções apresentadas.`,"validation.unknownResource":`Nomes de recursos herdados desconhecidos: {names}. Escolha apenas nomes da lista herdada.`,"validation.unknownWorkflow":`Fluxos de questões desconhecidos: {names}. Escolha apenas os tipos indicados.`,"validation.firstQuestion":`Esta é a primeira pergunta desta ronda. Reveja-a ou cancele a configuração.`,"validation.duplicateProducer":`Esta verificação de confiança foi selecionada duas vezes. Remova a seleção duplicada.`,"validation.savedStatus":`O valor Status guardado não existe em todos os Projects escolhidos. Selecione uma opção da lista.`,"validation.projectIncompatible":`Os Projects escolhidos não partilham qualquer valor Status. Escolha Projects compatíveis ou configure-os separadamente.`,"validation.projectLimit":`Escolha no máximo 10 Projects; separe os números ou URL por vírgulas.`,"validation.projectOwnerNeeded":`Uma URL de Project exige que se conheça o proprietário do repositório; introduza antes o número positivo.`,"validation.projectOwnerMismatch":`Use uma URL de Project do GitHub pertencente a {owner}, sem parâmetros.`,"validation.projectUrl":`Introduza uma URL válida de Project do GitHub ou o respetivo número positivo.`,"validation.projectNumber":`Introduza o número positivo apresentado na URL do Project, não um ID GraphQL PVT_.`,"validation.projectNumberRange":`O número do Project tem de ser um inteiro positivo até 2147483647.`,"validation.projectDuplicate":`O Project {number} foi selecionado mais do que uma vez.`,"validation.fixedIssues":`A sua configuração ativa explicitamente release ou hotfix. Mantenha Issues ativo ou altere primeiro a configuração.`,"validation.fixedWorkflowEnabled":`A sua configuração ativa {kind}. Mantenha esse fluxo selecionado ou altere primeiro a configuração.`,"validation.fixedWorkflowDisabled":`A sua configuração desativa {kind}. Desmarque esse fluxo ou altere primeiro a configuração.`,"validation.unknown":`Esta resposta não foi aceite. Reveja a pergunta e a ajuda; o terminal contém o detalhe técnico.`},fa={es:{All:`Todos`,prompt:`Preguntar antes de crear el enlace`,"create-if-missing":`Crear el enlace si falta`,disabled:`Desactivado`,replace:`Sustituir`,append:`Añadir`,preserve:`Conservar`,info:`Informativa`,low:`Baja`,medium:`Media`,high:`Alta`,smart:`Adaptativa`,default:`Predeterminado`,auto:`Automático`,always:`Reinstalar siempre`,recommend:`Recomendar aprobación`,guarded:`Aprobar solo con garantías`,off:`Desactivado`,check:`Check de CI que exige la cobertura`,numeric:`Informe numérico verificable`,repository:`Repositorio`,organization:`Organización`,selected:`Repositorios seleccionados`,private:`Repositorios privados`,all:`Todos los repositorios`,"production-lineage":`Conservar el linaje de producción`,"canonical-gitflow":`Git-Flow canónico`,manual:`Manual`,"auto-merge":`Fusionar automáticamente`,"merge-queue":`Cola de integración`,"create-only":`Solo crear PR`,direct:`Integración directa`,"sync-branch":`Mediante rama de sincronización`,"prefer-release":`Priorizar la release`,development:`Desarrollo`,both:`Ambos destinos`,"source-only":`Solo rama de origen`,"sync-only":`Solo rama de sincronización`,none:`Ninguna`,close:`Cerrar el issue`,"keep-open":`Mantener abierto`,guided:`Guiado`,compact:`Compacto`,quiet:`Mínimo`,update:`Actualizar el comentario`,milestones:`Publicar en hitos`,feature:`Funcionalidad`,bugfix:`Corrección`,documentation:`Documentación`,chore:`Mantenimiento`,help:`Ayuda o pregunta`,hotfix:`Arreglo urgente`,release:`Release`},fr:{All:`Tous`,prompt:`Demander avant de créer le renvoi`,"create-if-missing":`Créer le renvoi s’il manque`,disabled:`Désactivé`,replace:`Remplacer`,append:`Ajouter`,preserve:`Conserver`,info:`Information`,low:`Faible`,medium:`Moyenne`,high:`Élevée`,smart:`Adaptatif`,default:`Par défaut`,auto:`Automatique`,always:`Toujours réinstaller`,recommend:`Recommander une approbation`,guarded:`Approuver sous garde`,off:`Désactivé`,check:`Vérification CI imposant la couverture`,numeric:`Rapport numérique vérifiable`,repository:`Dépôt`,organization:`Organisation`,selected:`Dépôts sélectionnés`,private:`Dépôts privés`,all:`Tous les dépôts`,"production-lineage":`Préserver la filiation de production`,"canonical-gitflow":`Git-Flow canonique`,manual:`Manuel`,"auto-merge":`Fusionner automatiquement`,"merge-queue":`File de fusion`,"create-only":`Créer la PR uniquement`,direct:`Fusion directe`,"sync-branch":`Par branche de synchronisation`,"prefer-release":`Privilégier la version`,development:`Développement`,both:`Les deux destinations`,"source-only":`Branche source seulement`,"sync-only":`Branche de synchronisation seulement`,none:`Aucune`,close:`Fermer le ticket`,"keep-open":`Garder ouvert`,guided:`Guidé`,compact:`Compact`,quiet:`Minimal`,update:`Mettre le commentaire à jour`,milestones:`Publier aux étapes clés`,feature:`Fonctionnalité`,bugfix:`Correction`,documentation:`Documentation`,chore:`Maintenance`,help:`Aide ou question`,hotfix:`Correctif urgent`,release:`Version`},pt:{All:`Todos`,prompt:`Perguntar antes de criar o apontador`,"create-if-missing":`Criar o apontador se faltar`,disabled:`Desativado`,replace:`Substituir`,append:`Acrescentar`,preserve:`Conservar`,info:`Informação`,low:`Baixa`,medium:`Média`,high:`Alta`,smart:`Adaptativo`,default:`Predefinido`,auto:`Automático`,always:`Reinstalar sempre`,recommend:`Recomendar aprovação`,guarded:`Aprovar sob condições`,off:`Desativado`,check:`Verificação CI que exige cobertura`,numeric:`Relatório numérico verificável`,repository:`Repositório`,organization:`Organização`,selected:`Repositórios selecionados`,private:`Repositórios privados`,all:`Todos os repositórios`,"production-lineage":`Preservar a linhagem de produção`,"canonical-gitflow":`Git-Flow canónico`,manual:`Manual`,"auto-merge":`Integrar automaticamente`,"merge-queue":`Fila de integração`,"create-only":`Criar apenas a PR`,direct:`Integração direta`,"sync-branch":`Através de ramo de sincronização`,"prefer-release":`Priorizar a release`,development:`Desenvolvimento`,both:`Ambos os destinos`,"source-only":`Apenas ramo de origem`,"sync-only":`Apenas ramo de sincronização`,none:`Nenhum`,close:`Fechar a questão`,"keep-open":`Manter aberta`,guided:`Guiado`,compact:`Compacto`,quiet:`Mínimo`,update:`Atualizar o comentário`,milestones:`Publicar nos marcos`,feature:`Funcionalidade`,bugfix:`Correção`,documentation:`Documentação`,chore:`Manutenção`,help:`Ajuda ou pergunta`,hotfix:`Hotfix`,release:`Release`}},pa=new Set([`codex`,`opencode`,`cursor`,`openai`,`anthropic`,`google`,`openrouter`,`local`]);function ma(e,t,n){if(n===`en`||pa.has(t))return t;let r=fa[n];if(e===`issueWorkflows.enabled`&&t.includes(` — `)){let e=t.split(` — `,1)[0];if(r[e])return`${e} — ${r[e]}`}return e===`repository.reconciliationCleanup`&&t===`all`?{es:`Todas las ramas temporales`,fr:`Toutes les branches temporaires`,pt:`Todos os ramos temporários`}[n]:r[t]??t}var ha={en:ca,es:la,fr:ua,pt:da};function ga(e,t){if(!e.copyId)return t===`en`?e.text:Q(`unknownLocalError`,t);let n=ha[t][e.copyId],r=e.copyValues??{},i=e.copyId===`permission.preview`?{...r,issues:(r.issues??``).split(`|`).map(e=>ma(`issueWorkflows.enabled`,e,t)).join(`, `),approval:ma(`pullRequestApproval.mode`,r.approval??``,t),secrets:ma(`storage.secrets.defaultScope`,r.secrets??``,t),variables:ma(`storage.variables.defaultScope`,r.variables??``,t),projects:ma(`projects.ids`,r.projects??``,t)}:r,a=n.replace(/\{([a-zA-Z]\w*)\}/gu,(e,t)=>i[t]??``);return e.copyId!==`credential.checks`||!e.credentialChecks?.length?a:`${a}\n${e.credentialChecks.map(e=>{let n=`credential.status.${e.status}`;return`${e.name}: ${ha[t][n]}`}).join(` -`)}`}var _a={en:ia,es:aa,fr:oa,pt:sa};function va(e,t){return e.replace(/\{([a-zA-Z]\w*)\}/gu,(e,n)=>t[n]??``)}function ya(e,t){if(!e.copyId)return;let n=_a[t][e.copyId],r={...e.copyValues??{}};if(e.copyId===`credential.existing`&&r.status&&[`valid`,`invalid`,`missing`,`unverifiable`,`not_required`].includes(r.status)){let e=`credential.status.${r.status}`;r.status=ha[t][e]}return{title:va(n.title,r),description:va(n.description,r),...n.choices?{choices:n.choices}:{}}}function ba(e,t,n){return ya(e,t)?.choices?.[n]??e.choices[n]}var xa=W(`

                            `,1);function Sa(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`view`,8);Tn(()=>(U(o()),n(),ya),()=>{N(a,o()?.outcome===`complete`?Q(`completeTitle`,n()):o()?.outcome===`dry-run`?Q(`previewTitle`,n()):o()?.outcome===`cancelled`?Q(`cancelledTitle`,n()):o()?.outcome?Q(`blockedTitle`,n()):o()?.prompt?.kind===`question`?Q(`choices`,n()):o()?.prompt?.kind===`plan`?Q(`plan`,n()):o()?.prompt?ya(o().prompt,n())?.title??o().prompt.title:Q(`preparing`,n()))}),En(),Y();var s=xa(),c=F(s),l=L(P(c)),u=I(L(l));E(c);var d=L(c,2),f=I(d,!0),p=I(L(d,2),!0);R((e,t,n)=>{K(l,` ${e??``} `),K(u,`${t??``} / 06`),K(f,V(a)),K(p,n)},[()=>(U(qi),U(o()),n(),H(()=>qi(o()?.journey?.current,n()).toUpperCase())),()=>(U(o()),H(()=>String(o()?.journey?.position??1).padStart(2,`0`))),()=>(U(o()),U(Q),n(),H(()=>o()?.outcome?Q(`resultLede`,n()):Q(`activeLede`,n())))]),G(e,s),k(),i()}function Ca(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&(t.pathname===`/settings/personal-access-tokens`||t.pathname.startsWith(`/settings/personal-access-tokens/`))?t.toString():void 0}catch{return}}function wa(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/actions\/runs\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function Ta(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/[A-Za-z0-9-]{1,39}\/[A-Za-z0-9._-]{1,100}\/rules\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}function Ea(e){try{let t=new URL(e??``);return t.protocol===`https:`&&t.hostname===`github.com`&&!t.username&&!t.password&&!t.search&&!t.hash&&/^\/(?:orgs|users)\/[A-Za-z0-9-]{1,39}\/projects\/[1-9][0-9]*$/u.test(t.pathname)?t.toString():void 0}catch{return}}var Da=W(``),Oa=W(``);function ka(e,t){let n=Z(t,`label`,8),r=Z(t,`variant`,8,`primary`),i=Z(t,`disabled`,8,!1),a=Z(t,`arrow`,8,!1),o=Z(t,`onClick`,8);var s=Oa(),c=P(s,!0),l=L(c),u=e=>{G(e,Da())};q(l,e=>{a()&&e(u)}),E(s),R(()=>{ui(s,1,si(r())),s.disabled=i(),K(c,n())}),Sr(`click`,s,function(...e){o()?.apply(this,e)}),G(e,s)}Cr([`click`]);var Aa=W(` `),ja=W(`

                            `);function Ma(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`tone`,8,`info`),s=Z(t,`title`,8),c=Z(t,`message`,8),l=Z(t,`link`,8,void 0),u=Z(t,`actionLabel`,8,void 0),d=Z(t,`onAction`,8,void 0);Tn(()=>U(l()),()=>{N(a,Ca(l()))}),En(),Y();var f=ja(),p=P(f),m=I(p,!0),h=L(p),g=I(h,!0),_=L(h,2),v=e=>{var t=Aa(),r=I(t,!0);R(e=>{J(t,`href`,V(a)),K(r,e)},[()=>(U(Q),n(),H(()=>Q(`githubLink`,n())))]),G(e,t)};q(_,e=>{V(a)&&e(v)});var y=L(_,2),b=e=>{ka(e,{get label(){return u()},variant:`secondary`,get onClick(){return d()}})};q(y,e=>{u()&&d()&&e(b)}),E(f),R(()=>{ui(f,1,`banner ${o()??``}`),J(f,`role`,o()===`error`?`alert`:`status`),K(m,s()),K(g,c())}),G(e,f),k(),i()}function Na(e){let t=String(e.question.defaultValue),n=t.split(`,`).map(e=>e.trim()).filter(Boolean),r=e.question.kind===`multi-select`?n.includes(`All`)&&e.question.choices?.includes(`All`)?[`All`]:(e.question.choices??[]).filter(e=>e!==`All`&&n.includes(e.split(` — `)[0])):e.question.kind===`scope-overrides`?n:e.question.kind===`producer-select`?t.split(`;`).map(e=>e.trim()).filter(Boolean):e.question.kind===`project-select`?n.filter(t=>e.question.projectCandidates?.some(e=>String(e.number)===t)):[],i=e.question.kind===`project-select`?n.filter(e=>!r.includes(e)).join(`,`):t;return{value:e.question.kind===`producer-select`?``:i,selected:r}}function Pa(e,t){return t===`All`?e.includes(`All`)?[]:[`All`]:e.includes(t)?e.filter(e=>e!==t):[...e.filter(e=>e!==`All`),t]}function Fa(e,t,n){return e.question.kind===`scope-overrides`||e.question.kind===`multi-select`?n.length?n.join(`,`):`none`:e.question.kind===`producer-select`?[...n,...t.split(`;`).map(e=>e.trim()).filter(Boolean)].join(`;`):e.question.kind===`project-select`?[...n,...t.split(`,`).map(e=>e.trim()).filter(Boolean)].join(`,`)||`none`:t}var Ia={issueCreated:`projectTransitionIssueCreated`,pullRequestCreated:`projectTransitionPullRequestCreated`,issueInProgress:`projectTransitionIssueInProgress`,pullRequestInProgress:`projectTransitionPullRequestInProgress`};function La(e){if(e)try{let t=new URL(e);if(t.protocol!==`https:`||t.username||t.password||t.search)return;if(t.hostname===`docs.page`&&t.port===``&&t.pathname.startsWith(`/vypdev/copilot/`)||t.hostname===`docs.github.com`&&t.port===``&&t.pathname.startsWith(`/en/`))return t.href}catch{return}}var Ra=W(`

                            `),za=W(`

                            `),Ba=W(` `,1);function Va(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`kind`,8),s=Z(t,`status`,8),c=Z(t,`truncated`,8,!1),l={observed:`checksObserved`,"no-recent-runs":`checksNoRecent`,"no-verifiable-checks":`checksNoVerifiable`,"permission-denied":`checksDenied`,unavailable:`checksUnavailable`},u={observed:`projectsObserved`,empty:`projectsEmpty`,"permission-denied":`projectsDenied`,unavailable:`projectsUnavailable`,unsupported:`projectsUnsupported`};Tn(()=>(U(s()),U(o())),()=>{N(a,s()?o()===`checks`?l[s()]:u[s()]:void 0)}),En(),Y();var d=Ba(),f=F(d),p=e=>{var t=Ra(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),V(a),n(),H(()=>Q(V(a),n())))]),G(e,t)};q(f,e=>{V(a)&&e(p)});var m=L(f,2),h=e=>{var t=za(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),U(o()),n(),H(()=>Q(o()===`checks`?`checksDiscoveryScope`:`projectsDiscoveryScope`,n())))]),G(e,t)};q(m,e=>{(s()===`observed`||s()===`empty`||s()===`no-recent-runs`||s()===`no-verifiable-checks`)&&e(h)});var g=L(m,2),_=e=>{var t=za(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`discoveryTruncated`,n())))]),G(e,t)};q(g,e=>{c()&&e(_)}),G(e,d),k(),i()}var Ha={en:{success:`Passed`,failure:`Failed`,cancelled:`Cancelled`,neutral:`Neutral`,skipped:`Skipped`,timed_out:`Timed out`,action_required:`Action required`,stale:`Stale`,startup_failure:`Failed to start`,unknown:`Unknown outcome`},es:{success:`Correcto`,failure:`Falló`,cancelled:`Cancelado`,neutral:`Neutral`,skipped:`Omitido`,timed_out:`Agotó el tiempo`,action_required:`Requiere intervención`,stale:`Obsoleto`,startup_failure:`Falló al iniciar`,unknown:`Resultado desconocido`},fr:{success:`Réussi`,failure:`Échoué`,cancelled:`Annulé`,neutral:`Neutre`,skipped:`Ignoré`,timed_out:`Délai dépassé`,action_required:`Action nécessaire`,stale:`Obsolète`,startup_failure:`Échec au démarrage`,unknown:`Résultat inconnu`},pt:{success:`Concluído`,failure:`Falhou`,cancelled:`Cancelado`,neutral:`Neutro`,skipped:`Ignorado`,timed_out:`Tempo esgotado`,action_required:`Ação necessária`,stale:`Obsoleto`,startup_failure:`Falha ao iniciar`,unknown:`Resultado desconhecido`}};function Ua(e,t){return Ha[t][e]??Ha[t].unknown}function Wa(e,t,n){let r=e.trim(),i=n.trim(),a=String(t??``).trim(),o=Number(a);if(!(!r||!i||r.length>100||i.length>100||/[|;\r\n]/u.test(r+i)||!/^[1-9]\d*$/u.test(a)||!Number.isSafeInteger(o)))return`${r}|${o}|${i}`}var Ga=W(` `),Ka=W(`
                            `),qa=W(`
                          • `),Ja=W(`
                              `),Ya=W(``),Xa=W(`

                              `,1);function Za(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=Z(t,`candidates`,8),c=Z(t,`selected`,12),l=Z(t,`controller`,8),u=M(``),d=M(``),f=M(``),p=M(!1);function m(){let e=Wa(V(u),V(d),V(f));if(!e||c().length>=8){N(p,!0);return}N(p,!1),c().includes(e)||c([...c(),e]),N(u,``),N(d,``),N(f,``)}Tn(()=>U(s()),()=>{N(a,new Set(s().map(e=>`${e.name}|${e.sourceAppId}|${e.workflowName}`)))}),Tn(()=>(U(c()),V(a)),()=>{N(o,c().filter(e=>!V(a).has(e)))}),En(),Y();var h=Xa(),g=F(h);Qr(g,5,s,Jr,(e,t)=>{let r=A(()=>(V(t),H(()=>`${V(t).name}|${V(t).sourceAppId}|${V(t).workflowName}`)));var i=Ka(),a=P(i),o=P(a);xi(o);var s=L(o,2),u=P(s),d=I(P(u),!0);E(u);var f=L(u),p=I(P(f));E(f);var m=I(L(f),!0);E(s),E(a);var h=L(a,2),g=e=>{var r=Ga(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(wa),V(t),H(()=>wa(V(t).runUrl))),()=>(U(Q),n(),H(()=>Q(`ciRun`,n())))]),G(e,r)},_=gt(()=>(U(wa),V(t),H(()=>wa(V(t).runUrl))));q(h,e=>{V(_)&&e(g)});var v=L(h,2),y=e=>{var r=Ga(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(Ta),V(t),H(()=>Ta(V(t).requiredByRuleset?.sourceUrl))),()=>(U(Q),n(),H(()=>Q(`ciRule`,n())))]),G(e,r)},b=gt(()=>(U(Ta),V(t),H(()=>Ta(V(t).requiredByRuleset?.sourceUrl))));q(v,e=>{V(b)&&e(y)}),E(i),R((e,n,r,i,a,s)=>{Si(o,e),o.disabled=n,K(d,(V(t),H(()=>V(t).name))),K(p,`${V(t),H(()=>V(t).workflowName)??``} · ${V(t),H(()=>V(t).sourceAppName??`GitHub App`)??``} ${V(t),H(()=>V(t).sourceAppId)??``} · ${r??``} · ${i??``} · ${a??``}`),K(m,s)},[()=>(U(c()),U(V(r)),H(()=>c().includes(V(r)))),()=>(U(l()),U(c()),U(V(r)),H(()=>!l()||c().length>=8&&!c().includes(V(r)))),()=>(U(Ua),V(t),n(),H(()=>Ua(V(t).conclusion,n()))),()=>(V(t),H(()=>V(t).headSha.slice(0,7))),()=>(V(t),U(Q),n(),H(()=>V(t).observedAt??Q(`observationTimeUnknown`,n()))),()=>(V(t),U(Q),n(),H(()=>V(t).requiredByRuleset?Q(`branchRequirementObserved`,n(),{branch:V(t).requiredByRuleset.branch}):Q(`branchRequirementUnknown`,n())))]),Sr(`change`,o,()=>c(Pa(c(),V(r)))),G(e,i)}),E(g);var _=L(g,2),v=e=>{var t=Ja();Qr(t,5,()=>V(o),Jr,(e,t)=>{var r=qa(),i=P(r),a=I(i,!0),o=L(i,2),s=I(o,!0);E(r),R(e=>{K(a,V(t)),o.disabled=!l(),K(s,e)},[()=>(U(Q),n(),H(()=>Q(`producerRemove`,n())))]),Sr(`click`,o,()=>c(Pa(c(),V(t)))),G(e,r)}),E(t),G(e,t)};q(_,e=>{V(o),H(()=>V(o).length)&&e(v)});var y=L(_,2),b=I(y,!0),x=L(y,2),S=P(x),C=P(S,!0),ee=L(C);xi(ee),E(S);var te=L(S,2),ne=P(te,!0),re=L(ne);xi(re),E(te);var ie=L(te,2),ae=P(ie,!0),oe=L(ae);xi(oe),E(ie),E(x);var se=L(x,2),ce=I(se,!0),le=L(se,2),ue=e=>{var t=Ya(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`producerManualInvalid`,n())))]),G(e,t)};q(le,e=>{V(p)&&e(ue)}),R((e,t,n,r,i,a)=>{J(g,`aria-label`,e),K(b,t),K(C,n),ee.disabled=!l(),K(ne,r),re.disabled=!l(),K(ae,i),oe.disabled=!l(),se.disabled=!l(),K(ce,a)},[()=>(U(Q),n(),H(()=>Q(`checksObserved`,n()))),()=>(U(Q),n(),H(()=>Q(`producerManualHelp`,n()))),()=>(U(Q),n(),H(()=>Q(`producerName`,n()))),()=>(U(Q),n(),H(()=>Q(`producerAppId`,n()))),()=>(U(Q),n(),H(()=>Q(`producerWorkflow`,n()))),()=>(U(Q),n(),H(()=>Q(`producerAdd`,n())))]),Ei(ee,()=>V(u),e=>N(u,e)),Ei(re,()=>V(d),e=>N(d,e)),Ei(oe,()=>V(f),e=>N(f,e)),Sr(`click`,se,m),G(e,h),k(),i()}Cr([`change`,`click`]);var Qa=W(` `),$a=W(`
                              `),eo=W(`
                            • `),to=W(`

                                `,1),no=W(`
                                `,1);function ro(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=Z(t,`candidates`,8),c=Z(t,`selected`,12),l=Z(t,`value`,12),u=Z(t,`controller`,8);Tn(()=>U(s()),()=>{N(a,new Set(s().map(e=>String(e.number))))}),Tn(()=>(U(c()),V(a)),()=>{N(o,c().filter(e=>!V(a).has(e)))}),En(),Y();var d=no(),f=F(d);Qr(f,5,s,Jr,(e,t)=>{var r=$a(),i=P(r),a=P(i);xi(a);var o=L(a,2),s=P(o),l=I(P(s),!0);E(s);var d=L(s),f=I(P(d));E(d),E(o),E(i);var p=L(i,2),m=e=>{var r=Qa(),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(Ea),V(t),H(()=>Ea(V(t).url))),()=>(U(Q),n(),H(()=>Q(`projectUrl`,n())))]),G(e,r)},h=gt(()=>(U(Ea),V(t),H(()=>Ea(V(t).url))));q(p,e=>{V(h)&&e(m)}),E(r),R((e,n)=>{Si(a,e),a.disabled=n,K(l,(V(t),H(()=>V(t).title))),K(f,`${V(t),H(()=>V(t).owner)??``} · #${V(t),H(()=>V(t).number)??``}`)},[()=>(U(c()),V(t),H(()=>c().includes(String(V(t).number)))),()=>(U(u()),U(c()),V(t),H(()=>!u()||c().length>=10&&!c().includes(String(V(t).number))))]),Sr(`change`,a,()=>c(Pa(c(),String(V(t).number)))),G(e,r)}),E(f);var p=L(f,2),m=e=>{var t=to(),r=F(t),i=I(r,!0),a=L(r,2);Qr(a,5,()=>V(o),Jr,(e,t)=>{var r=eo(),i=P(r),a=I(i),o=L(i,2),s=I(o,!0);E(r),R(e=>{K(a,`#${V(t)??``}`),o.disabled=!u(),K(s,e)},[()=>(U(Q),n(),H(()=>Q(`removeSelection`,n())))]),Sr(`click`,o,()=>c(Pa(c(),V(t)))),G(e,r)}),E(a),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`projectSelectionNotObserved`,n())))]),G(e,t)};q(p,e=>{V(o),H(()=>V(o).length)&&e(m)});var h=L(p,2),g=I(h,!0),_=L(h,2);xi(_),R((e,t)=>{J(f,`aria-label`,e),K(g,t),_.disabled=!u()},[()=>(U(Q),n(),H(()=>Q(`projectsObserved`,n()))),()=>(U(Q),n(),H(()=>Q(`projectManual`,n())))]),Ei(_,l),G(e,d),k(),i()}Cr([`change`,`click`]);var io=W(``),ao=W(`
                                `),oo=W(` `,1);function so(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`explanation`,8),o=Z(t,`helpUrl`,8);Y();var s=oo(),c=F(s),l=e=>{var t=io(),r=P(t),i=I(r);E(t),R(e=>{J(r,`href`,o()),K(i,`${e??``} ↗`)},[()=>(U(Q),n(),H(()=>Q(`learnMore`,n())))]),G(e,t)};q(c,e=>{o()&&e(l)});var u=L(c,2),d=e=>{var t=ao(),r=P(t),i=I(r,!0),o=L(r),s=P(o),c=I(s,!0),l=L(s),u=I(l,!0),d=L(l,2),f=I(d,!0),p=L(d),m=I(p,!0),h=L(p,2),g=I(h,!0),_=L(h),v=I(_,!0),y=L(_,2),b=I(y,!0),x=L(y),S=I(x,!0),C=L(x,2),ee=I(C,!0),te=L(C),ne=I(te,!0),re=L(te,2),ie=I(re,!0),ae=L(re),oe=I(ae,!0),se=L(ae,2),ce=I(se,!0),le=I(L(se),!0);E(o),E(t),R((e,t,n,r,o,s,l,d)=>{K(i,e),K(c,t),K(u,(U(a()),H(()=>a().when))),K(f,n),K(m,(U(a()),H(()=>a().where))),K(g,r),K(v,(U(a()),H(()=>a().how))),K(b,o),K(S,(U(a()),H(()=>a().why))),K(ee,s),K(ne,(U(a()),H(()=>a().example))),K(ie,l),K(oe,(U(a()),H(()=>a().effect))),K(ce,d),K(le,(U(a()),H(()=>a().verify)))},[()=>(U(Q),n(),H(()=>Q(`whyMatters`,n()))),()=>(U(Q),n(),H(()=>Q(`whenApplies`,n()))),()=>(U(Q),n(),H(()=>Q(`whereConfigured`,n()))),()=>(U(Q),n(),H(()=>Q(`howToChoose`,n()))),()=>(U(Q),n(),H(()=>Q(`whyRecommendation`,n()))),()=>(U(Q),n(),H(()=>Q(`example`,n()))),()=>(U(Q),n(),H(()=>Q(`effect`,n()))),()=>(U(Q),n(),H(()=>Q(`verify`,n())))]),G(e,t)};q(u,e=>{a()&&e(d)}),G(e,s),k(),i()}var co=W(`· `,1),lo=W(`

                                `,1);function uo(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`candidate`,8);Y();var o=lo(),s=F(o),c=P(s),l=I(c),u=L(c,2),d=e=>{var t=co(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(wa),U(a()),H(()=>wa(a().runUrl))),()=>(U(Q),n(),H(()=>Q(`ciRun`,n())))]),G(e,t)},f=gt(()=>(U(wa),U(a()),H(()=>wa(a().runUrl))));q(u,e=>{V(f)&&e(d)}),E(s);var p=L(s,2),m=P(p),h=I(m),g=L(m),_=L(g),v=e=>{var t=co(),r=L(F(t)),i=I(r,!0);R((e,t)=>{J(r,`href`,e),K(i,t)},[()=>(U(Ta),U(a()),H(()=>Ta(a().requiredByRuleset?.sourceUrl))),()=>(U(Q),n(),H(()=>Q(`ciRule`,n())))]),G(e,t)},y=gt(()=>(U(Ta),U(a()),H(()=>Ta(a().requiredByRuleset?.sourceUrl))));q(_,e=>{V(y)&&e(v)}),E(p),R((e,t,n,r)=>{K(l,`${U(a()),H(()=>a().workflowName)??``} · GitHub App ${U(a()),H(()=>a().sourceAppId)??``}`),K(h,`${e??``} · ${t??``} · ${n??``}`),K(g,` · ${r??``} `)},[()=>(U(Ua),U(a()),n(),H(()=>Ua(a().conclusion,n()))),()=>(U(a()),H(()=>a().headSha.slice(0,7))),()=>(U(a()),U(Q),n(),H(()=>a().observedAt??Q(`observationTimeUnknown`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().requiredByRuleset?Q(`branchRequirementObserved`,n(),{branch:a().requiredByRuleset.branch}):Q(`branchRequirementUnknown`,n())))]),G(e,o),k(),i()}var fo=W(`

                                `);function po(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`question`,8);Y();var o=Mr(),s=F(o),c=e=>{var t=fo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`fixedIssuesRequired`,n())))]),G(e,t)},l=e=>{var t=Mr();Qr(F(t),1,()=>(U(a()),H(()=>Object.entries(a().fixedWorkflowFeatures).filter(([,e])=>e!==void 0))),Jr,(e,t)=>{var r=gt(()=>b(V(t),2));let i=()=>V(r)[0],a=()=>V(r)[1];var o=fo(),s=I(o,!0);R(e=>K(s,e),[()=>(U(Q),a(),n(),i(),H(()=>Q(a()?`fixedWorkflowEnabled`:`fixedWorkflowDisabled`,n(),{kind:i()})))]),G(e,o)}),G(e,t)};q(s,e=>{U(a()),H(()=>a().id===`features.issues`&&(a().fixedWorkflowFeatures?.release||a().fixedWorkflowFeatures?.hotfix))?e(c):(U(a()),H(()=>a().fixedWorkflowFeatures)&&e(l,1))}),G(e,o),k(),i()}var mo=W(` `),ho=W(`

                                `),go=W(`

                                `),_o=W(` `,1),vo=W(`

                                `),yo=W(`
                                `),bo=W(`

                                `),xo=W(``),So=W(`
                              • `),Co=W(`
                                  `),wo=W(`
                                  `),To=W(``),Eo=W(``),Do=W(` `,1),Oo=W(``),ko=W(`
                                  `),Ao=W(``),jo=W(``),Mo=W(`

                                  `,1);function No(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=M(),c=Z(t,`prompt`,8),l=Z(t,`controller`,8),u=Z(t,`busy`,8),d=Z(t,`onSubmit`,8),f=Z(t,`onRetryDiscovery`,8),p=Z(t,`onBack`,8),m=Na(c()),h=M(m.value),g=M(m.selected);Tn(()=>(U(c()),n()),()=>{N(a,c().presentation?.[n()])}),Tn(()=>V(a),()=>{N(o,La(V(a)?.documentation?.url))}),Tn(()=>(U(c()),n(),ma),()=>{N(s,typeof c().question.defaultValue==`boolean`?Q(c().question.defaultValue?`yes`:`no`,n()):c().question.defaultValue===``?Q(`none`,n()):c().question.kind===`choice`||c().question.kind===`multi-select`?ma(c().question.id,String(c().question.defaultValue),n()):String(c().question.defaultValue))}),En(),Y();var _=Mo(),v=F(_),y=P(v),b=I(y,!0),x=L(y),S=e=>{var t=mo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`permissionPreview`,n())))]),G(e,t)};q(x,e=>{U(c()),H(()=>c().phase===`permission-intent`)&&e(S)}),E(v);var C=L(v,2),ee=e=>{var t=ho(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),U(c()),H(()=>Q(`questionProgress`,n(),{current:String(c().progress.groupPosition),total:String(c().progress.groupTotal),overall:String(c().progress.position),all:String(c().progress.total)})))]),G(e,t)};q(C,e=>{U(c()),H(()=>c().progress)&&e(ee)});var te=L(C,2),ne=e=>{var t=go(),n=I(t,!0);R(()=>K(n,(V(a),H(()=>V(a).summary)))),G(e,t)};q(te,e=>{V(a)&&e(ne)});var re=L(te,2),ie=e=>{Va(e,{kind:`checks`,get status(){return U(c()),H(()=>c().question.discoveryStatus)},get truncated(){return U(c()),H(()=>c().question.discoveryTruncated)}})};q(re,e=>{U(c()),H(()=>c().question.id===`pullRequestApproval.testChecks`)&&e(ie)});var ae=L(re,2),oe=e=>{Va(e,{kind:`projects`,get status(){return U(c()),H(()=>c().question.discoveryStatus)},get truncated(){return U(c()),H(()=>c().question.discoveryTruncated)}})};q(ae,e=>{U(c()),H(()=>c().question.id===`projects.ids`)&&e(oe)});var se=L(ae,2),ce=e=>{var t=yo(),r=P(t),i=e=>{var t=_o(),r=F(t),i=I(r,!0),a=I(L(r,2),!0);R((e,t)=>{r.disabled=!l()||u(),K(i,e),K(a,t)},[()=>(U(Q),n(),H(()=>Q(`retryDiscovery`,n()))),()=>(U(Q),n(),U(c()),H(()=>Q(`retryRemaining`,n(),{count:String(c().question.discoveryRetryRemaining)})))]),Sr(`click`,r,function(...e){f()?.apply(this,e)}),G(e,t)},a=e=>{var t=vo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`retryExhausted`,n())))]),G(e,t)};q(r,e=>{U(c()),H(()=>c().question.discoveryRetryRemaining>0)?e(i):e(a,-1)}),E(t),G(e,t)};q(se,e=>{U(c()),H(()=>c().question.discoveryRetryRemaining!==void 0)&&e(ce)});var le=L(se,2),ue=e=>{var t=bo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`projectStatusUnavailable`,n())))]),G(e,t)};q(le,e=>{U(c()),H(()=>c().question.statusOptionState===`unavailable`)&&e(ue)});var de=L(le,2),fe=e=>{var t=xo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`projectStatusIncompatible`,n())))]),G(e,t)};q(de,e=>{U(c()),H(()=>c().question.statusOptionState===`incompatible`)&&e(fe)});var pe=L(de,2),me=e=>{var t=vo(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`projectSharedStatus`,n())))]),G(e,t)};q(pe,e=>{U(c()),H(()=>c().question.id===`projects.ids`)&&e(me)});var he=L(pe,2);po(he,{get question(){return U(c()),H(()=>c().question)}});var ge=L(he,2),_e=e=>{var t=Co();Qr(t,5,()=>(U(c()),H(()=>c().question.projectStatusValues)),Jr,(e,t)=>{var r=So(),i=P(r),a=L(i),o=I(P(a),!0);E(a),E(r),R(e=>{K(i,`${e??``}: `),K(o,(V(t),H(()=>V(t).value)))},[()=>(U(Q),U(Ia),V(t),n(),H(()=>Q(Ia[V(t).transition],n())))]),G(e,r)}),E(t),G(e,t)};q(ge,e=>{U(c()),H(()=>c().question.projectStatusValues)&&e(_e)});var ve=L(ge,2),ye=e=>{var t=wo(),r=P(t);let i;var o=I(r,!0),s=L(r);let u;var d=I(s,!0);E(t),R((e,n)=>{J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),J(r,`aria-pressed`,V(h)===`yes`||V(h)===`true`),r.disabled=!l(),i=ui(r,1,``,null,i,{selected:V(h)===`yes`||V(h)===`true`}),K(o,e),J(s,`aria-pressed`,V(h)===`no`||V(h)===`false`),s.disabled=!l(),u=ui(s,1,``,null,u,{selected:V(h)===`no`||V(h)===`false`}),K(d,n)},[()=>(U(Q),n(),H(()=>Q(`yes`,n()))),()=>(U(Q),n(),H(()=>Q(`no`,n())))]),Sr(`click`,r,()=>N(h,`yes`)),Sr(`click`,s,()=>N(h,`no`)),G(e,t)},be=e=>{var t=Do(),r=F(t),i=P(r),o=e=>{var t=To(),r=I(t,!0);t.value=t.__value=``,R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`selectOne`,n())))]),G(e,t)};q(i,e=>{U(c()),H(()=>!c().question.defaultValue)&&e(o)}),Qr(L(i),1,()=>(U(c()),H(()=>c().question.choices??[])),Jr,(e,t)=>{let r=A(()=>(U(c()),V(t),H(()=>c().question.id===`pullRequestApproval.coverage.checkName`?c().question.trustedProducers?.find(e=>e.name===V(t)):void 0)));var i=Eo(),a=I(i,!0),o={};R(e=>{K(a,e),o!==(o=V(t))&&(i.value=(i.__value=o)??``)},[()=>(U(V(r)),V(t),U(ma),U(c()),n(),H(()=>V(r)?`${V(t)} — ${V(r).workflowName} · App ${V(r).sourceAppId}`:ma(c().question.id,V(t),n())))]),G(e,i)}),E(r),mi(r);var s=L(r,2),u=e=>{var t=Mr();Qr(F(t),1,()=>(U(c()),V(h),H(()=>(c().question.producerCandidates??[]).filter(e=>e.name===V(h)))),Jr,(e,t)=>{uo(e,{get candidate(){return V(t)}})}),G(e,t)};q(s,e=>{U(c()),H(()=>c().question.id===`pullRequestApproval.coverage.checkName`)&&e(u)}),R(()=>{J(r,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),r.disabled=!l()}),hi(r,()=>V(h),e=>N(h,e)),G(e,t)},xe=e=>{{let t=A(()=>(U(c()),H(()=>c().question.producerCandidates??[])));Za(e,{get candidates(){return V(t)},get controller(){return l()},get selected(){return V(g)},set selected(e){N(g,e)},$$legacy:!0})}},Se=e=>{{let t=A(()=>(U(c()),H(()=>c().question.projectCandidates??[])));ro(e,{get candidates(){return V(t)},get controller(){return l()},get selected(){return V(g)},set selected(e){N(g,e)},get value(){return V(h)},set value(e){N(h,e)},$$legacy:!0})}},Ce=e=>{var t=ko();Qr(t,5,()=>(U(c()),H(()=>c().question.kind===`multi-select`?c().question.choices??[]:c().question.allowedNames??[])),Jr,(e,t)=>{var r=Oo(),i=P(r);xi(i);var a=I(L(i),!0);E(r),R((e,t)=>{Si(i,e),i.disabled=!l(),K(a,t)},[()=>(V(g),V(t),H(()=>V(g).includes(V(t)))),()=>(U(c()),U(ma),V(t),n(),H(()=>c().question.kind===`multi-select`?ma(c().question.id,V(t),n()):V(t)))]),Sr(`change`,i,()=>N(g,Pa(V(g),V(t)))),G(e,r)}),E(t),R(()=>J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label)))),G(e,t)},we=e=>{var t=Mr(),n=F(t),r=e=>{var t=Ao();it(t),R(()=>{J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),t.disabled=!l()}),Ei(t,()=>V(h),e=>N(h,e)),G(e,t)},i=e=>{var t=jo();xi(t),R(()=>{J(t,`aria-label`,(V(a),U(c()),H(()=>V(a)?.label??c().question.label))),J(t,`type`,(U(c()),H(()=>c().question.kind===`number`?`number`:`text`))),J(t,`min`,(U(c()),H(()=>c().question.kind===`number`?0:void 0))),t.disabled=!l()}),Ei(t,()=>V(h),e=>N(h,e)),G(e,t)};q(n,e=>{U(c()),H(()=>c().question.id===`ai.bugbotOrganizationRules`)?e(r):e(i,-1)}),G(e,t)};q(ve,e=>{U(c()),H(()=>c().question.kind===`boolean`)?e(ye):(U(c()),H(()=>c().question.kind===`choice`)?e(be,1):(U(c()),H(()=>c().question.kind===`producer-select`)?e(xe,2):(U(c()),H(()=>c().question.kind===`project-select`)?e(Se,3):(U(c()),H(()=>c().question.kind===`multi-select`||c().question.kind===`scope-overrides`)?e(Ce,4):e(we,-1)))))});var Te=L(ve,2),w=I(Te,!0),Ee=L(Te,2),T=e=>{var t=ho(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),U(c()),n(),H(()=>Q(c().question.suggestionSource===`github`?`sourceGithub`:c().question.suggestionSource===`local`?`sourceLocal`:c().question.suggestionSource===`configuration`?`sourceConfig`:`sourceDefault`,n())))]),G(e,t)};q(Ee,e=>{U(c()),H(()=>c().question.suggestionSource)&&e(T)});var De=L(Ee,2);so(De,{get explanation(){return V(a)},get helpUrl(){return V(o)}});var Oe=L(De,2),ke=P(Oe),Ae=e=>{{let t=A(()=>(U(Q),n(),H(()=>Q(`previousQuestion`,n())))),r=A(()=>!l()||u());ka(e,{get label(){return V(t)},variant:`secondary`,get onClick(){return p()},get disabled(){return V(r)}})}};q(ke,e=>{U(c()),H(()=>c().canGoBack)&&e(Ae)});var je=L(ke,2);{let e=A(()=>(U(Q),n(),H(()=>Q(`continue`,n())))),t=A(()=>!l()||u());ka(je,{get label(){return V(e)},arrow:!0,onClick:()=>d()(Fa(c(),V(h),V(g))),get disabled(){return V(t)}})}E(Oe),R((e,t)=>{K(b,e),K(w,t)},[()=>(V(a),U(c()),H(()=>V(a)?.label??c().question.label.replace(` (Space toggles, Enter confirms)`,``))),()=>(U(Q),n(),V(s),H(()=>Q(`suggested`,n(),{answer:V(s)})))]),G(e,_),k(),i()}Cr([`click`,`change`]);var Po=W(``),Fo=W(`
                                  `);function Io(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`prompt`,8),o=Z(t,`controller`,8),s=Z(t,`busy`,8),c=Z(t,`onSubmit`,8);Y();var l=Fo();Qr(l,5,()=>(U(a()),H(()=>a().choices)),Jr,(e,t,r)=>{var i=Po(),l=I(P(i),!0);ke(),E(i),R(e=>{i.disabled=!o()||s(),K(l,e)},[()=>(U(ba),U(a()),n(),H(()=>ba(a(),n(),r)))]),Sr(`click`,i,()=>c()(V(t))),G(e,i)}),E(l),G(e,l),k(),i()}Cr([`click`]);var Lo=W(`

                                  `,1),Ro=W(`

                                  `),zo=W(` `,1);function Bo(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`prompt`,8),s=Z(t,`controller`,8),c=Z(t,`busy`,8),l=Z(t,`onSubmit`,8),u=M(``);function d(){let e=V(u);o().kind===`secret`&&N(u,``),l()(e)}Tn(()=>U(o()),()=>{N(a,Ca(o().link))}),En(),Y();var f=zo(),p=F(f),m=e=>{var t=Lo(),r=F(t),i=P(r);ke(),E(r);var o=I(L(r),!0);R((e,t)=>{J(r,`href`,V(a)),K(i,`${e??``} `),K(o,t)},[()=>(U(Q),n(),H(()=>Q(`githubForm`,n()))),()=>(U(Q),n(),H(()=>Q(`githubFormHelp`,n())))]),G(e,t)};q(p,e=>{V(a)&&e(m)});var h=L(p,2),g=I(h,!0),_=L(h,2);xi(_);var v=L(_,2),y=e=>{var t=Ro(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`secretHelp`,n())))]),G(e,t)};q(v,e=>{U(o()),H(()=>o().kind===`secret`)&&e(y)});var b=L(v,2);{let e=A(()=>(U(Q),n(),H(()=>Q(`continue`,n())))),t=A(()=>(U(s()),U(c()),U(o()),V(u),H(()=>!s()||c()||!o().optional&&!V(u).trim())));ka(b,{get label(){return V(e)},arrow:!0,onClick:d,get disabled(){return V(t)}})}R((e,t)=>{K(g,e),J(_,`type`,(U(o()),H(()=>o().kind===`secret`?`password`:`text`))),_.disabled=!s(),J(_,`placeholder`,t)},[()=>(U(Q),U(o()),n(),H(()=>Q(o().kind===`secret`?`pasteHere`:`yourAnswer`,n()))),()=>(U(Q),U(o()),n(),H(()=>Q(o().kind===`secret`?`hiddenAfter`:`typeAnswer`,n())))]),Ei(_,()=>V(u),e=>N(u,e)),G(e,f),k(),i()}var Vo={"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Help / question issues remain branchless even when issue-managed-branches is enabled.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`Release automation is installed, but release issue events are disabled by the selected issue workflow profile.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Release and hotfix workflows require the workflow PAT Secret and a writable token.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.`},Ho={en:Vo,es:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`No has activado ningún tipo de flujo de incidencias. Sus eventos no se gestionarán hasta que actives un formulario de incidencia y su entrada en el perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Las incidencias de ayuda y consulta no crean ramas, aunque actives las ramas gestionadas por incidencias.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`La automatización de versiones ya está instalada, pero el perfil elegido desactiva los eventos de incidencias de versiones.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`La automatización de correcciones urgentes ya está instalada, pero el perfil elegido desactiva los eventos de sus incidencias.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`Has desactivado la generación de instrucciones para agentes del repositorio. Los colaboradores no recibirán el perfil ni la guía del flujo de trabajo generados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Los flujos de versiones y correcciones urgentes requieren el Secret con el PAT de la Action y un token con permisos de escritura.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La cola de merge bloqueará la operación si cada productor obligatorio no se verifica automáticamente o no dispone de una certificación exacta revisada.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`El modo de provisión permanente solo reinstala los entornos predeterminados de Codex y OpenCode desde paquetes fijados en el manifiesto. No sustituye ejecutables explícitos; Cursor debe estar instalado previamente.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`Está activado el cierre de incidencias inactivas. Las que estén en espera se cerrarán tras el plazo configurado y podrán reabrirse con un comentario.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`El PAT del bot debe tener acceso a los Projects seleccionados, y los cuatro valores de Status configurados deben existir en cada uno de ellos.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`Cursor es un entorno experimental en Copilot. Requiere una CLI compatible ya instalada y CURSOR_API_KEY; Copilot no instala Cursor automáticamente.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Los Secrets y Variables de organización requieren permisos en ella. Limitar el acceso a los repositorios elegidos es la opción más segura; los valores del repositorio tienen prioridad.`},fr:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Aucun type de flux de travail pour les tickets n’est activé. Leurs événements ne seront pas gérés tant qu’un formulaire de ticket pris en charge et son entrée de profil ne seront pas activés.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`Les tickets d’aide ou de question ne créent pas de branche, même lorsque les branches gérées par les tickets sont activées.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`L’automatisation des versions est déjà installée, mais le profil choisi désactive les événements des tickets de version.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`L’automatisation des correctifs urgents est déjà installée, mais le profil choisi désactive les événements des tickets correspondants.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`La génération des consignes pour les agents du dépôt est désactivée. Les collaborateurs ne recevront ni le profil ni le guide de flux de travail générés.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Les flux de version et de correctif urgent nécessitent le Secret contenant le PAT de l’Action et un jeton autorisé à écrire.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`La file de fusion bloque l’opération si chaque producteur requis n’est pas vérifié automatiquement ou couvert par une attestation exacte et examinée.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`Le mode de provisionnement permanent ne réinstalle que les environnements Codex et OpenCode par défaut depuis les paquets verrouillés du manifeste. Il ne remplace jamais les exécutables indiqués explicitement ; Cursor doit être préinstallé.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`La fermeture des tickets inactifs est activée. Les tickets en attente seront fermés après le délai configuré et pourront être rouverts par un nouveau commentaire.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`Le PAT du bot doit avoir accès aux Projects sélectionnés, et les quatre valeurs Status configurées doivent exister dans chacun de ces Projects.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`Cursor est un environnement expérimental dans Copilot. Il nécessite une CLI compatible déjà installée et CURSOR_API_KEY ; Copilot ne l’installe pas automatiquement.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Les Secrets et Variables d’organisation nécessitent des droits sur celle-ci. Limiter l’accès aux dépôts sélectionnés est le choix le plus sûr ; les valeurs du dépôt prévalent.`},pt:{"No issue workflow kind is enabled; issue events will remain unmanaged until a supported Issue Form and profile entry are enabled.":`Não está ativo nenhum tipo de fluxo de trabalho para issues. Os respetivos eventos não serão geridos até ativar um formulário de issue suportado e a entrada correspondente no perfil.`,"Help / question issues remain branchless even when issue-managed-branches is enabled.":`As issues de ajuda ou perguntas não criam ramos, mesmo com os ramos geridos por issues ativados.`,"Release automation is installed, but release issue events are disabled by the selected issue workflow profile.":`A automação de versões já está instalada, mas o perfil escolhido desativa os eventos das issues de versão.`,"Hotfix automation is installed, but hotfix issue events are disabled by the selected issue workflow profile.":`A automação de correções urgentes já está instalada, mas o perfil escolhido desativa os eventos das respetivas issues.`,"Repository agent guidance generation is disabled; collaborators will not receive the generated profile or workflow skill.":`A criação de orientações para agentes do repositório está desativada. Os colaboradores não receberão o perfil nem o guia do fluxo de trabalho gerados.`,"Release and hotfix workflows require the workflow PAT Secret and a writable token.":`Os fluxos de versão e correção urgente exigem o Secret com o PAT da Action e um token com permissão de escrita.`,"Merge queue mode fails closed unless every required producer is verified automatically or covered by an exact reviewed attestation.":`A fila de integração bloqueia a operação se cada produtor obrigatório não for verificado automaticamente ou coberto por uma declaração exata e revista.`,"Always-provision mode reinstalls only default Codex/OpenCode runtimes from pinned manifest packages; explicit executables are never replaced and Cursor must be preinstalled.":`O modo de aprovisionamento permanente reinstala apenas os ambientes padrão de Codex e OpenCode a partir de pacotes fixados no manifesto. Nunca substitui executáveis indicados explicitamente; o Cursor tem de estar pré-instalado.`,"Inactive issue closure is enabled; waiting issues are closed after the configured inactivity threshold and can be reopened with a new comment.":`O fecho de issues inativas está ativado. As que aguardam resposta serão fechadas após o prazo configurado e poderão ser reabertas com um novo comentário.`,"Selected Project numbers must be accessible to the bot PAT, and all four configured Status values must exist in every selected Project.":`O PAT do bot tem de ter acesso aos Projects selecionados, e os quatro valores de Status configurados têm de existir em cada Project.`,"Cursor is an experimental runtime in Copilot and requires a compatible preinstalled CLI plus CURSOR_API_KEY; Copilot has no automatic Cursor installer.":`O Cursor é um ambiente experimental no Copilot. Exige uma CLI compatível já instalada e CURSOR_API_KEY; o Copilot não instala o Cursor automaticamente.`,"Organization-level Secrets and Variables require organization permissions; selected access is the safest default and repository values take precedence.":`Os Secrets e Variables da organização exigem permissões nessa organização. Restringir o acesso aos repositórios selecionados é a opção mais segura; os valores do repositório prevalecem.`}};function Uo(e,t){let n=Ho[t]??Vo;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:t===`en`?e:Q(`planUnknownWarning`,t)}var Wo={en:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Issue comments`,pullRequestComments:`Pull-request comments`,release:`Releases`,hotfix:`Hotfixes`,agentProvisioning:`Agent provisioning`,credentialHealth:`Credential health`,inactiveIssueClosure:`Inactive issue closure`,issueTemplates:`Issue templates`,pullRequestTemplate:`Pull-request template`},es:{issues:`Issues`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentarios en issues`,pullRequestComments:`Comentarios en pull requests`,release:`Releases`,hotfix:`Correcciones urgentes`,agentProvisioning:`Instalación de agentes`,credentialHealth:`Estado de credenciales`,inactiveIssueClosure:`Cierre de issues inactivos`,issueTemplates:`Plantillas de issues`,pullRequestTemplate:`Plantilla de pull requests`},fr:{issues:`Tickets`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Commentaires des tickets`,pullRequestComments:`Commentaires des pull requests`,release:`Versions`,hotfix:`Correctifs urgents`,agentProvisioning:`Installation des agents`,credentialHealth:`État des identifiants`,inactiveIssueClosure:`Fermeture des tickets inactifs`,issueTemplates:`Modèles de tickets`,pullRequestTemplate:`Modèle de pull request`},pt:{issues:`Questões`,pullRequests:`Pull requests`,commits:`Commits`,issueComments:`Comentários nas questões`,pullRequestComments:`Comentários nas pull requests`,release:`Versões`,hotfix:`Correções urgentes`,agentProvisioning:`Instalação de agentes`,credentialHealth:`Estado das credenciais`,inactiveIssueClosure:`Fecho de questões inativas`,issueTemplates:`Modelos de questões`,pullRequestTemplate:`Modelo de pull request`}};function Go(e,t){return Wo[t][e]??e}var Ko={en:{planner:`Planner`,findings:`Findings analyst`,reviewer:`Reviewer`,fixer:`Fixer`,tester:`Tester`},es:{planner:`Planificador`,findings:`Analista de hallazgos`,reviewer:`Revisor`,fixer:`Corrector`,tester:`Probador`},fr:{planner:`Planificateur`,findings:`Analyste des problèmes`,reviewer:`Réviseur`,fixer:`Correcteur`,tester:`Testeur`},pt:{planner:`Planeador`,findings:`Analista de problemas`,reviewer:`Revisor`,fixer:`Corretor`,tester:`Testador`}};function qo(e,t){return Ko[t][e]??e}var Jo=W(`
                                • `),Yo=W(`
                                • `),Xo=W(`
                                    `),Zo=W(`· `,1),Qo=W(`
                                    `,1),$o=W(`
                                    `,1),es=W(`
                                      `),ts=W(`

                                        /

                                        `);function ns(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`decisions`,8);function o(e){return Q(e===`repository`?`scopeRepository`:e===`organization`?`scopeOrganization`:`scopeDisabled`,n())}function s(e){return Q(e===`guarded`?`approvalGuarded`:e===`recommend`?`approvalRecommend`:`approvalOff`,n())}Y();var c=ts(),l=P(c),u=I(l,!0),d=L(l,2),f=P(d),p=P(f),m=I(p,!0),h=I(L(p),!0);E(f);var g=L(f,2),_=P(g),v=I(_,!0),y=I(L(_),!0);E(g);var b=L(g,2),x=P(b),S=I(x,!0),C=L(x),ee=P(C);Qr(ee,5,()=>(U(a()),H(()=>a().agentRouting)),Jr,(e,t)=>{var r=Jo(),i=P(r),a=I(L(i));E(r),R(e=>{K(i,`${e??``}: `),K(a,`${V(t),H(()=>V(t).provider)??``} · ${V(t),H(()=>V(t).modelProvider)??``}/${V(t),H(()=>V(t).model)??``}`)},[()=>(U(qo),V(t),n(),H(()=>qo(V(t).role,n())))]),G(e,r)}),E(ee),E(C),E(b);var te=L(b,2),ne=P(te),re=I(ne,!0),ie=L(ne),ae=P(ie),oe=I(ae,!0),se=I(L(ae,2),!0);E(ie),E(te);var ce=L(te,2),le=P(ce),ue=I(le,!0),de=I(L(le),!0);E(ce);var fe=L(ce,2),pe=e=>{var t=$o(),r=F(t),i=P(r),o=I(i,!0),s=L(i),c=P(s),l=e=>{var t=Xo();Qr(t,5,()=>(U(a()),H(()=>a().trustedChecks)),Jr,(e,t)=>{var r=Yo(),i=P(r),a=I(i,!0),o=L(i),s=I(L(o),!0);E(r),R(e=>{K(a,(V(t),H(()=>V(t).name))),K(o,` · ${e??``} ${V(t),H(()=>V(t).sourceAppId)??``} · `),K(s,(V(t),H(()=>V(t).workflowName)))},[()=>(U(Q),n(),H(()=>Q(`producerAppId`,n())))]),G(e,r)}),E(t),G(e,t)},u=e=>{var t=jr();R(e=>K(t,e),[()=>(U(Q),n(),H(()=>Q(`none`,n())))]),G(e,t)};q(c,e=>{U(a()),H(()=>a().trustedChecks.length)?e(l):e(u,-1)}),E(s),E(r);var d=L(r,2),f=P(d),p=I(f,!0),m=I(L(f),!0);E(d);var h=L(d,2),g=P(h),_=I(g,!0),v=L(g),y=P(v,!0),b=L(y),x=e=>{var t=Zo(),n=I(L(F(t)),!0);R(()=>K(n,(U(a()),H(()=>a().coverageCheck)))),G(e,t)};q(b,e=>{U(a()),H(()=>a().coverageCheck)&&e(x)}),E(v),E(h);var S=L(h,2),C=e=>{var t=Qo(),r=F(t),i=P(r),o=I(i,!0),s=I(L(i),!0);E(r);var c=L(r,2),l=P(c),u=I(l,!0),d=L(l),f=I(P(d),!0);E(d),E(c);var p=L(c,2),m=P(p),h=I(m,!0),g=I(L(m),!0);E(p),R((e,t,n,r,i,a)=>{K(o,e),K(s,t),K(u,n),K(f,r),K(h,i),K(g,a)},[()=>(U(Q),n(),H(()=>Q(`planCoverageThreshold`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().coverageMinimum===void 0?Q(`none`,n()):`${a().coverageMinimum}%`)),()=>(U(Q),n(),H(()=>Q(`planCoverageReporter`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().coverageArtifactWorkflow||Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planReporterAttested`,n()))),()=>(U(Q),U(a()),n(),H(()=>Q(a().coverageReporterAttested?`yes`:`no`,n())))]),G(e,t)};q(S,e=>{U(a()),H(()=>a().coverageMode===`numeric`)&&e(C)}),R((e,t,n,r,i)=>{K(o,e),K(p,t),K(m,n),K(_,r),K(y,i)},[()=>(U(Q),n(),H(()=>Q(`planTrustedChecks`,n()))),()=>(U(Q),n(),H(()=>Q(`planProducerAttested`,n()))),()=>(U(Q),U(a()),n(),H(()=>Q(a().producerAttested?`yes`:`no`,n()))),()=>(U(Q),n(),H(()=>Q(`planCoverage`,n()))),()=>(U(ma),U(a()),n(),H(()=>ma(`pullRequestApproval.coverage.mode`,a().coverageMode,n())))]),G(e,t)};q(fe,e=>{U(a()),H(()=>a().approvalMode!==`off`)&&e(pe)});var me=L(fe,2),he=P(me),ge=I(he,!0),_e=I(L(he),!0);E(me);var ve=L(me,2),ye=e=>{var t=es(),r=P(t),i=I(r,!0),o=L(r),s=P(o);Qr(s,5,()=>(U(a()),H(()=>a().projectStatuses)),Jr,(e,t)=>{var r=Jo(),i=P(r),a=I(L(i),!0);E(r),R(e=>{K(i,`${e??``}: `),K(a,(V(t),H(()=>V(t).value)))},[()=>(U(Q),U(Ia),V(t),n(),H(()=>Q(Ia[V(t).transition],n())))]),G(e,r)}),E(s),E(o),E(t),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`planProjectStatuses`,n())))]),G(e,t)};q(ve,e=>{U(a()),H(()=>a().projectNumbers.length)&&e(ye)});var be=L(ve,2),xe=P(be),Se=I(xe,!0),Ce=I(L(xe),!0);E(be);var we=L(be,2),Te=P(we),w=I(Te,!0),Ee=I(L(Te),!0);E(we);var T=L(we,2),De=P(T),Oe=I(De,!0),ke=I(L(De),!0);E(T);var Ae=L(T,2),je=P(Ae),Me=I(je,!0),Ne=I(L(je),!0);E(Ae),E(d);var Pe=I(L(d,2),!0);E(c),R((e,t,n,r,i,o,s,c,l,d,f,p,g,_,b,x,C,ee,te,ne)=>{K(u,e),K(m,t),K(h,n),K(v,r),K(y,i),K(S,o),K(re,s),K(oe,(U(a()),H(()=>a().productionBranch))),K(se,(U(a()),H(()=>a().developmentBranch))),K(ue,c),K(de,l),K(ge,d),K(_e,f),K(Se,p),K(Ce,g),K(w,_),K(Ee,b),K(Oe,x),K(ke,C),K(Me,ee),K(Ne,te),K(Pe,ne)},[()=>(U(Q),n(),H(()=>Q(`planChoices`,n()))),()=>(U(Q),n(),H(()=>Q(`planEnabledCapabilities`,n()))),()=>(U(a()),U(Go),n(),U(Q),H(()=>a().enabledCapabilities.length?a().enabledCapabilities.map(e=>Go(e,n())).join(`, `):Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planIssueWorkflows`,n()))),()=>(U(a()),U(ma),n(),U(Q),H(()=>a().issueWorkflows.length?a().issueWorkflows.map(e=>ma(`issueWorkflows.enabled`,e,n())).join(`, `):Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planAgentRouting`,n()))),()=>(U(Q),n(),H(()=>Q(`planBranchRoles`,n()))),()=>(U(Q),n(),H(()=>Q(`planApprovalMode`,n()))),()=>(U(a()),H(()=>s(a().approvalMode))),()=>(U(Q),n(),H(()=>Q(`editProjects`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().projectNumbers.length?a().projectNumbers.map(e=>`#${e}`).join(`, `):Q(`none`,n()))),()=>(U(Q),n(),H(()=>Q(`planVariableScope`,n()))),()=>(U(a()),H(()=>o(a().variableScope))),()=>(U(Q),n(),H(()=>Q(`planSecretScope`,n()))),()=>(U(a()),H(()=>o(a().secretScope))),()=>(U(Q),n(),H(()=>Q(`planIssueResources`,n()))),()=>(U(Q),n(),H(()=>Q(`planIssueResourcesValue`,n()))),()=>(U(Q),n(),H(()=>Q(`planInitialTag`,n()))),()=>(U(Q),U(a()),n(),H(()=>Q(a().initialTag?`yes`:`no`,n()))),()=>(U(Q),n(),H(()=>Q(`planAdvancedDefaults`,n())))]),G(e,c),k(),i()}var rs=W(`
                                      • `),is=W(`

                                          `),as=W(`
                                        • `),os=W(`

                                            `),ss=W(`

                                              `),cs=W(``),ls=W(`

                                              `),us=W(`

                                              `,1);function ds(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`prompt`,8),s=Z(t,`controller`,8),c=Z(t,`busy`,8),l=Z(t,`onSubmit`,8),u={capabilities:`editCapabilities`,"agent-runtime":`editRuntimes`,"agent-model-defaults":`editModels`,"agent-role-overrides":`editRoleModels`,repository:`editRepository`,deployment:`editDeployment`,bugbot:`editBugbot`,"pull-request-approval":`editApproval`,projects:`editProjects`,provisioning:`editProvisioning`,storage:`editStorage`};Tn(()=>(n(),U(o())),()=>{N(a,[{title:Q(`files`,n()),items:o().plan.files},{title:Q(`workflows`,n()),items:o().plan.workflows},{title:Q(`variables`,n()),items:o().plan.variables},{title:Q(`secretNames`,n()),items:o().plan.secrets}])}),En(),Y();var d=us(),f=F(d),p=I(f,!0),m=L(f,2);ns(m,{get decisions(){return U(o()),H(()=>o().plan.decisions)}});var h=L(m,2),g=e=>{var t=is(),r=P(t),i=I(r,!0),a=L(r,2);Qr(a,5,()=>(U(o()),H(()=>o().plan.presentationDefaults)),Jr,(e,t)=>{var r=rs(),i=I(r);R(e=>K(i,`${e??``}: ${V(t),H(()=>V(t).count)??``}`),[()=>(V(t),U(Q),n(),H(()=>u[V(t).group]?Q(u[V(t).group],n()):V(t).group))]),G(e,r)}),E(a),E(t),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`planBasicDefaultsIntro`,n())))]),G(e,t)};q(h,e=>{U(o()),H(()=>o().plan.presentationDefaults.length)&&e(g)});var _=L(h,2);Qr(_,5,()=>V(a),Jr,(e,t)=>{var n=os(),r=P(n),i=P(r),a=I(L(i),!0);E(r);var o=L(r);Qr(o,5,()=>(V(t),H(()=>V(t).items)),Jr,(e,t)=>{var n=as(),r=I(P(n),!0);E(n),R(()=>K(r,V(t))),G(e,n)}),E(o),E(n),R(()=>{K(i,`${V(t),H(()=>V(t).title)??``} `),K(a,(V(t),H(()=>V(t).items.length)))}),G(e,n)}),E(_);var v=L(_,2),y=e=>{var t=ss(),r=P(t),i=I(r,!0),a=L(r);Qr(a,5,()=>(U(o()),H(()=>o().plan.warnings)),Jr,(e,t)=>{var r=rs(),i=I(r,!0);R(e=>K(i,e),[()=>(U(Uo),V(t),n(),H(()=>Uo(V(t),n())))]),G(e,r)}),E(a),E(t),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`beforeContinue`,n())))]),G(e,t)};q(v,e=>{U(o()),H(()=>o().plan.warnings.length)&&e(y)});var b=L(v,2),x=e=>{var t=ls(),r=P(t),i=I(r,!0),a=L(r),d=I(a,!0),f=L(a,2);Qr(f,5,()=>(U(o()),H(()=>o().editGroups)),Jr,(e,t)=>{var r=cs(),i=I(r,!0);R(e=>{r.disabled=!s()||c(),K(i,e)},[()=>(U(Q),n(),V(t),H(()=>Q(`changeSection`,n(),{section:Q(u[V(t)],n())})))]),Sr(`click`,r,()=>l()(`revise:${V(t)}`)),G(e,r)}),E(f),E(t),R((e,t)=>{K(i,e),K(d,t)},[()=>(U(Q),n(),H(()=>Q(`changeAnswersTitle`,n()))),()=>(U(Q),n(),H(()=>Q(`changeAnswersHelp`,n())))]),G(e,t)};q(b,e=>{U(o()),H(()=>o().editGroups?.length)&&e(x)});var S=L(b,2),C=P(S);{let e=A(()=>(U(Q),n(),H(()=>Q(`stopHere`,n())))),t=A(()=>!s()||c());ka(C,{get label(){return V(e)},variant:`secondary`,onClick:()=>l()(`decline`),get disabled(){return V(t)}})}var ee=L(C);{let e=A(()=>(U(Q),n(),H(()=>Q(`approvePlan`,n())))),t=A(()=>!s()||c());ka(ee,{get label(){return V(e)},arrow:!0,onClick:()=>l()(`approve`),get disabled(){return V(t)}})}E(S),R(e=>K(p,e),[()=>(U(Q),n(),H(()=>Q(`planBody`,n())))]),G(e,d),k(),i()}Cr([`click`]);function fs(e,t){let n=t,r=!0,i=()=>queueMicrotask(()=>{r&&e.isConnected&&e.focus({preventScroll:!0})});return i(),{update(e){e!==n&&(n=e,i())},destroy(){r=!1}}}var ps=W(`

                                              `),ms=W(`

                                              `),hs=W(`
                                              `);function gs(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=Z(t,`prompt`,8),s=Z(t,`revision`,8),c=Z(t,`promptRevision`,8),l=Z(t,`controller`,8),u=Z(t,`busy`,8),d=Z(t,`onSubmit`,8),f=Z(t,`onRetryDiscovery`,8),p=Z(t,`onBack`,8);Tn(()=>(U(o()),n()),()=>{N(a,ya(o(),n()))}),En(),Y();var m=hs(),h=P(m),g=P(h),_=I(g,!0),v=I(L(g));E(h);var y=L(h,2),b=e=>{var t=ps(),n=I(t,!0);R(()=>K(n,(V(a),U(o()),H(()=>V(a)?.title??o().title)))),G(e,t)};q(y,e=>{U(o()),H(()=>o().kind!==`question`)&&e(b)});var x=L(y,2),S=e=>{var t=ms(),n=I(t,!0);R(()=>K(n,(V(a),U(o()),H(()=>V(a)?.description??(`description`in o()?o().description:``))))),G(e,t)};q(x,e=>{V(a),U(o()),H(()=>V(a)?.description||`description`in o()&&o().description)&&e(S)}),qr(L(x,2),c,e=>{var t=Mr(),n=F(t),r=e=>{No(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()},get onRetryDiscovery(){return f()},get onBack(){return p()}})},i=e=>{Io(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},a=e=>{Bo(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})},s=e=>{ds(e,{get prompt(){return o()},get controller(){return l()},get busy(){return u()},get onSubmit(){return d()}})};q(n,e=>{U(o()),H(()=>o().kind===`question`)?e(r):(U(o()),H(()=>o().kind===`choice`||o().kind===`confirm`)?e(i,1):(U(o()),H(()=>o().kind===`text`||o().kind===`secret`)?e(a,2):(U(o()),H(()=>o().kind===`plan`)&&e(s,3))))}),G(e,t)}),E(m),ii(m,(e,t)=>fs?.(e,t),c),R((e,t,n)=>{J(m,`aria-label`,e),K(_,t),K(v,`${n??``} ${s()??``}`)},[()=>(U(Q),n(),H(()=>Q(`currentDecision`,n()))),()=>(U(Q),n(),H(()=>Q(`currentDecision`,n()))),()=>(U(Q),n(),H(()=>Q(`session`,n())))]),G(e,m),k(),i()}var _s={Metadata:`Metadata`,Contents:`Contents`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Issues`,Actions:`Actions`,Checks:`Checks`,Administration:`Administration`,Workflows:`Workflows`,"Issue Types":`Issue Types`,Projects:`Projects`,"Pull requests":`Pull requests`,Members:`Members`},vs={repository:`repository`,organization:`organization`,read:`Read`,write:`Write`,required:`Required`,conditional:`Conditional`,verified:`Verified`,missing:`Missing`,unverifiable:`Unverifiable`},ys={Metadata:`Metadatos`,Contents:`Contenido`,Secrets:`Secretos`,Variables:`Variables`,Issues:`Incidencias`,Actions:`Acciones`,Checks:`Comprobaciones`,Administration:`Administración`,Workflows:`Flujos de trabajo`,"Issue Types":`Tipos de incidencia`,Projects:`Proyectos`,"Pull requests":`Solicitudes de cambio`,Members:`Miembros`},bs={repository:`repositorio`,organization:`organización`,read:`Lectura`,write:`Escritura`,required:`Obligatorio`,conditional:`Condicional`,verified:`Verificado`,missing:`Faltante`,unverifiable:`No verificable`},xs={Metadata:`Métadonnées`,Contents:`Contenu`,Secrets:`Secrets`,Variables:`Variables`,Issues:`Tickets`,Actions:`Actions`,Checks:`Vérifications`,Administration:`Administration`,Workflows:`Flux de travail`,"Issue Types":`Types de ticket`,Projects:`Projets`,"Pull requests":`Demandes de tirage`,Members:`Membres`},Ss={repository:`dépôt`,organization:`organisation`,read:`Lecture`,write:`Écriture`,required:`Obligatoire`,conditional:`Conditionnel`,verified:`Vérifié`,missing:`Manquant`,unverifiable:`Non vérifiable`},Cs={Metadata:`Metadados`,Contents:`Conteúdo`,Secrets:`Segredos`,Variables:`Variáveis`,Issues:`Questões`,Actions:`Ações`,Checks:`Verificações`,Administration:`Administração`,Workflows:`Fluxos de trabalho`,"Issue Types":`Tipos de questão`,Projects:`Projetos`,"Pull requests":`Pedidos de alteração`,Members:`Membros`},ws={repository:`repositório`,organization:`organização`,read:`Leitura`,write:`Escrita`,required:`Obrigatório`,conditional:`Condicional`,verified:`Verificado`,missing:`Em falta`,unverifiable:`Não verificável`},Ts={en:_s,es:ys,fr:xs,pt:Cs},Es={en:vs,es:bs,fr:Ss,pt:ws};function Ds(e,t){return Es[e][t]}function Os(e,t){return Object.prototype.hasOwnProperty.call(Ts[e],t)?Ts[e][t]:t}function ks(e,t){if(t===`verified`||t===`missing`||t===`unverifiable`)return Es[e][t]}var As=`Resolve repository identity and visibility.(Inspect installed workflows and repository files.(Inspect and provision selected GitHub Actions Secrets.(Inspect and provision selected GitHub Actions Variables.(Provision labels and issue resources.(Inspect and dispatch credential-health workflows.(Inspect CI workflow runs and jobs for exact producer identities.(Discover exact CI check and producer identities.(Inspect branch protection and rulesets.(Bootstrap a missing credential-health workflow.(Inspect and provision organization Actions Secrets.(Inspect and provision organization Actions Variables.(Provision and assign configured issue types.(Inspect selected Projects and their Status options; setup does not edit Project items.(Create the initial repository tag when no version tag exists.(Inspect and provision selected repository Actions Secrets.(Inspect and provision selected repository Actions Variables.(Provision labels for the selected issue workflows.(Dispatch credential-health checks for existing Secrets.(Inspect CI workflow runs and jobs for approval evidence.(Temporarily install credential health when its workflow is not confirmed installed.(Inspect branch protection and effective rulesets.(Inspect and provision selected organization Actions Secrets.(Inspect and provision selected organization Actions Variables.(Provision native issue types for the selected workflows.(Resolve repository and collaborator metadata.(Dispatch selected release or hotfix workflows and check previous runs.(Check previous workflow runs before executing an enabled route.(Create managed branches, edit files, or merge selected release/hotfix changes.(Manage selected issue lifecycles, comments, and progress.(Manage selected pull request workflows, reviews, or autofix.(Verify current-head required checks and producer identities.(Load the guarded approval policy.(Select or authorize organization members for enabled workflows.(Assign configured organization issue types.(Update selected organization Projects.(Load the organization-scoped approval policy.(Secret provisioning enabled(Variable provisioning enabled(Issue workflows enabled(Credential health enabled(Pull-request approval enabled(Release, hotfix, or guarded approval enabled(Temporary health workflow required(Organization Secret storage selected(Organization Variable storage selected(Issue type automation enabled(Organization Projects selected`.split(`(`),js={"Resolve repository identity and visibility.":`Comprobar la identidad y visibilidad del repositorio.`,"Inspect installed workflows and repository files.":`Examinar los workflows instalados y los archivos del repositorio.`,"Inspect and provision selected GitHub Actions Secrets.":`Examinar y configurar los Secrets de GitHub Actions seleccionados.`,"Inspect and provision selected GitHub Actions Variables.":`Examinar y configurar las Variables de GitHub Actions seleccionadas.`,"Provision labels and issue resources.":`Crear etiquetas y recursos de issues.`,"Inspect and dispatch credential-health workflows.":`Examinar y ejecutar los workflows de comprobación de credenciales.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examinar ejecuciones y jobs de CI para identificar sus productores exactos.`,"Discover exact CI check and producer identities.":`Identificar los checks de CI y sus productores exactos.`,"Inspect branch protection and rulesets.":`Examinar la protección de ramas y sus reglas.`,"Bootstrap a missing credential-health workflow.":`Instalar provisionalmente el workflow de comprobación de credenciales que falta.`,"Inspect and provision organization Actions Secrets.":`Examinar y configurar Secrets de Actions en la organización.`,"Inspect and provision organization Actions Variables.":`Examinar y configurar Variables de Actions en la organización.`,"Provision and assign configured issue types.":`Crear y asignar los tipos de issue configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar los Projects seleccionados y sus opciones de Status; el setup no modifica los elementos de los Projects.`,"Create the initial repository tag when no version tag exists.":`Crear el tag inicial si el repositorio aún no tiene ninguno de versión.`,"Inspect and provision selected repository Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en el repositorio.`,"Inspect and provision selected repository Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en el repositorio.`,"Provision labels for the selected issue workflows.":`Crear las etiquetas de los flujos de issues seleccionados.`,"Dispatch credential-health checks for existing Secrets.":`Ejecutar comprobaciones de credenciales para los Secrets existentes.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examinar ejecuciones y jobs de CI como prueba para la aprobación.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporalmente la comprobación de credenciales si su workflow no está confirmado.`,"Inspect branch protection and effective rulesets.":`Examinar la protección de ramas y las reglas efectivas.`,"Inspect and provision selected organization Actions Secrets.":`Examinar y configurar los Secrets de Actions seleccionados en la organización.`,"Inspect and provision selected organization Actions Variables.":`Examinar y configurar las Variables de Actions seleccionadas en la organización.`,"Provision native issue types for the selected workflows.":`Crear tipos de issue nativos para los flujos seleccionados.`,"Resolve repository and collaborator metadata.":`Consultar los metadatos del repositorio y sus colaboradores.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Ejecutar los flujos de release o hotfix seleccionados y comprobar ejecuciones anteriores.`,"Check previous workflow runs before executing an enabled route.":`Comprobar ejecuciones anteriores antes de iniciar un flujo habilitado.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Crear ramas gestionadas, editar archivos o integrar cambios de release y hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gestionar el ciclo de vida, los comentarios y el progreso de los issues seleccionados.`,"Manage selected pull request workflows, reviews, or autofix.":`Gestionar flujos de pull requests, revisiones o correcciones automáticas.`,"Verify current-head required checks and producer identities.":`Verificar los checks obligatorios y productores del commit actual.`,"Load the guarded approval policy.":`Leer la política de aprobación protegida.`,"Select or authorize organization members for enabled workflows.":`Seleccionar o autorizar miembros de la organización para los flujos activos.`,"Assign configured organization issue types.":`Asignar los tipos de issue configurados en la organización.`,"Update selected organization Projects.":`Actualizar los Projects seleccionados de la organización.`,"Load the organization-scoped approval policy.":`Leer la política de aprobación guardada en la organización.`,"Secret provisioning enabled":`Configuración de Secrets activada`,"Variable provisioning enabled":`Configuración de Variables activada`,"Issue workflows enabled":`Flujos de issues activados`,"Credential health enabled":`Comprobación de credenciales activada`,"Pull-request approval enabled":`Aprobación de pull requests activada`,"Release, hotfix, or guarded approval enabled":`Release, hotfix o aprobación protegida activados`,"Temporary health workflow required":`Hace falta un workflow temporal de comprobación`,"Organization Secret storage selected":`Se eligió guardar Secrets en la organización`,"Organization Variable storage selected":`Se eligió guardar Variables en la organización`,"Issue type automation enabled":`Automatización de tipos de issue activada`,"Organization Projects selected":`Se seleccionaron Projects de la organización`},Ms={"Resolve repository identity and visibility.":`Vérifier l’identité et la visibilité du dépôt.`,"Inspect installed workflows and repository files.":`Examiner les workflows installés et les fichiers du dépôt.`,"Inspect and provision selected GitHub Actions Secrets.":`Examiner et configurer les Secrets GitHub Actions choisis.`,"Inspect and provision selected GitHub Actions Variables.":`Examiner et configurer les Variables GitHub Actions choisies.`,"Provision labels and issue resources.":`Créer des étiquettes et des ressources pour les tickets.`,"Inspect and dispatch credential-health workflows.":`Examiner et lancer les workflows de vérification des identifiants.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Examiner les exécutions et jobs CI pour identifier exactement leurs producteurs.`,"Discover exact CI check and producer identities.":`Identifier précisément les vérifications CI et leurs producteurs.`,"Inspect branch protection and rulesets.":`Examiner la protection des branches et les ensembles de règles.`,"Bootstrap a missing credential-health workflow.":`Installer provisoirement le workflow de vérification des identifiants manquant.`,"Inspect and provision organization Actions Secrets.":`Examiner et configurer les Secrets Actions de l’organisation.`,"Inspect and provision organization Actions Variables.":`Examiner et configurer les Variables Actions de l’organisation.`,"Provision and assign configured issue types.":`Créer et attribuer les types de ticket configurés.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consulter les Projects sélectionnés et leurs options Status ; la configuration ne modifie aucun élément de Project.`,"Create the initial repository tag when no version tag exists.":`Créer le tag initial si le dépôt ne possède encore aucun tag de version.`,"Inspect and provision selected repository Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans le dépôt.`,"Inspect and provision selected repository Actions Variables.":`Examiner et configurer les Variables Actions choisies dans le dépôt.`,"Provision labels for the selected issue workflows.":`Créer les étiquettes des workflows de ticket choisis.`,"Dispatch credential-health checks for existing Secrets.":`Lancer des vérifications d’identifiants pour les Secrets existants.`,"Inspect CI workflow runs and jobs for approval evidence.":`Examiner les exécutions et jobs CI comme preuve pour l’approbation.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Installer provisoirement la vérification des identifiants si son workflow n’est pas confirmé.`,"Inspect branch protection and effective rulesets.":`Examiner la protection des branches et les règles applicables.`,"Inspect and provision selected organization Actions Secrets.":`Examiner et configurer les Secrets Actions choisis dans l’organisation.`,"Inspect and provision selected organization Actions Variables.":`Examiner et configurer les Variables Actions choisies dans l’organisation.`,"Provision native issue types for the selected workflows.":`Créer des types de ticket natifs pour les workflows choisis.`,"Resolve repository and collaborator metadata.":`Consulter les métadonnées du dépôt et de ses collaborateurs.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Lancer les workflows de version ou correctif urgent choisis et vérifier les exécutions précédentes.`,"Check previous workflow runs before executing an enabled route.":`Vérifier les exécutions précédentes avant de lancer un parcours activé.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Créer des branches gérées, modifier des fichiers ou fusionner les changements de version et correctif.`,"Manage selected issue lifecycles, comments, and progress.":`Gérer le cycle de vie, les commentaires et la progression des tickets choisis.`,"Manage selected pull request workflows, reviews, or autofix.":`Gérer les workflows de pull request, les revues ou les corrections automatiques.`,"Verify current-head required checks and producer identities.":`Vérifier les contrôles requis et leurs producteurs pour le commit courant.`,"Load the guarded approval policy.":`Lire la politique d’approbation encadrée.`,"Select or authorize organization members for enabled workflows.":`Sélectionner ou autoriser des membres de l’organisation pour les workflows activés.`,"Assign configured organization issue types.":`Attribuer les types de ticket configurés dans l’organisation.`,"Update selected organization Projects.":`Mettre à jour les projets de l’organisation choisis.`,"Load the organization-scoped approval policy.":`Lire la politique d’approbation stockée dans l’organisation.`,"Secret provisioning enabled":`Configuration des Secrets activée`,"Variable provisioning enabled":`Configuration des Variables activée`,"Issue workflows enabled":`Workflows de ticket activés`,"Credential health enabled":`Vérification des identifiants activée`,"Pull-request approval enabled":`Approbation des pull requests activée`,"Release, hotfix, or guarded approval enabled":`Version, correctif urgent ou approbation encadrée activés`,"Temporary health workflow required":`Workflow temporaire de vérification requis`,"Organization Secret storage selected":`Stockage des Secrets dans l’organisation choisi`,"Organization Variable storage selected":`Stockage des Variables dans l’organisation choisi`,"Issue type automation enabled":`Automatisation des types de ticket activée`,"Organization Projects selected":`Projets de l’organisation choisis`},Ns={"Resolve repository identity and visibility.":`Verificar a identidade e visibilidade do repositório.`,"Inspect installed workflows and repository files.":`Inspecionar os fluxos instalados e os ficheiros do repositório.`,"Inspect and provision selected GitHub Actions Secrets.":`Inspecionar e configurar os Secrets do GitHub Actions selecionados.`,"Inspect and provision selected GitHub Actions Variables.":`Inspecionar e configurar as Variables do GitHub Actions selecionadas.`,"Provision labels and issue resources.":`Criar etiquetas e recursos para questões.`,"Inspect and dispatch credential-health workflows.":`Inspecionar e executar os fluxos de verificação de credenciais.`,"Inspect CI workflow runs and jobs for exact producer identities.":`Inspecionar execuções e jobs CI para identificar exatamente os seus produtores.`,"Discover exact CI check and producer identities.":`Identificar as verificações CI e os seus produtores exatos.`,"Inspect branch protection and rulesets.":`Inspecionar a proteção de ramos e os conjuntos de regras.`,"Bootstrap a missing credential-health workflow.":`Instalar temporariamente o fluxo de verificação de credenciais em falta.`,"Inspect and provision organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions da organização.`,"Inspect and provision organization Actions Variables.":`Inspecionar e configurar as Variables de Actions da organização.`,"Provision and assign configured issue types.":`Criar e atribuir os tipos de questão configurados.`,"Inspect selected Projects and their Status options; setup does not edit Project items.":`Consultar os Projects selecionados e as suas opções de Status; a configuração não altera os itens dos Projects.`,"Create the initial repository tag when no version tag exists.":`Criar a etiqueta inicial se o repositório ainda não tiver etiquetas de versão.`,"Inspect and provision selected repository Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados no repositório.`,"Inspect and provision selected repository Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas no repositório.`,"Provision labels for the selected issue workflows.":`Criar etiquetas para os fluxos de questões selecionados.`,"Dispatch credential-health checks for existing Secrets.":`Executar verificações de credenciais para os Secrets existentes.`,"Inspect CI workflow runs and jobs for approval evidence.":`Inspecionar execuções e jobs CI como prova para aprovação.`,"Temporarily install credential health when its workflow is not confirmed installed.":`Instalar temporariamente a verificação de credenciais se o fluxo não estiver confirmado.`,"Inspect branch protection and effective rulesets.":`Inspecionar a proteção de ramos e as regras aplicáveis.`,"Inspect and provision selected organization Actions Secrets.":`Inspecionar e configurar os Secrets de Actions selecionados na organização.`,"Inspect and provision selected organization Actions Variables.":`Inspecionar e configurar as Variables de Actions selecionadas na organização.`,"Provision native issue types for the selected workflows.":`Criar tipos de questão nativos para os fluxos selecionados.`,"Resolve repository and collaborator metadata.":`Consultar os metadados do repositório e dos colaboradores.`,"Dispatch selected release or hotfix workflows and check previous runs.":`Executar os fluxos de release ou hotfix selecionados e verificar execuções anteriores.`,"Check previous workflow runs before executing an enabled route.":`Verificar execuções anteriores antes de iniciar um percurso ativo.`,"Create managed branches, edit files, or merge selected release/hotfix changes.":`Criar ramos geridos, editar ficheiros ou integrar alterações de release e hotfix.`,"Manage selected issue lifecycles, comments, and progress.":`Gerir o ciclo de vida, os comentários e o progresso das questões selecionadas.`,"Manage selected pull request workflows, reviews, or autofix.":`Gerir fluxos de pull requests, revisões ou correções automáticas.`,"Verify current-head required checks and producer identities.":`Verificar as verificações obrigatórias e os produtores do commit atual.`,"Load the guarded approval policy.":`Ler a política de aprovação protegida.`,"Select or authorize organization members for enabled workflows.":`Selecionar ou autorizar membros da organização para os fluxos ativos.`,"Assign configured organization issue types.":`Atribuir os tipos de questão configurados na organização.`,"Update selected organization Projects.":`Atualizar os Projetos selecionados da organização.`,"Load the organization-scoped approval policy.":`Ler a política de aprovação guardada na organização.`,"Secret provisioning enabled":`Configuração de Secrets ativa`,"Variable provisioning enabled":`Configuração de Variables ativa`,"Issue workflows enabled":`Fluxos de questões ativos`,"Credential health enabled":`Verificação de credenciais ativa`,"Pull-request approval enabled":`Aprovação de pull requests ativa`,"Release, hotfix, or guarded approval enabled":`Release, hotfix ou aprovação protegida ativos`,"Temporary health workflow required":`É necessário um fluxo temporário de verificação`,"Organization Secret storage selected":`Armazenamento dos Secrets na organização selecionado`,"Organization Variable storage selected":`Armazenamento das Variables na organização selecionado`,"Issue type automation enabled":`Automatização de tipos de questão ativa`,"Organization Projects selected":`Projetos da organização selecionados`},Ps=new Set(As),Fs={es:js,fr:Ms,pt:Ns};function Is(e,t){return e===`en`?t:Ps.has(t)?Fs[e][t]:Q(`permissionUnknown`,e)}var Ls=W(` `),Rs=W(` `),zs=W(`
                                            • `),Bs=W(`

                                                `),Vs=W(`

                                                `),Hs=W(``);function Us(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`view`,8);Y();var o=Hs(),s=P(o),c=L(P(s)),l=I(c,!0),u=L(c),d=I(u,!0),f=L(u),p=I(P(f),!0);E(f),E(s);var m=L(s,2),h=e=>{var t=Bs(),r=L(P(t)),i=I(r),o=L(r),s=I(o,!0),c=L(o,2);Qr(c,5,()=>(U(a()),H(()=>a().permissions.report?.checks??a().permissions.requirements??[])),Jr,(e,t)=>{var r=zs(),i=P(r),a=P(i,!0),o=L(a),s=e=>{var n=Ls(),r=I(P(n));E(n),R(()=>K(r,`GitHub · ${V(t),H(()=>V(t).permission)??``}`)),G(e,n)},c=gt(()=>(n(),U(Os),V(t),H(()=>n()!==`en`&&Os(n(),V(t).permission)!==V(t).permission)));q(o,e=>{V(c)&&e(s)});var l=L(o),u=I(l),d=L(l),f=I(d,!0),p=L(d),m=e=>{var r=Rs(),i=I(r,!0);R(e=>K(i,e),[()=>(U(Is),n(),V(t),H(()=>Is(n(),V(t).condition)))]),G(e,r)};q(p,e=>{V(t),H(()=>V(t).condition)&&e(m)}),E(i);var h=L(i),g=P(h,!0),_=L(g),v=e=>{var r=Rs(),i=I(r,!0);R(e=>K(i,e),[()=>(U(ks),n(),V(t),H(()=>ks(n(),V(t).status)))]),G(e,r)},y=gt(()=>(V(t),U(ks),n(),H(()=>`status`in V(t)&&ks(n(),V(t).status))));q(_,e=>{V(y)&&e(v)}),E(h),E(r),R((e,t,n,r,i)=>{K(a,e),K(u,`${t??``} · ${n??``}`),K(f,r),K(g,i)},[()=>(U(Os),n(),V(t),H(()=>Os(n(),V(t).permission))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).scope))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).applicability))),()=>(U(Is),n(),V(t),H(()=>Is(n(),V(t).reason))),()=>(U(Ds),n(),V(t),H(()=>Ds(n(),V(t).level)))]),G(e,r)}),E(c);var l=I(L(c,2),!0);E(t),R((e,t,n,r)=>{K(i,`${e??``} ${t??``}`),K(s,n),K(l,r)},[()=>(U(a()),U(Q),n(),H(()=>a().permissions.role===`setup`?Q(`setupPat`,n()):Q(`botPat`,n()))),()=>(U(Q),n(),H(()=>Q(`access`,n()))),()=>(U(a()),U(Q),n(),H(()=>a().permissions.report?Q(`readOnlyCheck`,n()):Q(`provisionalGrants`,n()))),()=>(U(Q),n(),H(()=>Q(`conditionalGrants`,n())))]),G(e,t)},g=e=>{var t=Vs(),r=L(P(t)),i=I(r,!0),a=I(L(r),!0);E(t),R((e,t)=>{K(i,e),K(a,t)},[()=>(U(Q),n(),H(()=>Q(`permissionsFollow`,n()))),()=>(U(Q),n(),H(()=>Q(`permissionsFollowBody`,n())))]),G(e,t)};q(m,e=>{U(a()),H(()=>a().permissions)?e(h):e(g,-1)}),E(o),R((e,t,n)=>{J(o,`aria-label`,e),K(l,t),K(d,n),K(p,(U(a()),H(()=>a().repository)))},[()=>(U(Q),n(),H(()=>Q(`setup`,n()))),()=>(U(Q),n(),H(()=>Q(`repoFocus`,n()))),()=>(U(Q),n(),H(()=>Q(`repoFocusBody`,n())))]),G(e,o),k(),i()}var Ws=W(`

                                                `),Gs=W(`

                                                `),Ks=W(`

                                                `),qs=W(`
                                              • `),Js=W(`

                                                  `),Ys=W(`

                                                  `),Xs=W(`
                                                  `),Zs=W(`

                                                  `);function Qs(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=M(),o=M(),s=Z(t,`outcome`,8),c=Z(t,`controller`,8),l=Z(t,`onClose`,8),u=Z(t,`onDoctor`,8,async()=>void 0),d=Z(t,`doctor`,8,void 0),f=Z(t,`detail`,8,void 0),p={permissions:[`reasonPermissions`,`nextPermissions`],storage:[`reasonStorage`,`nextStorage`],configuration:[`reasonConfiguration`,`nextConfiguration`],"session-expired":[`reasonExpired`,`nextExpired`],cancelled:[`reasonCancelled`,`nextCancelled`],provider:[`reasonProvider`,`nextProvider`],"rate-limit":[`reasonRateLimit`,`nextRateLimit`],unknown:[`reasonUnknown`,`nextUnknown`]},m={files:`receiptFiles`,secrets:`receiptSecrets`,labels:`receiptLabels`,"issue-types":`receiptIssueTypes`,variables:`receiptVariables`,"initial-tag":`receiptInitialTag`};Tn(()=>(U(s()),n()),()=>{N(a,s()===`complete`?Q(`resultApplied`,n()):s()===`dry-run`?Q(`resultNoChanges`,n()):s()===`cancelled`||s()===`blocked`?Q(`resultStopped`,n()):Q(`resultPartial`,n()))}),Tn(()=>(U(s()),n()),()=>{N(o,s()===`complete`?Q(`resultCompleteBody`,n()):s()===`partial`?Q(`resultPartialBody`,n()):Q(`resultNoChangesBody`,n()))}),En(),Y();var h=Zs(),g=P(h),_=I(g,!0),v=L(g),y=I(v,!0),b=L(v,2),x=e=>{var t=Ks(),r=P(t),i=P(r),a=I(i),o=L(i);E(r);var c=L(r,2),l=e=>{var t=Ws(),r=P(t),i=I(r),a=L(r);E(t),R((e,t)=>{K(i,`${e??``}:`),K(a,` ${t??``}`)},[()=>(U(Q),n(),H(()=>Q(`progress`,n()))),()=>(U(qi),U(f()),n(),H(()=>qi(f().stoppedStage,n())))]),G(e,t)};q(c,e=>{U(f()),H(()=>f()?.stoppedStage)&&e(l)});var u=L(c,2),d=P(u),m=I(d),h=L(d);E(u);var g=L(u,2),_=P(g),v=I(_),y=L(_);E(g);var b=L(g,2),x=e=>{var t=Gs(),r=P(t),i=I(r),a=I(L(r,2),!0);E(t),R(e=>{K(i,`${e??``}:`),K(a,(U(f()),H(()=>f().diagnosticRef)))},[()=>(U(Q),n(),H(()=>Q(`diagnosticReference`,n())))]),G(e,t)};q(b,e=>{U(f()),H(()=>f()?.diagnosticRef)&&e(x)}),E(t),R((e,t,n,r,i,s)=>{K(a,`${e??``}:`),K(o,` ${t??``}`),K(m,`${n??``}:`),K(h,` ${r??``}`),K(v,`${i??``}:`),K(y,` ${s??``}`)},[()=>(U(Q),n(),H(()=>Q(`whatHappened`,n()))),()=>(U(Q),U(f()),n(),H(()=>Q(p[f()?.reasonCode??`unknown`][0],n()))),()=>(U(Q),n(),H(()=>Q(`alreadyChanged`,n()))),()=>(U(f()),U(s()),U(Q),n(),H(()=>f()?.mutationStarted||s()===`partial`?Q(`inspectPartial`,n()):Q(`noChanges`,n()))),()=>(U(Q),n(),H(()=>Q(`nextAction`,n()))),()=>(U(s()),U(Q),n(),U(f()),H(()=>s()===`partial`?`${Q(`inspectPartial`,n())} ${Q(p[f()?.reasonCode??`unknown`][1],n())}`:Q(p[f()?.reasonCode??`unknown`][1],n())))]),G(e,t)};q(b,e=>{(s()===`blocked`||s()===`cancelled`||s()===`partial`)&&e(x)});var S=L(b,2),C=e=>{var t=Js(),r=P(t),i=I(r,!0),a=L(r,2);Qr(a,5,()=>(U(f()),H(()=>f().effects)),Jr,(e,t)=>{var r=qs(),i=P(r),a=I(i,!0),o=L(i),s=L(o),c=e=>{var r=jr();R(e=>K(r,`· ${e??``}`),[()=>(U(Q),V(t),n(),H(()=>Q(V(t).scope===`local`?`scopeLocal`:V(t).scope===`organization`?`scopeOrganization`:V(t).scope===`mixed`?`scopeMixed`:`scopeRepository`,n())))]),G(e,r)};q(s,e=>{V(t),H(()=>V(t).scope)&&e(c)}),E(r),R((e,t)=>{K(a,e),K(o,` — ${t??``}`)},[()=>(V(t),U(Q),n(),H(()=>m[V(t).id]?Q(m[V(t).id],n()):V(t).id)),()=>(U(Q),V(t),n(),H(()=>Q(V(t).state===`completed`?`effectCompleted`:V(t).state===`skipped`?`effectSkipped`:V(t).state===`not-started`?`effectNotStarted`:`effectInspect`,n())))]),G(e,r)}),E(a),E(t),R(e=>K(i,e),[()=>(U(Q),n(),H(()=>Q(`resourceReceipt`,n())))]),G(e,t)};q(S,e=>{U(f()),H(()=>f()?.effects?.length)&&e(C)});var ee=L(S,2),te=I(ee,!0),ne=L(ee,2),re=e=>{var t=Ys(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`botRenewal`,n())))]),G(e,t)};q(ne,e=>{s()===`complete`&&e(re)});var ie=L(ne,2),ae=I(ie,!0),oe=L(ie,2),se=e=>{var t=Xs(),r=P(t),i=e=>{var t=Ys(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`doctorRunning`,n())))]),G(e,t)},a=e=>{var t=Ys(),r=I(t);R((e,t,n)=>K(r,`${e??``} ${t??``} ${n??``}`),[()=>(U(Q),U(d()),n(),H(()=>Q(d().healthy?`doctorPassed`:`doctorWarnings`,n()))),()=>(U(Q),n(),U(d()),H(()=>Q(`doctorCounts`,n(),{pass:String(d().pass??0),warn:String(d().warn??0),fail:String(d().fail??0),skipped:String(d().skipped??0)}))),()=>(U(Q),n(),H(()=>Q(`doctorSecretLimit`,n())))]),G(e,t)},o=e=>{var t=Ys(),r=I(t,!0);R(e=>K(r,e),[()=>(U(Q),n(),H(()=>Q(`doctorFailed`,n())))]),G(e,t)};q(r,e=>{U(d()),H(()=>d()?.status===`running`)?e(i):(U(d()),H(()=>d()?.status===`complete`)?e(a,1):(U(d()),H(()=>d()?.status===`failed`)&&e(o,2)))});var s=L(r,2),l=e=>{{let t=A(()=>(U(Q),n(),H(()=>Q(`doctorRun`,n()))));ka(e,{get label(){return V(t)},variant:`secondary`,get onClick(){return u()}})}};q(s,e=>{U(c()),U(d()),H(()=>c()&&d()?.status!==`running`&&d()?.status!==`complete`)&&e(l)}),E(t),G(e,t)};q(oe,e=>{s()===`complete`&&e(se)});var ce=L(oe,2),le=I(P(ce),!0);ke(),E(ce);var ue=L(ce),de=e=>{{let t=A(()=>(U(Q),n(),H(()=>Q(`closeSession`,n()))));ka(e,{get label(){return V(t)},get onClick(){return l()}})}};q(ue,e=>{c()&&e(de)}),E(h),ii(h,(e,t)=>fs?.(e,t),()=>1),R((e,t)=>{K(_,s()===`complete`?`✓`:`!`),K(y,V(a)),K(te,V(o)),K(ae,e),K(le,t)},[()=>(U(Q),n(),H(()=>Q(`doctorHelp`,n()))),()=>(U(Q),n(),H(()=>Q(`patSettings`,n())))]),G(e,h),k(),i()}var $s=W(`

                                                  `);function ec(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii();Y();var a=$s(),o=L(P(a)),s=I(o,!0),c=I(L(o),!0);E(a),R((e,t)=>{K(s,e),K(c,t)},[()=>Q(`working`,n()),()=>Q(`workingBody`,n())]),G(e,a),k(),i()}function tc(e,t){return!t&&/^[A-Fa-f0-9]{16}$/u.test(e.trim())}var nc=W(`

                                                  `);function rc(e,t){O(t,!1);let n=()=>X($,`$setupLocale`,r),[r,i]=Ii(),a=Z(t,`busy`,8),o=Z(t,`onPair`,8),s=Z(t,`mode`,8,`pair`),c=M(``);function l(){if(!tc(V(c),a()))return;let e=V(c).trim();N(c,``),o()(e)}Y();var u=nc(),d=P(u),f=I(P(d),!0);E(d);var p=L(d,2),m=I(P(p),!0);E(p);var h=L(p,2),g=I(h,!0),_=L(h,2),v=P(_),y=I(v,!0),b=L(v,2);xi(b);var x=L(b,2),S=I(x,!0),C=L(x,2);{let e=A(()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairButton`:`takeOver`,n())))),t=A(()=>(U(tc),V(c),U(a()),H(()=>!tc(V(c),a()))));ka(C,{get label(){return V(e)},arrow:!0,onClick:l,get disabled(){return V(t)}})}E(_),E(u),R((e,t,n,r,i,o,s)=>{J(u,`aria-label`,e),K(f,t),K(m,n),K(g,r),K(y,i),b.disabled=a(),J(b,`placeholder`,o),K(S,s)},[()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(U(Q),n(),H(()=>Q(`privateSession`,n()))),()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairTitle`:`takeOver`,n()))),()=>(U(Q),U(s()),n(),H(()=>Q(s()===`pair`?`pairBody`:`readOnlyBody`,n()))),()=>(U(Q),n(),H(()=>Q(`pairLabel`,n()))),()=>(U(Q),n(),H(()=>Q(`pairPlaceholder`,n()))),()=>(U(Q),n(),H(()=>Q(`pairHelp`,n())))]),xr(`submit`,_,e=>{e.preventDefault(),l()}),Ei(b,()=>V(c),e=>N(c,e)),G(e,u),k(),i()}var ic={"The local setup session is unavailable.":`The local setup session is unavailable. Check the terminal; you may need to restart setup.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connection lost. The CLI may have stopped. Check the terminal before trying again.`,"Could not join this local session.":`Could not join this local session. Check the terminal and pair again.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Could not connect to the local setup session. Check the terminal and pair again.`,"Pairing was rejected.":`Pairing was rejected. Check the code in the launching terminal.`,"Invalid local pairing response.":`The local pairing response was invalid. Restart setup from the terminal.`,"Could not pair this browser.":`Could not pair this browser. Check the terminal and try again.`,"The request was rejected.":`The local request was rejected. Refresh the page and check the terminal.`,"Could not submit this answer.":`Could not submit this answer. Refresh the page and try again.`,"Cancellation failed.":`Cancellation failed. Check whether setup has already started applying before closing.`,"Takeover failed.":`Could not take control. Re-enter the pairing code from the launching terminal.`,"Invalid local host or request context.":`The local request context was rejected. Open the exact URL printed in the terminal.`,"Invalid request origin.":`The request came from another origin. Open the exact local URL printed in the terminal.`,"JSON required.":`The local request format was invalid. Refresh the page and try again.`,"Too many pairing attempts. Restart setup.":`Too many incorrect pairing attempts. Restart setup from the terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Too many incorrect pairing attempts. Wait 30 seconds and try the code again; terminal setup remains available.`,"Incorrect pairing code. Check the terminal.":`Incorrect pairing code. Check the launching terminal.`,"Incorrect pairing code. Check the launching output.":`Incorrect pairing code. Check the launching output.`,"Pair this browser using the code printed by the CLI.":`Pair this browser using the code printed by the CLI.`,"This tab is read-only.":`This tab is read-only. Enter the pairing code again to take control.`,"Invalid answer.":`The answer was invalid. Review the current question and try again.`,"Control moved to another tab.":`Control moved to another tab. This tab is now read-only.`,"This question changed. Refresh the current state.":`This question changed. Refresh the page before answering again.`,"This setup has already started applying or ended.":`Setup has already started applying or ended. Inspect the current result before retrying.`,"Only the controller can close a finished session.":`Only the controlling tab can close this finished session.`,"Method not allowed.":`This local request is not allowed. Refresh the page.`,"Not found.":`The requested local page was not found. Open the URL printed in the terminal.`,"Invalid local request.":`The local request was invalid. Refresh the page and try again.`,"Body too large.":`The submitted answer is too large. Shorten it and try again.`,"JSON object required.":`The local request format was invalid. Refresh the page and try again.`,"Could not retry discovery.":`Could not refresh the GitHub suggestions. Retry or use verified manual entry.`,"Could not return to the previous question.":`Could not return to the previous question. Refresh the page and try again.`,"Invalid question revision.":`The question changed. Refresh the page before going back.`,"No earlier question is available here.":`There is no earlier question in this stage. Continue or return to the plan review.`,"Read-only verification failed.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification failed. Check the terminal.":`Read-only verification failed. Check the terminal and retry once.`,"Read-only verification is unavailable or already running.":`Read-only verification is unavailable or already running. Check the current result before retrying.`},ac={en:ic,es:{"The local setup session is unavailable.":`La sesión local no está disponible. Revisa la terminal; quizá debas reiniciar la configuración.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Se perdió la conexión. Es posible que el CLI se haya detenido. Revisa la terminal antes de reintentar.`,"Could not join this local session.":`No se pudo acceder a esta sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`No se pudo conectar con la sesión local. Revisa la terminal y vuelve a vincular el navegador.`,"Pairing was rejected.":`Se rechazó la vinculación. Comprueba el código en la terminal que inició el proceso.`,"Invalid local pairing response.":`La respuesta de vinculación local no es válida. Reinicia la configuración desde la terminal.`,"Could not pair this browser.":`No se pudo vincular este navegador. Revisa la terminal y vuelve a intentarlo.`,"The request was rejected.":`Se rechazó la petición local. Actualiza la página y revisa la terminal.`,"Could not submit this answer.":`No se pudo enviar la respuesta. Actualiza la página y vuelve a intentarlo.`,"Cancellation failed.":`No se pudo cancelar. Comprueba si ya se han empezado a aplicar cambios antes de cerrar.`,"Takeover failed.":`No se pudo tomar el control. Vuelve a introducir el código de la terminal inicial.`,"Invalid local host or request context.":`Se rechazó el contexto de la petición local. Abre la URL exacta que aparece en la terminal.`,"Invalid request origin.":`La petición llegó desde otro origen. Abre la URL local exacta de la terminal.`,"JSON required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Too many pairing attempts. Restart setup.":`Demasiados intentos de vinculación fallidos. Reinicia la configuración desde la terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiados intentos de vinculación fallidos. Espera 30 segundos y vuelve a probar el código; puedes seguir con el setup en la terminal.`,"Incorrect pairing code. Check the terminal.":`Código de vinculación incorrecto. Comprueba la terminal inicial.`,"Incorrect pairing code. Check the launching output.":`Código de vinculación incorrecto. Comprueba la salida de inicio.`,"Pair this browser using the code printed by the CLI.":`Vincula este navegador con el código mostrado por el CLI.`,"This tab is read-only.":`Esta pestaña es de solo lectura. Introduce otra vez el código para tomar el control.`,"Invalid answer.":`La respuesta no es válida. Revisa la pregunta actual e inténtalo de nuevo.`,"Control moved to another tab.":`El control pasó a otra pestaña. Esta ahora es de solo lectura.`,"This question changed. Refresh the current state.":`La pregunta cambió. Actualiza la página antes de volver a responder.`,"This setup has already started applying or ended.":`La configuración ya empezó a aplicarse o terminó. Revisa el resultado antes de reintentar.`,"Only the controller can close a finished session.":`Solo la pestaña que tiene el control puede cerrar esta sesión finalizada.`,"Method not allowed.":`Esta petición local no está permitida. Actualiza la página.`,"Not found.":`No se encontró la página local solicitada. Abre la URL de la terminal.`,"Invalid local request.":`La petición local no es válida. Actualiza la página y reinténtalo.`,"Body too large.":`La respuesta enviada es demasiado larga. Acórtala y reinténtalo.`,"JSON object required.":`El formato de la petición local no es válido. Actualiza la página y reinténtalo.`,"Could not retry discovery.":`No se pudieron actualizar las sugerencias de GitHub. Reinténtalo o introduce datos verificados manualmente.`,"Could not return to the previous question.":`No se pudo volver a la pregunta anterior. Actualiza la página y reinténtalo.`,"Invalid question revision.":`La pregunta cambió. Actualiza la página antes de volver atrás.`,"No earlier question is available here.":`No hay una pregunta anterior en esta etapa. Continúa o vuelve a revisar el plan.`,"Read-only verification failed.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification failed. Check the terminal.":`Falló la comprobación de solo lectura. Revisa la terminal y vuelve a intentarlo una vez.`,"Read-only verification is unavailable or already running.":`La comprobación de solo lectura no está disponible o ya se está ejecutando. Revisa el resultado antes de reintentar.`},fr:{"The local setup session is unavailable.":`La session locale est indisponible. Vérifiez le terminal ; vous devrez peut-être relancer la configuration.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Connexion perdue. Le CLI s’est peut-être arrêté. Vérifiez le terminal avant de réessayer.`,"Could not join this local session.":`Impossible de rejoindre cette session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Impossible de se connecter à la session locale. Vérifiez le terminal et associez de nouveau le navigateur.`,"Pairing was rejected.":`L’association a été refusée. Vérifiez le code dans le terminal de lancement.`,"Invalid local pairing response.":`La réponse d’association locale est invalide. Relancez la configuration depuis le terminal.`,"Could not pair this browser.":`Impossible d’associer ce navigateur. Vérifiez le terminal et réessayez.`,"The request was rejected.":`La demande locale a été refusée. Actualisez la page et vérifiez le terminal.`,"Could not submit this answer.":`Impossible d’envoyer cette réponse. Actualisez la page et réessayez.`,"Cancellation failed.":`Annulation impossible. Vérifiez si des changements ont déjà commencé avant de fermer.`,"Takeover failed.":`Impossible de prendre le contrôle. Ressaisissez le code du terminal de lancement.`,"Invalid local host or request context.":`Le contexte de la demande locale a été refusé. Ouvrez l’URL exacte affichée dans le terminal.`,"Invalid request origin.":`La demande vient d’une autre origine. Ouvrez l’URL locale exacte du terminal.`,"JSON required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Too many pairing attempts. Restart setup.":`Trop de tentatives d’association incorrectes. Relancez la configuration depuis le terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Trop de tentatives d’association incorrectes. Attendez 30 secondes puis ressaisissez le code ; la configuration par terminal reste disponible.`,"Incorrect pairing code. Check the terminal.":`Code d’association incorrect. Vérifiez le terminal de lancement.`,"Incorrect pairing code. Check the launching output.":`Code d’association incorrect. Vérifiez la sortie de lancement.`,"Pair this browser using the code printed by the CLI.":`Associez ce navigateur avec le code affiché par le CLI.`,"This tab is read-only.":`Cet onglet est en lecture seule. Ressaisissez le code pour prendre le contrôle.`,"Invalid answer.":`La réponse est invalide. Revoyez la question actuelle et réessayez.`,"Control moved to another tab.":`Le contrôle est passé à un autre onglet. Celui-ci est maintenant en lecture seule.`,"This question changed. Refresh the current state.":`La question a changé. Actualisez la page avant de répondre de nouveau.`,"This setup has already started applying or ended.":`La configuration est déjà en cours d’application ou terminée. Inspectez le résultat avant de réessayer.`,"Only the controller can close a finished session.":`Seul l’onglet qui détient le contrôle peut fermer cette session terminée.`,"Method not allowed.":`Cette demande locale n’est pas autorisée. Actualisez la page.`,"Not found.":`La page locale demandée est introuvable. Ouvrez l’URL affichée dans le terminal.`,"Invalid local request.":`La demande locale est invalide. Actualisez la page et réessayez.`,"Body too large.":`La réponse envoyée est trop longue. Raccourcissez-la et réessayez.`,"JSON object required.":`Le format de la demande locale est invalide. Actualisez la page et réessayez.`,"Could not retry discovery.":`Impossible d’actualiser les suggestions GitHub. Réessayez ou saisissez des données vérifiées manuellement.`,"Could not return to the previous question.":`Impossible de revenir à la question précédente. Actualisez la page et réessayez.`,"Invalid question revision.":`La question a changé. Actualisez la page avant de revenir en arrière.`,"No earlier question is available here.":`Il n’y a pas de question précédente à cette étape. Continuez ou revenez à la révision du plan.`,"Read-only verification failed.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification failed. Check the terminal.":`La vérification en lecture seule a échoué. Consultez le terminal et réessayez une fois.`,"Read-only verification is unavailable or already running.":`La vérification en lecture seule est indisponible ou déjà en cours. Consultez le résultat avant de réessayer.`},pt:{"The local setup session is unavailable.":`A sessão local não está disponível. Verifique o terminal; poderá ter de reiniciar a configuração.`,"Connection lost. The CLI may have stopped. Check the terminal before trying again.":`Ligação perdida. O CLI pode ter parado. Verifique o terminal antes de tentar novamente.`,"Could not join this local session.":`Não foi possível entrar nesta sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Could not connect to the local setup session. Check the terminal and pair again.":`Não foi possível ligar à sessão local. Verifique o terminal e volte a emparelhar o navegador.`,"Pairing was rejected.":`O emparelhamento foi recusado. Confirme o código no terminal de lançamento.`,"Invalid local pairing response.":`A resposta de emparelhamento local é inválida. Reinicie a configuração a partir do terminal.`,"Could not pair this browser.":`Não foi possível emparelhar este navegador. Verifique o terminal e tente novamente.`,"The request was rejected.":`O pedido local foi recusado. Atualize a página e verifique o terminal.`,"Could not submit this answer.":`Não foi possível enviar a resposta. Atualize a página e tente novamente.`,"Cancellation failed.":`Não foi possível cancelar. Confirme se a aplicação das alterações já começou antes de fechar.`,"Takeover failed.":`Não foi possível assumir o controlo. Volte a introduzir o código do terminal de lançamento.`,"Invalid local host or request context.":`O contexto do pedido local foi recusado. Abra o URL exato apresentado no terminal.`,"Invalid request origin.":`O pedido veio de outra origem. Abra o URL local exato do terminal.`,"JSON required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Too many pairing attempts. Restart setup.":`Demasiadas tentativas incorretas de emparelhamento. Reinicie a configuração no terminal.`,"Too many pairing attempts. Wait 30 seconds and retry.":`Demasiadas tentativas incorretas de emparelhamento. Aguarde 30 segundos e volte a introduzir o código; a configuração no terminal continua disponível.`,"Incorrect pairing code. Check the terminal.":`Código de emparelhamento incorreto. Verifique o terminal de lançamento.`,"Incorrect pairing code. Check the launching output.":`Código de emparelhamento incorreto. Verifique a saída de lançamento.`,"Pair this browser using the code printed by the CLI.":`Emparelhe este navegador com o código apresentado pelo CLI.`,"This tab is read-only.":`Este separador é apenas de leitura. Reintroduza o código para assumir o controlo.`,"Invalid answer.":`A resposta é inválida. Reveja a pergunta atual e tente novamente.`,"Control moved to another tab.":`O controlo passou para outro separador. Este é agora apenas de leitura.`,"This question changed. Refresh the current state.":`A pergunta mudou. Atualize a página antes de voltar a responder.`,"This setup has already started applying or ended.":`A configuração já começou a ser aplicada ou terminou. Inspecione o resultado antes de tentar novamente.`,"Only the controller can close a finished session.":`Só o separador que detém o controlo pode fechar esta sessão terminada.`,"Method not allowed.":`Este pedido local não é permitido. Atualize a página.`,"Not found.":`A página local pedida não foi encontrada. Abra o URL apresentado no terminal.`,"Invalid local request.":`O pedido local é inválido. Atualize a página e tente novamente.`,"Body too large.":`A resposta enviada é demasiado longa. Encurte-a e tente novamente.`,"JSON object required.":`O formato do pedido local é inválido. Atualize a página e tente novamente.`,"Could not retry discovery.":`Não foi possível atualizar as sugestões do GitHub. Tente novamente ou introduza dados verificados manualmente.`,"Could not return to the previous question.":`Não foi possível voltar à pergunta anterior. Atualize a página e tente novamente.`,"Invalid question revision.":`A pergunta mudou. Atualize a página antes de voltar atrás.`,"No earlier question is available here.":`Não há uma pergunta anterior nesta etapa. Continue ou volte à revisão do plano.`,"Read-only verification failed.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification failed. Check the terminal.":`A verificação só de leitura falhou. Consulte o terminal e tente mais uma vez.`,"Read-only verification is unavailable or already running.":`A verificação só de leitura não está disponível ou já está em curso. Consulte o resultado antes de tentar novamente.`}};function oc(e,t){let n=ac[t]??ic;return Object.prototype.hasOwnProperty.call(n,e)?n[e]:Q(`unknownLocalError`,t)}var sc=W(`
                                                  `),cc=W(` `,1),lc=W(``),uc=W(`
                                                  `,1),dc=W(`
                                                  `);function fc(e,t){O(t,!1);let n=()=>X(o,`$session`,i),r=()=>X($,`$setupLocale`,i),[i,a]=Ii(),o=Ri();Wr(()=>{let e=$.subscribe(e=>{document.documentElement.lang=e,document.documentElement.dir=`ltr`,document.title=`Copilot · ${Q(`studio`,e)}`}),t=window.setInterval(()=>{n().paired&&!n().view?.outcome&&o.poll()},900);return()=>{window.clearInterval(t),e()}});async function s(){window.confirm(Q(`cancelConfirm`,r()))&&await o.cancel()}async function c(e){let t=n().view?.promptRevision;t!==void 0&&await o.submit(t,e)}async function l(){let e=n().view?.promptRevision;e!==void 0&&await o.retryDiscovery(e)}async function u(){let e=n().view?.promptRevision;e!==void 0&&await o.back(e)}Y();var d=dc(),f=P(d);{let e=A(()=>n().view?.journey);Xi(f,{get journey(){return V(e)}})}var p=L(f,2),m=P(p);{let e=A(()=>n().view?.repository);ra(m,{get repository(){return V(e)}})}var h=L(m,2),g=P(h),_=e=>{{let t=A(()=>Q(`translationPreviewTitle`,r())),n=A(()=>Q(`translationPreviewBody`,r()));Ma(e,{tone:`warning`,get title(){return V(t)},get message(){return V(n)}})}};q(g,e=>{r()!==`en`&&e(_)});var v=L(g,2),y=e=>{Sa(e,{get view(){return n().view}})};q(v,e=>{n().paired&&e(y)});var b=L(v,2),x=e=>{var t=sc(),i=L(P(t));E(t),R(e=>K(i,` ${e??``}`),[()=>Q(`reviewPass`,r(),{pass:String(n().view.journey.choiceReviewPass)})]),G(e,t)};q(b,e=>{n().view?.journey?.choiceReviewPass&&n().view.journey.choiceReviewPass>1&&!n().view.outcome&&e(x)});var S=L(b,2),C=e=>{var t=cc(),i=F(t);{let e=A(()=>Q(`readOnly`,r())),t=A(()=>Q(`readOnlyBody`,r()));Ma(i,{tone:`warning`,get title(){return V(e)},get message(){return V(t)}})}rc(L(i,2),{mode:`takeover`,get busy(){return n().busy},get onPair(){return o.takeOver}}),G(e,t)};q(S,e=>{!n().controller&&n().view&&e(C)});var ee=L(S,2),te=e=>{{let t=A(()=>Q(`attention`,r())),i=A(()=>oc(n().error,r()));Ma(e,{tone:`error`,get title(){return V(t)},get message(){return V(i)}})}};q(ee,e=>{n().error&&e(te)});var ne=L(ee,2),re=e=>{{let t=A(()=>Q(n().view.message.tone===`success`?`checked`:n().view.message.tone===`warning`?`pleaseNote`:n().view.message.tone===`error`?`attention`:`progressUpdate`,r())),i=A(()=>ga(n().view.message,r()));Ma(e,{get tone(){return n().view.message.tone},get title(){return V(t)},get message(){return V(i)},get link(){return n().view.message.link}})}};q(ne,e=>{n().view?.message&&!n().view.outcome&&e(re)});var ie=L(ne,2),ae=e=>{rc(e,{get busy(){return n().busy},get onPair(){return o.pair}})},oe=e=>{Qs(e,{get outcome(){return n().view.outcome},get detail(){return n().view.resultDetail},get doctor(){return n().view.doctor},get controller(){return n().controller},get onDoctor(){return o.runDoctor},get onClose(){return o.close}})},se=e=>{var t=uc(),i=F(t),a=P(i);gs(a,{get prompt(){return n().view.prompt},get revision(){return n().view.revision},get promptRevision(){return n().view.promptRevision},get controller(){return n().controller},get busy(){return n().busy},onSubmit:c,onRetryDiscovery:l,onBack:u}),Us(L(a,2),{get view(){return n().view}}),E(i);var o=L(i,2),d=e=>{var t=lc(),i=I(t,!0);R(e=>{t.disabled=n().busy,K(i,e)},[()=>Q(`cancelSetup`,r())]),Sr(`click`,t,s),G(e,t)};q(o,e=>{n().controller&&n().view.journey?.current!==`Apply`&&e(d)}),G(e,t)},ce=e=>{ec(e,{})};q(ie,e=>{n().paired?n().view?.outcome?e(oe,1):n().view?.prompt?e(se,2):e(ce,-1):e(ae)});var le=L(ie,2),ue=P(le),de=L(ue,2),fe=L(de,2);E(le),E(h),E(p),E(d),R((e,t,n)=>{K(ue,`${e??``} `),K(de,` ${t??``} `),K(fe,` ${n??``}`)},[()=>Q(`footerLocal`,r()),()=>Q(`footerCloud`,r()),()=>Q(`footerGithub`,r())]),G(e,d),k(),a()}Cr([`click`]),zr(fc,{target:document.getElementById(`app`)}); \ No newline at end of file diff --git a/build/web/index.html b/build/web/index.html index bd5bb0dc5..f8628ee10 100644 --- a/build/web/index.html +++ b/build/web/index.html @@ -5,7 +5,7 @@ Copilot · Setup studio - + diff --git a/docs.json b/docs.json index 9adc46c1d..68302b40b 100644 --- a/docs.json +++ b/docs.json @@ -287,6 +287,11 @@ "href": "/development/testing", "icon": "vial" }, + { + "title": "Local setup assistant review", + "href": "/development/setup-assistant-review", + "icon": "clipboard" + }, { "title": "Product specifications", "href": "/development/specifications", diff --git a/docs/authentication.mdx b/docs/authentication.mdx index 86d7e1372..98a1befb9 100644 --- a/docs/authentication.mdx +++ b/docs/authentication.mdx @@ -54,6 +54,10 @@ For Projects, this early choice is only **whether you want the integration**. Listing private organization Projects requires authorization, so the assistant cannot reliably ask you to select Project numbers before the setup PAT exists. If you opt in, the guided setup PAT requests organization **Projects: read**. +The read-only check lists at most one accessible organization Project. A +non-public Project confirms the read grant. If the result contains only public +Projects or is empty, discovery can continue but the PAT grant remains +`Unverifiable`; access to each selected Project is checked again later. After you enter that PAT, the assistant lists the accessible Projects and lets you choose their numeric Project numbers and, when available, their Status options. You can enter a Project URL or number manually if discovery is @@ -108,7 +112,7 @@ these states: |---|---|---| | `✅ Verified` | A safe authentication-bound GitHub operation proved the requested read capability. | Continue. | | `❌ Missing` | GitHub deterministically rejected a required capability after identity and repository access were established. | Stop before the dependent mutation and name the permission to grant. | -| `? Unverifiable` | GitHub does not expose a safe non-mutating proof of the PAT grant, or the response was ambiguous/transient. | Required reads block unless the exact successful public-repository read has separate operational evidence. Required writes pause for a separate explicit acknowledgement and remain non-verified. | +| `? Unverifiable` | GitHub does not expose a safe non-mutating proof of the PAT grant, or the response was ambiguous/transient. | Required reads block unless an exact successful public-repository read or organization Projects list has separate operational evidence. Required writes pause for a separate explicit acknowledgement and remain non-verified. | A `403` is not automatically a missing-permission result. Copilot reports it as `Missing` only when bounded GitHub metadata explicitly identifies a permission @@ -130,6 +134,9 @@ access, so setup requires explicit acknowledgement for those rows. Public organization Issue Types reads remain `Unverifiable` as PAT evidence. After valid token identity, a successful public repository read can be used for that exact operation while its PAT permission row stays `Unverifiable`. +An organization Projects list containing only public Projects, or no Projects, +is similarly usable for discovery without proving the PAT grant. A malformed +or denied Projects response is not usable. The public organization members list can omit concealed members, so it cannot establish Members-read capability. Copilot instead checks the authenticated user's active organization membership through GitHub's permission-bound @@ -271,8 +278,8 @@ For comment-driven assistance, read-only commands are available to anyone who ca Read the required-permissions table before creating the token, then review the permission-check table after entry. A `❌ Missing` required row must be corrected before setup can continue. An ambiguous required - `? Unverifiable` read blocks; only a successful public-repository read can - remain unverified as PAT evidence but operationally usable. A required + `? Unverifiable` read blocks unless a successful public-repository read or + organization Projects list has separate operational evidence. A required write row means to compare the PAT settings with the requested access level and explicitly acknowledge it; it is never a pass. diff --git a/docs/development/architecture.mdx b/docs/development/architecture.mdx index 10c7327b2..5fbac1479 100644 --- a/docs/development/architecture.mdx +++ b/docs/development/architecture.mdx @@ -203,6 +203,18 @@ graph tests reject transitive dependencies from these use cases into CLI, infrastructure, Action, or browser code, and browser components can import only redacted application contracts as types. +`SetupSessionCoordinator` now owns the common repository → choices → setup PAT +→ plan → credentials → Apply sequence for terminal and browser setup. Its +semantic phase ports compose the existing use cases; it checks live-session +state after asynchronous work and classifies a possible write as partial if +the result is unknown. The initial setup workflow emits value-free resource +transitions through an optional progress port. The local Action path passes +those facts to the browser bridge, while the final structured receipt remains +authoritative for completed, skipped, and uncertain resources. The browser +never sees provider request bodies or credential values. +The [fixture-only acceptance review](/development/setup-assistant-review) +records the human browser, language, accessibility, and platform gates. + Inside `web/src`, `App.svelte` is only the page shell. The session client owns same-origin bootstrap, polling and revision-bound commands; it holds no pasted PAT in a store. Presenters in `components/` render progress, prompts, context, diff --git a/docs/development/index.mdx b/docs/development/index.mdx index cd50a5718..4207c1301 100644 --- a/docs/development/index.mdx +++ b/docs/development/index.mdx @@ -34,5 +34,6 @@ Documentation changes must also update `docs.json`, links, component usage, icon - [Build artifacts](/development/build-artifacts) - [Product specifications](/development/specifications) - [Testing](/development/testing) +- [Local setup assistant acceptance review](/development/setup-assistant-review) - [Agents](/agents) - [Security & Operations](/security-operations) diff --git a/docs/development/setup-assistant-review.mdx b/docs/development/setup-assistant-review.mdx new file mode 100644 index 000000000..3dc60e4ea --- /dev/null +++ b/docs/development/setup-assistant-review.mdx @@ -0,0 +1,74 @@ +# Local setup assistant acceptance review + +The [350-case acceptance ledger](../../specs/local-web-setup-assistant-acceptance.json) +is the source of truth for case status. Automated tests establish structural +and behavioral facts. The 40 human rows remain **open** until a reviewer +records the environment and observation for each row. Do not infer a visual, +linguistic, assistive-technology, or operating-system pass from Jest, SSR HTML, +or a screenshot alone. + +## Safe fixture setup + +1. Build the package with `pnpm run build` in a disposable checkout. Do not + run `copilot setup` against this or any other real repository for review. +2. Run `node scripts/serve-web-setup-review.cjs pending`. The script serves + the compiled browser UI and canned redacted views on `127.0.0.1`. It has + no GitHub, filesystem mutation, PAT, Issue, or Action adapter. Open the + printed local URL and enter the printed **fixture** pairing code. +3. Repeat with `action-required`, `blocked`, `partial`, `completed`, + `cancelled`, and `expired`. Stop the previous fixture before switching. + The fixture rejects answer and close commands; use it to review visible + content, navigation, focus and contrast, not to claim a successful setup. +4. Keep the browser console and network panel available. Record any missing + static asset or unintended external request. The GitHub PAT settings link + is informational; do not follow it to create a token for this review. + +## Required observations + +For each of the seven states above, review light and dark modes (`U041–U054`). +At 320 px, tablet width, desktop width, and 200% browser zoom, check that the +status, completed facts, next action, affected resource and inspection action +remain visible without horizontal page scrolling. Verify the focus indicator, +contrast, reduced-motion behavior, headings and landmarks. A screenshot may +supplement the recorded observation but cannot replace keyboard or screen +reader inspection. + +For each of English, Spanish, French and Portuguese, review keyboard order, +screen reader announcements, 200% zoom, 320 px and tablet layouts (`U075–U094`). +Check the pairing field, action-required prompt, progress changes, error text, +resource receipt and PAT cleanup link. Use a named screen reader and browser; +record actual announcements and any field whose label or correction is unclear. +English is the CLI language. Review the CLI's English prompts and result +wording separately. Review the meaning and consistency of the four web +languages with a fluent reviewer; automated key parity is not linguistic +approval. No other web language is in scope. + +On macOS, Linux and Windows, inspect packaged `--web` launch and browser-open +fallback (`I037–I042`) in an isolated fixture repository with fake ports and +no network credentials. Record the package version, OS, Node version, +browser, launcher output, URL, pairing behavior and whether fallback +instructions are usable. The CI fixture jobs check build and local server +behavior, but they do not replace these desktop observations. Do not use this +project or a live GitHub repository as a setup target. + +Controlled GitHub account switching, 2FA on GitHub, wrong-account handling, +and PAT deletion require a separate authorized human review with test accounts +outside this repository. They remain open here. Never create a real PAT, test +Issue, or Action run to fill a ledger row in this task. + +## Evidence record + +For each human row, record: + +| Field | Required content | +|---|---| +| Case ID | Exact `U` or `I` ID from the ledger | +| Reviewer and date | Person who performed the observation and local date | +| Environment | OS/version, browser/version, viewport, zoom, palette, locale, screen reader/version when relevant | +| Fixture | One of the seven states and the local build/commit ID | +| Observation | What was read, announced, focused or blocked; include the expected next action | +| Result | Pass or fail with a link to a redacted screenshot/recording if useful | + +Update the ledger row only after direct observation. A pass needs all fields; +leave it open when a platform, assistive technology or language reviewer is +unavailable. Run `pnpm run validate:setup-acceptance` after editing it. diff --git a/docs/how-to-use.mdx b/docs/how-to-use.mdx index fe2a90ce4..0c6784944 100644 --- a/docs/how-to-use.mdx +++ b/docs/how-to-use.mdx @@ -68,6 +68,11 @@ already deleted the setup PAT in GitHub, run `copilot doctor --read-only` with a valid setup PAT instead. A failed or partial Apply does not offer this button: inspect the itemized result and use the CLI command after resolving the uncertain resources. +While Apply runs, the page reports each resource as in progress and then as +completed, skipped, or needing inspection. If the process stops mid-write, +the operation may already have reached GitHub; inspect that resource before +starting a new setup session. A new process always requires a fresh review +and approval. The language selector starts in English and offers Spanish, French, and Portuguese. Switching language does not change the repository locale or reset your answers. Question headings, explanations, options, permission details, diff --git a/docs/security-operations/operations/troubleshooting.mdx b/docs/security-operations/operations/troubleshooting.mdx index ec39ba44a..3f0ef7e9b 100644 --- a/docs/security-operations/operations/troubleshooting.mdx +++ b/docs/security-operations/operations/troubleshooting.mdx @@ -28,14 +28,21 @@ not imply a setup failure: open the exact `127.0.0.1` URL printed by the CLI. Enter the terminal's 16-character pairing code in the page; after a refresh, enter it again. Do not share the code. TCP loopback can be reached by other local OS users; the code, not the public URL or OS-user identification, grants -access to this setup session. After five wrong codes, restart setup. +access to this setup session. After five wrong codes, pairing and takeover +pause for 30 seconds; wait, then retry the code printed by the launcher. If the local bind or bundled assets fail, stop and use `copilot setup` in the terminal. A second browser tab is read-only until you select **Take control in this tab**; the former tab then cannot submit decisions. A rejected stale answer means the page should refresh to the current decision, not replay it. -If the page closes during Apply, inspect the terminal result and run -`copilot doctor` before retrying; do not assume that completed local or remote -writes were rolled back. No local session shutdown revokes a PAT in GitHub. +If the page closes during Apply, reopen it and pair with the launching +terminal's code while that process is alive. The per-resource progress view +shows completed, skipped, in-progress, and uncertain operations. If the +process exits during a write, treat its result as needing inspection: check +the local checkout and corresponding GitHub resource names/scopes, then run +`copilot doctor --read-only` with a valid setup PAT before retrying. The +previous approval and secrets are not restored by a new process. Completed +local or remote writes are not rolled back. No local session shutdown revokes +a PAT in GitHub. If setup reports a lock belonging to a stopped process, it will not delete that lock automatically: another setup could have acquired the same path in @@ -59,6 +66,13 @@ directory. The lock contains no PAT or other credential. + In the web assistant, a PAT-related blocked result lists the required + grants that could not be confirmed, including scope, access level, and + status. It does not display the PAT. The terminal's aggregate error alone + may not name the grant; use the browser result before closing the local + session. If GitHub identity itself was rejected, fix account, repository + selection, token expiry, or organization approval before reviewing grants. + **`❌ Missing`:** GitHub rejected a safe read-only capability probe after setup confirmed the token identity and repository selection. Grant the named repository or organization permission to the correct resource owner, ensure @@ -89,6 +103,10 @@ directory. The lock contains no PAT or other credential. workflow files remain `Unverifiable` unless repository metadata proves the repository is private. Public organization member and issue-type responses are likewise inconclusive as PAT evidence or full-membership readiness. + An organization Projects list with only public Projects, or no Projects, + can support discovery while the `Projects: read` grant remains + `Unverifiable`; a non-public Project proves that read access. A denied or + malformed list still blocks and must be corrected or retried. Members read is verified only by a valid active self-membership response from the permission-bound endpoint; Issue Types, ambiguous responses, and writes remain blocking. diff --git a/docs/security-operations/security/self-hosted-runners.mdx b/docs/security-operations/security/self-hosted-runners.mdx index a1762ecec..896b302ad 100644 --- a/docs/security-operations/security/self-hosted-runners.mdx +++ b/docs/security-operations/security/self-hosted-runners.mdx @@ -16,6 +16,16 @@ A self-hosted runner that can access agent credentials MUST be dedicated or isol A shared persistent runner is not equivalent to an ephemeral trusted runner. +The `codex` label can route a job to macOS, Windows or Linux. Install Git and +Bash on every runner; Windows needs Git for Windows with its Bash available to +the Actions runner service. Installed workflows select `shell: bash` for +`run` steps so Windows does not create PowerShell scripts subject to local +execution policy. Keep Node.js 24 and pnpm provisioning available to jobs that +build the Action. Verify each operating system with an actual runner job before +claiming Action-wide compatibility; the setup fixture matrix exercises only +its isolated setup paths. In particular, inspect timeout and cancellation of +agent child processes on Windows separately from POSIX process-group behavior. + The Action passes agent children an allowlisted runtime environment plus only the credential selected for that provider; unrelated GitHub, cloud, database, and PAT variables are not inherited. Codex review capabilities are forced to `--sandbox read-only --ignore-user-config --ignore-rules`; fixer capabilities use `workspace-write`, with network and extra writable roots disabled. Cursor receives a per-invocation configuration/home with sandboxing and default-deny network policy. OpenCode receives a pure, inline default-deny permission profile with shell, task, skill, web, and external-directory tools disabled. Dangerous bypass flags are rejected for every runtime. These controls complement rather than replace runner/container isolation. Configured verification commands also receive a temporary `HOME` and credential-free allowlisted environment. They are repository processes, not model tools, so the runner must still prevent them from reading unrelated host paths through OS-level isolation. diff --git a/package.json b/package.json index 337d56ffa..769011fde 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "node": ">=24" }, "scripts": { - "build": "node scripts/clean-generated-bundles.cjs && pnpm run build:web && ncc build src/actions/github_action.ts -o build/github_action && ncc build src/cli.ts -o build/cli && ncc build src/api.ts -o build/api && node scripts/prepare-generated-bundles.cjs && chmod +x build/cli/index.js", + "build": "node scripts/clean-generated-bundles.cjs && pnpm run build:web && ncc build src/actions/github_action.ts -o build/github_action && ncc build src/cli.ts -o build/cli && ncc build src/api.ts -o build/api && node scripts/prepare-generated-bundles.cjs && node scripts/set-cli-executable.cjs", "build:web": "vite build --config web/vite.config.mts", "check:web": "svelte-check --tsconfig web/tsconfig.json && vite build --config web/vite.config.mts", "validate:build": "node scripts/validate-build.cjs", @@ -57,7 +57,7 @@ "smoke:npm-package": "node scripts/smoke-test-npm-package.cjs", "test": "jest", "test:watch": "jest --watch", - "test:coverage": "jest --coverage && node scripts/validate-coverage-budgets.cjs", + "test:coverage": "jest --coverage --json --outputFile=coverage/setup-acceptance-jest.json && node scripts/validate-coverage-budgets.cjs && node scripts/validate-setup-assistant-acceptance.cjs coverage/setup-acceptance-jest.json", "eval:bugbot": "jest src/tooling/__tests__/bugbot_quality_eval.test.ts src/tooling/__tests__/bugbot_benchmark.test.ts --runInBand", "typecheck": "tsc --noEmit", "metrics:architecture": "node scripts/collect-architecture-metrics.cjs", @@ -68,6 +68,7 @@ "validate:workflows": "node scripts/validate-workflow-contract.cjs", "generate:specifications": "node scripts/validate-specification-catalog.cjs --write && node scripts/validate-github-communication-test-budget.cjs", "validate:specifications": "node scripts/validate-specification-catalog.cjs && node scripts/validate-github-communication-test-budget.cjs", + "validate:setup-acceptance": "node scripts/validate-setup-assistant-acceptance.cjs", "lint:fix": "eslint src --fix", "postinstall": "node scripts/install-git-hooks.cjs" }, diff --git a/scripts/npm-pack-command.cjs b/scripts/npm-pack-command.cjs new file mode 100644 index 000000000..f9ef4ffe3 --- /dev/null +++ b/scripts/npm-pack-command.cjs @@ -0,0 +1,13 @@ +const { execFileSync } = require('node:child_process'); +const path = require('node:path'); + +function runNpmPack(args, options) { + if (process.platform === 'win32') { + // npm.cmd cannot be executed by execFile without a shell on Windows. + const npmCli = path.join(path.dirname(process.execPath), 'node_modules', 'npm', 'bin', 'npm-cli.js'); + return execFileSync(process.execPath, [npmCli, 'pack', ...args], options); + } + return execFileSync('npm', ['pack', ...args], options); +} + +module.exports = { runNpmPack }; diff --git a/scripts/serve-web-setup-review.cjs b/scripts/serve-web-setup-review.cjs new file mode 100644 index 000000000..0c3c87ebe --- /dev/null +++ b/scripts/serve-web-setup-review.cjs @@ -0,0 +1,89 @@ +#!/usr/bin/env node +/** Read-only browser review fixture. No repository, token or GitHub adapter is loaded. */ +const { createServer } = require('node:http'); +const { readFileSync, realpathSync } = require('node:fs'); +const { join, sep } = require('node:path'); + +const states = new Set(['pending', 'action-required', 'blocked', 'partial', 'completed', 'cancelled', 'expired']); +const selected = process.argv[2]; +if (!states.has(selected)) { + console.error(`Choose one fixture state: ${[...states].join(', ')}`); + process.exit(2); +} +const assetRoot = realpathSync(join(__dirname, '..', 'build', 'web')); +const html = readFileSync(join(assetRoot, 'index.html')); +const assets = new Set([...html.toString().matchAll(/(?:\.\/)?(assets\/[A-Za-z0-9._-]+\.(?:js|css))/g)].map(match => `/${match[1]}`)); +if (assets.size < 2) throw new Error('Build the web assets before reviewing fixtures.'); +const code = '0123456789abcdef'; // A public fixture value, never a real setup credential. +const key = 'f'.repeat(64); + +function view() { + const terminal = !['pending', 'action-required'].includes(selected); + const outcome = selected === 'completed' ? 'complete' : selected === 'expired' || selected === 'blocked' + ? 'blocked' : selected === 'partial' ? 'partial' : selected === 'cancelled' ? 'cancelled' : undefined; + const mutationStarted = selected === 'partial' || selected === 'completed'; + const current = selected === 'pending' ? 'Plan' : 'Apply'; + const effects = mutationStarted ? [ + { id: 'files', state: 'completed', scope: 'local' }, + { id: 'secrets', state: selected === 'partial' ? 'needs-inspection' : 'completed', scope: 'repository' }, + { id: 'labels', state: selected === 'partial' ? 'not-started' : 'skipped', scope: 'repository' }, + ] : undefined; + return { + revision: 1, repository: 'fixture-owner/fixture-repo', + journey: { repository: 'fixture-owner/fixture-repo', position: selected === 'pending' ? 4 : 6, + total: 6, current, complete: ['Repository', 'Setup choices', 'Setup PAT'], pending: [], + mutationStarted, choiceReviewPass: 1, ...(outcome ? { outcome } : {}) }, + ...(selected === 'action-required' ? { promptRevision: 1, prompt: { + kind: 'confirm', title: 'Apply this setup now?', copyId: 'apply.confirm', + choices: ['Apply setup', 'Stop without applying'], + } } : {}), + ...(terminal ? { outcome, resultDetail: { + reasonCode: selected === 'expired' ? 'session-expired' : selected === 'cancelled' ? 'cancelled' + : selected === 'blocked' ? 'permissions' : 'unknown', + stoppedStage: current, mutationStarted, ...(effects ? { effects } : {}), + } } : {}), + }; +} + +function reply(response, status, body) { + response.writeHead(status, { 'Content-Type': 'application/json; charset=utf-8', 'Cache-Control': 'no-store' }); + response.end(JSON.stringify(body)); +} + +const server = createServer((request, response) => { + const address = server.address(); + const host = `127.0.0.1:${address.port}`; + if (request.headers.host !== host) return reply(response, 403, { error: 'Local fixture only.' }); + if (request.method === 'GET' && request.url === '/') { + response.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8', 'Cache-Control': 'no-store' }); + response.end(html); + return; + } + if (request.method === 'GET' && assets.has(request.url)) { + const file = realpathSync(join(assetRoot, request.url.slice(1))); + if (!file.startsWith(`${assetRoot}${sep}`)) return reply(response, 403, { error: 'Invalid asset.' }); + response.writeHead(200, { 'Content-Type': file.endsWith('.css') ? 'text/css' : 'text/javascript', 'Cache-Control': 'no-store' }); + response.end(readFileSync(file)); + return; + } + if (request.method === 'POST' && request.url === '/api/pair') { + if (request.headers.origin !== `http://${host}`) return reply(response, 403, { error: 'Invalid origin.' }); + let body = ''; + request.on('data', chunk => { body += chunk; if (body.length > 1024) request.destroy(); }); + request.on('end', () => { + try { return reply(response, JSON.parse(body).code === code ? 200 : 403, + JSON.parse(body).code === code ? { sessionKey: key } : { error: 'Use the fixture code printed in the terminal.' }); } + catch { return reply(response, 400, { error: 'Invalid fixture request.' }); } + }); + return; + } + if (request.headers['x-setup-session-key'] !== key) return reply(response, 403, { error: 'Pair the fixture browser.' }); + if (request.method === 'GET' && request.url === '/api/bootstrap') return reply(response, 200, { controller: true, capability: 'e'.repeat(64) }); + if (request.method === 'GET' && request.url === '/api/state') return reply(response, 200, view()); + reply(response, 409, { error: 'Read-only review fixture; no setup action is available.' }); +}); +server.listen(0, '127.0.0.1', () => { + console.log(`Read-only ${selected} fixture: http://127.0.0.1:${server.address().port}/`); + console.log(`Fixture pairing code: ${code}`); + console.log('Press Ctrl+C to stop. This server cannot run setup.'); +}); diff --git a/scripts/set-cli-executable.cjs b/scripts/set-cli-executable.cjs new file mode 100644 index 000000000..cbf986331 --- /dev/null +++ b/scripts/set-cli-executable.cjs @@ -0,0 +1,7 @@ +const { chmodSync } = require('node:fs'); +const { join } = require('node:path'); + +// Windows uses the npm-generated command shim; POSIX launches the bundle. +if (process.platform !== 'win32') { + chmodSync(join(__dirname, '..', 'build', 'cli', 'index.js'), 0o755); +} diff --git a/scripts/setup-acceptance-path.cjs b/scripts/setup-acceptance-path.cjs new file mode 100644 index 000000000..acdc38da9 --- /dev/null +++ b/scripts/setup-acceptance-path.cjs @@ -0,0 +1,8 @@ +const path = require('node:path'); + +/** Match Jest's absolute suite path to the repository-relative ledger on any host. */ +function relativeJestSuitePath(root, suite, pathApi = path) { + return pathApi.relative(root, suite).split(pathApi.sep).join('/'); +} + +module.exports = { relativeJestSuitePath }; diff --git a/scripts/smoke-test-npm-package.cjs b/scripts/smoke-test-npm-package.cjs index ef9ea1b5d..2f094af36 100644 --- a/scripts/smoke-test-npm-package.cjs +++ b/scripts/smoke-test-npm-package.cjs @@ -4,15 +4,14 @@ const { execFileSync } = require('node:child_process'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); +const { runNpmPack } = require('./npm-pack-command.cjs'); const repositoryRoot = path.resolve(__dirname, '..'); const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'copilot-npm-smoke-')); try { - const output = execFileSync( - 'npm', + const output = runNpmPack( [ - 'pack', '--json', '--ignore-scripts', '--pack-destination', @@ -57,6 +56,11 @@ try { if (!fs.existsSync(webIndexPath) || !fs.readFileSync(webIndexPath, 'utf8').includes('/assets/')) { throw new Error('Packaged local web setup assets are missing or incomplete.'); } + const webAssets = [...fs.readFileSync(webIndexPath, 'utf8').matchAll(/(?:\.\/)?(assets\/[A-Za-z0-9._-]+\.(?:js|css))/g)] + .map(match => match[1]); + if (webAssets.length < 2 || webAssets.some(asset => !fs.statSync(path.join(packageRoot, 'build', 'web', asset)).isFile())) { + throw new Error('Packaged local web setup asset paths do not resolve from the extracted tarball.'); + } if (version !== packageJson.version) { throw new Error(`CLI reported ${version}, expected ${packageJson.version}.`); } @@ -86,7 +90,7 @@ try { const consumerRoot = path.join(temporaryDirectory, 'consumer'); const packageScope = path.join(consumerRoot, 'node_modules', '@vypdev'); fs.mkdirSync(packageScope, { recursive: true }); - fs.symlinkSync(packageRoot, path.join(packageScope, 'copilot'), 'dir'); + fs.symlinkSync(packageRoot, path.join(packageScope, 'copilot'), process.platform === 'win32' ? 'junction' : 'dir'); fs.writeFileSync(path.join(consumerRoot, 'index.ts'), [ "import { BugbotReviewService, type BugbotReviewConfiguration, type BugbotScmGateway } from '@vypdev/copilot/bugbot';", "const configuration: Partial = { effort: 'smart' };", diff --git a/scripts/validate-npm-package.cjs b/scripts/validate-npm-package.cjs index 20c557fc3..5ec818f86 100644 --- a/scripts/validate-npm-package.cjs +++ b/scripts/validate-npm-package.cjs @@ -1,9 +1,9 @@ #!/usr/bin/env node -const { execFileSync } = require('node:child_process'); const fs = require('node:fs'); const os = require('node:os'); const path = require('node:path'); +const { runNpmPack } = require('./npm-pack-command.cjs'); const repositoryRoot = path.resolve(__dirname, '..'); const packagePath = path.join(repositoryRoot, 'package.json'); @@ -87,10 +87,8 @@ if (fs.existsSync(cliPath)) { const temporaryDirectory = fs.mkdtempSync(path.join(os.tmpdir(), 'copilot-npm-pack-')); try { - const output = execFileSync( - 'npm', + const output = runNpmPack( [ - 'pack', '--dry-run', '--json', '--ignore-scripts', @@ -115,6 +113,11 @@ try { for (const asset of referencedAssets) { if (!packageFiles.has(asset)) error(`npm package is missing referenced web asset ${asset}.`); } + const packagedWebAssets = [...packageFiles].filter(file => file.startsWith('build/web/assets/')); + if (packagedWebAssets.length !== referencedAssets.length + || packagedWebAssets.some(asset => !referencedAssets.includes(asset))) { + error('npm package web assets must match exactly the JS/CSS files referenced by the web index.'); + } if ([...packageFiles].some(file => file.startsWith('build/web/') && file.endsWith('.map'))) { error('npm package must not include web source maps.'); } diff --git a/scripts/validate-setup-assistant-acceptance.cjs b/scripts/validate-setup-assistant-acceptance.cjs new file mode 100644 index 000000000..f6a2c101d --- /dev/null +++ b/scripts/validate-setup-assistant-acceptance.cjs @@ -0,0 +1,53 @@ +const { readFileSync, existsSync } = require('node:fs'); +const { join, resolve } = require('node:path'); +const { relativeJestSuitePath } = require('./setup-acceptance-path.cjs'); + +const root = resolve(__dirname, '..'); +const ledger = JSON.parse(readFileSync(join(root, 'specs/local-web-setup-assistant-acceptance.json'), 'utf8')); +const jestResultPath = process.argv[2]; +const jestResults = jestResultPath ? JSON.parse(readFileSync(resolve(jestResultPath), 'utf8')) : undefined; +const executedTests = new Map(); +for (const suite of jestResults?.testResults ?? []) { + const file = relativeJestSuitePath(root, suite.name); + for (const test of suite.assertionResults ?? []) executedTests.set(`${file}::${test.fullName}`, test.status); +} +const counts = { P: 48, S: 54, A: 40, C: 37, U: 101, I: 42, X: 28 }; +const expected = Object.entries(counts).flatMap(([prefix, count]) => Array.from({ length: count }, (_, index) => + `${prefix}${String(index + 1).padStart(3, '0')}`)); +const actual = ledger.cases.map(item => item.id); +const errors = []; +if (actual.length !== 350) errors.push(`expected 350 cases, found ${actual.length}`); +if (new Set(actual).size !== actual.length) errors.push('case IDs are not unique'); +for (const id of expected) if (!actual.includes(id)) errors.push(`missing ${id}`); +for (const id of actual) if (!expected.includes(id)) errors.push(`unexpected ${id}`); +const evidenceKeys = new Set(); +for (const item of ledger.cases) { + if (typeof item.assertion !== 'string' || item.assertion.length < 20) errors.push(`${item.id}: assertion is too vague`); + if (!['pass', 'open'].includes(item.status)) errors.push(`${item.id}: invalid status`); + if (item.evidence?.kind === 'jest') { + if (typeof item.evidence.file !== 'string' || !existsSync(join(root, item.evidence.file))) errors.push(`${item.id}: missing test file`); + if (typeof item.evidence.test !== 'string' || item.evidence.test.length < 15) errors.push(`${item.id}: missing test name`); + const key = `${item.evidence.file}::${item.evidence.test}`; + if (evidenceKeys.has(key)) errors.push(`${item.id}: duplicate test evidence`); + evidenceKeys.add(key); + if (jestResults && executedTests.get(key) !== 'passed') errors.push(`${item.id}: named Jest assertion did not pass in ${jestResultPath}`); + } else if (item.evidence?.kind === 'command') { + if (typeof item.evidence.command !== 'string' || !/^pnpm run (?:build|validate:npm-package|smoke:npm-package)$/u.test(item.evidence.command)) { + errors.push(`${item.id}: invalid package validation command`); + } + if (item.status === 'pass' && (!item.evidence.date || !item.evidence.observation || item.evidence.observation.startsWith('Awaiting'))) { + errors.push(`${item.id}: command pass lacks dated observed evidence`); + } + } else if (item.evidence?.kind === 'human') { + if (item.status === 'pass' && (!item.evidence.reviewer || !item.evidence.date || !item.evidence.environment || !item.evidence.observation)) { + errors.push(`${item.id}: human pass lacks recorded reviewer, date, environment or observation`); + } + if (typeof item.evidence.checklist !== 'string' || item.evidence.checklist.length < 20) errors.push(`${item.id}: human checklist is missing`); + } else errors.push(`${item.id}: invalid evidence kind`); +} +if (errors.length) { + for (const error of errors) console.error(error); + process.exit(1); +} +const passed = ledger.cases.filter(item => item.status === 'pass').length; +console.log(`Setup acceptance ledger: ${passed}/350 passed; ${350 - passed} explicitly open.`); diff --git a/scripts/validate-workflow-contract.cjs b/scripts/validate-workflow-contract.cjs index a744b1ef8..f08660227 100644 --- a/scripts/validate-workflow-contract.cjs +++ b/scripts/validate-workflow-contract.cjs @@ -208,6 +208,14 @@ function runnerLabels(value) { function assertRunner(file, workflow) { const relativeFile = relativeWorkflow(file); for (const [jobId, job] of Object.entries(workflow.jobs ?? {})) { + if (relativeFile === '.github/workflows/setup_platform_smoke.yml') { + const platforms = job.strategy?.matrix?.os; + if (jobId !== 'setup-platform-smoke' || job['runs-on'] !== '${{ matrix.os }}' + || JSON.stringify(platforms) !== JSON.stringify(['ubuntu-latest', 'windows-latest', 'macos-latest'])) { + throw new Error(`${relativeFile} must use the Ubuntu, Windows and macOS setup fixture matrix.`); + } + continue; + } const expected = relativeFile.startsWith('setup/workflows/') || relativeFile === '.github/workflows/copilot_pull_request_approval.yml' ? ['ubuntu-latest'] @@ -993,6 +1001,25 @@ function assertIncrementalRangeFetch(relativeFile, manifestFile, job) { } } +function assertPortableRunShell(file, workflow) { + const relativeFile = relativeWorkflow(file); + for (const [jobId, job] of Object.entries(workflow.jobs ?? {})) { + const isCodexRunner = relativeFile.startsWith('.github/workflows/') + && runnerLabels(job['runs-on']).includes('codex'); + const isDistributedReviewRange = relativeFile === 'setup/workflows/copilot_commit.yml' + || relativeFile === 'setup/workflows/copilot_pull_request.yml'; + const isSetupPlatformSmoke = relativeFile === '.github/workflows/setup_platform_smoke.yml'; + if (!isCodexRunner && !isDistributedReviewRange && !isSetupPlatformSmoke) continue; + for (const [stepIndex, step] of (job.steps ?? []).entries()) { + if (typeof step?.run !== 'string') continue; + const shell = step.shell ?? job.defaults?.run?.shell ?? workflow.defaults?.run?.shell; + if (shell !== 'bash') { + throw new Error(`${relativeFile} job ${jobId} step ${stepIndex + 1} must select shell: bash for portable run execution.`); + } + } + } +} + function assertSequentialMutationWorkflow(file, workflow) { const relativeFile = relativeWorkflow(file); if (!QUEUE_WORKFLOW_MANIFEST.some(entry => relativeFile.endsWith(`/${entry.file}`))) return; @@ -1017,6 +1044,7 @@ function validateWorkflow(file, workflow) { assertApprovalObserverWorkflow(file, workflow); assertPullRequestMergeQueueWorkflow(file, workflow); assertRunner(file, workflow); + assertPortableRunShell(file, workflow); assertSequentialMutationWorkflow(file, workflow); assertAgentInputs(file, workflow); assertRepositoryLocaleInputs(file, workflow); @@ -1089,6 +1117,7 @@ module.exports = { assertQueueWorkflow, assertIncrementalRangeFetch, assertRunner, + assertPortableRunShell, assertSequentialMutationWorkflow, assertDeploymentContinuationWorkflow, assertMergeQueueWorkflowSupport, diff --git a/setup/workflows/copilot_commit.yml b/setup/workflows/copilot_commit.yml index f0b38ce58..28b4adffa 100644 --- a/setup/workflows/copilot_commit.yml +++ b/setup/workflows/copilot_commit.yml @@ -31,6 +31,7 @@ jobs: node-version: '24.x' - name: Fetch push review range + shell: bash if: github.event.after != '0000000000000000000000000000000000000000' env: BEFORE_SHA: ${{ github.event.before }} diff --git a/setup/workflows/copilot_pull_request.yml b/setup/workflows/copilot_pull_request.yml index 613e8381e..e5887ae71 100644 --- a/setup/workflows/copilot_pull_request.yml +++ b/setup/workflows/copilot_pull_request.yml @@ -30,6 +30,7 @@ jobs: node-version: '24.x' - name: Fetch incremental review range + shell: bash if: github.event.action == 'synchronize' env: BEFORE_SHA: ${{ github.event.before }} diff --git a/specs/CATALOG.md b/specs/CATALOG.md index 8a433520d..a8c7ccaa9 100644 --- a/specs/CATALOG.md +++ b/specs/CATALOG.md @@ -16,8 +16,8 @@ debt or convert unknown historic intent into a design decision. | `bugbot-review-state-reconciliation` | Implemented | Reconcile review snapshots, findings, threads, comments, and check conclusions | [Bugbot review-state reconciliation](./bugbot-review-state-reconciliation.md) | 57 paths · 2026-09-24 | | `execution-lifecycle` | Implemented | Shared GitHub Action lifecycle from event admission through durable user-facing results | [Execution admission, queueing, routing, and result publication](./execution-admission-queue-and-publication.md) + 3 companion | 84 paths · 2026-09-16 | | `architecture-quality-hardening` | Implemented | Close verified concurrency, error-contract, context-coupling, fan-out, setup/doctor, and provider-policy risks in dependency order | [Architecture quality and scalability hardening](./architecture-quality-and-scalability-hardening.md) + 1 companion | 72 paths · 2026-09-16 | -| `setup-and-doctor` | Implemented | Plan, validate, provision, and audit a repository installation without exposing credentials | [Setup, configuration, credentials, and doctor](./setup-configuration-credentials-and-doctor.md) + 2 companion | 90 paths · 2026-09-28 | -| `local-web-setup-assistant` | Proposed | Offer a packaged, loopback-only Svelte setup interface over the existing engine with four-language guidance, English CLI help, basic/custom first-run paths, editable question and plan review, source-labelled GitHub facts, assisted CI and Project evidence, role-separated PATs, and truthful itemized outcomes | [Local web setup assistant](./local-web-setup-assistant.md) | 121 paths · 2026-09-29 | +| `setup-and-doctor` | Implemented | Plan, validate, provision, and audit a repository installation without exposing credentials | [Setup, configuration, credentials, and doctor](./setup-configuration-credentials-and-doctor.md) + 2 companion | 94 paths · 2026-10-02 | +| `local-web-setup-assistant` | Proposed | Offer a packaged, loopback-only Svelte setup interface over the existing engine with four-language guidance, English CLI help, basic/custom first-run paths, editable question and plan review, source-labelled GitHub facts, assisted CI and Project evidence, role-separated PATs, and truthful itemized outcomes | [Local web setup assistant](./local-web-setup-assistant.md) | 141 paths · 2026-10-02 | | `guided-bot-pat-onboarding` | Proposed | Guide creation of the persistent workflow PAT using GitHub's official form, verify bot identity and grants, and install the approved Actions Secret | [Guided bot PAT onboarding](./guided-bot-pat-onboarding.md) | 25 paths · 2026-09-25 | | `temporary-setup-operator-authorization` | Proposed | Guide creation of the one-run operator PAT through GitHub's official form, verify final setup access, and report user-owned deletion accurately | [Assisted setup PAT creation](./temporary-setup-operator-authorization.md) | 28 paths · 2026-09-25 | | `issue-start-and-sdd-readiness` | Implemented | Start every admitted issue with one explicit signal and publish a validated SDD before eligible Action-managed branch work | [Uniform issue start and pre-branch SDD readiness](./issue-start-and-branch-readiness.md) + 1 companion | 51 paths · 2026-09-17 | @@ -103,24 +103,24 @@ debt or convert unknown historic intent into a design decision. ### `setup-and-doctor` — Setup, configuration, credentials, and doctor - Owner: Copilot maintainers -- Last verified: 2026-09-28 +- Last verified: 2026-10-02 - Specifications: [`specs/setup-configuration-credentials-and-doctor.md`](./setup-configuration-credentials-and-doctor.md) · [`specs/setup-doctor-architecture-hardening.md`](./setup-doctor-architecture-hardening.md) · [`specs/setup-pat-permission-guidance-and-verification.md`](./setup-pat-permission-guidance-and-verification.md) - Workflows: [`setup/workflows/agent-cli-provisioning.yml`](../setup/workflows/agent-cli-provisioning.yml) · [`setup/workflows/copilot_credential_health.yml`](../setup/workflows/copilot_credential_health.yml) - Entrypoints: [`src/cli/commands/setup.ts`](../src/cli/commands/setup.ts) · [`src/cli/commands/doctor.ts`](../src/cli/commands/doctor.ts) -- Core code: [`src/domain/setup.ts`](../src/domain/setup.ts) · [`src/domain/setup_questionnaire.ts`](../src/domain/setup_questionnaire.ts) · [`src/domain/setup_token_permissions.ts`](../src/domain/setup_token_permissions.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/ports/setup_wizard_ports.ts`](../src/application/ports/setup_wizard_ports.ts) · [`src/application/ports/setup_token_permission_ports.ts`](../src/application/ports/setup_token_permission_ports.ts) · [`src/application/policies/setup_token_permission_evidence_policy.ts`](../src/application/policies/setup_token_permission_evidence_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/setup_configuration_storage_policy.ts`](../src/application/policies/setup_configuration_storage_policy.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/application/policies/setup_doctor_report_policy.ts`](../src/application/policies/setup_doctor_report_policy.ts) · [`src/application/policies/setup_journey_policy.ts`](../src/application/policies/setup_journey_policy.ts) · [`src/application/policies/setup_permission_summary_policy.ts`](../src/application/policies/setup_permission_summary_policy.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/usecases/setup/setup_token_permissions_use_case.ts`](../src/application/usecases/setup/setup_token_permissions_use_case.ts) · [`src/application/usecases/setup/doctor_use_case.ts`](../src/application/usecases/setup/doctor_use_case.ts) · [`src/application/usecases/setup/merge_queue_readiness_use_case.ts`](../src/application/usecases/setup/merge_queue_readiness_use_case.ts) · [`src/application/usecases/actions/initial_setup_workflow.ts`](../src/application/usecases/actions/initial_setup_workflow.ts) · [`src/application/usecases/actions/setup_resource_provisioning.ts`](../src/application/usecases/actions/setup_resource_provisioning.ts) · [`src/application/ports/message_catalog_ports.ts`](../src/application/ports/message_catalog_ports.ts) · [`src/application/usecases/localization/resolve_message_catalog_use_case.ts`](../src/application/usecases/localization/resolve_message_catalog_use_case.ts) · [`src/application/policies/setup_configuration_validation.ts`](../src/application/policies/setup_configuration_validation.ts) · [`src/infrastructure/setup_workspace_adapter.ts`](../src/infrastructure/setup_workspace_adapter.ts) · [`src/data/repository/repository_variables_repository.ts`](../src/data/repository/repository_variables_repository.ts) · [`src/infrastructure/github/ports/github_repository_variables_protocol.ts`](../src/infrastructure/github/ports/github_repository_variables_protocol.ts) · [`src/infrastructure/setup_remote_credential_health_adapter.ts`](../src/infrastructure/setup_remote_credential_health_adapter.ts) · [`src/infrastructure/setup_credential_validation_adapter.ts`](../src/infrastructure/setup_credential_validation_adapter.ts) · [`src/infrastructure/setup_token_permission_query_adapter.ts`](../src/infrastructure/setup_token_permission_query_adapter.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/cli/setup_journey_presenter.ts`](../src/cli/setup_journey_presenter.ts) · [`src/cli/setup_plan_presenter.ts`](../src/cli/setup_plan_presenter.ts) · [`src/cli/setup_doctor_presenter.ts`](../src/cli/setup_doctor_presenter.ts) · [`src/cli/setup_prompt_rendering.ts`](../src/cli/setup_prompt_rendering.ts) · [`src/cli/setup_credential_prompt_adapter.ts`](../src/cli/setup_credential_prompt_adapter.ts) · [`src/cli/setup_token_permission_presenter.ts`](../src/cli/setup_token_permission_presenter.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`src/infrastructure/composition/setup_token_permissions_composition_root.ts`](../src/infrastructure/composition/setup_token_permissions_composition_root.ts) · [`src/infrastructure/composition/setup_doctor_composition_root.ts`](../src/infrastructure/composition/setup_doctor_composition_root.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/documentation_pat_exception_policy.cjs`](../scripts/documentation_pat_exception_policy.cjs) · [`scripts/validate-documentation-contract.cjs`](../scripts/validate-documentation-contract.cjs) -- Tests: [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_configuration_policy.test.ts`](../src/application/policies/__tests__/setup_configuration_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/policies/__tests__/setup_doctor_message_catalog.test.ts`](../src/application/policies/__tests__/setup_doctor_message_catalog.test.ts) · [`src/application/policies/__tests__/setup_doctor_report_policy.test.ts`](../src/application/policies/__tests__/setup_doctor_report_policy.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts) · [`src/application/usecases/setup/__tests__/doctor_use_case.test.ts`](../src/application/usecases/setup/__tests__/doctor_use_case.test.ts) · [`src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts`](../src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts) · [`src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts`](../src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts) · [`src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts`](../src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts) · [`src/infrastructure/__tests__/setup_workspace_adapter.test.ts`](../src/infrastructure/__tests__/setup_workspace_adapter.test.ts) · [`src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts`](../src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts) · [`src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts`](../src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts) · [`src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts`](../src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts) · [`src/data/repository/__tests__/repository_variables_repository.test.ts`](../src/data/repository/__tests__/repository_variables_repository.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/setup_journey_presenter.test.ts`](../src/cli/__tests__/setup_journey_presenter.test.ts) · [`src/cli/__tests__/setup_prompt_rendering.test.ts`](../src/cli/__tests__/setup_prompt_rendering.test.ts) · [`src/cli/__tests__/setup_token_permission_presenter.test.ts`](../src/cli/__tests__/setup_token_permission_presenter.test.ts) · [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) · [`src/tooling/__tests__/documentation_pat_exception_policy.test.ts`](../src/tooling/__tests__/documentation_pat_exception_policy.test.ts) +- Core code: [`src/domain/setup.ts`](../src/domain/setup.ts) · [`src/domain/setup_questionnaire.ts`](../src/domain/setup_questionnaire.ts) · [`src/domain/setup_token_permissions.ts`](../src/domain/setup_token_permissions.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/ports/setup_wizard_ports.ts`](../src/application/ports/setup_wizard_ports.ts) · [`src/application/ports/setup_token_permission_ports.ts`](../src/application/ports/setup_token_permission_ports.ts) · [`src/application/policies/setup_token_permission_evidence_policy.ts`](../src/application/policies/setup_token_permission_evidence_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/setup_configuration_storage_policy.ts`](../src/application/policies/setup_configuration_storage_policy.ts) · [`src/application/policies/setup_doctor_message_catalog.ts`](../src/application/policies/setup_doctor_message_catalog.ts) · [`src/application/policies/setup_doctor_report_policy.ts`](../src/application/policies/setup_doctor_report_policy.ts) · [`src/application/policies/setup_journey_policy.ts`](../src/application/policies/setup_journey_policy.ts) · [`src/application/policies/setup_permission_summary_policy.ts`](../src/application/policies/setup_permission_summary_policy.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_session_coordinator.ts`](../src/application/usecases/setup/setup_session_coordinator.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/usecases/setup/setup_token_permissions_use_case.ts`](../src/application/usecases/setup/setup_token_permissions_use_case.ts) · [`src/application/usecases/setup/doctor_use_case.ts`](../src/application/usecases/setup/doctor_use_case.ts) · [`src/application/usecases/setup/merge_queue_readiness_use_case.ts`](../src/application/usecases/setup/merge_queue_readiness_use_case.ts) · [`src/application/usecases/actions/initial_setup_workflow.ts`](../src/application/usecases/actions/initial_setup_workflow.ts) · [`src/application/usecases/actions/setup_resource_provisioning.ts`](../src/application/usecases/actions/setup_resource_provisioning.ts) · [`src/application/ports/message_catalog_ports.ts`](../src/application/ports/message_catalog_ports.ts) · [`src/application/usecases/localization/resolve_message_catalog_use_case.ts`](../src/application/usecases/localization/resolve_message_catalog_use_case.ts) · [`src/application/policies/setup_configuration_validation.ts`](../src/application/policies/setup_configuration_validation.ts) · [`src/infrastructure/setup_workspace_adapter.ts`](../src/infrastructure/setup_workspace_adapter.ts) · [`src/data/repository/repository_variables_repository.ts`](../src/data/repository/repository_variables_repository.ts) · [`src/infrastructure/github/ports/github_repository_variables_protocol.ts`](../src/infrastructure/github/ports/github_repository_variables_protocol.ts) · [`src/infrastructure/setup_remote_credential_health_adapter.ts`](../src/infrastructure/setup_remote_credential_health_adapter.ts) · [`src/infrastructure/setup_credential_validation_adapter.ts`](../src/infrastructure/setup_credential_validation_adapter.ts) · [`src/infrastructure/setup_token_permission_query_adapter.ts`](../src/infrastructure/setup_token_permission_query_adapter.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/cli/setup_journey_presenter.ts`](../src/cli/setup_journey_presenter.ts) · [`src/cli/setup_plan_presenter.ts`](../src/cli/setup_plan_presenter.ts) · [`src/cli/setup_doctor_presenter.ts`](../src/cli/setup_doctor_presenter.ts) · [`src/cli/setup_prompt_rendering.ts`](../src/cli/setup_prompt_rendering.ts) · [`src/cli/setup_credential_prompt_adapter.ts`](../src/cli/setup_credential_prompt_adapter.ts) · [`src/cli/setup_credential_collection.ts`](../src/cli/setup_credential_collection.ts) · [`src/cli/commands/setup_execution.ts`](../src/cli/commands/setup_execution.ts) · [`src/cli/setup_token_permission_presenter.ts`](../src/cli/setup_token_permission_presenter.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`src/infrastructure/composition/setup_token_permissions_composition_root.ts`](../src/infrastructure/composition/setup_token_permissions_composition_root.ts) · [`src/infrastructure/composition/setup_doctor_composition_root.ts`](../src/infrastructure/composition/setup_doctor_composition_root.ts) · [`scripts/coverage-budgets.json`](../scripts/coverage-budgets.json) · [`scripts/documentation_pat_exception_policy.cjs`](../scripts/documentation_pat_exception_policy.cjs) · [`scripts/validate-documentation-contract.cjs`](../scripts/validate-documentation-contract.cjs) +- Tests: [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_configuration_policy.test.ts`](../src/application/policies/__tests__/setup_configuration_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/policies/__tests__/setup_doctor_message_catalog.test.ts`](../src/application/policies/__tests__/setup_doctor_message_catalog.test.ts) · [`src/application/policies/__tests__/setup_doctor_report_policy.test.ts`](../src/application/policies/__tests__/setup_doctor_report_policy.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts`](../src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts) · [`src/application/usecases/setup/__tests__/doctor_use_case.test.ts`](../src/application/usecases/setup/__tests__/doctor_use_case.test.ts) · [`src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts`](../src/application/usecases/setup/__tests__/merge_queue_readiness_use_case.test.ts) · [`src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts`](../src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts) · [`src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts`](../src/application/usecases/actions/__tests__/setup_resource_provisioning.test.ts) · [`src/infrastructure/__tests__/setup_workspace_adapter.test.ts`](../src/infrastructure/__tests__/setup_workspace_adapter.test.ts) · [`src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts`](../src/infrastructure/__tests__/setup_remote_credential_health_adapter.test.ts) · [`src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts`](../src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts) · [`src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts`](../src/infrastructure/composition/__tests__/setup_token_permissions_composition_root.test.ts) · [`src/data/repository/__tests__/repository_variables_repository.test.ts`](../src/data/repository/__tests__/repository_variables_repository.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/setup_journey_presenter.test.ts`](../src/cli/__tests__/setup_journey_presenter.test.ts) · [`src/cli/__tests__/setup_prompt_rendering.test.ts`](../src/cli/__tests__/setup_prompt_rendering.test.ts) · [`src/cli/__tests__/setup_token_permission_presenter.test.ts`](../src/cli/__tests__/setup_token_permission_presenter.test.ts) · [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) · [`src/tooling/__tests__/documentation_pat_exception_policy.test.ts`](../src/tooling/__tests__/documentation_pat_exception_policy.test.ts) - User documentation: [`README.md`](../README.md) · [`docs/how-to-use.mdx`](../docs/how-to-use.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) · [`docs/configuration-checklist.mdx`](../docs/configuration-checklist.mdx) · [`docs/authentication.mdx`](../docs/authentication.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/security-operations/operations/provisioning.mdx`](../docs/security-operations/operations/provisioning.mdx) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/security-operations/security/credentials.mdx`](../docs/security-operations/security/credentials.mdx) · [`docs/single-actions/workflow-and-cli.mdx`](../docs/single-actions/workflow-and-cli.mdx) · [`docs/security-operations/operations/verification.mdx`](../docs/security-operations/operations/verification.mdx) ### `local-web-setup-assistant` — Local web setup assistant - Owner: Copilot maintainers -- Last verified: 2026-09-29 +- Last verified: 2026-10-02 - Specifications: [`specs/local-web-setup-assistant.md`](./local-web-setup-assistant.md) -- Workflows: Not applicable for this capability. +- Workflows: [`.github/workflows/ci_check.yml`](../.github/workflows/ci_check.yml) · [`.github/workflows/setup_platform_smoke.yml`](../.github/workflows/setup_platform_smoke.yml) - Entrypoints: [`src/cli/commands/setup.ts`](../src/cli/commands/setup.ts) · [`package.json`](../package.json) · [`web/src/main.ts`](../web/src/main.ts) -- Core code: [`web/src/App.svelte`](../web/src/App.svelte) · [`web/src/session/setupSession.ts`](../web/src/session/setupSession.ts) · [`web/src/components/ActionButton.svelte`](../web/src/components/ActionButton.svelte) · [`web/src/components/PairingPanel.svelte`](../web/src/components/PairingPanel.svelte) · [`web/src/lib/pairingCode.ts`](../web/src/lib/pairingCode.ts) · [`web/src/components/ContextPanel.svelte`](../web/src/components/ContextPanel.svelte) · [`web/src/components/PromptCard.svelte`](../web/src/components/PromptCard.svelte) · [`web/src/components/ResultPanel.svelte`](../web/src/components/ResultPanel.svelte) · [`web/src/components/PlanPrompt.svelte`](../web/src/components/PlanPrompt.svelte) · [`web/src/components/PlanDecisionSummary.svelte`](../web/src/components/PlanDecisionSummary.svelte) · [`web/src/components/QuestionPrompt.svelte`](../web/src/components/QuestionPrompt.svelte) · [`web/src/components/FixedWorkflowNotice.svelte`](../web/src/components/FixedWorkflowNotice.svelte) · [`web/src/components/QuestionGuidance.svelte`](../web/src/components/QuestionGuidance.svelte) · [`web/src/components/DiscoveryNotice.svelte`](../web/src/components/DiscoveryNotice.svelte) · [`web/src/components/ProducerSelector.svelte`](../web/src/components/ProducerSelector.svelte) · [`web/src/lib/manualProducerIdentity.ts`](../web/src/lib/manualProducerIdentity.ts) · [`web/src/components/CoverageCheckEvidence.svelte`](../web/src/components/CoverageCheckEvidence.svelte) · [`web/src/components/ProjectSelector.svelte`](../web/src/components/ProjectSelector.svelte) · [`web/src/i18n/catalog.ts`](../web/src/i18n/catalog.ts) · [`web/src/i18n/projectTransitions.ts`](../web/src/i18n/projectTransitions.ts) · [`web/src/i18n/permissionTerms.ts`](../web/src/i18n/permissionTerms.ts) · [`web/src/components/StatusBanner.svelte`](../web/src/components/StatusBanner.svelte) · [`web/src/lib/questionAnswer.ts`](../web/src/lib/questionAnswer.ts) · [`web/src/lib/githubLink.ts`](../web/src/lib/githubLink.ts) · [`web/src/lib/focusOnRevision.ts`](../web/src/lib/focusOnRevision.ts) · [`web/src/i18n/featureNames.ts`](../web/src/i18n/featureNames.ts) · [`web/src/i18n/agentRoleNames.ts`](../web/src/i18n/agentRoleNames.ts) · [`web/src/i18n/checkEvidence.ts`](../web/src/i18n/checkEvidence.ts) · [`web/src/styles/controls.css`](../web/src/styles/controls.css) · [`web/src/styles/tokens.css`](../web/src/styles/tokens.css) · [`web/src/style.css`](../web/src/style.css) · [`src/application/contracts/web_setup_view.ts`](../src/application/contracts/web_setup_view.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/errors/setup_interaction_cancelled_error.ts`](../src/application/errors/setup_interaction_cancelled_error.ts) · [`src/application/policies/merge_setup_overrides_policy.ts`](../src/application/policies/merge_setup_overrides_policy.ts) · [`src/application/policies/setup_remote_facts_policy.ts`](../src/application/policies/setup_remote_facts_policy.ts) · [`src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts`](../src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts) · [`src/application/usecases/setup/audit_configured_setup_pat_use_case.ts`](../src/application/usecases/setup/audit_configured_setup_pat_use_case.ts) · [`src/application/usecases/setup/verify_web_setup_apply_use_case.ts`](../src/application/usecases/setup/verify_web_setup_apply_use_case.ts) · [`src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts`](../src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts) · [`src/cli_context.ts`](../src/cli_context.ts) · [`src/cli/setup_command_options.ts`](../src/cli/setup_command_options.ts) · [`src/cli/web_setup_bridge.ts`](../src/cli/web_setup_bridge.ts) · [`src/cli/web_setup_adapters.ts`](../src/cli/web_setup_adapters.ts) · [`src/cli/web_setup_server.ts`](../src/cli/web_setup_server.ts) · [`src/cli/setup_apply_snapshot.ts`](../src/cli/setup_apply_snapshot.ts) · [`src/cli/setup_result_receipt.ts`](../src/cli/setup_result_receipt.ts) · [`src/cli/setup_session_guard.ts`](../src/cli/setup_session_guard.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/policies/setup_terminal_choice_policy.ts`](../src/application/policies/setup_terminal_choice_policy.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_project_selection_policy.ts`](../src/application/policies/setup_project_selection_policy.ts) · [`src/application/ports/setup_project_discovery_port.ts`](../src/application/ports/setup_project_discovery_port.ts) · [`src/application/ports/setup_approval_check_discovery_port.ts`](../src/application/ports/setup_approval_check_discovery_port.ts) · [`src/infrastructure/github_setup_project_discovery_adapter.ts`](../src/infrastructure/github_setup_project_discovery_adapter.ts) · [`src/infrastructure/github_setup_approval_check_discovery_adapter.ts`](../src/infrastructure/github_setup_approval_check_discovery_adapter.ts) · [`src/application/policies/setup_question_documentation_policy.ts`](../src/application/policies/setup_question_documentation_policy.ts) · [`src/application/policies/setup_question_guidance_policy.ts`](../src/application/policies/setup_question_guidance_policy.ts) · [`src/application/policies/setup_question_purpose_policy.ts`](../src/application/policies/setup_question_purpose_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/setup_pat_creation_url_policy.ts`](../src/application/policies/setup_pat_creation_url_policy.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`scripts/validate-npm-package.cjs`](../scripts/validate-npm-package.cjs) · [`scripts/render-web-setup-component.cjs`](../scripts/render-web-setup-component.cjs) -- Tests: [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/__tests__/cli_context_branch.test.ts`](../src/__tests__/cli_context_branch.test.ts) · [`src/__tests__/cli_context_root.test.ts`](../src/__tests__/cli_context_root.test.ts) · [`src/cli/__tests__/web_setup_bridge.test.ts`](../src/cli/__tests__/web_setup_bridge.test.ts) · [`src/cli/__tests__/web_setup_adapters.test.ts`](../src/cli/__tests__/web_setup_adapters.test.ts) · [`src/cli/__tests__/web_setup_palette.test.ts`](../src/cli/__tests__/web_setup_palette.test.ts) · [`src/cli/__tests__/web_setup_ui_helpers.test.ts`](../src/cli/__tests__/web_setup_ui_helpers.test.ts) · [`src/cli/__tests__/web_setup_browser_session.test.ts`](../src/cli/__tests__/web_setup_browser_session.test.ts) · [`src/cli/__tests__/web_setup_server.test.ts`](../src/cli/__tests__/web_setup_server.test.ts) · [`src/cli/__tests__/web_setup_browser_open.test.ts`](../src/cli/__tests__/web_setup_browser_open.test.ts) · [`src/cli/__tests__/setup_apply_snapshot.test.ts`](../src/cli/__tests__/setup_apply_snapshot.test.ts) · [`src/cli/__tests__/setup_result_receipt.test.ts`](../src/cli/__tests__/setup_result_receipt.test.ts) · [`src/cli/__tests__/setup_session_guard.test.ts`](../src/cli/__tests__/setup_session_guard.test.ts) · [`src/cli/__tests__/setup_command_options.test.ts`](../src/cli/__tests__/setup_command_options.test.ts) · [`src/cli/__tests__/web_setup_components.test.ts`](../src/cli/__tests__/web_setup_components.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts`](../src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/web_setup_catalog.test.ts`](../src/cli/__tests__/web_setup_catalog.test.ts) · [`src/architecture/__tests__/web_setup_boundaries.test.ts`](../src/architecture/__tests__/web_setup_boundaries.test.ts) · [`src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts`](../src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts) · [`src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts`](../src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts) · [`src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_project_selection_policy.test.ts`](../src/application/policies/__tests__/setup_project_selection_policy.test.ts) · [`src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts) · [`src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts) · [`src/application/policies/__tests__/setup_question_documentation_policy.test.ts`](../src/application/policies/__tests__/setup_question_documentation_policy.test.ts) · [`src/application/policies/__tests__/setup_question_purpose_policy.test.ts`](../src/application/policies/__tests__/setup_question_purpose_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) -- User documentation: [`README.md`](../README.md) · [`docs/how-to-use.mdx`](../docs/how-to-use.mdx) · [`docs/authentication.mdx`](../docs/authentication.mdx) · [`docs/issues/assignees-and-projects.mdx`](../docs/issues/assignees-and-projects.mdx) · [`docs/pull-requests/guarded-approval.mdx`](../docs/pull-requests/guarded-approval.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) · [`docs/configuration-checklist.mdx`](../docs/configuration-checklist.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/dependency-rules.md`](../docs/dependency-rules.md) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/security-operations/operations/provisioning.mdx`](../docs/security-operations/operations/provisioning.mdx) +- Core code: [`web/src/App.svelte`](../web/src/App.svelte) · [`web/src/session/setupSession.ts`](../web/src/session/setupSession.ts) · [`web/src/components/ActionButton.svelte`](../web/src/components/ActionButton.svelte) · [`web/src/components/PairingPanel.svelte`](../web/src/components/PairingPanel.svelte) · [`web/src/lib/pairingCode.ts`](../web/src/lib/pairingCode.ts) · [`web/src/components/ContextPanel.svelte`](../web/src/components/ContextPanel.svelte) · [`web/src/components/PromptCard.svelte`](../web/src/components/PromptCard.svelte) · [`web/src/components/ResultPanel.svelte`](../web/src/components/ResultPanel.svelte) · [`web/src/components/ResourceProgress.svelte`](../web/src/components/ResourceProgress.svelte) · [`web/src/components/PlanPrompt.svelte`](../web/src/components/PlanPrompt.svelte) · [`web/src/components/PlanDecisionSummary.svelte`](../web/src/components/PlanDecisionSummary.svelte) · [`web/src/components/QuestionPrompt.svelte`](../web/src/components/QuestionPrompt.svelte) · [`web/src/components/FixedWorkflowNotice.svelte`](../web/src/components/FixedWorkflowNotice.svelte) · [`web/src/components/QuestionGuidance.svelte`](../web/src/components/QuestionGuidance.svelte) · [`web/src/components/DiscoveryNotice.svelte`](../web/src/components/DiscoveryNotice.svelte) · [`web/src/components/ProducerSelector.svelte`](../web/src/components/ProducerSelector.svelte) · [`web/src/lib/manualProducerIdentity.ts`](../web/src/lib/manualProducerIdentity.ts) · [`web/src/components/CoverageCheckEvidence.svelte`](../web/src/components/CoverageCheckEvidence.svelte) · [`web/src/components/ProjectSelector.svelte`](../web/src/components/ProjectSelector.svelte) · [`web/src/i18n/catalog.ts`](../web/src/i18n/catalog.ts) · [`web/src/i18n/projectTransitions.ts`](../web/src/i18n/projectTransitions.ts) · [`web/src/i18n/permissionTerms.ts`](../web/src/i18n/permissionTerms.ts) · [`web/src/components/StatusBanner.svelte`](../web/src/components/StatusBanner.svelte) · [`web/src/lib/questionAnswer.ts`](../web/src/lib/questionAnswer.ts) · [`web/src/lib/githubLink.ts`](../web/src/lib/githubLink.ts) · [`web/src/lib/focusOnRevision.ts`](../web/src/lib/focusOnRevision.ts) · [`web/src/i18n/featureNames.ts`](../web/src/i18n/featureNames.ts) · [`web/src/i18n/agentRoleNames.ts`](../web/src/i18n/agentRoleNames.ts) · [`web/src/i18n/checkEvidence.ts`](../web/src/i18n/checkEvidence.ts) · [`web/src/styles/controls.css`](../web/src/styles/controls.css) · [`web/src/styles/tokens.css`](../web/src/styles/tokens.css) · [`web/src/style.css`](../web/src/style.css) · [`src/application/contracts/web_setup_view.ts`](../src/application/contracts/web_setup_view.ts) · [`src/application/ports/setup_terminal_ports.ts`](../src/application/ports/setup_terminal_ports.ts) · [`src/application/errors/setup_interaction_cancelled_error.ts`](../src/application/errors/setup_interaction_cancelled_error.ts) · [`src/application/policies/merge_setup_overrides_policy.ts`](../src/application/policies/merge_setup_overrides_policy.ts) · [`src/application/policies/setup_remote_facts_policy.ts`](../src/application/policies/setup_remote_facts_policy.ts) · [`src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts`](../src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts) · [`src/application/usecases/setup/audit_configured_setup_pat_use_case.ts`](../src/application/usecases/setup/audit_configured_setup_pat_use_case.ts) · [`src/application/usecases/setup/verify_web_setup_apply_use_case.ts`](../src/application/usecases/setup/verify_web_setup_apply_use_case.ts) · [`src/application/usecases/setup/setup_session_coordinator.ts`](../src/application/usecases/setup/setup_session_coordinator.ts) · [`src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts`](../src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts) · [`src/cli_context.ts`](../src/cli_context.ts) · [`src/cli/setup_command_options.ts`](../src/cli/setup_command_options.ts) · [`src/cli/commands/setup_execution.ts`](../src/cli/commands/setup_execution.ts) · [`src/cli/setup_credential_collection.ts`](../src/cli/setup_credential_collection.ts) · [`src/cli/setup_pat_intent_adapter.ts`](../src/cli/setup_pat_intent_adapter.ts) · [`src/cli/setup_apply_authorization.ts`](../src/cli/setup_apply_authorization.ts) · [`src/cli/setup_outcome_adapter.ts`](../src/cli/setup_outcome_adapter.ts) · [`src/cli/web_setup_bridge.ts`](../src/cli/web_setup_bridge.ts) · [`src/cli/web_setup_adapters.ts`](../src/cli/web_setup_adapters.ts) · [`src/cli/web_setup_server.ts`](../src/cli/web_setup_server.ts) · [`src/cli/setup_apply_snapshot.ts`](../src/cli/setup_apply_snapshot.ts) · [`src/cli/setup_result_receipt.ts`](../src/cli/setup_result_receipt.ts) · [`src/application/usecases/actions/initial_setup_workflow.ts`](../src/application/usecases/actions/initial_setup_workflow.ts) · [`src/actions/local_action.ts`](../src/actions/local_action.ts) · [`src/cli/setup_session_guard.ts`](../src/cli/setup_session_guard.ts) · [`src/application/usecases/setup/setup_wizard_use_case.ts`](../src/application/usecases/setup/setup_wizard_use_case.ts) · [`src/application/usecases/setup/setup_questionnaire_controller.ts`](../src/application/usecases/setup/setup_questionnaire_controller.ts) · [`src/application/policies/setup_terminal_choice_policy.ts`](../src/application/policies/setup_terminal_choice_policy.ts) · [`src/cli/setup_terminal_driver.ts`](../src/cli/setup_terminal_driver.ts) · [`src/cli/setup_question_renderer.ts`](../src/cli/setup_question_renderer.ts) · [`src/application/usecases/setup/setup_journey_use_case.ts`](../src/application/usecases/setup/setup_journey_use_case.ts) · [`src/application/usecases/setup/setup_credentials_use_case.ts`](../src/application/usecases/setup/setup_credentials_use_case.ts) · [`src/application/policies/setup_questionnaire_policy.ts`](../src/application/policies/setup_questionnaire_policy.ts) · [`src/application/policies/setup_project_selection_policy.ts`](../src/application/policies/setup_project_selection_policy.ts) · [`src/application/ports/setup_project_discovery_port.ts`](../src/application/ports/setup_project_discovery_port.ts) · [`src/application/ports/setup_approval_check_discovery_port.ts`](../src/application/ports/setup_approval_check_discovery_port.ts) · [`src/infrastructure/github_setup_project_discovery_adapter.ts`](../src/infrastructure/github_setup_project_discovery_adapter.ts) · [`src/infrastructure/github_setup_approval_check_discovery_adapter.ts`](../src/infrastructure/github_setup_approval_check_discovery_adapter.ts) · [`src/application/policies/setup_question_documentation_policy.ts`](../src/application/policies/setup_question_documentation_policy.ts) · [`src/application/policies/setup_question_guidance_policy.ts`](../src/application/policies/setup_question_guidance_policy.ts) · [`src/application/policies/setup_question_purpose_policy.ts`](../src/application/policies/setup_question_purpose_policy.ts) · [`src/application/policies/setup_token_permission_policy.ts`](../src/application/policies/setup_token_permission_policy.ts) · [`src/application/policies/setup_configuration_plan.ts`](../src/application/policies/setup_configuration_plan.ts) · [`src/application/policies/setup_pat_creation_url_policy.ts`](../src/application/policies/setup_pat_creation_url_policy.ts) · [`src/infrastructure/composition/setup_credentials_composition_root.ts`](../src/infrastructure/composition/setup_credentials_composition_root.ts) · [`scripts/validate-npm-package.cjs`](../scripts/validate-npm-package.cjs) · [`scripts/validate-setup-assistant-acceptance.cjs`](../scripts/validate-setup-assistant-acceptance.cjs) · [`scripts/serve-web-setup-review.cjs`](../scripts/serve-web-setup-review.cjs) · [`scripts/validate-workflow-contract.cjs`](../scripts/validate-workflow-contract.cjs) · [`scripts/set-cli-executable.cjs`](../scripts/set-cli-executable.cjs) · [`scripts/render-web-setup-component.cjs`](../scripts/render-web-setup-component.cjs) +- Tests: [`src/__tests__/cli.test.ts`](../src/__tests__/cli.test.ts) · [`src/__tests__/cli_context_branch.test.ts`](../src/__tests__/cli_context_branch.test.ts) · [`src/__tests__/cli_context_root.test.ts`](../src/__tests__/cli_context_root.test.ts) · [`src/cli/__tests__/web_setup_bridge.test.ts`](../src/cli/__tests__/web_setup_bridge.test.ts) · [`src/cli/__tests__/web_setup_adapters.test.ts`](../src/cli/__tests__/web_setup_adapters.test.ts) · [`src/cli/__tests__/web_setup_palette.test.ts`](../src/cli/__tests__/web_setup_palette.test.ts) · [`src/cli/__tests__/web_setup_ui_helpers.test.ts`](../src/cli/__tests__/web_setup_ui_helpers.test.ts) · [`src/cli/__tests__/web_setup_browser_session.test.ts`](../src/cli/__tests__/web_setup_browser_session.test.ts) · [`src/cli/__tests__/web_setup_server.test.ts`](../src/cli/__tests__/web_setup_server.test.ts) · [`src/cli/__tests__/web_setup_browser_open.test.ts`](../src/cli/__tests__/web_setup_browser_open.test.ts) · [`src/cli/__tests__/setup_apply_snapshot.test.ts`](../src/cli/__tests__/setup_apply_snapshot.test.ts) · [`src/cli/__tests__/setup_result_receipt.test.ts`](../src/cli/__tests__/setup_result_receipt.test.ts) · [`src/cli/__tests__/setup_session_guard.test.ts`](../src/cli/__tests__/setup_session_guard.test.ts) · [`src/cli/__tests__/setup_command_options.test.ts`](../src/cli/__tests__/setup_command_options.test.ts) · [`src/cli/__tests__/web_setup_components.test.ts`](../src/cli/__tests__/web_setup_components.test.ts) · [`src/cli/__tests__/setup_terminal_driver.test.ts`](../src/cli/__tests__/setup_terminal_driver.test.ts) · [`src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts`](../src/cli/__tests__/setup_terminal_driver_stream_integration.test.ts) · [`src/cli/__tests__/setup_presenters.test.ts`](../src/cli/__tests__/setup_presenters.test.ts) · [`src/cli/__tests__/web_setup_catalog.test.ts`](../src/cli/__tests__/web_setup_catalog.test.ts) · [`src/architecture/__tests__/web_setup_boundaries.test.ts`](../src/architecture/__tests__/web_setup_boundaries.test.ts) · [`src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts`](../src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts) · [`src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts`](../src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts) · [`src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts`](../src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts) · [`src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts`](../src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts) · [`src/actions/__tests__/local_action.test.ts`](../src/actions/__tests__/local_action.test.ts) · [`src/tooling/__tests__/validate_workflow_contract.test.ts`](../src/tooling/__tests__/validate_workflow_contract.test.ts) · [`src/application/policies/__tests__/setup_remote_facts_policy.test.ts`](../src/application/policies/__tests__/setup_remote_facts_policy.test.ts) · [`src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts`](../src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts`](../src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts) · [`src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts) · [`src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts`](../src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts) · [`src/application/policies/__tests__/setup_questionnaire_policy.test.ts`](../src/application/policies/__tests__/setup_questionnaire_policy.test.ts) · [`src/application/policies/__tests__/setup_project_selection_policy.test.ts`](../src/application/policies/__tests__/setup_project_selection_policy.test.ts) · [`src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts) · [`src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts`](../src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts) · [`src/application/policies/__tests__/setup_question_documentation_policy.test.ts`](../src/application/policies/__tests__/setup_question_documentation_policy.test.ts) · [`src/application/policies/__tests__/setup_question_purpose_policy.test.ts`](../src/application/policies/__tests__/setup_question_purpose_policy.test.ts) · [`src/application/policies/__tests__/setup_token_permission_policy.test.ts`](../src/application/policies/__tests__/setup_token_permission_policy.test.ts) · [`src/architecture/__tests__/setup_doctor_boundaries.test.ts`](../src/architecture/__tests__/setup_doctor_boundaries.test.ts) +- User documentation: [`README.md`](../README.md) · [`docs/how-to-use.mdx`](../docs/how-to-use.mdx) · [`docs/authentication.mdx`](../docs/authentication.mdx) · [`docs/issues/assignees-and-projects.mdx`](../docs/issues/assignees-and-projects.mdx) · [`docs/pull-requests/guarded-approval.mdx`](../docs/pull-requests/guarded-approval.mdx) · [`docs/configuration.mdx`](../docs/configuration.mdx) · [`docs/configuration-checklist.mdx`](../docs/configuration-checklist.mdx) · [`docs/development/architecture.mdx`](../docs/development/architecture.mdx) · [`docs/development/setup-assistant-review.mdx`](../docs/development/setup-assistant-review.mdx) · [`docs/dependency-rules.md`](../docs/dependency-rules.md) · [`docs/security-operations/operations/troubleshooting.mdx`](../docs/security-operations/operations/troubleshooting.mdx) · [`docs/security-operations/operations/provisioning.mdx`](../docs/security-operations/operations/provisioning.mdx) ### `guided-bot-pat-onboarding` — Guided bot PAT onboarding diff --git a/specs/catalog.json b/specs/catalog.json index a079d543f..ef14533c0 100644 --- a/specs/catalog.json +++ b/specs/catalog.json @@ -644,7 +644,7 @@ "status": "implemented", "scope": "Plan, validate, provision, and audit a repository installation without exposing credentials", "owner": "Copilot maintainers", - "lastVerified": "2026-09-28", + "lastVerified": "2026-10-02", "specs": [ "specs/setup-configuration-credentials-and-doctor.md", "specs/setup-doctor-architecture-hardening.md", @@ -676,6 +676,7 @@ "src/application/policies/setup_permission_summary_policy.ts", "src/application/usecases/setup/setup_wizard_use_case.ts", "src/application/usecases/setup/setup_journey_use_case.ts", + "src/application/usecases/setup/setup_session_coordinator.ts", "src/application/usecases/setup/setup_questionnaire_controller.ts", "src/application/usecases/setup/setup_credentials_use_case.ts", "src/application/usecases/setup/setup_token_permissions_use_case.ts", @@ -699,6 +700,8 @@ "src/cli/setup_doctor_presenter.ts", "src/cli/setup_prompt_rendering.ts", "src/cli/setup_credential_prompt_adapter.ts", + "src/cli/setup_credential_collection.ts", + "src/cli/commands/setup_execution.ts", "src/cli/setup_token_permission_presenter.ts", "src/infrastructure/composition/setup_credentials_composition_root.ts", "src/infrastructure/composition/setup_token_permissions_composition_root.ts", @@ -717,6 +720,7 @@ "src/application/usecases/setup/__tests__/setup_questionnaire_controller.test.ts", "src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts", "src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts", + "src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts", "src/application/usecases/setup/__tests__/setup_credentials_use_case.test.ts", "src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts", "src/application/usecases/setup/__tests__/doctor_use_case.test.ts", @@ -757,11 +761,14 @@ "status": "proposed", "scope": "Offer a packaged, loopback-only Svelte setup interface over the existing engine with four-language guidance, English CLI help, basic/custom first-run paths, editable question and plan review, source-labelled GitHub facts, assisted CI and Project evidence, role-separated PATs, and truthful itemized outcomes", "owner": "Copilot maintainers", - "lastVerified": "2026-09-29", + "lastVerified": "2026-10-02", "specs": [ "specs/local-web-setup-assistant.md" ], - "workflows": [], + "workflows": [ + ".github/workflows/ci_check.yml", + ".github/workflows/setup_platform_smoke.yml" + ], "entrypoints": [ "src/cli/commands/setup.ts", "package.json", @@ -776,6 +783,7 @@ "web/src/components/ContextPanel.svelte", "web/src/components/PromptCard.svelte", "web/src/components/ResultPanel.svelte", + "web/src/components/ResourceProgress.svelte", "web/src/components/PlanPrompt.svelte", "web/src/components/PlanDecisionSummary.svelte", "web/src/components/QuestionPrompt.svelte", @@ -807,14 +815,22 @@ "src/application/usecases/setup/prepare_setup_pat_intent_use_case.ts", "src/application/usecases/setup/audit_configured_setup_pat_use_case.ts", "src/application/usecases/setup/verify_web_setup_apply_use_case.ts", + "src/application/usecases/setup/setup_session_coordinator.ts", "src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts", "src/cli_context.ts", "src/cli/setup_command_options.ts", + "src/cli/commands/setup_execution.ts", + "src/cli/setup_credential_collection.ts", + "src/cli/setup_pat_intent_adapter.ts", + "src/cli/setup_apply_authorization.ts", + "src/cli/setup_outcome_adapter.ts", "src/cli/web_setup_bridge.ts", "src/cli/web_setup_adapters.ts", "src/cli/web_setup_server.ts", "src/cli/setup_apply_snapshot.ts", "src/cli/setup_result_receipt.ts", + "src/application/usecases/actions/initial_setup_workflow.ts", + "src/actions/local_action.ts", "src/cli/setup_session_guard.ts", "src/application/usecases/setup/setup_wizard_use_case.ts", "src/application/usecases/setup/setup_questionnaire_controller.ts", @@ -837,6 +853,10 @@ "src/application/policies/setup_pat_creation_url_policy.ts", "src/infrastructure/composition/setup_credentials_composition_root.ts", "scripts/validate-npm-package.cjs", + "scripts/validate-setup-assistant-acceptance.cjs", + "scripts/serve-web-setup-review.cjs", + "scripts/validate-workflow-contract.cjs", + "scripts/set-cli-executable.cjs", "scripts/render-web-setup-component.cjs" ], "tests": [ @@ -863,6 +883,10 @@ "src/application/usecases/setup/__tests__/prepare_setup_pat_intent_use_case.test.ts", "src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts", "src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts", + "src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts", + "src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts", + "src/actions/__tests__/local_action.test.ts", + "src/tooling/__tests__/validate_workflow_contract.test.ts", "src/application/policies/__tests__/setup_remote_facts_policy.test.ts", "src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts", "src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts", @@ -887,6 +911,7 @@ "docs/configuration.mdx", "docs/configuration-checklist.mdx", "docs/development/architecture.mdx", + "docs/development/setup-assistant-review.mdx", "docs/dependency-rules.md", "docs/security-operations/operations/troubleshooting.mdx", "docs/security-operations/operations/provisioning.mdx" diff --git a/specs/local-web-setup-assistant-acceptance.json b/specs/local-web-setup-assistant-acceptance.json new file mode 100644 index 000000000..52bdce4ff --- /dev/null +++ b/specs/local-web-setup-assistant-acceptance.json @@ -0,0 +1,356 @@ +{ + "baseline": "2026-09-30 follow-up branch; fixture-only verification; human and platform gates remain open", + "sourceRun": "coverage/setup-acceptance-jest.json (2026-09-30 local pnpm run test:coverage; regenerated by CI)", + "cases": [ + {"id":"P001","assertion":"setup questionnaire policy accepts bounded numeric and indexed choice answers and rejects invalid values","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy accepts bounded numeric and indexed choice answers and rejects invalid values"}}, + {"id":"P002","assertion":"setup questionnaire policy asks for numeric threshold, artifact workflow, and reporter attestation only in numeric mode","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy asks for numeric threshold, artifact workflow, and reporter attestation only in numeric mode"}}, + {"id":"P003","assertion":"setup questionnaire policy basic presentation omits only advanced defaults, never security or mutation choices","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy basic presentation omits only advanced defaults, never security or mutation choices"}}, + {"id":"P004","assertion":"setup questionnaire policy does not mutate or share nested references with frozen defaults","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy does not mutate or share nested references with frozen defaults"}}, + {"id":"P005","assertion":"setup questionnaire policy keeps Basic defaults safe when an optional nested configuration section is absent","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy keeps Basic defaults safe when an optional nested configuration section is absent"}}, + {"id":"P006","assertion":"setup questionnaire policy lets either presentation explicitly clear every issue workflow","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy lets either presentation explicitly clear every issue workflow"}}, + {"id":"P007","assertion":"setup configuration policy builds a complete safe default plan","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy builds a complete safe default plan"}}, + {"id":"P008","assertion":"setup configuration policy does not request credentials for agent roles whose workflows are disabled","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy does not request credentials for agent roles whose workflows are disabled"}}, + {"id":"P009","assertion":"setup configuration policy rejects unavailable organization inventory needed to preserve repository-default resources","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy rejects unavailable organization inventory needed to preserve repository-default resources"}}, + {"id":"P010","assertion":"setup configuration policy requires Action-managed branches for the SDD gate and release or hotfix workflows","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy requires Action-managed branches for the SDD gate and release or hotfix workflows"}}, + {"id":"P011","assertion":"setup questionnaire policy accepts a manual Project number when an older question has no discovery candidate field","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy accepts a manual Project number when an older question has no discovery candidate field"}}, + {"id":"P012","assertion":"setup questionnaire policy accepts explicit text and negative boolean answers","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy accepts explicit text and negative boolean answers"}}, + {"id":"P013","assertion":"setup questionnaire policy adds per-role model questions only after the explicit independent decision","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy adds per-role model questions only after the explicit independent decision"}}, + {"id":"P014","assertion":"setup questionnaire policy clears saved Project IDs when the operator changes Project intent to no","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy clears saved Project IDs when the operator changes Project intent to no"}}, + {"id":"P015","assertion":"setup questionnaire policy does not label a required ruleset check as verified after the target development branch changes","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy does not label a required ruleset check as verified after the target development branch changes"}}, + {"id":"P016","assertion":"setup questionnaire policy keeps the same question and prior draft after invalid input","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy keeps the same question and prior draft after invalid input"}}, + {"id":"P017","assertion":"setup questionnaire policy preserves independent agent overrides on revisit and normalizes them only when explicitly disabled","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy preserves independent agent overrides on revisit and normalizes them only when explicitly disabled"}}, + {"id":"P018","assertion":"setup questionnaire policy rejects ambiguous trusted check names and preserves previous answers on discovery refresh","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy rejects ambiguous trusted check names and preserves previous answers on discovery refresh"}}, + {"id":"P019","assertion":"setup questionnaire policy rejects invalid review/confirmation transitions","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy rejects invalid review/confirmation transitions"}}, + {"id":"P020","assertion":"setup questionnaire policy uses the current draft when permission intent is revised","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_questionnaire_policy.test.ts","test":"setup questionnaire policy uses the current draft when permission intent is revised"}}, + {"id":"P021","assertion":"SetupWizardUseCase discovers Projects when the operator enables them while revising a plan that originally skipped them","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts","test":"SetupWizardUseCase discovers Projects when the operator enables them while revising a plan that originally skipped them"}}, + {"id":"P022","assertion":"SetupWizardUseCase rejects invalid non-interactive overrides before presenting a plan","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts","test":"SetupWizardUseCase rejects invalid non-interactive overrides before presenting a plan"}}, + {"id":"P023","assertion":"setup token permission policy adds Administration read for release or hotfix automation","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Administration read for release or hotfix automation"}}, + {"id":"P024","assertion":"setup token permission policy adds Checks and Variables read for guarded approval","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Checks and Variables read for guarded approval"}}, + {"id":"P025","assertion":"setup token permission policy adds guarded approval PR writes without unrelated Actions, Contents, or Issues writes","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds guarded approval PR writes without unrelated Actions, Contents, or Issues writes"}}, + {"id":"P026","assertion":"setup token permission policy adds Members read for automatic issue assignees","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Members read for automatic issue assignees"}}, + {"id":"P027","assertion":"setup token permission policy adds Members read for automatic PR assignees","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Members read for automatic PR assignees"}}, + {"id":"P028","assertion":"setup token permission policy adds Members read for automatic PR reviewers","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Members read for automatic PR reviewers"}}, + {"id":"P029","assertion":"setup token permission policy adds Members read for members-only commit automation","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Members read for members-only commit automation"}}, + {"id":"P030","assertion":"setup token permission policy adds Members read for members-only issue comment automation","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Members read for members-only issue comment automation"}}, + {"id":"P031","assertion":"setup token permission policy adds Members read for members-only PR comment automation","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Members read for members-only PR comment automation"}}, + {"id":"P032","assertion":"setup token permission policy adds Members read for members-only standalone single actions","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_token_permission_policy.test.ts","test":"setup token permission policy adds Members read for members-only standalone single actions"}}, + {"id":"P033","assertion":"setup configuration policy blocks unavailable repository inventory even when every selected resource is organization-only","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy blocks unavailable repository inventory even when every selected resource is organization-only"}}, + {"id":"P034","assertion":"setup configuration policy keeps an existing credential only when preservation retains its effective scope","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy keeps an existing credential only when preservation retains its effective scope"}}, + {"id":"P035","assertion":"setup configuration policy keeps replacement credentials on the effective repository scope unless scope is explicitly overridden","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy keeps replacement credentials on the effective repository scope unless scope is explicitly overridden"}}, + {"id":"P036","assertion":"setup configuration policy preserves an inherited organization resource unless an override is explicit","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy preserves an inherited organization resource unless an override is explicit"}}, + {"id":"P037","assertion":"setup configuration policy preserves live merge queue checks in the setup presentation plan","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy preserves live merge queue checks in the setup presentation plan"}}, + {"id":"P038","assertion":"setup configuration policy removes optional files while retaining core setup resources","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy removes optional files while retaining core setup resources"}}, + {"id":"P039","assertion":"setup configuration policy requires organization inventory only for selected scopes or preservation discovery","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_configuration_policy.test.ts","test":"setup configuration policy requires organization inventory only for selected scopes or preservation discovery"}}, + {"id":"P040","assertion":"SetupWizardUseCase adds live merge-queue readiness to the setup plan","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts","test":"SetupWizardUseCase adds live merge-queue readiness to the setup plan"}}, + {"id":"P041","assertion":"SetupWizardUseCase blocks organization-only resources when repository shadow inventory is unavailable","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts","test":"SetupWizardUseCase blocks organization-only resources when repository shadow inventory is unavailable"}}, + {"id":"P042","assertion":"SetupWizardUseCase maps missing pre-plan inspection to bounded unavailable facts before the final audit","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_wizard_use_case.test.ts","test":"SetupWizardUseCase maps missing pre-plan inspection to bounded unavailable facts before the final audit"}}, + {"id":"P043","assertion":"setup Project selection Status compatibility: no selected Project","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_project_selection_policy.test.ts","test":"setup Project selection Status compatibility: no selected Project"}}, + {"id":"P044","assertion":"setup Project selection Status compatibility: one selected Project was not discovered","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_project_selection_policy.test.ts","test":"setup Project selection Status compatibility: one selected Project was not discovered"}}, + {"id":"P045","assertion":"setup Project selection Status compatibility: one Status field is unreadable","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_project_selection_policy.test.ts","test":"setup Project selection Status compatibility: one Status field is unreadable"}}, + {"id":"P046","assertion":"setup Project selection Status compatibility: the Projects have disjoint options","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_project_selection_policy.test.ts","test":"setup Project selection Status compatibility: the Projects have disjoint options"}}, + {"id":"P047","assertion":"setup Project selection Status compatibility: the Projects share one option","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_project_selection_policy.test.ts","test":"setup Project selection Status compatibility: the Projects share one option"}}, + {"id":"P048","assertion":"setup Project selection Status compatibility: the Projects share options in the first field order","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_project_selection_policy.test.ts","test":"setup Project selection Status compatibility: the Projects share options in the first field order"}}, + {"id":"S001","assertion":"shared setup session coordinator a completed effect cannot be demoted by a later stale progress event","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator a completed effect cannot be demoted by a later stale progress event"}}, + {"id":"S002","assertion":"shared setup session coordinator an unknown provider outcome after the write boundary is partial, with retained facts","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator an unknown provider outcome after the write boundary is partial, with retained facts"}}, + {"id":"S003","assertion":"shared setup session coordinator an unresolved in-progress write cannot produce a complete outcome","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator an unresolved in-progress write cannot produce a complete outcome"}}, + {"id":"S004","assertion":"shared setup session coordinator runs semantic stages in order and returns an immutable resource receipt","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator runs semantic stages in order and returns an immutable resource receipt"}}, + {"id":"S005","assertion":"setup journey keeps ordered milestones and does not imply changes before apply","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_journey_use_case.test.ts","test":"setup journey keeps ordered milestones and does not imply changes before apply"}}, + {"id":"S006","assertion":"shared setup session coordinator a possible credential-health write makes later cancellation partial","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator a possible credential-health write makes later cancellation partial"}}, + {"id":"S007","assertion":"shared setup session coordinator authorizeApply decision cancelled stops before Apply as cancelled","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator authorizeApply decision cancelled stops before Apply as cancelled"}}, + {"id":"S008","assertion":"shared setup session coordinator choices decision blocked stops before Apply as blocked","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator choices decision blocked stops before Apply as blocked"}}, + {"id":"S009","assertion":"shared setup session coordinator liveness cancelled during awaited approval stops before mutation","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator liveness cancelled during awaited approval stops before mutation"}}, + {"id":"S010","assertion":"shared setup session coordinator liveness expired during awaited approval stops before mutation","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts","test":"shared setup session coordinator liveness expired during awaited approval stops before mutation"}}, + {"id":"S011","assertion":"WebSetupBridge a retry cannot commit after cancellation or a controller takeover","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge a retry cannot commit after cancellation or a controller takeover"}}, + {"id":"S012","assertion":"WebSetupBridge back navigation rotates the question revision without resolving or echoing a draft answer","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge back navigation rotates the question revision without resolving or echoing a draft answer"}}, + {"id":"S013","assertion":"WebSetupBridge cancelling while discovery is in flight discards its result and leaves no pending answer","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge cancelling while discovery is in flight discards its result and leaves no pending answer"}}, + {"id":"S014","assertion":"WebSetupBridge explicit discovery retry updates the pending prompt in place without consuming its answer","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge explicit discovery retry updates the pending prompt in place without consuming its answer"}}, + {"id":"S015","assertion":"WebSetupBridge finishing resolves an unanswered prompt but preserves no secret","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge finishing resolves an unanswered prompt but preserves no secret"}}, + {"id":"S016","assertion":"WebSetupBridge publishes semantic prompts with one-use revisions and never echoes an answer","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge publishes semantic prompts with one-use revisions and never echoes an answer"}}, + {"id":"S017","assertion":"WebSetupBridge read-only subscribers receive redacted revisions and can unsubscribe","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge read-only subscribers receive redacted revisions and can unsubscribe"}}, + {"id":"S018","assertion":"browser session transport a busy submission cannot send a second answer or cancel concurrently","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport a busy submission cannot send a second answer or cancel concurrently"}}, + {"id":"S019","assertion":"browser session transport a discovery retry sends only the revision and controller capability, then reads updated state","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport a discovery retry sends only the revision and controller capability, then reads updated state"}}, + {"id":"S020","assertion":"browser session transport a failed reconnect drops the old controller capability and cannot replay a PAT","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport a failed reconnect drops the old controller capability and cannot replay a PAT"}}, + {"id":"S021","assertion":"VerifySetupPatBootstrapUseCase invalid identity blocks regardless of a ready permission table","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts","test":"VerifySetupPatBootstrapUseCase invalid identity blocks regardless of a ready permission table"}}, + {"id":"S022","assertion":"VerifySetupPatBootstrapUseCase unverifiable identity blocks regardless of a ready permission table","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_setup_pat_bootstrap_use_case.test.ts","test":"VerifySetupPatBootstrapUseCase unverifiable identity blocks regardless of a ready permission table"}}, + {"id":"S023","assertion":"AuditConfiguredSetupPatUseCase dry-run preview without a token may show unknown owner grants without authorizing mutations","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts","test":"AuditConfiguredSetupPatUseCase dry-run preview without a token may show unknown owner grants without authorizing mutations"}}, + {"id":"S024","assertion":"AuditConfiguredSetupPatUseCase invalid PAT identity blocks even when checks are otherwise ready","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts","test":"AuditConfiguredSetupPatUseCase invalid PAT identity blocks even when checks are otherwise ready"}}, + {"id":"S025","assertion":"AuditConfiguredSetupPatUseCase preview without a PAT shows requirements but never probes permissions","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts","test":"AuditConfiguredSetupPatUseCase preview without a PAT shows requirements but never probes permissions"}}, + {"id":"S026","assertion":"AuditConfiguredSetupPatUseCase unavailable owner inspection blocks a token-backed audit before permission probes","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts","test":"AuditConfiguredSetupPatUseCase unavailable owner inspection blocks a token-backed audit before permission probes"}}, + {"id":"S027","assertion":"AuditConfiguredSetupPatUseCase unknown owner type blocks token-backed audit despite Organization assertion","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts","test":"AuditConfiguredSetupPatUseCase unknown owner type blocks token-backed audit despite Organization assertion"}}, + {"id":"S028","assertion":"AuditConfiguredSetupPatUseCase unknown owner type blocks token-backed audit despite User assertion","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/audit_configured_setup_pat_use_case.test.ts","test":"AuditConfiguredSetupPatUseCase unknown owner type blocks token-backed audit despite User assertion"}}, + {"id":"S029","assertion":"VerifyWebSetupApplyUseCase authorizes only after reconfirming local, remote, workflow and PAT facts","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase authorizes only after reconfirming local, remote, workflow and PAT facts"}}, + {"id":"S030","assertion":"VerifyWebSetupApplyUseCase blocks when the final PAT audit loses a required grant","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase blocks when the final PAT audit loses a required grant"}}, + {"id":"S031","assertion":"VerifyWebSetupApplyUseCase cancellation arriving during remote inspection wins before another read","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase cancellation arriving during remote inspection wins before another read"}}, + {"id":"S032","assertion":"VerifyWebSetupApplyUseCase does not inspect or mutate after approval response stop","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase does not inspect or mutate after approval response stop"}}, + {"id":"S033","assertion":"VerifyWebSetupApplyUseCase does not inspect or mutate after approval response undefined","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase does not inspect or mutate after approval response undefined"}}, + {"id":"S034","assertion":"VerifyWebSetupApplyUseCase expiry arriving during the final audit prevents approval","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase expiry arriving during the final audit prevents approval"}}, + {"id":"S035","assertion":"VerifyWebSetupApplyUseCase fails closed on file drift before remote reads","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase fails closed on file drift before remote reads"}}, + {"id":"S036","assertion":"VerifyWebSetupApplyUseCase fails closed when a remote variable value changes","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase fails closed when a remote variable value changes"}}, + {"id":"S037","assertion":"VerifyWebSetupApplyUseCase fails closed when branch changed","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase fails closed when branch changed"}}, + {"id":"S038","assertion":"VerifyWebSetupApplyUseCase fails closed when checkoutRoot changed","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/verify_web_setup_apply_use_case.test.ts","test":"VerifyWebSetupApplyUseCase fails closed when checkoutRoot changed"}}, + {"id":"S039","assertion":"setup session guard a failed staged write never publishes an empty lock or leaves a staging file","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard a failed staged write never publishes an empty lock or leaves a staging file"}}, + {"id":"S040","assertion":"setup session guard a replacement lock is never unlinked after a stale-owner probe","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard a replacement lock is never unlinked after a stale-owner probe"}}, + {"id":"S041","assertion":"setup session guard does not mistake a failed atomic link for an existing setup session","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard does not mistake a failed atomic link for an existing setup session"}}, + {"id":"S042","assertion":"setup session guard fails closed for an unverifiable lock not-json","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard fails closed for an unverifiable lock not-json"}}, + {"id":"S043","assertion":"setup session guard fails closed for an unverifiable lock {\"pid\":-1,\"nonce\":\"bad\",\"repository\":\"wrong\"}","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard fails closed for an unverifiable lock {\"pid\":-1,\"nonce\":\"bad\",\"repository\":\"wrong\"}"}}, + {"id":"S044","assertion":"setup session guard fails closed on a verified dead owner until the operator removes its exact lock","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard fails closed on a verified dead owner until the operator removes its exact lock"}}, + {"id":"S045","assertion":"setup session guard propagates a filesystem error instead of treating it as a competing session","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard propagates a filesystem error instead of treating it as a competing session"}}, + {"id":"S046","assertion":"setup session guard serializes setup across directories of the same checkout and releases only its own lock","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_session_guard.test.ts","test":"setup session guard serializes setup across directories of the same checkout and releases only its own lock"}}, + {"id":"S047","assertion":"InitialSetupUseCase continues and reports progress-label provisioning errors","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts","test":"InitialSetupUseCase continues and reports progress-label provisioning errors"}}, + {"id":"S048","assertion":"InitialSetupUseCase distinguishes skipped files from newly created labels and issue types in the receipt","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts","test":"InitialSetupUseCase distinguishes skipped files from newly created labels and issue types in the receipt"}}, + {"id":"S049","assertion":"InitialSetupUseCase emits ordered, value-free resource progress before the final receipt","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts","test":"InitialSetupUseCase emits ordered, value-free resource progress before the final receipt"}}, + {"id":"S050","assertion":"InitialSetupUseCase marks a failed local write as needing inspection and later resources as not started","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts","test":"InitialSetupUseCase marks a failed local write as needing inspection and later resources as not started"}}, + {"id":"S051","assertion":"InitialSetupUseCase marks a failed Variable write for inspection and retains mixed scope even when setup stops early","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts","test":"InitialSetupUseCase marks a failed Variable write for inspection and retains mixed scope even when setup stops early"}}, + {"id":"S052","assertion":"InitialSetupUseCase reports provisioned Secrets and keeps a failed Secret write marked for inspection","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts","test":"InitialSetupUseCase reports provisioned Secrets and keeps a failed Secret write marked for inspection"}}, + {"id":"S053","assertion":"setup result receipt does not serialize provider error messages or unsafe action identifiers","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_result_receipt.test.ts","test":"setup result receipt does not serialize provider error messages or unsafe action identifiers"}}, + {"id":"S054","assertion":"setup result receipt does not throw or leak text if a legacy action returns an unstructured error","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_result_receipt.test.ts","test":"setup result receipt does not throw or leak text if a legacy action returns an unstructured error"}}, + {"id":"A001","assertion":"GitHub setup approval check discovery distinguishes no recent PR runs from missing permission and provider outage","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts","test":"GitHub setup approval check discovery distinguishes no recent PR runs from missing permission and provider outage"}}, + {"id":"A002","assertion":"GitHub setup approval check discovery does not claim ruleset evidence when rules are malformed or GitHub denies inspection","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts","test":"GitHub setup approval check discovery does not claim ruleset evidence when rules are malformed or GitHub denies inspection"}}, + {"id":"A003","assertion":"GitHub setup approval check discovery does not invent identities from a job name, skipped workflow or unsafe producer","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts","test":"GitHub setup approval check discovery does not invent identities from a job name, skipped workflow or unsafe producer"}}, + {"id":"A004","assertion":"GitHub setup approval check discovery maps a later Check Runs failure to a nonempty error status instead of an empty trusted list","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts","test":"GitHub setup approval check discovery maps a later Check Runs failure to a nonempty error status instead of an empty trusted list"}}, + {"id":"A005","assertion":"GitHub setup approval check discovery marks only an exact check/App pair required by an active branch ruleset","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts","test":"GitHub setup approval check discovery marks only an exact check/App pair required by an active branch ruleset"}}, + {"id":"A006","assertion":"GitHub setup approval check discovery suggests only exact jobs joined to a completed PR workflow and Check Run App ID","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_approval_check_discovery_adapter.test.ts","test":"GitHub setup approval check discovery suggests only exact jobs joined to a completed PR workflow and Check Run App ID"}}, + {"id":"A007","assertion":"GitHub setup Project discovery distinguishes personal-owner unsupported, empty, denied and provider unavailable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts","test":"GitHub setup Project discovery distinguishes personal-owner unsupported, empty, denied and provider unavailable"}}, + {"id":"A008","assertion":"GitHub setup Project discovery follows REST page links, reports a truncated inventory, and does not trust partial field listings","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts","test":"GitHub setup Project discovery follows REST page links, reports a truncated inventory, and does not trust partial field listings"}}, + {"id":"A009","assertion":"GitHub setup Project discovery ignores a malformed next-page URL without making another request","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts","test":"GitHub setup Project discovery ignores a malformed next-page URL without making another request"}}, + {"id":"A010","assertion":"GitHub setup Project discovery ignores closed, malformed and unsafe Project rows","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/github_setup_project_discovery_adapter.test.ts","test":"GitHub setup Project discovery ignores closed, malformed and unsafe Project rows"}}, + {"id":"A011","assertion":"setup remote fact equivalence detects a change in credentialHealthWorkflow","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in credentialHealthWorkflow"}}, + {"id":"A012","assertion":"setup remote fact equivalence detects a change in defaultBranch","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in defaultBranch"}}, + {"id":"A013","assertion":"setup remote fact equivalence detects a change in organizationAccess","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in organizationAccess"}}, + {"id":"A014","assertion":"setup remote fact equivalence detects a change in organizationSecrets","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in organizationSecrets"}}, + {"id":"A015","assertion":"setup remote fact equivalence detects a change in organizationSecretsAccess","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in organizationSecretsAccess"}}, + {"id":"A016","assertion":"setup remote fact equivalence detects a change in organizationVariables","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in organizationVariables"}}, + {"id":"A017","assertion":"setup remote fact equivalence detects a change in organizationVariablesAccess","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in organizationVariablesAccess"}}, + {"id":"A018","assertion":"setup remote fact equivalence detects a change in ownerType","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_remote_facts_policy.test.ts","test":"setup remote fact equivalence detects a change in ownerType"}}, + {"id":"A019","assertion":"SetupTokenPermissionQueryAdapter bounds a stalled permission probe with the configured timeout","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter bounds a stalled permission probe with the configured timeout"}}, + {"id":"A020","assertion":"SetupTokenPermissionQueryAdapter does not make a request when GitHub has no safe read-only probe","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter does not make a request when GitHub has no safe read-only probe"}}, + {"id":"A021","assertion":"SetupTokenPermissionQueryAdapter keeps a primary rate limit HTTP 403 unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a primary rate limit HTTP 403 unverifiable"}}, + {"id":"A022","assertion":"SetupTokenPermissionQueryAdapter keeps a secondary rate limit HTTP 403 unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a secondary rate limit HTTP 403 unverifiable"}}, + {"id":"A023","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public organization Issue Types probe unusable as permission evidence","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public organization Issue Types probe unusable as permission evidence"}}, + {"id":"A024","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public repository actions probe unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public repository actions probe unverifiable"}}, + {"id":"A025","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public repository administration probe unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public repository administration probe unverifiable"}}, + {"id":"A026","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public repository checks probe unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public repository checks probe unverifiable"}}, + {"id":"A027","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public repository contents probe unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public repository contents probe unverifiable"}}, + {"id":"A028","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public repository issues probe unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public repository issues probe unverifiable"}}, + {"id":"A029","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public repository metadata probe unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public repository metadata probe unverifiable"}}, + {"id":"A030","assertion":"SetupTokenPermissionQueryAdapter keeps a successful public repository pull-requests probe unverifiable","status":"pass","evidence":{"kind":"jest","file":"src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts","test":"SetupTokenPermissionQueryAdapter keeps a successful public repository pull-requests probe unverifiable"}}, + {"id":"A031","assertion":"web setup apply snapshot also guards managed files that a configuration may retire","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot also guards managed files that a configuration may retire"}}, + {"id":"A032","assertion":"web setup apply snapshot detects creation and modification of selected files","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot detects creation and modification of selected files"}}, + {"id":"A033","assertion":"web setup apply snapshot guards .agents/skills/copilot-repository-workflow/SKILL.md against drift even when repository guidance is disabled","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot guards .agents/skills/copilot-repository-workflow/SKILL.md against drift even when repository guidance is disabled"}}, + {"id":"A034","assertion":"web setup apply snapshot guards .copilot/AGENT_GUIDE.md against drift even when repository guidance is disabled","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot guards .copilot/AGENT_GUIDE.md against drift even when repository guidance is disabled"}}, + {"id":"A035","assertion":"web setup apply snapshot guards .copilot/repository-profile.json against drift even when repository guidance is disabled","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot guards .copilot/repository-profile.json against drift even when repository guidance is disabled"}}, + {"id":"A036","assertion":"web setup apply snapshot guards .copilot/setup-manifest.json against drift even when repository guidance is disabled","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot guards .copilot/setup-manifest.json against drift even when repository guidance is disabled"}}, + {"id":"A037","assertion":"web setup apply snapshot guards AGENTS.md against drift even when repository guidance is disabled","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot guards AGENTS.md against drift even when repository guidance is disabled"}}, + {"id":"A038","assertion":"web setup apply snapshot guards checkout destinations, not the package-source labels shown in the plan","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot guards checkout destinations, not the package-source labels shown in the plan"}}, + {"id":"A039","assertion":"web setup apply snapshot normalizes duplicate selected paths and remains stable when nothing changed","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot normalizes duplicate selected paths and remains stable when nothing changed"}}, + {"id":"A040","assertion":"web setup apply snapshot rejects absolute paths and files too large to snapshot safely","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_apply_snapshot.test.ts","test":"web setup apply snapshot rejects absolute paths and files too large to snapshot safely"}}, + {"id":"C001","assertion":"setup command option adapter collects and normalizes per-resource scopes","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter collects and normalizes per-resource scopes"}}, + {"id":"C002","assertion":"setup command option adapter collects opaque Secrets without logging or altering their values","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter collects opaque Secrets without logging or altering their values"}}, + {"id":"C003","assertion":"setup command option adapter keeps unspecified approval mode and resource overrides absent","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter keeps unspecified approval mode and resource overrides absent"}}, + {"id":"C004","assertion":"setup command option adapter maps agent, guidance, approval and storage flags into typed overrides","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter maps agent, guidance, approval and storage flags into typed overrides"}}, + {"id":"C005","assertion":"setup command option adapter maps bounded features and issue workflows","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter maps bounded features and issue workflows"}}, + {"id":"C006","assertion":"setup command option adapter rejects invalid option {\"agent\":\"unknown\"}","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter rejects invalid option {\"agent\":\"unknown\"}"}}, + {"id":"C007","assertion":"setup command option adapter rejects invalid option {\"agentGuidance\":\"unknown\"}","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter rejects invalid option {\"agentGuidance\":\"unknown\"}"}}, + {"id":"C008","assertion":"setup command option adapter rejects invalid option {\"features\":\"unknown\"}","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter rejects invalid option {\"features\":\"unknown\"}"}}, + {"id":"C009","assertion":"setup command option adapter rejects invalid option {\"issueWorkflows\":\"feature,feature\"}","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_command_options.test.ts","test":"setup command option adapter rejects invalid option {\"issueWorkflows\":\"feature,feature\"}"}}, + {"id":"C010","assertion":"setup presenters and prompt-specific adapters cancels rather than applying when section selection is interrupted","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters cancels rather than applying when section selection is interrupted"}}, + {"id":"C011","assertion":"setup presenters and prompt-specific adapters collects hidden setup and runtime credentials without rendering their values","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters collects hidden setup and runtime credentials without rendering their values"}}, + {"id":"C012","assertion":"setup presenters and prompt-specific adapters distinguishes an initial PAT failure from a blocked final plan","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters distinguishes an initial PAT failure from a blocked final plan"}}, + {"id":"C013","assertion":"setup presenters and prompt-specific adapters distinguishes approval, decline, and interrupted confirmation","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters distinguishes approval, decline, and interrupted confirmation"}}, + {"id":"C014","assertion":"setup presenters and prompt-specific adapters distinguishes the first permission-intent pass from a deliberate second pass","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters distinguishes the first permission-intent pass from a deliberate second pass"}}, + {"id":"C015","assertion":"setup presenters and prompt-specific adapters does not invent workflow PAT requirements when the manual guide has none","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters does not invent workflow PAT requirements when the manual guide has none"}}, + {"id":"C016","assertion":"setup presenters and prompt-specific adapters does not show a correction link before guided mode is selected","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters does not show a correction link before guided mode is selected"}}, + {"id":"C017","assertion":"setup presenters and prompt-specific adapters explains a bot login on ? without treating it as an account","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_presenters.test.ts","test":"setup presenters and prompt-specific adapters explains a bot login on ? without treating it as an account"}}, + {"id":"C018","assertion":"The npm tarball includes the executable CLI launcher.","status":"pass","evidence":{"kind":"command","command":"pnpm run validate:npm-package","observation":"npm package validation passed with 69 files and required CLI, web and API assets.","date":"2026-09-30"}}, + {"id":"C019","assertion":"The npm tarball includes the compiled web index.","status":"pass","evidence":{"kind":"command","command":"pnpm run validate:npm-package","observation":"npm package validation passed with 69 files and required CLI, web and API assets.","date":"2026-09-30"}}, + {"id":"C020","assertion":"The npm tarball includes only required hashed web JavaScript and CSS assets.","status":"pass","evidence":{"kind":"command","command":"pnpm run validate:npm-package","observation":"npm package validation passed with 69 files and required CLI, web and API assets.","date":"2026-09-30"}}, + {"id":"C021","assertion":"Packaged asset paths resolve relative to the installed package.","status":"pass","evidence":{"kind":"command","command":"pnpm run smoke:npm-package","observation":"Isolated tarball smoke test passed: CLI version/help and typed Bugbot API consumer.","date":"2026-09-30"}}, + {"id":"C022","assertion":"The packaged CLI reports its version and setup help.","status":"pass","evidence":{"kind":"command","command":"pnpm run smoke:npm-package","observation":"Isolated tarball smoke test passed: CLI version/help and typed Bugbot API consumer.","date":"2026-09-30"}}, + {"id":"C023","assertion":"The packaged Bugbot API includes its TypeScript declarations.","status":"pass","evidence":{"kind":"command","command":"pnpm run smoke:npm-package","observation":"Isolated tarball smoke test passed: CLI version/help and typed Bugbot API consumer.","date":"2026-09-30"}}, + {"id":"C024","assertion":"Action and API bundles exclude the local web server implementation.","status":"pass","evidence":{"kind":"command","command":"pnpm run smoke:npm-package","observation":"Isolated tarball smoke test passed: CLI version/help and typed Bugbot API consumer.","date":"2026-09-30"}}, + {"id":"C025","assertion":"The packaged CLI starts without Vite or source TypeScript files.","status":"pass","evidence":{"kind":"command","command":"pnpm run smoke:npm-package","observation":"Isolated tarball smoke test passed: CLI version/help and typed Bugbot API consumer.","date":"2026-09-30"}}, + {"id":"C026","assertion":"A separate TypeScript consumer resolves the typed Bugbot API.","status":"pass","evidence":{"kind":"command","command":"pnpm run smoke:npm-package","observation":"Isolated tarball smoke test passed: CLI version/help and typed Bugbot API consumer.","date":"2026-09-30"}}, + {"id":"C027","assertion":"The POSIX CLI launcher has executable mode after the production build.","status":"pass","evidence":{"kind":"command","command":"pnpm run build","observation":"Production build completed; CLI launcher executable mode set.","date":"2026-09-30"}}, + {"id":"C028","assertion":"local web setup architecture browser imports only redacted application contracts, as types, across the actual dependency graph","status":"pass","evidence":{"kind":"jest","file":"src/architecture/__tests__/web_setup_boundaries.test.ts","test":"local web setup architecture browser imports only redacted application contracts, as types, across the actual dependency graph"}}, + {"id":"C029","assertion":"local web setup architecture browser presenters cannot acquire transport, provider, or persistent-secret responsibilities","status":"pass","evidence":{"kind":"jest","file":"src/architecture/__tests__/web_setup_boundaries.test.ts","test":"local web setup architecture browser presenters cannot acquire transport, provider, or persistent-secret responsibilities"}}, + {"id":"C030","assertion":"local web setup architecture dependency reader includes re-exports, require, dynamic import and type-only forms","status":"pass","evidence":{"kind":"jest","file":"src/architecture/__tests__/web_setup_boundaries.test.ts","test":"local web setup architecture dependency reader includes re-exports, require, dynamic import and type-only forms"}}, + {"id":"C031","assertion":"local web setup architecture domain and application never import browser, HTTP server, or terminal adapters","status":"pass","evidence":{"kind":"jest","file":"src/architecture/__tests__/web_setup_boundaries.test.ts","test":"local web setup architecture domain and application never import browser, HTTP server, or terminal adapters"}}, + {"id":"C032","assertion":"local web setup architecture new setup application decisions have no transitive path to CLI, infrastructure, or browser adapters","status":"pass","evidence":{"kind":"jest","file":"src/architecture/__tests__/web_setup_boundaries.test.ts","test":"local web setup architecture new setup application decisions have no transitive path to CLI, infrastructure, or browser adapters"}}, + {"id":"C033","assertion":"local web setup architecture page shell and presenters remain small and styles have one explicit entrypoint","status":"pass","evidence":{"kind":"jest","file":"src/architecture/__tests__/web_setup_boundaries.test.ts","test":"local web setup architecture page shell and presenters remain small and styles have one explicit entrypoint"}}, + {"id":"C034","assertion":"application architecture boundaries keeps Bugbot reconciliation behind narrow contracts and one-way dependencies","status":"pass","evidence":{"kind":"jest","file":"src/application/__tests__/architecture_boundaries.test.ts","test":"application architecture boundaries keeps Bugbot reconciliation behind narrow contracts and one-way dependencies"}}, + {"id":"C035","assertion":"application architecture boundaries keeps canonical Bugbot finding contracts in the provider-neutral domain","status":"pass","evidence":{"kind":"jest","file":"src/application/__tests__/architecture_boundaries.test.ts","test":"application architecture boundaries keeps canonical Bugbot finding contracts in the provider-neutral domain"}}, + {"id":"C036","assertion":"application architecture boundaries keeps composition roots independent from entrypoint-owned contracts","status":"pass","evidence":{"kind":"jest","file":"src/application/__tests__/architecture_boundaries.test.ts","test":"application architecture boundaries keeps composition roots independent from entrypoint-owned contracts"}}, + {"id":"C037","assertion":"application architecture boundaries keeps lifecycle reconciliation dependent on a narrow context contract","status":"pass","evidence":{"kind":"jest","file":"src/application/__tests__/architecture_boundaries.test.ts","test":"application architecture boundaries keeps lifecycle reconciliation dependent on a narrow context contract"}}, + {"id":"U001","assertion":"web setup localization catalog all current plan warnings have exactly one translation per language","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog all current plan warnings have exactly one translation per language"}}, + {"id":"U002","assertion":"web setup localization catalog English is the default and only the four selected locales are advertised","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog English is the default and only the four selected locales are advertised"}}, + {"id":"U003","assertion":"web setup localization catalog every known questionnaire validation has localized copy and unknown text cannot leak English into other locales","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog every known questionnaire validation has localized copy and unknown text cannot leak English into other locales"}}, + {"id":"U004","assertion":"web setup localization catalog every literal permission reason and condition has exactly one translated key","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog every literal permission reason and condition has exactly one translated key"}}, + {"id":"U005","assertion":"web setup localization catalog every non-English preview explicitly discloses untranslated setup text","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog every non-English preview explicitly discloses untranslated setup text"}}, + {"id":"U006","assertion":"web setup localization catalog every prompt has the same translated keys, placeholders and choice count","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog every prompt has the same translated keys, placeholders and choice count"}}, + {"id":"U007","assertion":"web setup localization catalog every static HTTP error and final doctor/back failure has reviewed four-language copy","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog every static HTTP error and final doctor/back failure has reviewed four-language copy"}}, + {"id":"U008","assertion":"web setup localization catalog interpolation and stage names follow the selected locale","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog interpolation and stage names follow the selected locale"}}, + {"id":"U009","assertion":"web setup localization catalog local session errors have exact key parity and a translated unknown-error fallback","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog local session errors have exact key parity and a translated unknown-error fallback"}}, + {"id":"U010","assertion":"web setup localization catalog permission metadata uses translated labels without changing permission identities","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog permission metadata uses translated labels without changing permission identities"}}, + {"id":"U011","assertion":"web setup localization catalog plan review names every agent role in each supported language","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog plan review names every agent role in each supported language"}}, + {"id":"U012","assertion":"web setup localization catalog public permission and prompt copy translate known text and omit missing placeholders safely","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog public permission and prompt copy translate known text and omit missing placeholders safely"}}, + {"id":"U013","assertion":"web setup localization catalog question and plan presenters share the same localized Project Status transition labels","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog question and plan presenters share the same localized Project Status transition labels"}}, + {"id":"U014","assertion":"web setup localization catalog shared question labels route English and Spanish without leaking terminal selector hints","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog shared question labels route English and Spanish without leaking terminal selector hints"}}, + {"id":"U015","assertion":"web setup localization catalog static question options have the same keys in every translated catalog","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog static question options have the same keys in every translated catalog"}}, + {"id":"U016","assertion":"web setup localization catalog unknown server-side validation is not mislabeled as a known translated rule","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog unknown server-side validation is not mislabeled as a known translated rule"}}, + {"id":"U017","assertion":"web setup localization catalog unsupported runtime locale falls back to complete English copy","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_catalog.test.ts","test":"web setup localization catalog unsupported runtime locale falls back to complete English copy"}}, + {"id":"U018","assertion":"web setup component semantics blocked page identifies the cause and next action in the chosen language","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics blocked page identifies the cause and next action in the chosen language"}}, + {"id":"U019","assertion":"web setup component semantics boolean question presenter exposes the expected accessible control","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics boolean question presenter exposes the expected accessible control"}}, + {"id":"U020","assertion":"web setup component semantics boolean recommendations use the selected language rather than raw true or false","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics boolean recommendations use the selected language rather than raw true or false"}}, + {"id":"U021","assertion":"web setup component semantics choice question presenter exposes the expected accessible control","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics choice question presenter exposes the expected accessible control"}}, + {"id":"U022","assertion":"web setup component semantics choice recommendations translate their display label without changing the option value","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics choice recommendations translate their display label without changing the option value"}}, + {"id":"U023","assertion":"web setup component semantics completed Spanish result offers safe in-page verification and explains unverified Secret values","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics completed Spanish result offers safe in-page verification and explains unverified Secret values"}}, + {"id":"U024","assertion":"web setup component semantics en PAT-intent workflow question explains fixed feature overrides before input","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics en PAT-intent workflow question explains fixed feature overrides before input"}}, + {"id":"U025","assertion":"web setup component semantics es PAT-intent workflow question explains fixed feature overrides before input","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics es PAT-intent workflow question explains fixed feature overrides before input"}}, + {"id":"U026","assertion":"web setup component semantics fr PAT-intent workflow question explains fixed feature overrides before input","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics fr PAT-intent workflow question explains fixed feature overrides before input"}}, + {"id":"U027","assertion":"web setup component semantics French technical question guidance is complete, not a mixed-language preview","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics French technical question guidance is complete, not a mixed-language preview"}}, + {"id":"U028","assertion":"web setup component semantics language selector lists exactly the four supported languages, with English first","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics language selector lists exactly the four supported languages, with English first"}}, + {"id":"U029","assertion":"web setup component semantics multi-select question presenter exposes the expected accessible control","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics multi-select question presenter exposes the expected accessible control"}}, + {"id":"U030","assertion":"web setup component semantics non-question decisions show their purpose before the choices","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics non-question decisions show their purpose before the choices"}}, + {"id":"U031","assertion":"web setup component semantics numeric coverage plan review includes the exact threshold, reporter and operator attestation in Spanish","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics numeric coverage plan review includes the exact threshold, reporter and operator attestation in Spanish"}}, + {"id":"U032","assertion":"web setup component semantics pt PAT-intent workflow question explains fixed feature overrides before input","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics pt PAT-intent workflow question explains fixed feature overrides before input"}}, + {"id":"U033","assertion":"web setup component semantics question details explain where, how and why, with a safe contextual link","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics question details explain where, how and why, with a safe contextual link"}}, + {"id":"U034","assertion":"web setup component semantics scope-overrides question presenter exposes the expected accessible control","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics scope-overrides question presenter exposes the expected accessible control"}}, + {"id":"U035","assertion":"web setup component semantics successive question revisions render their own default values","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics successive question revisions render their own default values"}}, + {"id":"U036","assertion":"web setup component semantics text question presenter exposes the expected accessible control","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics text question presenter exposes the expected accessible control"}}, + {"id":"U037","assertion":"setup question documentation agents.findings.executable has a related, locally documented destination","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_question_documentation_policy.test.ts","test":"setup question documentation agents.findings.executable has a related, locally documented destination"}}, + {"id":"U038","assertion":"setup question documentation agents.findings.model has a related, locally documented destination","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_question_documentation_policy.test.ts","test":"setup question documentation agents.findings.model has a related, locally documented destination"}}, + {"id":"U039","assertion":"setup question documentation agents.planner.provider has a related, locally documented destination","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_question_documentation_policy.test.ts","test":"setup question documentation agents.planner.provider has a related, locally documented destination"}}, + {"id":"U040","assertion":"setup question documentation ai.bugbotFixVerifyCommands has a related, locally documented destination","status":"pass","evidence":{"kind":"jest","file":"src/application/policies/__tests__/setup_question_documentation_policy.test.ts","test":"setup question documentation ai.bugbotFixVerifyCommands has a related, locally documented destination"}}, + {"id":"U041","assertion":"The pending view is legible in light mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The pending view is legible in light mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U042","assertion":"The pending view is legible in dark mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The pending view is legible in dark mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U043","assertion":"The action required view is legible in light mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The action required view is legible in light mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U044","assertion":"The action required view is legible in dark mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The action required view is legible in dark mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U045","assertion":"The blocked view is legible in light mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The blocked view is legible in light mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U046","assertion":"The blocked view is legible in dark mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The blocked view is legible in dark mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U047","assertion":"The partial view is legible in light mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The partial view is legible in light mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U048","assertion":"The partial view is legible in dark mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The partial view is legible in dark mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U049","assertion":"The completed view is legible in light mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The completed view is legible in light mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U050","assertion":"The completed view is legible in dark mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The completed view is legible in dark mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U051","assertion":"The cancelled view is legible in light mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The cancelled view is legible in light mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U052","assertion":"The cancelled view is legible in dark mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The cancelled view is legible in dark mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U053","assertion":"The expired view is legible in light mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The expired view is legible in light mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U054","assertion":"The expired view is legible in dark mode with clear current status, retained facts, next action and focus.","status":"open","evidence":{"kind":"human","checklist":"The expired view is legible in dark mode with clear current status, retained facts, next action and focus. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U055","assertion":"web setup component semantics choice prompt escapes untrusted text and disables a read-only controller","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics choice prompt escapes untrusted text and disables a read-only controller"}}, + {"id":"U056","assertion":"web setup component semantics manual producer App ID remains string-bound while offering a numeric keyboard","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics manual producer App ID remains string-bound while offering a numeric keyboard"}}, + {"id":"U057","assertion":"web setup component semantics secret presenter uses a password input and only an allowlisted GitHub URL","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics secret presenter uses a password input and only an allowlisted GitHub URL"}}, + {"id":"U058","assertion":"web setup presentation helpers Enter and button pairing share strict code and busy validation","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers Enter and button pairing share strict code and busy validation"}}, + {"id":"U059","assertion":"web setup presentation helpers focus follows a new prompt revision but not background status polls","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers focus follows a new prompt revision but not background status polls"}}, + {"id":"U060","assertion":"web setup component semantics a Project retained across discovery refresh remains visible as unverified and removable","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics a Project retained across discovery refresh remains visible as unverified and removable"}}, + {"id":"U061","assertion":"web setup component semantics blocked result explains actual mutation state and PAT cleanup","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics blocked result explains actual mutation state and PAT cleanup"}}, + {"id":"U062","assertion":"web setup component semantics cancelled result explains actual mutation state and PAT cleanup","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics cancelled result explains actual mutation state and PAT cleanup"}}, + {"id":"U063","assertion":"web setup component semantics complete result explains actual mutation state and PAT cleanup","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics complete result explains actual mutation state and PAT cleanup"}}, + {"id":"U064","assertion":"web setup component semantics coverage choice links back to the selected exact CI producer","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics coverage choice links back to the selected exact CI producer"}}, + {"id":"U065","assertion":"web setup component semantics coverage selector shows the selected producer identity and the observation limitation","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics coverage selector shows the selected producer identity and the observation limitation"}}, + {"id":"U066","assertion":"web setup component semantics credential presenter rejects an untrusted external URL","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics credential presenter rejects an untrusted external URL"}}, + {"id":"U067","assertion":"web setup component semantics discovery scope is specific and unsupported personal Projects do not offer retry","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics discovery scope is specific and unsupported personal Projects do not offer retry"}}, + {"id":"U068","assertion":"web setup component semantics dry-run result explains actual mutation state and PAT cleanup","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics dry-run result explains actual mutation state and PAT cleanup"}}, + {"id":"U069","assertion":"web setup component semantics empty issue workflow selection still has an enabled Continue control","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics empty issue workflow selection still has an enabled Continue control"}}, + {"id":"U070","assertion":"web setup component semantics en has a localized pairing screen","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics en has a localized pairing screen"}}, + {"id":"U071","assertion":"web setup component semantics en Project discovery offers a localized bounded retry without claiming the organization is empty","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics en Project discovery offers a localized bounded retry without claiming the organization is empty"}}, + {"id":"U072","assertion":"web setup component semantics en Project selector explains permission denial and manual fallback","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics en Project selector explains permission denial and manual fallback"}}, + {"id":"U073","assertion":"web setup component semantics es has a localized pairing screen","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics es has a localized pairing screen"}}, + {"id":"U074","assertion":"web setup component semantics es Project discovery offers a localized bounded retry without claiming the organization is empty","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_components.test.ts","test":"web setup component semantics es Project discovery offers a localized bounded retry without claiming the organization is empty"}}, + {"id":"U075","assertion":"In English, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In English, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U076","assertion":"In English, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In English, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U077","assertion":"In English, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In English, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U078","assertion":"In English, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In English, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U079","assertion":"In English, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In English, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U080","assertion":"In Spanish, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Spanish, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U081","assertion":"In Spanish, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Spanish, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U082","assertion":"In Spanish, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Spanish, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U083","assertion":"In Spanish, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Spanish, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U084","assertion":"In Spanish, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Spanish, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U085","assertion":"In French, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In French, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U086","assertion":"In French, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In French, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U087","assertion":"In French, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In French, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U088","assertion":"In French, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In French, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U089","assertion":"In French, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In French, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U090","assertion":"In Portuguese, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Portuguese, verify the complete setup journey with keyboard-only navigation and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U091","assertion":"In Portuguese, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Portuguese, verify the complete setup journey with screen reader announcements and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U092","assertion":"In Portuguese, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Portuguese, verify the complete setup journey with 200% browser zoom and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U093","assertion":"In Portuguese, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Portuguese, verify the complete setup journey with 320px responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U094","assertion":"In Portuguese, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable.","status":"open","evidence":{"kind":"human","checklist":"In Portuguese, verify the complete setup journey with tablet responsive layout and record whether progress, errors and recovery are perceivable. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"U095","assertion":"web setup presentation helpers absent documentation link remains absent","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers absent documentation link remains absent"}}, + {"id":"U096","assertion":"web setup presentation helpers allowlisted GitHub link http://github.com/settings/personal-access-tokens: false","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers allowlisted GitHub link http://github.com/settings/personal-access-tokens: false"}}, + {"id":"U097","assertion":"web setup presentation helpers allowlisted GitHub link https://evil.example/settings/personal-access-tokens: false","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers allowlisted GitHub link https://evil.example/settings/personal-access-tokens: false"}}, + {"id":"U098","assertion":"web setup presentation helpers allowlisted GitHub link https://github.com/settings/keys: false","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers allowlisted GitHub link https://github.com/settings/keys: false"}}, + {"id":"U099","assertion":"web setup presentation helpers allowlisted GitHub link https://github.com/settings/personal-access-tokens/new?name=Setup: true","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers allowlisted GitHub link https://github.com/settings/personal-access-tokens/new?name=Setup: true"}}, + {"id":"U100","assertion":"web setup presentation helpers allowlisted GitHub link https://github.com/settings/personal-access-tokens: true","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers allowlisted GitHub link https://github.com/settings/personal-access-tokens: true"}}, + {"id":"U101","assertion":"web setup presentation helpers allowlisted GitHub link javascript:alert(1): false","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_ui_helpers.test.ts","test":"web setup presentation helpers allowlisted GitHub link javascript:alert(1): false"}}, + {"id":"I001","assertion":"semantic web setup adapters a cancelled choice and a corrected bootstrap link do not grant access","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters a cancelled choice and a corrected bootstrap link do not grant access"}}, + {"id":"I002","assertion":"semantic web setup adapters a cancelled plan and cancelled workflow decision do not approve anything","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters a cancelled plan and cancelled workflow decision do not approve anything"}}, + {"id":"I003","assertion":"semantic web setup adapters a web discovery retry refreshes the current Project question without restarting the questionnaire","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters a web discovery retry refreshes the current Project question without restarting the questionnaire"}}, + {"id":"I004","assertion":"semantic web setup adapters API key and existing credential decisions stay in separate secret/choice prompts","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters API key and existing credential decisions stay in separate secret/choice prompts"}}, + {"id":"I005","assertion":"semantic web setup adapters back navigation shows the earlier web question within the same run","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters back navigation shows the earlier web question within the same run"}}, + {"id":"I006","assertion":"semantic web setup adapters cancelled bot-login and optional API-key inputs never produce credentials","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters cancelled bot-login and optional API-key inputs never produce credentials"}}, + {"id":"I007","assertion":"semantic web setup adapters collects policy-owned intent questions without terminal prompt parsing","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters collects policy-owned intent questions without terminal prompt parsing"}}, + {"id":"I008","assertion":"semantic web setup adapters credential explanation and checks distinguish invalid from verified evidence","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters credential explanation and checks distinguish invalid from verified evidence"}}, + {"id":"I009","assertion":"semantic web setup adapters guided bot token uses distinct GitHub link, numeric identity, and masked handoff","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters guided bot token uses distinct GitHub link, numeric identity, and masked handoff"}}, + {"id":"I010","assertion":"semantic web setup adapters guided cleanup and corrected link are visible without token values","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters guided cleanup and corrected link are visible without token values"}}, + {"id":"I011","assertion":"semantic web setup adapters guided setup account requires a reported identity and a positive operator decision","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters guided setup account requires a reported identity and a positive operator decision"}}, + {"id":"I012","assertion":"semantic web setup adapters intent review Continue to GitHub resolves to continue","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_adapters.test.ts","test":"semantic web setup adapters intent review Continue to GitHub resolves to continue"}}, + {"id":"I013","assertion":"browser session transport a rejected answer refreshes the question while keeping the error visible and the PAT private","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport a rejected answer refreshes the question while keeping the error visible and the PAT private"}}, + {"id":"I014","assertion":"browser session transport control transfer during cancellation reconnects without reporting success","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport control transfer during cancellation reconnects without reporting success"}}, + {"id":"I015","assertion":"browser session transport control transfer reconnects as read-only and does not replay an answer","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport control transfer reconnects as read-only and does not replay an answer"}}, + {"id":"I016","assertion":"browser session transport controller transfer during a discovery retry reconnects read-only and never replays it","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport controller transfer during a discovery retry reconnects read-only and never replays it"}}, + {"id":"I017","assertion":"browser session transport doctor failure preserves success, reports the error, and refreshes the failed status","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport doctor failure preserves success, reports the error, and refreshes the failed status"}}, + {"id":"I018","assertion":"browser session transport overlapping refresh calls do not race to replace the current view","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport overlapping refresh calls do not race to replace the current view"}}, + {"id":"I019","assertion":"browser session transport read-only doctor is available only after success to the controller, refreshes redacted results, and cannot run twice concurrently","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport read-only doctor is available only after success to the controller, refreshes redacted results, and cannot run twice concurrently"}}, + {"id":"I020","assertion":"browser session transport takeover replaces the controller capability and refreshes server-owned state","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport takeover replaces the controller capability and refreshes server-owned state"}}, + {"id":"I021","assertion":"SetupDoctorUseCase continues local diagnosis and skips every remote dependant after PAT failure","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase continues local diagnosis and skips every remote dependant after PAT failure"}}, + {"id":"I022","assertion":"SetupDoctorUseCase distinguishes missing, mismatched, and intentionally preserved variables","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase distinguishes missing, mismatched, and intentionally preserved variables"}}, + {"id":"I023","assertion":"SetupDoctorUseCase does not invoke credential health when no required Secret is present","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase does not invoke credential health when no required Secret is present"}}, + {"id":"I024","assertion":"SetupDoctorUseCase fails every invalid alternative and a group with no allowed runner authentication","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase fails every invalid alternative and a group with no allowed runner authentication"}}, + {"id":"I025","assertion":"SetupDoctorUseCase fails required organization access","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase fails required organization access"}}, + {"id":"I026","assertion":"SetupDoctorUseCase keeps declared report order when remote probes resolve out of order","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase keeps declared report order when remote probes resolve out of order"}}, + {"id":"I027","assertion":"SetupDoctorUseCase keeps independent root and PAT checks when configuration is invalid","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase keeps independent root and PAT checks when configuration is invalid"}}, + {"id":"I028","assertion":"SetupDoctorUseCase maps a merge-queue provider failure to one check without hiding resource checks","status":"pass","evidence":{"kind":"jest","file":"src/application/usecases/setup/__tests__/doctor_use_case.test.ts","test":"SetupDoctorUseCase maps a merge-queue provider failure to one check without hiding resource checks"}}, + {"id":"I029","assertion":"setup configuration file loader accepts independent organization storage policies without credential values","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader accepts independent organization storage policies without credential values"}}, + {"id":"I030","assertion":"setup configuration file loader accepts JSON because JSON is a YAML-compatible document","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader accepts JSON because JSON is a YAML-compatible document"}}, + {"id":"I031","assertion":"setup configuration file loader accepts non-secret credential management switches in the override file","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader accepts non-secret credential management switches in the override file"}}, + {"id":"I032","assertion":"setup configuration file loader loads a typed YAML override object","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader loads a typed YAML override object"}}, + {"id":"I033","assertion":"setup configuration file loader loads structured merge-queue attestations without string coercion","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader loads structured merge-queue attestations without string coercion"}}, + {"id":"I034","assertion":"setup configuration file loader rejects a secret-like value","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader rejects a secret-like value"}}, + {"id":"I035","assertion":"setup configuration file loader rejects a wrong nested type","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader rejects a wrong nested type"}}, + {"id":"I036","assertion":"setup configuration file loader rejects an invalid merge-queue attestation","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/setup_config_file.test.ts","test":"setup configuration file loader rejects an invalid merge-queue attestation"}}, + {"id":"I037","assertion":"On macOS, verify packaged setup --web launch and pairing with local fixture-only repository and capture terminal/browser evidence.","status":"open","evidence":{"kind":"human","checklist":"On macOS, verify packaged setup --web launch and pairing with local fixture-only repository and capture terminal/browser evidence. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"I038","assertion":"On macOS, verify packaged setup --web browser-open fallback with local fixture-only repository and capture terminal/browser evidence.","status":"open","evidence":{"kind":"human","checklist":"On macOS, verify packaged setup --web browser-open fallback with local fixture-only repository and capture terminal/browser evidence. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"I039","assertion":"On Linux, verify packaged setup --web launch and pairing with local fixture-only repository and capture terminal/browser evidence.","status":"open","evidence":{"kind":"human","checklist":"On Linux, verify packaged setup --web launch and pairing with local fixture-only repository and capture terminal/browser evidence. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"I040","assertion":"On Linux, verify packaged setup --web browser-open fallback with local fixture-only repository and capture terminal/browser evidence.","status":"open","evidence":{"kind":"human","checklist":"On Linux, verify packaged setup --web browser-open fallback with local fixture-only repository and capture terminal/browser evidence. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"I041","assertion":"On Windows, verify packaged setup --web launch and pairing with local fixture-only repository and capture terminal/browser evidence.","status":"open","evidence":{"kind":"human","checklist":"On Windows, verify packaged setup --web launch and pairing with local fixture-only repository and capture terminal/browser evidence. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"I042","assertion":"On Windows, verify packaged setup --web browser-open fallback with local fixture-only repository and capture terminal/browser evidence.","status":"open","evidence":{"kind":"human","checklist":"On Windows, verify packaged setup --web browser-open fallback with local fixture-only repository and capture terminal/browser evidence. Record reviewer, date, browser/OS, assistive technology where applicable, and observed result."}}, + {"id":"X001","assertion":"local web setup server a correct pairing resets prior wrong-code attempts","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server a correct pairing resets prior wrong-code attempts"}}, + {"id":"X002","assertion":"local web setup server allows only the paired controller to explicitly retry the current discovery revision","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server allows only the paired controller to explicitly retry the current discovery revision"}}, + {"id":"X003","assertion":"local web setup server five incorrect pairing attempts cause a recoverable cooldown, not a permanent lockout","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server five incorrect pairing attempts cause a recoverable cooldown, not a permanent lockout"}}, + {"id":"X004","assertion":"local web setup server pairing rejects missing, cross-origin, and incorrect codes without exposing the session key","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server pairing rejects missing, cross-origin, and incorrect codes without exposing the session key"}}, + {"id":"X005","assertion":"local web setup server pairing requires JSON even for a valid code","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server pairing requires JSON even for a valid code"}}, + {"id":"X006","assertion":"local web setup server rejects forged hosts and cross-origin mutation","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server rejects forged hosts and cross-origin mutation"}}, + {"id":"X007","assertion":"local web setup server rejects proxy or cross-site context {\"Forwarded\":\"host=evil.example\"}","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server rejects proxy or cross-site context {\"Forwarded\":\"host=evil.example\"}"}}, + {"id":"X008","assertion":"local web setup server rejects proxy or cross-site context {\"X-Forwarded-Host\":\"evil.example\"}","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server rejects proxy or cross-site context {\"X-Forwarded-Host\":\"evil.example\"}"}}, + {"id":"X009","assertion":"local web setup server authorizes back navigation by revision without replaying the entire setup session","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server authorizes back navigation by revision without replaying the entire setup session"}}, + {"id":"X010","assertion":"local web setup server cancel requires the controller and never claims to cancel in-flight Apply","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server cancel requires the controller and never claims to cancel in-flight Apply"}}, + {"id":"X011","assertion":"local web setup server close is rejected before a result and succeeds for the finished controller","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server close is rejected before a result and succeeds for the finished controller"}}, + {"id":"X012","assertion":"local web setup server limits wrong-code takeover attempts temporarily without returning a controller capability","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server limits wrong-code takeover attempts temporarily without returning a controller capability"}}, + {"id":"X013","assertion":"local web setup server mutating requests without a controller capability do nothing","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server mutating requests without a controller capability do nothing"}}, + {"id":"X014","assertion":"local web setup server post-success read-only verification requires the controller and returns only redacted counts","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server post-success read-only verification requires the controller and returns only redacted counts"}}, + {"id":"X015","assertion":"WebSetupBridge a second tab is read-only until takeover and old capabilities fail","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_bridge.test.ts","test":"WebSetupBridge a second tab is read-only until takeover and old capabilities fail"}}, + {"id":"X016","assertion":"local web setup server a finished session closes itself after its result-reading window","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server a finished session closes itself after its result-reading window"}}, + {"id":"X017","assertion":"local web setup server a key from a different local setup run cannot bootstrap this session","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server a key from a different local setup run cannot bootstrap this session"}}, + {"id":"X018","assertion":"local web setup server accepts one authorized answer and never returns the submitted PAT","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server accepts one authorized answer and never returns the submitted PAT"}}, + {"id":"X019","assertion":"local web setup server the public loopback URL contains no secret and API access requires terminal pairing","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server the public loopback URL contains no secret and API access requires terminal pairing"}}, + {"id":"X020","assertion":"browser session transport bootstrap and revision-bound submission keep the PAT out of observable state","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport bootstrap and revision-bound submission keep the PAT out of observable state"}}, + {"id":"X021","assertion":"browser session transport pairs through same-origin POST and keeps code and key out of observable state","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_browser_session.test.ts","test":"browser session transport pairs through same-origin POST and keeps code and key out of observable state"}}, + {"id":"X022","assertion":"local web setup server a second tab explicitly takes over and invalidates the first tab capability","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server a second tab explicitly takes over and invalidates the first tab capability"}}, + {"id":"X023","assertion":"local web setup server an asset replaced by an escaping symlink is not served","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server an asset replaced by an escaping symlink is not served"}}, + {"id":"X024","assertion":"local web setup server bounds simultaneous loopback connections","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server bounds simultaneous loopback connections"}}, + {"id":"X025","assertion":"local web setup server ends a response safely if an asset write fails after headers were sent","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server ends a response safely if an asset write fails after headers were sent"}}, + {"id":"X026","assertion":"local web setup server startup refuses an index symlink outside the asset root","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server startup refuses an index symlink outside the asset root"}}, + {"id":"X027","assertion":"local web setup server startup refuses missing or symlinked packaged assets","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server startup refuses missing or symlinked packaged assets"}}, + {"id":"X028","assertion":"local web setup server uses the packaged web asset location when no override is supplied","status":"pass","evidence":{"kind":"jest","file":"src/cli/__tests__/web_setup_server.test.ts","test":"local web setup server uses the packaged web asset location when no override is supplied"}} + ] +} diff --git a/specs/local-web-setup-assistant.md b/specs/local-web-setup-assistant.md index 4aa015a6b..27f0280d9 100644 --- a/specs/local-web-setup-assistant.md +++ b/specs/local-web-setup-assistant.md @@ -3,10 +3,10 @@ - Status: Implementation in progress — target contract, not yet release acceptance - Date: 2026-09-28 - Catalog capability ID: `local-web-setup-assistant` -- Last verified: 2026-09-29 (source/build tests and screenshot review; no live GitHub setup or dogfooding) +- Last verified: 2026-10-02 (PR #402 merge baseline and fixture-only follow-up evidence are recorded below; the operator incident is external evidence, not agent dogfooding) - Owners: Copilot maintainers; product, security, and accessibility reviewers - Scope: optional, local Svelte-based presentation of the existing repository setup journey, sharing its policy, credential, and application engine with the terminal -- Related issues/PRs: [PR #402](https://github.com/vypdev/copilot/pull/402) carries this implementation alongside the earlier guided PAT work; no test issue or Action is created +- Related issues/PRs: [merged PR #402](https://github.com/vypdev/copilot/pull/402) established the baseline; this follow-up starts from its merge on `develop`. No test issue or Action is created. - Required review gates: product UX, Clean Architecture, browser/loopback security, credential handling, packaging, cross-platform operation, accessibility, testing, documentation - Open decisions blocking readiness: none at the product-contract level; implementation MUST still pass the security and packaged-install review gates below @@ -442,6 +442,20 @@ single-flight and cannot be entered if the approval use case did not return an approved result. Deterministic fake-port tests cover every drift category, cancel/expiry interleavings, and audit outcomes. +The follow-up extraction MUST introduce a frontend-neutral application session +coordinator that owns the order and terminal classification of repository +confirmation, choice collection, operator PAT verification, plan review, +credential collection, final authorization, Apply, and result recording. +Its ports express these semantic operations and emit immutable progress facts; +CLI and web composition supply existing use cases and presentation adapters. +The coordinator MUST own cancellation checks before every external operation, +the single-flight Apply transition, and the distinction between a failure +before any possible write and an ambiguous or confirmed partial write. Moving +the command body into a different infrastructure file without these decisions +in application is not an acceptable extraction. The CLI command retains flag +parsing, dependency composition, exit-code adaptation, and terminal cleanup. +The browser retains HTTP/capability validation and redacted rendering. + The pre-PAT permission-intent review is likewise an application use case: it owns questionnaire transitions, owner-kind conflict checks, provisional grant calculation, review passes, and guided-link eligibility. Terminal and @@ -537,6 +551,18 @@ Both terminal and web routes use the same questionnaire parser for this choice. browser uses bounded polling or server events for **read-only** progress; reconnecting to the same live process retrieves redacted current state, not secret values or an implicit retry. +- Progress is an ordered, append-only sequence of semantic stage and resource + transitions. A resource receipt has a stable ID, scope, and one of + `not-started`, `in-progress`, `completed`, `skipped`, or `needs-inspection`. + `needs-inspection` covers a request whose remote effect cannot be proven, + including process exit during an in-flight write; it MUST never be presented + as rollback. A bounded public view may project this ledger but may not + infer completion from an attempted call. Cancellation before Apply records + no resource writes. Cancellation after mutation begins is rejected and the + running operation reports its eventual receipt. Expiry and process exit + dispose in-memory authority; after process exit a new invocation begins a + fresh review, never a resumed approval. The operator uses existing GitHub + and local evidence to inspect ambiguous effects before retrying. ### 8.3 Executable architecture and packaging constraints @@ -1325,6 +1351,51 @@ existing CLI tests are retained, not re-counted as new web evidence. | Security/abuse | 28 | forged links, stale revisions/controller takeover, PAT exclusion, permissions and least-privilege fallback | | **Total** | **350** | No double counting | +The acceptance ledger is [`local-web-setup-assistant-acceptance.json`](./local-web-setup-assistant-acceptance.json). +It MUST contain one row per ID below with an observable assertion, the +automated test or explicit human evidence, and `pass`/`open` status. Ranges +partition the 350 cases; a Jest count alone cannot close an ID. A human row +remains open until a reviewer records browser/OS, viewport or zoom, assistive +technology where relevant, locale, date, and observed result. Each automated +row must identify a focused assertion or table case; one test cannot be used +as evidence for unrelated rows. + +| IDs | Cases | Acceptance family | +|---|---:|---| +| P001–P012 | 12 | choice normalization and bounded configuration | +| P013–P022 | 10 | dependent invalidation and revision | +| P023–P032 | 10 | grant/role derivation and final audit | +| P033–P042 | 10 | plan and resource projection | +| P043–P048 | 6 | Project Status compatibility | +| S001–S010 | 10 | stage order and terminal outcomes | +| S011–S020 | 10 | edit, replay, revision and controller ownership | +| S021–S028 | 8 | PAT identity and permission transitions | +| S029–S038 | 10 | concurrent Apply and stale authorization | +| S039–S046 | 8 | cancellation, idle expiry and process exit | +| S047–S054 | 8 | resource progress, partial receipt and retry guidance | +| A001–A010 | 10 | bounded GitHub discovery | +| A011–A018 | 8 | resource inventory and scope | +| A019–A030 | 12 | HTTP status, provider errors and retry | +| A031–A040 | 10 | checkout and remote drift | +| C001–C009 | 9 | CLI flags, help and unattended compatibility | +| C010–C017 | 8 | CLI progress and result wording | +| C018–C027 | 10 | packaged npm install and asset parity | +| C028–C037 | 10 | workflow/bundle/architecture isolation | +| U001–U040 | 40 | four-language semantic copy and options | +| U041–U054 | 14 | seven terminal views in light and dark | +| U055–U074 | 20 | prompt, progress, input and focus interaction | +| U075–U094 | 20 | keyboard, screen reader, 200% zoom and responsive review | +| U095–U101 | 7 | untrusted text/link rendering | +| I001–I012 | 12 | CLI/web parity on the same semantic fixtures | +| I013–I020 | 8 | reconnect and answer replay | +| I021–I028 | 8 | partial recovery and doctor isolation | +| I029–I036 | 8 | config and package compatibility | +| I037–I042 | 6 | macOS, Linux and Windows launch/fallback | +| X001–X008 | 8 | pairing, Host, Origin and cooldown | +| X009–X016 | 8 | controller, CSRF, revision and idempotency | +| X017–X022 | 6 | PAT redaction, lifetime and role separation | +| X023–X028 | 6 | path, symlink, asset and local-only boundaries | + Within the 101 UI cases, cover at least one render/interaction for each prompt presenter, one revision-change form reset, secret clearing before dispatch, read-only disabling, all outcome variants, and both theme palettes. Static @@ -1483,6 +1554,11 @@ help for `--web` explains local-only scope and the `--non-interactive` conflict. every high-risk question identifies source, recommendation and consequence, errors identify the exact field and correction, and progress/result changes are announced without relying on color or a terminal window. +29. Given setup stops at the PAT audit, the browser result retains the last + redacted permission report and shows each required missing or unverifiable + grant with its scope and access level in the selected locale. If identity + itself failed, the result says so separately. A completed or unrelated + blocked result must not attribute an earlier PAT report as its cause. ## 17. Requirements traceability @@ -1497,6 +1573,8 @@ help for `--web` explains local-only scope and the `--non-interactive` conflict. | Accessible truthful UX (§9) | Svelte presenter + message catalog | scenarios 5–7, 10–11, 13–14 | how-to-use, troubleshooting | | Complete question help and links (§9.3–9.5) | application semantic help catalog + English CLI renderer + four-language web presenter | scenarios 17–20; exhaustive ID/link/locale gates | how-to-use, configuration, authentication, agents | | First-run completion (§9.6) | pure questionnaire/evidence policies, application session/edit/receipt use cases, read-only provider ports, CLI/web presenters | scenarios 21–28; 76 added risk-derived cases plus human first-use review | how-to-use, authentication, troubleshooting, configuration | +| Actionable PAT failure result (§9, §10) | redacted web permission report and result presenter | scenario 29; four-locale semantic fixture, unrelated-result exclusion, missing-report fallback | authentication, troubleshooting | +| Human acceptance review | [`docs/development/setup-assistant-review.mdx`](../docs/development/setup-assistant-review.mdx) | fixture-only seven-state, four-language, accessibility and platform checklist | acceptance ledger `U041–U054`, `U075–U094`, `I037–I042` | ## 18. Implementation sequence and current evidence @@ -1523,8 +1601,8 @@ answer normalization, allowlisted links, and revision/capability transport. This decomposition is an implementation slice, not evidence of the still-open application coordinator and full UI/accessibility acceptance gates. -These facts are **not** release acceptance. The orchestration in -`src/cli/commands/setup.ts` still needs extraction into the prescribed +These 2026-09-29 facts are **not** release acceptance. The orchestration in +`src/cli/commands/setup.ts` still needed extraction into the prescribed application-level session coordinator; the revised 350-case budget, full human cross-platform/accessibility review, exact per-resource progress/partial evidence, and adversarial concurrency/idle/crash suite remain open. The @@ -1620,8 +1698,9 @@ These measurements do **not** close independent linguistic, keyboard/screen- reader, 200%-zoom, dark/light, real-browser/cross-platform, or full 350-case acceptance review. A disk-persisted resume remains a separately specified future capability; this slice supports reconnecting to a live session only. -The CLI orchestration has not yet been extracted into the prescribed -frontend-neutral coordinator. Until these gates are evidenced, the catalog +At the 2026-09-29 baseline, the CLI orchestration had not yet been extracted +into the prescribed frontend-neutral coordinator. Until the remaining gates +are evidenced, the catalog remains `proposed` and the non-English browser notice remains a translation preview, not an unconditional release-quality claim. @@ -1643,6 +1722,71 @@ button state and form submission, so Enter cannot consume invalid attempts or bypass a busy state. Structural tests cover accepted hex input, incomplete and non-hex input, and the busy state. Server-side rate limiting remains authoritative. +The 2026-09-30 follow-up adds `SetupSessionCoordinator` in the application +layer and has both CLI and web invocation use the same ordered semantic +phase ports. The command now registers flags and delegates execution; +separate composition modules handle pre-PAT presentation, web Apply adapters, +and terminal outcome wording. Fake-port tests cover once-only execution, +ordered stages, stale/cancelled/expired approval, concurrent calls, and +partial classification after a possible write. The provisioning workflow +emits value-free `in-progress` and terminal resource transitions; the browser +displays them while Apply runs and conservatively changes an interrupted +in-progress state to `needs-inspection`. The final structured receipt remains +the result authority. Empty action results no longer count as success. + +The 350-row acceptance ledger records distinct assertions and exact test +names or an explicit human checklist. The ledger validator checks the ID +partition, uniqueness, evidence paths, exact passing Jest titles from the +coverage run, and prevents an unevidenced human `pass`. The 2026-09-30 local +run passed 510 suites and 5,734 tests. Overall coverage was 96.19% +statements, 91.36% branches, 96.88% functions, and 97.49% lines; all +configured module budgets passed. The ledger records **310 passed and 40 +open**, with every open row requiring direct human observation. Production +build, Svelte check, typecheck, lint, workflow, documentation and catalog +validators passed; an isolated npm tarball passed content and executable/API +smoke checks. Browser inspection of the pending and partial fixtures caught +and corrected four-language result copy that falsely said Apply had not +started despite an uncertain Secret receipt. The four-language regression +passed, but this limited inspection does not certify the full UI review. +The prior Linux and Windows CI fixture jobs exercised build, typecheck, local +server, session guard, snapshot, and coordinator behavior; Linux also checked +the isolated npm package. These jobs are coverage opportunities, not evidence +of a real-browser or global-install review until their checks run. Human +keyboard/screen-reader, 200%-zoom, light/dark, linguistic, and cross-platform +launch/fallback observations remain explicitly open. The catalog remains +`proposed`; neither source tests nor an unreviewed CI configuration imply +release readiness. + +The 2026-10-02 operator report exposed a blocked PAT result that hid the +permission report while instructing the operator to check it. The terminal +showed only the aggregate rejection, so the diagnostic reference alone could +not identify the grant. This follow-up requires the blocked browser result to +retain and display safe, localized permission evidence; it must never display +the PAT or pairing code. The incident also selected organization Projects, +which exposed a missing read-only probe described in the permission SDD. +Fixture tests add this regression to the existing acceptance budget; they do +not close the human visual/accessibility or live-provider gates. The local +coverage run passed 511 suites / 5,752 tests, with 96.19% statements, 91.37% +branches, 96.88% functions, and 97.49% lines overall. The acceptance ledger +remains 310/350 passed and 40 human-review rows open. + +The same PR exposed a runner-routing risk: `codex` now selects self-hosted +Windows as well as macOS and will also select Ubuntu. A push-review `run` +step inherited PowerShell on Windows and was stopped by the host's signed +script policy before the Action ran. Every installed `codex` workflow with a +`run` step MUST select Bash explicitly, including CI, review, merge-queue and +release preparation; distributed push/PR templates MUST retain Bash for their +POSIX review-range scripts. Workflow validation MUST reject a new `run` step +that silently inherits a platform-dependent shell. The isolated setup fixture +workflow MUST run build, typecheck, session fixtures and npm-pack smoke on +Ubuntu, Windows and macOS. The npm validation scripts MUST invoke npm without +depending on Windows `.cmd` direct-execution behavior or privileged symlink +creation. A green fixture job proves only its tested path; Action execution, +child-process cancellation, and release +preparation on each self-hosted platform remain open until direct runner +evidence exists. No live setup or credential-bearing test dispatch is allowed +to close those gates. + 1. Review this threat model and UI prototype with product/security/accessibility; freeze semantic transport schemas, redacted views, and error taxonomy. 2. Extract the existing CLI orchestration into a frontend-neutral setup diff --git a/specs/setup-configuration-credentials-and-doctor.md b/specs/setup-configuration-credentials-and-doctor.md index f3cd1c1ac..45c0eb180 100644 --- a/specs/setup-configuration-credentials-and-doctor.md +++ b/specs/setup-configuration-credentials-and-doctor.md @@ -2,9 +2,9 @@ - Status: Implemented — automated architecture, UX, documentation, and coverage gates complete; controlled live GitHub permission-path evidence remains external - Date: 2026-09-11 -- Last updated: 2026-09-28 +- Last updated: 2026-09-30 - Catalog capability ID: `setup-and-doctor` -- Last verified: 2026-09-28 (automated journey/presentation gates; live GitHub path remains external) +- Last verified: 2026-09-30 (shared-session and resource-progress fixture evidence; live GitHub path remains external) - Owners: Copilot maintainers - Scope: interactive/non-interactive installation planning, file and resource provisioning, credential validation, and metadata-only diagnosis - Related issues/PRs: merge-queue readiness SDD; architecture quality and @@ -239,10 +239,10 @@ rules, secret serialization, backups, and confirmation are not configurable. |---|---|---| | Domain | setup plan/check/value types | prompts/Octokit/fs | | Policies | defaults, immutable clone/questionnaire, validation, storage, plans, typed message catalogs, doctor report | terminal I/O or language/provider selection | -| Use cases | drive questionnaire, credential decisions, provision, doctor probes, resolve one complete doctor catalog | provider DTOs or feature-local language branches | +| Use cases | drive one frontend-neutral setup session (repository through result), questionnaire, credential decisions, provision, doctor probes, resolve one complete doctor catalog | provider DTOs, terminal/browser objects, feature-local language branches | | Ports | raw terminal, render/present/confirm, workspace, narrow remote queries/commands, health | provider implementation | | Adapters | terminal mechanics, presenters, filesystem, narrow Octokit reads/writes, health query/bootstrap | product defaults/question order | -| CLI composition | command flags and concrete wiring | duplicated validation | +| CLI composition | command flags, concrete wiring, exit-code adaptation and terminal cleanup | duplicated validation, stage ordering, mutation classification | ```mermaid flowchart LR @@ -257,6 +257,16 @@ adapter owns backups and writes; GitHub adapters own remote error mapping. Architecture tests and workflow/catalog validators enforce dependencies and asset parity. +The shared coordinator is the authority for stage order, cancellation before +mutation, single-flight Apply, and the conservative partial outcome once a +write may have started. Terminal and browser ports use the existing +questionnaire, PAT, plan, credential, and provider use cases; neither adapter +may substitute its own setup policy. An in-memory resource receipt records +`not-started`, `in-progress`, `completed`, `skipped`, or +`needs-inspection`; a crash or unknown remote response is not rollback +evidence. The browser exposes only a redacted projection. See the acceptance +ledger in [local web setup assistant](./local-web-setup-assistant.md#14-testing-strategy-and-numeric-budget). + ## 9. UI/UX and content contract ### Interactive journey presentation (2026-09-28 amendment) diff --git a/specs/setup-pat-permission-guidance-and-verification.md b/specs/setup-pat-permission-guidance-and-verification.md index 8a78044bd..ed84bad8b 100644 --- a/specs/setup-pat-permission-guidance-and-verification.md +++ b/specs/setup-pat-permission-guidance-and-verification.md @@ -3,7 +3,7 @@ - Status: Implemented — permission UX, deterministic provider mapping, scope-sensitive gating, coverage, and documentation gates complete - Date: 2026-09-20 - Catalog capability ID: `setup-and-doctor` -- Last verified: 2026-09-24 +- Last verified: 2026-10-02 - Owners: Copilot maintainers and setup operators - Scope: show least-privilege permission requirements before collecting setup and workflow PATs, then report evidence-based permission checks without exposing or mutating credentials - Related issues/PRs: none recorded @@ -957,6 +957,15 @@ at widths 40/80/120 and `NO_COLOR`. before permission probes or provisioning. A guided owner assertion cannot bypass this; once GitHub verifies `User` or `Organization`, the requirements are recomputed for that actual type. +52. Given organization Projects were selected before PAT entry, the bootstrap + audit performs a bounded GET of the organization's Projects V2 list. A + successful list containing an explicitly non-public Project verifies the + permission-bound read. A successful public-only or empty list is usable + only for the currently visible Projects and remains `Unverifiable` as PAT + grant evidence; later selected Project access must be checked separately. + Denial, malformed data, timeout, and provider failure never become a pass. + The audit performs no test mutation and does not require a live Project in + test fixtures. ## 17. Requirements traceability @@ -973,6 +982,7 @@ at widths 40/80/120 and `NO_COLOR`. | absent-snapshot fail-closed provisioning | resource grouping and initial setup workflow | missing port, failed inspection, no-upsert tests | troubleshooting/provisioning | | all-provisioning fail-closed boundary | initial setup workflow + storage policy | no local file copy or label/type/tag/Secret/Variable calls after failed inspection | troubleshooting | | public-read and Members evidence | permission query adapter + evidence policy + readiness use case + presenter | public repository provenance; protected active self-membership success; public-list, malformed, pending, denied, Issue-Types and write fixtures | authentication/troubleshooting | +| organization Projects read evidence | permission query adapter + evidence policy + bootstrap use case | scenario 52; private/public/empty/malformed/denied local GET fixtures | authentication/troubleshooting | | safe bootstrap 404 | credential health bootstrap adapter | exact path/visibility proof, create-only SHA ownership, conditional cleanup and no-mutation ambiguous/race fixtures | authentication | | no write probes | semantic query port/architecture rule | method/transport tests | architecture | | secret safety | all contracts/presenter | redaction fixtures | credentials | diff --git a/src/__tests__/cli.test.ts b/src/__tests__/cli.test.ts index b337ce63f..bb124852f 100644 --- a/src/__tests__/cli.test.ts +++ b/src/__tests__/cli.test.ts @@ -497,6 +497,7 @@ describe('CLI', () => { for (const option of setupCommand.options) { setupCommand.setOptionValue(option.attributeName(), option.defaultValue); } + (runLocalAction as jest.Mock).mockResolvedValue([{ id: 'InitialSetupUseCase', success: true, executed: true, errors: [] }]); }); describe('local web command handoff', () => { @@ -774,6 +775,12 @@ describe('CLI', () => { expect(logInfo).toHaveBeenCalledWith(expect.stringContaining('partial completion')); }); + it('does not call an empty mutation result complete', async () => { + (runLocalAction as jest.Mock).mockResolvedValueOnce([]); + await program.parseAsync(['node', 'cli', 'setup', '--web', '--pr-approval-mode', 'off', '--skip-secrets']); + expect(process.exitCode).toBe(1); + }); + it('passes only explicitly approved changed workflows to the mutation boundary', async () => { const comparison = jest.spyOn(SetupDoctorWorkspaceQueryAdapter.prototype, 'compareWorkflows') .mockReturnValue([ @@ -784,7 +791,8 @@ describe('CLI', () => { ? 'Update setup-managed workflows' : answerWebPrompt(prompt)); try { await program.parseAsync(['node', 'cli', 'setup', '--web', '--pr-approval-mode', 'off', '--skip-secrets']); - expect(runLocalAction).toHaveBeenCalledWith(expect.objectContaining({ setupWorkflowUpdates: ['copilot_issue.yml'] })); + expect(runLocalAction).toHaveBeenCalledWith(expect.objectContaining({ setupWorkflowUpdates: ['copilot_issue.yml'] }), + expect.objectContaining({ onSetupProgress: expect.any(Function) })); } finally { comparison.mockRestore(); } }); diff --git a/src/actions/__tests__/common_action.test.ts b/src/actions/__tests__/common_action.test.ts index 1c52b65b0..9f60d82b5 100644 --- a/src/actions/__tests__/common_action.test.ts +++ b/src/actions/__tests__/common_action.test.ts @@ -288,7 +288,7 @@ describe('mainRun', () => { expect(Object.isFrozen(context)).toBe(true); expect(Object.isFrozen(context.branches)).toBe(true); expect(logger.clearAccumulatedLogs).toHaveBeenCalledTimes(1); - expect(createMainRunRouteCompositionRoot).toHaveBeenCalledWith(projectBoardCommandPort, 'github-workflow'); + expect(createMainRunRouteCompositionRoot).toHaveBeenCalledWith(projectBoardCommandPort, 'github-workflow', undefined); }); it('rejects an execution without repository context before calling use cases', async () => { diff --git a/src/actions/__tests__/local_action.test.ts b/src/actions/__tests__/local_action.test.ts index abb8c9322..198e52700 100644 --- a/src/actions/__tests__/local_action.test.ts +++ b/src/actions/__tests__/local_action.test.ts @@ -68,6 +68,12 @@ describe('runLocalAction', () => { expect(execution.welcome).toBeDefined(); }); + it('passes only an optional semantic setup progress observer to the local route', async () => { + const onSetupProgress = jest.fn(); + await runLocalAction({ repo: { owner: 'o', repo: 'r' }, [INPUT_KEYS.TOKEN]: 'fixture-token' }, { onSetupProgress }); + expect(mockMainRun.mock.calls[0][7]).toBe(onSetupProgress); + }); + it('uses additionalParams over actionInputs defaults', async () => { mockGetActionInputsWithDefaults.mockReturnValue({ ...minimalActionInputs(), diff --git a/src/actions/common_action.ts b/src/actions/common_action.ts index 344fe4abe..2fff3aa38 100644 --- a/src/actions/common_action.ts +++ b/src/actions/common_action.ts @@ -45,6 +45,7 @@ export async function mainRun( lifecycleStateUseCase?: SynchronizeLifecycleStateUseCase, agentActivityUseCase?: SynchronizeAgentActivityUseCase, prepareRuntime?: PrepareExecutionRuntime, + setupProgress?: (effect: import('../domain/setup').SetupOperationEffect) => void, ): Promise { configureApplicationLogger(createLoggerAdapter()); setGlobalLoggerDebug(execution.debug, execution.inputs === undefined); @@ -88,7 +89,7 @@ export async function mainRun( } await prepareRuntime?.(execution); - const routeHandlers = createMainRunRouteCompositionRoot(projectBoardCommandPort, compositionSurface); + const routeHandlers = createMainRunRouteCompositionRoot(projectBoardCommandPort, compositionSurface, setupProgress); if (execution.runnedByToken) { return runTrackedRoute(execution, 'single-action', () => runTokenExecution(execution, routeHandlers), undefined, agentActivityUseCase); diff --git a/src/actions/local_action.ts b/src/actions/local_action.ts index 79ef699dc..7fd1f4606 100644 --- a/src/actions/local_action.ts +++ b/src/actions/local_action.ts @@ -16,6 +16,7 @@ import { buildLocalActionExecution } from './local_action_execution'; import { requireRepositoryCoordinates } from './repository_context'; import { createSynchronizeAgentActivityUseCase } from '../infrastructure/composition/agent_activity_composition_root'; import type { Result } from '../data/model/result'; +import type { SetupOperationEffect } from '../domain/setup'; import { runAtApplicationErrorBoundary } from '../application/errors/application_error_context'; import { INPUT_KEYS } from '../application/contracts/input_keys'; import { assertLocalSingleActionAllowed } from '../application/policies/local_single_action_policy'; @@ -23,7 +24,7 @@ import { resolvePublicationCatalog } from '../application/policies/publication_m export async function runLocalAction( additionalParams: Record, - options: { render?: boolean } = {}, + options: { render?: boolean; onSetupProgress?: (effect: SetupOperationEffect) => void } = {}, ): Promise { return runAtApplicationErrorBoundary(async () => { const requestedAction = additionalParams[INPUT_KEYS.SINGLE_ACTION]; @@ -46,6 +47,8 @@ export async function runLocalAction( repository: execution.repo, token: execution.tokens.token, }), + undefined, + options.onSetupProgress, ); if (options.render !== false) { diff --git a/src/application/contracts/web_setup_view.ts b/src/application/contracts/web_setup_view.ts index 6d9f1f9c8..328d34c0f 100644 --- a/src/application/contracts/web_setup_view.ts +++ b/src/application/contracts/web_setup_view.ts @@ -103,6 +103,6 @@ export interface WebSetupView { readonly stoppedStage: string; readonly mutationStarted: boolean; readonly diagnosticRef?: string; - readonly effects?: readonly { readonly id: string; readonly state: 'completed' | 'skipped' | 'needs-inspection' | 'not-started'; readonly scope?: 'local' | 'repository' | 'organization' | 'mixed' }[]; + readonly effects?: readonly { readonly id: string; readonly state: 'completed' | 'skipped' | 'needs-inspection' | 'not-started' | 'in-progress'; readonly scope?: 'local' | 'repository' | 'organization' | 'mixed' }[]; }; } diff --git a/src/application/policies/__tests__/setup_project_selection_policy.test.ts b/src/application/policies/__tests__/setup_project_selection_policy.test.ts index be2920e79..dc19cb43c 100644 --- a/src/application/policies/__tests__/setup_project_selection_policy.test.ts +++ b/src/application/policies/__tests__/setup_project_selection_policy.test.ts @@ -29,17 +29,15 @@ describe('setup Project selection', () => { expect(parseSetupProjectSelection('https://github.com/orgs/acme/projects/5')).toHaveProperty('error'); }); - test('uses only Status options common to all selected Projects', () => { - expect(sharedProjectStatusOptions('', [])).toEqual({ state: 'unavailable', options: [] }); - expect(sharedProjectStatusOptions('2,3', [ - { number: 2, statusOptions: ['Todo', 'In Progress'] }, - { number: 3, statusOptions: ['In Progress', 'Done'] }, - ])).toEqual({ state: 'observed', options: ['In Progress'] }); - expect(sharedProjectStatusOptions('2,3', [ - { number: 2, statusOptions: ['Todo'] }, { number: 3, statusOptions: ['Done'] }, - ])).toEqual({ state: 'incompatible', options: [] }); - expect(sharedProjectStatusOptions('2,4', [{ number: 2, statusOptions: ['Todo'] }])) - .toEqual({ state: 'unavailable', options: [] }); + test.each([ + ['no selected Project', '', [], { state: 'unavailable', options: [] }], + ['one selected Project was not discovered', '2,4', [{ number: 2, statusOptions: ['Todo'] }], { state: 'unavailable', options: [] }], + ['one Status field is unreadable', '2,3', [{ number: 2, statusOptions: ['Todo'] }, { number: 3 }], { state: 'unavailable', options: [] }], + ['the Projects have disjoint options', '2,3', [{ number: 2, statusOptions: ['Todo'] }, { number: 3, statusOptions: ['Done'] }], { state: 'incompatible', options: [] }], + ['the Projects share one option', '2,3', [{ number: 2, statusOptions: ['Todo', 'In Progress'] }, { number: 3, statusOptions: ['In Progress', 'Done'] }], { state: 'observed', options: ['In Progress'] }], + ['the Projects share options in the first field order', '2,3', [{ number: 2, statusOptions: ['Todo', 'Done'] }, { number: 3, statusOptions: ['Done', 'Todo'] }], { state: 'observed', options: ['Todo', 'Done'] }], + ] as const)('Status compatibility: %s', (_label, ids, projects, expected) => { + expect(sharedProjectStatusOptions(ids, projects)).toEqual(expected); }); test('validates configured Status values against discovered Projects without trusting incomplete discovery', () => { diff --git a/src/application/policies/setup_token_permission_evidence_policy.ts b/src/application/policies/setup_token_permission_evidence_policy.ts index 4a928ab0d..28f932119 100644 --- a/src/application/policies/setup_token_permission_evidence_policy.ts +++ b/src/application/policies/setup_token_permission_evidence_policy.ts @@ -47,6 +47,12 @@ export function isOperationallyAvailableSetupRead( requirement: Pick, evidence: SetupTokenPublicReadEvidence | undefined, ): boolean { + if (requirement.level === 'read' + && requirement.scope === 'organization' + && requirement.permission === 'Projects' + && requirement.probe === 'projects') { + return evidence === 'public-organization-projects'; + } return requirement.level === 'read' && requirement.scope === 'repository' && evidence === 'public-repository' @@ -75,7 +81,8 @@ function isMatchingEvidence( && value.message.trim().length > 0 && (value.operationallyAvailable === undefined || value.operationallyAvailable === true) && (value.publicReadEvidence === undefined - || value.publicReadEvidence === 'public-repository'); + || value.publicReadEvidence === 'public-repository' + || value.publicReadEvidence === 'public-organization-projects'); } function isPermissionStatus(value: unknown): value is SetupTokenPermissionStatus { diff --git a/src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts b/src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts index 4a70a770d..e698eae2a 100644 --- a/src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts +++ b/src/application/usecases/actions/__tests__/initial_setup_use_case.test.ts @@ -294,6 +294,30 @@ describe('InitialSetupUseCase', () => { ])); }); + it('emits ordered, value-free resource progress before the final receipt', async () => { + const progress = jest.fn(); + const observed = new InitialSetupUseCase( + { getUser: mockGetUserFromToken, getUserDetails: jest.fn() }, + { ensureInitialLabels: mockEnsureInitialLabels }, + { ensureIssueTypes: mockEnsureIssueTypes }, + { getLatestTag: mockGetLatestTag }, + { getDefaultBranch: mockGetDefaultBranch } as any, + { createTag: mockCreateTag } as any, + { prepare: mockSetupPrepare, hasValidToken: mockSetupHasValidToken }, + { upsert: mockSetupVariablesUpsert }, + undefined, undefined, progress, + ); + const result = await observed.invoke(baseParam()); + expect(progress.mock.calls.map(([effect]) => `${effect.id}:${effect.state}`)).toEqual([ + 'files:in-progress', 'files:completed', 'secrets:skipped', 'labels:in-progress', + 'labels:skipped', 'issue-types:in-progress', 'issue-types:skipped', + 'variables:skipped', 'initial-tag:in-progress', 'initial-tag:skipped', + ]); + expect(JSON.stringify(progress.mock.calls)).not.toContain('fake-workflow-token'); + expect(getResultPayload(getResultPayload(result[0].payload)?.setupReceipt)?.effects) + .toEqual(expect.arrayContaining([{ id: 'files', state: 'completed', scope: 'local' }])); + }); + it('creates default tag v1.0.0 when no version tags exist', async () => { mockGetLatestTag.mockResolvedValue(undefined); const param = baseParam(); diff --git a/src/application/usecases/actions/initial_setup_use_case.ts b/src/application/usecases/actions/initial_setup_use_case.ts index a39d25393..0dcfd874a 100644 --- a/src/application/usecases/actions/initial_setup_use_case.ts +++ b/src/application/usecases/actions/initial_setup_use_case.ts @@ -7,6 +7,7 @@ import type { BoundSetupWorkspacePort } from '../../ports/setup_workspace_ports' import { ParamUseCase } from '../base/param_usecase'; import { runInitialSetupWorkflow } from './initial_setup_workflow'; import type { InitialSetupContext } from '../push_single_action_contexts'; +import type { SetupOperationEffect } from '../../../domain/setup'; import type { BoundSetupRemoteConfigurationReadPort, BoundSetupRepositorySecretsCommandPort, @@ -28,6 +29,7 @@ export class InitialSetupUseCase implements ParamUseCase void, ) {} async invoke(param: InitialSetupContext): Promise { @@ -42,6 +44,7 @@ export class InitialSetupUseCase implements ParamUseCase void; authenticatedUserPort: BoundAuthenticatedUserPort; initialLabelProvisioningPort: BoundInitialLabelProvisioningPort; issueTypeProvisioningPort: BoundIssueTypeProvisioningPort; @@ -66,8 +67,11 @@ export async function runInitialSetupWorkflow( const mark = (id: SetupOperationEffect['id'], state: SetupOperationEffect['state']) => { const index = effects.findIndex(effect => effect.id === id); effects[index] = { ...effects[index], state }; + try { dependencies.progress?.(Object.freeze({ ...effects[index] })); } + catch { /* Presentation observers cannot abort provisioning. */ } }; - const receipt = () => buildResult(errors, steps, effects); + const receipt = () => buildResult(errors, steps, effects.map(effect => effect.state === 'in-progress' + ? { ...effect, state: 'needs-inspection' } : effect)); try { const setupConfiguration = request.setupConfiguration; @@ -134,19 +138,19 @@ export async function runInitialSetupWorkflow( approvedWorkflowFiles: request.workflowUpdates, } : {}), }; - mark('files', 'needs-inspection'); + mark('files', 'in-progress'); const filesResult = dependencies.setupWorkspacePort.prepare(workspaceSelection); mark('files', filesResult.copied > 0 ? 'completed' : 'skipped'); steps.push(`✅ Setup files: ${filesResult.copied} copied, ${filesResult.skipped} already existed`); - if (setupConfiguration?.manageRepositorySecrets && secretValues > 0) mark('secrets', 'needs-inspection'); + if (setupConfiguration?.manageRepositorySecrets && secretValues > 0) mark('secrets', 'in-progress'); const secrets = await ensureRepositorySecrets(request, dependencies, setupConfiguration, remoteConfiguration); mark('secrets', secrets.errors.length ? 'needs-inspection' : secrets.writes > 0 ? 'completed' : 'skipped'); if (secrets.step) steps.push(secrets.step); if (secrets.errors.length > 0) errors.push(...fromMessages(secrets.errors, 'authorization.credential-invalid')); logInfo('🏷️ Checking configured and progress labels...'); - mark('labels', 'needs-inspection'); + mark('labels', 'in-progress'); const labels = await ensureInitialLabels(request, dependencies.initialLabelProvisioningPort, setupConfiguration); mark('labels', !labels.completed || labels.configured.errors.length || labels.progress.errors.length ? 'needs-inspection' : labels.configured.created + labels.progress.created > 0 ? 'completed' : 'skipped'); @@ -158,7 +162,7 @@ export async function runInitialSetupWorkflow( } logInfo('📋 Checking issue types...'); - mark('issue-types', 'needs-inspection'); + mark('issue-types', 'in-progress'); const issueTypes = await ensureIssueTypes(request, dependencies.issueTypeProvisioningPort, setupConfiguration); mark('issue-types', !issueTypes.success ? 'needs-inspection' : issueTypes.created > 0 ? 'completed' : 'skipped'); if (!issueTypes.success) { @@ -167,13 +171,13 @@ export async function runInitialSetupWorkflow( steps.push(`✅ Issue types checked: ${issueTypes.created} created, ${issueTypes.existing} already existed`); } - if (setupConfiguration?.manageRepositoryVariables) mark('variables', 'needs-inspection'); + if (setupConfiguration?.manageRepositoryVariables) mark('variables', 'in-progress'); const variables = await ensureRepositoryVariables(request, dependencies, setupConfiguration, remoteConfiguration); mark('variables', variables.errors.length ? 'needs-inspection' : variables.writes > 0 ? 'completed' : 'skipped'); if (variables.step) steps.push(variables.step); if (variables.errors.length > 0) errors.push(...fromMessages(variables.errors, 'provider.unavailable')); - if (setupConfiguration?.createInitialTag !== false) mark('initial-tag', 'needs-inspection'); + if (setupConfiguration?.createInitialTag !== false) mark('initial-tag', 'in-progress'); const defaultVersion = await ensureDefaultVersion(request, dependencies, setupConfiguration); mark('initial-tag', defaultVersion.error ? 'needs-inspection' : defaultVersion.step?.includes('created on branch') ? 'completed' : 'skipped'); diff --git a/src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts b/src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts new file mode 100644 index 000000000..f76584a3a --- /dev/null +++ b/src/application/usecases/setup/__tests__/setup_session_coordinator.test.ts @@ -0,0 +1,95 @@ +import { SetupSessionCoordinator, type SetupSessionDecision, type SetupSessionPorts } from '../setup_session_coordinator'; +import type { SetupOperationEffect } from '../../../../domain/setup'; + +const completed: SetupOperationEffect = { id: 'files', scope: 'local', state: 'completed' }; +const uncertain: SetupOperationEffect = { id: 'secrets', scope: 'repository', state: 'needs-inspection' }; + +function fixture(overrides: Partial = {}) { + const calls: string[] = []; + const ports: SetupSessionPorts = { + repository: async () => { calls.push('repository'); return 'continue'; }, + choices: async () => { calls.push('choices'); return 'continue'; }, + setupPat: async () => { calls.push('setup-pat'); return 'continue'; }, + plan: async () => { calls.push('plan'); return 'continue'; }, + credentials: async () => { calls.push('credentials'); return 'continue'; }, + authorizeApply: async () => { calls.push('authorization'); return 'continue'; }, + apply: async effect => { calls.push('apply'); effect(completed); return { success: true, effects: [completed] }; }, + liveness: () => 'active', + present: () => undefined, + isCancellationError: () => false, + ...overrides, + }; + return { coordinator: new SetupSessionCoordinator(ports), calls }; +} + +describe('shared setup session coordinator', () => { + test('runs semantic stages in order and returns an immutable resource receipt', async () => { + const { coordinator, calls } = fixture(); + const result = await coordinator.execute(); + expect(calls).toEqual(['repository', 'choices', 'setup-pat', 'plan', 'credentials', 'authorization', 'apply']); + expect(result).toMatchObject({ outcome: 'complete', mutationStarted: true, effects: [completed] }); + await expect(coordinator.execute()).rejects.toThrow('only once'); + }); + + test.each([ + ['repository', 'cancelled', 'cancelled'], + ['choices', 'blocked', 'blocked'], + ['plan', 'dry-run', 'dry-run'], + ['authorizeApply', 'cancelled', 'cancelled'], + ] as const)('%s decision %s stops before Apply as %s', async (step, decision, outcome) => { + const { coordinator, calls } = fixture({ [step]: async () => decision as SetupSessionDecision }); + expect(await coordinator.execute()).toMatchObject({ outcome, mutationStarted: false, effects: [] }); + expect(calls).not.toContain('apply'); + }); + + test.each(['cancelled', 'expired'] as const)('liveness %s during awaited approval stops before mutation', async state => { + let live: 'active' | typeof state = 'active'; + const { coordinator, calls } = fixture({ + authorizeApply: async () => { live = state; return 'continue'; }, + liveness: () => live, + }); + expect(await coordinator.execute()).toMatchObject({ outcome: state === 'expired' ? 'blocked' : 'cancelled', mutationStarted: false }); + expect(calls).not.toContain('apply'); + }); + + test('rejects concurrent execution while a phase is pending', async () => { + let release!: (value: SetupSessionDecision) => void; + const { coordinator } = fixture({ repository: () => new Promise(resolve => { release = resolve; }) }); + const first = coordinator.execute(); + await expect(coordinator.execute()).rejects.toThrow('only once'); + release('cancelled'); + expect((await first).outcome).toBe('cancelled'); + }); + + test('an unknown provider outcome after the write boundary is partial, with retained facts', async () => { + const error = new Error('connection dropped'); + const { coordinator } = fixture({ apply: async effect => { effect(uncertain); throw error; } }); + const result = await coordinator.execute(); + expect(result).toMatchObject({ outcome: 'partial', mutationStarted: true, effects: [uncertain], error }); + }); + + test('a completed effect cannot be demoted by a later stale progress event', async () => { + const { coordinator } = fixture({ apply: async effect => { + effect(completed); + effect({ ...completed, state: 'needs-inspection' }); + return { success: true, effects: [completed] }; + } }); + expect((await coordinator.execute()).effects).toEqual([completed]); + }); + + test('an unresolved in-progress write cannot produce a complete outcome', async () => { + const { coordinator } = fixture({ apply: async effect => { + effect({ id: 'secrets', state: 'in-progress', scope: 'repository' }); + return { success: true, effects: [] }; + } }); + expect(await coordinator.execute()).toMatchObject({ outcome: 'partial', effects: [uncertain] }); + }); + + test('a possible credential-health write makes later cancellation partial', async () => { + const { coordinator, calls } = fixture({ + credentials: async mark => { mark(); return 'cancelled'; }, + }); + expect(await coordinator.execute()).toMatchObject({ outcome: 'partial', mutationStarted: true }); + expect(calls).not.toContain('apply'); + }); +}); diff --git a/src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts b/src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts index 0c6f83c30..60ed2de5e 100644 --- a/src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts +++ b/src/application/usecases/setup/__tests__/setup_token_permissions_use_case.test.ts @@ -241,6 +241,32 @@ describe('SetupTokenPermissionsUseCase', () => { expect(report.checks[0]).toMatchObject({ status: 'unverifiable', operationallyAvailable: true }); }); + it('accepts bounded public organization Projects discovery without claiming the PAT grant', async () => { + const projects: SetupTokenPermissionRequirement = { + ...required, id: 'setup.organization.projects', scope: 'organization', + permission: 'Projects', probe: 'projects', + }; + const validation = { validateSetupPat: jest.fn().mockResolvedValue({ name: 'SETUP_PAT', status: 'valid', message: 'ok' }) }; + const report = await new SetupTokenPermissionsUseCase(validation, { inspect: jest.fn().mockResolvedValue([{ + ...projects, status: 'unverifiable', operationallyAvailable: true, + publicReadEvidence: 'public-organization-projects', message: 'public Projects list usable', + }]) }).inspect({ role: 'setup', owner: 'owner', repository: 'repo', token: 'secret', requirements: [projects] }); + expect(report).toMatchObject({ ready: true, confirmationRequired: false }); + expect(report.checks[0]).toMatchObject({ status: 'unverifiable', operationallyAvailable: true }); + }); + + it('rejects organization Projects usability on an unrelated permission', async () => { + const other = { ...required, id: 'setup.organization.secrets', scope: 'organization' as const, + permission: 'Secrets', probe: 'secrets' as const }; + const validation = { validateSetupPat: jest.fn().mockResolvedValue({ name: 'SETUP_PAT', status: 'valid', message: 'ok' }) }; + const report = await new SetupTokenPermissionsUseCase(validation, { inspect: jest.fn().mockResolvedValue([{ + ...other, status: 'unverifiable', operationallyAvailable: true, + publicReadEvidence: 'public-organization-projects', message: 'forged public marker', + }]) }).inspect({ role: 'setup', owner: 'owner', repository: 'repo', token: 'secret', requirements: [other] }); + expect(report.ready).toBe(false); + expect(report.checks[0].operationallyAvailable).toBeUndefined(); + }); + it('does not trust an operational flag without public-read provenance', async () => { const validation = { validateSetupPat: jest.fn().mockResolvedValue({ name: 'SETUP_PAT', status: 'valid', message: 'ok' }) }; const report = await new SetupTokenPermissionsUseCase(validation, { diff --git a/src/application/usecases/setup/setup_session_coordinator.ts b/src/application/usecases/setup/setup_session_coordinator.ts new file mode 100644 index 000000000..e3bfa717f --- /dev/null +++ b/src/application/usecases/setup/setup_session_coordinator.ts @@ -0,0 +1,115 @@ +import type { SetupOperationEffect } from '../../../domain/setup'; +import type { SetupJourneyOutcome, SetupJourneyStage } from '../../policies/setup_journey_policy'; + +export type SetupSessionDecision = 'continue' | 'cancelled' | 'blocked' | 'dry-run'; +export type SetupSessionLiveness = 'active' | 'cancelled' | 'expired'; + +export interface SetupSessionReceipt { + readonly success: boolean; + readonly effects: readonly SetupOperationEffect[]; +} + +/** Semantic work only. Entrypoints adapt prompts, providers and process exit codes. */ +export interface SetupSessionPorts { + readonly repository: () => Promise; + readonly choices: () => Promise; + readonly setupPat: () => Promise; + readonly plan: () => Promise; + readonly credentials: (possibleMutation: () => void) => Promise; + readonly authorizeApply: () => Promise; + readonly apply: (effect: (effect: SetupOperationEffect) => void) => Promise; + readonly liveness: () => SetupSessionLiveness; + readonly present: (stage: SetupJourneyStage, mutationStarted: boolean, outcome?: SetupJourneyOutcome) => void; + readonly isCancellationError: (error: unknown) => boolean; +} + +export interface SetupSessionRunResult { + readonly outcome: SetupJourneyOutcome; + readonly mutationStarted: boolean; + readonly effects: readonly SetupOperationEffect[]; + readonly error?: unknown; +} + +/** Owns cross-frontend stage order, the write boundary and conservative outcomes. */ +export class SetupSessionCoordinator { + private running = false; + private finished = false; + private mutationStarted = false; + private stage: SetupJourneyStage = 'repository'; + private readonly effects = new Map(); + + constructor(private readonly ports: SetupSessionPorts) {} + + async execute(): Promise { + if (this.running || this.finished) throw new Error('Setup session can run only once.'); + this.running = true; + try { + const stages: readonly [SetupJourneyStage, () => Promise][] = [ + ['repository', this.ports.repository], + ['choices', this.ports.choices], + ['setup-pat', this.ports.setupPat], + ['plan', this.ports.plan], + ['credentials', () => this.ports.credentials(() => this.markPossibleMutation())], + ['apply', this.ports.authorizeApply], + ]; + for (const [stage, operation] of stages) { + this.stage = stage; + this.ports.present(stage, this.mutationStarted); + const before = this.liveOutcome(); + if (before) return this.finish(before); + const decision = await operation(); + const after = this.liveOutcome(); + if (after) return this.finish(after); + if (decision !== 'continue') return this.finish(decision === 'dry-run' ? 'dry-run' : decision); + } + + // The authorization operation must finish while the live session is active. + // The mutation marker is set before entering the provider boundary: a + // rejected/unknown request can already have reached GitHub. + this.markPossibleMutation(); + const receipt = await this.ports.apply(effect => this.record(effect)); + for (const effect of receipt.effects) this.record(effect); + return this.finish(receipt.success && !this.hasUncertainEffect() ? 'complete' : 'partial'); + } catch (error) { + const cancelled = this.ports.isCancellationError(error) || this.ports.liveness() === 'cancelled'; + return this.finish(this.mutationStarted ? 'partial' : cancelled ? 'cancelled' : 'blocked', error); + } finally { + this.running = false; + this.finished = true; + } + } + + private liveOutcome(): SetupJourneyOutcome | undefined { + const state = this.ports.liveness(); + if (state === 'active') return undefined; + return this.mutationStarted ? 'partial' : state === 'cancelled' ? 'cancelled' : 'blocked'; + } + + private markPossibleMutation(): void { + if (this.mutationStarted) return; + this.mutationStarted = true; + this.ports.present(this.stage, true); + } + + private record(effect: SetupOperationEffect): void { + const previous = this.effects.get(effect.id); + if (previous?.state === 'completed' && effect.state !== 'completed') return; + this.effects.set(effect.id, Object.freeze({ ...effect })); + } + + private hasUncertainEffect(): boolean { + return [...this.effects.values()].some(effect => effect.state === 'needs-inspection' || effect.state === 'in-progress'); + } + + private finish(outcome: SetupJourneyOutcome, error?: unknown): SetupSessionRunResult { + // An interrupted in-flight write must not be reported as no change. + const finalOutcome = this.mutationStarted && (outcome === 'cancelled' || outcome === 'blocked' + || (outcome === 'complete' && this.hasUncertainEffect())) ? 'partial' : outcome; + for (const [id, effect] of this.effects) { + if (effect.state === 'in-progress') this.effects.set(id, Object.freeze({ ...effect, state: 'needs-inspection' })); + } + this.ports.present(this.stage, this.mutationStarted, finalOutcome); + return { outcome: finalOutcome, mutationStarted: this.mutationStarted, + effects: [...this.effects.values()], ...(error === undefined ? {} : { error }) }; + } +} diff --git a/src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts b/src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts index a2398ac46..da586c3a2 100644 --- a/src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts +++ b/src/application/usecases/setup/verify_setup_pat_bootstrap_use_case.ts @@ -37,7 +37,7 @@ export class VerifySetupPatBootstrapUseCase { expiresIn: 1, requirements: request.requirements, })); throw new ApplicationError('authorization.credential-invalid', - 'The setup PAT has missing or unconfirmed required access. Grant or explicitly confirm the permissions shown above and retry.'); + 'The setup PAT has missing or unconfirmed required access. Review the permission report, correct or explicitly confirm the required grants, and retry.'); } if (!await this.ports.confirmAccount(report.account)) { throw new ApplicationError('authorization.credential-invalid', diff --git a/src/architecture/__tests__/web_setup_boundaries.test.ts b/src/architecture/__tests__/web_setup_boundaries.test.ts index 484d46535..f565f0462 100644 --- a/src/architecture/__tests__/web_setup_boundaries.test.ts +++ b/src/architecture/__tests__/web_setup_boundaries.test.ts @@ -103,7 +103,7 @@ describe('local web setup architecture', () => { test('new setup application decisions have no transitive path to CLI, infrastructure, or browser adapters', () => { const useCases = ['prepare_setup_pat_intent_use_case', 'verify_setup_pat_bootstrap_use_case', - 'audit_configured_setup_pat_use_case', 'verify_web_setup_apply_use_case'] + 'audit_configured_setup_pat_use_case', 'verify_web_setup_apply_use_case', 'setup_session_coordinator'] .map(name => join(root, 'src', 'application', 'usecases', 'setup', `${name}.ts`)); const visited = new Set(); const traverse = (path: string): void => { @@ -120,6 +120,12 @@ describe('local web setup architecture', () => { }; for (const entry of useCases) traverse(entry); expect(visited.size).toBeGreaterThan(useCases.length); + const command = readFileSync(join(root, 'src', 'cli', 'commands', 'setup.ts'), 'utf8'); + const execution = readFileSync(join(root, 'src', 'cli', 'commands', 'setup_execution.ts'), 'utf8'); + expect(command).toContain('.action(executeSetupCommand)'); + expect(command.split('\n').length).toBeLessThanOrEqual(65); + expect(execution).toContain('new SetupSessionCoordinator('); + expect(execution).not.toMatch(/journey\?\.finish\('complete'\)|journey\?\.finish\('partial'\)/); }); test('domain and application never import browser, HTTP server, or terminal adapters', () => { for (const path of [...sources(join(root, 'src', 'domain')), ...sources(join(root, 'src', 'application'))]) { diff --git a/src/cli/__tests__/setup_session_guard.test.ts b/src/cli/__tests__/setup_session_guard.test.ts index 04784eb2e..a2b5d9f83 100644 --- a/src/cli/__tests__/setup_session_guard.test.ts +++ b/src/cli/__tests__/setup_session_guard.test.ts @@ -7,12 +7,16 @@ import { acquireSetupSessionGuard } from '../setup_session_guard'; describe('setup session guard', () => { let root: string; + let canonicalRepository: string; beforeEach(() => { root = mkdtempSync(join(tmpdir(), 'copilot-setup-guard-')); execFileSync('git', ['init', '-q', root]); + canonicalRepository = realpathSync(execFileSync('git', ['-C', root, 'rev-parse', '--show-toplevel'], { encoding: 'utf8' }).trim()); mkdirSync(join(root, 'nested')); }); - const lockPath = () => join(tmpdir(), `copilot-setup-${createHash('sha256').update(realpathSync(root)).digest('hex').slice(0, 32)}.lock`); + // Git may report a different spelling of the same Windows checkout path. + // Seed the exact canonical path used by acquireSetupSessionGuard. + const lockPath = () => join(tmpdir(), `copilot-setup-${createHash('sha256').update(canonicalRepository).digest('hex').slice(0, 32)}.lock`); afterEach(() => { const lock = lockPath(); if (existsSync(lock)) unlinkSync(lock); @@ -32,7 +36,7 @@ describe('setup session guard', () => { }); test('fails closed on a verified dead owner until the operator removes its exact lock', () => { - const oldRecord = JSON.stringify({ pid: 99999999, nonce: 'old-owner', repository: realpathSync(root) }); + const oldRecord = JSON.stringify({ pid: 99999999, nonce: 'old-owner', repository: canonicalRepository }); writeFileSync(lockPath(), oldRecord); expect(() => acquireSetupSessionGuard(root)).toThrow(`remove only that file manually`); expect(readFileSync(lockPath(), 'utf8')).toBe(oldRecord); @@ -43,8 +47,8 @@ describe('setup session guard', () => { }); test('a replacement lock is never unlinked after a stale-owner probe', () => { - writeFileSync(lockPath(), JSON.stringify({ pid: 99999999, nonce: 'old-owner', repository: realpathSync(root) })); - const newRecord = JSON.stringify({ pid: process.pid, nonce: 'new-owner', repository: realpathSync(root) }); + writeFileSync(lockPath(), JSON.stringify({ pid: 99999999, nonce: 'old-owner', repository: canonicalRepository })); + const newRecord = JSON.stringify({ pid: process.pid, nonce: 'new-owner', repository: canonicalRepository }); const probe = jest.spyOn(process, 'kill').mockImplementationOnce(() => { unlinkSync(lockPath()); writeFileSync(lockPath(), newRecord); // Another process won the race after our read. diff --git a/src/cli/__tests__/web_setup_bridge.test.ts b/src/cli/__tests__/web_setup_bridge.test.ts index 71284616e..29cf3f225 100644 --- a/src/cli/__tests__/web_setup_bridge.test.ts +++ b/src/cli/__tests__/web_setup_bridge.test.ts @@ -36,6 +36,24 @@ describe('WebSetupBridge', () => { { id: 'files', state: 'completed' }, { id: 'secret', state: 'needs-inspection' }, ] })); }); + test('publishes live resource states and conservatively closes an interrupted write', () => { + const bridge = new WebSetupBridge('owner/repo'); + bridge.setJourney({ repository: 'owner/repo', position: 6, total: 6, current: 'Apply', complete: [], pending: [], mutationStarted: true, choiceReviewPass: 1 }); + bridge.progress({ id: 'files', state: 'in-progress', scope: 'local' }); + bridge.progress({ id: 'files', state: 'completed', scope: 'local' }); + bridge.progress({ id: 'secrets', state: 'in-progress', scope: 'repository' }); + expect(bridge.snapshot().resultDetail?.effects).toEqual([ + { id: 'files', state: 'completed', scope: 'local' }, + { id: 'secrets', state: 'in-progress', scope: 'repository' }, + ]); + bridge.finish('partial', 'Inspect before retry'); + expect(bridge.snapshot().resultDetail?.effects).toEqual([ + { id: 'files', state: 'completed', scope: 'local' }, + { id: 'secrets', state: 'needs-inspection', scope: 'repository' }, + ]); + bridge.progress({ id: 'secrets', state: 'completed', scope: 'repository' }); + expect(bridge.snapshot().resultDetail?.effects?.[1].state).toBe('needs-inspection'); + }); test('back navigation rotates the question revision without resolving or echoing a draft answer', async () => { const bridge = new WebSetupBridge('owner/repo'); const commit = jest.fn(); @@ -222,4 +240,17 @@ describe('WebSetupBridge', () => { bridge.report({ role: 'setup', identityStatus: 'valid', identityMessage: 'checked', checks: [], ready: true, confirmationRequired: false }); expect(bridge.snapshot().permissions).toMatchObject({ role: 'setup', report: { ready: true }, requirements: [] }); }); + + test('blocked PAT result retains its redacted permission report after the prompt closes', () => { + const bridge = new WebSetupBridge('owner/repo'); + bridge.report({ role: 'setup', identityStatus: 'valid', identityMessage: 'checked', + ready: false, confirmationRequired: false, checks: [{ id: 'setup.organization.projects', + role: 'setup', scope: 'organization', permission: 'Projects', level: 'read', + applicability: 'required', reason: 'Inspect selected Projects.', probe: 'projects', + status: 'unverifiable', message: 'No safe read evidence.' }] }); + bridge.resultReason('permissions'); + bridge.finish('blocked', 'No further setup changes will be applied.'); + expect(bridge.snapshot().permissions?.report?.checks[0]).toMatchObject({ permission: 'Projects', status: 'unverifiable' }); + expect(JSON.stringify(bridge.snapshot())).not.toContain('secret-token'); + }); }); diff --git a/src/cli/__tests__/web_setup_components.test.ts b/src/cli/__tests__/web_setup_components.test.ts index 5b0948366..435a98327 100644 --- a/src/cli/__tests__/web_setup_components.test.ts +++ b/src/cli/__tests__/web_setup_components.test.ts @@ -70,6 +70,46 @@ describe('web setup component semantics', () => { expect(html).toContain('No se iniciaron cambios'); }); + test.each([ + ['en', 'PAT permission evidence', 'Projects', 'Unverifiable'], + ['es', 'Comprobación de permisos del PAT', 'Proyectos', 'No verificable'], + ['fr', 'Vérification des droits du PAT', 'Projets', 'Non vérifiable'], + ['pt', 'Verificação das permissões do PAT', 'Projetos', 'Não verificável'], + ])('%s blocked PAT result preserves the exact failed grant without a credential', (locale, title, name, status) => { + const html = markup('ResultPanel', { outcome: 'blocked', controller: true, + detail: { reasonCode: 'permissions', stoppedStage: 'Setup PAT', mutationStarted: false }, + permissionReport: { role: 'setup', identityStatus: 'valid', identityMessage: 'ok', ready: false, + confirmationRequired: false, checks: [{ id: 'setup.organization.projects', role: 'setup', + permission: 'Projects', scope: 'organization', level: 'read', applicability: 'required', + reason: 'Inspect Projects', probe: 'projects', status: 'unverifiable', + message: 'private diagnostic secret-token' }] } }, locale); + expect(html).toContain(title); + expect(html).toContain(name); + expect(html).toContain(status); + if (locale !== 'en') expect(html).toContain('GitHub · Projects'); + expect(html).not.toContain('private diagnostic'); + expect(html).not.toContain('secret-token'); + }); + + test('invalid identity is not presented as missing individual permissions', () => { + const html = markup('ResultPanel', { outcome: 'blocked', controller: true, + detail: { reasonCode: 'permissions', stoppedStage: 'Setup PAT', mutationStarted: false }, + permissionReport: { role: 'setup', identityStatus: 'invalid', identityMessage: 'rejected', + ready: false, confirmationRequired: false, checks: [{ permission: 'Projects', + scope: 'organization', level: 'read', applicability: 'required', status: 'missing' }] } }); + expect(html).toContain('Rejected'); + expect(html).not.toContain('Projects'); + }); + + test('unrelated blocked outcome does not attribute stale permission evidence to its cause', () => { + const html = markup('ResultPanel', { outcome: 'blocked', controller: true, + detail: { reasonCode: 'storage', stoppedStage: 'Plan', mutationStarted: false }, + permissionReport: { role: 'setup', identityStatus: 'valid', checks: [{ permission: 'Projects', + scope: 'organization', level: 'read', applicability: 'required', status: 'unverifiable' }] } }); + expect(html).not.toContain('PAT permission evidence'); + expect(html).not.toContain('Projects'); + }); + test('partial result shows structured cause, safe effects, and diagnostic reference', () => { const html = markup('ResultPanel', { outcome: 'partial', controller: true, onClose: noOp, detail: { reasonCode: 'provider', stoppedStage: 'Apply', mutationStarted: true, @@ -81,6 +121,19 @@ describe('web setup component semantics', () => { expect(html).toContain('12345678-1234-4123-8123-123456789abc'); }); + test.each([ + ['en', 'which changes completed', 'before Apply'], + ['es', 'qué cambios se completaron', 'antes de aplicar cambios'], + ['fr', 'modifications effectuées', 'avant l’application'], + ['pt', 'quais alterações foram concluídas', 'antes de aplicar'], + ])('%s partial result with unknown cause does not claim Apply never started', (locale, expected, falseClaim) => { + const html = markup('ResultPanel', { outcome: 'partial', controller: true, onClose: noOp, + detail: { reasonCode: 'unknown', stoppedStage: 'Apply', mutationStarted: true, + effects: [{ id: 'secrets', state: 'needs-inspection', scope: 'repository' }] } }, locale); + expect(html).toContain(expected); + expect(html).not.toContain(falseClaim); + }); + test('French technical question guidance is complete, not a mixed-language preview', () => { const question: SetupQuestion = { stateId: 'pull-request-approval', id: 'pullRequestApproval.testChecks', label: 'Trusted checks', kind: 'text', defaultValue: '' }; diff --git a/src/cli/commands/setup.ts b/src/cli/commands/setup.ts index 5d57fc8b2..a5a700068 100644 --- a/src/cli/commands/setup.ts +++ b/src/cli/commands/setup.ts @@ -1,54 +1,7 @@ import { Command } from 'commander'; -import { runLocalAction } from '../../actions/local_action'; import { TITLE } from '../../application/contracts/product_identity'; -import { getSetupToken } from '../../utils/setup_files'; -import { logError, logInfo } from '../../utils/logger'; -import { getCurrentAttachedBranch, getCurrentHeadSha, getGitInfo, getGitRepositoryRoot, hasLocalOrTrackedGitBranch, isGitRepositoryRoot, isInsideGitRepo } from '../../cli_context'; -import { buildSetupParams } from './setup_policy'; -import { collectApprovalCheck, collectScope, collectSecret, loadSetupOverrides } from '../setup_command_options'; -import { SetupQuestionnaireController, SetupWizardUseCase } from '../../application/usecases/setup'; -import { setupPlanGuardPaths } from '../../application/policies/setup_configuration_plan'; -import { PrepareSetupPatIntentUseCase } from '../../application/usecases/setup/prepare_setup_pat_intent_use_case'; -import { AuditConfiguredSetupPatUseCase } from '../../application/usecases/setup/audit_configured_setup_pat_use_case'; -import { VerifySetupPatBootstrapUseCase } from '../../application/usecases/setup/verify_setup_pat_bootstrap_use_case'; -import { buildSetupCredentialRequirements, effectiveIssueWorkflowFeatures } from '../../application/policies/setup_configuration_policy'; -import { - buildSetupPatPermissionRequirements, - buildWorkflowPatPermissionRequirements, -} from '../../application/policies/setup_token_permission_policy'; -import { createSetupCredentialsUseCase, createSetupRemoteConfigurationReadPort } from '../../infrastructure/composition/setup_credentials_composition_root'; -import { createSetupDoctorUseCase, createSetupMergeQueueReadinessUseCase } from '../../infrastructure/composition/setup_doctor_composition_root'; -import { SetupDoctorWorkspaceQueryAdapter } from '../../infrastructure/setup_workspace_adapter'; -import { GithubSetupApprovalReadinessAdapter } from '../../infrastructure/setup_approval_readiness_adapter'; -import { GithubSetupApprovalCheckDiscoveryAdapter } from '../../infrastructure/github_setup_approval_check_discovery_adapter'; -import { GithubSetupProjectDiscoveryAdapter } from '../../infrastructure/github_setup_project_discovery_adapter'; -import type { SetupConfiguration } from '../../domain/setup'; -import { ApplicationError, toApplicationError } from '../../application/errors/application_error'; -import { createInteractiveTerminalDriver } from '../setup_terminal_driver'; -import { ConsoleSetupQuestionRenderer } from '../setup_question_renderer'; -import { ConsoleSetupPlanPresenter } from '../setup_plan_presenter'; -import { DryRunSetupPlanConfirmation, SetupPlanConfirmationAdapter } from '../setup_confirmation_adapter'; -import { SetupCredentialPromptAdapter, SetupTerminalCancelledError } from '../setup_credential_prompt_adapter'; -import { SetupWorkflowUpdatePromptAdapter } from '../setup_workflow_update_prompt_adapter'; -import { ConsoleSetupTokenPermissionPresenter } from '../setup_token_permission_presenter'; -import { createSetupTokenPermissionsUseCase } from '../../infrastructure/composition/setup_token_permissions_composition_root'; -import { buildSetupPatCreationUrl, UnsupportedSetupPatLinkError } from '../../application/policies/setup_pat_creation_url_policy'; -import { SetupGithubIdentityQueryAdapter } from '../../infrastructure/setup_github_identity_query_adapter'; -import { VerifyGuidedWorkflowPatIdentityUseCase } from '../../application/usecases/setup/verify_guided_workflow_pat_identity_use_case'; -import { VerifyWebSetupApplyUseCase } from '../../application/usecases/setup/verify_web_setup_apply_use_case'; -import { SetupJourneyUseCase } from '../../application/usecases/setup/setup_journey_use_case'; -import { buildSetupJourneyView } from '../../application/policies/setup_journey_policy'; -import { ConsoleSetupJourneyPresenter } from '../setup_journey_presenter'; -import { WebSetupBridge } from '../web_setup_bridge'; -import { captureSetupApplySnapshot, setupApplySnapshotMatches } from '../setup_apply_snapshot'; -import { acquireSetupSessionGuard } from '../setup_session_guard'; -import { startWebSetupServer, openWebSetupBrowser, type WebSetupServer } from '../web_setup_server'; -import { - WebSetupCredentialPrompt, WebSetupJourneyPresenter, WebSetupPermissionPresenter, - WebSetupPlanConfirmation, WebSetupPlanPresenter, WebSetupQuestionnaireCollector, - WebSetupWorkflowUpdatePrompt, -} from '../web_setup_adapters'; -import { setupActionResultFailure, setupResultEffects, setupResultReason } from '../setup_result_receipt'; +import { collectApprovalCheck, collectScope, collectSecret } from '../setup_command_options'; +import { executeSetupCommand } from './setup_execution'; export function registerSetupCommand(program: Command): void { program @@ -81,395 +34,5 @@ export function registerSetupCommand(program: Command): void { .option('--update-workflows', 'Allow setup-managed workflows already in the repository to be updated', false) .option('--workflow-pat ', 'Workflow PAT for the bot account (prefer the hidden interactive prompt)') .option('--secret ', 'Secret value for non-interactive setup; repeat for each API key', collectSecret, {}) - .action(async (options) => { - const terminal = options.nonInteractive || options.web ? undefined : createInteractiveTerminalDriver(); - const webBridge = options.web ? new WebSetupBridge('Resolving repository…') : undefined; - let webServer: WebSetupServer | undefined; - const credentialPrompt = webBridge ? new WebSetupCredentialPrompt(webBridge) : new SetupCredentialPromptAdapter(terminal, { - ...(options.workflowPat ? { PAT: options.workflowPat } : {}), - ...options.secret, - }, Boolean(options.confirmUnverifiableWritePermissions)); - const permissionPresenter = webBridge ? new WebSetupPermissionPresenter(webBridge) - : new ConsoleSetupTokenPermissionPresenter(options.nonInteractive ? 'full' : 'summary'); - const tokenPermissions = createSetupTokenPermissionsUseCase(); - const workflowPrompt = webBridge ? new WebSetupWorkflowUpdatePrompt(webBridge) : new SetupWorkflowUpdatePromptAdapter(terminal); - const cwd = process.cwd(); - let setupMutationStarted = false; - let setupApplyStarted = false; - let releaseSetupGuard: (() => void) | undefined; - let journey: SetupJourneyUseCase | undefined; - try { - if (options.web && (options.nonInteractive || options.yes || options.token || options.workflowPat - || Object.keys(options.secret ?? {}).length || options.confirmUnverifiableWritePermissions)) { - throw new ApplicationError('configuration.invalid', '--web cannot be combined with --non-interactive, --yes, --token, --workflow-pat, --secret, or --confirm-unverifiable-write-permissions. Use the browser for these decisions or run copilot setup in the terminal.'); - } - logInfo('🔍 Checking we are inside a git repository...'); - if (!isInsideGitRepo(cwd)) { - logError('❌ Not a git repository. Run "copilot setup" from the root of a git repo.'); - process.exitCode = 1; - return; - } - logInfo('✅ Git repository detected.'); - logInfo('🔗 Resolving repository (owner/repo)...'); - const gitInfo = getGitInfo(); - if ('error' in gitInfo) { - logError(gitInfo.error); - process.exitCode = 1; - return; - } - logInfo(`📦 Repository: ${gitInfo.owner}/${gitInfo.repo}`); - const checkoutRoot = webBridge ? getGitRepositoryRoot(cwd) : cwd; - if (webBridge && !isGitRepositoryRoot(cwd)) { - throw new ApplicationError('configuration.invalid', `Web setup must start from the repository root (${checkoutRoot}). Change to that directory and rerun before creating PATs. No local setup session started.`); - } - releaseSetupGuard = acquireSetupSessionGuard(cwd); - const initialBranch = webBridge ? getCurrentAttachedBranch(cwd) : undefined; - const initialHead = webBridge ? getCurrentHeadSha() : undefined; - if (webBridge && (!initialBranch || !initialHead)) { - throw new ApplicationError('configuration.invalid', 'An attached Git branch and revision are required for web setup. Check out a branch before creating PATs. No local setup session started.'); - } - if (webBridge) { - webBridge.setRepository(`${gitInfo.owner}/${gitInfo.repo}`); - webBridge.setJourney(buildSetupJourneyView(`${gitInfo.owner}/${gitInfo.repo}`, 'repository', false)); - webServer = await startWebSetupServer(webBridge); - logInfo(`🌐 Local setup assistant: ${webServer.url}`); - logInfo(`🔑 Browser pairing code: ${webServer.pairingCode}`, false, undefined, true); - logInfo('If the browser does not open, copy this URL into a browser on this computer, then enter the pairing code shown above. The terminal setup remains available with copilot setup.'); - openWebSetupBrowser(webServer.url); - } - if (!options.nonInteractive) { - journey = new SetupJourneyUseCase(`${gitInfo.owner}/${gitInfo.repo}`, - webBridge ? new WebSetupJourneyPresenter(webBridge) : new ConsoleSetupJourneyPresenter()); - if (webBridge) { - const target = await webBridge.ask({ kind: 'confirm', title: 'Confirm this repository', copyId: 'repository.confirm', copyValues: { repository: `${gitInfo.owner}/${gitInfo.repo}`, branch: initialBranch ?? '' }, - description: `This local checkout resolves to ${gitInfo.owner}/${gitInfo.repo} on branch ${initialBranch}. Confirm the target before configuring PAT access or files.`, - choices: ['Yes, this is my repository', 'Stop and choose another checkout'] }); - if (target === undefined) throw new SetupTerminalCancelledError(); - if (target !== 'Yes, this is my repository') { journey.finish('cancelled'); return; } - } - journey.advance('choices'); - } - const overrides = loadSetupOverrides(options); - let presentationMode: 'basic' | 'custom' = 'custom'; - if (!options.nonInteractive && !options.dryRun) { - if (webBridge) { - const depth = await webBridge.ask({ kind: 'choice', title: 'Choose setup detail', copyId: 'setup.depth', - choices: ['Basic guided setup', 'Customize every setting'], defaultValue: 'Basic guided setup' }); - if (depth === undefined) throw new SetupTerminalCancelledError(); - presentationMode = depth === 'Basic guided setup' ? 'basic' : 'custom'; - } else if (credentialPrompt instanceof SetupCredentialPromptAdapter) { - presentationMode = await credentialPrompt.chooseSetupPresentationMode(); - } - } - let setupPatPermissions = buildSetupPatPermissionRequirements(); - let token = getSetupToken(cwd, options.token); - if (webBridge && token) { - const choice = await webBridge.ask({ kind: 'choice', title: 'An environment setup PAT is available', copyId: 'setup.environmentPat', - description: 'Its value stays in the CLI process and is never sent to this page. Exiting Copilot cannot unset your parent shell variable.', - choices: ['Use the environment PAT', 'Create or enter a different PAT'] }); - if (choice === undefined) throw new SetupTerminalCancelledError(); - if (choice !== 'Use the environment PAT') token = undefined; - } - if (token || options.nonInteractive) permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); - else permissionPresenter.showRequirements('setup', setupPatPermissions); - let setupPatAccount: string | undefined; - let permissionIntent: { draft: SetupConfiguration; answeredQuestionIds: readonly string[]; projectsWanted: boolean } | undefined; - let assertedOwnerKind: 'Organization' | 'User' | undefined; - if (!token && !options.nonInteractive && !options.dryRun) { - if (await credentialPrompt.chooseSetupPatMethod() === 'guided') { - const prepared = await new PrepareSetupPatIntentUseCase({ - collect: (initial, context, pass) => (webBridge - ? new WebSetupQuestionnaireCollector(webBridge, pass) - : new SetupQuestionnaireController(terminal!, new ConsoleSetupQuestionRenderer('permission-intent', pass))) - .collect(initial, context), - chooseOwnerKind: () => credentialPrompt.chooseSetupOwnerKind(), - review: () => credentialPrompt.reviewSetupPatIntent(), - showPreview: ({ draft, requirements, uncertain, ownerConflict, errors, pass, projectsWanted }) => { - if (ownerConflict) logInfo('This plan selects organization storage or Projects, but the owner was declared a personal account. Revise the choices or use the manual PAT path.'); - if (errors.length) logInfo(`The selected local configuration needs correction before a guided link can be generated:\n${errors.map(item => ` - ${item}`).join('\n')}`); - if (pass > 1) logInfo('Choice review complete. Returning to setup PAT permission review.'); - logInfo('Permission intent:'); - logInfo(` Initial tag: ${draft.createInitialTag ? 'yes' : 'no'}; issue workflows: ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval: ${draft.pullRequestApproval.mode}`); - logInfo(` Secrets: ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables: ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects: ${projectsWanted ? 'yes (choose exact Projects after PAT)' : 'none'}`); - webBridge?.message(`Permission preview: issue workflows ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval ${draft.pullRequestApproval.mode}; Secrets ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects ${projectsWanted ? 'yes (choose after PAT)' : 'none'}.`, 'info', undefined, 'permission.preview', { - issues: draft.features.issues ? draft.issueWorkflows.enabled.join('|') || 'none' : 'disabled', - approval: draft.pullRequestApproval.mode, - secrets: draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off', - variables: draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off', - projects: projectsWanted ? 'yes' : 'none', - }); - permissionPresenter.showRequirements('setup', requirements); - if (uncertain.length) logInfo(`May need after GitHub inspection:\n${uncertain.map(item => ` - ${item}`).join('\n')}`); - }, - showDetails: requirements => permissionPresenter.showDetailedRequirements('setup', requirements), - onManual: reason => { - if (reason === 'owner-unknown') logInfo('Owner type was not confirmed. Use the manual PAT table, or check whether the GitHub owner is an organization before retrying guided setup.'); - if (reason === 'unsupported') logInfo('A guided setup PAT link is unavailable for this owner or permission set. Enter a manually created PAT using the table above.'); - credentialPrompt.useManualSetupPat(); - permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); - }, - advanceToSetupPat: () => { journey?.advance('setup-pat'); }, - revisitChoices: () => journey!.revisitChoices(), - }).execute({ - owner: gitInfo.owner, repository: gitInfo.repo, overrides, - skipRepositoryVariables: Boolean(options.skipVariables), - skipRepositorySecrets: Boolean(options.skipSecrets), - }); - if (prepared.kind === 'guided') { - credentialPrompt.configureSetupPatGuide(prepared.url); - setupPatPermissions = [...prepared.requirements]; - assertedOwnerKind = prepared.ownerKind; - permissionIntent = prepared.permissionIntent; - } - } else { - journey?.advance('setup-pat'); - permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); - } - } - if (options.dryRun && !token && !webBridge) journey?.advance('plan'); - if (!token && !options.dryRun) journey?.advance('setup-pat'); - if (!token && !options.nonInteractive && !options.dryRun) token = await credentialPrompt.requestSetupPat(); - if (!token && !options.dryRun) { - logError('🛑 Setup requires PERSONAL_ACCESS_TOKEN with a valid token.'); - logInfo(' You can:'); - logInfo(' • Pass it on the command line: copilot setup --token '); - logInfo(' • Add it to your environment: export PERSONAL_ACCESS_TOKEN=your_github_token'); - process.exitCode = 1; - return; - } - if (token) { - journey?.advance('setup-pat'); - setupPatAccount = await new VerifySetupPatBootstrapUseCase({ - permissions: tokenPermissions, - presenter: permissionPresenter, - confirmUnverifiable: report => credentialPrompt.confirmUnverifiableTokenPermissions(report), - confirmAccount: account => credentialPrompt.confirmGuidedSetupAccount(account), - showCorrectedLink: url => credentialPrompt.showUpdatedSetupPatLink(url, 'bootstrap'), - }).execute({ owner: gitInfo.owner, repository: gitInfo.repo, token, - requirements: setupPatPermissions, guided: credentialPrompt.usedGuidedSetupPat }); - journey?.advance('plan'); - } - logInfo(options.dryRun ? '🧭 Building a dry-run setup plan...' : '🧭 Building your setup plan...'); - const auditConfiguredSetupPat = new AuditConfiguredSetupPatUseCase({ - owner: gitInfo.owner, repository: gitInfo.repo, token, - provisionalRequirements: setupPatPermissions, assertedOwnerKind, - guided: credentialPrompt.usedGuidedSetupPat, - }, { - permissions: tokenPermissions, - presenter: permissionPresenter, - confirmUnverifiable: report => credentialPrompt.confirmUnverifiableTokenPermissions(report), - showOwnerMismatch: (asserted, actual) => logInfo(`The owner was declared ${asserted}, but GitHub reports ${actual}. The guided link is no longer valid for this plan.`), - showExcessGrants: grants => logInfo(`The final plan no longer requires grants suggested earlier: ${grants.join(', ')}. Your PAT may have excess access; replace it in GitHub if least privilege is required.`), - showUpdatedLink: (url, grants) => credentialPrompt.showUpdatedSetupPatLink(url, 'final', grants), - }); - const remoteConfigurationReader = createSetupRemoteConfigurationReadPort(); - const wizard = new SetupWizardUseCase({ - ...(terminal || webBridge ? { - collector: webBridge ? new WebSetupQuestionnaireCollector(webBridge) - : new SetupQuestionnaireController(terminal!, new ConsoleSetupQuestionRenderer()), - } : {}), - planPresenter: webBridge ? new WebSetupPlanPresenter(webBridge) : new ConsoleSetupPlanPresenter(), - confirmation: options.dryRun - ? new DryRunSetupPlanConfirmation() - : webBridge ? new WebSetupPlanConfirmation(webBridge) - : new SetupPlanConfirmationAdapter(terminal, Boolean(options.yes)), - finalPermissionAudit: auditConfiguredSetupPat, - remoteConfiguration: remoteConfigurationReader, - mergeQueueReadiness: createSetupMergeQueueReadinessUseCase(), - approvalReadiness: new GithubSetupApprovalReadinessAdapter(), - approvalCheckDiscovery: new GithubSetupApprovalCheckDiscoveryAdapter(), - projectDiscovery: new GithubSetupProjectDiscoveryAdapter(), - }); - const result = await wizard.execute({ - mode: options.nonInteractive ? 'non-interactive' : 'interactive', - overrides, - ...(permissionIntent ? { permissionIntent } : {}), - skipRepositoryVariables: Boolean(options.skipVariables), - skipRepositorySecrets: Boolean(options.skipSecrets), - previewOnly: Boolean(options.dryRun), - presentationMode, - developmentBranchObservedLocally: hasLocalOrTrackedGitBranch(cwd, overrides.repository?.developmentBranch ?? 'develop'), - ...(token ? { remoteTarget: { owner: gitInfo.owner, repository: gitInfo.repo, token } } : {}), - }); - if (result.status === 'cancelled') { - journey?.finish('cancelled'); - if (result.reason !== 'questionnaire-cancelled') { - logInfo('⏭️ Setup cancelled. No changes were applied.'); - } - if (result.exitCode !== 0) process.exitCode = result.exitCode; - return; - } - if (result.status === 'blocked') { - journey?.finish('blocked'); - webBridge?.resultReason(result.reason === 'setup-permissions-unavailable' ? 'permissions' : 'storage'); - logError(new ApplicationError( - result.reason === 'setup-permissions-unavailable' ? 'authorization.credential-invalid' : 'provider.unavailable', - `${result.reason === 'setup-permissions-unavailable' - ? 'Setup is blocked by missing or unconfirmed PAT permissions:' - : 'Setup is blocked by unavailable remote storage:'}\n${result.errors.map(error => `- ${error}`).join('\n')}`, - )); - process.exitCode = result.exitCode; - return; - } - const { configuration, remoteConfiguration } = result; - const guardedFiles = webBridge ? setupPlanGuardPaths(result.plan) : undefined; - const webApplySnapshot = guardedFiles ? captureSetupApplySnapshot(checkoutRoot, guardedFiles) : undefined; - const credentialRequirements = buildSetupCredentialRequirements(configuration); - const workflowComparisons = new SetupDoctorWorkspaceQueryAdapter().compareWorkflows(effectiveIssueWorkflowFeatures(configuration), configuration); - const updateWorkflows = await workflowPrompt.confirmWorkflowUpdates(workflowComparisons, Boolean(options.updateWorkflows)); - const approvedWorkflowFiles = updateWorkflows - ? workflowComparisons.filter(comparison => comparison.status === 'changed').map(comparison => comparison.file) - : []; - if (options.dryRun) { - if (webBridge) journey?.advance('plan'); - journey?.finish('dry-run'); - logInfo('✅ Dry run complete. No files or GitHub resources were changed.'); - return; - } - journey?.advance('credentials'); - const workflowTokenPermissions = buildWorkflowPatPermissionRequirements(configuration, remoteConfiguration); - const githubIdentities = new SetupGithubIdentityQueryAdapter(); - if (!options.nonInteractive && !options.workflowPat && !options.secret?.PAT) { - try { - const workflowPatGuide = buildSetupPatCreationUrl({ - role: 'workflow', owner: gitInfo.owner, repository: gitInfo.repo, expiresIn: 90, - requirements: workflowTokenPermissions, - }); - credentialPrompt.configureWorkflowPatGuide(workflowPatGuide, login => githubIdentities.resolve(login, token!), workflowTokenPermissions); - } catch (error) { - if (!(error instanceof UnsupportedSetupPatLinkError)) throw error; - logInfo('A guided fine-grained bot PAT link is unavailable for one or more required permissions. Use the permission table and manual path; review whether a classic PAT is required for this plan.'); - permissionPresenter.showDetailedRequirements('workflow', workflowTokenPermissions); - } - } - const credentials = await createSetupCredentialsUseCase(credentialPrompt, permissionPresenter, - webBridge ? { allowPreApplyHealthWorkflow: false } : { - onTemporaryWorkflowMutationAttempt: () => { - setupMutationStarted = true; - journey?.markMutationStarted(); - }, - }).collect({ - owner: gitInfo.owner, - repository: gitInfo.repo, - setupToken: token ?? '', - requirements: credentialRequirements, - manageSecrets: !options.skipSecrets && configuration.manageRepositorySecrets, - secretStoragePolicy: configuration.storage.secrets, - ref: configuration.repository.mainBranch, - remoteConfiguration, - workflowTokenPermissions, - }); - const guidedBotIdentity = credentialPrompt.guidedWorkflowBotIdentity; - if (guidedBotIdentity && credentials.collection.workflowPat) { - const verifiedBot = await new VerifyGuidedWorkflowPatIdentityUseCase(githubIdentities) - .execute(guidedBotIdentity, credentials.collection.workflowPat.value); - logInfo(`✅ Workflow PAT owner verified as @${verifiedBot.login} (GitHub account ID ${verifiedBot.id}).`); - if (setupPatAccount?.toLowerCase() === verifiedBot.login.toLowerCase()) { - logInfo('The workflow PAT and setup PAT use the same GitHub account. If this account authors PRs, bot-generated events and guarded self-approval may not behave as intended; use a dedicated bot account where required.'); - } - } - if (webBridge) { - if (!remoteConfiguration || !guardedFiles || !webApplySnapshot || !initialBranch || !initialHead || !token) { - throw new ApplicationError('configuration.invalid', 'The approved setup evidence is incomplete. No mutation started; restart and review a new plan.'); - } - const authorization = await new VerifyWebSetupApplyUseCase({ - confirm: async () => { - const answer = await webBridge.ask({ kind: 'confirm', title: 'Apply this setup now?', copyId: 'apply.confirm', - description: 'This is the final approval. Local files and selected GitHub resources may change. A partial result may require inspection before retrying.', - choices: ['Apply setup', 'Stop without applying'] }); - return answer === undefined ? undefined : answer === 'Apply setup' ? 'apply' : 'stop'; - }, - readRepositoryFacts: () => { - const current = getGitInfo(); - return 'error' in current ? undefined : { - owner: current.owner, repository: current.repo, checkoutRoot: getGitRepositoryRoot(cwd), - branch: getCurrentAttachedBranch(cwd) ?? '', head: getCurrentHeadSha() ?? '', - }; - }, - fileSnapshotMatches: setupApplySnapshotMatches, - remote: remoteConfigurationReader, - permissionAudit: auditConfiguredSetupPat, - sessionState: () => webBridge.snapshot().outcome === 'cancelled' ? 'cancelled' - : webBridge.snapshot().outcome ? 'ended' : 'active', - }).execute({ - repository: { owner: gitInfo.owner, repository: gitInfo.repo, checkoutRoot, - branch: initialBranch, head: initialHead }, - selectedFiles: guardedFiles, fileSnapshot: webApplySnapshot, approvedRemote: remoteConfiguration, - configuration, setupToken: token, - }); - if (authorization === 'cancelled') throw new SetupTerminalCancelledError(); - if (authorization === 'declined') { journey?.finish('cancelled'); return; } - } - logInfo('⚙️ Applying the approved setup plan...'); - journey?.advance('apply'); - const params = buildSetupParams( - options, - gitInfo, - token ?? '', - configuration, - credentials.collection, - approvedWorkflowFiles, - remoteConfiguration, - ); - setupMutationStarted = true; - journey?.markMutationStarted(); - setupApplyStarted = true; - const actionResults = await runLocalAction(params); - webBridge?.effects(setupResultEffects(actionResults)); - if (actionResults.some(actionResult => !actionResult.success || actionResult.errors.length > 0)) { - const failure = setupActionResultFailure(actionResults); - if (failure) webBridge?.resultReason(failure.reasonCode, failure.diagnosticRef); - journey?.finish('partial'); - logInfo('Setup reported failures or partial completion. If a bot PAT was supplied, its Secret may already have been written; inspect the result and GitHub Secret name/scope before retrying or revoking it.'); - process.exitCode = 1; - } else { - if (webBridge && token) { - const doctorToken = token; - webBridge.configureReadOnlyDoctor(async () => { - const diagnosis = await createSetupDoctorUseCase().execute({ owner: gitInfo.owner, - repository: gitInfo.repo, setupToken: doctorToken, configuration, readOnly: true }); - return { healthy: diagnosis.report.healthy, ...diagnosis.report.totals }; - }); - } - journey?.finish('complete'); - } - } catch (error) { - journey?.finish(setupMutationStarted ? 'partial' : error instanceof SetupTerminalCancelledError ? 'cancelled' : 'blocked'); - const normalizedError = error instanceof SetupTerminalCancelledError ? undefined - : toApplicationError(error, 'workflow.failed', 'Setup failed.'); - webBridge?.resultReason(error instanceof SetupTerminalCancelledError ? 'cancelled' - : setupResultReason(normalizedError!.code), normalizedError?.correlationId); - if (setupMutationStarted && !setupApplyStarted) { - logInfo('A temporary credential-health workflow create was attempted before Apply. Inspect the selected branch and GitHub workflow history before retrying; a failed request may still have reached GitHub.'); - } - if (credentialPrompt.guidedWorkflowBotIdentity) { - logInfo(setupApplyStarted - ? 'Setup may be partially applied. Inspect the GitHub Secret before deleting or replacing the bot PAT.' - : 'No bot Secret write started. If you generated an unused bot PAT in GitHub, delete it there; Copilot cannot revoke it.'); - } - if (error instanceof SetupTerminalCancelledError) { - logInfo(setupMutationStarted - ? 'Setup stopped after a possible credential-health workflow change. Inspect the selected branch and GitHub workflow history before retrying.' - : 'Setup cancelled. No changes were applied.'); - process.exitCode = 130; - return; - } - logError(toApplicationError(error, 'workflow.failed', 'Setup failed.')); - process.exitCode = 1; - } finally { - credentialPrompt.showSetupPatCleanupReminder(); - terminal?.close(); - if (webBridge && webServer) { - const outcome = webBridge.snapshot().journey?.outcome ?? (process.exitCode ? 'blocked' : 'cancelled'); - webBridge.finish(outcome, outcome === 'complete' - ? 'Setup completed. Delete the temporary setup PAT in GitHub; keep the bot PAT while its Secret is in use.' - : outcome === 'dry-run' ? 'Dry run complete. No files or GitHub resources changed.' - : outcome === 'partial' ? 'Setup may be partial. Inspect GitHub resources and run copilot doctor --read-only before retrying.' - : 'No further setup changes will be applied. Any PAT already created in GitHub still exists until you delete it there.'); - logInfo('The local browser page shows the result. Choose “Close local session” there, or stop this command with Ctrl+C.'); - await webServer.closed; - } - releaseSetupGuard?.(); - } - }); + .action(executeSetupCommand); } diff --git a/src/cli/commands/setup_execution.ts b/src/cli/commands/setup_execution.ts new file mode 100644 index 000000000..cdb87c213 --- /dev/null +++ b/src/cli/commands/setup_execution.ts @@ -0,0 +1,361 @@ +import { runLocalAction } from '../../actions/local_action'; +import { getSetupToken } from '../../utils/setup_files'; +import { logError, logInfo } from '../../utils/logger'; +import { getCurrentAttachedBranch, getCurrentHeadSha, getGitInfo, getGitRepositoryRoot, hasLocalOrTrackedGitBranch, isGitRepositoryRoot, isInsideGitRepo } from '../../cli_context'; +import { buildSetupParams } from './setup_policy'; +import { loadSetupOverrides, type SetupCommandOverrideOptions } from '../setup_command_options'; +import { SetupQuestionnaireController, SetupWizardUseCase } from '../../application/usecases/setup'; +import { SetupSessionCoordinator, type SetupSessionDecision } from '../../application/usecases/setup/setup_session_coordinator'; +import { setupPlanGuardPaths } from '../../application/policies/setup_configuration_plan'; +import { collectSetupPatIntent } from '../setup_pat_intent_adapter'; +import { AuditConfiguredSetupPatUseCase } from '../../application/usecases/setup/audit_configured_setup_pat_use_case'; +import { VerifySetupPatBootstrapUseCase } from '../../application/usecases/setup/verify_setup_pat_bootstrap_use_case'; +import { effectiveIssueWorkflowFeatures } from '../../application/policies/setup_configuration_policy'; +import { buildSetupPatPermissionRequirements } from '../../application/policies/setup_token_permission_policy'; +import { createSetupRemoteConfigurationReadPort } from '../../infrastructure/composition/setup_credentials_composition_root'; +import { collectSetupCredentials } from '../setup_credential_collection'; +import { createSetupDoctorUseCase, createSetupMergeQueueReadinessUseCase } from '../../infrastructure/composition/setup_doctor_composition_root'; +import { SetupDoctorWorkspaceQueryAdapter } from '../../infrastructure/setup_workspace_adapter'; +import { GithubSetupApprovalReadinessAdapter } from '../../infrastructure/setup_approval_readiness_adapter'; +import { GithubSetupApprovalCheckDiscoveryAdapter } from '../../infrastructure/github_setup_approval_check_discovery_adapter'; +import { GithubSetupProjectDiscoveryAdapter } from '../../infrastructure/github_setup_project_discovery_adapter'; +import type { SetupConfiguration, SetupCredentialCollection, SetupRemoteConfiguration } from '../../domain/setup'; +import type { SetupConfigurationOverrides } from '../../application/policies/setup_configuration_policy'; +import { ApplicationError } from '../../application/errors/application_error'; +import { createInteractiveTerminalDriver } from '../setup_terminal_driver'; +import { ConsoleSetupQuestionRenderer } from '../setup_question_renderer'; +import { ConsoleSetupPlanPresenter } from '../setup_plan_presenter'; +import { DryRunSetupPlanConfirmation, SetupPlanConfirmationAdapter } from '../setup_confirmation_adapter'; +import { SetupCredentialPromptAdapter, SetupTerminalCancelledError } from '../setup_credential_prompt_adapter'; +import { SetupWorkflowUpdatePromptAdapter } from '../setup_workflow_update_prompt_adapter'; +import { ConsoleSetupTokenPermissionPresenter } from '../setup_token_permission_presenter'; +import { createSetupTokenPermissionsUseCase } from '../../infrastructure/composition/setup_token_permissions_composition_root'; +import { authorizeWebSetupApply } from '../setup_apply_authorization'; +import { SetupJourneyUseCase } from '../../application/usecases/setup/setup_journey_use_case'; +import { buildSetupJourneyView } from '../../application/policies/setup_journey_policy'; +import { ConsoleSetupJourneyPresenter } from '../setup_journey_presenter'; +import { WebSetupBridge } from '../web_setup_bridge'; +import { captureSetupApplySnapshot } from '../setup_apply_snapshot'; +import { acquireSetupSessionGuard } from '../setup_session_guard'; +import { startWebSetupServer, openWebSetupBrowser, type WebSetupServer } from '../web_setup_server'; +import { + WebSetupCredentialPrompt, WebSetupJourneyPresenter, WebSetupPermissionPresenter, + WebSetupPlanConfirmation, WebSetupPlanPresenter, WebSetupQuestionnaireCollector, + WebSetupWorkflowUpdatePrompt, +} from '../web_setup_adapters'; +import { setupActionResultFailure, setupResultEffects } from '../setup_result_receipt'; +import { reportSetupFailure, finishWebSetupSession } from '../setup_outcome_adapter'; + +export interface SetupExecutionOptions extends SetupCommandOverrideOptions { + debug?: boolean; token?: string; workflowPat?: string; secret?: Record; + nonInteractive?: boolean; web?: boolean; yes?: boolean; dryRun?: boolean; + skipSecrets?: boolean; skipVariables?: boolean; updateWorkflows?: boolean; + confirmUnverifiableWritePermissions?: boolean; +} + +export async function executeSetupCommand(options: SetupExecutionOptions): Promise { + const terminal = options.nonInteractive || options.web ? undefined : createInteractiveTerminalDriver(); + const webBridge = options.web ? new WebSetupBridge('Resolving repository…') : undefined; + let webServer: WebSetupServer | undefined; + const credentialPrompt = webBridge ? new WebSetupCredentialPrompt(webBridge) : new SetupCredentialPromptAdapter(terminal, { + ...(options.workflowPat ? { PAT: options.workflowPat } : {}), + ...options.secret, + }, Boolean(options.confirmUnverifiableWritePermissions)); + const permissionPresenter = webBridge ? new WebSetupPermissionPresenter(webBridge) + : new ConsoleSetupTokenPermissionPresenter(options.nonInteractive ? 'full' : 'summary'); + const tokenPermissions = createSetupTokenPermissionsUseCase(); + const workflowPrompt = webBridge ? new WebSetupWorkflowUpdatePrompt(webBridge) : new SetupWorkflowUpdatePromptAdapter(terminal); + const cwd = process.cwd(); + let setupMutationStarted = false; + let setupApplyStarted = false; + let releaseSetupGuard: (() => void) | undefined; + let journey: SetupJourneyUseCase | undefined; + let gitInfo!: { owner: string; repo: string }; + let checkoutRoot = cwd; + let initialBranch: string | undefined; + let initialHead: string | undefined; + let overrides!: SetupConfigurationOverrides; + let presentationMode: 'basic' | 'custom' = 'custom'; + let setupPatPermissions = buildSetupPatPermissionRequirements(); + let token: string | undefined; + let setupPatAccount: string | undefined; + let permissionIntent: { draft: SetupConfiguration; answeredQuestionIds: readonly string[]; projectsWanted: boolean } | undefined; + let assertedOwnerKind: 'Organization' | 'User' | undefined; + let auditConfiguredSetupPat!: AuditConfiguredSetupPatUseCase; + let remoteConfigurationReader!: ReturnType; + let configuration!: SetupConfiguration; + let remoteConfiguration: SetupRemoteConfiguration | undefined; + let guardedFiles: ReturnType | undefined; + let webApplySnapshot: ReturnType | undefined; + let approvedWorkflowFiles: string[] = []; + let credentialsCollection: SetupCredentialCollection | undefined; + try { + const session = new SetupSessionCoordinator({ + repository: async (): Promise => { + if (options.web && (options.nonInteractive || options.yes || options.token || options.workflowPat + || Object.keys(options.secret ?? {}).length || options.confirmUnverifiableWritePermissions)) { + throw new ApplicationError('configuration.invalid', '--web cannot be combined with --non-interactive, --yes, --token, --workflow-pat, --secret, or --confirm-unverifiable-write-permissions. Use the browser for these decisions or run copilot setup in the terminal.'); + } + logInfo('🔍 Checking we are inside a git repository...'); + if (!isInsideGitRepo(cwd)) { + logError('❌ Not a git repository. Run "copilot setup" from the root of a git repo.'); + process.exitCode = 1; + return 'blocked'; + } + logInfo('✅ Git repository detected.'); + logInfo('🔗 Resolving repository (owner/repo)...'); + const resolvedGitInfo = getGitInfo(); + if ('error' in resolvedGitInfo) { + logError(resolvedGitInfo.error); + process.exitCode = 1; + return 'blocked'; + } + gitInfo = resolvedGitInfo; + logInfo(`📦 Repository: ${gitInfo.owner}/${gitInfo.repo}`); + checkoutRoot = webBridge ? getGitRepositoryRoot(cwd) : cwd; + if (webBridge && !isGitRepositoryRoot(cwd)) { + throw new ApplicationError('configuration.invalid', `Web setup must start from the repository root (${checkoutRoot}). Change to that directory and rerun before creating PATs. No local setup session started.`); + } + releaseSetupGuard = acquireSetupSessionGuard(cwd); + initialBranch = webBridge ? getCurrentAttachedBranch(cwd) : undefined; + initialHead = webBridge ? getCurrentHeadSha() : undefined; + if (webBridge && (!initialBranch || !initialHead)) { + throw new ApplicationError('configuration.invalid', 'An attached Git branch and revision are required for web setup. Check out a branch before creating PATs. No local setup session started.'); + } + if (webBridge) { + webBridge.setRepository(`${gitInfo.owner}/${gitInfo.repo}`); + webBridge.setJourney(buildSetupJourneyView(`${gitInfo.owner}/${gitInfo.repo}`, 'repository', false)); + webServer = await startWebSetupServer(webBridge); + logInfo(`🌐 Local setup assistant: ${webServer.url}`); + logInfo(`🔑 Browser pairing code: ${webServer.pairingCode}`, false, undefined, true); + logInfo('If the browser does not open, copy this URL into a browser on this computer, then enter the pairing code shown above. The terminal setup remains available with copilot setup.'); + openWebSetupBrowser(webServer.url); + } + if (!options.nonInteractive) { + journey = new SetupJourneyUseCase(`${gitInfo.owner}/${gitInfo.repo}`, + webBridge ? new WebSetupJourneyPresenter(webBridge) : new ConsoleSetupJourneyPresenter()); + if (webBridge) { + const target = await webBridge.ask({ kind: 'confirm', title: 'Confirm this repository', copyId: 'repository.confirm', copyValues: { repository: `${gitInfo.owner}/${gitInfo.repo}`, branch: initialBranch ?? '' }, + description: `This local checkout resolves to ${gitInfo.owner}/${gitInfo.repo} on branch ${initialBranch}. Confirm the target before configuring PAT access or files.`, + choices: ['Yes, this is my repository', 'Stop and choose another checkout'] }); + if (target === undefined) throw new SetupTerminalCancelledError(); + if (target !== 'Yes, this is my repository') return 'cancelled'; + } + } + return 'continue'; + }, + choices: async (): Promise => { + overrides = loadSetupOverrides(options); + if (!options.nonInteractive && !options.dryRun) { + if (webBridge) { + const depth = await webBridge.ask({ kind: 'choice', title: 'Choose setup detail', copyId: 'setup.depth', + choices: ['Basic guided setup', 'Customize every setting'], defaultValue: 'Basic guided setup' }); + if (depth === undefined) throw new SetupTerminalCancelledError(); + presentationMode = depth === 'Basic guided setup' ? 'basic' : 'custom'; + } else if (credentialPrompt instanceof SetupCredentialPromptAdapter) { + presentationMode = await credentialPrompt.chooseSetupPresentationMode(); + } + } + token = getSetupToken(cwd, options.token); + if (webBridge && token) { + const choice = await webBridge.ask({ kind: 'choice', title: 'An environment setup PAT is available', copyId: 'setup.environmentPat', + description: 'Its value stays in the CLI process and is never sent to this page. Exiting Copilot cannot unset your parent shell variable.', + choices: ['Use the environment PAT', 'Create or enter a different PAT'] }); + if (choice === undefined) throw new SetupTerminalCancelledError(); + if (choice !== 'Use the environment PAT') token = undefined; + } + if (token || options.nonInteractive) permissionPresenter.showDetailedRequirements('setup', setupPatPermissions); + else permissionPresenter.showRequirements('setup', setupPatPermissions); + if (!token && !options.nonInteractive && !options.dryRun) { + const intent = await collectSetupPatIntent({ + owner: gitInfo.owner, repository: gitInfo.repo, overrides, + skipRepositoryVariables: Boolean(options.skipVariables), + skipRepositorySecrets: Boolean(options.skipSecrets), + terminal, bridge: webBridge, journey, credentialPrompt, permissionPresenter, + initialRequirements: setupPatPermissions, + }); + setupPatPermissions = [...intent.requirements]; + assertedOwnerKind = intent.assertedOwnerKind; + permissionIntent = intent.permissionIntent; + } + return 'continue'; + }, + setupPat: async (): Promise => { + if (!token && !options.nonInteractive && !options.dryRun) token = await credentialPrompt.requestSetupPat(); + if (!token && !options.dryRun) { + logError('🛑 Setup requires PERSONAL_ACCESS_TOKEN with a valid token.'); + logInfo(' You can:'); + logInfo(' • Pass it on the command line: copilot setup --token '); + logInfo(' • Add it to your environment: export PERSONAL_ACCESS_TOKEN=your_github_token'); + process.exitCode = 1; + return 'blocked'; + } + if (token) { + setupPatAccount = await new VerifySetupPatBootstrapUseCase({ + permissions: tokenPermissions, + presenter: permissionPresenter, + confirmUnverifiable: report => credentialPrompt.confirmUnverifiableTokenPermissions(report), + confirmAccount: account => credentialPrompt.confirmGuidedSetupAccount(account), + showCorrectedLink: url => credentialPrompt.showUpdatedSetupPatLink(url, 'bootstrap'), + }).execute({ owner: gitInfo.owner, repository: gitInfo.repo, token, + requirements: setupPatPermissions, guided: credentialPrompt.usedGuidedSetupPat }); + } + return 'continue'; + }, + plan: async (): Promise => { + logInfo(options.dryRun ? '🧭 Building a dry-run setup plan...' : '🧭 Building your setup plan...'); + auditConfiguredSetupPat = new AuditConfiguredSetupPatUseCase({ + owner: gitInfo.owner, repository: gitInfo.repo, token, + provisionalRequirements: setupPatPermissions, assertedOwnerKind, + guided: credentialPrompt.usedGuidedSetupPat, + }, { + permissions: tokenPermissions, + presenter: permissionPresenter, + confirmUnverifiable: report => credentialPrompt.confirmUnverifiableTokenPermissions(report), + showOwnerMismatch: (asserted, actual) => logInfo(`The owner was declared ${asserted}, but GitHub reports ${actual}. The guided link is no longer valid for this plan.`), + showExcessGrants: grants => logInfo(`The final plan no longer requires grants suggested earlier: ${grants.join(', ')}. Your PAT may have excess access; replace it in GitHub if least privilege is required.`), + showUpdatedLink: (url, grants) => credentialPrompt.showUpdatedSetupPatLink(url, 'final', grants), + }); + remoteConfigurationReader = createSetupRemoteConfigurationReadPort(); + const wizard = new SetupWizardUseCase({ + ...(terminal || webBridge ? { + collector: webBridge ? new WebSetupQuestionnaireCollector(webBridge) + : new SetupQuestionnaireController(terminal!, new ConsoleSetupQuestionRenderer()), + } : {}), + planPresenter: webBridge ? new WebSetupPlanPresenter(webBridge) : new ConsoleSetupPlanPresenter(), + confirmation: options.dryRun + ? new DryRunSetupPlanConfirmation() + : webBridge ? new WebSetupPlanConfirmation(webBridge) + : new SetupPlanConfirmationAdapter(terminal, Boolean(options.yes)), + finalPermissionAudit: auditConfiguredSetupPat, + remoteConfiguration: remoteConfigurationReader, + mergeQueueReadiness: createSetupMergeQueueReadinessUseCase(), + approvalReadiness: new GithubSetupApprovalReadinessAdapter(), + approvalCheckDiscovery: new GithubSetupApprovalCheckDiscoveryAdapter(), + projectDiscovery: new GithubSetupProjectDiscoveryAdapter(), + }); + const result = await wizard.execute({ + mode: options.nonInteractive ? 'non-interactive' : 'interactive', + overrides, + ...(permissionIntent ? { permissionIntent } : {}), + skipRepositoryVariables: Boolean(options.skipVariables), + skipRepositorySecrets: Boolean(options.skipSecrets), + previewOnly: Boolean(options.dryRun), + presentationMode, + developmentBranchObservedLocally: hasLocalOrTrackedGitBranch(cwd, overrides.repository?.developmentBranch ?? 'develop'), + ...(token ? { remoteTarget: { owner: gitInfo.owner, repository: gitInfo.repo, token } } : {}), + }); + if (result.status === 'cancelled') { + if (result.reason !== 'questionnaire-cancelled') { + logInfo('⏭️ Setup cancelled. No changes were applied.'); + } + if (result.exitCode !== 0) process.exitCode = result.exitCode; + return 'cancelled'; + } + if (result.status === 'blocked') { + webBridge?.resultReason(result.reason === 'setup-permissions-unavailable' ? 'permissions' : 'storage'); + logError(new ApplicationError( + result.reason === 'setup-permissions-unavailable' ? 'authorization.credential-invalid' : 'provider.unavailable', + `${result.reason === 'setup-permissions-unavailable' + ? 'Setup is blocked by missing or unconfirmed PAT permissions:' + : 'Setup is blocked by unavailable remote storage:'}\n${result.errors.map(error => `- ${error}`).join('\n')}`, + )); + process.exitCode = result.exitCode; + return 'blocked'; + } + configuration = result.configuration; + remoteConfiguration = result.remoteConfiguration; + guardedFiles = webBridge ? setupPlanGuardPaths(result.plan) : undefined; + webApplySnapshot = guardedFiles ? captureSetupApplySnapshot(checkoutRoot, guardedFiles) : undefined; + const workflowComparisons = new SetupDoctorWorkspaceQueryAdapter().compareWorkflows(effectiveIssueWorkflowFeatures(configuration), configuration); + const updateWorkflows = await workflowPrompt.confirmWorkflowUpdates(workflowComparisons, Boolean(options.updateWorkflows)); + approvedWorkflowFiles = updateWorkflows + ? workflowComparisons.filter(comparison => comparison.status === 'changed').map(comparison => comparison.file) + : []; + if (options.dryRun) { + logInfo('✅ Dry run complete. No files or GitHub resources were changed.'); + return 'dry-run'; + } + return 'continue'; + }, + credentials: async (possibleMutation): Promise => { + credentialsCollection = await collectSetupCredentials({ + owner: gitInfo.owner, repository: gitInfo.repo, setupToken: token ?? '', + setupPatAccount, configuration, remoteConfiguration, + skipSecrets: Boolean(options.skipSecrets), nonInteractive: Boolean(options.nonInteractive), + workflowPat: options.workflowPat, secret: options.secret, bridge: webBridge, + prompt: credentialPrompt, permissionPresenter, + possibleMutation: () => { setupMutationStarted = true; possibleMutation(); }, + }); + return 'continue'; + }, + authorizeApply: async (): Promise => { + if (webBridge) return authorizeWebSetupApply({ + bridge: webBridge, cwd, owner: gitInfo.owner, repository: gitInfo.repo, + checkoutRoot, initialBranch, initialHead, selectedFiles: guardedFiles, + fileSnapshot: webApplySnapshot, approvedRemote: remoteConfiguration, + configuration, setupToken: token, remoteReader: remoteConfigurationReader, + permissionAudit: auditConfiguredSetupPat, + }); + return 'continue'; + }, + apply: async report => { + logInfo('⚙️ Applying the approved setup plan...'); + const params = buildSetupParams( + options, + gitInfo, + token ?? '', + configuration, + credentialsCollection, + approvedWorkflowFiles, + remoteConfiguration, + ); + setupMutationStarted = true; + setupApplyStarted = true; + const actionResults = await runLocalAction(params, { + onSetupProgress: effect => { report(effect); webBridge?.progress(effect); }, + }); + webBridge?.effects(setupResultEffects(actionResults)); + if (actionResults.length === 0 || actionResults.some(actionResult => !actionResult.success || actionResult.errors.length > 0)) { + const failure = setupActionResultFailure(actionResults); + if (failure) webBridge?.resultReason(failure.reasonCode, failure.diagnosticRef); + logInfo('Setup reported failures or partial completion. If a bot PAT was supplied, its Secret may already have been written; inspect the result and GitHub Secret name/scope before retrying or revoking it.'); + process.exitCode = 1; + } else { + if (webBridge && token) { + const doctorToken = token; + webBridge.configureReadOnlyDoctor(async () => { + const diagnosis = await createSetupDoctorUseCase().execute({ owner: gitInfo.owner, + repository: gitInfo.repo, setupToken: doctorToken, configuration, readOnly: true }); + return { healthy: diagnosis.report.healthy, ...diagnosis.report.totals }; + }); + } + } + return { success: actionResults.length > 0 && actionResults.every(actionResult => actionResult.success && actionResult.errors.length === 0), effects: [] }; + }, + liveness: () => webBridge?.snapshot().outcome === 'cancelled' ? 'cancelled' + : webBridge?.snapshot().outcome ? 'expired' : 'active', + present: (stage, mutationStarted, outcome) => { + if (!journey) return; + journey.advance(stage); + if (mutationStarted) journey.markMutationStarted(); + if (outcome) journey.finish(outcome); + }, + isCancellationError: error => error instanceof SetupTerminalCancelledError, + }); + const run = await session.execute(); + setupMutationStarted = run.mutationStarted; + if (run.error !== undefined) throw run.error; + if (run.outcome === 'blocked' || run.outcome === 'partial') process.exitCode = 1; + } catch (error) { + process.exitCode = reportSetupFailure(error, { journey, bridge: webBridge, + mutationStarted: setupMutationStarted, applyStarted: setupApplyStarted, + guidedBotIdentity: Boolean(credentialPrompt.guidedWorkflowBotIdentity) }); + } finally { + credentialPrompt.showSetupPatCleanupReminder(); + terminal?.close(); + await finishWebSetupSession(webBridge, webServer, process.exitCode); + releaseSetupGuard?.(); + } + +} diff --git a/src/cli/setup_apply_authorization.ts b/src/cli/setup_apply_authorization.ts new file mode 100644 index 000000000..1049ba871 --- /dev/null +++ b/src/cli/setup_apply_authorization.ts @@ -0,0 +1,61 @@ +import { getCurrentAttachedBranch, getCurrentHeadSha, getGitInfo, getGitRepositoryRoot } from '../cli_context'; +import type { SetupConfiguration, SetupRemoteConfiguration } from '../domain/setup'; +import type { AuditConfiguredSetupPatUseCase } from '../application/usecases/setup/audit_configured_setup_pat_use_case'; +import { VerifyWebSetupApplyUseCase } from '../application/usecases/setup/verify_web_setup_apply_use_case'; +import { ApplicationError } from '../application/errors/application_error'; +import type { SetupRemoteConfigurationReadPort } from '../application/ports/setup_wizard_ports'; +import { SetupTerminalCancelledError } from './setup_credential_prompt_adapter'; +import { captureSetupApplySnapshot, setupApplySnapshotMatches } from './setup_apply_snapshot'; +import type { WebSetupBridge } from './web_setup_bridge'; + +export interface WebApplyAuthorizationInput { + readonly bridge: WebSetupBridge; + readonly cwd: string; + readonly owner: string; + readonly repository: string; + readonly checkoutRoot: string; + readonly initialBranch?: string; + readonly initialHead?: string; + readonly selectedFiles?: readonly string[]; + readonly fileSnapshot?: ReturnType; + readonly approvedRemote?: SetupRemoteConfiguration; + readonly configuration: SetupConfiguration; + readonly setupToken?: string; + readonly remoteReader: SetupRemoteConfigurationReadPort; + readonly permissionAudit: AuditConfiguredSetupPatUseCase; +} + +/** Web transport and Git facts for the application-owned final approval. */ +export async function authorizeWebSetupApply(input: WebApplyAuthorizationInput): Promise<'continue' | 'cancelled'> { + const { bridge } = input; + if (!input.approvedRemote || !input.selectedFiles || !input.fileSnapshot || !input.initialBranch || !input.initialHead || !input.setupToken) { + throw new ApplicationError('configuration.invalid', 'The approved setup evidence is incomplete. No mutation started; restart and review a new plan.'); + } + const authorization = await new VerifyWebSetupApplyUseCase({ + confirm: async () => { + const answer = await bridge.ask({ kind: 'confirm', title: 'Apply this setup now?', copyId: 'apply.confirm', + description: 'This is the final approval. Local files and selected GitHub resources may change. A partial result may require inspection before retrying.', + choices: ['Apply setup', 'Stop without applying'] }); + return answer === undefined ? undefined : answer === 'Apply setup' ? 'apply' : 'stop'; + }, + readRepositoryFacts: () => { + const current = getGitInfo(); + return 'error' in current ? undefined : { + owner: current.owner, repository: current.repo, checkoutRoot: getGitRepositoryRoot(input.cwd), + branch: getCurrentAttachedBranch(input.cwd) ?? '', head: getCurrentHeadSha() ?? '', + }; + }, + fileSnapshotMatches: setupApplySnapshotMatches, + remote: input.remoteReader, + permissionAudit: input.permissionAudit, + sessionState: () => bridge.snapshot().outcome === 'cancelled' ? 'cancelled' + : bridge.snapshot().outcome ? 'ended' : 'active', + }).execute({ + repository: { owner: input.owner, repository: input.repository, checkoutRoot: input.checkoutRoot, + branch: input.initialBranch, head: input.initialHead }, + selectedFiles: input.selectedFiles, fileSnapshot: input.fileSnapshot, approvedRemote: input.approvedRemote, + configuration: input.configuration, setupToken: input.setupToken, + }); + if (authorization === 'cancelled') throw new SetupTerminalCancelledError(); + return authorization === 'declined' ? 'cancelled' : 'continue'; +} diff --git a/src/cli/setup_credential_collection.ts b/src/cli/setup_credential_collection.ts new file mode 100644 index 000000000..49ba5f99b --- /dev/null +++ b/src/cli/setup_credential_collection.ts @@ -0,0 +1,69 @@ +import type { SetupConfiguration, SetupCredentialCollection, SetupRemoteConfiguration } from '../domain/setup'; +import { buildSetupCredentialRequirements } from '../application/policies/setup_configuration_policy'; +import { buildWorkflowPatPermissionRequirements } from '../application/policies/setup_token_permission_policy'; +import { buildSetupPatCreationUrl, UnsupportedSetupPatLinkError } from '../application/policies/setup_pat_creation_url_policy'; +import { VerifyGuidedWorkflowPatIdentityUseCase } from '../application/usecases/setup/verify_guided_workflow_pat_identity_use_case'; +import { createSetupCredentialsUseCase } from '../infrastructure/composition/setup_credentials_composition_root'; +import { SetupGithubIdentityQueryAdapter } from '../infrastructure/setup_github_identity_query_adapter'; +import { logInfo } from '../utils/logger'; +import { SetupCredentialPromptAdapter } from './setup_credential_prompt_adapter'; +import { ConsoleSetupTokenPermissionPresenter } from './setup_token_permission_presenter'; +import { WebSetupCredentialPrompt, WebSetupPermissionPresenter } from './web_setup_adapters'; +import type { WebSetupBridge } from './web_setup_bridge'; + +interface CredentialInput { + readonly owner: string; + readonly repository: string; + readonly setupToken: string; + readonly setupPatAccount?: string; + readonly configuration: SetupConfiguration; + readonly remoteConfiguration?: SetupRemoteConfiguration; + readonly skipSecrets: boolean; + readonly nonInteractive: boolean; + readonly workflowPat?: string; + readonly secret?: Readonly>; + readonly bridge?: WebSetupBridge; + readonly prompt: SetupCredentialPromptAdapter | WebSetupCredentialPrompt; + readonly permissionPresenter: ConsoleSetupTokenPermissionPresenter | WebSetupPermissionPresenter; + readonly possibleMutation: () => void; +} + +/** Wires bot-PAT guidance and credential ports for both setup presentations. */ +export async function collectSetupCredentials(input: CredentialInput): Promise { + const requirements = buildSetupCredentialRequirements(input.configuration); + const workflowTokenPermissions = buildWorkflowPatPermissionRequirements(input.configuration, input.remoteConfiguration); + const githubIdentities = new SetupGithubIdentityQueryAdapter(); + if (!input.nonInteractive && !input.workflowPat && !input.secret?.PAT) { + try { + const guide = buildSetupPatCreationUrl({ + role: 'workflow', owner: input.owner, repository: input.repository, expiresIn: 90, + requirements: workflowTokenPermissions, + }); + input.prompt.configureWorkflowPatGuide(guide, login => githubIdentities.resolve(login, input.setupToken), workflowTokenPermissions); + } catch (error) { + if (!(error instanceof UnsupportedSetupPatLinkError)) throw error; + logInfo('A guided fine-grained bot PAT link is unavailable for one or more required permissions. Use the permission table and manual path; review whether a classic PAT is required for this plan.'); + input.permissionPresenter.showDetailedRequirements('workflow', workflowTokenPermissions); + } + } + const credentials = await createSetupCredentialsUseCase(input.prompt, input.permissionPresenter, + input.bridge ? { allowPreApplyHealthWorkflow: false } : { + onTemporaryWorkflowMutationAttempt: input.possibleMutation, + }).collect({ + owner: input.owner, repository: input.repository, setupToken: input.setupToken, + requirements, manageSecrets: !input.skipSecrets && input.configuration.manageRepositorySecrets, + secretStoragePolicy: input.configuration.storage.secrets, + ref: input.configuration.repository.mainBranch, remoteConfiguration: input.remoteConfiguration, + workflowTokenPermissions, + }); + const guidedBotIdentity = input.prompt.guidedWorkflowBotIdentity; + if (guidedBotIdentity && credentials.collection.workflowPat) { + const verifiedBot = await new VerifyGuidedWorkflowPatIdentityUseCase(githubIdentities) + .execute(guidedBotIdentity, credentials.collection.workflowPat.value); + logInfo(`✅ Workflow PAT owner verified as @${verifiedBot.login} (GitHub account ID ${verifiedBot.id}).`); + if (input.setupPatAccount?.toLowerCase() === verifiedBot.login.toLowerCase()) { + logInfo('The workflow PAT and setup PAT use the same GitHub account. If this account authors PRs, bot-generated events and guarded self-approval may not behave as intended; use a dedicated bot account where required.'); + } + } + return credentials.collection; +} diff --git a/src/cli/setup_outcome_adapter.ts b/src/cli/setup_outcome_adapter.ts new file mode 100644 index 000000000..cf3205a28 --- /dev/null +++ b/src/cli/setup_outcome_adapter.ts @@ -0,0 +1,52 @@ +import { toApplicationError } from '../application/errors/application_error'; +import type { SetupJourneyUseCase } from '../application/usecases/setup/setup_journey_use_case'; +import { logError, logInfo } from '../utils/logger'; +import { SetupTerminalCancelledError } from './setup_credential_prompt_adapter'; +import { setupResultReason } from './setup_result_receipt'; +import type { WebSetupBridge } from './web_setup_bridge'; +import type { WebSetupServer } from './web_setup_server'; + +interface FailureContext { + readonly journey?: SetupJourneyUseCase; + readonly bridge?: WebSetupBridge; + readonly mutationStarted: boolean; + readonly applyStarted: boolean; + readonly guidedBotIdentity: boolean; +} + +/** Terminal diagnostics are separate from the redacted browser result. */ +export function reportSetupFailure(error: unknown, context: FailureContext): number { + const cancelled = error instanceof SetupTerminalCancelledError; + context.journey?.finish(context.mutationStarted ? 'partial' : cancelled ? 'cancelled' : 'blocked'); + const normalized = cancelled ? undefined : toApplicationError(error, 'workflow.failed', 'Setup failed.'); + context.bridge?.resultReason(cancelled ? 'cancelled' : setupResultReason(normalized!.code), normalized?.correlationId); + if (context.mutationStarted && !context.applyStarted) { + logInfo('A temporary credential-health workflow create was attempted before Apply. Inspect the selected branch and GitHub workflow history before retrying; a failed request may still have reached GitHub.'); + } + if (context.guidedBotIdentity) { + logInfo(context.applyStarted + ? 'Setup may be partially applied. Inspect the GitHub Secret before deleting or replacing the bot PAT.' + : 'No bot Secret write started. If you generated an unused bot PAT in GitHub, delete it there; Copilot cannot revoke it.'); + } + if (cancelled) { + logInfo(context.mutationStarted + ? 'Setup stopped after a possible credential-health workflow change. Inspect the selected branch and GitHub workflow history before retrying.' + : 'Setup cancelled. No changes were applied.'); + return 130; + } + logError(normalized!); + return 1; +} + +export async function finishWebSetupSession(bridge?: WebSetupBridge, server?: WebSetupServer, + exitCode?: number | string | null): Promise { + if (!bridge || !server) return; + const outcome = bridge.snapshot().journey?.outcome ?? (exitCode ? 'blocked' : 'cancelled'); + bridge.finish(outcome, outcome === 'complete' + ? 'Setup completed. Delete the temporary setup PAT in GitHub; keep the bot PAT while its Secret is in use.' + : outcome === 'dry-run' ? 'Dry run complete. No files or GitHub resources changed.' + : outcome === 'partial' ? 'Setup may be partial. Inspect GitHub resources and run copilot doctor --read-only before retrying.' + : 'No further setup changes will be applied. Any PAT already created in GitHub still exists until you delete it there.'); + logInfo('The local browser page shows the result. Choose “Close local session” there, or stop this command with Ctrl+C.'); + await server.closed; +} diff --git a/src/cli/setup_pat_intent_adapter.ts b/src/cli/setup_pat_intent_adapter.ts new file mode 100644 index 000000000..fe8f0e9ff --- /dev/null +++ b/src/cli/setup_pat_intent_adapter.ts @@ -0,0 +1,81 @@ +import { PrepareSetupPatIntentUseCase } from '../application/usecases/setup/prepare_setup_pat_intent_use_case'; +import type { SetupConfigurationOverrides } from '../application/policies/setup_configuration_policy'; +import { SetupQuestionnaireController } from '../application/usecases/setup/setup_questionnaire_controller'; +import type { SetupJourneyUseCase } from '../application/usecases/setup/setup_journey_use_case'; +import type { SetupTokenPermissionRequirement } from '../domain/setup_token_permissions'; +import type { SetupConfiguration } from '../domain/setup'; +import { logInfo } from '../utils/logger'; +import type { createInteractiveTerminalDriver } from './setup_terminal_driver'; +import { ConsoleSetupQuestionRenderer } from './setup_question_renderer'; +import { SetupCredentialPromptAdapter } from './setup_credential_prompt_adapter'; +import { ConsoleSetupTokenPermissionPresenter } from './setup_token_permission_presenter'; +import { WebSetupQuestionnaireCollector, WebSetupCredentialPrompt, WebSetupPermissionPresenter } from './web_setup_adapters'; +import type { WebSetupBridge } from './web_setup_bridge'; + +interface SetupPatIntentInput { + readonly owner: string; + readonly repository: string; + readonly overrides: SetupConfigurationOverrides; + readonly skipRepositoryVariables: boolean; + readonly skipRepositorySecrets: boolean; + readonly terminal?: ReturnType; + readonly bridge?: WebSetupBridge; + readonly journey?: SetupJourneyUseCase; + readonly credentialPrompt: SetupCredentialPromptAdapter | WebSetupCredentialPrompt; + readonly permissionPresenter: ConsoleSetupTokenPermissionPresenter | WebSetupPermissionPresenter; + readonly initialRequirements: readonly SetupTokenPermissionRequirement[]; +} + +export interface SetupPatIntentResult { + readonly requirements: readonly SetupTokenPermissionRequirement[]; + readonly assertedOwnerKind?: 'Organization' | 'User'; + readonly permissionIntent?: { draft: SetupConfiguration; answeredQuestionIds: readonly string[]; projectsWanted: boolean }; +} + +/** Presentation wiring for the shared application permission-intent decision. */ +export async function collectSetupPatIntent(input: SetupPatIntentInput): Promise { + const { bridge, credentialPrompt, permissionPresenter } = input; + if (await credentialPrompt.chooseSetupPatMethod() !== 'guided') { + permissionPresenter.showDetailedRequirements('setup', input.initialRequirements); + return { requirements: input.initialRequirements }; + } + const prepared = await new PrepareSetupPatIntentUseCase({ + collect: (initial, context, pass) => (bridge + ? new WebSetupQuestionnaireCollector(bridge, pass) + : new SetupQuestionnaireController(input.terminal!, new ConsoleSetupQuestionRenderer('permission-intent', pass))) + .collect(initial, context), + chooseOwnerKind: () => credentialPrompt.chooseSetupOwnerKind(), + review: () => credentialPrompt.reviewSetupPatIntent(), + showPreview: ({ draft, requirements, uncertain, ownerConflict, errors, pass, projectsWanted }) => { + if (ownerConflict) logInfo('This plan selects organization storage or Projects, but the owner was declared a personal account. Revise the choices or use the manual PAT path.'); + if (errors.length) logInfo(`The selected local configuration needs correction before a guided link can be generated:\n${errors.map(item => ` - ${item}`).join('\n')}`); + if (pass > 1) logInfo('Choice review complete. Returning to setup PAT permission review.'); + logInfo('Permission intent:'); + logInfo(` Initial tag: ${draft.createInitialTag ? 'yes' : 'no'}; issue workflows: ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval: ${draft.pullRequestApproval.mode}`); + logInfo(` Secrets: ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables: ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects: ${projectsWanted ? 'yes (choose exact Projects after PAT)' : 'none'}`); + bridge?.message(`Permission preview: issue workflows ${draft.features.issues ? draft.issueWorkflows.enabled.join(', ') || 'none' : 'disabled'}; PR approval ${draft.pullRequestApproval.mode}; Secrets ${draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off'}; Variables ${draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off'}; Projects ${projectsWanted ? 'yes (choose after PAT)' : 'none'}.`, 'info', undefined, 'permission.preview', { + issues: draft.features.issues ? draft.issueWorkflows.enabled.join('|') || 'none' : 'disabled', + approval: draft.pullRequestApproval.mode, + secrets: draft.manageRepositorySecrets ? draft.storage.secrets.defaultScope : 'off', + variables: draft.manageRepositoryVariables ? draft.storage.variables.defaultScope : 'off', + projects: projectsWanted ? 'yes' : 'none', + }); + permissionPresenter.showRequirements('setup', requirements); + if (uncertain.length) logInfo(`May need after GitHub inspection:\n${uncertain.map(item => ` - ${item}`).join('\n')}`); + }, + showDetails: requirements => permissionPresenter.showDetailedRequirements('setup', requirements), + onManual: reason => { + if (reason === 'owner-unknown') logInfo('Owner type was not confirmed. Use the manual PAT table, or check whether the GitHub owner is an organization before retrying guided setup.'); + if (reason === 'unsupported') logInfo('A guided setup PAT link is unavailable for this owner or permission set. Enter a manually created PAT using the table above.'); + credentialPrompt.useManualSetupPat(); + permissionPresenter.showDetailedRequirements('setup', input.initialRequirements); + }, + advanceToSetupPat: () => { input.journey?.advance('setup-pat'); }, + revisitChoices: () => input.journey!.revisitChoices(), + }).execute({ owner: input.owner, repository: input.repository, overrides: input.overrides, + skipRepositoryVariables: input.skipRepositoryVariables, skipRepositorySecrets: input.skipRepositorySecrets }); + if (prepared.kind !== 'guided') return { requirements: input.initialRequirements }; + credentialPrompt.configureSetupPatGuide(prepared.url); + return { requirements: [...prepared.requirements], assertedOwnerKind: prepared.ownerKind, + permissionIntent: prepared.permissionIntent }; +} diff --git a/src/cli/setup_result_receipt.ts b/src/cli/setup_result_receipt.ts index a92c3689b..2fcb6b357 100644 --- a/src/cli/setup_result_receipt.ts +++ b/src/cli/setup_result_receipt.ts @@ -28,7 +28,7 @@ export function setupResultEffects(results: readonly Result[]): NonNullable item.id === effect.id) + ? previous.map(item => item.id === effect.id ? { ...effect } : item) + : [...previous, { ...effect }]; + this.effects(effects); + } finish(outcome: NonNullable, text: string): void { if (this.view.outcome) return; this.pending?.resolve(undefined); this.pending = undefined; + const effects = this.view.resultDetail?.effects?.map(effect => effect.state === 'in-progress' + ? { ...effect, state: 'needs-inspection' as const } : effect); this.publish({ prompt: undefined, promptRevision: undefined, outcome, message: { tone: outcome === 'complete' || outcome === 'dry-run' ? 'success' : 'warning', text }, + ...(this.view.resultDetail && effects ? { resultDetail: { ...this.view.resultDetail, effects } } : {}), ...(this.view.resultDetail ? {} : { resultDetail: { reasonCode: outcome === 'cancelled' ? 'cancelled' : outcome === 'blocked' ? 'unknown' : 'unknown', stoppedStage: this.view.journey?.current ?? 'Preparation', diff --git a/src/domain/setup.ts b/src/domain/setup.ts index a2df26621..93146bfcd 100644 --- a/src/domain/setup.ts +++ b/src/domain/setup.ts @@ -260,6 +260,6 @@ export interface SetupPlan { /** Structured, value-free receipt for the local setup workflow. */ export interface SetupOperationEffect { readonly id: 'files' | 'secrets' | 'labels' | 'issue-types' | 'variables' | 'initial-tag'; - readonly state: 'completed' | 'skipped' | 'needs-inspection' | 'not-started'; + readonly state: 'completed' | 'skipped' | 'needs-inspection' | 'not-started' | 'in-progress'; readonly scope: 'local' | 'repository' | 'organization' | 'mixed'; } diff --git a/src/domain/setup_token_permissions.ts b/src/domain/setup_token_permissions.ts index cc249a084..ae7912ecf 100644 --- a/src/domain/setup_token_permissions.ts +++ b/src/domain/setup_token_permissions.ts @@ -3,7 +3,7 @@ export type SetupTokenPermissionScope = 'repository' | 'organization'; export type SetupTokenPermissionLevel = 'read' | 'write'; export type SetupTokenPermissionApplicability = 'required' | 'conditional'; export type SetupTokenPermissionStatus = 'verified' | 'missing' | 'unverifiable'; -export type SetupTokenPublicReadEvidence = 'public-repository'; +export type SetupTokenPublicReadEvidence = 'public-repository' | 'public-organization-projects'; export type SetupTokenPermissionProbe = | 'metadata' diff --git a/src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts b/src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts index a31bdd92b..e9b4f6d8c 100644 --- a/src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts +++ b/src/infrastructure/__tests__/setup_token_permission_query_adapter.test.ts @@ -1,5 +1,7 @@ import { SetupTokenPermissionQueryAdapter } from '../setup_token_permission_query_adapter'; import type { SetupTokenPermissionRequirement } from '../../domain/setup_token_permissions'; +import { SetupTokenPermissionsUseCase } from '../../application/usecases/setup/setup_token_permissions_use_case'; +import { buildSetupPatPermissionRequirements } from '../../application/policies/setup_token_permission_policy'; const requirement = ( level: 'read' | 'write' = 'read', @@ -9,7 +11,8 @@ const requirement = ( id: `setup.${scope}.${probe}`, role: 'setup', scope, - permission: probe === 'members' ? 'Members' : probe === 'issue-types' ? 'Issue Types' : probe, + permission: probe === 'members' ? 'Members' : probe === 'issue-types' ? 'Issue Types' + : probe === 'projects' && scope === 'organization' ? 'Projects' : probe, level, applicability: 'required', reason: 'test', probe, }); @@ -41,6 +44,25 @@ const ambiguousForbiddenResponses: ReadonlyArray<{ ]; describe('SetupTokenPermissionQueryAdapter', () => { + it('allows bootstrap to continue when organization Projects discovery is empty but usable', async () => { + const requirements = buildSetupPatPermissionRequirements() + .filter(item => item.permission === 'Metadata' || item.permission === 'Contents' || item.permission === 'Projects') + .map(item => ({ ...item, applicability: 'required' as const })); + const fetcher = jest.fn(async (url: string) => url.endsWith('/projectsV2?per_page=1') + ? response(true, 200, { payload: [] }) + : response(true, 200, { payload: { private: true, default_branch: 'main' } })); + const audit = new SetupTokenPermissionsUseCase({ + validateSetupPat: jest.fn().mockResolvedValue({ name: 'SETUP_PAT', status: 'valid', message: 'ok' }), + }, new SetupTokenPermissionQueryAdapter({ fetcher: fetcher as typeof fetch })); + const report = await audit.inspect({ role: 'setup', owner: 'owner', repository: 'repo', + token: 'secret-token', requirements }); + expect(report.ready).toBe(true); + expect(report.checks.find(check => check.permission === 'Projects')).toMatchObject({ + status: 'unverifiable', operationallyAvailable: true, + publicReadEvidence: 'public-organization-projects', + }); + expect(fetcher.mock.calls.map(call => call[0])).toContain('https://api.github.com/orgs/owner/projectsV2?per_page=1'); + }); it('can be constructed with the production defaults', () => { expect(new SetupTokenPermissionQueryAdapter()).toBeInstanceOf(SetupTokenPermissionQueryAdapter); }); @@ -403,7 +425,7 @@ describe('SetupTokenPermissionQueryAdapter', () => { it('does not make a request when GitHub has no safe read-only probe', async () => { const fetcher = jest.fn(); const [check] = await new SetupTokenPermissionQueryAdapter({ fetcher }).inspect( - 'owner', 'repo', 'secret', [requirement('write', 'projects', 'organization')], + 'owner', 'repo', 'secret', [requirement('write', 'workflows', 'organization')], ); expect(fetcher).not.toHaveBeenCalled(); expect(check).toMatchObject({ status: 'unverifiable' }); @@ -446,7 +468,7 @@ describe('SetupTokenPermissionQueryAdapter', () => { ])); }); - it('maps every supported organization probe and leaves Projects unsupported', async () => { + it('maps every supported organization probe including read-only Projects discovery', async () => { const fetcher = jest.fn().mockResolvedValue(response(true, 200)); const probes: SetupTokenPermissionRequirement['probe'][] = ['secrets', 'variables', 'members', 'issue-types', 'projects']; @@ -457,16 +479,52 @@ describe('SetupTokenPermissionQueryAdapter', () => { probes.map(probe => requirement('read', probe, 'organization')), ); - expect(fetcher).toHaveBeenCalledTimes(4); + expect(fetcher).toHaveBeenCalledTimes(5); expect(fetcher.mock.calls.map(call => call[0])).toEqual(expect.arrayContaining([ 'https://api.github.com/orgs/owner/actions/secrets?per_page=1', 'https://api.github.com/orgs/owner/actions/variables?per_page=1', 'https://api.github.com/user/memberships/orgs/owner', 'https://api.github.com/orgs/owner/issue-types?per_page=1', + 'https://api.github.com/orgs/owner/projectsV2?per_page=1', ])); expect(checks.at(-1)).toMatchObject({ probe: 'projects', status: 'unverifiable' }); }); + it('verifies organization Projects read only from a non-public result', async () => { + const fetcher = jest.fn().mockResolvedValue(response(true, 200, { payload: [{ number: 3, public: false }] })); + const [check] = await new SetupTokenPermissionQueryAdapter({ fetcher }).inspect( + 'owner', 'repo', 'secret-token', [requirement('read', 'projects', 'organization')], + ); + expect(check).toMatchObject({ status: 'verified' }); + expect(fetcher).toHaveBeenCalledWith('https://api.github.com/orgs/owner/projectsV2?per_page=1', + expect.objectContaining({ method: 'GET', headers: expect.objectContaining({ 'X-GitHub-Api-Version': '2026-03-10' }) })); + expect(JSON.stringify(check)).not.toContain('secret-token'); + }); + + it.each([ + { label: 'empty', payload: [] }, + { label: 'public-only', payload: [{ number: 2, public: true }] }, + ])('keeps $label Projects access usable without claiming a PAT grant', async ({ payload }) => { + const [check] = await new SetupTokenPermissionQueryAdapter({ + fetcher: jest.fn().mockResolvedValue(response(true, 200, { payload })), + }).inspect('owner', 'repo', 'secret-token', [requirement('read', 'projects', 'organization')]); + expect(check).toMatchObject({ status: 'unverifiable', operationallyAvailable: true, + publicReadEvidence: 'public-organization-projects' }); + }); + + it.each([ + ['malformed', response(true, 200, { payload: [{ number: 1 }] })], + ['non-list', response(true, 200, { payload: { public: false } })], + ['denied', response(false, 403, { message: 'Resource not accessible by personal access token' })], + ['missing', response(false, 404)], + ])('does not accept %s organization Projects evidence', async (_case, providerResponse) => { + const [check] = await new SetupTokenPermissionQueryAdapter({ + fetcher: jest.fn().mockResolvedValue(providerResponse), + }).inspect('owner', 'repo', 'secret-token', [requirement('read', 'projects', 'organization')]); + expect(check.operationallyAvailable).toBeUndefined(); + expect(check.status).not.toBe('verified'); + }); + it('leaves an unsupported repository probe unverifiable without a request', async () => { const fetcher = jest.fn(); const [check] = await new SetupTokenPermissionQueryAdapter({ fetcher }).inspect( diff --git a/src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts b/src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts index fb7fdc4c4..4caa2ffb9 100644 --- a/src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts +++ b/src/infrastructure/composition/__tests__/initial_setup_composition_root.test.ts @@ -50,7 +50,8 @@ describe('initial setup composition root', () => { ); expect(mockComposeInitialSetupUseCase).toHaveBeenCalledTimes(1); const dependencies = mockComposeInitialSetupUseCase.mock.calls[0]; - expect(dependencies).toHaveLength(10); + expect(dependencies).toHaveLength(11); + expect(dependencies[10]).toBeUndefined(); const labels = dependencies[1] as { ensureInitialLabels(value: unknown): Promise }; await labels.ensureInitialLabels({ lifecycle: {} }); expect(mockLabelProvisioning.ensureInitialLabels).toHaveBeenCalledWith( diff --git a/src/infrastructure/composition/initial_setup_composition_root.ts b/src/infrastructure/composition/initial_setup_composition_root.ts index c83270900..ecf4a69a3 100644 --- a/src/infrastructure/composition/initial_setup_composition_root.ts +++ b/src/infrastructure/composition/initial_setup_composition_root.ts @@ -3,6 +3,7 @@ import { createIssueLabelProvisioningClient } from './github_issue_client_factor import { createGraphqlTransportClient } from './github_project_client_factory'; import { createReleaseClient } from './github_release_client_factory'; import { InitialSetupUseCase } from "../../application/usecases/actions/initial_setup_use_case"; +import type { SetupOperationEffect } from '../../domain/setup'; import { IssueLabelProvisioningRepository } from "../../data/repository/issue/issue_label_provisioning_repository"; import { IssueTypeRepository } from "../../data/repository/issue/issue_type_repository"; @@ -31,7 +32,8 @@ import { bindSetupWorkspace, } from './push_single_action_capability_port_binding'; -export function createInitialSetupCompositionRoot(binding: RepositoryCredentialBinding): InitialSetupUseCase { +export function createInitialSetupCompositionRoot(binding: RepositoryCredentialBinding, + progress?: (effect: SetupOperationEffect) => void): InitialSetupUseCase { const labelProvisioning = new IssueLabelProvisioningRepository( createIssueLabelProvisioningClient(), ); @@ -48,5 +50,6 @@ export function createInitialSetupCompositionRoot(binding: RepositoryCredentialB bindSetupVariables(new RepositoryVariablesCommandRepository(githubResourceClient), binding), bindSetupSecrets(new RepositorySecretsCommandRepository(githubResourceClient), binding), bindSetupRemoteConfiguration(new SetupRemoteConfigurationQueryRepository(githubResourceClient), binding), + progress, ); } diff --git a/src/infrastructure/composition/main_run_route_composition_root.ts b/src/infrastructure/composition/main_run_route_composition_root.ts index 3065afbc6..3f9fa833b 100644 --- a/src/infrastructure/composition/main_run_route_composition_root.ts +++ b/src/infrastructure/composition/main_run_route_composition_root.ts @@ -114,6 +114,7 @@ export type MainRunCompositionSurface = "github-workflow" | "local"; export function createSingleActionUseCaseCompositionRoot( surface: MainRunCompositionSurface, binding: BugbotScmBinding, + setupProgress?: (effect: import('../../domain/setup').SetupOperationEffect) => void, ): SingleActionUseCase { const catalogResolver = new ResolveMessageCatalogUseCase(createLanguageQueryPort()); const issueDescriptionQueryPort = createIssueContentCompositionRoot(); @@ -136,7 +137,7 @@ export function createSingleActionUseCaseCompositionRoot( bindIssueDescriptionQuery(issueDescriptionQueryPort, binding), createFindingsQueryPort(), ), - createInitialSetupCompositionRoot(binding), + createInitialSetupCompositionRoot(binding, setupProgress), createCheckProgressCompositionRoot(binding), createDetectPotentialProblemsUseCase(binding), new RecommendStepsUseCase( @@ -312,6 +313,7 @@ export function createCommitUseCaseCompositionRoot( export function createMainRunRouteCompositionRoot( projectBoardCommandPort: ProjectBoardCommandPort, surface: MainRunCompositionSurface, + setupProgress?: (effect: import('../../domain/setup').SetupOperationEffect) => void, ): MainRunRouteHandlers { let singleAction: SingleActionUseCase | undefined; let issueComment: IssueCommentUseCase | undefined; @@ -321,7 +323,7 @@ export function createMainRunRouteCompositionRoot( let push: CommitUseCase | undefined; return { "single-action": async (execution) => { - singleAction ??= createSingleActionUseCaseCompositionRoot(surface, bugbotBinding(execution)); + singleAction ??= createSingleActionUseCaseCompositionRoot(surface, bugbotBinding(execution), setupProgress); return singleAction.invoke(execution); }, "issue-comment": async (execution) => { diff --git a/src/infrastructure/setup_token_permission_query_adapter.ts b/src/infrastructure/setup_token_permission_query_adapter.ts index 787169139..24c2f5da8 100644 --- a/src/infrastructure/setup_token_permission_query_adapter.ts +++ b/src/infrastructure/setup_token_permission_query_adapter.ts @@ -10,7 +10,7 @@ import { isOperationallyAvailableSetupRead } from '../application/policies/setup const SETUP_PERMISSION_PROBE_CONCURRENCY = 4; const MAX_GITHUB_DEFAULT_BRANCH_LENGTH = 255; -type ProbeReadEvidence = 'permission-bound' | 'publicly-readable' | 'organization-membership'; +type ProbeReadEvidence = 'permission-bound' | 'publicly-readable' | 'organization-membership' | 'organization-projects'; type ProbeTarget = | Readonly<{ @@ -64,7 +64,7 @@ export class SetupTokenPermissionQueryAdapter implements SetupTokenPermissionQue try { const request = (url: string) => this.fetcher(url, { method: 'GET', - headers: permissionProbeHeaders(token), + headers: permissionProbeHeaders(token, requirement), signal: controller.signal, }); const target = await resolveProbeTarget(owner, repository, requirement, request); @@ -83,11 +83,12 @@ export class SetupTokenPermissionQueryAdapter implements SetupTokenPermissionQue } } -function permissionProbeHeaders(token: string): Record { +function permissionProbeHeaders(token: string, requirement: SetupTokenPermissionRequirement): Record { return { Authorization: `Bearer ${token}`, Accept: 'application/vnd.github+json', - 'X-GitHub-Api-Version': '2022-11-28', + 'X-GitHub-Api-Version': requirement.scope === 'organization' && requirement.probe === 'projects' + ? '2026-03-10' : '2022-11-28', }; } @@ -112,6 +113,9 @@ async function resolveProbeTarget( if (requirement.scope === 'organization' && requirement.probe === 'members') { return { status: 'ready', url, readEvidence: 'organization-membership' }; } + if (requirement.scope === 'organization' && requirement.probe === 'projects') { + return { status: 'ready', url, readEvidence: 'organization-projects' }; + } if (requiresRepositoryVisibilityProof(requirement)) { const metadataResponse = await request(repositoryRoot(owner, repository)); if (!metadataResponse.ok) { @@ -236,6 +240,9 @@ async function mapProbeResponse( owner: string, ): Promise { if (response.ok) { + if (readEvidence === 'organization-projects' && requirement.level === 'read') { + return inspectOrganizationProjectsRead(requirement, response); + } if (readEvidence === 'organization-membership') { return response.status === 200 && await isActiveOrganizationMembership(response, owner) ? outcome(requirement, 'verified', 'GitHub confirmed active organization membership through a permission-bound Members-read probe.') @@ -287,6 +294,32 @@ async function mapProbeResponse( return outcome(requirement, 'unverifiable', `GitHub could not verify this permission safely (HTTP ${response.status}).`); } +async function inspectOrganizationProjectsRead( + requirement: SetupTokenPermissionRequirement, + response: Response, +): Promise { + try { + const payload: unknown = await response.json(); + if (!Array.isArray(payload)) { + return outcome(requirement, 'unverifiable', 'GitHub returned an unrecognized organization Projects list.'); + } + if (payload.some(project => typeof project !== 'object' || project === null + || Array.isArray(project) || typeof (project as Record).public !== 'boolean')) { + return outcome(requirement, 'unverifiable', 'GitHub returned an unrecognized organization Projects list.'); + } + if (payload.some(project => (project as Record).public === false)) { + return outcome(requirement, 'verified', 'GitHub returned a non-public organization Project through a read-only Projects probe.'); + } + return { + ...outcome(requirement, 'unverifiable', 'Only public or no organization Projects were returned; listing is available, but the PAT grant is not proven.'), + operationallyAvailable: true, + publicReadEvidence: 'public-organization-projects', + }; + } catch { + return outcome(requirement, 'unverifiable', 'GitHub organization Projects response could not be inspected safely.'); + } +} + async function isActiveOrganizationMembership(response: Response, owner: string): Promise { try { const payload: unknown = await response.json(); @@ -356,6 +389,7 @@ function probeUrl( if (requirement.probe === 'variables') return `${organizationRoot}/actions/variables?per_page=1`; if (requirement.probe === 'members') return `https://api.github.com/user/memberships/orgs/${encodedOwner}`; if (requirement.probe === 'issue-types') return `${organizationRoot}/issue-types?per_page=1`; + if (requirement.probe === 'projects') return `${organizationRoot}/projectsV2?per_page=1`; return undefined; } if (requirement.probe === 'metadata') return root; diff --git a/src/tooling/__tests__/setup_acceptance_path.test.ts b/src/tooling/__tests__/setup_acceptance_path.test.ts new file mode 100644 index 000000000..615773bad --- /dev/null +++ b/src/tooling/__tests__/setup_acceptance_path.test.ts @@ -0,0 +1,14 @@ +import { posix, win32 } from 'node:path'; + +const { relativeJestSuitePath } = require('../../../scripts/setup-acceptance-path.cjs') as { + relativeJestSuitePath: (root: string, suite: string, pathApi: typeof posix) => string; +}; + +describe('setup acceptance Jest evidence paths', () => { + test.each([ + ['POSIX', posix, '/checkout/copilot', '/checkout/copilot/src/cli/commands/setup.test.ts'], + ['Windows', win32, 'D:\\a\\copilot\\copilot', 'D:\\a\\copilot\\copilot\\src\\cli\\commands\\setup.test.ts'], + ] as const)('normalizes %s absolute suite names to the ledger path', (_platform, pathApi, root, suite) => { + expect(relativeJestSuitePath(root, suite, pathApi)).toBe('src/cli/commands/setup.test.ts'); + }); +}); diff --git a/src/tooling/__tests__/validate_workflow_contract.test.ts b/src/tooling/__tests__/validate_workflow_contract.test.ts index 04a86d02c..681b6473b 100644 --- a/src/tooling/__tests__/validate_workflow_contract.test.ts +++ b/src/tooling/__tests__/validate_workflow_contract.test.ts @@ -7,6 +7,7 @@ interface ContractModule { assertQueueWorkflow(file: string, workflow: Record): void; assertDirectEventTriggers(file: string, workflow: Record): void; assertRunner(file: string, workflow: Record): void; + assertPortableRunShell(file: string, workflow: Record): void; assertMajorActionReferences(file: string, workflow: Record): void; assertCopilotActionInputs(file: string, workflow: Record): void; assertNoJobLevelSecrets(file: string, workflow: Record): void; @@ -32,6 +33,7 @@ const { assertQueueWorkflow, assertDirectEventTriggers, assertRunner, + assertPortableRunShell, assertMajorActionReferences, assertCopilotActionInputs, assertNoJobLevelSecrets, @@ -312,6 +314,29 @@ describe('workflow contract validator', () => { expect(() => validateWorkflow(file, workflow)).toThrow('must materialize and verify the exact GitHub before/after review range'); }); + it.each([ + ['.github/workflows', 'copilot_commit.yml', 'copilot-commits'], + ['.github/workflows', 'ci_check.yml', 'ci-check'], + ['.github/workflows', 'release_workflow.yml', 'prepare-compiled-files'], + ['setup/workflows', 'copilot_commit.yml', 'copilot-commits'], + ['setup/workflows', 'copilot_pull_request.yml', 'copilot-pull-requests'], + ])('requires portable Bash for run steps in %s/%s', (directory, fileName, jobId) => { + const file = path.join(process.cwd(), directory, fileName); + const workflow = yaml.load(readFileSync(file, 'utf8')) as MutationWorkflow; + expect(() => assertPortableRunShell(file, workflow)).not.toThrow(); + delete workflow.defaults; + delete workflow.jobs[jobId].defaults; + for (const step of workflow.jobs[jobId].steps) delete step.shell; + expect(() => assertPortableRunShell(file, workflow)).toThrow('must select shell: bash'); + }); + + it('rejects a platform-specific shell override on a Codex runner', () => { + const file = path.join(process.cwd(), '.github/workflows/copilot_commit.yml'); + const workflow = yaml.load(readFileSync(file, 'utf8')) as MutationWorkflow; + workflow.jobs['copilot-commits'].steps.find((step: { run?: string }) => step.run).shell = 'pwsh'; + expect(() => assertPortableRunShell(file, workflow)).toThrow('must select shell: bash'); + }); + it.each(['.github/workflows', 'setup/workflows'])('requires a full checkout for push review ranges in %s', (directory) => { const file = path.join(process.cwd(), directory, 'copilot_commit.yml'); const workflow = yaml.load(readFileSync(file, 'utf8')) as MutationWorkflow; @@ -680,6 +705,14 @@ describe('workflow contract validator', () => { })).toThrow('runs-on self-hosted, codex'); }); + it('requires the Ubuntu, Windows and macOS setup fixture matrix', () => { + const file = path.join(process.cwd(), '.github', 'workflows', 'setup_platform_smoke.yml'); + const workflow = yaml.load(readFileSync(file, 'utf8')) as MutationWorkflow; + expect(() => validateWorkflow(file, workflow)).not.toThrow(); + workflow.jobs['setup-platform-smoke'].strategy.matrix.os = ['ubuntu-latest', 'windows-latest']; + expect(() => assertRunner(file, workflow)).toThrow('Ubuntu, Windows and macOS setup fixture matrix'); + }); + it('requires checkout v5, major tags for other actions, and explicit checkout credentials', () => { const file = path.join(process.cwd(), '.github', 'workflows', 'ci_check.yml'); expect(() => assertMajorActionReferences(file, { diff --git a/web/src/App.svelte b/web/src/App.svelte index d6767d7a3..2e6d8586d 100644 --- a/web/src/App.svelte +++ b/web/src/App.svelte @@ -69,7 +69,7 @@ {#if !$session.paired} {:else if $session.view?.outcome} - + {:else if $session.view?.prompt}
                                                  @@ -77,7 +77,7 @@
                                                  {#if $session.controller && $session.view.journey?.current !== 'Apply'}{/if} {:else} - + {/if}
                                                  {tr('footerLocal', $setupLocale)} {tr('footerCloud', $setupLocale)} {tr('footerGithub', $setupLocale)}
                                                  diff --git a/web/src/components/ResourceProgress.svelte b/web/src/components/ResourceProgress.svelte new file mode 100644 index 000000000..d428b7c43 --- /dev/null +++ b/web/src/components/ResourceProgress.svelte @@ -0,0 +1,23 @@ + + +

                                                  {tr('resourceReceipt', $setupLocale)}

                                                  +
                                                    {#each effects as effect (effect.id)}
                                                  • {names[effect.id] ? tr(names[effect.id], $setupLocale) : effect.id} — {tr(states[effect.state], $setupLocale)}{#if effect.scope} · {tr(scopes[effect.scope], $setupLocale)}{/if}
                                                  • {/each}
                                                  +
                                                  diff --git a/web/src/components/ResultPanel.svelte b/web/src/components/ResultPanel.svelte index a5f34d326..60821d4ed 100644 --- a/web/src/components/ResultPanel.svelte +++ b/web/src/components/ResultPanel.svelte @@ -3,21 +3,22 @@ import { tr, stageLabel, type SetupMessageKey } from '../i18n/catalog'; import { setupLocale } from '../i18n/localeStore'; import ActionButton from './ActionButton.svelte'; + import ResourceProgress from './ResourceProgress.svelte'; import { focusOnRevision } from '../lib/focusOnRevision'; + import { permissionName, permissionTerm } from '../i18n/permissionTerms'; export let outcome: NonNullable; export let controller: boolean; export let onClose: () => Promise; export let onDoctor: () => Promise = async () => undefined; export let doctor: WebSetupView['doctor'] = undefined; export let detail: WebSetupView['resultDetail'] = undefined; + export let permissionReport: NonNullable['report'] = undefined; const reasons: Record['reasonCode'], [SetupMessageKey, SetupMessageKey]> = { permissions: ['reasonPermissions', 'nextPermissions'], storage: ['reasonStorage', 'nextStorage'], configuration: ['reasonConfiguration', 'nextConfiguration'], 'session-expired': ['reasonExpired', 'nextExpired'], cancelled: ['reasonCancelled', 'nextCancelled'], provider: ['reasonProvider', 'nextProvider'], 'rate-limit': ['reasonRateLimit', 'nextRateLimit'], unknown: ['reasonUnknown', 'nextUnknown'], }; - const effectKeys: Record = { files: 'receiptFiles', secrets: 'receiptSecrets', - labels: 'receiptLabels', 'issue-types': 'receiptIssueTypes', variables: 'receiptVariables', 'initial-tag': 'receiptInitialTag' }; $: heading = outcome === 'complete' ? tr('resultApplied', $setupLocale) : outcome === 'dry-run' ? tr('resultNoChanges', $setupLocale) : outcome === 'cancelled' || outcome === 'blocked' ? tr('resultStopped', $setupLocale) @@ -27,6 +28,11 @@ : outcome === 'partial' ? tr('resultPartialBody', $setupLocale) : tr('resultNoChangesBody', $setupLocale); + $: blockedPermissionReport = outcome === 'blocked' && detail?.reasonCode === 'permissions' + ? permissionReport : undefined; + $: unresolvedPermissions = blockedPermissionReport?.identityStatus === 'valid' + ? blockedPermissionReport.checks.filter(check => check.applicability === 'required' + && check.status !== 'verified' && check.operationallyAvailable !== true) : [];

                                                  {heading}

                                                  @@ -39,11 +45,21 @@ {#if detail?.diagnosticRef}

                                                  {tr('diagnosticReference', $setupLocale)}: {detail.diagnosticRef}

                                                  {/if} {/if} - {#if detail?.effects?.length} -

                                                  {tr('resourceReceipt', $setupLocale)}

                                                  -
                                                    {#each detail.effects as effect}
                                                  • {effectKeys[effect.id] ? tr(effectKeys[effect.id], $setupLocale) : effect.id} — {tr(effect.state === 'completed' ? 'effectCompleted' : effect.state === 'skipped' ? 'effectSkipped' : effect.state === 'not-started' ? 'effectNotStarted' : 'effectInspect', $setupLocale)}{#if effect.scope} · {tr(effect.scope === 'local' ? 'scopeLocal' : effect.scope === 'organization' ? 'scopeOrganization' : effect.scope === 'mixed' ? 'scopeMixed' : 'scopeRepository', $setupLocale)}{/if}
                                                  • {/each}
                                                  + {#if blockedPermissionReport} +
                                                  +

                                                  {tr('permissionReportTitle', $setupLocale)}

                                                  +

                                                  {tr('permissionReportLead', $setupLocale)}

                                                  +

                                                  {tr('permissionIdentity', $setupLocale)}: {tr(blockedPermissionReport.identityStatus === 'valid' ? 'permissionIdentityValid' : blockedPermissionReport.identityStatus === 'invalid' ? 'permissionIdentityInvalid' : 'permissionIdentityUnknown', $setupLocale)}

                                                  + {#if unresolvedPermissions.length} +
                                                    {#each unresolvedPermissions as check}
                                                  • {permissionName($setupLocale, check.permission)}{#if $setupLocale !== 'en' && permissionName($setupLocale, check.permission) !== check.permission} GitHub · {check.permission}{/if} — {permissionTerm($setupLocale, check.scope)} · {permissionTerm($setupLocale, check.level)} · {permissionTerm($setupLocale, check.status)}
                                                  • {/each}
                                                  + {:else if blockedPermissionReport.identityStatus === 'valid'} +

                                                  {tr('permissionReportNoFailedGrant', $setupLocale)}

                                                  + {/if}
                                                  {/if} + {#if detail?.effects?.length} + + {/if}

                                                  {explanation}

                                                  {#if outcome === 'complete'}

                                                  {tr('botRenewal', $setupLocale)}

                                                  {/if}

                                                  {tr('doctorHelp', $setupLocale)}

                                                  diff --git a/web/src/components/WaitingPanel.svelte b/web/src/components/WaitingPanel.svelte index e66070fc9..62821e247 100644 --- a/web/src/components/WaitingPanel.svelte +++ b/web/src/components/WaitingPanel.svelte @@ -1,6 +1,9 @@ -

                                                  {tr('working', $setupLocale)}

                                                  {tr('workingBody', $setupLocale)}

                                                  +

                                                  {tr('working', $setupLocale)}

                                                  {tr('workingBody', $setupLocale)}

                                                  {#if effects?.length}{/if}
                                                  diff --git a/web/src/i18n/en.ts b/web/src/i18n/en.ts index 9771d631d..717b29679 100644 --- a/web/src/i18n/en.ts +++ b/web/src/i18n/en.ts @@ -25,15 +25,18 @@ export const en = { resultNoChangesBody: 'Copilot did not begin applying setup changes. PATs you created in GitHub still exist until you delete them there.', whatHappened: 'What happened', alreadyChanged: 'Already changed', noChanges: 'No repository or GitHub setup changes were started in this session.', nextAction: 'Next action', reasonPermissions: 'The setup PAT lacked or could not confirm required permissions.', nextPermissions: 'Check the displayed grants, correct the PAT in GitHub, then start a fresh setup run.', + permissionReportTitle: 'PAT permission evidence', permissionReportLead: 'Any required grants that could not be confirmed are listed below. Unverifiable does not mean missing.', + permissionIdentity: 'GitHub identity and repository access', permissionIdentityValid: 'Verified', permissionIdentityInvalid: 'Rejected', permissionIdentityUnknown: 'Could not be confirmed', + permissionReportNoFailedGrant: 'No required grant failed this check. Review the intended PAT account and the terminal error before retrying.', reasonStorage: 'The selected GitHub Actions storage could not be used safely.', nextStorage: 'Inspect the Variables/Secrets scope and existing resources, then retry.', reasonConfiguration: 'The chosen configuration could not be validated.', nextConfiguration: 'Review the terminal validation details, correct the choices, and retry.', - reasonExpired: 'The local setup session expired before applying changes.', nextExpired: 'Start a new setup session; the old approval cannot be replayed.', - reasonCancelled: 'This setup was cancelled before applying changes.', nextCancelled: 'Start a new run if you still want to configure this repository.', - reasonUnknown: 'Setup stopped before Apply. The browser could not determine the exact cause.', nextUnknown: 'Check the final terminal error before retrying; do not assume a PAT was revoked.', + reasonExpired: 'The local setup session expired.', nextExpired: 'Start a new setup session; the old approval cannot be replayed.', + reasonCancelled: 'This setup was cancelled.', nextCancelled: 'Start a new run if you still want to configure this repository.', + reasonUnknown: 'Setup stopped. The browser could not determine the exact cause or which changes completed.', nextUnknown: 'Check the final terminal error before retrying; do not assume a PAT was revoked.', reasonProvider: 'GitHub or another provider did not complete the requested operation.', nextProvider: 'Use the diagnostic reference to inspect the terminal result, check provider availability and access, then retry only after reviewing possible partial changes.', reasonRateLimit: 'GitHub temporarily limited the requests needed for setup.', nextRateLimit: 'Wait for the limit to reset. Inspect any completed changes before starting another setup run.', diagnosticReference: 'Diagnostic reference', resourceReceipt: 'Setup operation receipt', effectCompleted: 'Reported completed', effectSkipped: 'Reported skipped', effectInspect: 'Outcome needs inspection', - effectNotStarted: 'Not started', scopeLocal: 'Local checkout', scopeMixed: 'Repository and organization', + effectNotStarted: 'Not started', effectInProgress: 'In progress; outcome not yet confirmed', scopeLocal: 'Local checkout', scopeMixed: 'Repository and organization', receiptFiles: 'Setup files', receiptSecrets: 'GitHub Actions Secrets', receiptLabels: 'Issue labels', receiptIssueTypes: 'Issue types', receiptVariables: 'GitHub Actions Variables', receiptInitialTag: 'Initial version tag', inspectPartial: 'Some setup changes may already be active. Inspect GitHub and the terminal result before retrying.', patSettings: 'Open GitHub PAT settings ↗', closeSession: 'Close local session', diff --git a/web/src/i18n/es.ts b/web/src/i18n/es.ts index b3006bf54..1e9e30d4f 100644 --- a/web/src/i18n/es.ts +++ b/web/src/i18n/es.ts @@ -27,15 +27,18 @@ export const es: Record = { resultNoChangesBody: 'Copilot no empezó a aplicar cambios de configuración. Los PAT creados en GitHub siguen existiendo hasta que los elimines allí.', whatHappened: 'Qué ha pasado', alreadyChanged: 'Qué ha cambiado', noChanges: 'No se iniciaron cambios de configuración en el repositorio ni en GitHub durante esta sesión.', nextAction: 'Siguiente paso', reasonPermissions: 'Faltan permisos del PAT de configuración o no pudieron confirmarse.', nextPermissions: 'Comprueba los permisos mostrados, corrige el PAT en GitHub e inicia una nueva sesión.', + permissionReportTitle: 'Comprobación de permisos del PAT', permissionReportLead: 'Se muestran los permisos obligatorios que no pudieron confirmarse. «No verificable» no significa «ausente».', + permissionIdentity: 'Identidad de GitHub y acceso al repositorio', permissionIdentityValid: 'Verificados', permissionIdentityInvalid: 'Rechazados', permissionIdentityUnknown: 'No se pudieron confirmar', + permissionReportNoFailedGrant: 'La comprobación no detectó un permiso obligatorio fallido. Revisa la cuenta prevista para el PAT y el error de la terminal antes de reintentarlo.', reasonStorage: 'No se pudo usar de forma segura el almacenamiento elegido de GitHub Actions.', nextStorage: 'Revisa el ámbito de Variables/Secrets y los recursos existentes; después, reinténtalo.', reasonConfiguration: 'No se pudo validar la configuración elegida.', nextConfiguration: 'Revisa el detalle de validación en la terminal, corrige las opciones y reinténtalo.', - reasonExpired: 'La sesión local caducó antes de aplicar cambios.', nextExpired: 'Inicia una sesión nueva; la aprobación anterior no puede reutilizarse.', - reasonCancelled: 'La sesión se canceló antes de aplicar cambios.', nextCancelled: 'Inicia una nueva ejecución si todavía quieres configurar este repositorio.', - reasonUnknown: 'La configuración se detuvo antes de aplicar cambios. La web no pudo determinar la causa exacta.', nextUnknown: 'Consulta el último error de la terminal antes de reintentar; no supongas que se revocó ningún PAT.', + reasonExpired: 'La sesión local caducó.', nextExpired: 'Inicia una sesión nueva; la aprobación anterior no puede reutilizarse.', + reasonCancelled: 'La sesión se canceló.', nextCancelled: 'Inicia una nueva ejecución si todavía quieres configurar este repositorio.', + reasonUnknown: 'La configuración se detuvo. La web no pudo determinar la causa exacta ni qué cambios se completaron.', nextUnknown: 'Consulta el último error de la terminal antes de reintentar; no supongas que se revocó ningún PAT.', reasonProvider: 'GitHub u otro proveedor no completó la operación solicitada.', nextProvider: 'Usa la referencia de diagnóstico para consultar la terminal, comprueba la disponibilidad y el acceso al proveedor y revisa posibles cambios parciales antes de reintentar.', reasonRateLimit: 'GitHub ha limitado temporalmente las solicitudes necesarias para la configuración.', nextRateLimit: 'Espera a que se restablezca el límite. Inspecciona los cambios completados antes de iniciar otra configuración.', diagnosticReference: 'Referencia de diagnóstico', resourceReceipt: 'Registro de operaciones de configuración', effectCompleted: 'Marcada como completada', effectSkipped: 'Marcada como omitida', effectInspect: 'Resultado pendiente de inspección', - effectNotStarted: 'No iniciada', scopeLocal: 'Checkout local', scopeMixed: 'Repositorio y organización', + effectNotStarted: 'No iniciada', effectInProgress: 'En curso; resultado aún sin confirmar', scopeLocal: 'Checkout local', scopeMixed: 'Repositorio y organización', receiptFiles: 'Archivos de configuración', receiptSecrets: 'Secrets de GitHub Actions', receiptLabels: 'Etiquetas de issues', receiptIssueTypes: 'Tipos de issue', receiptVariables: 'Variables de GitHub Actions', receiptInitialTag: 'Etiqueta de versión inicial', inspectPartial: 'Algunos cambios podrían estar activos. Revisa GitHub y el resultado de la terminal antes de reintentar.', patSettings: 'Abrir ajustes de PAT en GitHub ↗', closeSession: 'Cerrar sesión local', diff --git a/web/src/i18n/fr.ts b/web/src/i18n/fr.ts index a3b593454..465308625 100644 --- a/web/src/i18n/fr.ts +++ b/web/src/i18n/fr.ts @@ -27,15 +27,18 @@ export const fr: Record = { resultNoChangesBody: 'Copilot n’a pas commencé à appliquer la configuration. Les PAT créés sur GitHub restent actifs jusqu’à leur suppression là-bas.', whatHappened: 'Ce qui s’est passé', alreadyChanged: 'Déjà modifié', noChanges: 'Aucun changement du dépôt ou de GitHub n’a commencé pendant cette session.', nextAction: 'Prochaine étape', reasonPermissions: 'Les droits nécessaires du PAT de configuration manquent ou n’ont pas pu être confirmés.', nextPermissions: 'Vérifiez les droits affichés, corrigez le PAT sur GitHub, puis recommencez.', + permissionReportTitle: 'Vérification des droits du PAT', permissionReportLead: 'Les droits requis qui n’ont pas pu être confirmés sont indiqués ci-dessous. « Non vérifiable » ne signifie pas « absent ».', + permissionIdentity: 'Identité GitHub et accès au dépôt', permissionIdentityValid: 'Vérifiés', permissionIdentityInvalid: 'Refusés', permissionIdentityUnknown: 'Non confirmés', + permissionReportNoFailedGrant: 'Cette vérification n’a trouvé aucun droit requis en échec. Vérifiez le compte prévu pour le PAT et l’erreur du terminal avant de réessayer.', reasonStorage: 'Le stockage GitHub Actions choisi ne peut pas être utilisé en sécurité.', nextStorage: 'Vérifiez la portée des Variables/Secrets et les ressources existantes, puis réessayez.', reasonConfiguration: 'La configuration choisie n’a pas pu être validée.', nextConfiguration: 'Lisez les détails du terminal, corrigez les choix et réessayez.', - reasonExpired: 'La session locale a expiré avant toute modification.', nextExpired: 'Démarrez une nouvelle session ; l’ancienne approbation ne peut pas être réutilisée.', - reasonCancelled: 'La configuration a été annulée avant toute modification.', nextCancelled: 'Démarrez une nouvelle session si vous souhaitez encore configurer ce dépôt.', - reasonUnknown: 'La configuration s’est arrêtée avant l’application ; la cause exacte est inconnue.', nextUnknown: 'Consultez la dernière erreur du terminal avant de réessayer. Ne supposez pas qu’un PAT a été révoqué.', + reasonExpired: 'La session locale a expiré.', nextExpired: 'Démarrez une nouvelle session ; l’ancienne approbation ne peut pas être réutilisée.', + reasonCancelled: 'La configuration a été annulée.', nextCancelled: 'Démarrez une nouvelle session si vous souhaitez encore configurer ce dépôt.', + reasonUnknown: 'La configuration s’est arrêtée. Le navigateur ne peut déterminer ni la cause exacte ni les modifications effectuées.', nextUnknown: 'Consultez la dernière erreur du terminal avant de réessayer. Ne supposez pas qu’un PAT a été révoqué.', reasonProvider: 'GitHub ou un autre fournisseur n’a pas terminé l’opération demandée.', nextProvider: 'Utilisez la référence de diagnostic pour consulter le terminal, vérifiez la disponibilité et les accès, puis examinez tout changement partiel avant de réessayer.', reasonRateLimit: 'GitHub a temporairement limité les requêtes nécessaires à la configuration.', nextRateLimit: 'Attendez la réinitialisation de la limite. Examinez les changements effectués avant de recommencer.', diagnosticReference: 'Référence de diagnostic', resourceReceipt: 'Reçu des opérations de configuration', effectCompleted: 'Signalée comme terminée', effectSkipped: 'Signalée comme ignorée', effectInspect: 'Résultat à vérifier', - effectNotStarted: 'Non commencée', scopeLocal: 'Dossier local', scopeMixed: 'Dépôt et organisation', + effectNotStarted: 'Non commencée', effectInProgress: 'En cours ; résultat non encore confirmé', scopeLocal: 'Dossier local', scopeMixed: 'Dépôt et organisation', receiptFiles: 'Fichiers de configuration', receiptSecrets: 'Secrets GitHub Actions', receiptLabels: 'Étiquettes des tickets', receiptIssueTypes: 'Types de ticket', receiptVariables: 'Variables GitHub Actions', receiptInitialTag: 'Première étiquette de version', inspectPartial: 'Des changements peuvent déjà être actifs. Vérifiez GitHub et le terminal avant de réessayer.', patSettings: 'Ouvrir les paramètres PAT GitHub ↗', closeSession: 'Fermer la session locale', diff --git a/web/src/i18n/pt.ts b/web/src/i18n/pt.ts index f97556353..1e3379a73 100644 --- a/web/src/i18n/pt.ts +++ b/web/src/i18n/pt.ts @@ -27,15 +27,18 @@ export const pt: Record = { resultNoChangesBody: 'O Copilot não começou a aplicar alterações. Os PAT criados no GitHub permanecem até serem eliminados lá.', whatHappened: 'O que aconteceu', alreadyChanged: 'O que mudou', noChanges: 'Não foram iniciadas alterações no repositório nem no GitHub nesta sessão.', nextAction: 'Próximo passo', reasonPermissions: 'Faltam permissões do PAT de configuração ou não foi possível confirmá-las.', nextPermissions: 'Verifique as permissões, corrija o PAT no GitHub e inicie uma nova sessão.', + permissionReportTitle: 'Verificação das permissões do PAT', permissionReportLead: 'As permissões obrigatórias que não puderam ser confirmadas aparecem abaixo. «Não verificável» não significa «ausente».', + permissionIdentity: 'Identidade GitHub e acesso ao repositório', permissionIdentityValid: 'Verificados', permissionIdentityInvalid: 'Recusados', permissionIdentityUnknown: 'Não confirmados', + permissionReportNoFailedGrant: 'Esta verificação não encontrou uma permissão obrigatória em falta. Confirme a conta prevista para o PAT e o erro no terminal antes de tentar novamente.', reasonStorage: 'O armazenamento GitHub Actions escolhido não pôde ser usado com segurança.', nextStorage: 'Verifique o âmbito das Variables/Secrets e os recursos existentes; depois tente novamente.', reasonConfiguration: 'Não foi possível validar a configuração escolhida.', nextConfiguration: 'Leia os detalhes no terminal, corrija as opções e tente novamente.', - reasonExpired: 'A sessão local expirou antes de aplicar alterações.', nextExpired: 'Inicie uma nova sessão; a aprovação anterior não pode ser reutilizada.', - reasonCancelled: 'A configuração foi cancelada antes de aplicar alterações.', nextCancelled: 'Inicie outra execução se ainda quiser configurar o repositório.', - reasonUnknown: 'A configuração parou antes de aplicar; a causa exata é desconhecida.', nextUnknown: 'Leia o último erro no terminal antes de tentar novamente. Não presuma que um PAT foi revogado.', + reasonExpired: 'A sessão local expirou.', nextExpired: 'Inicie uma nova sessão; a aprovação anterior não pode ser reutilizada.', + reasonCancelled: 'A configuração foi cancelada.', nextCancelled: 'Inicie outra execução se ainda quiser configurar o repositório.', + reasonUnknown: 'A configuração parou. O navegador não conseguiu determinar a causa exata nem quais alterações foram concluídas.', nextUnknown: 'Leia o último erro no terminal antes de tentar novamente. Não presuma que um PAT foi revogado.', reasonProvider: 'O GitHub ou outro fornecedor não concluiu a operação solicitada.', nextProvider: 'Use a referência de diagnóstico para consultar o terminal, verifique a disponibilidade e o acesso e reveja possíveis alterações parciais antes de tentar novamente.', reasonRateLimit: 'O GitHub limitou temporariamente os pedidos necessários para a configuração.', nextRateLimit: 'Aguarde a reposição do limite. Inspecione as alterações concluídas antes de iniciar outra configuração.', diagnosticReference: 'Referência de diagnóstico', resourceReceipt: 'Registo das operações de configuração', effectCompleted: 'Indicada como concluída', effectSkipped: 'Indicada como ignorada', effectInspect: 'Resultado por inspecionar', - effectNotStarted: 'Não iniciada', scopeLocal: 'Checkout local', scopeMixed: 'Repositório e organização', + effectNotStarted: 'Não iniciada', effectInProgress: 'Em curso; resultado ainda por confirmar', scopeLocal: 'Checkout local', scopeMixed: 'Repositório e organização', receiptFiles: 'Ficheiros de configuração', receiptSecrets: 'Secrets do GitHub Actions', receiptLabels: 'Etiquetas das questões', receiptIssueTypes: 'Tipos de questão', receiptVariables: 'Variables do GitHub Actions', receiptInitialTag: 'Etiqueta de versão inicial', inspectPartial: 'Algumas alterações podem estar ativas. Verifique o GitHub e o terminal antes de tentar novamente.', patSettings: 'Abrir definições de PAT no GitHub ↗', closeSession: 'Fechar sessão local',