create-principles-disciple 1.146.4 → 1.146.6
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/_release/product-identity.json +1 -1
- package/package.json +3 -3
- package/release-manager/package.json +3 -3
- package/console/dist/ui/App.d.ts +0 -1
- package/console/dist/ui/App.js +0 -172
- package/console/dist/ui/api.d.ts +0 -611
- package/console/dist/ui/api.js +0 -1094
- package/console/dist/ui/components/auth/login-form.d.ts +0 -4
- package/console/dist/ui/components/auth/login-form.js +0 -142
- package/console/dist/ui/components/auth/splash-screen.d.ts +0 -9
- package/console/dist/ui/components/auth/splash-screen.js +0 -22
- package/console/dist/ui/components/error-boundary.d.ts +0 -15
- package/console/dist/ui/components/error-boundary.js +0 -30
- package/console/dist/ui/components/focus/daily-thought-card.d.ts +0 -1
- package/console/dist/ui/components/focus/daily-thought-card.js +0 -41
- package/console/dist/ui/components/language-switcher.d.ts +0 -2
- package/console/dist/ui/components/language-switcher.js +0 -17
- package/console/dist/ui/components/layout/app-sidebar.d.ts +0 -27
- package/console/dist/ui/components/layout/app-sidebar.js +0 -128
- package/console/dist/ui/components/layout/page-loading.d.ts +0 -13
- package/console/dist/ui/components/layout/page-loading.js +0 -14
- package/console/dist/ui/components/layout/page-shell.d.ts +0 -12
- package/console/dist/ui/components/layout/page-shell.js +0 -11
- package/console/dist/ui/components/layout/section-title.d.ts +0 -10
- package/console/dist/ui/components/layout/section-title.js +0 -9
- package/console/dist/ui/components/notifications/NotificationProvider.d.ts +0 -14
- package/console/dist/ui/components/notifications/NotificationProvider.js +0 -136
- package/console/dist/ui/components/notifications/favicon-badge.d.ts +0 -3
- package/console/dist/ui/components/notifications/favicon-badge.js +0 -68
- package/console/dist/ui/components/notifications/notification-reducer.d.ts +0 -9
- package/console/dist/ui/components/notifications/notification-reducer.js +0 -9
- package/console/dist/ui/components/notifications/sound-storage.d.ts +0 -3
- package/console/dist/ui/components/notifications/sound-storage.js +0 -37
- package/console/dist/ui/components/notifications/useNotifications.d.ts +0 -1
- package/console/dist/ui/components/notifications/useNotifications.js +0 -9
- package/console/dist/ui/components/onboarding/CircuitDiagram.d.ts +0 -8
- package/console/dist/ui/components/onboarding/CircuitDiagram.js +0 -18
- package/console/dist/ui/components/onboarding/DemoResultView.d.ts +0 -22
- package/console/dist/ui/components/onboarding/DemoResultView.js +0 -33
- package/console/dist/ui/components/onboarding/SlashCommandsCard.d.ts +0 -16
- package/console/dist/ui/components/onboarding/SlashCommandsCard.js +0 -20
- package/console/dist/ui/components/onboarding/slashCommands.d.ts +0 -20
- package/console/dist/ui/components/onboarding/slashCommands.js +0 -22
- package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.d.ts +0 -6
- package/console/dist/ui/components/receipts/ReceiptCoverageDisclosure.js +0 -66
- package/console/dist/ui/components/theme-provider.d.ts +0 -14
- package/console/dist/ui/components/theme-provider.js +0 -40
- package/console/dist/ui/components/theme-toggle.d.ts +0 -2
- package/console/dist/ui/components/theme-toggle.js +0 -11
- package/console/dist/ui/components/ui/alert-dialog.d.ts +0 -20
- package/console/dist/ui/components/ui/alert-dialog.js +0 -26
- package/console/dist/ui/components/ui/badge.d.ts +0 -9
- package/console/dist/ui/components/ui/badge.js +0 -22
- package/console/dist/ui/components/ui/button.d.ts +0 -11
- package/console/dist/ui/components/ui/button.js +0 -34
- package/console/dist/ui/components/ui/card.d.ts +0 -8
- package/console/dist/ui/components/ui/card.js +0 -16
- package/console/dist/ui/components/ui/charts.d.ts +0 -51
- package/console/dist/ui/components/ui/charts.js +0 -72
- package/console/dist/ui/components/ui/dialog.d.ts +0 -19
- package/console/dist/ui/components/ui/dialog.js +0 -22
- package/console/dist/ui/components/ui/input.d.ts +0 -3
- package/console/dist/ui/components/ui/input.js +0 -8
- package/console/dist/ui/components/ui/markdown.d.ts +0 -24
- package/console/dist/ui/components/ui/markdown.js +0 -119
- package/console/dist/ui/components/ui/progress-bar.d.ts +0 -20
- package/console/dist/ui/components/ui/progress-bar.js +0 -38
- package/console/dist/ui/components/ui/select.d.ts +0 -13
- package/console/dist/ui/components/ui/select.js +0 -26
- package/console/dist/ui/components/ui/separator.d.ts +0 -3
- package/console/dist/ui/components/ui/separator.js +0 -6
- package/console/dist/ui/components/ui/sheet.d.ts +0 -25
- package/console/dist/ui/components/ui/sheet.js +0 -37
- package/console/dist/ui/components/ui/shiny-text.d.ts +0 -28
- package/console/dist/ui/components/ui/shiny-text.js +0 -46
- package/console/dist/ui/components/ui/skeleton.d.ts +0 -3
- package/console/dist/ui/components/ui/skeleton.js +0 -6
- package/console/dist/ui/components/ui/sonner.d.ts +0 -3
- package/console/dist/ui/components/ui/sonner.js +0 -13
- package/console/dist/ui/components/ui/tooltip.d.ts +0 -7
- package/console/dist/ui/components/ui/tooltip.js +0 -10
- package/console/dist/ui/data/daily-thoughts.d.ts +0 -15
- package/console/dist/ui/data/daily-thoughts.js +0 -164
- package/console/dist/ui/hooks/useNotificationSound.d.ts +0 -12
- package/console/dist/ui/hooks/useNotificationSound.js +0 -74
- package/console/dist/ui/i18n/en.json +0 -2399
- package/console/dist/ui/i18n/index.d.ts +0 -2
- package/console/dist/ui/i18n/index.js +0 -32
- package/console/dist/ui/i18n/zh-CN.json +0 -2399
- package/console/dist/ui/main.d.ts +0 -1
- package/console/dist/ui/main.js +0 -9
- package/console/dist/ui/pages/ReportProblemValidators.d.ts +0 -144
- package/console/dist/ui/pages/ReportProblemValidators.js +0 -418
- package/console/dist/ui/pages/activation/ActivationPage.d.ts +0 -1
- package/console/dist/ui/pages/activation/ActivationPage.js +0 -512
- package/console/dist/ui/pages/activation/ActivationValidators.d.ts +0 -20
- package/console/dist/ui/pages/activation/ActivationValidators.js +0 -160
- package/console/dist/ui/pages/control-center/AgentCard.d.ts +0 -31
- package/console/dist/ui/pages/control-center/AgentCard.js +0 -212
- package/console/dist/ui/pages/control-center/AgentGroup.d.ts +0 -26
- package/console/dist/ui/pages/control-center/AgentGroup.js +0 -38
- package/console/dist/ui/pages/control-center/ControlCenterPage.d.ts +0 -1
- package/console/dist/ui/pages/control-center/ControlCenterPage.js +0 -509
- package/console/dist/ui/pages/control-center/DesignGatePanel.d.ts +0 -1
- package/console/dist/ui/pages/control-center/DesignGatePanel.js +0 -137
- package/console/dist/ui/pages/control-center/RuntimeProfileManager.d.ts +0 -31
- package/console/dist/ui/pages/control-center/RuntimeProfileManager.js +0 -199
- package/console/dist/ui/pages/control-center/WorkflowDiagram.d.ts +0 -17
- package/console/dist/ui/pages/control-center/WorkflowDiagram.js +0 -55
- package/console/dist/ui/pages/debt/DebtPage.d.ts +0 -2
- package/console/dist/ui/pages/debt/DebtPage.js +0 -222
- package/console/dist/ui/pages/design-system/DesignSystemPage.d.ts +0 -2
- package/console/dist/ui/pages/design-system/DesignSystemPage.js +0 -30
- package/console/dist/ui/pages/examiner/ExaminerPage.d.ts +0 -15
- package/console/dist/ui/pages/examiner/ExaminerPage.js +0 -158
- package/console/dist/ui/pages/failed-tasks/FailedTasksPage.d.ts +0 -1
- package/console/dist/ui/pages/failed-tasks/FailedTasksPage.js +0 -421
- package/console/dist/ui/pages/focus/ApprovalSubjectReading.d.ts +0 -24
- package/console/dist/ui/pages/focus/ApprovalSubjectReading.js +0 -133
- package/console/dist/ui/pages/focus/FocusPage.d.ts +0 -123
- package/console/dist/ui/pages/focus/FocusPage.js +0 -567
- package/console/dist/ui/pages/focus/OwnerDecisionCard.d.ts +0 -9
- package/console/dist/ui/pages/focus/OwnerDecisionCard.js +0 -111
- package/console/dist/ui/pages/focus/OwnerWorkbench.d.ts +0 -19
- package/console/dist/ui/pages/focus/OwnerWorkbench.js +0 -75
- package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.d.ts +0 -34
- package/console/dist/ui/pages/focus/RuleCandidateBindingPanel.js +0 -298
- package/console/dist/ui/pages/focus/focus-validation.d.ts +0 -40
- package/console/dist/ui/pages/focus/focus-validation.js +0 -211
- package/console/dist/ui/pages/intent/IntentOnboarding.d.ts +0 -67
- package/console/dist/ui/pages/intent/IntentOnboarding.js +0 -289
- package/console/dist/ui/pages/intent/IntentPage.d.ts +0 -1
- package/console/dist/ui/pages/intent/IntentPage.js +0 -252
- package/console/dist/ui/pages/pain/PainEvidenceValidators.d.ts +0 -59
- package/console/dist/ui/pages/pain/PainEvidenceValidators.js +0 -125
- package/console/dist/ui/pages/pain/PainPage.d.ts +0 -1
- package/console/dist/ui/pages/pain/PainPage.js +0 -420
- package/console/dist/ui/pages/pain/pain-card-helpers.d.ts +0 -175
- package/console/dist/ui/pages/pain/pain-card-helpers.js +0 -181
- package/console/dist/ui/pages/principles/CorePrinciplesPage.d.ts +0 -10
- package/console/dist/ui/pages/principles/CorePrinciplesPage.js +0 -59
- package/console/dist/ui/pages/principles/PrincipleDetailPage.d.ts +0 -60
- package/console/dist/ui/pages/principles/PrincipleDetailPage.js +0 -602
- package/console/dist/ui/pages/principles/PrinciplesPage.d.ts +0 -1
- package/console/dist/ui/pages/principles/PrinciplesPage.js +0 -327
- package/console/dist/ui/pages/principles/PrinciplesViewNav.d.ts +0 -8
- package/console/dist/ui/pages/principles/PrinciplesViewNav.js +0 -15
- package/console/dist/ui/pages/report-problem/ReportProblemPage.d.ts +0 -1
- package/console/dist/ui/pages/report-problem/ReportProblemPage.js +0 -467
- package/console/dist/ui/pages/settings/SettingsPage.d.ts +0 -4
- package/console/dist/ui/pages/settings/SettingsPage.js +0 -457
- package/console/dist/ui/pages/settings/UpdatePage.d.ts +0 -1
- package/console/dist/ui/pages/settings/UpdatePage.js +0 -215
- package/console/dist/ui/pages/welcome/WelcomePage.d.ts +0 -5
- package/console/dist/ui/pages/welcome/WelcomePage.js +0 -187
- package/console/dist/ui/utils/agent-metadata.d.ts +0 -71
- package/console/dist/ui/utils/agent-metadata.js +0 -284
- package/console/dist/ui/utils/approval-review.d.ts +0 -30
- package/console/dist/ui/utils/approval-review.js +0 -50
- package/console/dist/ui/utils/approval-warning-localization.d.ts +0 -34
- package/console/dist/ui/utils/approval-warning-localization.js +0 -148
- package/console/dist/ui/utils/attention-presentation.d.ts +0 -35
- package/console/dist/ui/utils/attention-presentation.js +0 -46
- package/console/dist/ui/utils/blocker-localization.d.ts +0 -23
- package/console/dist/ui/utils/blocker-localization.js +0 -36
- package/console/dist/ui/utils/control-center-helpers.d.ts +0 -79
- package/console/dist/ui/utils/control-center-helpers.js +0 -189
- package/console/dist/ui/utils/enum-labels.d.ts +0 -50
- package/console/dist/ui/utils/enum-labels.js +0 -171
- package/console/dist/ui/utils/format-date.d.ts +0 -11
- package/console/dist/ui/utils/format-date.js +0 -17
- package/console/dist/ui/utils/onboarding-state.d.ts +0 -25
- package/console/dist/ui/utils/onboarding-state.js +0 -77
- package/console/dist/ui/utils/reading-layout.d.ts +0 -20
- package/console/dist/ui/utils/reading-layout.js +0 -46
- package/console/dist/ui/utils/rule-binding-validators.d.ts +0 -13
- package/console/dist/ui/utils/rule-binding-validators.js +0 -188
- package/console/dist/ui/utils/runtime-mode.d.ts +0 -11
- package/console/dist/ui/utils/runtime-mode.js +0 -11
- package/console/dist/ui/utils/token-storage.d.ts +0 -22
- package/console/dist/ui/utils/token-storage.js +0 -47
- package/console/dist/ui/utils/validators.d.ts +0 -1178
- package/console/dist/ui/utils/validators.js +0 -3297
- package/release-manager/dist/bootstrap-entry.d.ts +0 -2
- package/release-manager/dist/bootstrap-entry.d.ts.map +0 -1
- package/release-manager/dist/bootstrap-entry.js.map +0 -1
- package/release-manager/dist/i18n.d.ts +0 -6
- package/release-manager/dist/i18n.d.ts.map +0 -1
- package/release-manager/dist/i18n.js.map +0 -1
- package/release-manager/dist/index.d.ts +0 -7
- package/release-manager/dist/index.d.ts.map +0 -1
- package/release-manager/dist/index.js +0 -656
- package/release-manager/dist/index.js.map +0 -1
- package/release-manager/dist/installer.d.ts +0 -629
- package/release-manager/dist/installer.d.ts.map +0 -1
- package/release-manager/dist/installer.js.map +0 -1
- package/release-manager/dist/installers/codex-host-installer.d.ts +0 -39
- package/release-manager/dist/installers/codex-host-installer.d.ts.map +0 -1
- package/release-manager/dist/installers/codex-host-installer.js.map +0 -1
- package/release-manager/dist/installers/index.d.ts +0 -51
- package/release-manager/dist/installers/index.d.ts.map +0 -1
- package/release-manager/dist/installers/index.js.map +0 -1
- package/release-manager/dist/installers/openclaw-host-installer.d.ts +0 -14
- package/release-manager/dist/installers/openclaw-host-installer.d.ts.map +0 -1
- package/release-manager/dist/installers/openclaw-host-installer.js.map +0 -1
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts +0 -335
- package/release-manager/dist/installers/workbuddy-host-installer.d.ts.map +0 -1
- package/release-manager/dist/installers/workbuddy-host-installer.js.map +0 -1
- package/release-manager/dist/mvp-config.d.ts +0 -233
- package/release-manager/dist/mvp-config.d.ts.map +0 -1
- package/release-manager/dist/mvp-config.js.map +0 -1
- package/release-manager/dist/prompts.d.ts +0 -43
- package/release-manager/dist/prompts.d.ts.map +0 -1
- package/release-manager/dist/prompts.js +0 -268
- package/release-manager/dist/prompts.js.map +0 -1
- package/release-manager/dist/skill-language.d.ts +0 -32
- package/release-manager/dist/skill-language.d.ts.map +0 -1
- package/release-manager/dist/skill-language.js.map +0 -1
- package/release-manager/dist/uninstaller.d.ts +0 -68
- package/release-manager/dist/uninstaller.d.ts.map +0 -1
- package/release-manager/dist/uninstaller.js +0 -746
- package/release-manager/dist/uninstaller.js.map +0 -1
- package/release-manager/dist/update/apply-payload.d.ts +0 -143
- package/release-manager/dist/update/apply-payload.d.ts.map +0 -1
- package/release-manager/dist/update/apply-payload.js.map +0 -1
- package/release-manager/dist/update/atomic-file.d.ts +0 -35
- package/release-manager/dist/update/atomic-file.d.ts.map +0 -1
- package/release-manager/dist/update/atomic-file.js.map +0 -1
- package/release-manager/dist/update/bootstrap-executor.d.ts +0 -21
- package/release-manager/dist/update/bootstrap-executor.d.ts.map +0 -1
- package/release-manager/dist/update/bootstrap-executor.js.map +0 -1
- package/release-manager/dist/update/bootstrap-protocol.d.ts +0 -56
- package/release-manager/dist/update/bootstrap-protocol.d.ts.map +0 -1
- package/release-manager/dist/update/bootstrap-protocol.js.map +0 -1
- package/release-manager/dist/update/channel-metadata.d.ts +0 -28
- package/release-manager/dist/update/channel-metadata.d.ts.map +0 -1
- package/release-manager/dist/update/channel-metadata.js.map +0 -1
- package/release-manager/dist/update/channel-promotion.d.ts +0 -39
- package/release-manager/dist/update/channel-promotion.d.ts.map +0 -1
- package/release-manager/dist/update/channel-promotion.js +0 -55
- package/release-manager/dist/update/channel-promotion.js.map +0 -1
- package/release-manager/dist/update/console-surface.d.ts +0 -19
- package/release-manager/dist/update/console-surface.d.ts.map +0 -1
- package/release-manager/dist/update/console-surface.js.map +0 -1
- package/release-manager/dist/update/data-compatibility.d.ts +0 -35
- package/release-manager/dist/update/data-compatibility.d.ts.map +0 -1
- package/release-manager/dist/update/data-compatibility.js +0 -45
- package/release-manager/dist/update/data-compatibility.js.map +0 -1
- package/release-manager/dist/update/install-layout.d.ts +0 -105
- package/release-manager/dist/update/install-layout.d.ts.map +0 -1
- package/release-manager/dist/update/install-layout.js.map +0 -1
- package/release-manager/dist/update/product-identity.d.ts +0 -70
- package/release-manager/dist/update/product-identity.d.ts.map +0 -1
- package/release-manager/dist/update/product-identity.js.map +0 -1
- package/release-manager/dist/update/release-asset-manifest.d.ts +0 -31
- package/release-manager/dist/update/release-asset-manifest.d.ts.map +0 -1
- package/release-manager/dist/update/release-asset-manifest.js.map +0 -1
- package/release-manager/dist/update/release-identity.d.ts +0 -33
- package/release-manager/dist/update/release-identity.d.ts.map +0 -1
- package/release-manager/dist/update/release-identity.js.map +0 -1
- package/release-manager/dist/update/release-manager-authority.d.ts +0 -39
- package/release-manager/dist/update/release-manager-authority.d.ts.map +0 -1
- package/release-manager/dist/update/release-manager-authority.js.map +0 -1
- package/release-manager/dist/update/release-manager.d.ts +0 -156
- package/release-manager/dist/update/release-manager.d.ts.map +0 -1
- package/release-manager/dist/update/release-manager.js.map +0 -1
- package/release-manager/dist/update/release-metadata-publisher.d.ts +0 -199
- package/release-manager/dist/update/release-metadata-publisher.d.ts.map +0 -1
- package/release-manager/dist/update/release-metadata-publisher.js +0 -478
- package/release-manager/dist/update/release-metadata-publisher.js.map +0 -1
- package/release-manager/dist/update/release-metadata-source.d.ts +0 -85
- package/release-manager/dist/update/release-metadata-source.d.ts.map +0 -1
- package/release-manager/dist/update/release-metadata-source.js.map +0 -1
- package/release-manager/dist/update/release-metadata.d.ts +0 -60
- package/release-manager/dist/update/release-metadata.d.ts.map +0 -1
- package/release-manager/dist/update/release-metadata.js.map +0 -1
- package/release-manager/dist/update/release-policy.d.ts +0 -51
- package/release-manager/dist/update/release-policy.d.ts.map +0 -1
- package/release-manager/dist/update/release-policy.js.map +0 -1
- package/release-manager/dist/update/rollback-policy.d.ts +0 -56
- package/release-manager/dist/update/rollback-policy.d.ts.map +0 -1
- package/release-manager/dist/update/rollback-policy.js +0 -61
- package/release-manager/dist/update/rollback-policy.js.map +0 -1
- package/release-manager/dist/update/transaction-journal.d.ts +0 -212
- package/release-manager/dist/update/transaction-journal.d.ts.map +0 -1
- package/release-manager/dist/update/transaction-journal.js.map +0 -1
- package/release-manager/dist/update/trust-metadata.d.ts +0 -55
- package/release-manager/dist/update/trust-metadata.d.ts.map +0 -1
- package/release-manager/dist/update/trust-metadata.js.map +0 -1
- package/release-manager/dist/update/trust-root-provisioning.d.ts +0 -99
- package/release-manager/dist/update/trust-root-provisioning.d.ts.map +0 -1
- package/release-manager/dist/update/trust-root-provisioning.js.map +0 -1
- package/release-manager/dist/update/update-history.d.ts +0 -46
- package/release-manager/dist/update/update-history.d.ts.map +0 -1
- package/release-manager/dist/update/update-history.js +0 -123
- package/release-manager/dist/update/update-history.js.map +0 -1
- package/release-manager/dist/utils/config-file-io.d.ts +0 -34
- package/release-manager/dist/utils/config-file-io.d.ts.map +0 -1
- package/release-manager/dist/utils/config-file-io.js.map +0 -1
- package/release-manager/dist/utils/env.d.ts +0 -94
- package/release-manager/dist/utils/env.d.ts.map +0 -1
- package/release-manager/dist/utils/env.js.map +0 -1
- package/release-manager/dist/utils/logger.d.ts +0 -15
- package/release-manager/dist/utils/logger.d.ts.map +0 -1
- package/release-manager/dist/utils/logger.js.map +0 -1
- package/release-manager/dist/utils/workspace-divergence.d.ts +0 -36
- package/release-manager/dist/utils/workspace-divergence.d.ts.map +0 -1
- package/release-manager/dist/utils/workspace-divergence.js.map +0 -1
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Focus-page runtime validators for the approvals-grouped payload.
|
|
3
|
-
* Lives outside FocusPage.tsx so contract tests need not load the React page;
|
|
4
|
-
* kept separate from ui/utils/validators.ts because the page additionally
|
|
5
|
-
* enforces the pending/approved/rejected status whitelist it renders on.
|
|
6
|
-
*/
|
|
7
|
-
import type { ApprovalsGroupedData, ApprovalGroup } from "../../api.js";
|
|
8
|
-
export declare function validateApprovalsGroupedData(raw: unknown): ApprovalsGroupedData | null;
|
|
9
|
-
/**
|
|
10
|
-
* PRI-940: which string may the pending-review card render as its title.
|
|
11
|
-
*
|
|
12
|
-
* `principleTitle` degrades to the synthesized `unlinked:<artifactId>` grouping
|
|
13
|
-
* key when the pinned artifact is missing — a machine id that must never reach
|
|
14
|
-
* the Owner as a title (real case: an approval pinned to a superseded scribe
|
|
15
|
-
* revision rendered `unlinked:pi-art-scribe-…` on the card). Returns undefined
|
|
16
|
-
* for that case so the caller falls back to the localized untitled copy; the
|
|
17
|
-
* degradation itself is explained by the artifactUnavailable note, not here.
|
|
18
|
-
*
|
|
19
|
-
* PRI-941 closes the second path to the same key: the artifact row exists, so
|
|
20
|
-
* `artifactUnavailable` is never set, yet it yields no description and its
|
|
21
|
-
* lineage still cannot be resolved. The grouping key — and therefore
|
|
22
|
-
* `principleTitle` — is the machine id either way, so the prefix check guards
|
|
23
|
-
* the render rule itself instead of relying on one producer's flag.
|
|
24
|
-
*
|
|
25
|
-
* What this predicate cannot catch: the prefix only marks unresolved lineage.
|
|
26
|
-
* When the ledger read fails, groups whose lineage DID resolve fall back to a
|
|
27
|
-
* bare principle UUID (`principleTitles.get(id) ?? id`), which renders as a
|
|
28
|
-
* machine id with no note — recorded as a follow-up, not papered over here.
|
|
29
|
-
*/
|
|
30
|
-
export declare function selectApprovalGroupDisplayTitle(group: Pick<ApprovalGroup, "candidateDescription" | "principleTitle" | "artifactUnavailable">): string | undefined;
|
|
31
|
-
/**
|
|
32
|
-
* PRI-941: an untitled card must say why (rc-9 — degradation may not be silent).
|
|
33
|
-
* The artifactUnavailable copy already covers "the draft artifact is gone"; this
|
|
34
|
-
* is the other reason the title ends up empty: the artifact row exists but
|
|
35
|
-
* yields no description, and its grouping key never resolved to a principle.
|
|
36
|
-
* Derived from the title rule itself so the note can never contradict a title
|
|
37
|
-
* the card actually managed to show — a candidate whose description extracted
|
|
38
|
-
* fine keeps its title and gets no warning.
|
|
39
|
-
*/
|
|
40
|
-
export declare function showsUnlinkedCandidateNote(group: Pick<ApprovalGroup, "candidateDescription" | "principleTitle" | "artifactUnavailable">): boolean;
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
import { validatePromptInjectionBudgetStatus } from "../../utils/validators.js";
|
|
2
|
-
/** Type guard: is this a non-null object with own properties (not inherited)? */
|
|
3
|
-
function isRecord(value) {
|
|
4
|
-
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
|
-
}
|
|
6
|
-
function validateApprovalGroup(raw) {
|
|
7
|
-
if (!isRecord(raw))
|
|
8
|
-
return null;
|
|
9
|
-
if (!Object.hasOwn(raw, "principleId") ||
|
|
10
|
-
!Object.hasOwn(raw, "principleTitle") ||
|
|
11
|
-
!Object.hasOwn(raw, "status") ||
|
|
12
|
-
!Object.hasOwn(raw, "records")) {
|
|
13
|
-
return null;
|
|
14
|
-
}
|
|
15
|
-
const { principleId, principleTitle, status, records } = raw;
|
|
16
|
-
if (typeof principleId !== "string" ||
|
|
17
|
-
typeof principleTitle !== "string" ||
|
|
18
|
-
typeof status !== "string" ||
|
|
19
|
-
!["pending", "approved", "rejected"].includes(status) ||
|
|
20
|
-
!Array.isArray(records)) {
|
|
21
|
-
return null;
|
|
22
|
-
}
|
|
23
|
-
const validRecords = [];
|
|
24
|
-
for (const r of records) {
|
|
25
|
-
if (!isRecord(r))
|
|
26
|
-
return null;
|
|
27
|
-
if (!Object.hasOwn(r, "id") ||
|
|
28
|
-
!Object.hasOwn(r, "artifactId") ||
|
|
29
|
-
!Object.hasOwn(r, "channel") ||
|
|
30
|
-
!Object.hasOwn(r, "createdAt") ||
|
|
31
|
-
!Object.hasOwn(r, "status") ||
|
|
32
|
-
typeof r.id !== "string" ||
|
|
33
|
-
typeof r.artifactId !== "string" ||
|
|
34
|
-
typeof r.channel !== "string" ||
|
|
35
|
-
typeof r.createdAt !== "string" ||
|
|
36
|
-
typeof r.status !== "string") {
|
|
37
|
-
return null;
|
|
38
|
-
}
|
|
39
|
-
let recordRevisionReviewUnavailable;
|
|
40
|
-
if (Object.hasOwn(r, "revisionReviewUnavailable")) {
|
|
41
|
-
if (typeof r.revisionReviewUnavailable !== "boolean")
|
|
42
|
-
return null;
|
|
43
|
-
recordRevisionReviewUnavailable = r.revisionReviewUnavailable;
|
|
44
|
-
}
|
|
45
|
-
validRecords.push({
|
|
46
|
-
id: r.id,
|
|
47
|
-
artifactId: r.artifactId,
|
|
48
|
-
channel: r.channel,
|
|
49
|
-
createdAt: r.createdAt,
|
|
50
|
-
status: r.status,
|
|
51
|
-
...(recordRevisionReviewUnavailable !== undefined ? { revisionReviewUnavailable: recordRevisionReviewUnavailable } : {}),
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
// Wave 7: candidateDescription is optional — present when backend could
|
|
55
|
-
// extract human-readable content from the artifact contentJson.
|
|
56
|
-
// ERR-009: if field exists but is wrong type, fail loud (return null).
|
|
57
|
-
let candidateDescription;
|
|
58
|
-
if (Object.hasOwn(raw, "candidateDescription")) {
|
|
59
|
-
const { candidateDescription: description } = raw;
|
|
60
|
-
if (typeof description !== "string")
|
|
61
|
-
return null;
|
|
62
|
-
candidateDescription = description;
|
|
63
|
-
}
|
|
64
|
-
// PR-1894: fitsPromptBudget is optional. ERR-009 discipline — present but
|
|
65
|
-
// wrong type fails loud; absent stays undefined, which the badge treats as
|
|
66
|
-
// "unknown size → do not promise rotation".
|
|
67
|
-
let fitsPromptBudget;
|
|
68
|
-
if (Object.hasOwn(raw, "fitsPromptBudget")) {
|
|
69
|
-
const { fitsPromptBudget: fits } = raw;
|
|
70
|
-
if (typeof fits !== "boolean")
|
|
71
|
-
return null;
|
|
72
|
-
fitsPromptBudget = fits;
|
|
73
|
-
}
|
|
74
|
-
// SPEC-PD-MODEL-AWARE-PROMPT-BUDGET-001: promptBudgetTierFit is optional,
|
|
75
|
-
// whitelist-checked. model_dependent qualifies the rotation promise.
|
|
76
|
-
let promptBudgetTierFit;
|
|
77
|
-
if (Object.hasOwn(raw, "promptBudgetTierFit")) {
|
|
78
|
-
const { promptBudgetTierFit: tier } = raw;
|
|
79
|
-
if (tier !== "fits_all_tiers" && tier !== "model_dependent"
|
|
80
|
-
&& tier !== "exceeds_max_tier" && tier !== "unconfirmed") {
|
|
81
|
-
return null;
|
|
82
|
-
}
|
|
83
|
-
promptBudgetTierFit = tier;
|
|
84
|
-
}
|
|
85
|
-
// PRI-940: artifactUnavailable is optional. ERR-009 discipline — present but
|
|
86
|
-
// wrong type fails loud (return null); absent stays undefined, which keeps
|
|
87
|
-
// the card title rendering exactly as before.
|
|
88
|
-
let artifactUnavailable;
|
|
89
|
-
if (Object.hasOwn(raw, "artifactUnavailable")) {
|
|
90
|
-
const { artifactUnavailable: unavailable } = raw;
|
|
91
|
-
if (typeof unavailable !== "boolean")
|
|
92
|
-
return null;
|
|
93
|
-
artifactUnavailable = unavailable;
|
|
94
|
-
}
|
|
95
|
-
let revisionReviewUnavailable;
|
|
96
|
-
if (Object.hasOwn(raw, 'revisionReviewUnavailable')) {
|
|
97
|
-
const { revisionReviewUnavailable: unavailable } = raw;
|
|
98
|
-
if (typeof unavailable !== 'boolean')
|
|
99
|
-
return null;
|
|
100
|
-
revisionReviewUnavailable = unavailable;
|
|
101
|
-
}
|
|
102
|
-
let revisionReview;
|
|
103
|
-
if (Object.hasOwn(raw, 'revisionReview')) {
|
|
104
|
-
const review = raw.revisionReview;
|
|
105
|
-
if (!isRecord(review) || typeof review.oldStatement !== 'string' || typeof review.newStatement !== 'string' || !isRecord(review.intentFields))
|
|
106
|
-
return null;
|
|
107
|
-
const intentFields = {};
|
|
108
|
-
for (const [key, value] of Object.entries(review.intentFields)) {
|
|
109
|
-
if (typeof value !== 'string')
|
|
110
|
-
return null;
|
|
111
|
-
intentFields[key] = value;
|
|
112
|
-
}
|
|
113
|
-
revisionReview = { oldStatement: review.oldStatement, newStatement: review.newStatement, intentFields,
|
|
114
|
-
...(typeof review.artifactId === 'string' ? { artifactId: review.artifactId } : {}),
|
|
115
|
-
...(typeof review.artifactDigest === 'string' && /^sha256:[a-f0-9]{64}$/.test(review.artifactDigest) ? { artifactDigest: review.artifactDigest } : {}) };
|
|
116
|
-
}
|
|
117
|
-
return {
|
|
118
|
-
principleId,
|
|
119
|
-
principleTitle,
|
|
120
|
-
candidateDescription,
|
|
121
|
-
status,
|
|
122
|
-
fitsPromptBudget,
|
|
123
|
-
promptBudgetTierFit,
|
|
124
|
-
artifactUnavailable,
|
|
125
|
-
revisionReviewUnavailable,
|
|
126
|
-
revisionReview,
|
|
127
|
-
records: validRecords,
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
export function validateApprovalsGroupedData(raw) {
|
|
131
|
-
if (!isRecord(raw))
|
|
132
|
-
return null;
|
|
133
|
-
if (!Object.hasOwn(raw, "groups") ||
|
|
134
|
-
!Object.hasOwn(raw, "generatedAt")) {
|
|
135
|
-
return null;
|
|
136
|
-
}
|
|
137
|
-
const { groups, generatedAt } = raw;
|
|
138
|
-
if (!Array.isArray(groups) || typeof generatedAt !== "string") {
|
|
139
|
-
return null;
|
|
140
|
-
}
|
|
141
|
-
const validatedGroups = [];
|
|
142
|
-
for (const g of groups) {
|
|
143
|
-
const validated = validateApprovalGroup(g);
|
|
144
|
-
if (validated === null)
|
|
145
|
-
return null;
|
|
146
|
-
validatedGroups.push(validated);
|
|
147
|
-
}
|
|
148
|
-
return {
|
|
149
|
-
groups: validatedGroups,
|
|
150
|
-
generatedAt,
|
|
151
|
-
note: Object.hasOwn(raw, "note") && typeof raw.note === "string" ? raw.note : undefined,
|
|
152
|
-
// PRI-908: the pre-approval injection-budget forecast must survive page-local
|
|
153
|
-
// validation, or the queue badge can never render; malformed status degrades
|
|
154
|
-
// to undefined (badge absent) rather than rejecting the payload.
|
|
155
|
-
promptInjection: validatePromptInjectionBudgetStatus(raw.promptInjection) ?? undefined,
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
/**
|
|
159
|
-
* The server synthesizes this grouping key when an approval's lineage cannot be
|
|
160
|
-
* resolved (`ApprovalsGroupedConsoleModel`: `unlinked:${artifactId}`). It is an
|
|
161
|
-
* internal identifier, never Owner copy.
|
|
162
|
-
*/
|
|
163
|
-
const UNLINKED_GROUPING_KEY_PREFIX = "unlinked:";
|
|
164
|
-
/** True when a title is the synthesized grouping key rather than a real name. */
|
|
165
|
-
function isUnlinkedSyntheticPrincipleTitle(title) {
|
|
166
|
-
return title.startsWith(UNLINKED_GROUPING_KEY_PREFIX);
|
|
167
|
-
}
|
|
168
|
-
/**
|
|
169
|
-
* PRI-940: which string may the pending-review card render as its title.
|
|
170
|
-
*
|
|
171
|
-
* `principleTitle` degrades to the synthesized `unlinked:<artifactId>` grouping
|
|
172
|
-
* key when the pinned artifact is missing — a machine id that must never reach
|
|
173
|
-
* the Owner as a title (real case: an approval pinned to a superseded scribe
|
|
174
|
-
* revision rendered `unlinked:pi-art-scribe-…` on the card). Returns undefined
|
|
175
|
-
* for that case so the caller falls back to the localized untitled copy; the
|
|
176
|
-
* degradation itself is explained by the artifactUnavailable note, not here.
|
|
177
|
-
*
|
|
178
|
-
* PRI-941 closes the second path to the same key: the artifact row exists, so
|
|
179
|
-
* `artifactUnavailable` is never set, yet it yields no description and its
|
|
180
|
-
* lineage still cannot be resolved. The grouping key — and therefore
|
|
181
|
-
* `principleTitle` — is the machine id either way, so the prefix check guards
|
|
182
|
-
* the render rule itself instead of relying on one producer's flag.
|
|
183
|
-
*
|
|
184
|
-
* What this predicate cannot catch: the prefix only marks unresolved lineage.
|
|
185
|
-
* When the ledger read fails, groups whose lineage DID resolve fall back to a
|
|
186
|
-
* bare principle UUID (`principleTitles.get(id) ?? id`), which renders as a
|
|
187
|
-
* machine id with no note — recorded as a follow-up, not papered over here.
|
|
188
|
-
*/
|
|
189
|
-
export function selectApprovalGroupDisplayTitle(group) {
|
|
190
|
-
if (group.candidateDescription !== undefined && group.candidateDescription !== "") {
|
|
191
|
-
return group.candidateDescription;
|
|
192
|
-
}
|
|
193
|
-
if (group.artifactUnavailable === true)
|
|
194
|
-
return undefined;
|
|
195
|
-
return isUnlinkedSyntheticPrincipleTitle(group.principleTitle) ? undefined : group.principleTitle;
|
|
196
|
-
}
|
|
197
|
-
/**
|
|
198
|
-
* PRI-941: an untitled card must say why (rc-9 — degradation may not be silent).
|
|
199
|
-
* The artifactUnavailable copy already covers "the draft artifact is gone"; this
|
|
200
|
-
* is the other reason the title ends up empty: the artifact row exists but
|
|
201
|
-
* yields no description, and its grouping key never resolved to a principle.
|
|
202
|
-
* Derived from the title rule itself so the note can never contradict a title
|
|
203
|
-
* the card actually managed to show — a candidate whose description extracted
|
|
204
|
-
* fine keeps its title and gets no warning.
|
|
205
|
-
*/
|
|
206
|
-
export function showsUnlinkedCandidateNote(group) {
|
|
207
|
-
if (group.artifactUnavailable === true)
|
|
208
|
-
return false;
|
|
209
|
-
return (isUnlinkedSyntheticPrincipleTitle(group.principleTitle)
|
|
210
|
-
&& selectApprovalGroupDisplayTitle(group) === undefined);
|
|
211
|
-
}
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* PRI-477 + spec 2026-06-27: Intent Engineering onboarding components.
|
|
3
|
-
*
|
|
4
|
-
* Three components:
|
|
5
|
-
* 1. OnboardingModal — 5-step wizard (intro → Why → Desired Outcome →
|
|
6
|
-
* Non-negotiables → Stop/Escalation → Current Strategic Focus → finish)
|
|
7
|
-
* 2. IntentEditor — section editor with 5 independent textareas (one per
|
|
8
|
-
* section), replacing the single monolithic textarea
|
|
9
|
-
* 3. CreateIntentButton — creates INTENT.md template, optionally shows wizard
|
|
10
|
-
*
|
|
11
|
-
* SPEC §22.1.1 update: Intent Page supports inline editing. This breaks the
|
|
12
|
-
* original "read-only governance view" constraint, but preserves the
|
|
13
|
-
* Owner-owned boundary: all edits are triggered by Owner clicking buttons,
|
|
14
|
-
* never by Agent auto-modification (SPEC §3.9 preserved).
|
|
15
|
-
*
|
|
16
|
-
* Architecture note: parseIntentDocSections / assembleIntentDoc are imported
|
|
17
|
-
* from @principles/core/runtime-v2. These are pure functions (no I/O, no
|
|
18
|
-
* node:crypto) and safe for the browser bundle. The crypto-dependent
|
|
19
|
-
* computeIntentContentHash lives in intent-hash.ts to keep intent-doc.ts
|
|
20
|
-
* browser-bundleable.
|
|
21
|
-
*/
|
|
22
|
-
import { type IntentDocSections } from "@principles/core/runtime-v2/intent-browser";
|
|
23
|
-
interface OnboardingModalProps {
|
|
24
|
-
/** Called when user completes all 5 steps with the assembled sections */
|
|
25
|
-
onComplete: (sections: IntentDocSections) => void;
|
|
26
|
-
/** Called when user clicks "Skip" — creates empty template without wizard */
|
|
27
|
-
onSkip: () => void;
|
|
28
|
-
/** Called when user closes the modal without completing */
|
|
29
|
-
onClose: () => void;
|
|
30
|
-
}
|
|
31
|
-
export declare function OnboardingModal({ onComplete, onSkip, onClose }: OnboardingModalProps): import("react").JSX.Element;
|
|
32
|
-
interface IntentEditorProps {
|
|
33
|
-
/** Initial content to populate the editor (current INTENT.md content) */
|
|
34
|
-
initialContent: string;
|
|
35
|
-
/** Called after successful save — parent should refresh the summary */
|
|
36
|
-
onSaved: () => void;
|
|
37
|
-
/** Called when user cancels editing — parent should hide the editor */
|
|
38
|
-
onCancel: () => void;
|
|
39
|
-
/** Language for bilingual INTENT.md */
|
|
40
|
-
lang: 'zh-CN' | 'en';
|
|
41
|
-
}
|
|
42
|
-
export declare function IntentEditor({ initialContent, onSaved, onCancel, lang }: IntentEditorProps): import("react").JSX.Element;
|
|
43
|
-
interface CreateIntentButtonProps {
|
|
44
|
-
/**
|
|
45
|
-
* Called after INTENT.md is successfully created (or already existed).
|
|
46
|
-
* Receives `openEditor` so the parent (IntentPage) can split the two
|
|
47
|
-
* concerns of the create flow:
|
|
48
|
-
* - always: refresh the summary so NotFoundBanner updates to sections
|
|
49
|
-
* - optionally: open the inline editor immediately afterwards
|
|
50
|
-
*
|
|
51
|
-
* PR-1083 review (CodeRabbit A5): previously this was `() => void` and only
|
|
52
|
-
* invoked when openEditor was true — so the Skip path left NotFoundBanner
|
|
53
|
-
* showing stale "file not found" state after a successful create.
|
|
54
|
-
*/
|
|
55
|
-
onCreated: (openEditor: boolean) => void;
|
|
56
|
-
/** If true, show onboarding wizard before creating. If false, create directly. */
|
|
57
|
-
showOnboarding?: boolean;
|
|
58
|
-
/** Language for bilingual INTENT.md */
|
|
59
|
-
lang: 'zh-CN' | 'en';
|
|
60
|
-
}
|
|
61
|
-
export declare function CreateIntentButton({ onCreated, showOnboarding, lang }: CreateIntentButtonProps): import("react").JSX.Element;
|
|
62
|
-
interface EditButtonProps {
|
|
63
|
-
onClick: () => void;
|
|
64
|
-
loading?: boolean;
|
|
65
|
-
}
|
|
66
|
-
export declare function EditButton({ onClick, loading }: EditButtonProps): import("react").JSX.Element;
|
|
67
|
-
export {};
|
|
@@ -1,289 +0,0 @@
|
|
|
1
|
-
import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
/**
|
|
3
|
-
* PRI-477 + spec 2026-06-27: Intent Engineering onboarding components.
|
|
4
|
-
*
|
|
5
|
-
* Three components:
|
|
6
|
-
* 1. OnboardingModal — 5-step wizard (intro → Why → Desired Outcome →
|
|
7
|
-
* Non-negotiables → Stop/Escalation → Current Strategic Focus → finish)
|
|
8
|
-
* 2. IntentEditor — section editor with 5 independent textareas (one per
|
|
9
|
-
* section), replacing the single monolithic textarea
|
|
10
|
-
* 3. CreateIntentButton — creates INTENT.md template, optionally shows wizard
|
|
11
|
-
*
|
|
12
|
-
* SPEC §22.1.1 update: Intent Page supports inline editing. This breaks the
|
|
13
|
-
* original "read-only governance view" constraint, but preserves the
|
|
14
|
-
* Owner-owned boundary: all edits are triggered by Owner clicking buttons,
|
|
15
|
-
* never by Agent auto-modification (SPEC §3.9 preserved).
|
|
16
|
-
*
|
|
17
|
-
* Architecture note: parseIntentDocSections / assembleIntentDoc are imported
|
|
18
|
-
* from @principles/core/runtime-v2. These are pure functions (no I/O, no
|
|
19
|
-
* node:crypto) and safe for the browser bundle. The crypto-dependent
|
|
20
|
-
* computeIntentContentHash lives in intent-hash.ts to keep intent-doc.ts
|
|
21
|
-
* browser-bundleable.
|
|
22
|
-
*/
|
|
23
|
-
import { useState, useEffect, useRef, useMemo } from "react";
|
|
24
|
-
import { useTranslation } from "react-i18next";
|
|
25
|
-
import { toast } from "sonner";
|
|
26
|
-
import { createIntentTemplate, saveIntentContent } from "../../api.js";
|
|
27
|
-
import { parseIntentDocSections, assembleIntentDoc, } from "@principles/core/runtime-v2/intent-browser";
|
|
28
|
-
// ── Section step helpers ─────────────────────────────────────────────────────
|
|
29
|
-
const SECTION_STEPS = [1, 2, 3, 4, 5];
|
|
30
|
-
const STEP_TO_KEY = {
|
|
31
|
-
1: "why",
|
|
32
|
-
2: "desiredOutcome",
|
|
33
|
-
3: "nonNegotiables",
|
|
34
|
-
4: "stopEscalation",
|
|
35
|
-
5: "currentStrategicFocus",
|
|
36
|
-
};
|
|
37
|
-
// ── localStorage key for onboarding dismissal ─────────────────────────────────
|
|
38
|
-
const ONBOARDING_DISMISSED_KEY = "pd_intent_onboarding_dismissed";
|
|
39
|
-
function isOnboardingDismissed() {
|
|
40
|
-
try {
|
|
41
|
-
return localStorage.getItem(ONBOARDING_DISMISSED_KEY) === "true";
|
|
42
|
-
}
|
|
43
|
-
catch {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
function setOnboardingDismissed() {
|
|
48
|
-
try {
|
|
49
|
-
localStorage.setItem(ONBOARDING_DISMISSED_KEY, "true");
|
|
50
|
-
}
|
|
51
|
-
catch {
|
|
52
|
-
// ignore localStorage errors
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
export function OnboardingModal({ onComplete, onSkip, onClose }) {
|
|
56
|
-
const { t } = useTranslation();
|
|
57
|
-
const [step, setStep] = useState("intro");
|
|
58
|
-
const [sections, setSections] = useState({});
|
|
59
|
-
const [showDiscardConfirm, setShowDiscardConfirm] = useState(false);
|
|
60
|
-
const textareaRef = useRef(null);
|
|
61
|
-
// Focus textarea when entering a section step
|
|
62
|
-
useEffect(() => {
|
|
63
|
-
if (typeof step === "number") {
|
|
64
|
-
textareaRef.current?.focus();
|
|
65
|
-
}
|
|
66
|
-
}, [step]);
|
|
67
|
-
const hasContent = useMemo(() => Object.values(sections).some((v) => typeof v === "string" && v.trim().length > 0), [sections]);
|
|
68
|
-
function handleRequestClose() {
|
|
69
|
-
if (hasContent) {
|
|
70
|
-
setShowDiscardConfirm(true);
|
|
71
|
-
}
|
|
72
|
-
else {
|
|
73
|
-
onClose();
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
function handleNext() {
|
|
77
|
-
if (step === "intro") {
|
|
78
|
-
setStep(1);
|
|
79
|
-
return;
|
|
80
|
-
}
|
|
81
|
-
if (typeof step === "number" && step < 5) {
|
|
82
|
-
setStep((step + 1));
|
|
83
|
-
return;
|
|
84
|
-
}
|
|
85
|
-
if (step === 5) {
|
|
86
|
-
setStep("finish");
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
function handlePrev() {
|
|
90
|
-
if (typeof step === "number" && step > 1) {
|
|
91
|
-
setStep((step - 1));
|
|
92
|
-
return;
|
|
93
|
-
}
|
|
94
|
-
if (step === 1) {
|
|
95
|
-
setStep("intro");
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
function handleSectionChange(value) {
|
|
99
|
-
if (typeof step !== "number")
|
|
100
|
-
return;
|
|
101
|
-
const key = STEP_TO_KEY[step];
|
|
102
|
-
setSections((prev) => ({ ...prev, [key]: value }));
|
|
103
|
-
}
|
|
104
|
-
const currentSectionValue = typeof step === "number" ? (sections[STEP_TO_KEY[step]] ?? "") : "";
|
|
105
|
-
const isCurrentSectionEmpty = typeof step === "number" && currentSectionValue.trim().length === 0;
|
|
106
|
-
return (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-ink/40 backdrop-blur-sm animate-[pdFadeIn_200ms_ease-out]", role: "dialog", "aria-modal": "true", "aria-labelledby": "onboarding-title", onClick: handleRequestClose, children: _jsxs("div", { className: "bg-surface border border-line rounded-[8px] p-6 max-w-[620px] w-full mx-4 max-h-[85vh] overflow-y-auto", onClick: (e) => e.stopPropagation(), children: [_jsxs("div", { className: "flex items-start justify-between mb-4", children: [_jsxs("div", { children: [_jsx("h2", { id: "onboarding-title", className: "text-[20px] font-semibold tracking-tight text-ink mb-1", children: t("pages.intent.onboarding.title") }), step === "intro" && (_jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed", children: t("pages.intent.onboarding.subtitle") })), typeof step === "number" && (_jsx("p", { className: "text-ink-3 text-[12px] font-mono", children: t("pages.intent.wizard.progressLabel", { current: step }) }))] }), _jsx("button", { type: "button", onClick: handleRequestClose, className: "shrink-0 ml-3 text-ink-3 hover:text-ink transition-colors", "aria-label": t("pages.intent.onboarding.close"), children: _jsx("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M4 4L14 14M14 4L4 14", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round" }) }) })] }), step === "intro" && (_jsxs("div", { className: "mb-5", children: [_jsxs("div", { className: "mb-5", children: [_jsx("h3", { className: "text-[14px] font-semibold text-ink mb-1.5", children: t("pages.intent.onboarding.whatIsIt.title") }), _jsx("p", { className: "text-ink-2 text-[13px] leading-relaxed", children: t("pages.intent.onboarding.whatIsIt.description") })] }), _jsxs("div", { className: "mb-5", children: [_jsx("h3", { className: "text-[14px] font-semibold text-ink mb-1.5", children: t("pages.intent.onboarding.whyYouFill.title") }), _jsx("p", { className: "text-ink-2 text-[13px] leading-relaxed", children: t("pages.intent.onboarding.whyYouFill.description") })] }), _jsxs("div", { className: "mb-5", children: [_jsx("h3", { className: "text-[14px] font-semibold text-ink mb-1.5", children: t("pages.intent.onboarding.sectionGuide.title") }), _jsx("p", { className: "text-ink-3 text-[12px] leading-relaxed mb-2", children: t("pages.intent.onboarding.sectionGuide.description") }), _jsx("ul", { className: "space-y-1.5", children: SECTION_STEPS.map((s) => {
|
|
107
|
-
const key = STEP_TO_KEY[s];
|
|
108
|
-
return (_jsxs("li", { className: "text-ink-2 text-[13px] leading-relaxed", children: [_jsx("span", { className: "font-mono text-gov", children: "\u2022" }), " ", t(`pages.intent.wizard.stepLabels.${key}`)] }, s));
|
|
109
|
-
}) })] })] })), typeof step === "number" && (_jsxs("div", { className: "mb-5", children: [_jsx("h3", { className: "text-[15px] font-semibold text-ink mb-1.5", children: t(`pages.intent.wizard.stepLabels.${STEP_TO_KEY[step]}`) }), _jsx("p", { className: "text-ink-3 text-[12px] leading-relaxed mb-3", children: t(`pages.intent.wizard.guidance.${STEP_TO_KEY[step]}`) }), _jsx("textarea", { ref: textareaRef, value: currentSectionValue, onChange: (e) => handleSectionChange(e.target.value), placeholder: t(`pages.intent.wizard.guidance.${STEP_TO_KEY[step]}`), className: "w-full h-[180px] bg-surface border border-line rounded-[4px] p-3 text-[13px] text-ink leading-relaxed resize-y focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov/30", spellCheck: false, "aria-label": t(`pages.intent.wizard.stepLabels.${STEP_TO_KEY[step]}`) }), isCurrentSectionEmpty && (_jsx("p", { className: "text-amber text-[12px] mt-1.5", role: "alert", children: t("pages.intent.wizard.emptyWarning") }))] })), step === "finish" && (_jsxs("div", { className: "mb-5", children: [_jsx("h3", { className: "text-[15px] font-semibold text-ink mb-3", children: t("pages.intent.wizard.finish") }), _jsx("div", { className: "space-y-3", children: SECTION_STEPS.map((s) => {
|
|
110
|
-
const key = STEP_TO_KEY[s];
|
|
111
|
-
const value = sections[key] ?? "";
|
|
112
|
-
return (_jsxs("div", { className: "border-l-2 border-gov/40 pl-3", children: [_jsx("p", { className: "font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-0.5", children: t(`pages.intent.wizard.stepLabels.${key}`) }), _jsx("p", { className: "text-ink-2 text-[13px] leading-relaxed whitespace-pre-wrap", children: value || t("pages.intent.wizard.emptyWarning") })] }, s));
|
|
113
|
-
}) })] })), _jsxs("div", { className: "flex items-center justify-between gap-2 pt-3 border-t border-line", children: [_jsxs("div", { children: [step === "intro" && (_jsx("button", { type: "button", onClick: onSkip, className: "border border-line bg-surface text-ink-2 rounded-[4px] px-4 py-2 text-[13px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.intent.onboarding.skipOption") })), typeof step === "number" && (_jsx("button", { type: "button", onClick: handlePrev, className: "border border-line bg-surface text-ink-2 rounded-[4px] px-4 py-2 text-[13px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.intent.wizard.prev") }))] }), _jsxs("div", { children: [step === "intro" && (_jsx("button", { type: "button", onClick: handleNext, className: "bg-gov text-paper rounded-[4px] px-4 py-2 text-[13px] font-medium hover:bg-gov-dark transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.intent.onboarding.startFilling") })), typeof step === "number" && step < 5 && (_jsx("button", { type: "button", onClick: handleNext, disabled: isCurrentSectionEmpty, className: "bg-gov text-paper rounded-[4px] px-4 py-2 text-[13px] font-medium hover:bg-gov-dark transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.intent.wizard.next") })), step === 5 && (_jsx("button", { type: "button", onClick: handleNext, disabled: isCurrentSectionEmpty, className: "bg-gov text-paper rounded-[4px] px-4 py-2 text-[13px] font-medium hover:bg-gov-dark transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.intent.wizard.review") })), step === "finish" && (_jsx("button", { type: "button", onClick: () => onComplete(sections), className: "bg-gov text-paper rounded-[4px] px-4 py-2 text-[13px] font-medium hover:bg-gov-dark transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2", children: t("pages.intent.wizard.complete") }))] })] }), showDiscardConfirm && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-ink/40 backdrop-blur-sm", role: "alertdialog", "aria-modal": "true", "aria-labelledby": "discard-title", onClick: () => setShowDiscardConfirm(false), children: _jsxs("div", { className: "bg-surface border border-line rounded-[8px] p-5 max-w-[400px] w-full mx-4", onClick: (e) => e.stopPropagation(), children: [_jsx("p", { id: "discard-title", className: "text-ink text-[14px] font-semibold mb-2", children: t("pages.intent.wizard.discardConfirmTitle") }), _jsx("p", { className: "text-ink-3 text-[13px] leading-relaxed mb-4", children: t("pages.intent.wizard.discardConfirmBody") }), _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx("button", { type: "button", onClick: () => setShowDiscardConfirm(false), className: "border border-line bg-surface text-ink-2 rounded-[4px] px-3 py-1.5 text-[12px] hover:border-line-2 transition-colors", children: t("pages.intent.wizard.discardConfirmCancel") }), _jsx("button", { type: "button", onClick: () => {
|
|
114
|
-
setShowDiscardConfirm(false);
|
|
115
|
-
onClose();
|
|
116
|
-
}, className: "bg-red-600 text-white rounded-[4px] px-3 py-1.5 text-[12px] hover:bg-red-700 transition-colors", children: t("pages.intent.wizard.discardConfirmConfirm") })] })] }) }))] }) }));
|
|
117
|
-
}
|
|
118
|
-
export function IntentEditor({ initialContent, onSaved, onCancel, lang }) {
|
|
119
|
-
const { t } = useTranslation();
|
|
120
|
-
// Parse initial content into 5 sections on mount. parseIntentDocSections
|
|
121
|
-
// returns undefined for missing sections; we normalize to empty string for
|
|
122
|
-
// textarea value binding (controlled input requires a string value).
|
|
123
|
-
const [sections, setSections] = useState(() => {
|
|
124
|
-
const parsed = parseIntentDocSections(initialContent);
|
|
125
|
-
return {
|
|
126
|
-
why: parsed.why ?? "",
|
|
127
|
-
desiredOutcome: parsed.desiredOutcome ?? "",
|
|
128
|
-
nonNegotiables: parsed.nonNegotiables ?? "",
|
|
129
|
-
stopEscalation: parsed.stopEscalation ?? "",
|
|
130
|
-
currentStrategicFocus: parsed.currentStrategicFocus ?? "",
|
|
131
|
-
};
|
|
132
|
-
});
|
|
133
|
-
const [saving, setSaving] = useState(false);
|
|
134
|
-
const [showDiscardConfirm, setShowDiscardConfirm] = useState(false);
|
|
135
|
-
const firstTextareaRef = useRef(null);
|
|
136
|
-
// Focus the first textarea on mount
|
|
137
|
-
useEffect(() => {
|
|
138
|
-
firstTextareaRef.current?.focus();
|
|
139
|
-
}, []);
|
|
140
|
-
// Detect changes by comparing current sections to initial parsed sections.
|
|
141
|
-
// We re-parse initialContent on each render (cheap, pure function) rather
|
|
142
|
-
// than storing a second state variable — avoids stale closure issues.
|
|
143
|
-
const initialSections = useMemo(() => parseIntentDocSections(initialContent), [initialContent]);
|
|
144
|
-
const hasChanges = useMemo(() => {
|
|
145
|
-
for (const step of SECTION_STEPS) {
|
|
146
|
-
const key = STEP_TO_KEY[step];
|
|
147
|
-
const current = sections[key] ?? "";
|
|
148
|
-
const initial = initialSections[key] ?? "";
|
|
149
|
-
if (current !== initial)
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
return false;
|
|
153
|
-
}, [sections, initialSections]);
|
|
154
|
-
function handleSectionChange(key, value) {
|
|
155
|
-
setSections((prev) => ({ ...prev, [key]: value }));
|
|
156
|
-
}
|
|
157
|
-
async function handleSave() {
|
|
158
|
-
if (!hasChanges || saving)
|
|
159
|
-
return;
|
|
160
|
-
// Client-side validation: require at least one non-empty section.
|
|
161
|
-
// Empty individual sections are allowed (user may clear a section
|
|
162
|
-
// intentionally); the server emits warnings, not errors, for empty
|
|
163
|
-
// sections.
|
|
164
|
-
const allEmpty = SECTION_STEPS.every((s) => {
|
|
165
|
-
const key = STEP_TO_KEY[s];
|
|
166
|
-
return (sections[key] ?? "").trim().length === 0;
|
|
167
|
-
});
|
|
168
|
-
if (allEmpty) {
|
|
169
|
-
toast.error(t("pages.intent.editor.emptyContent"));
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
const assembled = assembleIntentDoc(sections);
|
|
173
|
-
setSaving(true);
|
|
174
|
-
const result = await saveIntentContent(assembled, lang);
|
|
175
|
-
setSaving(false);
|
|
176
|
-
if (!result.success) {
|
|
177
|
-
// Branch on structured reason field, NOT substring matching (PR-1083 N4).
|
|
178
|
-
if (result.reason === "oversized") {
|
|
179
|
-
toast.error(t("pages.intent.editor.oversized"));
|
|
180
|
-
}
|
|
181
|
-
else {
|
|
182
|
-
toast.error(t("pages.intent.editor.saveFailed"));
|
|
183
|
-
}
|
|
184
|
-
return;
|
|
185
|
-
}
|
|
186
|
-
toast.success(t("pages.intent.editor.saveSuccess"));
|
|
187
|
-
onSaved();
|
|
188
|
-
}
|
|
189
|
-
function handleCancel() {
|
|
190
|
-
if (hasChanges) {
|
|
191
|
-
setShowDiscardConfirm(true);
|
|
192
|
-
}
|
|
193
|
-
else {
|
|
194
|
-
onCancel();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
return (_jsxs("div", { className: "bg-panel border border-line rounded-[6px] p-5", children: [_jsx("div", { className: "flex items-center justify-between mb-4", children: _jsxs("div", { children: [_jsx("h3", { id: "section-editor", className: "text-[15px] font-semibold text-ink mb-0.5", children: t("pages.intent.editor.title") }), _jsx("p", { className: "text-ink-3 text-[12px] leading-relaxed", children: t("pages.intent.editor.description") })] }) }), _jsx("div", { className: "space-y-4", children: SECTION_STEPS.map((step, idx) => {
|
|
198
|
-
const key = STEP_TO_KEY[step];
|
|
199
|
-
const value = sections[key] ?? "";
|
|
200
|
-
return (_jsxs("div", { children: [_jsx("label", { htmlFor: `intent-section-${key}`, className: "block font-mono text-[11px] uppercase tracking-[0.08em] text-ink-3 mb-1", children: t(`pages.intent.wizard.stepLabels.${key}`) }), _jsx("p", { className: "text-ink-3 text-[12px] leading-relaxed mb-1.5", children: t(`pages.intent.wizard.guidance.${key}`) }), _jsx("textarea", { ref: idx === 0 ? firstTextareaRef : undefined, id: `intent-section-${key}`, value: value, onChange: (e) => handleSectionChange(key, e.target.value), className: "w-full h-[120px] bg-surface border border-line rounded-[4px] p-3 text-[13px] text-ink leading-relaxed resize-y focus:outline-none focus:border-gov focus:ring-1 focus:ring-gov/30", spellCheck: false, "aria-label": t(`pages.intent.wizard.stepLabels.${key}`) })] }, step));
|
|
201
|
-
}) }), _jsxs("div", { className: "flex items-center justify-end gap-2 mt-4", children: [_jsx("button", { type: "button", onClick: handleCancel, disabled: saving, className: "border border-line bg-surface text-ink-2 rounded-[4px] px-4 py-2 text-[13px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed", children: t("pages.intent.editor.cancel") }), _jsx("button", { type: "button", onClick: handleSave, disabled: !hasChanges || saving, className: "bg-gov text-paper rounded-[4px] px-4 py-2 text-[13px] font-medium hover:bg-gov-dark transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed", children: saving ? t("pages.intent.editor.saving") : t("pages.intent.editor.save") })] }), showDiscardConfirm && (_jsx("div", { className: "fixed inset-0 z-50 flex items-center justify-center bg-ink/40 backdrop-blur-sm", role: "alertdialog", "aria-modal": "true", "aria-labelledby": "discard-title", onClick: () => setShowDiscardConfirm(false), children: _jsxs("div", { className: "bg-surface border border-line rounded-[8px] p-5 max-w-[400px] w-full mx-4", onClick: (e) => e.stopPropagation(), children: [_jsx("p", { id: "discard-title", className: "text-ink text-[14px] mb-4", children: t("pages.intent.editor.confirmDiscard") }), _jsxs("div", { className: "flex items-center justify-end gap-2", children: [_jsx("button", { type: "button", onClick: () => setShowDiscardConfirm(false), className: "border border-line bg-surface text-ink-2 rounded-[4px] px-3 py-1.5 text-[12px] hover:border-line-2 transition-colors", children: t("pages.intent.editor.no") }), _jsx("button", { type: "button", onClick: () => {
|
|
202
|
-
setShowDiscardConfirm(false);
|
|
203
|
-
onCancel();
|
|
204
|
-
}, className: "bg-red-600 text-white rounded-[4px] px-3 py-1.5 text-[12px] hover:bg-red-700 transition-colors", children: t("pages.intent.editor.yes") })] })] }) }))] }));
|
|
205
|
-
}
|
|
206
|
-
export function CreateIntentButton({ onCreated, showOnboarding = false, lang }) {
|
|
207
|
-
const { t } = useTranslation();
|
|
208
|
-
const [busy, setBusy] = useState(false);
|
|
209
|
-
const [showOnboardingModal, setShowOnboardingModal] = useState(showOnboarding && !isOnboardingDismissed());
|
|
210
|
-
// Create template + save assembled content from wizard.
|
|
211
|
-
// Called when user completes all 5 wizard steps.
|
|
212
|
-
async function createFromWizard(sections) {
|
|
213
|
-
setBusy(true);
|
|
214
|
-
// Step 1: create template (idempotent — ensures file exists)
|
|
215
|
-
const createResult = await createIntentTemplate(false, lang);
|
|
216
|
-
if (!createResult.success) {
|
|
217
|
-
setBusy(false);
|
|
218
|
-
toast.error(t("pages.intent.notFound.createFailed"));
|
|
219
|
-
return;
|
|
220
|
-
}
|
|
221
|
-
// Step 2: save the assembled content (overwrites template defaults)
|
|
222
|
-
const assembled = assembleIntentDoc(sections);
|
|
223
|
-
const saveResult = await saveIntentContent(assembled, lang);
|
|
224
|
-
setBusy(false);
|
|
225
|
-
if (!saveResult.success) {
|
|
226
|
-
// Template was created but wizard content failed to save.
|
|
227
|
-
// The file exists (template), so refresh summary; show error so the
|
|
228
|
-
// user knows to edit manually. This is NOT a silent fallback (rc-9).
|
|
229
|
-
if (saveResult.reason === "oversized") {
|
|
230
|
-
toast.error(t("pages.intent.editor.oversized"));
|
|
231
|
-
}
|
|
232
|
-
else {
|
|
233
|
-
toast.error(t("pages.intent.editor.saveFailed"));
|
|
234
|
-
}
|
|
235
|
-
onCreated(true); // open editor so user can retry / inspect
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
toast.success(t("pages.intent.notFound.createSuccess"));
|
|
239
|
-
onCreated(false); // wizard already filled content — no need to open editor
|
|
240
|
-
}
|
|
241
|
-
// Create empty template. Returns true on success so the caller can decide
|
|
242
|
-
// whether to open the editor (legacy path) or just refresh (skip path).
|
|
243
|
-
// Does NOT call onCreated itself — avoids double-callback bug.
|
|
244
|
-
async function createEmptyTemplate() {
|
|
245
|
-
setBusy(true);
|
|
246
|
-
const result = await createIntentTemplate(false, lang);
|
|
247
|
-
setBusy(false);
|
|
248
|
-
if (!result.success) {
|
|
249
|
-
toast.error(t("pages.intent.notFound.createFailed"));
|
|
250
|
-
return false;
|
|
251
|
-
}
|
|
252
|
-
toast.success(t("pages.intent.notFound.createSuccess"));
|
|
253
|
-
return true;
|
|
254
|
-
}
|
|
255
|
-
function handleComplete(sections) {
|
|
256
|
-
setShowOnboardingModal(false);
|
|
257
|
-
setOnboardingDismissed();
|
|
258
|
-
void createFromWizard(sections);
|
|
259
|
-
}
|
|
260
|
-
function handleSkip() {
|
|
261
|
-
setShowOnboardingModal(false);
|
|
262
|
-
setOnboardingDismissed();
|
|
263
|
-
void createEmptyTemplate().then((ok) => {
|
|
264
|
-
if (ok)
|
|
265
|
-
onCreated(false);
|
|
266
|
-
});
|
|
267
|
-
}
|
|
268
|
-
function handleClose() {
|
|
269
|
-
setShowOnboardingModal(false);
|
|
270
|
-
}
|
|
271
|
-
function handleClick() {
|
|
272
|
-
if (showOnboarding && !isOnboardingDismissed()) {
|
|
273
|
-
setShowOnboardingModal(true);
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
// Legacy direct-create path (onboarding already dismissed or not enabled):
|
|
277
|
-
// create template then open editor so user can fill content manually.
|
|
278
|
-
void createEmptyTemplate().then((ok) => {
|
|
279
|
-
if (ok)
|
|
280
|
-
onCreated(true);
|
|
281
|
-
});
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
return (_jsxs(_Fragment, { children: [_jsx("button", { type: "button", onClick: handleClick, disabled: busy, className: "bg-gov text-paper rounded-[4px] px-4 py-2 text-[13px] font-medium hover:bg-gov-dark transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed", children: busy ? t("pages.intent.notFound.creating") : t("pages.intent.notFound.createButton") }), showOnboardingModal && (_jsx(OnboardingModal, { onComplete: handleComplete, onSkip: handleSkip, onClose: handleClose }))] }));
|
|
285
|
-
}
|
|
286
|
-
export function EditButton({ onClick, loading = false }) {
|
|
287
|
-
const { t } = useTranslation();
|
|
288
|
-
return (_jsx("button", { type: "button", onClick: onClick, disabled: loading, "aria-busy": loading, className: "border border-line bg-surface text-ink-2 rounded-[4px] px-3 py-1.5 text-[12px] hover:border-line-2 transition-colors focus-visible:outline-2 focus-visible:outline-gov focus-visible:outline-offset-2 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:border-line", children: loading ? t("common.loading") : t("pages.intent.editor.edit") }));
|
|
289
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function IntentPage(): import("react").JSX.Element;
|