@agentwhy/cli 0.0.0-dev
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +2 -0
- package/README.md +181 -0
- package/THIRD_PARTY_NOTICES.md +31 -0
- package/dist/adapter/claude-code/contract/assumptions.js +208 -0
- package/dist/adapter/claude-code/contract/denials.js +15 -0
- package/dist/adapter/claude-code/contract/entry-points.js +15 -0
- package/dist/adapter/claude-code/contract/fields.js +73 -0
- package/dist/adapter/claude-code/contract/hooks.js +96 -0
- package/dist/adapter/claude-code/contract/identifiers.js +15 -0
- package/dist/adapter/claude-code/contract/layout.js +29 -0
- package/dist/adapter/claude-code/contract/line-types.js +26 -0
- package/dist/adapter/claude-code/contract/projects.js +23 -0
- package/dist/adapter/claude-code/contract/recognition.js +14 -0
- package/dist/adapter/claude-code/contract/session-title.js +20 -0
- package/dist/adapter/claude-code/contract/settings.js +27 -0
- package/dist/adapter/claude-code/contract/task-notifications.js +33 -0
- package/dist/adapter/claude-code/contract/tools.js +37 -0
- package/dist/adapter/claude-code/contract/version.js +51 -0
- package/dist/adapter/claude-code/discovery/claude-code-project-catalogue.js +129 -0
- package/dist/adapter/claude-code/discovery/claude-code-recognition.js +46 -0
- package/dist/adapter/claude-code/discovery/claude-code-session-catalogue.js +100 -0
- package/dist/adapter/claude-code/discovery/claude-code-session-discovery.js +61 -0
- package/dist/adapter/claude-code/discovery/claude-code-session-titles.js +28 -0
- package/dist/adapter/claude-code/discovery/discovered-session.js +1 -0
- package/dist/adapter/claude-code/discovery/session-entries.js +41 -0
- package/dist/adapter/claude-code/discovery/transcript-tail.js +81 -0
- package/dist/adapter/claude-code/events/claude-code-session-source.js +197 -0
- package/dist/adapter/claude-code/events/delegation-index.js +15 -0
- package/dist/adapter/claude-code/events/transcript-scan.js +179 -0
- package/dist/adapter/claude-code/hooks/hook-output.js +42 -0
- package/dist/adapter/claude-code/hooks/pre-tool-use-input.js +23 -0
- package/dist/adapter/claude-code/hooks/stop-input.js +25 -0
- package/dist/adapter/claude-code/hooks/subagent-stop-input.js +26 -0
- package/dist/adapter/claude-code/policy/deny-rules.js +46 -0
- package/dist/adapter/claude-code/probe/claude-code-probe.js +86 -0
- package/dist/adapter/claude-code/probe/collectors/agent-tool-input-key-collector.js +24 -0
- package/dist/adapter/claude-code/probe/collectors/denial-kind-collector.js +20 -0
- package/dist/adapter/claude-code/probe/collectors/denied-call-collector.js +11 -0
- package/dist/adapter/claude-code/probe/collectors/identifier-collector.js +19 -0
- package/dist/adapter/claude-code/probe/collectors/line-collector.js +1 -0
- package/dist/adapter/claude-code/probe/collectors/line-type-collector.js +29 -0
- package/dist/adapter/claude-code/probe/collectors/sidechain-collector.js +20 -0
- package/dist/adapter/claude-code/probe/collectors/task-notification-collector.js +51 -0
- package/dist/adapter/claude-code/probe/collectors/tool-result-reference-collector.js +31 -0
- package/dist/adapter/claude-code/probe/collectors/tool-use-collector.js +24 -0
- package/dist/adapter/claude-code/probe/collectors/tool-version-collector.js +14 -0
- package/dist/adapter/claude-code/probe/collectors/top-level-key-collector.js +14 -0
- package/dist/adapter/claude-code/probe/collectors/unknown-line-type-key-collector.js +24 -0
- package/dist/adapter/claude-code/probe/collectors/working-directory-collector.js +28 -0
- package/dist/adapter/claude-code/probe/doctor-report.js +1 -0
- package/dist/adapter/claude-code/probe/meta-tally.js +42 -0
- package/dist/adapter/claude-code/probe/session-probe.js +1 -0
- package/dist/adapter/claude-code/probe/session-tally.js +41 -0
- package/dist/adapter/claude-code/probe/transcript-line.js +30 -0
- package/dist/adapter/claude-code/probe/transcript-tally.js +74 -0
- package/dist/adapter/claude-code/settings/deny-entries.js +65 -0
- package/dist/adapter/claude-code/settings/hook-entries.js +303 -0
- package/dist/adapter/codex/contract/actions.js +69 -0
- package/dist/adapter/codex/contract/assumptions.js +55 -0
- package/dist/adapter/codex/contract/capabilities.js +24 -0
- package/dist/adapter/codex/contract/delegations.js +30 -0
- package/dist/adapter/codex/contract/deliveries.js +25 -0
- package/dist/adapter/codex/contract/envelope.js +33 -0
- package/dist/adapter/codex/contract/hook-refusals.js +14 -0
- package/dist/adapter/codex/contract/hooks.js +46 -0
- package/dist/adapter/codex/contract/messages.js +47 -0
- package/dist/adapter/codex/contract/permissions.js +27 -0
- package/dist/adapter/codex/contract/reviews.js +13 -0
- package/dist/adapter/codex/contract/session.js +31 -0
- package/dist/adapter/codex/contract/turns.js +23 -0
- package/dist/adapter/codex/contract/version.js +15 -0
- package/dist/adapter/codex/discovery/codex-conversations.js +44 -0
- package/dist/adapter/codex/discovery/codex-project-catalogue.js +49 -0
- package/dist/adapter/codex/discovery/codex-recognition.js +20 -0
- package/dist/adapter/codex/discovery/codex-session-catalogue.js +28 -0
- package/dist/adapter/codex/discovery/codex-session-discovery.js +115 -0
- package/dist/adapter/codex/discovery/codex-session-index.js +21 -0
- package/dist/adapter/codex/discovery/codex-session-titles.js +135 -0
- package/dist/adapter/codex/discovery/session-header.js +86 -0
- package/dist/adapter/codex/discovery/session-owners.js +11 -0
- package/dist/adapter/codex/discovery/session-roots.js +49 -0
- package/dist/adapter/codex/events/action-items.js +138 -0
- package/dist/adapter/codex/events/capability-records.js +26 -0
- package/dist/adapter/codex/events/codex-session-source.js +121 -0
- package/dist/adapter/codex/events/hook-refusals.js +27 -0
- package/dist/adapter/codex/events/rollout-scan.js +614 -0
- package/dist/adapter/codex/events/turn-permissions.js +60 -0
- package/dist/adapter/codex/hooks/pre-tool-use-input.js +24 -0
- package/dist/adapter/codex/hooks/stop-refusals.js +57 -0
- package/dist/adapter/codex/probe/codex-doctor-report.js +1 -0
- package/dist/adapter/codex/probe/codex-probe.js +268 -0
- package/dist/adapter/codex/settings/codex-hooks.js +83 -0
- package/dist/cli/cli-command.js +1 -0
- package/dist/cli/command-router.js +42 -0
- package/dist/cli/commands/check-cli-command.js +128 -0
- package/dist/cli/commands/codex-stop-cli-command.js +27 -0
- package/dist/cli/commands/doctor-arguments.js +32 -0
- package/dist/cli/commands/doctor-cli-command.js +31 -0
- package/dist/cli/commands/doctor-usage.js +14 -0
- package/dist/cli/commands/init-cli-command.js +123 -0
- package/dist/cli/commands/menu-cli-command.js +58 -0
- package/dist/cli/commands/notify-cli-command.js +158 -0
- package/dist/cli/commands/refuse-cli-command.js +79 -0
- package/dist/cli/commands/report-arguments.js +62 -0
- package/dist/cli/commands/report-cli-command.js +36 -0
- package/dist/cli/commands/report-usage.js +41 -0
- package/dist/cli/commands/sessions-cli-command.js +184 -0
- package/dist/cli/commands/start-cli-command.js +83 -0
- package/dist/cli/commands/watch-cli-command.js +142 -0
- package/dist/cli/exit-codes.js +13 -0
- package/dist/cli/project-switches.js +46 -0
- package/dist/cli.js +80 -0
- package/dist/composition-root.js +411 -0
- package/dist/core/access/command-line.js +454 -0
- package/dist/core/access/listing.js +58 -0
- package/dist/core/access/path-shape.js +59 -0
- package/dist/core/access/path-tokens.js +37 -0
- package/dist/core/access/protected-access.js +310 -0
- package/dist/core/access/protected-values.js +102 -0
- package/dist/core/access/recorded-effect.js +67 -0
- package/dist/core/access/returns.js +173 -0
- package/dist/core/access/search-output.js +34 -0
- package/dist/core/access/search-reach.js +268 -0
- package/dist/core/access/uses.js +143 -0
- package/dist/core/access/words-before.js +52 -0
- package/dist/core/agent.js +1 -0
- package/dist/core/capability.js +11 -0
- package/dist/core/combined-project-catalogue.js +36 -0
- package/dist/core/combined-session-catalogue.js +25 -0
- package/dist/core/completeness.js +10 -0
- package/dist/core/context.js +1 -0
- package/dist/core/correlation/correlate.js +329 -0
- package/dist/core/delegation.js +1 -0
- package/dist/core/detector/prompt-signals.js +78 -0
- package/dist/core/entry-point.js +1 -0
- package/dist/core/event.js +1 -0
- package/dist/core/evidence.js +9 -0
- package/dist/core/late-message.js +32 -0
- package/dist/core/message.js +1 -0
- package/dist/core/nearest-project.js +28 -0
- package/dist/core/policy/default-policy.js +32 -0
- package/dist/core/policy/glob.js +56 -0
- package/dist/core/policy/parse-policy.js +70 -0
- package/dist/core/policy/policy.js +20 -0
- package/dist/core/policy/resolve-policy.js +16 -0
- package/dist/core/project-catalogue.js +1 -0
- package/dist/core/project-root.js +133 -0
- package/dist/core/provider-titles.js +10 -0
- package/dist/core/redaction/entropy.js +46 -0
- package/dist/core/redaction/redacted.js +4 -0
- package/dist/core/redaction/redactor.js +339 -0
- package/dist/core/redaction/secret-patterns.js +22 -0
- package/dist/core/redaction/value-shapes.js +81 -0
- package/dist/core/redaction/value-trace.js +110 -0
- package/dist/core/review.js +1 -0
- package/dist/core/session-catalogue.js +19 -0
- package/dist/core/session-filter.js +42 -0
- package/dist/core/session-format.js +27 -0
- package/dist/core/session-model.js +1 -0
- package/dist/core/session-reader.js +22 -0
- package/dist/core/session-records.js +1 -0
- package/dist/core/session-source.js +1 -0
- package/dist/core/session-titles.js +21 -0
- package/dist/core/turn.js +1 -0
- package/dist/doctor/codex-doctor.js +14 -0
- package/dist/doctor/doctor-use-case.js +1 -0
- package/dist/doctor/format-selecting-doctor.js +28 -0
- package/dist/doctor/render/attention/attention-rule.js +1 -0
- package/dist/doctor/render/attention/doctor-attention-rules.js +28 -0
- package/dist/doctor/render/attention/rules/damaged-meta-files-rule.js +8 -0
- package/dist/doctor/render/attention/rules/damaged-transcripts-rule.js +9 -0
- package/dist/doctor/render/attention/rules/incomplete-subagent-pairs-rule.js +6 -0
- package/dist/doctor/render/attention/rules/missing-main-transcript-rule.js +5 -0
- package/dist/doctor/render/attention/rules/missing-spilled-results-rule.js +6 -0
- package/dist/doctor/render/attention/rules/multiple-working-directories-rule.js +15 -0
- package/dist/doctor/render/attention/rules/unknown-denial-kinds-rule.js +5 -0
- package/dist/doctor/render/attention/rules/unknown-line-types-rule.js +6 -0
- package/dist/doctor/render/attention/rules/unrecognised-entries-rule.js +6 -0
- package/dist/doctor/render/attention/rules/unusable-directories-rule.js +12 -0
- package/dist/doctor/render/attention/transcript-scopes.js +6 -0
- package/dist/doctor/render/codex-text-doctor-renderer.js +97 -0
- package/dist/doctor/render/doctor-renderers.js +1 -0
- package/dist/doctor/render/json-doctor-renderer.js +7 -0
- package/dist/doctor/render/output-format.js +1 -0
- package/dist/doctor/render/text-doctor-renderer.js +124 -0
- package/dist/doctor/session-doctor.js +16 -0
- package/dist/infrastructure/clack-asker.js +24 -0
- package/dist/infrastructure/clack-chooser.js +40 -0
- package/dist/infrastructure/clack-multi-chooser.js +31 -0
- package/dist/infrastructure/file-alert-store.js +120 -0
- package/dist/infrastructure/file-checked-store.js +55 -0
- package/dist/infrastructure/file-mark-store.js +67 -0
- package/dist/infrastructure/file-onboarding-store.js +93 -0
- package/dist/infrastructure/folder-window.js +26 -0
- package/dist/infrastructure/node-agentwhy-invocation.js +99 -0
- package/dist/infrastructure/node-browser.js +40 -0
- package/dist/infrastructure/node-file-system.js +111 -0
- package/dist/infrastructure/node-local-server.js +115 -0
- package/dist/infrastructure/node-text-input.js +26 -0
- package/dist/infrastructure/os-notifier.js +21 -0
- package/dist/infrastructure/osascript-folder-chooser.js +53 -0
- package/dist/infrastructure/powershell-folder-chooser.js +78 -0
- package/dist/infrastructure/real-directory.js +18 -0
- package/dist/infrastructure/stream-printer.js +11 -0
- package/dist/infrastructure/terminal-banner.js +19 -0
- package/dist/ports/agentwhy-invocation.js +1 -0
- package/dist/ports/alert-store.js +1 -0
- package/dist/ports/asker.js +1 -0
- package/dist/ports/browser.js +1 -0
- package/dist/ports/checked-store.js +1 -0
- package/dist/ports/chooser.js +1 -0
- package/dist/ports/directory-reader.js +1 -0
- package/dist/ports/file-access-error.js +11 -0
- package/dist/ports/file-reader.js +1 -0
- package/dist/ports/file-tail-reader.js +1 -0
- package/dist/ports/file-writer.js +1 -0
- package/dist/ports/folder-chooser.js +1 -0
- package/dist/ports/local-server.js +1 -0
- package/dist/ports/mark-store.js +10 -0
- package/dist/ports/multi-chooser.js +1 -0
- package/dist/ports/notifier.js +1 -0
- package/dist/ports/onboarding-store.js +1 -0
- package/dist/ports/printer.js +1 -0
- package/dist/ports/text-input.js +1 -0
- package/dist/refuse/command-reach.js +135 -0
- package/dist/refuse/command-refusal.js +88 -0
- package/dist/refuse/render/codex-stop-words.js +21 -0
- package/dist/refuse/render/refusal-words.js +34 -0
- package/dist/report/build-report.js +1037 -0
- package/dist/report/check/actions-digest.js +73 -0
- package/dist/report/check/check-lines.js +83 -0
- package/dist/report/check/mark-request.js +90 -0
- package/dist/report/check/marks.js +84 -0
- package/dist/report/check/render/text-digest-renderer.js +332 -0
- package/dist/report/check/session-actions.js +90 -0
- package/dist/report/check/session-check.js +91 -0
- package/dist/report/choose-policy.js +61 -0
- package/dist/report/flow-reads.js +18 -0
- package/dist/report/private-files/tell-lists.js +84 -0
- package/dist/report/project-rules.js +33 -0
- package/dist/report/render/home-relative.js +18 -0
- package/dist/report/render/html-head.js +26 -0
- package/dist/report/render/html-report-components.js +48 -0
- package/dist/report/render/html-report-styles.js +500 -0
- package/dist/report/render/html-sidebar.js +42 -0
- package/dist/report/render/path-tail.js +14 -0
- package/dist/report/render/report-copy.js +1177 -0
- package/dist/report/render/report-page/advanced-view.js +167 -0
- package/dist/report/render/report-page/file-story.js +114 -0
- package/dist/report/render/report-page/files-view.js +381 -0
- package/dist/report/render/report-page/files.js +77 -0
- package/dist/report/render/report-page/fix-wizard-script.js +269 -0
- package/dist/report/render/report-page/fix-wizard.js +310 -0
- package/dist/report/render/report-page/helpers-view.js +383 -0
- package/dist/report/render/report-page/helpers.js +51 -0
- package/dist/report/render/report-page/item-names.js +63 -0
- package/dist/report/render/report-page/protect-patterns.js +13 -0
- package/dist/report/render/report-page/providers.js +208 -0
- package/dist/report/render/report-page/record-view.js +367 -0
- package/dist/report/render/report-page/report-page-renderer.js +129 -0
- package/dist/report/render/report-page/report-views.js +31 -0
- package/dist/report/render/report-page/story-window.js +356 -0
- package/dist/report/render/report-page/times.js +25 -0
- package/dist/report/render/report-page/to-do-view.js +299 -0
- package/dist/report/render/report-page/to-do.js +152 -0
- package/dist/report/render/report-page.js +1 -0
- package/dist/report/render/session-view.js +250 -0
- package/dist/report/render/text-report-renderer.js +981 -0
- package/dist/report/render/ui/add-file-popup.js +122 -0
- package/dist/report/render/ui/app-sidebar.js +78 -0
- package/dist/report/render/ui/ask-panel.js +80 -0
- package/dist/report/render/ui/avatar.js +19 -0
- package/dist/report/render/ui/backdrop.js +29 -0
- package/dist/report/render/ui/brand-mark.js +4 -0
- package/dist/report/render/ui/button.js +67 -0
- package/dist/report/render/ui/callout.js +20 -0
- package/dist/report/render/ui/chat-example.js +17 -0
- package/dist/report/render/ui/checklist.js +50 -0
- package/dist/report/render/ui/confirm-dialog.js +34 -0
- package/dist/report/render/ui/data-table.js +49 -0
- package/dist/report/render/ui/drawer.js +25 -0
- package/dist/report/render/ui/file-chip.js +37 -0
- package/dist/report/render/ui/fold-line.js +22 -0
- package/dist/report/render/ui/guide-card.js +25 -0
- package/dist/report/render/ui/hero.js +37 -0
- package/dist/report/render/ui/labelled-select.js +10 -0
- package/dist/report/render/ui/live-script.js +222 -0
- package/dist/report/render/ui/local-date.js +58 -0
- package/dist/report/render/ui/mode-icon.js +6 -0
- package/dist/report/render/ui/page-shell.js +101 -0
- package/dist/report/render/ui/pill-tabs.js +47 -0
- package/dist/report/render/ui/popup.js +77 -0
- package/dist/report/render/ui/progress.js +35 -0
- package/dist/report/render/ui/project-list.js +284 -0
- package/dist/report/render/ui/scope-choice.js +19 -0
- package/dist/report/render/ui/stats.js +21 -0
- package/dist/report/render/ui/status-icon.js +30 -0
- package/dist/report/render/ui/status-look.js +21 -0
- package/dist/report/render/ui/switch.js +11 -0
- package/dist/report/render/ui/tag.js +19 -0
- package/dist/report/render/ui/task-list.js +56 -0
- package/dist/report/render/ui/tokens.js +46 -0
- package/dist/report/render/ui/update-notice.js +146 -0
- package/dist/report/render/ui/words/app-words.js +163 -0
- package/dist/report/render/ui/words/conversations-words.js +457 -0
- package/dist/report/render/ui/words/month-words.js +59 -0
- package/dist/report/render/ui/words/onboarding-words.js +446 -0
- package/dist/report/render/ui/words/projects-words.js +217 -0
- package/dist/report/render/ui/words/report-words.js +2099 -0
- package/dist/report/render/ui/words/settings-words.js +611 -0
- package/dist/report/render/ui/words/to-fix-words.js +287 -0
- package/dist/report/report-model.js +2 -0
- package/dist/report/report-use-case.js +1 -0
- package/dist/report/rule-names.js +20 -0
- package/dist/report/session-report.js +163 -0
- package/dist/report/start/app-nav.js +37 -0
- package/dist/report/start/conversations/calendar-view.js +104 -0
- package/dist/report/start/conversations/conversation-columns.js +187 -0
- package/dist/report/start/conversations/conversations-renderer.js +54 -0
- package/dist/report/start/conversations/empty-week.js +120 -0
- package/dist/report/start/conversations/files-window.js +166 -0
- package/dist/report/start/conversations/period-section.js +280 -0
- package/dist/report/start/conversations/periods-script.js +440 -0
- package/dist/report/start/conversations/periods.js +110 -0
- package/dist/report/start/conversations/week-view.js +30 -0
- package/dist/report/start/conversations/weeks.js +17 -0
- package/dist/report/start/month/month-renderer.js +50 -0
- package/dist/report/start/month/month-view.js +135 -0
- package/dist/report/start/month/months.js +17 -0
- package/dist/report/start/onboarding/done.js +171 -0
- package/dist/report/start/onboarding/finish-onboarding.js +93 -0
- package/dist/report/start/onboarding/intro.js +100 -0
- package/dist/report/start/onboarding/onboarding-changes.js +40 -0
- package/dist/report/start/onboarding/onboarding-renderer.js +195 -0
- package/dist/report/start/onboarding/onboarding-script.js +400 -0
- package/dist/report/start/onboarding/onboarding-view.js +98 -0
- package/dist/report/start/onboarding/project-step.js +210 -0
- package/dist/report/start/onboarding/steps.js +239 -0
- package/dist/report/start/onboarding/welcome.js +66 -0
- package/dist/report/start/page-notice.js +10 -0
- package/dist/report/start/projects/index-projects.js +43 -0
- package/dist/report/start/projects/moved-page.js +82 -0
- package/dist/report/start/projects/project-switch.js +138 -0
- package/dist/report/start/projects/projects-window.js +67 -0
- package/dist/report/start/projects/temporary-space.js +18 -0
- package/dist/report/start/render/air-datepicker-vendor.js +27 -0
- package/dist/report/start/render/session-status.js +41 -0
- package/dist/report/start/render/start-words.js +84 -0
- package/dist/report/start/repository.js +28 -0
- package/dist/report/start/serve/index-handler.js +372 -0
- package/dist/report/start/serve/onboarding-request.js +50 -0
- package/dist/report/start/serve/settings-request.js +1 -0
- package/dist/report/start/serve/settings-setup.js +193 -0
- package/dist/report/start/session-index.js +1 -0
- package/dist/report/start/session-start.js +974 -0
- package/dist/report/start/settings/alerts-tab.js +104 -0
- package/dist/report/start/settings/files-tab.js +169 -0
- package/dist/report/start/settings/general-tab.js +71 -0
- package/dist/report/start/settings/settings-renderer.js +254 -0
- package/dist/report/start/settings/settings-script.js +161 -0
- package/dist/report/start/settings/settings-view.js +240 -0
- package/dist/report/start/settings/settings-windows.js +334 -0
- package/dist/report/start/settings-files.js +43 -0
- package/dist/report/start/to-fix/done-list.js +45 -0
- package/dist/report/start/to-fix/file-window.js +110 -0
- package/dist/report/start/to-fix/to-fix-list.js +70 -0
- package/dist/report/start/to-fix/to-fix-renderer.js +237 -0
- package/dist/report/start/to-fix/to-fix-script.js +94 -0
- package/dist/report/start/to-fix/to-fix-view.js +124 -0
- package/dist/report/watch/agent-alert.js +72 -0
- package/dist/report/watch/notice-choices.js +35 -0
- package/dist/report/watch/notice-settings.js +65 -0
- package/dist/report/watch/preferences.js +100 -0
- package/dist/report/watch/render/instruction-words.js +54 -0
- package/dist/report/watch/render/notice-words.js +182 -0
- package/dist/report/watch/subagent-watch.js +345 -0
- package/dist/report/watch/watch-notice.js +1 -0
- package/dist/setup/behind.js +18 -0
- package/dist/setup/codex-mirror.js +171 -0
- package/dist/setup/not-a-project.js +19 -0
- package/dist/setup/project-setup.js +644 -0
- package/dist/setup/protected-patterns.js +30 -0
- package/dist/shared/colour.js +23 -0
- package/dist/shared/compare.js +4 -0
- package/dist/shared/content-version.js +13 -0
- package/dist/shared/counter.js +11 -0
- package/dist/shared/file-stamp.js +4 -0
- package/dist/shared/json.js +13 -0
- package/dist/shared/label.js +13 -0
- package/dist/shared/package-name.js +6 -0
- package/dist/shared/plain-invocation.js +44 -0
- package/dist/shared/plain-version.js +21 -0
- package/dist/shared/printable.js +25 -0
- package/dist/shared/renderer.js +1 -0
- package/dist/shared/sentence.js +20 -0
- package/dist/shared/terminal-logo.js +41 -0
- package/dist/shared/text-table.js +15 -0
- package/dist/shared/wrap.js +29 -0
- package/package.json +70 -0
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The Fix it wizard's steps (the report page spec P18-P25): one step shown at a time; on the first, "Skip for now", which
|
|
3
|
+
* moves to the next file and writes nothing (F52, O13), beside the main button "I did it", which goes on once every row
|
|
4
|
+
* is ticked and, before that, points at the rows still to do; the path copied, the answer to "What's in this file?"
|
|
5
|
+
* drawing its checklist (F49), and a finished file drawn done on the list.
|
|
6
|
+
*
|
|
7
|
+
* What it writes (P42, P43): Done and the quiet skip send a mark, and **Yes, protect it** a rule, to the server the page
|
|
8
|
+
* was loaded from - only where the page says it is served. The file is drawn done, or the rule drawn in place, after
|
|
9
|
+
* the server says so; a refusal is shown in the server's words and changes nothing. A page that is not served, or
|
|
10
|
+
* whose server has stopped, shows the command that does the same instead. A shared copy writes nothing and shows no
|
|
11
|
+
* command (P46). Words come from the page, in every language, never from here.
|
|
12
|
+
*
|
|
13
|
+
* A page that cannot know when it is written whether it will be served - To fix - says `auto`, and the address decides.
|
|
14
|
+
* There a note typed in the last step goes with the mark, the handed-over command carries the run's range, and a
|
|
15
|
+
* written mark is announced (`wizard-marked`) so the page can read itself again (to-fix spec T14, R60).
|
|
16
|
+
*/
|
|
17
|
+
export const FIX_WIZARD_SCRIPT = String.raw `
|
|
18
|
+
(() => {
|
|
19
|
+
const words = document.getElementById('wizard-words');
|
|
20
|
+
const say = (key) => (words ? words.querySelector('[data-word="' + key + '"]').innerHTML : key);
|
|
21
|
+
const served = words !== null && (words.dataset.served === 'true' ||
|
|
22
|
+
(words.dataset.served === 'auto' && (location.protocol === 'http:' || location.protocol === 'https:')));
|
|
23
|
+
|
|
24
|
+
/** A path as a shell reads it back: in single quotes, with a quote inside closed and reopened. */
|
|
25
|
+
const quoted = (text) => "'" + text.split("'").join("'\\''") + "'";
|
|
26
|
+
|
|
27
|
+
/** reached: the server answered at all. A page that is not served never asks. */
|
|
28
|
+
const send = (route, body) => (!served
|
|
29
|
+
? Promise.resolve({ reached: false, ok: false, message: '' })
|
|
30
|
+
: fetch(route, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(body) })
|
|
31
|
+
.then((response) => response.json().then((answer) => ({ reached: true, ok: response.ok && answer.ok === true, message: String(answer.message || '') })))
|
|
32
|
+
.catch(() => ({ reached: false, ok: false, message: '' })));
|
|
33
|
+
|
|
34
|
+
const handOver = (box, command) => {
|
|
35
|
+
box.querySelector('[data-command]').textContent = command;
|
|
36
|
+
box.querySelector('[data-copy]').setAttribute('data-copy', command);
|
|
37
|
+
box.hidden = false;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
const copy = (button) => {
|
|
41
|
+
const text = button.getAttribute('data-copy');
|
|
42
|
+
const shown = () => { button.classList.add('wz-copied'); setTimeout(() => button.classList.remove('wz-copied'), 2000); };
|
|
43
|
+
if (text && navigator.clipboard && navigator.clipboard.writeText) navigator.clipboard.writeText(text).then(shown, () => {});
|
|
44
|
+
};
|
|
45
|
+
|
|
46
|
+
// P38: the rule is sent, and the window closes only once it is written; otherwise it says why, or what to run.
|
|
47
|
+
const protect = (button) => {
|
|
48
|
+
const dialog = button.closest('dialog');
|
|
49
|
+
const every = dialog.querySelector('[data-protect-every]');
|
|
50
|
+
const pattern = every && every.checked ? button.getAttribute('data-pattern-every') : button.getAttribute('data-pattern');
|
|
51
|
+
const reason = dialog.querySelector('[data-note-reason]');
|
|
52
|
+
const command = dialog.querySelector('[data-note-command]');
|
|
53
|
+
reason.hidden = true;
|
|
54
|
+
command.hidden = true;
|
|
55
|
+
const buttons = [...dialog.querySelectorAll('button')];
|
|
56
|
+
buttons.forEach((each) => { each.disabled = true; });
|
|
57
|
+
send('api/settings', { change: 'protect', pattern }).then((answer) => {
|
|
58
|
+
buttons.forEach((each) => { each.disabled = false; });
|
|
59
|
+
if (answer.ok) {
|
|
60
|
+
const at = button.getAttribute('data-protect');
|
|
61
|
+
document.querySelectorAll('[data-protect-open="' + at + '"]').forEach((open) => { open.hidden = true; open.style.display = 'none'; });
|
|
62
|
+
document.querySelectorAll('[data-protected="' + at + '"]').forEach((tag) => { tag.hidden = false; });
|
|
63
|
+
document.querySelectorAll('[data-file-key="' + at + '"]').forEach((row) => { row.dataset.prot = 'yes'; });
|
|
64
|
+
document.dispatchEvent(new CustomEvent('files-changed'));
|
|
65
|
+
dialog.close();
|
|
66
|
+
} else if (answer.reached) {
|
|
67
|
+
reason.textContent = answer.message;
|
|
68
|
+
reason.hidden = false;
|
|
69
|
+
} else {
|
|
70
|
+
handOver(command, 'agentwhy init --protect ' + quoted(pattern));
|
|
71
|
+
}
|
|
72
|
+
});
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
document.addEventListener('click', (event) => {
|
|
76
|
+
const copying = event.target.closest('[data-copy]');
|
|
77
|
+
if (copying) { copy(copying); return; }
|
|
78
|
+
const protecting = event.target.closest('[data-protect]');
|
|
79
|
+
if (protecting) protect(protecting);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
const wizards = [...document.querySelectorAll('[data-wizard]')];
|
|
83
|
+
if (wizards.length === 0) return;
|
|
84
|
+
|
|
85
|
+
const state = new Map();
|
|
86
|
+
const stateOf = (wizard) => {
|
|
87
|
+
if (!state.has(wizard)) state.set(wizard, { step: 1, answer: null });
|
|
88
|
+
return state.get(wizard);
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
const scopeOf = (wizard) => (wizard.dataset.kind === 'keys'
|
|
92
|
+
? wizard.querySelector('[data-step="1"]')
|
|
93
|
+
: wizard.querySelector('.wz-answered.wz-on [data-checklist]'));
|
|
94
|
+
|
|
95
|
+
const tickedAll = (scope) => {
|
|
96
|
+
const rows = scope ? scope.querySelectorAll('[data-checklist] .ck-row') : [];
|
|
97
|
+
return rows.length > 0 && [...rows].every((row) => row.classList.contains('ck-on'));
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const draw = (wizard) => {
|
|
101
|
+
const s = stateOf(wizard);
|
|
102
|
+
wizard.querySelectorAll('.wz-step').forEach((step) => step.classList.toggle('wz-on', step.dataset.step === String(s.step)));
|
|
103
|
+
wizard.querySelectorAll('.st-step').forEach((item, at) => {
|
|
104
|
+
const n = at + 1;
|
|
105
|
+
const state = n < s.step || (n === 3 && s.step === 3) ? 'past' : n === s.step ? 'current' : 'future';
|
|
106
|
+
item.className = 'st-step st-' + state;
|
|
107
|
+
item.querySelector('.st-mark').textContent = state === 'past' ? '✓' : String(n);
|
|
108
|
+
});
|
|
109
|
+
const main = wizard.querySelector('[data-wz-next]');
|
|
110
|
+
const last = wizard.querySelector('[data-wz-last]');
|
|
111
|
+
const skip = wizard.querySelector('[data-wz-skip]');
|
|
112
|
+
const later = wizard.querySelector('[data-wz-later]');
|
|
113
|
+
const back = wizard.querySelector('[data-wz-back]');
|
|
114
|
+
const hint = wizard.querySelector('[data-wz-hint]');
|
|
115
|
+
back.hidden = s.step !== 2;
|
|
116
|
+
if (skip) skip.hidden = s.step !== 1;
|
|
117
|
+
later.hidden = s.step !== 1;
|
|
118
|
+
main.hidden = s.step === 3;
|
|
119
|
+
last.hidden = s.step !== 3;
|
|
120
|
+
if (s.step === 1) {
|
|
121
|
+
const all = tickedAll(scopeOf(wizard));
|
|
122
|
+
main.className = 'pill pill-lg wz-main js-only pill-primary' + (all ? '' : ' wz-wait');
|
|
123
|
+
main.innerHTML = say('wz.all');
|
|
124
|
+
if (all) hint.hidden = true;
|
|
125
|
+
} else if (s.step === 2) {
|
|
126
|
+
hint.hidden = true;
|
|
127
|
+
main.className = 'pill pill-lg wz-main js-only pill-mint';
|
|
128
|
+
main.innerHTML = say('wz.finish');
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
const markDone = (wizard) => {
|
|
133
|
+
const at = wizard.dataset.item;
|
|
134
|
+
const card = document.querySelector('.tc[data-item="' + at + '"]');
|
|
135
|
+
if (card && !card.classList.contains('tc-done')) {
|
|
136
|
+
card.classList.add('tc-done');
|
|
137
|
+
card.querySelector('.tc-check').textContent = '✓';
|
|
138
|
+
}
|
|
139
|
+
const done = document.querySelectorAll('.tc.tc-done').length;
|
|
140
|
+
const total = document.querySelectorAll('.tc[data-item]').length;
|
|
141
|
+
document.querySelectorAll('[data-done]').forEach((element) => { element.textContent = String(done); });
|
|
142
|
+
const fill = document.querySelector('[data-progress] .pg-fill');
|
|
143
|
+
if (fill) fill.style.width = (total === 0 ? 0 : Math.round((done / total) * 1000) / 10) + '%';
|
|
144
|
+
const track = document.querySelector('[data-progress] .pg-track');
|
|
145
|
+
if (track) track.setAttribute('aria-valuenow', String(done));
|
|
146
|
+
document.querySelectorAll('[data-files-fix="' + at + '"]').forEach((element) => { element.hidden = true; });
|
|
147
|
+
document.querySelectorAll('[data-files-fixed="' + at + '"]').forEach((element) => { element.hidden = false; });
|
|
148
|
+
document.querySelectorAll('[data-file-item="' + at + '"]').forEach((row) => {
|
|
149
|
+
row.dataset.group = 'fixed';
|
|
150
|
+
const bar = row.querySelector('.dt-bar');
|
|
151
|
+
if (bar) bar.remove();
|
|
152
|
+
});
|
|
153
|
+
document.dispatchEvent(new CustomEvent('files-changed'));
|
|
154
|
+
document.querySelectorAll('[data-story-fix="' + at + '"]').forEach((element) => { element.hidden = true; });
|
|
155
|
+
document.querySelectorAll('[data-story-fixed="' + at + '"]').forEach((element) => { element.hidden = false; });
|
|
156
|
+
document.querySelectorAll('.rl-dash[data-rail-item="' + at + '"]').forEach((dash) => { if (!dash.classList.contains('rl-now')) dash.className = 'rl-dash rl-done'; });
|
|
157
|
+
const next = document.querySelector('.tc[data-item]:not(.tc-done)');
|
|
158
|
+
const go = document.querySelector('[data-guide-go]');
|
|
159
|
+
if (go && next) {
|
|
160
|
+
go.setAttribute('href', '#fix-' + next.dataset.item);
|
|
161
|
+
go.setAttribute('data-popup-open', 'fix-' + next.dataset.item);
|
|
162
|
+
}
|
|
163
|
+
const guide = document.querySelector('[data-guide]');
|
|
164
|
+
const finished = document.querySelector('[data-all-done]');
|
|
165
|
+
if (!next && guide && finished) { guide.hidden = true; finished.hidden = false; }
|
|
166
|
+
// The coral "!" above the answer gives way to the mint tick once everything is done.
|
|
167
|
+
if (!next) {
|
|
168
|
+
document.querySelectorAll('[data-hero-todo]').forEach((mark) => { mark.hidden = true; });
|
|
169
|
+
document.querySelectorAll('[data-hero-done]').forEach((mark) => { mark.hidden = false; });
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
const finish = (wizard) => {
|
|
174
|
+
stateOf(wizard).step = 3;
|
|
175
|
+
markDone(wizard);
|
|
176
|
+
draw(wizard);
|
|
177
|
+
};
|
|
178
|
+
|
|
179
|
+
// F25, F50: the mark is written first; the file is drawn done once it is, or once the command is on the screen.
|
|
180
|
+
const close = (wizard, result) => {
|
|
181
|
+
const reason = wizard.querySelector('[data-wz-reason]');
|
|
182
|
+
const handover = wizard.querySelector('[data-handover]');
|
|
183
|
+
reason.hidden = true;
|
|
184
|
+
handover.hidden = true;
|
|
185
|
+
if (wizard.hasAttribute('data-shared')) { finish(wizard); return; }
|
|
186
|
+
const main = wizard.querySelector('[data-wz-next]');
|
|
187
|
+
const buttons = [...wizard.querySelectorAll('.wz-foot button')];
|
|
188
|
+
buttons.forEach((each) => { each.disabled = true; });
|
|
189
|
+
if (served && !main.hidden) main.innerHTML = say('wz.saving');
|
|
190
|
+
const field = wizard.querySelector('[data-wz-note]');
|
|
191
|
+
const note = field ? field.value.trim() : '';
|
|
192
|
+
const body = { path: wizard.dataset.path, result };
|
|
193
|
+
if (note !== '') body.note = note;
|
|
194
|
+
const since = wizard.dataset.since;
|
|
195
|
+
send('api/mark', body).then((answer) => {
|
|
196
|
+
buttons.forEach((each) => { each.disabled = false; });
|
|
197
|
+
if (!answer.ok && answer.reached) {
|
|
198
|
+
reason.textContent = answer.message;
|
|
199
|
+
reason.hidden = false;
|
|
200
|
+
draw(wizard);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
if (!answer.ok) {
|
|
204
|
+
handOver(handover, 'agentwhy check --mark ' + result + ' ' + quoted(wizard.dataset.path) +
|
|
205
|
+
(since ? ' --since ' + quoted(since) : '') + (note === '' ? '' : ' --note ' + quoted(note)));
|
|
206
|
+
} else {
|
|
207
|
+
wizard.dispatchEvent(new CustomEvent('wizard-marked', { bubbles: true }));
|
|
208
|
+
}
|
|
209
|
+
finish(wizard);
|
|
210
|
+
});
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
// F52: "Skip for now" leaves this file as it is and goes to the next one, or back to the list after the last.
|
|
214
|
+
const leave = (wizard) => {
|
|
215
|
+
const dialog = wizard.closest('dialog');
|
|
216
|
+
const next = document.getElementById('fix-' + (Number(wizard.dataset.item) + 1));
|
|
217
|
+
if (dialog) dialog.close();
|
|
218
|
+
if (next && typeof next.showModal === 'function' && !next.open) next.showModal();
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
// "I did it" before every row is ticked: the rows still to do are pointed at, and the hint says what to click - or,
|
|
222
|
+
// before "What's in this file?" is answered, that it is to be answered first.
|
|
223
|
+
const nudge = (wizard, scope) => {
|
|
224
|
+
const hint = wizard.querySelector('[data-wz-hint]');
|
|
225
|
+
hint.innerHTML = say(scope ? 'wz.tickFirst' : 'wz.pickFirst');
|
|
226
|
+
hint.hidden = false;
|
|
227
|
+
const rows = scope ? [...scope.querySelectorAll('[data-checklist] .ck-row:not(.ck-on)')] : [...wizard.querySelectorAll('[data-answer]')];
|
|
228
|
+
rows.forEach((row) => { const fold = row.closest('details'); if (fold) fold.open = true; });
|
|
229
|
+
rows.forEach((row) => { row.classList.add('ck-nudge'); setTimeout(() => row.classList.remove('ck-nudge'), 1600); });
|
|
230
|
+
if (rows[0]) rows[0].scrollIntoView({ block: 'nearest', behavior: 'smooth' });
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
wizards.forEach(draw);
|
|
234
|
+
|
|
235
|
+
document.addEventListener('checklist', (event) => {
|
|
236
|
+
const wizard = event.target.closest('[data-wizard]');
|
|
237
|
+
if (wizard) draw(wizard);
|
|
238
|
+
});
|
|
239
|
+
|
|
240
|
+
document.addEventListener('click', (event) => {
|
|
241
|
+
const wizard = event.target.closest('[data-wizard]');
|
|
242
|
+
if (!wizard) return;
|
|
243
|
+
const s = stateOf(wizard);
|
|
244
|
+
|
|
245
|
+
if (event.target.closest('[data-wz-next]')) {
|
|
246
|
+
if (s.step === 1) {
|
|
247
|
+
const scope = scopeOf(wizard);
|
|
248
|
+
if (!tickedAll(scope)) { nudge(wizard, scope); return; }
|
|
249
|
+
s.step = 2;
|
|
250
|
+
} else if (s.step === 2) { close(wizard, wizard.dataset.kind === 'keys' ? 'rotated' : 'handled'); return; }
|
|
251
|
+
draw(wizard);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
if (event.target.closest('[data-wz-later]')) { leave(wizard); return; }
|
|
255
|
+
if (event.target.closest('[data-wz-back]')) { s.step = 1; draw(wizard); return; }
|
|
256
|
+
const skip = event.target.closest('[data-wz-skip]');
|
|
257
|
+
if (skip) { close(wizard, skip.getAttribute('data-wz-skip')); return; }
|
|
258
|
+
if (event.target.closest('[data-wz-last]')) { const dialog = wizard.closest('dialog'); if (dialog) dialog.close(); return; }
|
|
259
|
+
|
|
260
|
+
const answer = event.target.closest('[data-answer]');
|
|
261
|
+
if (answer) {
|
|
262
|
+
wizard.querySelectorAll('[data-answer]').forEach((each) => each.setAttribute('aria-checked', String(each === answer)));
|
|
263
|
+
s.answer = answer.dataset.answer;
|
|
264
|
+
wizard.querySelectorAll('.wz-answered').forEach((block) => block.classList.toggle('wz-on', block.dataset.forAnswer === s.answer));
|
|
265
|
+
draw(wizard);
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
})();
|
|
269
|
+
`;
|
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { escapeHtml as e } from '../html-report-components.js';
|
|
2
|
+
import { inLanguages, labelAttributes, LANGS, translator } from '../report-copy.js';
|
|
3
|
+
import { askPanel, askTrigger } from '../ui/ask-panel.js';
|
|
4
|
+
import { closeButton, pill, textButton } from '../ui/button.js';
|
|
5
|
+
import { checklist } from '../ui/checklist.js';
|
|
6
|
+
import { foldLine } from '../ui/fold-line.js';
|
|
7
|
+
import { CLOSES, opener, popup } from '../ui/popup.js';
|
|
8
|
+
import { rail, stepper } from '../ui/progress.js';
|
|
9
|
+
import { listOf, nameOf, titleOf } from './item-names.js';
|
|
10
|
+
import { fixId } from './to-do-view.js';
|
|
11
|
+
/** What the quiet skip says, by the mark it writes. */
|
|
12
|
+
const SKIP_WORDS = {
|
|
13
|
+
'not-secret': 'wz.skip.keys',
|
|
14
|
+
'not-private': 'wz.skip.data',
|
|
15
|
+
handled: 'fix.skip.handled',
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* The Fix it wizard, one window per file (the report page spec P18-P25; design file *agentwhy App*): where the person is,
|
|
19
|
+
* which file, then one step at a time. A file of keys goes New keys → Your app → Done; a file whose contents cannot be
|
|
20
|
+
* changed goes Limit the damage → Stop it next time → Done. With no script every step is on the page in order.
|
|
21
|
+
*
|
|
22
|
+
* Done writes a mark - *rotated* for keys, *handled* for the rest - and the quiet skip writes *not a real secret* (a
|
|
23
|
+
* template's, R31) or *not private* (a file with no key in it, F50); the page's script sends it where the page is
|
|
24
|
+
* served, and shows the command otherwise (P42, P43). A file of keys that is not a template has no skip.
|
|
25
|
+
*/
|
|
26
|
+
export function fixWizard(items, at, page, extras = {}) {
|
|
27
|
+
const item = items[at];
|
|
28
|
+
const id = fixId(at);
|
|
29
|
+
const keys = item.kind === 'keys';
|
|
30
|
+
const names = page.names ?? nameOf;
|
|
31
|
+
const name = e(names(item.path));
|
|
32
|
+
const next = at + 1 < items.length ? fixId(at + 1) : undefined;
|
|
33
|
+
const label = (key) => inLanguages((t) => t(key));
|
|
34
|
+
const top = '<div class="wz-top"><span class="wz-file" id="' + id + '-title">' + inLanguages((t) => t('wz.file', { n: at + 1, total: items.length })) + '</span>' +
|
|
35
|
+
'<span data-wz-stepper>' + stepper((keys ? ['wz.step.keys', 'wz.step.app', 'wz.step.done'] : ['wz.step.limit', 'wz.step.stop', 'wz.step.done'])
|
|
36
|
+
.map((key, step) => ({ label: label(key), state: step === 0 ? 'current' : 'future' }))) + '</span>' +
|
|
37
|
+
closeButton(labelAttributes((t) => t('app.close')) + CLOSES, 'sm') + '</div>';
|
|
38
|
+
const now = '<div class="wz-now">' +
|
|
39
|
+
rail(items.map((each, index) => ({
|
|
40
|
+
state: index === at ? 'now' : page.done.has(each.path) ? 'done' : 'waiting',
|
|
41
|
+
title: e(names(each.path)),
|
|
42
|
+
item: index,
|
|
43
|
+
}))) +
|
|
44
|
+
'<div class="wz-now-label">' + label('wz.now') + '</div>' +
|
|
45
|
+
'<div class="wz-now-row"><span class="wz-chip" title="' + e(item.path) + '">' + name + '</span>' +
|
|
46
|
+
'<span class="wz-now-title">' + inLanguages((t, lang) => titleOf(item, t, lang)) + '</span></div>' +
|
|
47
|
+
'<div class="wz-context">' + inLanguages((t) => t(keys ? 'wz.context.keys' : 'wz.context.data', { n: item.readers, name: '<code>' + name + '</code>' }) +
|
|
48
|
+
// Found 2026-09-24: asked for one value, the AI opened the file and was shown every line. Said where more than one
|
|
49
|
+
// line held a key (M2a), so the count is a fact of this file.
|
|
50
|
+
(keys && item.keyCount > 1 ? ' ' + t('wz.context.every', { n: item.keyCount }) : '')) + '</div>' +
|
|
51
|
+
(extras.notice === undefined ? '' : '<div class="wz-notice">' + extras.notice + '</div>') +
|
|
52
|
+
(extras.where === undefined ? '' : '<details class="wz-where"><summary class="wz-where-toggle">' + extras.where.summary + '</summary>' +
|
|
53
|
+
'<div class="wz-where-body">' + extras.where.body + '</div></details>') +
|
|
54
|
+
'</div>';
|
|
55
|
+
const note = extras.note === true && !page.shared ? noteField(id + '-note') : '';
|
|
56
|
+
const steps = keys ? keySteps(item, note) : dataSteps(item, page, note);
|
|
57
|
+
const done = '<section class="wz-step wz-done" data-step="3">' +
|
|
58
|
+
'<div class="wz-done-mark" aria-hidden="true">✓</div>' +
|
|
59
|
+
'<h2 class="wz-h2">' + label(keys ? 'wz.done.keys.title' : 'wz.done.data.title') + '</h2>' +
|
|
60
|
+
'<p class="wz-done-text">' + label(keys ? 'wz.done.keys.text' : 'wz.done.data.text') + ' ' +
|
|
61
|
+
(next === undefined ? label('wz.last') : inLanguages((t) => t('wz.left', { n: items.length - at - 1 }))) + '</p>' +
|
|
62
|
+
'<div class="wz-handover" data-handover hidden><p class="wz-handover-text">' + label('wz.cmd.mark') + '</p>' + commandRow() + '</div></section>';
|
|
63
|
+
const standard = keys ? (item.template ? 'not-secret' : undefined) : 'not-private';
|
|
64
|
+
const skip = page.shared ? undefined : extras.skip === undefined ? standard : extras.skip ?? undefined;
|
|
65
|
+
const ask = askPanel(questionsFor(item), id + '-ask');
|
|
66
|
+
const foot = '<div class="wz-foot"><span class="wz-foot-left">' +
|
|
67
|
+
'<button type="button" class="wz-back" data-wz-back hidden>' + label('wz.back') + '</button>' +
|
|
68
|
+
askTrigger(label('app.stuck'), id + '-ask') + '</span>' +
|
|
69
|
+
'<span class="wz-foot-right">' +
|
|
70
|
+
(skip === undefined ? '' : textButton(label(SKIP_WORDS[skip] ?? 'wz.skip.data'), ' data-wz-skip="' + skip + '"', 'wz-skip js-only')) +
|
|
71
|
+
'<button type="button" class="pill pill-outline pill-lg wz-later js-only" data-wz-later>' + label('wz.later') + '</button>' +
|
|
72
|
+
'<button type="button" class="pill pill-primary pill-lg wz-main js-only" data-wz-next>' + label('wz.all') + '</button>' +
|
|
73
|
+
(next === undefined
|
|
74
|
+
? pill({ label: label('wz.backToList'), tone: 'light', size: 'lg', button: true, attributes: CLOSES + ' data-wz-last hidden' })
|
|
75
|
+
: pill({ label: label('wz.nextFile'), tone: 'light', size: 'lg', href: '#' + next, attributes: opener(next) + ' data-wz-last hidden' })) +
|
|
76
|
+
'</span></div>';
|
|
77
|
+
return popup({
|
|
78
|
+
id,
|
|
79
|
+
size: 'wizard',
|
|
80
|
+
labelledBy: id + '-title',
|
|
81
|
+
body: '<div class="wz" data-wizard data-kind="' + item.kind + '" data-item="' + at + '" data-path="' + e(item.path) + '"' +
|
|
82
|
+
(page.shared ? ' data-shared' : '') + (extras.since === undefined ? '' : ' data-since="' + e(extras.since) + '"') + '>' + top + now +
|
|
83
|
+
'<div class="wz-body">' + steps + done + ask + '<p class="wz-hint" data-wz-hint role="status" hidden></p>' +
|
|
84
|
+
'<p class="wz-reason" data-wz-reason role="alert" hidden></p></div>' + foot + '</div>',
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
/** The words on a checklist row's button, in every language. */
|
|
88
|
+
const TICK = () => ({ mark: inLanguages((t) => t('app.tick')), done: inLanguages((t) => t('app.ticked')) });
|
|
89
|
+
function keySteps(item, note) {
|
|
90
|
+
const label = (key, vars = {}) => inLanguages((t) => t(key, vars));
|
|
91
|
+
const code = (name) => '<code class="wz-ck-line">' + e(name) + '</code>';
|
|
92
|
+
const service = (provider, guessed) => ({
|
|
93
|
+
name: e(provider.name),
|
|
94
|
+
// O11: a service read from a line's name is said as a guess, with the name it was read from.
|
|
95
|
+
what: label(provider.what) + (guessed === undefined ? ''
|
|
96
|
+
: '<span class="wz-guess">' + inLanguages((t) => t('wz.keys.guess', { names: guessed.map(code).join(', ') })) + '</span>'),
|
|
97
|
+
...(provider.checked === undefined ? {} : { link: { label: label('wz.open', { provider: e(provider.name) }), href: provider.url } }),
|
|
98
|
+
});
|
|
99
|
+
// F45: a service by a key's format, then by its line's name; a key line neither names is listed by its name, for the
|
|
100
|
+
// person to read. P20b: the secrets first, a test key after them with a word that it is one.
|
|
101
|
+
const tests = new Set(item.tests.map(String));
|
|
102
|
+
const test = '<span class="wz-guess">' + label('wz.keys.testNote') + '</span>';
|
|
103
|
+
const guessed = (testing) => item.guesses.filter((guess) => guess.names.every((each) => tests.has(each)) === testing)
|
|
104
|
+
.map((guess) => { const check = service(guess.provider, guess.names.map(String)); return testing ? { ...check, what: check.what + test } : check; });
|
|
105
|
+
const lined = (testing) => item.lines.filter((each) => tests.has(each) === testing)
|
|
106
|
+
.map((each) => ({ name: code(each), what: label('wz.keys.lineWhat') + (testing ? test : '') }));
|
|
107
|
+
const checks = [...item.providers.map((provider) => service(provider)), ...guessed(false), ...lined(false), ...guessed(true), ...lined(true)];
|
|
108
|
+
// No line was seen holding a key, yet a rule says the file holds them: every line read is listed, and the one that is
|
|
109
|
+
// no key is ticked by the person.
|
|
110
|
+
const everyLine = checks.length === 0 && !item.keyedNames && item.names.length > 0;
|
|
111
|
+
if (everyLine) {
|
|
112
|
+
for (const name of item.names)
|
|
113
|
+
checks.push({ name: code(name), what: label('wz.keys.lineWhat') });
|
|
114
|
+
}
|
|
115
|
+
else if (item.unnamed || checks.length === 0) {
|
|
116
|
+
checks.push({ name: label(checks.length === 0 ? 'wz.keys.unnamed' : 'wz.keys.others'), what: label('wz.keys.unnamedWhat') });
|
|
117
|
+
}
|
|
118
|
+
const text = item.guesses.length > 0 ? label('wz.keys.textGuess')
|
|
119
|
+
: item.providers.length > 0 ? inLanguages((t, lang) => t('wz.keys.text', { providers: e(listOf(item.providers.map((provider) => provider.name), lang)) }))
|
|
120
|
+
: item.lines.length > 0 || everyLine ? label('wz.keys.textLines') : label('wz.keys.textUnnamed');
|
|
121
|
+
// A long list shows its first rows and folds the rest; "I did it" still counts every row (F52).
|
|
122
|
+
const SHOWN = 5;
|
|
123
|
+
const list = checks.length <= SHOWN + 1 ? checklist(checks, TICK())
|
|
124
|
+
: checklist(checks.slice(0, SHOWN), TICK()) + '<details class="wz-more"><summary class="wz-more-line">' +
|
|
125
|
+
inLanguages((t) => t('wz.keys.more', { n: checks.length - SHOWN })) + '</summary>' + checklist(checks.slice(SHOWN), TICK()) + '</details>';
|
|
126
|
+
// P20b: keys named as public are set apart, said as a guess, and are nothing to change.
|
|
127
|
+
const open = item.open.length === 0 ? '' : '<div class="wz-open">' + foldLine({
|
|
128
|
+
summary: inLanguages((t) => t('wz.keys.open', { n: item.open.length })),
|
|
129
|
+
body: '<p class="wz-note">' + label('wz.keys.openWhy') + '</p><p class="wz-open-names">' + item.open.map((each) => code(each)).join(' ') + '</p>',
|
|
130
|
+
}) + '</div>';
|
|
131
|
+
const after = (everyLine ? '<p class="wz-note">' + label('wz.keys.notKey') + '</p>' : '') + open;
|
|
132
|
+
const lines = item.names.length === 0
|
|
133
|
+
? '<p class="wz-line">' + label('wz.app.linesGeneric') + '</p>'
|
|
134
|
+
: '<div class="wz-line">' + label('wz.app.lines') + '</div><div class="wz-env">' + item.names.map((name) => '<div class="wz-env-line"><span class="wz-env-key">' + e(name) + '</span><span class="wz-env-eq">=</span>' +
|
|
135
|
+
'<span class="wz-env-new">' + label('wz.app.placeholder') + '</span></div>').join('') + '</div>';
|
|
136
|
+
return '<section class="wz-step" data-step="1">' + stepHead('wz.stepOf', 1, 'wz.keys.title') + '<p class="wz-p">' + text + '</p>' +
|
|
137
|
+
list + after + '</section>' +
|
|
138
|
+
'<section class="wz-step" data-step="2">' + stepHead('wz.stepOf', 2, 'wz.app.title') + '<p class="wz-p wz-p-tight">' + label('wz.app.text') + '</p>' +
|
|
139
|
+
'<div class="wz-warn"><span class="wz-warn-mark" aria-hidden="true">!</span><span><strong>' + label('wz.app.warnStrong') + '</strong> ' +
|
|
140
|
+
'<span class="wz-warn-why">' + label('wz.app.warn') + '</span></span></div>' +
|
|
141
|
+
'<ol class="wz-howto">' +
|
|
142
|
+
'<li><span class="wz-n" aria-hidden="true">1</span><div><div class="wz-line">' + label('wz.app.open') + '</div>' +
|
|
143
|
+
'<div class="wz-path-row"><span class="wz-path">' + e(item.path) + '</span>' + copyButton(item.path) + '</div></div></li>' +
|
|
144
|
+
'<li><span class="wz-n" aria-hidden="true">2</span><div>' + lines + '</div></li>' +
|
|
145
|
+
'<li><span class="wz-n" aria-hidden="true">3</span><div class="wz-line">' + label('wz.app.save') + '</div></li>' +
|
|
146
|
+
'</ol>' + note + '</section>';
|
|
147
|
+
}
|
|
148
|
+
/** F49: what a file holds decides what limiting the damage is. The person says it; the page never guesses it. */
|
|
149
|
+
const ANSWERS = [
|
|
150
|
+
['wz.data.people', [['wz.data.report', 'wz.data.reportWhat'], ['wz.data.team', 'wz.data.teamWhat'], ['wz.data.move', 'wz.data.moveWhat']]],
|
|
151
|
+
['wz.data.business', [['wz.data.agreement', 'wz.data.agreementWhat'], ['wz.data.team', 'wz.data.teamWhat'], ['wz.data.move', 'wz.data.moveWhat']]],
|
|
152
|
+
['wz.data.other', [['wz.data.team', 'wz.data.teamWhat'], ['wz.data.move', 'wz.data.moveWhat']]],
|
|
153
|
+
];
|
|
154
|
+
function dataSteps(item, page, note) {
|
|
155
|
+
const label = (key) => inLanguages((t) => t(key));
|
|
156
|
+
const key = page.protectKeys.get(item.path);
|
|
157
|
+
// P38a: only a file inside the project can be protected from here, and a shared copy changes nothing (P46). A file a
|
|
158
|
+
// rule protects already (M3) says so; its window is the one the Files view offers, keyed the same.
|
|
159
|
+
const protect = page.toldPaths?.has(item.path) === true
|
|
160
|
+
? '<p class="wz-p">' + label('wz.stop.told') + '</p>'
|
|
161
|
+
: page.protectedPaths.has(item.path)
|
|
162
|
+
? '<span class="wz-protected">' + label('pr.done') + '</span><p class="wz-honest">' + label('wz.stop.honest') + '</p>'
|
|
163
|
+
: key === undefined && page.protectAt !== undefined && !page.shared
|
|
164
|
+
? pill({ label: label('wz.protect'), tone: 'light', size: 'lg', href: e(page.protectAt) }) + '<p class="wz-honest">' + label('wz.stop.honest') + '</p>'
|
|
165
|
+
: key === undefined
|
|
166
|
+
? '<p class="wz-p">' + label(page.shared ? 'wz.stop.shared' : 'wz.stop.outside') + '</p>'
|
|
167
|
+
: pill({ label: label('wz.protect'), tone: 'light', size: 'lg', href: '#protect-' + key, attributes: opener('protect-' + key) + ' data-protect-open="' + key + '"' }) +
|
|
168
|
+
'<span class="wz-protected" data-protected="' + key + '" hidden>' + label('pr.done') + '</span>' +
|
|
169
|
+
'<p class="wz-honest">' + label('wz.stop.honest') + '</p>';
|
|
170
|
+
return '<section class="wz-step" data-step="1">' + stepHead('wz.stepOf', 1, 'wz.data.title') +
|
|
171
|
+
'<div class="wz-ask">' + label('wz.data.ask') + '</div>' +
|
|
172
|
+
'<p class="wz-p wz-p-tight">' + label('wz.data.askHelp') + '</p>' +
|
|
173
|
+
'<div class="wz-answers" role="radiogroup">' +
|
|
174
|
+
// Each answer says what it means, so a person who has never sorted their files this way can still pick one (F49).
|
|
175
|
+
// The fourth answer, "Nothing private in it", is the wizard's own skip in its foot (F50), as the design file has it.
|
|
176
|
+
ANSWERS.map(([answer], index) => '<button type="button" class="wz-answer" role="radio" aria-checked="false" data-answer="' + index + '">' +
|
|
177
|
+
'<span class="wz-option-mark" aria-hidden="true"></span><span class="wz-option"><span class="wz-option-name">' + label(answer) + '</span>' +
|
|
178
|
+
'<span class="wz-option-what">' + label(answer + 'What') + '</span></span></button>').join('') +
|
|
179
|
+
'</div>' +
|
|
180
|
+
ANSWERS.map(([answer, checks], index) => '<div class="wz-answered" data-for-answer="' + index + '"><h3 class="wz-answer-title">' + label(answer) + '</h3>' +
|
|
181
|
+
'<p class="wz-p">' + label('wz.data.text') + '</p>' +
|
|
182
|
+
checklist(checks.map(([name, what]) => ({ name: label(name), what: label(what) })), TICK()) + '</div>').join('') +
|
|
183
|
+
'</section>' +
|
|
184
|
+
'<section class="wz-step" data-step="2">' + stepHead('wz.stepOf', 2, 'wz.stop.title') + '<p class="wz-p">' + label('wz.stop.text') + '</p>' +
|
|
185
|
+
protect + '<p class="wz-path-note"><code>' + e(item.path) + '</code></p>' + note + '</section>';
|
|
186
|
+
}
|
|
187
|
+
/** T14: a note the mark carries, typed before the step that writes it. Never a key: the field says what it is for. */
|
|
188
|
+
function noteField(field) {
|
|
189
|
+
const placeholder = (lang) => e(translator(lang)('fix.window.notePlaceholder'));
|
|
190
|
+
return '<div class="wz-note-field"><label class="wz-note-label" for="' + field + '">' + inLanguages((t) => t('fix.window.note')) + '</label>' +
|
|
191
|
+
'<input class="wz-note-input" id="' + field + '" data-wz-note maxlength="200" autocomplete="off" placeholder="' + placeholder('en') + '"' +
|
|
192
|
+
LANGS.map((lang) => ' data-placeholder-' + lang + '="' + placeholder(lang) + '"').join('') + '></div>';
|
|
193
|
+
}
|
|
194
|
+
/** A button that copies `text`, saying so for two seconds. Filled in by the page's script where `text` is empty. */
|
|
195
|
+
function copyButton(text, label = 'wz.copy') {
|
|
196
|
+
return '<button type="button" class="wz-copy" data-copy="' + e(text) + '"><span class="wz-copy-idle">' + inLanguages((t) => t(label)) + '</span>' +
|
|
197
|
+
'<span class="wz-copy-done">' + inLanguages((t) => t('wz.copied')) + '</span></button>';
|
|
198
|
+
}
|
|
199
|
+
/** The command a page that cannot write hands over (P43, R32, R61), with its Copy: filled in by the page's script. */
|
|
200
|
+
export function commandRow() {
|
|
201
|
+
return '<div class="wz-path-row"><code class="wz-path" data-command></code>' + copyButton('', 'wz.copyCommand') + '</div>';
|
|
202
|
+
}
|
|
203
|
+
function stepHead(of, n, title) {
|
|
204
|
+
return '<div class="wz-step-of">' + inLanguages((t) => t(of, { n })) + '</div><h2 class="wz-h2">' + inLanguages((t) => t(title)) + '</h2>';
|
|
205
|
+
}
|
|
206
|
+
/** The ready-made questions of §7.1, answered in advance (F43). */
|
|
207
|
+
function questionsFor(item) {
|
|
208
|
+
const first = (item.providers[0] ?? item.guesses[0]?.provider)?.name;
|
|
209
|
+
const say = (render) => inLanguages(render);
|
|
210
|
+
if (item.kind === 'data') {
|
|
211
|
+
return [['ask.tell', 'ask.tellA'], ['ask.who', 'ask.whoA'], ['ask.next', 'ask.nextA']].map(([question, answer]) => ({
|
|
212
|
+
question: say((t) => t(question)), answer: say((t) => t(answer)),
|
|
213
|
+
}));
|
|
214
|
+
}
|
|
215
|
+
return [
|
|
216
|
+
first === undefined
|
|
217
|
+
? { question: say((t) => t('ask.makeAny')), answer: say((t) => t('ask.makeAnyA')) }
|
|
218
|
+
: { question: say((t) => t('ask.make', { provider: e(first) })), answer: say((t) => t('ask.makeA', { provider: e(first) })) },
|
|
219
|
+
{ question: say((t) => t('ask.login')), answer: say((t) => t('ask.loginA')) },
|
|
220
|
+
{ question: say((t) => t('ask.stop')), answer: say((t) => t('ask.stopA')) },
|
|
221
|
+
];
|
|
222
|
+
}
|
|
223
|
+
export const FIX_WIZARD_STYLE = String.raw `
|
|
224
|
+
.wz-top{display:flex;align-items:center;gap:14px;padding:14px 24px;border-bottom:1px solid var(--white-07)}
|
|
225
|
+
.wz-file{flex:none;font-size:13px;font-weight:600;color:var(--text-2);white-space:nowrap}
|
|
226
|
+
.wz-top [data-wz-stepper]{flex:1;display:flex}
|
|
227
|
+
.wz-now{padding:22px 36px 20px;background:var(--coral-05);border-bottom:1px solid var(--coral-18)}
|
|
228
|
+
.wz-now-label{font-size:13px;font-weight:600;color:var(--coral-text);margin-bottom:8px}
|
|
229
|
+
.wz-now-row{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:10px}
|
|
230
|
+
.wz-chip{font-family:var(--mono);font-size:20px;font-weight:600;color:var(--text);background:var(--panel);border:1px solid var(--coral-45);border-radius:8px;padding:6px 12px}
|
|
231
|
+
.wz-now-title{font-size:17px;font-weight:650;line-height:1.3}
|
|
232
|
+
.wz-context{font-size:14.5px;line-height:1.5;color:var(--text-2);text-wrap:pretty}
|
|
233
|
+
.wz-context code{font-family:var(--mono);font-size:13.5px;color:var(--text)}
|
|
234
|
+
.wz-body{padding:32px 36px 30px;min-height:340px}
|
|
235
|
+
.js .wz-step:not(.wz-on){display:none}
|
|
236
|
+
.wz-step+.wz-step{margin-top:32px}.js .wz-step+.wz-step{margin-top:0}
|
|
237
|
+
.wz-step-of{font-size:13px;font-weight:600;color:var(--coral-text);margin-bottom:10px}
|
|
238
|
+
.wz-h2{margin:0 0 10px;font-size:28px;line-height:1.2;letter-spacing:-0.02em;font-weight:650;text-wrap:balance}
|
|
239
|
+
.wz-p{margin:0 0 24px;font-size:16px;line-height:1.5;color:var(--text-2);text-wrap:pretty}.wz-p-tight{margin-bottom:22px}
|
|
240
|
+
.wz-warn{display:flex;gap:12px;align-items:flex-start;padding:14px 16px;border-radius:14px;background:var(--coral-07);border:1px solid var(--coral-35);margin-bottom:22px;font-size:15px;line-height:1.5}
|
|
241
|
+
.wz-warn strong{font-weight:650}.wz-warn-why{color:var(--text-soft)}
|
|
242
|
+
.wz-warn-mark{flex:none;width:24px;height:24px;border-radius:50%;background:var(--coral);color:var(--on-coral);font-size:14px;font-weight:700;display:flex;align-items:center;justify-content:center}
|
|
243
|
+
.wz-howto{list-style:none;margin:0 0 22px;padding:0;display:flex;flex-direction:column;gap:18px}
|
|
244
|
+
.wz-howto>li{display:grid;grid-template-columns:28px minmax(0,1fr);gap:14px}
|
|
245
|
+
.wz-howto>li>div{padding-top:3px;min-width:0}
|
|
246
|
+
.wz-n{width:28px;height:28px;border-radius:50%;background:var(--coral-14);color:var(--coral-text);font-size:13px;font-weight:600;display:flex;align-items:center;justify-content:center}
|
|
247
|
+
.wz-line{font-size:16px;line-height:1.5;margin-bottom:10px}p.wz-line{margin:0}
|
|
248
|
+
.wz-path-row{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
|
|
249
|
+
.wz-path{font-family:var(--mono);font-size:14px;color:var(--text);background:var(--panel);border:1px solid var(--white-10);border-radius:8px;padding:8px 12px;overflow-wrap:anywhere}
|
|
250
|
+
.wz-copy{background:transparent;color:var(--text);border:1px solid var(--white-14);border-radius:999px;padding:7px 14px;font:inherit;font-size:13px;font-weight:600;cursor:pointer}
|
|
251
|
+
.wz-copy-done{display:none}.wz-copied{background:var(--mint-14);color:var(--mint)}.wz-copied .wz-copy-idle{display:none}.wz-copied .wz-copy-done{display:inline}
|
|
252
|
+
.wz-env{border-radius:10px;background:var(--panel);border:1px solid var(--white-10);padding:10px 14px;font-family:var(--mono);font-size:14px;line-height:1.9;overflow:auto}
|
|
253
|
+
.wz-env-line{white-space:nowrap}.wz-env-key{color:var(--text)}.wz-env-eq{color:var(--coral-text)}
|
|
254
|
+
.wz-env-new{color:var(--text-3);background:var(--coral-12);border-radius:4px;padding:1px 6px}
|
|
255
|
+
.wz-ck-line{font-family:var(--mono);font-size:15px;overflow-wrap:anywhere}
|
|
256
|
+
.wz-guess{display:block;margin-top:3px}.wz-guess .wz-ck-line{font-size:12.5px;color:var(--text-2)}
|
|
257
|
+
.wz-more{margin-top:10px}.wz-more>.ck{margin-top:10px}
|
|
258
|
+
.wz-more-line{display:inline-flex;align-items:center;gap:6px;padding:8px 14px;border-radius:999px;border:1px solid var(--white-14);color:var(--text-soft);font-size:14px;font-weight:600;cursor:pointer;list-style:none}
|
|
259
|
+
.wz-more-line::-webkit-details-marker{display:none}.wz-more-line:hover{background:var(--white-05);color:var(--text)}.wz-more[open]>.wz-more-line{display:none}
|
|
260
|
+
.wz-open{margin-top:18px}.wz-open .wz-note{margin:0 0 10px}.wz-open-names{margin:0;display:flex;flex-wrap:wrap;gap:6px 14px}
|
|
261
|
+
.wz-note{margin:14px 0 0;font-size:14px;line-height:1.5;color:var(--text-3);text-wrap:pretty}
|
|
262
|
+
.wz-ask{font-size:16px;font-weight:600;margin:0 0 12px}
|
|
263
|
+
.wz-answers{display:flex;flex-direction:column;gap:8px;margin-bottom:24px}
|
|
264
|
+
.wz-answer{display:flex;align-items:flex-start;gap:14px;width:100%;text-align:left;background:var(--panel);border:1px solid var(--white-10);color:var(--text);border-radius:14px;padding:14px 16px;font:inherit;cursor:pointer}
|
|
265
|
+
.wz-answer:hover{border-color:var(--white-30)}
|
|
266
|
+
.wz-answer.ck-nudge{border-color:var(--coral-60);box-shadow:0 0 0 3px var(--coral-14)}
|
|
267
|
+
.wz-option-mark{flex:none;width:20px;height:20px;margin-top:2px;border-radius:50%;border:1.5px solid var(--white-30)}
|
|
268
|
+
.wz-option{display:flex;flex-direction:column;gap:3px}
|
|
269
|
+
.wz-option-name{font-size:15.5px;font-weight:600}
|
|
270
|
+
.wz-option-what{font-size:14px;line-height:1.45;color:var(--text-2)}
|
|
271
|
+
.wz-answer[aria-checked="true"]{border-color:var(--coral-50);background:var(--coral-07)}
|
|
272
|
+
.wz-answer[aria-checked="true"] .wz-option-mark{border:6px solid var(--coral)}
|
|
273
|
+
.js .wz-answered{display:none}.js .wz-answered.wz-on{display:block}
|
|
274
|
+
.wz-answer-title{margin:0 0 8px;font-size:15px;font-weight:650}.js .wz-answer-title{display:none}
|
|
275
|
+
.wz-answered+.wz-answered{margin-top:24px}
|
|
276
|
+
.wz-honest{margin:18px 0 0;font-size:14px;line-height:1.5;color:var(--text-3)}
|
|
277
|
+
.wz-path-note{margin:10px 0 0;font-size:13px;color:var(--text-3)}.wz-path-note code{font-family:var(--mono)}
|
|
278
|
+
.wz-done{text-align:center;padding:30px 0 10px}
|
|
279
|
+
.wz-done-mark{width:64px;height:64px;border-radius:50%;background:var(--mint);color:var(--on-mint);display:flex;align-items:center;justify-content:center;font-size:30px;font-weight:700;margin:0 auto 22px}
|
|
280
|
+
.wz-done .wz-h2{font-size:30px}
|
|
281
|
+
.wz-done-text{margin:0 auto;max-width:400px;font-size:16px;line-height:1.5;color:var(--text-2)}
|
|
282
|
+
.wz-handover{margin:22px auto 0;max-width:520px;text-align:left}
|
|
283
|
+
.wz-handover-text{margin:0 0 10px;font-size:14px;line-height:1.5;color:var(--text-2)}
|
|
284
|
+
.wz-reason{margin:18px 0 0;padding:12px 14px;border-radius:12px;background:var(--coral-07);border:1px solid var(--coral-35);font-size:14px;line-height:1.5;white-space:pre-line}
|
|
285
|
+
.wz-reason[hidden],.wz-handover[hidden],.wz-protected[hidden]{display:none}
|
|
286
|
+
.wz-protected{display:inline-flex;align-items:center;padding:12px 20px;border-radius:999px;background:var(--mint-14);color:var(--mint);font-size:15px;font-weight:600}
|
|
287
|
+
.wz-foot{position:sticky;bottom:0;z-index:1;display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;padding:16px 24px;border-top:1px solid var(--white-07);background:var(--popup-foot)}
|
|
288
|
+
.wz-foot-left,.wz-foot-right{display:flex;gap:14px;align-items:center}.wz-foot-right{gap:10px}
|
|
289
|
+
.wz-back{background:transparent;border:1px solid var(--white-12);color:var(--text-soft);border-radius:999px;padding:10px 16px;font:inherit;font-size:14px;cursor:pointer}
|
|
290
|
+
.wz-foot [hidden]{display:none}
|
|
291
|
+
.cf-note .wz-reason,.cf-note .wz-handover{margin:0 0 18px;max-width:none}
|
|
292
|
+
.wz-skip{color:var(--text-3);font-weight:400;padding:6px 4px}.wz-skip:hover{color:var(--text)}
|
|
293
|
+
.wz-foot-right{flex-wrap:wrap;justify-content:flex-end}
|
|
294
|
+
.wz-main.wz-wait{opacity:.5}
|
|
295
|
+
.wz-hint{margin:16px 0 0;font-size:14.5px;font-weight:600;color:var(--coral-text)}.wz-hint[hidden]{display:none}
|
|
296
|
+
.wz-main.pill-primary,.wz-main.pill-mint{border-color:transparent}
|
|
297
|
+
.wz-main{padding:12px 22px}
|
|
298
|
+
.wz-notice{margin-top:14px}
|
|
299
|
+
.wz-where{margin-top:14px;border-top:1px solid var(--coral-18);padding-top:12px}
|
|
300
|
+
.wz-where-toggle{display:inline-flex;align-items:center;gap:6px;cursor:pointer;list-style:none;font-size:14px;font-weight:600;color:var(--text-soft)}
|
|
301
|
+
.wz-where-toggle::-webkit-details-marker{display:none}
|
|
302
|
+
.wz-where-toggle:after{content:"▾";font-size:12px;color:var(--text-3)}.wz-where[open] .wz-where-toggle:after{content:"▴"}
|
|
303
|
+
.wz-where-toggle:hover{color:var(--text)}
|
|
304
|
+
.wz-where-body{margin-top:12px}
|
|
305
|
+
.wz-note-field{margin-top:26px;padding-top:22px;border-top:1px solid var(--white-07)}
|
|
306
|
+
.wz-note-label{display:block;font-size:14px;font-weight:600;color:var(--text-2);margin-bottom:8px}
|
|
307
|
+
.wz-note-input{width:100%;background:var(--panel);border:1px solid var(--white-12);border-radius:10px;padding:11px 14px;color:var(--text);font:inherit;font-size:15px;outline:none}
|
|
308
|
+
.wz-note-input:focus-visible{border-color:var(--coral-50)}
|
|
309
|
+
@media (max-width:640px){.wz-now{padding:18px 20px}.wz-body{padding:24px 20px}.wz-top{flex-wrap:wrap}}
|
|
310
|
+
`;
|